koreth@ssyx.ucsc.edu (Steven Grimm) (05/30/88)
Submitted-by: bammi@mandrill.ces.cwru.edu (Jwahar R. Bammi) Posting-number: Volume 1, Issue 45 Archive-name: zmdm/part05 #!/bin/sh # this is part 5 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file SZ.C continued # CurArch=5 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file SZ.C" sed 's/^X//' << 'SHAR_EOF' >> SZ.C X fflush(logf); X X } X#endif X stalarm(c); X c=read_modem(byt, count); X X stalarm(0); X#ifdef SDEBUG X if (Verbose>5) X { X fprintf(STDERR, "ret cnt=%d %x %x\n", c, byt[0], byt[1]); X fprintf(logf, "ret cnt=%d %x %x\n", c, byt[0], byt[1]); X fflush(logf); X } X#endif X X if (c<1) X return TIMEOUT; X if (c==1) X return (byt[0]&0377); X else X while (c) X if (byt[--c] != CAN) X return ERROR; X return CAN; X} X Xsreadline(n) X{ X return (readock(n, 1)); X} X X Xsusage() X{ X fprintf(STDERR,"\nSend file(s) with ZMODEM/YMODEM/XMODEM Protocol\n"); X fprintf(STDERR," (Y) = Option applies to YMODEM only\n"); X fprintf(STDERR," (Z) = Option applies to ZMODEM only\n"); X fprintf(STDERR, X "%s for %s by ST Enthusiasts at Case Western Reserve University\n", X SSTVERSION, STOS); X fprintf(STDERR,"\tBased on %s for %s by Chuck Forsberg\n\n", SVERSION, OS); X/* fprintf(STDERR,"Usage: sz [-12+adefknquvXy] [-] file ...\n"); */ X fprintf(STDERR,"Usage: sz [-+defknquvXyB] file ...\n"); X/* fprintf(STDERR," sz [-1eqv] -c COMMAND\n"); */ X fprintf(STDERR," sz [-eqv] -c COMMAND\n"); X/* fprintf(STDERR," 1 Use stdout for modem input\n"); */ X#ifdef CSTOPB X fprintf(STDERR," 2 Use 2 stop bits\n"); X#endif X fprintf(STDERR," + Append to existing destination file (Z)\n"); X/* fprintf(STDERR," a (ASCII) change NL to CR/LF\n"); */ X fprintf(STDERR," c send COMMAND (Z)\n"); X fprintf(STDERR," d Change '.' to '/' in pathnames (Y/Z)\n"); X fprintf(STDERR," e Escape control characters (Z)\n"); X fprintf(STDERR," f send Full pathname (Y/Z)\n"); X fprintf(STDERR," i send COMMAND, ack Immediately (Z)\n"); X fprintf(STDERR," k Send 1024 byte packets (Y)\n"); X fprintf(STDERR," L N Limit packet length to N bytes (Z)\n"); X fprintf(STDERR," l N Limit frame length to N bytes (l>=L) (Z)\n"); X fprintf(STDERR," n send file if Newer|longer (Z)\n"); X fprintf(STDERR," N send file if different length|date (Z)\n"); X fprintf(STDERR, " o Use 16 bit CRC instead of 32 bit CRC (Z)\n"); X fprintf(STDERR," p Protect existing destination file (Z)\n"); X fprintf(STDERR," r Resume/Recover interrupted file transfer (Z)\n"); X fprintf(STDERR," q Quiet (no progress reports)\n"); X fprintf(STDERR," u Unlink file after transmission\n"); X fprintf(STDERR," v Verbose - debugging information\n"); X fprintf(STDERR," X XMODEM protocol - send no pathnames\n"); X fprintf(STDERR," y Yes, overwrite existing file (Z)\n"); X fprintf(STDERR," B Force Binary mode transfers (Z)\n"); X/* fprintf(STDERR, X"- as pathname sends standard input as sPID.sz or environment ONAME\n"); */ X return(1); X} X X/* X * Get the receiver's init parameters X */ Xgetzrxinit() X{ X register int n; X X for (n=10; --n>=0; ) { X X switch (zgethdr(Rxhdr, 1)) { X case ZCHALLENGE: /* Echo receiver's challenge numbr */ X stohdr(Rxpos); X zshhdr(ZACK, Txhdr); X continue; X case ZCOMMAND: /* They didn't see out ZRQINIT */ X stohdr(0L); X zshhdr(ZRQINIT, Txhdr); X continue; X case ZRINIT: X Rxflags = 0377 & Rxhdr[ZF0]; X Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32)); X X Rxbuflen = (0337 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8); X vfile("Rxbuflen=%d Tframlen=%d", Rxbuflen, Tframlen); X siggi = 0; X#ifndef READCHECK X#ifdef USG X mode(2); /* Set cbreak, XON/XOFF, etc. */ X#else X /* Use 1024 byte frames if no sample/interrupt */ X if (Rxbuflen < 32 || Rxbuflen > 1024) { X Rxbuflen = 1024; X vfile("Rxbuflen=%d", Rxbuflen); X } X#endif X#endif X /* Override to force shorter frame length */ X if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32)) X Rxbuflen = Tframlen; X if ( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024)) X Rxbuflen = Tframlen; X vfile("Rxbuflen=%d", Rxbuflen); X X /* X * If input is not a regular file, force ACK's each 1024 X * (A smarter strategey could be used here ...) X */ X if ((Rxbuflen == 0) || (Rxbuflen > 1024)) X Rxbuflen = 1024; X vfile("Rxbuflen=%d", Rxbuflen); X X return (sendzsinit()); X case ZCAN: X case TIMEOUT: X return ERROR; X case ZRQINIT: X if (Rxhdr[ZF0] == ZCOMMAND) X continue; X default: X zshhdr(ZNAK, Txhdr); X continue; X } X } X return ERROR; X} X X/* Send send-init information */ Xsendzsinit() X{ X register int c; X register int errors; X X if (Myattn[0] == '\0') X return OK; X X errors = 0; X for (;;) { X stohdr(0L); X zsbhdr(ZSINIT, Txhdr); X zsdata(Myattn, 1+strlen(Myattn), ZCRCW); X c = zgethdr(Rxhdr, 1); X switch (c) { X case ZCAN: X return ERROR; X case ZACK: X return OK; X default: X if (++errors > 9) X return ERROR; X continue; X } X } X} X X/* Send file name and related info */ Xzsendfile(buf, blen, szbytes) Xchar *buf; Xint blen; Xlong szbytes; X{ X register int c, szstat; X long start_time, end_time; X extern void rd_time(); X X Supexec(rd_time); X start_time = pr_time; X X for (;;) { X Txhdr[ZF0] = Lzconv; /* file conversion request */ X Txhdr[ZF1] = Lzmanag; /* file management request */ X Txhdr[ZF2] = Lztrans; /* file transport request */ X Txhdr[ZF3] = 0; X zsbhdr(ZFILE, Txhdr); X zsdata(buf, blen, ZCRCW); Xagain: X c = zgethdr(Rxhdr, 1); X switch (c) { X case ZRINIT: X goto again; X case ZCAN: X case TIMEOUT: X case ZABORT: X case ZFIN: X return ERROR; X case ZSKIP: X#ifndef REMOTE X fprintf(STDERR,"\n\n"); X#endif X stfclose(in); in = (-1); return c; X case ZRPOS: X if(stfseek(in, Rxpos, 0)) X { X fprintf(STDERR,"\r\nError While Seeking file\n"); X return ERROR; X } X Txpos = Rxpos; Lastc = (-1); Dontread = FALSE; X if((szstat = zsendfdata()) == OK) X { X#ifndef REMOTE X Supexec(rd_time); X end_time = pr_time; X fprintf(STDERR,"%ld Bytes Sent\t\ XTransfer Time %ld secs.\tApprox %ld cps\n\n", szbytes, (end_time - start_time)/200L, Xszbytes/((end_time - start_time)/200L)); X#endif X } X return szstat; X case ERROR: X default: X continue; X } X } X} X X/* Send the data in the file */ Xzsendfdata() X{ X register int c, c1, e; X register int newcnt; X register long tcount = 0; X static int tleft = 6; /* Counter for test mode */ X X if (Baudrate > 300) X Blklen = 256; X if (Baudrate > 2400) X Blklen = KSIZE; X/* if (Rxbuflen && Blklen>Rxbuflen) --jrb do not limit block size */ X if (Rxbuflen) X Blklen = Rxbuflen; X if (blkopt && Blklen > blkopt) X Blklen = blkopt; X vfile("Rxbuflen=%d Blklen=%d", Rxbuflen, Blklen); Xsomemore: X if (setjmp(intrjmp)) { Xwaitack: X switch (c1 = getinsync()) { X default: X case ZCAN: X fprintf(STDERR,"\r\nReceiver Cancelled Transfer\n\n"); X stfclose(in); X in = (-1); X return ERROR; X case ZSKIP: X#ifndef REMOTE X fprintf(STDERR,"\r\nReceiver forced SKIP Transfer(1)\n\n"); X#endif X stfclose(in); X in = (-1); X return c1; X case ZACK: X tcount += c; X lreport(tcount); X /* fall thru */ X case ZRPOS: X break; X case ZRINIT: X return OK; X } X } X X siggi = 1; X newcnt = Rxbuflen; X stohdr(Txpos); X zsbhdr(ZDATA, Txhdr); X X /* X * Special testing mode. This should force receiver to Attn,ZRPOS X * many times. Each time the signal should be caught, causing the X * file to be started over from the beginning. X */ X#ifdef TESTATTN X if (Testattn) { X if ( --tleft) X while (tcount < 20000) { X wr_modem(qbf); X tcount += strlen(qbf); X#ifdef READCHECK X while (Bconstat(1)) { X switch (sreadline(1)) { X case CAN: X case ZPAD: X goto waitack; X } X } X#endif X } X siggi = 0; canit(); X stsleep(3); purgeline(); mode(0); X#ifdef SDEBUG X if(logf != (FILE *)NULL) X fclose(logf); X#endif X X/* printf("\nsz: Tcount = %ld\n", tcount); */ X if (tleft) { X /* printf("\r\nERROR: Interrupts Not Caught\n"); */ X aexit(1); X } X aexit(0); X } X#endif X X do { X if (Dontread) { X c = Lastc; X } else { X c = zfilbuf(secbuf, Blklen); X Lastread = Txpos; Lastc = c; X } X#ifdef SDEBUG X if (Verbose > 10) X vfile("Dontread=%d c=%d", Dontread, c); X#endif X X Dontread = FALSE; X if (c < Blklen) X e = ZCRCE; X else if (Rxbuflen && (newcnt -= c) <= 0) X e = ZCRCW; X else X e = ZCRCG; X zsdata(secbuf, c, e); X Txpos += c; X if(e == ZCRCG) X { X tcount += c; X lreport(tcount); X } X X if (e == ZCRCW) X goto waitack; X#ifdef READCHECK X /* X * If the reverse channel can be tested for data, X * this logic may be used to detect error packets X * sent by the receiver, in place of setjmp/longjmp X * rdchk(fdes) returns non 0 if a character is available X */ X flush_modem(); X while (Bconstat(1)) { X switch (sreadline(1)) { X case CAN: X case ZPAD: X zsdata(secbuf, 0, ZCRCE); X goto waitack; X } X } X#endif X } while (c == Blklen); X tcount += c; X lreport(tcount); X siggi = 0; X lsct = 1; X X for (;;) { X stohdr(Txpos); X zsbhdr(ZEOF, Txhdr); X switch (getinsync()) { X case ZACK: X continue; X case ZRPOS: X goto somemore; X case ZRINIT: X return OK; X case ZSKIP: X#ifndef REMOTE X fprintf(STDERR,"\r\nReceiver forced SKIP Transfer(2)\n\n"); X#endif X stfclose(in); X in = (-1); X return c; X default: X fprintf(STDERR,"\r\nErrors while Send Data\n\n"); X stfclose(in); X in = (-1); X return ERROR; X } X } X} X X/* X * Respond to receiver's complaint, get back in sync with receiver X */ Xgetinsync() X{ X register int c; X X for (;;) { X#ifdef TESTATTN X if (Testattn) { X wr_modem("\r\n\n\n***** Signal Caught *****\r\n"); X Rxpos = 0; c = ZRPOS; X } else X#endif X X c = zgethdr(Rxhdr, 0); X switch (c) { X case ZCAN: X case ZABORT: X case ZFIN: X case TIMEOUT: X return ERROR; X case ZRPOS: X if (Lastc >= 0 && Lastread == Rxpos) { X Dontread = TRUE; X } else { X /* clearerr(in); */ /* In case file EOF seen */ X if(stfseek(in, Rxpos, 0)) X { X fprintf(STDERR,"\r\nError While Seeking file\n"); X return ERROR; X } X X } X Txpos = Rxpos; X return c; X case ZACK: X return c; X case ZRINIT: X case ZSKIP: X#ifndef REMOTE X fprintf(STDERR,"\n\n"); X#endif X stfclose(in); X in = (-1); X return c; X case ERROR: X default: X zsbhdr(ZNAK, Txhdr); X continue; X } X } X} X/* Say "bibi" to the receiver, try to do it cleanly */ Xsaybibi() X{ X for (;;) { X stohdr(0L); X zsbhdr(ZFIN, Txhdr); X switch (zgethdr(Rxhdr, 0)) { X case ZFIN: X sendline('O'); sendline('O'); flush_modem(); X case ZCAN: X case TIMEOUT: X return; X } X } X} X X/* Send command and related info */ Xzsendcmd(buf, blen) Xchar *buf; X{ X register int c, errors; X long cmdnum; X X/* cmdnum = getpid(); */ X cmdnum = 1; /* A random # */ X errors = 0; X for (;;) { X stohdr(cmdnum); X Txhdr[ZF0] = Cmdack1; X zsbhdr(ZCOMMAND, Txhdr); X zsdata(buf, blen, ZCRCW); Xlisten: X Rxtimeout = 100; /* Ten second wait for resp. */ X c = zgethdr(Rxhdr, 1); X X switch (c) { X case ZRINIT: X continue; X case ERROR: X case TIMEOUT: X if (++errors > Cmdtries) X return ERROR; X continue; X case ZCAN: X case ZABORT: X case ZFIN: X case ZSKIP: X case ZRPOS: X return ERROR; X default: X if (++errors > 10) X return ERROR; X continue; X case ZCOMPL: X Exitcode = Rxpos; X saybibi(); X return OK; X case ZRQINIT: X vfile("******** RZ *******"); X/* stsystem("rz"); */ X vfile("******** SZ *******"); X goto listen; X } X } X} X X X#ifndef STANDALONE X/* X * If called as sb use YMODEM protocol X */ Xschkinvok(s) Xchar *s; X{ X if (s[0]=='s' && s[1]=='b') { X Nozmodem = TRUE; Blklen=KSIZE; X } X} X#endif X X/* -eof- */ SHAR_EOF echo "File SZ.C is complete" chmod 0600 SZ.C || echo "restore of SZ.C fails" echo "x - extracting SZLNK (Text)" sed 's/^X//' << 'SHAR_EOF' > SZLNK && Xc:\lib\gemstart.o common.o sz.o util.o tyme.o zm.o fileio.o Xc:\lib\osbind.o c:\lib\gemlib c:\lib\libf SHAR_EOF chmod 0600 SZLNK || echo "restore of SZLNK fails" echo "x - extracting TRANSFER.C (Text)" sed 's/^X//' << 'SHAR_EOF' > TRANSFER.C && X/* X * (Quick & Dirty) Transfer Shell X * X * Jwahar Bammi X * usenet: mandrill!bammi@{decvax,sun}.UUCP X * csnet: bammi@mandrill.ces.CWRU.edu X * arpa: bammi@mandrill.ces.CWRU.edu X * CompuServe: 71515,155 X */ X X#include "config.h" X X#ifdef DLIBS X#include <string.h> X#endif X X#include "zmdm.h" X#include "common.h" X X#define ISWILD(X) ((X == '*')||(X == '?')) X#define PROMPT fprintf(STDERR,"zmdm> ") X Xextern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(), X hhelp(); X X#ifdef RECURSE Xextern int doszf(); X#endif X Xstatic struct comnds { X char *command; /* command string */ X int (*routine)(); /* routine to invoke */ X char *synopsis; /* synopsis */ X int expand; /* expand wildcards before calling routine? */ X} comtab [] = { X { "rz", dorz, "receive files using Z/X modem protocol", TRUE }, X { "rb", dorz, "receive files using Y modem protocol", TRUE }, X#ifdef RECURSE X { "sz", doszf, "send files using Z/Y/X modem protocol", TRUE }, X#else X { "sz", dosz, "send files using Z/Y/X modem protocol", TRUE }, X#endif X { "sb", dosz, "send files using Y modem protocol", TRUE }, X { "rm", rm, "remove files", TRUE }, X { "cp", cp, "copy files", TRUE }, X { "ls", ls, "list directory", FALSE}, X { "cd", cd, "change working directory", FALSE}, X { "md", md, "make a directory", FALSE}, X { "rd", rd, "remove a directory", FALSE}, X { "pwd",pwd, "print working directory", FALSE}, X { "df", df, "check free space", FALSE}, X { "?", hhelp, "this message", FALSE}, X { (char *)NULL, (int (*)())NULL, (char *)NULL, FALSE} X}; X X#define MAXARGS 1024 Xstatic char *targv[MAXARGS]; Xstatic int targc; Xchar *alltolower(); X Xtransfer() X{ X char linebuf[132]; X char *line; X int command; X int status; X extern int find_command(); X extern int expnd_args(); X#ifdef DEBUG X int i; X#endif X X fprintf(STDERR,"hit <RETURN> to return to emulator, <?> for help\n\n"); X targc = 0; X while (TRUE) X { X if(targc > 1) X free_args(); X X PROMPT; X linebuf[0] = 127; X#ifndef REMOTE X Cconrs(linebuf); X#else X Cconraux(linebuf); X#endif X putc('\n', STDERR); X if(linebuf[1] == 0) X /* cancelled */ X return; X X linebuf[(linebuf[1]+2)] = '\0'; X line = &linebuf[2]; X#ifdef DEBUG Xprintf("Line: |%s|\n", line); X#endif X X targv[0] = line; X targc = 1; X X /* pick up targv[0] */ X while((*line != '\0') && (!isspace(*line))) X line++; X X if(*line != '\0') X { X *line++ = '\0'; X } X X if((command = find_command(targv[0])) < 0) X { X fprintf(STDERR,"Invalid Command\n"); X continue; X } X X if(expnd_args(line, comtab[command].expand)) X /* too many args */ X continue; X#ifdef DEBUG Xprintf("targc %d\n", targc); Xfor(i = 0; i < targc; i++) X printf("%s ", targv[i]); Xprintf("\n\n"); X#endif X X if((status = (*(comtab[command].routine))(targc, targv)) != 0) X fprintf(STDERR,"Exit Status %d\n", status); X X#ifdef DEBUG Xprintf("Exit Status %d\n", status); X#endif X X } /* While */ X} X X/* X * Straight sequential search thru comtab X */ Xint find_command(s) Xregister char *s; X{ X register int i; X X for(i = 0; comtab[i].command != (char *)NULL; i++) X { X if(strcmp(s, comtab[i].command) == 0) X return i; X } X X return -1; X} X X/* X * Expand command line args, return TRUE if too many args, or Not matching Quotes X */ Xint expnd_args(s, expand_wild) Xregister char *s; Xint expand_wild; X{ X char next_arg[128]; X register char *p; X register int contains_wild; X extern int add_argv(); X extern int handl_wild(); X X while(*s != '\0') X { X p = next_arg; X while(isspace(*s)) s++; /* skip leading space */ X if(*s != '\0') X { X contains_wild = FALSE; X if(*s == '\047') X { X /* Quoted arg */ X s++; X while((*s != '\0') && (*s != '\047')) X *p++ = *s++; X *p = '\0'; X if(*s == '\0') X { X fprintf(STDERR,"No Matching Quote\n"); X return TRUE; X } X else X s++; X if(add_argv(next_arg)) X return TRUE; X } X else X { X while(!isspace(*s) && (*s != '\0')) X { X contains_wild |= ISWILD(*s); X *p++ = *s++; X } X *p = '\0'; X X if(contains_wild && expand_wild) X { X if(handl_wild(next_arg)) X return TRUE; X } X else X { X if(add_argv(next_arg)) X return TRUE; X } X } /* if-else */ X } /* If */ X } /* while */ X X return FALSE; X} X X/* X * add an arg to argv. Return TRUE if error X */ Xint add_argv(s) Xchar *s; X{ X extern char *myalloc(); X extern char *strcpy(); X extern int strlen(); X X if(targc > (MAXARGS-1)) X { X fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS); X return TRUE; X } X targv[targc++] = strcpy(myalloc(strlen(s)+1), s); X X return FALSE; X X} X X/* X * expand wild card arguments. Return TRUE on error. X */ Xint handl_wild(s) Xchar *s; X{ X extern struct stat statbuf; X extern char *mkpathname(); X X if(Fsfirst(s, 0x21) != 0) X { X /* No match */ X fprintf(STDERR,"No Match for %s\n", s); X return TRUE; X } X X alltolower(statbuf.st_name); X if(add_argv(mkpathname(s, statbuf.st_name))) X return TRUE; X X while(Fsnext() == 0) X { X alltolower(statbuf.st_name); X if(add_argv(mkpathname(s, statbuf.st_name))) X return TRUE; X } X X return FALSE; X} X X/* X * Given a spec with a trailing wildcard and a base will name construct pathname X * X */ Xchar *mkpathname(spec, file) Xregister char *spec, *file; X{ X extern char *rindex(); X register char *p; X X if((p = rindex(spec, '\\')) == (char *)NULL) X /* no path name */ X return file; X X while(*file != '\0') X *++p = *file++; X *++p = '\0'; X X return spec; X} X Xfree_args() X{ X register int i; X X for(i = 1; i < targc; i++) X free(targv[i]); X} X X/* X * remove files X * Usage: rm [-i] files ... X */ Xint rm(argc, argv) Xregister int argc; Xregister char **argv; X{ X register int interactive; X register int status, s; X extern int yesno(); X extern int errno; X X interactive = FALSE; X status = 0; X while(--argc) X { X ++argv; X if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') ) X interactive = TRUE; X else X { X if(interactive) X if(!yesno("rm: remove", *argv)) X continue; X if(unlink(*argv)) X { X s |= 1; X fprintf(STDERR, "%s: no such file\n", *argv); X } X status |= s; X } X } X return status; X} X X/* X * Prompt and return Yes/No truth value X * X */ Xint yesno(p1, p2) Xregister char *p1, *p2; X{ X char reply[16]; X X fprintf(STDERR,"%s %s (y/n): ", p1, p2); X reply[0] = 16; X#ifndef REMOTE X Cconrs(reply); X#else X Cconraux(reply); X#endif X X putc('\n', STDERR); X return ( (reply[2] == 'y') || (reply[2] == 'Y') ); X X} X X/* X * copy files X * Usage: X * cp src dest X * or X * cp files.. directory X */ Xint cp(argc, argv) Xint argc; Xchar **argv; X{ X char dest[128]; X register int status; X extern int strlen(); X extern int cpy(); X extern char *basename(); X X status = 0; X if(argc > 3) X { X register int i; X X if(!existd(argv[argc-1])) X { X fprintf(STDERR,"%s does not exists or is not a directory\n", X argv[argc-1]); X return 1; X } X X for(i = 1; i < argc - 1; i++) X { X strcpy(dest, argv[argc-1]); X if( (argv[argc-1])[(strlen(argv[argc-1])-1)] != '\\') X strcat(dest, "\\"); X strcat(dest, basename(argv[i])); X X fprintf(STDERR,"copying %s to %s\n", argv[i], dest); X status |= cpy(argv[i], dest); X } X } X else X { X if(argc > 2) X { X if(existd(argv[2])) X { X /* dest is a directory */ X strcpy(dest, argv[2]); X if( (argv[2])[(strlen(argv[2])-1)] != '\\') X strcat(dest, "\\"); X X strcat(dest, basename(argv[1])); X X fprintf(STDERR,"copying %s to %s\n", argv[1], dest); X return (cpy(argv[1], dest)); X } X X if(strcmp(argv[1], argv[2]) == 0) X { X fprintf(STDERR,"Cannot copy a file onto itself\n"); X return 3; X } X status = cpy(argv[1], argv[2]); X } X else X { X fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n"); X return 2; X } X } X X return status; X} X X X/* X * Cpy src -> dest X * X */ Xint cpy(src, dest) Xchar *src, *dest; X{ X register int fps,fpd; X register long count; X register int status; X X status = 0; X X if((fps = Fopen(src, 0)) < (-3)) X { X status = fps; X fprintf(STDERR,"%s: no such file\n", src); X return status; X } X X if((fpd = Fcreate(dest, 0)) < (-3)) X { X if((fpd = Fopen(dest, 1)) < (-3)) X { X Fclose(fps); X status = fpd; X fprintf(STDERR,"%s: cannot create\n",dest); X return status; X } X } X X while( (count = Fread(fps, (long)BBUFSIZ, bufr)) > 0L) X { X if(Fwrite(fpd, count, bufr) != count) X { X status = 1; X fprintf(STDERR,"Error Writing %s\n",dest); X break; X } X } X if(count < 0L) X { X status = 2; X fprintf(STDERR,"Error Reading %s\n", src); X } X X Fclose(fpd); X Fclose(fps); X X return status; X} X X#define haswild(X) \ X( (rindex(X,'*') != (char *)NULL) || (rindex(X,'?') != (char *)NULL) ) X X/* X * list directories X */ Xint ls(argc, argv) Xint argc; Xchar **argv; X{ X char path[128]; X register char *p; X extern char *rindex(); X extern int existd(); X X if(argc < 2) X lis("*.*"); X else X { X while(--argc) X { X ++argv; X if((p = rindex(*argv,'\\')) == (char *)NULL) X p = *argv; X else X p++; X if(*p == '\0') X { X strcpy(path, *argv); X strcat(path,"*.*"); X } X else X { X if(haswild(p)) X strcpy(path, *argv); X else X { X if(existd(p)) X { X strcpy(path, *argv); X strcat(path, "\\*.*"); X } X else X strcpy(path, *argv); X } X } X lis(path); X } /* while */ X } X X return 0; X} X X/* X * given a possibly wild carded string put out list of subtrees X * X */ Xlis(wild) Xchar *wild; X{ X extern struct stat statbuf; X register int count; X X#ifdef DEBUG Xprintf("ls %s\n", wild); X#endif X X if(Fsfirst(wild, 0x0020 | 0x0010) != 0) X { X fprintf(STDERR,"%s - no match.\n", wild); X return; X } X X count = 0; X alltolower(statbuf.st_name); X if(!((strcmp(statbuf.st_name,".") == 0) || X (strcmp(statbuf.st_name, "..") == 0))) X putls(&statbuf, ++count); X X while(Fsnext() == 0) X { X alltolower(statbuf.st_name); X if(!((strcmp(statbuf.st_name,".") == 0) || X (strcmp(statbuf.st_name, "..") == 0))) X putls(&statbuf, ++count); X } X X if((count % 4)) X putc('\n', STDERR); X X} X X/* X * Put out a directory entry X */ Xputls(statbuf, count) Xregister struct stat *statbuf; Xregister int count; X{ X char dbuf[16]; X X if((statbuf->st_mode) & 0x0010) X { X /* subtree */ X strcpy(dbuf, statbuf->st_name); X strcat(dbuf, "/"); X fprintf(STDERR,"%-13s ", dbuf); X } X else X /* file */ X fprintf(STDERR,"%-12s %5ld ", statbuf->st_name, statbuf->st_size); X X if(!(count %4)) X putc('\n', STDERR); X} X X/* X * Change working directory X */ Xint cd(argc, argv) Xint argc; Xchar **argv; X{ X register char *d, *path; X register int drive; X extern char *index(); X X if((argc < 2) || (argc > 2)) X { X fprintf(STDERR,"Usage: cd directory\n"); X return 1; X } X X X X if((d = index(argv[1],':')) == (char *)NULL) X { X /* Drive was not specified, must mean the current drive */ X path = argv[1]; X } X else X { X d--; X if(isupper(*d)) X { X *d = tolower(*d); X } X drive = *d - 'a'; X if(d[2] != '\\') /* just gave D: */ X { X /* we will shove in the '\' */ X d[1] = '\\'; X path = &d[1]; X } X else X path = &d[2]; X X /* Set the Drive */ X if(Dsetdrv(drive) < 0) X { X fprintf(STDERR,"Could not set drive %c:\n", *d); X return 2; X } X X } X X X /* Set the Path */ X if(Dsetpath(path) != 0) X { X fprintf(STDERR,"Could not set directory %s\n", path); X return 3; X } X X return 0; X X} X X/* X * pwd - figure out the current working directory X * X */ Xint pwd() X{ X register int drive; X char _cwd[128]; X X drive = Dgetdrv(); X Dgetpath(&_cwd[3],0); X fprintf(STDERR,"%c:%s%s\n", (drive + 'a'), X ((_cwd[3] == '\\')? "" : "\\"), &_cwd[3]); X X return 0; X} X X/* X * Print free space X */ Xint df(argc, argv) Xint argc; Xchar **argv; X{ X struct { X long b_free; X long b_total; X long b_secsiz; X long b_clsiz; X } fbuf; X X register int drive; X register long ffree, total; X extern long drv_map; X X if(argc > 1) X { X ++argv; X drive = (*argv)[0]; X if(isupper(drive)) X drive = tolower(drive); X X drive = drive - 'a'; X if((drv_map & (1L << drive)) == 0) X { X fprintf(STDERR,"Invalid Drive %c:\n", (drive + 'a')); X return 1; X } X drive +=1; X } X else X drive = Dgetdrv()+1; /* default current drive */ X X fprintf(STDERR,"Please Wait ....."); X Dfree(&fbuf,drive); X ffree = fbuf.b_free * fbuf.b_clsiz * fbuf.b_secsiz; X total = fbuf.b_total * fbuf.b_clsiz * fbuf.b_secsiz; X fprintf(STDERR,"\r%ld Bytes (", ffree); X prratio(STDERR, ffree, total); X fprintf(STDERR, ") Free on drive %c:\n", ((drive-1) + 'a')); X X return 0; X} X X X/* X * print a ratio X * avoid floats like the plague X */ Xprratio(stream, num, den) XFILE *stream; Xlong num, den; X{ X register int q; /* Doesn't need to be long */ X X if(num > 214748L) { /* 2147483647/10000 */ X q = num / (den / 10000L); X } else { X q = 10000L * num / den; /* Long calculations, though */ X } X if (q < 0) { X putc('-', stream); X q = -q; X } X fprintf(stream, "%d.%02d%%", q / 100, q % 100); X} X X/* X * Make directories X */ Xint md(argc, argv) Xint argc; Xchar **argv; X{ X register int status, s; X X status = 0; X while(--argc) X { X ++argv; X if(( s = Dcreate(*argv))) X { X status |= s; X fprintf(STDERR,"Could not create %s\n", *argv); X } X } X X return status; X} X X/* X * Remove directories X */ Xint rd(argc, argv) Xint argc; Xchar **argv; X{ X register int status, s; X X status = 0; X while(--argc) X { X ++argv; X if(( s = Ddelete(*argv))) X { X status |= s; X fprintf(STDERR,"Could not delete %s\n", *argv); X } X } X X return status; X} X X X/* X * Allocate memory with error check X * X */ Xchar *myalloc(size) Xunsigned int size; X{ X register char *m; X extern char *malloc(); X X if((m = malloc(size)) == (char *)NULL) X { X fprintf(STDERR,"Out of Memory\nSorry, cannot continue\n"); X exit(1); X } X X return m; X} X X/* X * Put out help X */ Xint hhelp() X{ X register int i; X X#ifdef REMOTE X fprintf(STDERR,"\n\t\t\t Available Commands \n\n"); X#else X fprintf(STDERR,"\n\t\t\t \033p Available Commands \033q\n\n"); X#endif X for(i = 0; comtab[i].command != (char *)NULL; i++) X { X fprintf(STDERR,"\t%s\t%s\n", comtab[i].command, X comtab[i].synopsis); X } X fprintf(STDERR,"\n\tor hit <RETURN> to exit to terminal emulator\n\n"); X return 0; X X} X X/* X * Lower case string X */ Xchar *alltolower(s) Xregister char *s; X{ X register char *p; X X for(p = s; *p != '\0'; p++) X { X if(isupper(*p)) X *p = tolower(*p); X } X return s; X} X X/* X * return the base filename, given (potentially) a pathname X */ Xchar *basename(s) Xregister char *s; X{ X register char *p; X extern char *rindex(); X X if((p = rindex(s, '\\')) == (char *)NULL) X { X if((p = rindex(s, ':')) == (char *)NULL) X return s; X else X return ++p; X } X return ++p; X} X X#ifdef RECURSE Xint doszf(argc, argv) Xint argc; Xchar **argv; X{ X extern int expandargs(); X#ifdef DDEBUG Xint i; Xprintf("doszf: argc %d\n", argc); Xfor(i = 0; i < argc; i++) X printf("%s ", argv[i]); Xprintf("\n\n"); X#endif X X return(expandargs(dosz, argc, argv)); X} X X#include "expandar.c" X X#endif X X#ifdef REMOTE X/* X * Read a line from the Aux port X * X */ X XCconraux(l) Xchar *l; X{ X register int c; X register int count; X register char *p; X X p = &l[2]; X count = 0; X X while((c = get_a_c()) != '\n') X { X *p++ = c; X count++; X } X l[1] = count; X} X Xstatic char _chr_buf[128]; Xstatic int _n_chr = 0; Xstatic char *_next_chr = &_chr_buf[0]; Xstatic char *_next_avail = &_chr_buf[0]; X Xint get_a_c() X{ X register int c; X X if(_n_chr > 0) X { X _n_chr--; X return(*_next_avail++); X } X X _n_chr = 0; X _next_avail = &_chr_buf[0]; X _next_chr = &_chr_buf[0]; X X while( ((c = Bconin(1) & 0x7fff) != '\r') && (c != '\n')) X { X if((c == '\003') || (c == '\025')) X { X while(_n_chr-- > 0) X wr_modem("\b \b"); X _n_chr = 0; X _next_avail = &_chr_buf[0]; X _next_chr = &_chr_buf[0]; X X } X X if((c == '\b') || (c == '\177')) X { X if(_n_chr > 0) X { X _next_chr--; X _n_chr--; X wr_modem("\b \b"); X } X } X else X { X *_next_chr++ = c; X _n_chr++; X Bconout(1, c); X } X } X X *_next_chr = '\n'; X return(*_next_avail++); X} X#endif /* REMOTE */ X X/* -eof- */ SHAR_EOF chmod 0600 TRANSFER.C || echo "restore of TRANSFER.C fails" echo "x - extracting TYME.C (Text)" sed 's/^X//' << 'SHAR_EOF' > TYME.C && X/* X * Time conversions Module X * X * Jwahar Bammi X * usenet: mandrill!bammi@{decvax,sun}.UUCP X * csnet: bammi@mandrill.ces.CWRU.edu X * arpa: bammi@mandrill.ces.CWRU.edu X * CompuServe: 71515,155 X */ X X#include "config.h" X#include <stdio.h> X X X/* X * days in a given year X */ X#define days_in_year(Y) (leap(Y) ? 366 : 365) X X/* # of days / month in a normal year */ Xstatic unsigned int md[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; X Xstatic int leap (y) Xint y; X{ X y += 1900; X if ((y % 400) == 0) X return (1); X if ((y % 100) == 0) X return (0); X return ((y % 4) == 0); X} X X/* Return the number of days between Jan 1, Given Year and the given X * broken-down time. X */ X Xstatic unsigned long ndays (since, year, month, day) Xunsigned int year, month, day; X{ X register unsigned long n = day; X register unsigned int m, y; X X for (y = since; y < year; y++) X { X n += 365; X if (leap (y)) n++; X } X for (m = 0; m < (month-1); m++) X n += md[m] + ( ((m == 1) && leap(y))? 1 : 0); X X return (n); X} X X/* Convert a broken-down time into seconds X * X */ X Xunsigned long tm_to_time (base_year, year, month, day, hours, mins, secs) Xunsigned int base_year, year, month, day, hours, mins, secs; X{ X register unsigned long t; X extern unsigned long ndays(); X X t = (ndays(base_year, year, month, day) - 1L) * (unsigned long)86400L X + hours * (unsigned long)3600L + mins * (unsigned long)60L + secs; X X return t; X} X X/* X * Convert ST time to Unix time X * X */ Xunsigned long st2unix(time, date) Xunsigned int time, date; X{ X extern unsigned long tm_to_time(); X X unsigned int yr = ((date >> 9) & 0x007f) + 80; /* dissect the date */ X unsigned int mo = (date >> 5) & 0x000f; X unsigned int dy = date & 0x1f; X X unsigned int hr = (time >> 11) & 0x001f; /* dissect the time */ X unsigned int mm = (time >> 5) & 0x003f; X unsigned int ss = (time & 0x001f) * 2; X X#ifdef SDEBUG X printf("%d/%d/%d %d:%d:%d\n", mo, dy, yr,hr, mm, ss); X#endif X return (tm_to_time(70, yr, mo, dy, hr, mm, ss) - X (unsigned long)GMTDIFF); X} X X/* X * Convert Unix Time to ST Time X * X */ Xvoid unix2st(Unix, time, date) Xunsigned long Unix; Xunsigned int *date, *time; X{ X long stbase; X unsigned int hours, yrs, day, months, mins, seconds, t; X long days, secs; X extern unsigned long tm_to_time(); X X#ifdef DEBUG Xprintf("\n\nUnix Time %ld\n", Unix); X#endif X X X if((Unix - tm_to_time(70, 80, 0, 0, 0, 0, 0)) <= 0) /* base 1980 */ X { X /* thats before St's time */ X *time = 0; X *date = (1 << 5) | 1; /* Jan 1, 1980 00:00:00 GMT */ X#ifdef DEBUG Xprintf("Before my time\n"); X#endif X return; X } X X stbase = Unix; /* do from base year 1970 */ X X days = stbase / 86400L; /* 3600*24 */ X secs = stbase % 86400L + GMTDIFF; X if(secs < 0) /* previous day here */ X { X days -= 1; X secs += 86400L; X } X X /* extract hrs : mins : seconds */ X hours = secs / 3600; X secs = secs - (hours * 3600); X mins = secs / 60; X seconds = secs - (mins * 60); X seconds &= ~1L; /* ST has 2 sec resolution */ X X /* get the year and day of the year */ X for(t = 70; days >= days_in_year(t); t++) X days -= days_in_year(t); X yrs = t; X day = days; X X /* get the month */ X if(days_in_year(yrs) == 366) X md[1] = 29; X X for(t = 0; day >= md[t]; t++) X day -= md[t]; X X md[1] = 28; X day = day + 1; X months = t + 1; X X#ifdef DEBUG Xprintf("%d/%d/%d %d:%d:%d\n", months, day, yrs, hours, mins, seconds); X#endif X X yrs -= 80; X *date = (((yrs & 0x007f) << 9) | ((months & 0x000f) << 5) X | (day & 0x001f)); X X *time = (((hours & 0x001f) << 11) | ((mins & 0x003f) << 5) X | (seconds & 0x001e)); X} X X#ifdef TEST X#include <stdio.h> X#include <osbind.h> X Xmain() X{ X unsigned int time, date; X unsigned long Unix; X extern unsigned long st2unix(); X X time = Tgettime(); X date = Tgetdate(); X Unix = st2unix(time, date); X X printd(time, date); X printf("Unix Time %ld\n", Unix); X X unix2st(Unix, &time, &date); X printd(time, date); X} X Xprintd(time, date) Xunsigned int time, date; X{ X X unsigned int yr = ((date >> 9) & 0x007f) + 80; /* dissect the date */ X unsigned int mo = (date >> 5) & 0x000f; X unsigned int dy = date & 0x1f; X X unsigned int hr = (time >> 11) & 0x001f; /* dissect the time */ X unsigned int mm = (time >> 5) & 0x003f; X unsigned int ss = (time & 0x001f) * 2; X X printf("%d/%d/%d\t%d:%d:%d\n", mo, dy, yr, hr, mm, ss); X} X#endif /* TEST */ X X/* -eof- */ SHAR_EOF chmod 0600 TYME.C || echo "restore of TYME.C fails" echo "x - extracting UTIL.C (Text)" sed 's/^X//' << 'SHAR_EOF' > UTIL.C && X/* X * Utilities Module X * X * Jwahar Bammi X * usenet: mandrill!bammi@{decvax,sun}.UUCP X * csnet: bammi@mandrill.ces.CWRU.edu X * arpa: bammi@mandrill.ces.CWRU.edu X * CompuServe: 71515,155 X */ X X X#include "config.h" X#include "zmdm.h" X X#ifndef Vsync /* Atari forgot these in osbind.h */ X#define Vsync() xbios(37) X#endif X X#define GOTO(r,c) EscSeq('Y');Bconout(2, r+040);Bconout(2, c+040) X X /* External Variables */ Xlong pr_time = 0L; /* Present time (200 Hz) */ X X#ifndef STANDALONE X#ifndef REMOTE Xextern int *aline_addr; /* Ptr to base of Aline variables */ Xextern long *ms_ptr; /* pointer to my screen memory aligned to a 256 X byte boundary */ X X /* Globals */ Xstatic char *hs_ptr; /* pointer to his screen memory */ Xstatic int x_saved, y_saved; /* Saved cursor position */ X#endif X#endif X Xstatic long *hz_200 = (long *)0x000004ba; /* Yes the Hitch Hikers */ X /* Guide is wrong!! */ X X/* X * rd_time() - read the value of the systems 200 Hz counter X * must be called in Super Mode else you get X * what you deserve - MUSHROOMS!! X */ Xvoid rd_time() X{ X pr_time = *hz_200; X} X X#ifndef STANDALONE X/* X * my_screen() - Start using my screen memory X * for all output. X * X */ Xvoid my_screen() X{ X#ifndef REMOTE X /* The cursor position has been saved prior to calling this routine */ X x_saved = aline_addr[-14]; X y_saved = aline_addr[-13]; X X /* save his screen memory pointer */ X hs_ptr = (char *)Logbase(); X X /* switch to my display memory */ X Setscreen(ms_ptr, ms_ptr, -1); X#else X wr_modem("\r\n\n"); X#endif X} X X Xvoid his_screen() X{ X#ifndef REMOTE X /* switch to his Screen memory, wait for a Vblank, so X * that the Logical Loc == Physical Loc, then pop saved X * cursor */ X Setscreen(hs_ptr, hs_ptr, -1); X Vsync(); X Vsync(); /* starts happening at the last one */ X GOTO(y_saved, x_saved); X#else X wr_modem("\r\n\n"); X#endif X X} X X/* X * hit_key() - wait for the user to hit a key X * X */ Xvoid hit_key() X{ X#ifndef REMOTE X Bconws("\r\n\033pHit Any Key To Continue .....\033q"); X Bconin(2); X Bconws("\r\n"); X#else X wr_modem("\r\nHit Any Key To Continue ....."); X Bconin(1); X wr_modem("\r\n"); X#endif X} X#endif /* STANDALONE */ X X/* X * find the size of a file given its name X */ Xlong filesize(name) Xregister char *name; X{ X extern struct stat statbuf; X X if(Fsfirst(name,(int)(0x01 | 0x020)) != 0) X { X return 0L; X X } X X return statbuf.st_size; X} X X X/* X * Write a string to console X */ XBconws(s) Xregister char *s; X{ X while(*s) X Bconout(2, *s++); X} X X#ifndef STANDALONE X#ifndef REMOTE X#ifndef MANX X#ifndef MWC X X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */ X/* */ X/* ALCYON C dependant, this routine must return the base address of */ X/* of the linea variable block */ X/* */ X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */ X X/* X * return the base address of the line A variables X */ Xint *aaddress() X{ X asm("dc.w $A000"); /* Line A trap - 0000 is init aline */ X /* d0 and a0 now contain the address */ X /* so we can just return and the result X * will be valid X */ X} X X X/* X * Make hi rez screen bios handle 50 lines of 8x8 characters X * X * Adapted to C use from origonal asm posting X * X */ Xhi50() X{ X /* Switch to 50 lines display */ X X asm(".dc.w $a000"); /* get the important pointers */ X X asm("move.l 04(a1),a1"); /* a1 -> 8x8 font header */ X X asm("move.l 72(a1),-$0A(a0)"); /* v_off_ad <- 8x8 offset table addr */ X asm("move.l 76(a1),-$16(a0)"); /* v_fnt_ad <- 8x8 font data addr */ X X asm("move.w #008,-$2E(a0)"); /* v_cel_ht <- 8 8x8 cell height */ X asm("move.w #049,-$2A(a0)"); /* v_cel_my <- 49 maximum cell "Y" */ X asm("move.w #640,-$28(a0)"); /* v_cel_wr <- 640 offset to cell Y+1 */ X X} X X/* X * Make hi rez screen bios handle 25 lines of 8x16 characters X * X */ Xhi25() X{ X X /* Switch to 25 lines display */ X X X asm(".dc.w $a000"); /* get the important pointers */ X X asm("move.l 08(a1),a1"); /* a1 -> 8x16 font header */ X X asm("move.l 72(a1),-$0A(a0)"); /* v_off_ad <- 8x16 offset table addr */ X asm("move.l 76(a1),-$16(a0)"); /* v_fnt_ad <- 8x16 font data addr */ X X asm("move.w #0016,-$2E(a0)"); /* v_cel_ht <- 16 8x16 cell height */ X asm("move.w #0024,-$2A(a0)"); /* v_cel_my <- 24 maximum cell "Y" */ X asm("move.w #1280,-$28(a0)"); /* v_cel_wr <- 1280 vertical byte offset */ X} X X#else X X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */ X/* */ X/* MWC dependant, this routine must return the base address of */ X/* of the linea variable block */ X/* */ X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */ X#include <linea.h> X/* X * return the base address of the line A variables X */ X Xint *aaddress() X{ X linea0(); /* Init LineA - dumps returned values into la_init */ X return (int *)(la_init.li_a0); /* Return address of Parameter Block */ X} X X /* Mark Williams C */ X /* See file hi5025.s */ X /* for functions hi50() */ X /* and hi25() */ X#endif /* MWC */ X#endif /* MANX */ SHAR_EOF echo "End of part 5" echo "File UTIL.C is continued in part 6" echo "6" > s2_seq_.tmp exit 0