/* MAIN module File #2 */ #include "zmp.h" #include char *malloc(); fstat(fname,status) char *fname; struct stat *status; { unsigned filelength(); fcbinit(fname,&Thefcb); status->records = filelength(&Thefcb); getfirst(fname); fcbinit("????????.???",&Thefcb); } unsigned filelength(fcbp) struct fcb *fcbp; { int olduser; bdoslp(SETDMA,CPMBUF); /* set dma address */ olduser = getuid(); /* save this user number */ #ifdef MC68K setuid(fcbp->freserved[0] & 0x0f); /* go to file's user no. */ #else setuid(fcbp->freserved & 0x0f); /* go to file's user no. */ #endif bdoslp(35,fcbp); setuid(olduser); /* restore original */ return fcbp->ranrec; } roundup(dividend,divisor) int dividend, divisor; { return (dividend/divisor + ((dividend%divisor) ? 1 : 0)); } getfirst(aname) /* ambiguous file name */ char *aname; { bdoslp(SETDMA,CPMBUF); /* set dma address */ fcbinit(aname,&Thefcb); return bdoslp(SFF,&Thefcb) & 0xff; } getnext() { bdoslp(SETDMA,CPMBUF); /* set dma address */ return bdoslp(SFN, (long) NULL) & 0xff; } memcpy(dest,source,count) char *dest, *source; int count; { while (count--) *dest++ = *source++; } memset(dest,byte,count) char *dest, byte; int count; { while (count--) *dest++ = byte; } /* command: expand wild cards in the command line. (7/25/83) * usage: command(&argc, &argv) modifies argc and argv as necessary * Written by Dr. Jim Gillogly; Modified for CP/M by Walt Bilofsky. * Modified by HM to just get ambiguous fn for zmodem, ymodem. * Modified rjm so that it actually works, and with CP/M-68k as well. */ int COMnf, COMc; char *COMarg, *COMs, **COMfn, **COMv; int expand(); command(argcp,argvp) int *argcp; char **argvp; { char *p, c; char *f_alloc[MAXFILES]; COMfn = f_alloc; COMc = *argcp; COMv = (char **) *argvp; COMnf = 0; for (COMarg = *COMv; COMc--; COMarg = *++COMv) { #ifdef DEBUG printf("\nDoing %s",COMarg); #endif for (COMs = COMarg; *COMs; COMs++) if (*COMs == '?' || *COMs == '*') { if (!expand()) { /* Too many */ *argcp = 0; return; } goto contn; /* expand each name at most once */ } COMfn[COMnf] = malloc(FNSIZE); p = COMarg; while (c = *p) /* Convert to lower case */ *p++ = tolower(c); strcpy(COMfn[COMnf++],COMarg); /* no expansion */ contn:; } *argcp = COMnf; COMfn[COMnf++] = (char *) -1; *argvp = malloc((sizeof(char *)) * COMnf); COMv = (char **) *argvp; while (COMnf--) COMv[COMnf] = COMfn[COMnf]; } expand() /* Returns FALSE if error */ { char fcb[36]; static char *p,*q,*r,c; static int i,flg,olduser; #ifdef DEBUG printf("\nExpanding %s",COMarg); #endif olduser = getuid(); /* save original user area */ fcbinit(COMarg,fcb); if (fcb[0] == -1) fcb[0] = '?'; /* Check for all users */ for (i = flg = 1; i <= 11; ++i) { /* Expand *'s */ if (i == 9) flg = 1; if (fcb[i] == '*') flg = 0; if (flg == 0) fcb[i] = '?'; } setuid(fcb[13]); /* go to specified user area */ flg = 17; bdoslp(26,CPMBUF); /* Make sure DMA address OK */ while (((i = bdoslp(flg,fcb)) & 0xff) != 0xff) { COMfn[COMnf++] = q = malloc(FNSIZE); if (COMnf >= MAXFILES-1) { for (p = "Too many file names.\n"; putchar(*p++); ); { setuid(olduser); return FALSE; } } #ifdef MC68K p = (_base + 0x81) + (i * 32); /* Where to find dir. record */ #else p = (char *) 0x81 + (i * 32); #endif /* transfer du: first */ if ((index(COMarg,':')) && COMarg[0] != '?') { r = COMarg; do *q++ = c = *r++; while (c != ':'); } /* Now transfer filename */ for (i = 12; --i; ) { if (i == 3) *q++ = '.'; if ((*q = tolower(*p++ & 0177)) != ' ') ++q; } *q = 0; flg = 18; } setuid(olduser); return TRUE; } ctr(p) char *p; { return max((80 - strlen(p))/2,0); } opabort() { Lastkey = getch() & 0xff; if (Lastkey == ESC) { flush(); if (!Inhost && !Dialing) report(MESSAGE,"Operator abort"); QuitFlag = TRUE; } return QuitFlag; } /* * readock(timeout, count) reads character(s) from modem * (1 <= count <= 3) * it attempts to read count characters. If it gets more than one, * it is an error unless all are CAN * (otherwise, only normal response is ACK, CAN, or C) * * timeout is in tenths of seconds */ readock(timeout, count) int timeout, count; { static int c; static char byt[5]; c = mread(byt,count,timeout); if (c < 1) return TIMEOUT; if (c == 1) return (byt[0] & 0xff); else while (c) if (byt[--c] != CAN) return NERROR; return CAN; } readline(n) int n; { return (readock(n,1)); } putlabel(string) char string[]; { cls(); locate(0,ctr(string) - 1); /* Centre on top line */ stndout(); /* Inverse video */ printf(" %s \n\n",string); /* Print the string */ stndend(); /* Inverse off */ } killlabel() /*disable 25th line*/ { cls(); /* just clear screen */ } mgetchar(seconds) /* allows input from modem or operator */ int seconds; { static int c, tenths; Lastkey = 0; tenths = seconds * 10; if ((c=readline(tenths)) != TIMEOUT) return (c & 0xff); else if (Lastkey) return Lastkey; return TIMEOUT; } #ifdef AZTEC_C /* Dummy routine to allow long arithmetic in overlays */ dummylong() { long a = 1L; a = a * 2L; } #endif box() /* put box on screen for file transfer */ { register int i; static char *headings[] = { "","Protocol:","File Name:","File Size:", "Block Check:","Transfer Time:", "Bytes Transferred:","Blocks Transferred:", "Sectors in File:","Error Count:", "Last Message: NONE", "Status:" }; static int start[] = { 0,13+LC,12+LC,12+LC,10+LC,8+LC,4+LC,3+LC,6+LC, 10+LC,9+LC,15+LC }; LOCATE(TR,LC); putchar(UL); for (i = 1; i < WD-1; i++) putchar(HORIZ); putchar(UR); LOCATE(BR,LC); putchar(LL); for (i = 1; i < WD-1; i++) putchar(HORIZ); putchar(LR); for (i = 1; i < HT-1; i++) { LOCATE(TR+i,LC); putchar(VERT); LOCATE(TR+i,RC); putchar(VERT); } clrbox(); for (i = 1; i < 12; i++) { locate(TR+i,start[i]); printf(headings[i]); } } clrbox() { register int i; for (i=TR+1; i < BR; i++) { locate(i,LC+1); printf(" "); } } mread(buffer, count, timeout) /* time in tenths of secs */ char *buffer; int count, timeout; { int i, c; i = count = 0; while (!(c = mrd()) && (timeout--) && !opabort()); if (c) buffer[i++] = mcharinp(); return i; } mcharinp() { static unsigned c; c = mchin(); if (Stopped) { mchout(CTRLQ); Stopped = FALSE; } return c; } mcharout(c) char c; { while (!moutrdy()) opabort(); /* Test for operator abort while we wait */ mchout(c); /* Then send it */ } minprdy() { return mirdy() || Stopped; } /* Ask user a question and get a Y/N reply: return TRUE if yes, FALSE if no */ askuser(question) char *question; { char c; short i; locate(QUESTION,1); /* move to correct line */ while(*question) putchar(*question++); /* print it */ c = toupper(chrin()); /* get answer */ locate(QUESTION,1); /* return to line to erase it */ for (i = 0; i < 72; i++) putchar(' '); /* fill with spaces */ return (c == 'Y'); } /* End of MAIN module */