diff --git a/components/utilities/ZMODEM/RBSB.C b/components/utilities/ZMODEM/RBSB.C deleted file mode 100644 index 2a1394e273..0000000000 --- a/components/utilities/ZMODEM/RBSB.C +++ /dev/null @@ -1,24 +0,0 @@ -/* -rev 05-12-86 - * mode function and most of the rest of the system dependent - * stuff for rb.c and sb.c This file is #included so the includer - * can set parameters such as HOWMANY. - */ - -int iofd = 0; /* File descriptor for ioctls & reads */ - -/* - * mode(n) - * 2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g option - * 1: save old tty stat, set raw mode - * 0: restore original tty mode - */ -int mode(int n) -{ - return 0; -} - -int sendbrk() -{ - //ioctl(iofd, TCSBRK, 0); - return 0; -} diff --git a/components/utilities/ZMODEM/RZ.1 b/components/utilities/ZMODEM/RZ.1 deleted file mode 100644 index a0869b8c36..0000000000 --- a/components/utilities/ZMODEM/RZ.1 +++ /dev/null @@ -1,269 +0,0 @@ -'\" Revision Level -'\" Last Delta 05-19-86 -.TH RZ 1 OMEN -.SH NAME -rb, rz \- XMODEM, YMODEM, ZMODEM (Batch) file receive -.SH SYNOPSIS -.B rz -.RB [\- "\ 1bquv" ] -.br -.B rb -.RB [\- "\ 1bquv" ] -.br -.B rz -.RB [\- "\ 1bcquv" ] -.I file -.br -.RB [ \- ][ v ] rzCOMMAND -.SH DESCRIPTION -This program uses error correcting protocol to receive -files over a serial port from a variety of programs running under -PC-DOS, CP/M, -.SM Unix, -and other operating systems. - -The first form of -.B rz -(Receive Batch) -receives files with ZMODEM batch protocol. -If the sending program does not support ZMODEM, -.B rz -steps down to YMODEM protocol -after 50 seconds. -This delay can be eliminated by calling the program as -.I rb . - -.B Rb -accepts either standard 128 byte sectors or -1024 byte sectors -(YAM -.B -k -option). -The user should determine experimentally -the conditions under which use of 1k blocks -actually improves throughput without causing -problems. - -Normally, the file contents are converted to -.SM Unix -conventions by stripping carriage returns and all characters -beginning with Control Z (CP/M end of file). -If the raw pathname ends in -".A", -".ARC", -".CCC", -".CL", -".CMD", -".COM", -".CRL", -".DAT", -".DIR", -".EXE", -".O", -".OBJ", -".OVL", -".PAG", -".REL", -".SAV", -".SUB", -".SWP", -".SYS", -".TAR", -".UTL", -".a", -".o", -".tar", -or if the first packet contains -data that suggest a binary file -(parity bits or characters in the range 000 to 006 before the first ^Z), -or if the file mode is transmitted and the 0100000 -bit is set, that file will be received in binary mode anyway. -Otherwise, -if the raw pathname ends in .MSG, or .TXT, an existing file will -be appended to rather than replaced. - -If extended file information (file length, etc.) -is received, -the file length controls the number of bytes written to -the output dataset (YMODEM only), -and the modify time and file mode -(iff non zero) -are set accordingly. - -If no extended file information is received, -slashes in the pathname are changed to underscore, -and any trailing period in the pathname is eliminated. -This conversion is useful for files received from CP/M systems. -Normally, each file name is converted to lower case -unless it contains one or more lower case letters. - - -The second form of -.B rz -receives a single -.I file -with XMODEM protocol. -The user must supply the file name to both sending and receiving programs. - - -The third form of -.B rz -is invoked as -.B rzCOMMAND -(with an optional leading \- as generated by login(1)). -For each received file, -rz will pipe the file to ``COMMAND filename'' -where filename is the name of the transmitted file -with the file contents as standard input. - -Each file transfer is acknowledged when COMMAND exits with 0 status. -A non zero exit status terminates transfers. - -A typical use for this form is -.I rzrmail -which calls rmail(1) -to post mail to the user specified by the transmitted file name. -For example, sending the file "caf" from a PC-DOS system to -.I rzrmail -on a -.SM Unix -system -would result in the contents of the DOS file "caf" being mailed to user "caf". - -On some -.SM Unix -systems, the login directory must contain a link to -COMMAND as login sets SHELL=rsh which disallows absolute -pathnames. -If invoked with a leading ``v'', -.B rz -will report progress to LOGFILE. -The following entry works for -.SM Unix -3.0: -.ce -rzrmail::5:1::/bin:/usr/local/rzrmail -If the SHELL environment variable includes -.I "rsh" -or -.I "rksh" -(restricted shell), -rz will not accept absolute pathnames -or references to a parent directory, -will not modify an existing file, and -removes any files received in error. - -If -.B rz -is invoked with stdout and stderr to different datasets, -Verbose is set to 2, causing frame by frame progress reports -to stderr. -This may be disabled with the -.B q -option. - -.PP -The meanings of the available options are: -.PP -.PD 0 -.TP -.B 1 -Use file descriptor 1 for ioctls and reads (Unix only). -By default, file descriptor 0 is used. -This option allows -.B rz -to be used with the -.I cu -~$ -command. -.TP -.B b -Transfer all files in binary -(tell it like it is) -mode. -This option disables file append. -.TP -.B c -Request 16 bit CRC -(XMODEM file transfers default to 8 bit checksum). -Batch transfers use 16 bit CRC. -.TP -.B D -Output file data to /dev/null; for testing. -.TP -.B q -Quiet suppresses verbosity. -.TP -.B v -Verbose -causes a list of file -names to be appended to -/tmp/rzlog . -More v's generate more output. -.TP -.B u -Retain upper case letters in file names. -.PD -.SH EXAMPLES -.ne 6 -.RE -(Pro-YAM command) -.RS -.I -.br -YAM Command: -.I "sz *.h *.c" -.br -(This automatically invokes -.I rz -on the connected system.) -.RE -.SH SEE ALSO -ZMODEM.DOC, -YMODEM.DOC, -IMP(CP/M), -cu(1), -Professional-YAM manual, -sz(omen), -usq(omen), -undos(omen) - -Compile time options required -for various operating systems are described in the -source file. -.SH BUGS -Pathnames are restricted to 127 characters. -In XMODEM single file mode, the pathname given on the command line -is still processed as described above. -The CR/LF to NL translation merely deletes CR\'s; -undos(omen) performs a more intelligent translation. -.SH "VMS VERSION" -Some of the #includes with file names enclosed with angle brackets <> -may need to have the angle brackets changed to "", or vice versa. - -The VMS version does not set binary mode according to the incoming -file type. -Non binary file processing consists of stripping all characters beginning -with CPMEOF (^Z). - -The VMS version does not set the file time. - -At high speeds, -VMS sometimes loses incoming characters, resulting in retries -and degradation of throughput. - -The mysterious -VMS C Standard I/O Package and RMS may interact to modify -file contents unexpectedly. - -The VMS version does not support invocation as -.B rzCOMMAND . -ZMODEM has not yet been implemented on the VMS version. -.SH "ZMODEM CAPABILITIES" -.B Rz -supports incoming ZMODEM binary (-b), ASCII (-a), and append (-+) -requests, and ZMODEM command execution. -.SH FILES -rz.c, rbsb.c, zm.c, zmodem.h source files. - -/tmp/rzlog stores debugging output generated with -vv option. diff --git a/components/utilities/ZMODEM/RZ.C b/components/utilities/ZMODEM/RZ.C deleted file mode 100644 index fdc1ae247d..0000000000 --- a/components/utilities/ZMODEM/RZ.C +++ /dev/null @@ -1,1104 +0,0 @@ -#define VERSION "1.03 05-18-86" -#define PUBDIR "/usr/spool/uucppublic" - -/*% cc -DNFGVMIN -K -O % -o rz; size rz - * - * rz.c By Chuck Forsberg - * - * cc -O rz.c -o rz USG (3.0) Unix - * cc -O -DV7 rz.c -o rz Unix V7, BSD 2.8 - 4.3 - * - * ln rz rb For either system - * - * ln rz /usr/bin/rbrmail For remote mail. Make this the - * login shell. rbrmail then calls - * rmail(1) to deliver mail. - * - * Unix is a trademark of Western Electric Company - * - * A program for Unix to receive files and commands from computers running - * Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM. - * rz uses Unix buffered input to reduce wasted CPU time. - * - * Iff the program is invoked by rzCOMMAND, output is piped to - * "COMMAND filename" - * - * Some systems (Venix, Coherent, Regulus) may not support tty raw mode - * read(2) the same way as Unix. ONEREAD must be defined to force one - * character reads for these systems. Added 7-01-84 CAF - * - * Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF - * - * NFGVMIN Added 1-13-85 CAF for PC-AT Xenix systems where c_cc[VMIN] - * doesn't seem to work (even though it compiles without error!). - * - * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin - */ -#define zperr vfile - -#include "rtthread.h" -#include "finsh.h" -#include "shell.h" -#include"rtdef.h" -#include -#include -#include - - -#define OK 0 -#define FALSE 0 -#define TRUE 1 -#define ERROR (-1) - -#define HOWMANY 133 -int Zmodem=0; /* ZMODEM protocol requested */ -int Nozmodem = 0; /* If invoked as "rb" */ -unsigned Baudrate; -#include "rbsb.c" /* most of the system dependent stuff here */ - - -int fout; - -/* - * Routine to calculate the free bytes on the current file system - * ~0 means many free bytes (unknown) - */ -long getfree() -{ - return(~0L); /* many free bytes ... */ -} - -char *Extensions[] = { -".A", -".ARC", -".CCC", -".CL", -".CMD", -".COM", -".CRL", -".DAT", -".DIR", -".EXE", -".O", -".OBJ", -".OVL", -".PAG", -".REL", -".SAV", -".SUB", -".SWP", -".SYS", -".TAR", -".UTL", -".a", -".arc", -".com", -".dat", -".o", -".obj", -".ovl", -".sys", -".tar", -"" -}; - -/* Ward Christensen / CP/M parameters - Don't change these! */ -#define ENQ 005 -#define CAN ('X'&037) -#define XOFF ('s'&037) -#define XON ('q'&037) -#define SOH 1 -#define STX 2 -#define EOT 4 -#define ACK 6 -#define NAK 025 -#define CPMEOF 032 -#define WANTCRC 0103 /* send C not NAK to get crc not checksum */ -#define TIMEOUT (-2) -#define ERRORMAX 5 -#define RETRYMAX 5 -#define WCEOT (-10) -#define SECSIZ 128 /* cp/m's Magic Number record size */ -#define PATHLEN 257 /* ready for 4.2 bsd ? */ -#define KSIZE 1024 /* record size with k option */ -#define UNIXFILE 0x8000 /* happens to the the S_IFREG file mask bit for stat */ - -int Lastrx; -int Crcflg; -int Firstsec; -int Eofseen; /* indicates cpm eof (^Z) has been received */ -int errors; -int Restricted=0; /* restricted; no /.. or ../ in filenames */ -int Badclose = 0; /* Error on last close */ -#define ONEREAD 1 -#ifdef ONEREAD -/* Sorry, Regulus and some others don't work right in raw mode! */ -int Readnum = 1; /* Number of bytes to ask for in read() from modem */ -#else -int Readnum = KSIZE; /* Number of bytes to ask for in read() from modem */ -#endif - -#define DEFBYTL 2000000000L /* default rx file size */ -long Bytesleft; /* number of bytes of incoming file left */ -long Modtime; /* Unix style mod time for incoming file */ -short Filemode; /* Unix style mode for incoming file */ -char Pathname[PATHLEN]; -char *Progname; /* the name by which we were called */ - -int Batch=0; -int Wcsmask=0377; -int Topipe=0; -int MakeLCPathname=TRUE; /* make received pathname lower case */ -int Verbose=0; -int Quiet=0; /* overrides logic that would otherwise set verbose */ -int Nflag = 0; /* Don't really transfer files */ -int Rxbinary=FALSE; /* receive all files in bin mode */ -int Thisbinary; /* current file is to be received in bin mode */ -int Blklen; /* record length of received packets */ -char secbuf[KSIZE]; -char linbuf[KSIZE]; -int Lleft=0; /* number of characters in linbuf */ - -char zconv; /* ZMODEM file conversion request */ -char zmanag; /* ZMODEM file management request */ -char ztrans; /* ZMODEM file transport request */ - - -int purgeline(void); -unsigned short int updcrc(int c, int crc); -int procheader(char *name); -int report(int sct); -int tryz(void); -int rzfiles(void); -int rzfile(void); -int closeit(void); -int zmputs(char *s); -int ackbibi(void); -int wcreceive(int argc, char **argp); -int wcrxpn(char *rpn); -int wcrx(void); -int wcgetsec(char *rxbuf, int maxtime); -int readline(int timeout); -int putsec(char *buf, int n); -int sendline(int c); -int xsendline(int c); -int log(const char *s,...); -int bttyout(int c); -int flushmo(void); -int canit(void); -int sys2(char *s); -int exec2(char *s); - -#include "zm.c" - - -/* called by signal interrupt or terminate to clean things up */ -int bibi(int n) -{ - if (Zmodem) - zmputs(Attn); - canit(); - mode(0); - return 0; -} - -int zrmain(void) -{ - if (wcreceive(0, 0)==ERROR) { - canit(); - zperr("received error,exit\n"); - return 1; - } - return 0; -} - - -int usage(void) -{ - //rt_kprintf("%s %s for %s by Chuck Forsberg\n", - // Progname, VERSION, OS); - //rt_kprintf("Usage: rz [-1buv] (ZMODEM Batch)\n"); - //rt_kprintf("or rb [-1buv] (YMODEM Batch)\n"); - //rt_kprintf("or rz [-1bcv] file (XMODEM)\n"); - //rt_kprintf(" -1 For cu(1): Use fd 1 for input\n"); - //rt_kprintf(" -b Binary transfer for all files\n"); - //rt_kprintf(" -u Allow all UPPER CASE names\n"); - //rt_kprintf(" -v Verbose more v's give more info\n"); - //rt_kprintf(" -c Use 16 bit CRC (XMODEM)\n"); - //exit(1); - return 0; -} -/* - * Debugging information output interface routine - */ -/* VARARGS1 */ -void vfile(const char *fmt,...) -{ - return; -} - -/* - * Let's receive something already. - */ -int wcreceive(int argc, char **argp) -{ - int c; - - if (Batch || argc==0) { - Crcflg=(Wcsmask==0377); - if ( !Quiet) - rt_kprintf("\nrz: ready...\n"); - c = tryz(); - if (c) { - if (c == ZCOMPL) - return OK; - if (c == ERROR) - goto fubar; - c = rzfiles(); - if (c) - goto fubar; - } else { - for (;;) { - if (wcrxpn(secbuf)== ERROR) - goto fubar; - if (secbuf[0]==0) - return OK; - if (procheader(secbuf) == ERROR) - goto fubar; - if (wcrx()==ERROR) - goto fubar; - } - } - } else { - Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L; - - strcpy(Pathname, *argp); - //checkpath(Pathname); - //rt_kprintf(stderr, "\nrz: ready to receive %s ", Pathname); - //if ((fout=fopen(Pathname, "w")) == NULL) - // return ERROR; - if (wcrx()==ERROR) - goto fubar; - } - return OK; -fubar: - canit(); - if (Topipe && fout) { - close(fout); return ERROR; - } - if (fout) - close(fout); - if (Restricted) { - unlink(Pathname); - rt_kprintf("\r\nrz: %s removed.\r\n", Pathname); - } - return ERROR; -} - - -/* - * Fetch a pathname from the other end as a C ctyle ASCIZ string. - * Length is indeterminate as long as less than Blklen - * A null string represents no more files (YMODEM) - */ -int wcrxpn(char *rpn) -{ - int c; - -#ifdef NFGVMIN - readline(1); -#else - purgeline(); -#endif - -et_tu: - Firstsec=TRUE; Eofseen=FALSE; - sendline(Crcflg?WANTCRC:NAK); - Lleft=0; /* Do read next time ... */ - while ((c = wcgetsec(rpn, 100)) != 0) { - log( "Pathname fetch returned %d\n", c); - if (c == WCEOT) { - sendline(ACK); - Lleft=0; /* Do read next time ... */ - readline(1); - goto et_tu; - } - return ERROR; - } - sendline(ACK); - return OK; -} - -/* - * Adapted from CMODEM13.C, written by - * Jack M. Wierda and Roderick W. Hart - */ - -int wcrx(void) -{ - register int sectnum, sectcurr; - register char sendchar; - register char *p; - int cblklen; /* bytes to dump this block */ - - Firstsec=TRUE;sectnum=0; Eofseen=FALSE; - sendchar=Crcflg?WANTCRC:NAK; - - for (;;) { - sendline(sendchar); /* send it now, we're ready! */ - Lleft=0; /* Do read next time ... */ - sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130); - report(sectcurr); - if (sectcurr==(sectnum+1 &Wcsmask)) { - - if (sectnum==0 && !Thisbinary) { - p=secbuf; sectcurr=Blklen; - if (*p == 032) /* A hack for .arc files */ - goto binbin; - for (; *p != 032 && --sectcurr>=0; ++p) - if (*p < 07 || (*p & 0200)) { -binbin: - Thisbinary++; - if (Verbose) - rt_kprintf("Changed to BIN\n"); - break; - } - } - sectnum++; - cblklen = Bytesleft>Blklen ? Blklen:Bytesleft; - if (putsec(secbuf, cblklen)==ERROR) - return ERROR; - if ((Bytesleft-=cblklen) < 0) - Bytesleft = 0; - sendchar=ACK; - } - else if (sectcurr==(sectnum&Wcsmask)) { - log( "Received dup Sector\n"); - sendchar=ACK; - } - else if (sectcurr==WCEOT) { - if (closeit()) - return ERROR; - sendline(ACK); - Lleft=0; /* Do read next time ... */ - return OK; - } - else if (sectcurr==ERROR) - return ERROR; - else { - log( "Sync Error\n"); - return ERROR; - } - } -} - -/* - * Wcgetsec fetches a Ward Christensen type sector. - * Returns sector number encountered or ERROR if valid sector not received, - * or CAN CAN received - * or WCEOT if eot sector - * time is timeout for first char, set to 4 seconds thereafter - ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK ************** - * (Caller must do that when he is good and ready to get next sector) - */ - -int wcgetsec(char *rxbuf, int maxtime) -{ - int checksum, wcj, firstch; - unsigned short oldcrc; - char *p; - int sectcurr; - - for (Lastrx=errors=0; errors=0; ) { - if ((firstch=readline(1)) < 0) - goto bilge; - oldcrc=updcrc(firstch, oldcrc); - checksum += (*p++ = firstch); - } - if ((firstch=readline(1)) < 0) - goto bilge; - if (Crcflg) { - oldcrc=updcrc(firstch, oldcrc); - if ((firstch=readline(1)) < 0) - goto bilge; - oldcrc=updcrc(firstch, oldcrc); - if (oldcrc & 0xFFFF) - log("CRC=0%o\n", oldcrc); - else { - Firstsec=FALSE; - return sectcurr; - } - } - else if (((checksum-firstch)&Wcsmask)==0) { - Firstsec=FALSE; - return sectcurr; - } - else - log( "Checksum Error\n"); - } - else - log("Sector number garbled 0%o 0%o\n", - sectcurr, oldcrc); - } - /* make sure eot really is eot and not just mixmash */ -#ifdef NFGVMIN - else if (firstch==EOT && readline(1)==TIMEOUT) - return WCEOT; -#else - else if (firstch==EOT && Lleft==0) - return WCEOT; -#endif - else if (firstch==CAN) { - if (Lastrx==CAN) { - log("Sender CANcelled\n"); - return ERROR; - } else { - Lastrx=CAN; - continue; - } - } - else if (firstch==TIMEOUT) { - if (Firstsec) - goto humbug; -bilge: - log( "Timeout\n"); - } - else - log( "Got 0%o sector header\n", firstch); - -humbug: - Lastrx=0; - while(readline(1)!=TIMEOUT) - ; - if (Firstsec) { - sendline(Crcflg?WANTCRC:NAK); - Lleft=0; /* Do read next time ... */ - } else { - maxtime=40; sendline(NAK); - Lleft=0; /* Do read next time ... */ - } - } - /* try to stop the bubble machine. */ - canit(); - return ERROR; -} - -/* - * This version of readline is reasoably well suited for - * reading many characters. - * (except, currently, for the Regulus version!) - * - * timeout is in tenths of seconds - */ -int readline(int timeout) -{ - static char *cdq; /* pointer for removing chars from linbuf */ - static char data_buffer[8]; - if (--Lleft >= 0) - { - return (*cdq++ & Wcsmask); - } - while (1) - { - Lleft = zread(shell->device, 0, data_buffer, 1); - if (Lleft) - { - Lleft = Lleft; - cdq = &data_buffer[0]; - break; - } - } - - if (Lleft < 1) - return TIMEOUT; - --Lleft; - return (*cdq++ & Wcsmask); -} - - - -/* - * Purge the modem input queue of all characters - */ -int purgeline(void) -{ - - Lleft = 0; -#ifdef USG - ioctl(iofd, TCFLSH, 0); -#else - lseek(iofd, 0L, 2); -#endif - return 0; -} - -/* - * Update CRC CRC-16 used by XMODEM/CRC, YMODEM, and ZMODEM. - * Note: Final result must be masked with 0xFFFF before testing - * More efficient table driven routines exist. - */ -unsigned short int -updcrc(int c, int crc) -{ - int count; - - for (count=8; --count>=0;) { - if (crc & 0x8000) { - crc <<= 1; - crc += (((c<<=1) & 0400) != 0); - crc ^= 0x1021; - } - else { - crc <<= 1; - crc += (((c<<=1) & 0400) != 0); - } - } - return crc; -} - -/* - * Process incoming file information header - */ -int procheader(char *name) -{ - char *openmode, *ptr; - unsigned char i; - char fname[100]; - /* set default parameters */ - openmode = "w"; Thisbinary=Rxbinary; - - /* - * Process ZMODEM remote file management requests - */ - if (zconv == ZCNL) /* Remote ASCII override */ - Thisbinary = 0; - if (zconv == ZCBIN) /* Remote Binary override */ - ++Thisbinary; - else if (zmanag == ZMAPND) - openmode = "a"; - openmode = openmode; - Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L; - for(i=0;i<100;i++) fname[i] = 0; - for (i=1,ptr=name;i=0; ) - write(fout,p++,1); - } - else { - if (Eofseen) - return OK; - for (p=buf; --n>=0; ++p ) { - if ( *p == '\r') - continue; - if (*p == CPMEOF) { - Eofseen=TRUE; return OK; - } - write(fout,p,1); - } - } - return OK; -} - -/* - * Send a character to modem. Small is beautiful. - */ -int sendline(int c) -{ - zwrite(c); - return 0; -} - -int xsendline(int c) -{ - sendline(c); - return 0; -} - -int flushmo(void) -{ - return 0; -} - - - - -/* - * substr(string, token) searches for token in string s - * returns pointer to token within string if found, NULL otherwise - */ -char * -substr(char *s, char *t) -{ - register char *ss,*tt; - /* search for first char of token */ - for (ss=s; *s; s++) - if (*s == *t) - /* compare token with substring */ - for (ss=s,tt=t; ;) { - if (*tt == 0) - return s; - if (*ss++ != *tt++) - break; - } - return NULL; -} - -/* - * Log an error - */ -/*VARARGS1*/ -int log(const char *s,...) -{ - return 0; -} - -/* send cancel string to get the other end to shut up */ -int canit(void) -{ /* - static char canistr[] = { - ZPAD,ZPAD,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0 - }; - */ - //printf(canistr); - Lleft=0; /* Do read next time ... */ - //fflush(stdout); - return 0; -} - - -/* - * Return 1 iff stdout and stderr are different devices - * indicating this program operating with a modem on a - * different line - */ -int fromcu(void) -{ - struct stat a, b; - fstat(1, &a); - fstat(2, &b); - //return (a.st_rdev != b.st_rdev); - return 0; -} - -int report(int sct) -{ - //if (Verbose>1) - // rt_kprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r'); - return 0; -} - -/* - * If called as [-][dir/../]vrzCOMMAND set Verbose to 1 - * If called as [-][dir/../]rzCOMMAND set the pipe flag - * If called as rb use YMODEM protocol - */ -int chkinvok(char *s) -{ - register char *p; - - p = s; - while (*p == '-') - s = ++p; - while (*p) - if (*p++ == '/') - s = p; - if (*s == 'v') { - Verbose=1; ++s; - } - Progname = s; - if (s[0]=='r' && s[1]=='b') - Nozmodem = TRUE; - if (s[2] && s[0]=='r' && s[1]=='b') - Topipe=TRUE; - if (s[2] && s[0]=='r' && s[1]=='z') - Topipe=TRUE; - return 0; -} - -/* - * Totalitarian Communist pathname processing - */ -int checkpath(char *name) -{ -// if (Restricted) { - // if (fopen(name, "r") != NULL) { - // canit(); - //rt_kprintf(stderr, "\r\nrz: %s exists\n", name); - // bibi(); - // } - /* restrict pathnames to current tree or uucppublic */ - // if ( substr(name, "../") - // || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) { - // canit(); - //rt_kprintf(stderr,"\r\nrz:\tSecurity Violation\r\n"); - // bibi(); - // } -// } - return 0; -} - -/* - * Initialize for Zmodem receive attempt, try to activate Zmodem sender - * Handles ZSINIT frame - * Return ZFILE if Zmodem filename received, -1 on error, - * ZCOMPL if transaction finished, else 0 - */ -int tryz(void) -{ - int n; - int cmdzack1flg; - - if (Nozmodem) /* Check for "rb" program name */ - return 0; - Rxtimeout = 100; - - - for (n=5; --n>=0; ) { - /* Set buffer length (0) and capability flags */ - stohdr(0L); - Txhdr[ZF0] = CANFDX|CANOVIO|CANBRK; - zshhdr(Badclose?ZFERR:ZRINIT, Txhdr); -again: - switch (zgethdr(Rxhdr, 0)) { - case ZRQINIT: - continue; - case ZEOF: - continue; - case TIMEOUT: - continue; - case ZFILE: - zconv = Rxhdr[ZF0]; - zmanag = Rxhdr[ZF1]; - ztrans = Rxhdr[ZF2]; - Badclose = FALSE; - if (zrbdata(secbuf, KSIZE) == GOTCRCW) - return ZFILE; - zshhdr(ZNAK, Txhdr); - case ZSINIT: - if (zrbdata(Attn, ZATTNLEN) == GOTCRCW) { - zshhdr(ZACK, Txhdr); - goto again; - } - zshhdr(ZNAK, Txhdr); - continue; - case ZFREECNT: - stohdr(getfree()); - zshhdr(ZACK, Txhdr); - goto again; - case ZCOMMAND: - cmdzack1flg = Rxhdr[ZF0]; - if (zrbdata(secbuf, KSIZE) == GOTCRCW) { - if (cmdzack1flg & ZCACK1) - stohdr(0L); - else - stohdr((long)sys2(secbuf)); - purgeline(); /* dump impatient questions */ - do { - zshhdr(ZCOMPL, Txhdr); - } - while (++errors<10 && zgethdr(Rxhdr,1) != ZFIN); - ackbibi(); - if (cmdzack1flg & ZCACK1) - exec2(secbuf); - return ZCOMPL; - } - zshhdr(ZNAK, Txhdr); goto again; - case ZCOMPL: - goto again; - default: - continue; - case ZFIN: - ackbibi(); return ZCOMPL; - case ZCAN: - return ERROR; - } - } - return 0; -} - -/* - * Receive 1 or more files with ZMODEM protocol - */ -int rzfiles(void) -{ - int c; - - for (;;) { - switch (c = rzfile()) { - case ZEOF: - case ZSKIP: - switch (tryz()) { - case ZCOMPL: - return OK; - default: - return ERROR; - case ZFILE: - break; - } - continue; - default: - return c; - case ERROR: - return ERROR; - } - } -} - -/* - * Receive a file with ZMODEM protocol - * Assumes file name frame is in secbuf - */ -int rzfile(void) -{ - int c, n; - long int rxbytes; - - Eofseen=FALSE; - if (procheader(secbuf) == ERROR) { - zshhdr(ZSKIP, Txhdr); - return ZSKIP; - } - - n = 10; rxbytes = 0l; - - for (;;) { - stohdr(rxbytes); - zshhdr(ZRPOS, Txhdr); -nxthdr: - switch (c = zgethdr(Rxhdr, 0)) { - default: - vfile("rzfile: zgethdr returned %d", c); - return ERROR; - case ZNAK: - case TIMEOUT: - if ( --n < 0) { - vfile("rzfile: zgethdr returned %d", c); - return ERROR; - } - case ZFILE: - continue; - case ZEOF: - if (rclhdr(Rxhdr) != rxbytes) { - continue; - } - if (closeit()) { - Badclose = TRUE; - vfile("rzfile: closeit returned <> 0"); - return ERROR; - } - vfile("rzfile: normal EOF"); - return c; - case ERROR: /* Too much garbage in header search error */ - if ( --n < 0) { - vfile("rzfile: zgethdr returned %d", c); - return ERROR; - } - zmputs(Attn); - continue; - case ZDATA: - n = 10; - if (rclhdr(Rxhdr) != rxbytes) { - zmputs(Attn); - continue; - } -moredata: - switch (c = zrbdata(secbuf, KSIZE)) { - case ZCAN: - vfile("rzfile: zgethdr returned %d", c); - return ERROR; - case ERROR: /* CRC error */ - if ( --n < 0) { - vfile("rzfile: zgethdr returned %d", c); - return ERROR; - } - zmputs(Attn); - continue; - case TIMEOUT: - if ( --n < 0) { - vfile("rzfile: zgethdr returned %d", c); - return ERROR; - } - continue; - case GOTCRCW: - putsec(secbuf, Rxcount); - rxbytes += Rxcount; - stohdr(rxbytes); - zshhdr(ZACK, Txhdr); - goto nxthdr; - case GOTCRCQ: - putsec(secbuf, Rxcount); - rxbytes += Rxcount; - stohdr(rxbytes); - zshhdr(ZACK, Txhdr); - goto moredata; - case GOTCRCG: - putsec(secbuf, Rxcount); - rxbytes += Rxcount; - goto moredata; - case GOTCRCE: - putsec(secbuf, Rxcount); - rxbytes += Rxcount; - goto nxthdr; - } - } - } -} - -/* - * Send a string to the modem, processing for \336 (sleep 1 sec) - * and \335 (break signal) - */ -int zmputs(char *s) -{ - int c; - - while (*s) { - switch (c = *s++) { - case '\336': - //sleep(1); - continue; - case '\335': - sendbrk(); continue; - default: - sendline(c); - } - } - return 0; -} - -/* - * Close the receive dataset, return OK or ERROR - */ -int closeit(void) -{ - if (Topipe) { - if (close(fout)) { - return ERROR; - } - return OK; - } - if (close(fout)==ERROR) { - //rt_kprintf(stderr, "file close ERROR\n"); - return ERROR; - } -// if (Modtime) { -// timep[0] = time(NULL); - // timep[1] = Modtime; - // utime(Pathname, timep); - //} - //if (Filemode) - //chmod(Pathname, (07777 & Filemode)); - return OK; -} - -/* - * Ack a ZFIN packet, let byegones be byegones - */ -int ackbibi(void) -{ - int n; - - vfile("ackbibi:"); - Readnum = 1; - stohdr(0L); - for (n=4; --n>=0; ) { - zshhdr(ZFIN, Txhdr); - for (;;) { - switch (readline(100)) { - case 'O': - readline(1); /* Discard 2nd 'O' */ - /* ***** FALL THRU TO ***** */ - case TIMEOUT: - vfile("ackbibi complete"); - return 0; - default: - break; - } - } - } - return 0; -} - -/* - * Local console output simulation - */ -int bttyout(int c) -{ - //if (Verbose || fromcu) - //putc(c, stderr); - return 0; -} - -/* - * Strip leading ! if present, do shell escape. - */ -int sys2(char *s) -{ - if (*s == '!') - ++s; - return 0; -} -/* - * Strip leading ! if present, do exec. - */ -int exec2(char *s) -{ - if (*s == '!') - ++s; - mode(0); - return 0; -} diff --git a/components/utilities/ZMODEM/RZ.H b/components/utilities/ZMODEM/RZ.H deleted file mode 100644 index 8a4f237114..0000000000 --- a/components/utilities/ZMODEM/RZ.H +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __RZ_H__ -#define __RZ_H__ - -#include "zmodem.h" - - -unsigned short int updcrc(int c, unsigned int crc); -void zmputs(char *s); -int closeit(void); -int sys2(char *s); -int exec2(char *s); -int rzfile(void); -void ackbibi(void); -unsigned int IsAnyLower(char *s); -void usage(void); -static int wcrx(void); -char *substr(char *s, char *t); - -void alrm(void); -void bibi(int n); -int zreceive_main(void); -void usage(void); -static int wcreceive(unsigned int argc, char **argp); -static int wcrxpn(char *rpn); -static int wcgetsec(char *rxbuf, int maxtime); -int readline(int timeout); -unsigned short int updcrc(int c, unsigned int crc); -int procheader(char *name); -int purgeline(void); -int putsec(char *buf, int n); -int readline(int timeout); -unsigned short int updcrc(int c, unsigned int crc); - -int bttyout(int c); -int sys2(char *s); -int exec2(char *s); -void sendline(char c); -void xsendline(char c); -void canit(void); -int tryz(void); -int rzfiles(void); - - -extern int Verbose; -extern int iofd; /* File descriptor for ioctls & reads */ -extern int Zmodem; /* ZMODEM protocol requested */ -extern int Nozmodem; /* If invoked as "rb" */ -/* Ward Christensen / CP/M parameters - Don't change these! */ -#define ENQ 005 -#define CAN ('X'&037) -//#define XOFF ('s'&037) -//#define XON ('q'&037) -#define SOH 1 -#define STX 2 -#define EOT 4 -#define ACK 6 -#define NAK 025 -#define CPMEOF 032 -#define WANTCRC 0103 /* send C not NAK to get crc not checksum */ -#define TIMEOUT (-2) -#define ERRORMAX 5 -#define RETRYMAX 5 -#define WCEOT (-10) -#define SECSIZ 128 /* cp/m's Magic Number record size */ -#define PATHLEN 257 /* ready for 4.2 bsd ? */ -#define KSIZE 1024 /* record size with k option */ -#define UNIXFILE 0x8000 /* happens to the the S_IFREG file mask bit for stat */ -/**************************zm.c **************************/ - - - - - - - - -#endif diff --git a/components/utilities/ZMODEM/SZ.1 b/components/utilities/ZMODEM/SZ.1 deleted file mode 100644 index e5cd56029a..0000000000 --- a/components/utilities/ZMODEM/SZ.1 +++ /dev/null @@ -1,336 +0,0 @@ -'\" Revision Level -'\" Last Delta 5-19-86 -.TH SZ 1 OMEN -.SH NAME -sz \- XMODEM, YMODEM, ZMODEM Batch file Send -.SH SYNOPSIS -sz -.RB [\- +1adfknqTuvy ] -.I file ... -.br -sz -X -.RB [\- 1kquv ] -.I file -.br -sz -.RB [\- 1qv ] -.B "-c COMMAND" -.br -sz -.RB [\- 1qv ] -.B "-i COMMAND" -.SH DESCRIPTION -.B Sz -uses the ZMODEM, YMODEM or XMODEM error correcting protocol to send -one or more files over a serial port to a variety of programs running under -PC-DOS, CP/M, Unix, VMS, and other operating systems. - - -The first form of -.B sz -sends one or more files with ZMODEM or YMODEM batch protocol. -Normally, only the file name part of the pathname is transmitted. -On -.SM Unix -systems, additional information about the file is transmitted. -If the receiving program uses this information, -the transmitted file length controls the exact number of bytes written to -the output dataset, -and the modify time and file mode -are set accordingly. - -Output from another program may be piped to -.B sz -for transmission by specifying the -.B -1 -option and denoting standard input by "-": -.ce -ps -ef | sz - -The program output is transmitted with the filename sPID.sz -where PID is the process ID of the -.B sz -program. -If the environment variable -.B ONAME -is set, that is used instead. -In this case, the Unix command: -.ce -ONAME=con ps -ef|sz -ay - -will send a "file" to the PC-DOS console display. -The -.B -y -bypasses the receiver\'s checking of the output filename. -The -.B -a -causes the receiver to convert Unix newlines to PC-DOS carriage returns -and linefeeds. - -Unix -.B sz -supports -.B YMODEM-g -with "cbreak" tty mode, XON/XOFF flow control, -and the interrupt character set to CAN. -.B YMODEM-g -(Professional-YAM -.B g -option) -increases throughput over error free channels -(direct connection, X.PC, etc.) -by not acknowledging each transmitted sector. - - -The second form of -.B sz -uses the -.B -X -flag to send a single -.I file -with -.B XMODEM -protocol. -The user must supply the file name to both sending and receiving programs. - -Iff -.B sz -is invoked with $SHELL set and iff that variable contains the -string -.I "rsh" -or -.I "rksh" -(restricted shell), sz operates in restricted mode. -Restricted mode restricts pathnames to the current directory and -PUBDIR (usually /usr/spool/uucppublic) and/or subdirectories -thereof. - - -The third form sends a single COMMAND to the receiver for execution. -.B Sz -exits with the COMMAND return value. -If COMMAND includes spaces or characters special to the shell, -it must be quoted. - -The fourth form sends a single COMMAND to the receiver for execution. -.B Sz -exits as soon as the receiver has received the command, before it is executed. - - -If sz is invoked with stdout and stderr to different datasets, -Verbose is set to 2, causing frame by frame progress reports -to stderr. -This may be disabled with the -.B q -option. -.PP -The meanings of the available options are: -.PP -.PD 0 -.TP -.B + -Force the receiver to append transmitted data to an existing file -(ZMODEM only). -.TP -.B 1 -Use file descriptor 1 for ioctls and reads (Unix only). -By default, file descriptor 0 is used. -This option allows -.B sz -to be used with the -.I cu -~$ -command. -.TP -.B a -Convert NL characters in the transmitted file to CR/LF. -This is done by the sender for XMODEM and YMODEM, by the receiver -for ZMODEM. -.TP -.B "c COMMAND" -Send COMMAND to the receiver for execution, return with COMMAND\'s exit status. -.TP -.B "C N" -Make N attempts at ten second intervals -to read COMMAND\'s exit status before exiting. -.TP -.B d -Change all instances of "." to "/" in the transmitted pathname. -Thus, C.omenB0000 (which is unacceptable to MSDOS or CP/M) -is transmitted as C/omenB0000. -If the resultant filename has more than 8 characters in the stem, -a "." in inserted to allow a total of eleven. -.TP -.B f -Send Full pathname. -Normally directory prefixes are stripped from the transmitted -filename. -.TP -.B "i COMMAND" -Send COMMAND to the receiver for execution, return Immediately. -.TP -.B k -Send files using YMODEM 1024 byte blocks -rather than the default 128 byte blocks. -1024 byte packets speed file transfers at high bit rates. -(ZMODEM streams the data for the best possible throughput.) -.TP -.B n -Instruct ZMODEM receiver to skip files if the length and modification times -of the source file and the file on the destination system are equal. -.TP -.B N -Instruct ZMODEM receiver to skip files if the length and CRC\'s -of the source file and the file on the destination system are equal. -.TP -.B q -Quiet suppresses verbosity. -.TP -.B r -Resume interrupted file transfer. -If the source file is longer than the destination file, -the transfer commences at the offset in the source file that equals -the length of the destination file. -.TP -.B u -Unlink the file after successful transmission. -.TP -.B v -Verbose -causes a list of file -names to be appended to -/tmp/szlog . -More v's generate more output. -.TP -.B X -Send a single file with -.B XMODEM -protocol. -.TP -.B y -Force a ZMODEM receiving program to overwrite any existing file -with the same name. -.PD -.SH EXAMPLES -.ne 7 -.B "ZMODEM File Transfer" -.br -.B "$ sz -a *.c" -.br -This single command transfers all .c files in the current Unix directory -with conversion -.RB ( -a ) -to PC-DOS end of line conventions. -With ZMODEM AutoDownload enabled, Professional-YAM automatically recieves -the files after performing a security challenge. - -.B "ZMODEM Command Download" -.br - cpszall:all - sz -c "c:;cd /yam/dist" - sz -ya $(YD)/*.me - sz -yqb y*.exe - sz -c "cd /yam" - sz -i "!insms" -.br -This Makefile fragment uses -.B sz -to issue commands to Professional-YAM to change current disk and directory. -Next, -.B sz -transfers the -.I .me -files from the $YD directory, commanding the receiver to overwrite the old files -and to convert from Unix end of line conventions to PC-DOS conventions. -The third line transfers some -.I .exe -files. -The fourth and fifth lines command Pro-YAM to -change directory and execute a PC-DOS batch file -.I insms . -Since the batch file takes considerable time, the -.B "-i" -form is used to allow -.B sz -to exit immediately. - -.B "XMODEM File Transfer" -.br -$ -.B "sz -Xa foo.c" -.br -.B "ESC" -.br -.B "rx foo.c" -.br -The above three commands transfer a single file -from Unix to a PC and Crosstalk XVI 3.6, -translating Unix newlines to DOS CR/LF. - -.SH SEE ALSO -rz(omen), -ZMODEM.DOC, -YMODEM.DOC, -Professional-YAM manual, -IMP(CP/M), -cu(1), -sq(omen), -todos(omen), -tocpm(omen), -tomac(omen), -yam(omen) - -Compile time options required for various operating systems are described in -the source file. -.SH "VMS VERSION" -The VMS version does not transmit the file date. -The VMS version calculates the file length by reading the file -and counting the bytes. - -The VMS version does not support YMODEM-g or ZMODEM. - -When VMS is lightly loaded, the response time may be too quick for MODEM7 -unless the MODEM7 -.B "q" -modifier is used. - -The VMS C standard i/o package and RMS sometimes interact to modify -file contents unexpectedly. -.SH FILES -sz.c, rbsb.c, zm.c, zmodem.h source files - -/tmp/szlog stores debugging output (sz -vv) -.SH "TESTING FEATURE" -The command "sz -T file" -exercises the -.B Attn -sequence error recovery by commanding -errors with unterminated packets. -The receiving program should complain five times about -binary data packets being too long. -Each time -.B sz -is interrupted, -it should send a ZDATA header followed by another defective packet. -If the receiver does not detect five long data packets, -the -.B Attn -sequence is not interrupting the sender, and the -.B Myattn -string in -.B sz.c -must be modified. - -After 5 packets, -.B sz -stops the "transfer" and -prints the total number of characters "sent" (Tcount). -The difference between Tcount and 5120 represents the number of characters -stored in various buffers when the Attn sequence is generated. -.SH BUGS -XMODEM transfers add up to 127 spurious bytes per file. - -Circular buffering and a ZMODEM sliding window should be used -when input is from pipes instead of acknowledging frames each 1024 bytes. -.B Sz -should check for the presence of at least one accessible file before -getting hot and bothered. -The test mode leaves a zero length file on the receiving system. diff --git a/components/utilities/ZMODEM/SZ.C b/components/utilities/ZMODEM/SZ.C deleted file mode 100644 index f4aaaae345..0000000000 --- a/components/utilities/ZMODEM/SZ.C +++ /dev/null @@ -1,1168 +0,0 @@ -#define VERSION "sz 1.03 05-18-86" -#define PUBDIR "/usr/spool/uucppublic" - -/*% cc -O -K sz.c -o sz; size sz - - * sz.c By Chuck Forsberg - * - * cc -O sz.c -o sz USG (SYS III/V) Unix - * cc -O -DV7 sz.c -o sz Unix Version 7, 2.8 - 4.3 BSD - * - * ******* Some systems (Venix, Coherent, Regulus) do not ******* - * ******* support tty raw mode read(2) identically to ******* - * ******* Unix. ONEREAD must be defined to force one ******* - * ******* character reads for these systems. ******* - * - * A program for Unix to send files and commands to computers running - * Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM. - * - * Sz uses buffered I/O to greatly reduce CPU time compared to UMODEM. - * - * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin - */ - -/* - * Attention string to be executed by receiver to interrupt streaming data - * when an error is detected. A pause (0336) may be needed before the - * ^C (03) or after it. - */ -char Myattn[] = { 03, 0336, 0 }; - -unsigned updcrc(); -char *substr(), *getenv(); - -#define LOGFILE "/tmp/szlog" -#define zperr vfile - -/* -#include -#include -#include -#include -*/ -#include "rtthread.h" -#include "finsh.h" -#include "shell.h" -#include"rtdef.h" -#include -#include -#include -#include "zmodem.h" - -#define PATHLEN 256 -#define OK 0 -#define FALSE 0 -#define TRUE 1 -#define ERROR (-1) - -#define HOWMANY 2 -int Zmodem=0; /* ZMODEM protocol requested */ -unsigned Baudrate; -#include "rbsb.c" /* most of the system dependent stuff here */ - -int in; - -/* Ward Christensen / CP/M parameters - Don't change these! */ -#define ENQ 005 -#define CAN ('X'&037) -#define XOFF ('s'&037) -#define XON ('q'&037) -#define SOH 1 -#define STX 2 -#define EOT 4 -#define ACK 6 -#define NAK 025 -#define CPMEOF 032 -#define WANTCRC 0103 /* send C not NAK to get crc not checksum */ -#define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */ -#define TIMEOUT (-2) -#define RETRYMAX 10 -#define SECSIZ 128 /* cp/m's Magic Number record size */ -#define KSIZE 1024 - -char Lastrx; -char Crcflg; -int Wcsmask=0377; -int Verbose=0; -int Modem=0; /* MODEM - don't send pathnames */ -int Restricted=0; /* restricted; no /.. or ../ in filenames */ -int Quiet=0; /* overrides logic that would otherwise set verbose */ -int Ascii=0; /* Add CR's for brain damaged programs */ -int Fullname=0; /* transmit full pathname */ -int Unlinkafter=0; /* Unlink file after it is sent */ -int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */ -int firstsec; -int errcnt=0; /* number of files unreadable */ -int blklen=SECSIZ; /* length of transmitted records */ -int Optiong; /* Let it rip no wait for sector ACK's */ -int Noeofseen; -int Totsecs; /* total number of sectors this file */ -char txbuf[KSIZE]; -int Filcnt=0; /* count of number of files opened */ -int Lfseen=0; -unsigned Rxbuflen = 16384; /* Receiver's max buffer length */ -int Rxflags = 0; -char Lzconv; /* Local ZMODEM file conversion request */ -char Lzmanag; /* Local ZMODEM file management request */ -char Lztrans; -char zconv; /* ZMODEM file conversion request */ -char zmanag; /* ZMODEM file management request */ -char ztrans; /* ZMODEM file transport request */ -int Command; /* Send a command, then exit. */ -char *Cmdstr; /* Pointer to the command string */ -int Cmdtries = 11; -int Cmdack1; /* Rx ACKs command, then do it */ -int Exitcode; -int Testattn; /* Force receiver to send Attn, etc with qbf. */ -char *qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n"; - - -//jmp_buf tohere; /* For the interrupt on RX timeout */ -//jmp_buf intrjmp; /* For the interrupt on RX CAN */ - -/* called by signal interrupt or terminate to clean things up */ -bibi(n) -{ - canit(); - //fflush(stdout); - mode(0); - //rt_kprintf(stderr, "sz: caught signal %d; exiting\n", n); - //if (n == SIGQUIT) - // abort(); - //exit(128+n); -} -/* Called when Zmodem gets an interrupt (^X) */ -onintr() -{ - //signal(SIGINT, SIG_IGN); - //longjmp(intrjmp, -1); -} - - -//#define sendline(c) putchar(c & Wcsmask) - -//#define xsendline(c) putchar(c) -int sendline (int c) -{ - c = c&Wcsmask; - zwrite(c); - -} -int xsendline(int c) -{ - zwrite(c); -} - - -flushmo() -{ - //fflush(stdout); -} - -#include "zm.c" - -zsmain(argc, argv) -char *argv[]; -{ - register char *cp; - register npats; - int agcnt; char **agcv; - char **patts; - static char xXbuf[BUFSIZ]; - - //if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rsh"))) - // Restricted=TRUE; - - Rxtimeout = 600; - npats=0; - /* - if (argc<2) - usage(); - //setbuf(stdout, xXbuf); - while (--argc) { - cp = *++argv; - if (*cp++ == '-' && *cp) { - while ( *cp) { - switch(*cp++) { - case '+': - Lzmanag = ZMAPND; break; - case '1': - iofd = 1; break; - case '7': - Wcsmask=0177; break; - case 'a': - Lzconv = ZCNL; - Ascii = TRUE; break; - case 'b': - Lzconv = ZCBIN; break; - case 'C': - if (--argc < 1) { - usage(); - } - Cmdtries = atoi(*++argv); - break; - case 'i': - Cmdack1 = ZCACK1; - //* **** FALL THROUGH TO **** - case 'c': - if (--argc != 1) { - usage(); - } - Command = TRUE; - Cmdstr = *++argv; - break; - case 'd': - ++Dottoslash; - //* **** FALL THROUGH TO **** * - case 'f': - Fullname=TRUE; break; - case 'k': - blklen=KSIZE; break; - case 'N': - Lzmanag = ZMCRC; break; - case 'n': - Lzmanag = ZMNEW; break; - case 'r': - Lzconv = ZCRESUM; - case 'q': - Quiet=TRUE; Verbose=0; break; - case 'T': - Testattn = TRUE; break; - case 'u': - ++Unlinkafter; break; - case 'v': - ++Verbose; break; - case 'X': - ++Modem; break; - case 'y': - Lzmanag = ZMCLOB; break; - default: - usage(); - } - } - } - else if ( !npats && argc>0) { - if (argv[0][0]) { - npats=argc; - patts=argv; - if ( !strcmp(*patts, "-")) - iofd = 1; - } - } - } - if (npats < 1 && !Command) - usage(); - if (Verbose) { - if (freopen(LOGFILE, "a", stderr)==NULL) { - printf("Can't open log file %s\n",LOGFILE); - exit(0200); - } - setbuf(stderr, NULL); - } - if (fromcu() && !Quiet) { - if (Verbose == 0) - Verbose = 2; - } - - mode(1); - -// if (signal(SIGINT, bibi) == SIG_IGN) { -// signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN); -// } -// else { - // signal(SIGINT, bibi); signal(SIGKILL, bibi); -// signal(SIGQUIT, bibi); -// } - - if ( !Modem) { - if (!Command) { - printf("rz\r"); fflush(stdout); - } - if (!Command && !Quiet && Verbose != 1) { - rt_kprintf(stderr, "sz: %d file%s requested:\r\n", - npats, npats>1?"s":""); - for ( agcnt=npats, agcv=patts; --agcnt>=0; ) { - rt_kprintf(stderr, "%s ", *agcv++); - } - rt_kprintf(stderr, "\r\n"); - printf("\r\n\bSending in Batch Mode\r\n"); - } - stohdr(0L); - if (Command) - Txhdr[ZF0] = ZCOMMAND; - zshhdr(ZRQINIT, Txhdr); - } - fflush(stdout); - */ - if (Command) { - if (getzrxinit()) { - Exitcode=0200; canit(); - } - else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) { - Exitcode=0200; canit(); - } - } else if (wcsend(npats, patts)==ERROR) { - Exitcode=0200; - canit(); - } - //fflush(stdout); - //mode(0); - //exit((errcnt != 0) | Exitcode); - /*NOTREACHED*/ -} - -wcsend(argc, argp) -char *argp[]; -{ - register n; - - Crcflg=FALSE; - firstsec=TRUE; - //for (n=0; n>7); - //} - //rt_kprintf(stderr, "Give your local XMODEM receive command now.\r\n"); - return OK; - } - logent("\r\nAwaiting pathname nak for %s\r\n", *name?name:""); - if ( !Zmodem) - if (getnak()) - return ERROR; - - q = (char *) 0; - if (Dottoslash) { /* change . to . */ - for (p=name; *p; ++p) { - if (*p == '/') - q = p; - else if (*p == '.') - *(q=p) = '/'; - } - if (q && strlen(++q) > 8) { /* If name>8 chars */ - q += 8; /* make it .ext */ - strcpy(name2, q); /* save excess of name */ - *q = '.'; - strcpy(++q, name2); /* add it back */ - } - } - - for (p=name, q=txbuf ; *p; ) - if ((*q++ = *p++) == '/' && !Fullname) - q = txbuf; - *q++ = 0; - p=q; - while (q < (txbuf + KSIZE)) - *q++ = 0; - //if (!Ascii && (in!=stdin) && *name && fstat(fileno(in), &f)!= -1) - //sprintf(p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode); - fstat(in,&f); - /* force 1k blocks if name won't fit in 128 byte block */ - if (txbuf[125]) - blklen=KSIZE; - else { /* A little goodie for IMP/KMD */ - if (Zmodem) - blklen = SECSIZ; - txbuf[127] = f.st_size >>7; - txbuf[126] = f.st_size >>15; - } - if (Zmodem) - return zsendfile(txbuf, 1+strlen(p)+(p-txbuf)); - if (wcputsec(txbuf, 0, SECSIZ)==ERROR) - return ERROR; - return OK; -} - -getnak() -{ - register firstch; - - Lastrx = 0; - for (;;) { - switch (firstch = readock(800,1)) { - case ZPAD: - if (getzrxinit()) - return ERROR; - Ascii = 0; - return FALSE; - case TIMEOUT: - logent("Timeout on pathname\n"); - return TRUE; - case WANTG: - mode(2); /* Set cbreak, XON/XOFF, etc. */ - Optiong = TRUE; - blklen=KSIZE; - case WANTCRC: - Crcflg = TRUE; - case NAK: - return FALSE; - case CAN: - if (Lastrx == CAN) - return TRUE; - default: - break; - } - Lastrx = firstch; - } -} - - -wctx() -{ - register int sectnum, attempts, firstch; - - firstsec=TRUE; - - while ((firstch=readock(400, 2))!=NAK && firstch != WANTCRC - && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN) - ; - if (firstch==CAN) { - logent("Receiver CANcelled\n"); - return ERROR; - } - if (firstch==WANTCRC) - Crcflg=TRUE; - if (firstch==WANTG) - Crcflg=TRUE; - sectnum=1; - while (filbuf(txbuf, blklen)) { - if (wcputsec(txbuf, sectnum, blklen)==ERROR) { - return ERROR; - } else - sectnum++; - } - //if (Verbose>1) - // rt_kprintf(stderr, " Closing "); - close(in); - attempts=0; - do { - logent(" EOT "); - purgeline(); - sendline(EOT); - //fflush(stdout); - ++attempts; - } - while ((firstch=(readock(100, 1)) != ACK) && attempts < RETRYMAX); - if (attempts == RETRYMAX) { - logent("No ACK on EOT\n"); - return ERROR; - } - else - return OK; -} - -wcputsec(buf, sectnum, cseclen) -char *buf; -int sectnum; -int cseclen; /* data length of this sector to send */ -{ - register checksum, wcj; - register char *cp; - unsigned oldcrc; - int firstch; - int attempts; - - firstch=0; /* part of logic to detect CAN CAN */ - - //if (Verbose>1) - // rt_kprintf(stderr, "\rSector %3d %2dk ", Totsecs, Totsecs/8 ); - for (attempts=0; attempts <= RETRYMAX; attempts++) { - Lastrx= firstch; - sendline(cseclen==KSIZE?STX:SOH); - sendline(sectnum); - sendline(-sectnum -1); - oldcrc=checksum=0; - for (wcj=cseclen,cp=buf; --wcj>=0; ) { - sendline(*cp); - oldcrc=updcrc(*cp, oldcrc); - checksum += *cp++; - } - if (Crcflg) { - oldcrc=updcrc(0,updcrc(0,oldcrc)); - sendline((int)oldcrc>>8); - sendline((int)oldcrc); - } - else - sendline(checksum); - - if (Optiong) { - firstsec = FALSE; return OK; - } - firstch = readock(400, (Noeofseen&§num) ? 2:1); -gotnak: - switch (firstch) { - case CAN: - if(Lastrx == CAN) { -cancan: - logent("Cancelled\n"); return ERROR; - } - break; - case TIMEOUT: - logent("Timeout on sector ACK\n"); continue; - case WANTCRC: - if (firstsec) - Crcflg = TRUE; - case NAK: - logent("NAK on sector\n"); continue; - case ACK: - firstsec=FALSE; - Totsecs += (cseclen>>7); - return OK; - case ERROR: - logent("Got burst for sector ACK\n"); break; - default: - logent("Got %02x for sector ACK\n", firstch); break; - } - for (;;) { - Lastrx = firstch; - if ((firstch = readock(400, 2)) == TIMEOUT) - break; - if (firstch == NAK || firstch == WANTCRC) - goto gotnak; - if (firstch == CAN && Lastrx == CAN) - goto cancan; - } - } - logent("Retry Count Exceeded\n"); - return ERROR; -} - -/* fill buf with count chars padding with ^Z for CPM */ -filbuf(buf, count) -register char *buf; -{ - register c, m; - - if ( !Ascii) { - m = read(in, buf, count); - if (m <= 0) - return 0; - while (m < count) - buf[m++] = 032; - return count; - } - m=count; - if (Lfseen) { - *buf++ = 012; --m; Lfseen = 0; - } - ///////////////////////////////////////////////////////////////////////////////////// - /* - while ((c=getc(in))!=EOF) { - if (c == 012) { - *buf++ = 015; - if (--m == 0) { - Lfseen = TRUE; break; - } - } - *buf++ =c; - if (--m == 0) - break; - } - */ - if (m==count) - return 0; - else - while (--m>=0) - *buf++ = CPMEOF; - return count; -} -/* fill buf with count chars */ -zfilbuf(buf, count) -register char *buf; -{ //int read(int fd, void *buf, size_t len) - int c, m; - int res; - - m=count; - res = 0; - while (1) { - res = read(in,&c,1); - if (res == 0) break; - *buf++ =c; - res = 0; - if (--m == 0) - break; - } - return (count - m); -} - -/* VARARGS1 */ -vfile(f, a, b, c) -register char *f; -{ -// if (Verbose > 1) { - // rt_kprintf(stderr, f, a, b, c); - // rt_kprintf(stderr, "\n"); -// } -} - - -alarm() -{ - //longjmp(tohere, -1); -} - - -/* - * readock(timeout, count) reads character(s) from file descriptor 0 - * (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) - * Only looks for one if Optiong, which signifies cbreak, not raw input - * - * timeout is in tenths of seconds - */ -readock(timeout, count) -{ - register int c; - static char byt[5]; - int ch; - if (Optiong) - count = 1; /* Special hack for cbreak */ - - //fflush(stdout); - //if (setjmp(tohere)) { - // logent("TIMEOUT\n"); - // return TIMEOUT; - //} - c = 0; - while (1) - { - c = zread(shell->device, 0, byt, 1); - if (c > 0) break; - } - //if (Verbose>5) - // rt_kprintf(stderr, "ret cnt=%d %x %x\n", c, byt[0], byt[1]); - if (c<1) - return TIMEOUT; - if (c==1) - return (byt[0]&0377); - else - while (c) - if (byt[--c] != CAN) - return ERROR; - return CAN; -} -readline(n) -{ - return (readock(n, 1)); -} - - -purgeline() -{ -#ifdef USG - ioctl(iofd, TCFLSH, 0); -#else - lseek(iofd, 0L, 2); -#endif -} - -/* update CRC */ -unsigned -updcrc(c, crc) -register c; -register unsigned crc; -{ - register count; - - for (count=8; --count>=0;) { - if (crc & 0x8000) { - crc <<= 1; - crc += (((c<<=1) & 0400) != 0); - crc ^= 0x1021; - } - else { - crc <<= 1; - crc += (((c<<=1) & 0400) != 0); - } - } - return crc; -} - -/* send cancel string to get the other end to shut up */ -canit() -{ - static char canistr[] = { - ZPAD,ZPAD,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0 - }; - - //printf(canistr); - //fflush(stdout); -} - -/*VARARGS1*/ -logent(a, b, c) -char *a, *b, *c; -{ -// if(Verbose) - // rt_kprintf(stderr, a, b, c); -} - -/* - * return 1 iff stdout and stderr are different devices - * indicating this program operating with a modem on a - * different line - */ -fromcu() -{ - struct stat a, b; - fstat(1, &a); fstat(2, &b); -// return (a.st_rdev != b.st_rdev); -} - -/* - * substr(string, token) searches for token in string s - * returns pointer to token within string if found, NULL otherwise - */ -char * -substr(s, t) -register char *s,*t; -{ - register char *ss,*tt; - /* search for first char of token */ - for (ss=s; *s; s++) - if (*s == *t) - /* compare token with substring */ - for (ss=s,tt=t; ;) { - if (*tt == 0) - return s; - if (*ss++ != *tt++) - break; - } - return NULL; -} - -usage() -{ - -} - -/* - * Get the receiver's init parameters - */ -getzrxinit() -{ - register n; - struct stat f; - - for (n=10; --n>=0; ) { - - switch (zgethdr(Rxhdr, 1)) { - case ZCHALLENGE: /* Echo receiver's challenge numbr */ - stohdr(Rxpos); - zshhdr(ZACK, Txhdr); - continue; - case ZCOMMAND: /* They didn't see out ZRQINIT */ - stohdr(0L); - zshhdr(ZRQINIT, Txhdr); - continue; - case ZRINIT: - Rxflags = Rxhdr[ZF0]; - Rxbuflen = Rxhdr[ZP0] + (Rxhdr[ZP1]<<8); - //signal(SIGINT, SIG_IGN); - mode(2); /* Set cbreak, XON/XOFF, etc. */ - - /* If using a pipe for testing set lower buf len */ - fstat(iofd, &f); - if ((f.st_mode & S_IFMT) != S_IFCHR - && (Rxbuflen == 0 || Rxbuflen > 4096)) - Rxbuflen = 4096; - /* - * If input is not a regular file, force ACK's each 1024 - * (A smarter strategey could be used here ...) - */ - fstat(in, &f); - if (((f.st_mode & S_IFMT) != S_IFREG) - && (Rxbuflen == 0 || Rxbuflen > 1024)) - Rxbuflen = 1024; - - return (sendzsinit()); - case ZCAN: - case TIMEOUT: - return ERROR; - case ZRQINIT: - if (Rxhdr[ZF0] == ZCOMMAND) - continue; - default: - zshhdr(ZNAK, Txhdr); - continue; - } - } - return ERROR; -} - -/* Send send-init information */ -sendzsinit() -{ - register c; - register errors; - - errors = 0; - for (;;) { - stohdr(0L); - zsbhdr(ZSINIT, Txhdr); - zsbdata(Myattn, 1+strlen(Myattn), ZCRCW); - c = zgethdr(Rxhdr, 1); - switch (c) { - case ZCAN: - return ERROR; - case ZACK: - return OK; - default: - if (++errors > 9) - return ERROR; - continue; - } - } -} - -/* Send file name and related info */ -zsendfile(buf, blen) -char *buf; -{ - register c; - - for (;;) { - Txhdr[ZF0] = Lzconv; /* file conversion request */ - Txhdr[ZF1] = Lzmanag; /* file management request */ - Txhdr[ZF2] = Lztrans; /* file transport request */ - Txhdr[ZF3] = 0; - zsbhdr(ZFILE, Txhdr); - zsbdata(buf, blen, ZCRCW); -again: - c = zgethdr(Rxhdr, 1); - switch (c) { - case ZRINIT: - goto again; - case ZCAN: - case TIMEOUT: - case ZABORT: - case ZFIN: - return ERROR; - case ZSKIP: - close(in); return c; - case ZRPOS: - lseek(in, Rxpos, 0); - Txpos = Rxpos; - return zsendfdata(); - case ERROR: - default: - continue; - } - } -} - -/* Send the data in the file */ -zsendfdata() -{ - register c, e; - register newcnt; - register long tcount = 0; - static int tleft = 6; /* Counter for test mode */ - - if (Baudrate > 300) - blklen = 256; - if (Baudrate > 2400) - blklen = KSIZE; - if (Rxbuflen && blklen>Rxbuflen) - blklen = Rxbuflen; -somemore: - //if (setjmp(intrjmp)) { -waitack: - // switch (c = getinsync()) { - // default: - // case ZCAN: - // close(in); - // return ERROR; - // case ZSKIP: - // close(in); - // return c; - // case ZACK: - // case ZRPOS: - // break; - // } -// } - - //signal(SIGINT, onintr); - newcnt = Rxbuflen; - stohdr(Txpos); - zsbhdr(ZDATA, Txhdr); - - /* - * Special testing mode. This should force receiver to Attn,ZRPOS - * many times. Each time the signal should be caught, causing the - * file to be started over from the beginning. - */ - if (Testattn) { - if ( --tleft) - while (tcount < 20000) { - //printf(qbf); - //fflush(stdout); - tcount += strlen(qbf); - } - //signal(SIGINT, SIG_IGN); - canit(); - //sleep(3); - purgeline(); mode(0); - //printf("\nsz: Tcount = %ld\n", tcount); - if (tleft) { - //printf("ERROR: Interrupts Not Caught\n"); - //exit(1); - } - //exit(0); - } - - do { - c = zfilbuf(txbuf, blklen); - if (c < blklen) - e = ZCRCE; - else if (Rxbuflen && (newcnt -= c) <= 0) - e = ZCRCW; - else - e = ZCRCG; - zsbdata(txbuf, c, e); - Txpos += c; - if (e == ZCRCW) - goto waitack; -#ifdef NOTDEF_DOS - if ( !carrier()) { - return ERROR; - } - /* - * If the reverse channel can be tested for data, - * this logic may be used to detect error packets - * sent by the receiver, in place of setjmp/longjmp - * miready() returns non 0 if a character is available - */ - while (miready()) { - if (readline(1) == ZPAD) { - zsbdata(U.ubuf, 0, ZCRCW); - goto somemore; - } - } -#endif - } while (c == blklen); - //signal(SIGINT, SIG_IGN); - - for (;;) { - stohdr(Txpos); - zsbhdr(ZEOF, Txhdr); - switch (getinsync()) { - case ZRPOS: - goto somemore; - case ZRINIT: - close(in); - return OK; - case ZSKIP: - close(in); - return c; - default: - close(in); - return ERROR; - } - } -} - -/* - * Respond to receiver's complaint, get back in sync with receiver - */ -getinsync() -{ - register c; - - for (;;) { - if (Testattn) { - //printf("\r\n\n\n***** Signal Caught *****\r\n"); - Rxpos = 0; c = ZRPOS; - } else - c = zgethdr(Rxhdr, 0); - switch (c) { - case ZCAN: - case ZABORT: - case ZFIN: - case TIMEOUT: - return ERROR; - case ZRPOS: - //clearerr(in); /* In case file EOF seen */ - lseek(in, Rxpos, 0); - Txpos = Rxpos; - return c; - case ZACK: - return c; - case ZRINIT: - case ZSKIP: - close(in); - return c; - case ERROR: - default: - zsbhdr(ZNAK, Txhdr); - continue; - } - } -} -/* Say "bibi" to the receiver, try to do it cleanly */ -saybibi() -{ - for (;;) { - stohdr(0L); - zsbhdr(ZFIN, Txhdr); - switch (zgethdr(Rxhdr, 0)) { - case ZFIN: - sendline('O'); sendline('O'); flushmo(); - case ZCAN: - case TIMEOUT: - return; - } - } -} - -/* Local screen character display function */ -bttyout(c) -{ - //if (Verbose) - // putc(c, stderr); -} - -/* Send command and related info */ -zsendcmd(buf, blen) -char *buf; -{ - register c, errors; - long cmdnum; - -// cmdnum = getpid(); - errors = 0; - for (;;) { - stohdr(cmdnum); - Txhdr[ZF0] = Cmdack1; - zsbhdr(ZCOMMAND, Txhdr); - zsbdata(buf, blen, ZCRCW); -listen: - Rxtimeout = 100; /* Ten second wait for resp. */ - c = zgethdr(Rxhdr, 1); - - switch (c) { - case ZRINIT: - continue; - case ERROR: - case TIMEOUT: - if (++errors > Cmdtries) - return ERROR; - continue; - case ZCAN: - case ZABORT: - case ZFIN: - case ZSKIP: - case ZRPOS: - return ERROR; - default: - if (++errors > 10) - return ERROR; - continue; - case ZCOMPL: - Exitcode = Rxpos; - saybibi(); - return OK; - case ZRQINIT: - vfile("******** RZ *******"); - system("rz"); - vfile("******** SZ *******"); - goto listen; - } - } -} - diff --git a/components/utilities/ZMODEM/ZM.C b/components/utilities/ZMODEM/ZM.C deleted file mode 100644 index 6dceb7ae09..0000000000 --- a/components/utilities/ZMODEM/ZM.C +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Z M . C - * ZMODEM protocol primitives - * 5-18-86 Chuck Forsberg Omen Technology Inc - * - * Entry point Functions: - * zsbhdr(type, hdr) send binary header - * zshhdr(type, hdr) send hex header - * zgethdr(hdr, eflag) receive header - binary or hex - * zsbdata(buf, len, frameend) send binary data - * zrbdata(buf, len) receive binary data - * stohdr(pos) store position data in Txhdr - * long rclhdr(hdr) recover position offset from header - */ - -//#ifndef CANFDX -#include "zmodem.h" -int Rxtimeout = 100; /* Tenths of seconds to wait for something */ -//#endif -#define ERROR (-1) -static char *frametypes[] = { - "TIMEOUT", - "ERROR", - "ZRQINIT", - "ZRINIT", - "ZSINIT", - "ZACK", - "ZFILE", - "ZSKIP", - "ZNAK", - "ZABORT", - "ZFIN", - "ZRPOS", - "ZDATA", - "ZEOF", - "ZFERR", - "ZCRC", - "ZCHALLENGE", - "ZCOMPL", - "ZCAN", - "ZFREECNT", - "ZCOMMAND", - "ZCACK" -#define FRTYPES 21 /* Total number of frame types in this array */ -}; - -long int rclhdr(char *hdr); -int zputhex(int c); -int zsendline(int c); -int zgethex(void); -int zgeth1(void); -int zrbhdr(char *hdr); -int zrhhdr(char *hdr); -int zdlread(void); -int noxread7(void); - - -/* Send ZMODEM binary header hdr of type type */ -int zsbhdr(int type, char *hdr) -{ - int n; - unsigned short oldcrc; - - vfile("zsbhdr: %s %lx", frametypes[type+2], rclhdr(hdr)); - xsendline(ZPAD); xsendline(ZDLE); xsendline(ZBIN); - - zsendline(type); oldcrc = updcrc(type, 0); - - for (n=4; --n >= 0;) { - zsendline(*hdr); - oldcrc = updcrc(*hdr++, oldcrc); - } - oldcrc = updcrc(0,updcrc(0,oldcrc)); - zsendline(oldcrc>>8); - zsendline(oldcrc); - if (type != ZDATA) - flushmo(); - return 0; -} - -/* Send ZMODEM HEX header hdr of type type */ -int zshhdr(int type, char *hdr) -{ - int n; - unsigned short oldcrc; - - vfile("zshhdr: %s %lx", frametypes[type+2], rclhdr(hdr)); - - sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX); - zputhex(type); - - oldcrc = updcrc(type, 0); - for (n=4; --n >= 0;) { - zputhex(*hdr); oldcrc = updcrc(*hdr++, oldcrc); - } - oldcrc = updcrc(0,updcrc(0,oldcrc)); - zputhex(oldcrc>>8); zputhex(oldcrc); - - /* Make it printable on remote machine */ - sendline(015); sendline(0212); /*012*/ - /* - * Uncork the remote in case a fake XOFF has stopped data flow - */ - if (type != ZFIN) - sendline(021); - flushmo(); - return 0; -} - -/* - * Send binary array buf of length length, with ending ZDLE sequence frameend - */ -int zsbdata(char *buf, int length, int frameend) -{ - register unsigned short oldcrc; - - vfile("zsbdata: length=%d end=%x", length, frameend); - oldcrc = 0; - for (;--length >= 0;) { - zsendline(*buf); - oldcrc = updcrc(*buf++, oldcrc); - } - xsendline(ZDLE); xsendline(frameend); - oldcrc = updcrc(frameend, oldcrc); - - oldcrc = updcrc(0,updcrc(0,oldcrc)); - zsendline(oldcrc>>8); - zsendline(oldcrc); - if (frameend == ZCRCW) - flushmo(); - return 0; -} - -/* - * Receive binary array buf of max length with ending ZDLE sequence - * and CRC. Returns the ending character or error code. - */ -int zrbdata(char *buf, int length) -{ - int c; - unsigned short oldcrc; - int d; - - oldcrc = Rxcount = 0; - for (;;) { - if ((c = zdlread()) & ~0377) { - switch (c) { - case GOTCRCE: - case GOTCRCG: - case GOTCRCQ: - case GOTCRCW: - oldcrc = updcrc((d=c)&0377, oldcrc); - if ((c = zdlread()) & ~0377) - goto badcrc; - oldcrc = updcrc(c, oldcrc); - if ((c = zdlread()) & ~0377) - goto badcrc; - oldcrc = updcrc(c, oldcrc); - if (oldcrc & 0xFFFF) { -badcrc: - zperr("Bad data packet CRC"); - return ERROR; - } - vfile("zrbdata: Rxcount = %d ret = %x", - Rxcount, d); - return d; - case GOTCAN: - zperr("ZMODEM: Sender Canceled"); - return ZCAN; - case TIMEOUT: - zperr("ZMODEM data packet TIMEOUT"); - return c; - default: - zperr("ZMODEM bad data packet ret=%x", c); - return c; - } - } - if (--length < 0) { - zperr("ZMODEM binary data packet too long"); - return ERROR; - } - ++Rxcount; - *buf++ = c; - oldcrc = updcrc(c, oldcrc); - continue; - } -} - -/* - * Read a ZMODEM header to hdr, either binary or hex. - * eflag controls local display of non zmodem characters: - * 0: no display - * 1: display printing characters only - * 2: display all non ZMODEM characters - * On success, set Zmodem to 1 and return type of header. - * Otherwise return negative on error - */ -int zgethdr(char *hdr, int eflag) -{ - int c, n; - - n = Baudrate; /* Max characters before start of frame */ -again: - Rxframeind = Rxtype = 0; - switch (c = noxread7()) { - case TIMEOUT: - goto fifi; - case ZDLE: - if (noxread7() == ZDLE) { - c = ZCAN; goto fifi; - } - /* **** FALL THRU TO **** */ - default: - if ( --n == 0) { - zperr("ZMODEM Garbage count exceeded"); - return(ERROR); - } - if (eflag && ((c &= 0177) & 0140)) - bttyout(c); - else if (eflag > 1) - bttyout(c); - goto again; - case ZPAD: - break; - } -splat: - switch (c = noxread7()) { - case ZPAD: - goto splat; - case TIMEOUT: - goto fifi; - default: - goto again; - case ZDLE: - break; - } - - switch (c = noxread7()) { - case TIMEOUT: - goto fifi; - case ZBIN: - Rxframeind = ZBIN; - c = zrbhdr(hdr); - break; - case ZHEX: - Rxframeind = ZHEX; - c = zrhhdr(hdr); - break; - case ZDLE: - if (noxread7() == ZDLE) { - c = ZCAN; goto fifi; - } - /* **** FALL THRU TO **** */ - default: - goto again; - } - Rxpos = hdr[ZP3] & 0377; - Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377); - Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377); - Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377); -fifi: - switch (c) { - case GOTCAN: - c = ZCAN; - /* **** FALL THRU TO **** */ - case ZNAK: - case ZCAN: - case ERROR: - case TIMEOUT: - zperr("ZMODEM: Got %s header", frametypes[c+2]); - default: - if (c >= -2 && c <= FRTYPES) - vfile("zgethdr: %s %lx", frametypes[c+2], Rxpos); - else - vfile("zgethdr: %d %lx", c, Rxpos); - } - return c; -} - -/* Receive a binary style header (type and position) */ -int zrbhdr(char *hdr) -{ - int c, n; - unsigned short oldcrc; - - if ((c = zdlread()) & ~0377) - return c; - Rxtype = c; - oldcrc = updcrc(c, 0); - - for (n=4; --n >= 0;) { - if ((c = zdlread()) & ~0377) - return c; - oldcrc = updcrc(c, oldcrc); - *hdr++ = c; - } - if ((c = zdlread()) & ~0377) - return c; - oldcrc = updcrc(c, oldcrc); - if ((c = zdlread()) & ~0377) - return c; - oldcrc = updcrc(c, oldcrc); - if (oldcrc & 0xFFFF) { - zperr("Bad Header CRC"); return ERROR; - } - Zmodem = 1; - return Rxtype; -} - -/* Receive a hex style header (type and position) */ -int zrhhdr(char *hdr) -{ - int c; - unsigned short oldcrc; - int n; - - if ((c = zgethex()) < 0) - return c; - Rxtype = c; - oldcrc = updcrc(c, 0); - - for (n=4; --n >= 0;) { - if ((c = zgethex()) < 0) - return c; - oldcrc = updcrc(c, oldcrc); - *hdr++ = c; - } - if ((c = zgethex()) < 0) - return c; - oldcrc = updcrc(c, oldcrc); - if ((c = zgethex()) < 0) - return c; - oldcrc = updcrc(c, oldcrc); - if (oldcrc & 0xFFFF) { - zperr("Bad Header CRC"); return ERROR; - } - if (readline(1) == '\r') /* Throw away possible cr/lf */ - readline(1); - Zmodem = 1; return Rxtype; -} - -/* Send a byte as two hex digits */ -int zputhex(int c) -{ - static char digits[] = "0123456789abcdef"; - - if (Verbose>4) - vfile("zputhex: %x", c); - sendline(digits[(c&0xF0)>>4]); - sendline(digits[(c)&0xF]); - return 0; -} - -/* Send character c with ZMODEM escape sequence encoding */ -int zsendline(int c) -{ - switch (c & 0377) { - case ZDLE: - case 021: - case 023: - case 0221: - case 0223: - xsendline(ZDLE); - c ^= 0100; - /* **** FALL THRU TO **** */ - default: - xsendline(c); - } - return 0; -} - -/* Decode two lower case hex digits into an 8 bit byte value */ -int zgethex(void) -{ - int c; - - c = zgeth1(); - if (Verbose>4) - vfile("zgethex: %x", c); - return c; -} -int zgeth1(void) -{ - int c, n; - - if ((c = noxread7()) < 0) - return c; - n = c - '0'; - if (n > 9) - n -= ('a' - ':'); - if (n & ~0xF) - return ERROR; - if ((c = noxread7()) < 0) - return c; - c -= '0'; - if (c > 9) - c -= ('a' - ':'); - if (c & ~0xF) - return ERROR; - c += (n<<4); - return c; -} - -/* - * Read a byte, checking for ZMODEM escape encoding - * including CAN-CAN which represents a quick abort - */ -int zdlread(void) -{ - int c; - - if ((c = readline(Rxtimeout)) != ZDLE) - return c; - if ((c = readline(Rxtimeout)) < 0) - return c; - switch (c) { - case ZDLE: - return GOTCAN; - case ZCRCE: - case ZCRCG: - case ZCRCQ: - case ZCRCW: - return (c | GOTOR); - case ZRUB0: - return 0177; - case ZRUB1: - return 0377; - default: - if ((c & 0140) == 0100) - return (c ^ 0100); - break; - } - zperr("Got bad ZMODEM escape sequence %x", c); - return ERROR; -} - -/* - * Read a character from the modem line with timeout. - * Eat parity, XON and XOFF characters. - */ -int noxread7(void) -{ - int c; - - for (;;) { - if ((c = readline(Rxtimeout)) < 0) - return c; - switch (c &= 0177) { - case XON: - case XOFF: - continue; - default: - return c; - } - } -} - -/* Store long integer pos in Txhdr */ -int stohdr(long int pos) -{ - Txhdr[ZP0] = pos; - Txhdr[ZP1] = pos>>8; - Txhdr[ZP2] = pos>>16; - Txhdr[ZP3] = pos>>24; - return 0; -} - -/* Recover a long integer from a header */ -long -int rclhdr(char *hdr) -{ - long int l; - - l = (hdr[ZP3] & 0377); - l = (l << 8) | (hdr[ZP2] & 0377); - l = (l << 8) | (hdr[ZP1] & 0377); - l = (l << 8) | (hdr[ZP0] & 0377); - return l; -} - diff --git a/components/utilities/ZMODEM/ZMODEM.DOC b/components/utilities/ZMODEM/ZMODEM.DOC deleted file mode 100644 index 3b2149c884..0000000000 --- a/components/utilities/ZMODEM/ZMODEM.DOC +++ /dev/null @@ -1,2056 +0,0 @@ - - - - The ZMODEM Asynchronous Inter Application File Transfer Protocol - - Chuck Forsberg - - Omen Technology Inc - - - Chuck Forsberg - Omen Technology Inc - 17505-V Northwest Sauvie Island Road - Portland Oregon 97231 - Voice: 503-621-3406 - Modem (Telegodzilla): 503-621-3746 Speed 1200,300 - Compuserve: 70715,131 - UUCP: ...!tektronix!reed!omen!caf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Chapter 0 rev051486 Printed 5-16-86 1 - - - - - - - -Chapter 0 rev051486 Printed 5-16-86 2 - - - -1. INTENDED AUDIENCE - -This document is intended for systems programmers and other technically -qualified people who choose and implement asynchronous file transfer -protocols over dial-up networks and related environments. - - -2. ACKNOWLEDGMENTS - -Encouragement and suggestions by Stuart Mathison, Thomas Buck, John Wales, -Ward Christensen, and Irv Hoff are gratefully acknowledged. - - -3. RELATED DOCUMENTS - -The following files should be available for reference while studying this -document: - -YMODEM.DOC Describes the XMODEM and YMODEM file transfer protocols - -ZMODEM.H Provides definitions for the manifest constants referenced - herein. - -rz.c, sz.c, rbsb.c Unix source code for operating ZMODEM programs. - -rz.1, sz.1 Manual pages for rz and sz. - -zm.c, zmodem.h Operating system independent ZMODEM subroutines, header - file. - - -4. ROSETTA STONE - -Here are some definitions which reflect the current vernacular in the -computer media. The attempt here is identify the file transfer protocol -rather than specific programs. - -Frame A ZMODEM frame consists of a header packet and 0 or more data - packets. - -XMODEM refers to the original 1979 file transfer etiquette introduced by - Ward Christensen's 1979 MODEM2 program. It's also called the - MODEM or MODEM2 protocol. Some who are unaware of MODEM7's - unusual batch file mode call it MODEM7. Other aliases include - "CP/M Users's Group" and "TERM II FTP 3". This protocol is - supported by every serious communications program because of its - universality, simplicity, and reasonable performance. - -XMODEM/CRC replaces XMODEM's 1 byte checksum with a two byte Cyclical - Redundancy Check (CRC-16), giving modern error detection - protection. - - - -Chapter 4 rev051486 Printed 5-16-86 2 - - - - - - - -Chapter 4 rev051486 Printed 5-16-86 3 - - - -YMODEM refers to the XMODEM/CRC protocol with the throughput and/or batch - transmission enhancements described in YMODEM.DOC. - -ZMODEM Zmodem is a second generation streaming protocol for text and - binary file transmission between applications running on - microcomputers and mainframes. - - -5. WHY DEVELOP ZMODEM? - -Since its development half a decade ago, the Ward Christensen MODEM -protocol has enabled a wide variety of computer systems to interchange -data. There is hardly a communications program that doesn't at least -claim to support this protocol, now called XMODEM. - -Advances in computing, modems and networking have spread the XMODEM -protocol far beyond the micro to micro environment for which it was -designed. These application have exposed some weaknesses: - - + The user interface is suitable for computer hobbyists. Three or four - commands must be keyboarded to transfer each file. - - + The short block length causes throughput to suffer when used with - timesharing systems, packet switched networks, satellite circuits, - and buffered (error correcting) modems. - - + The 8 bit checksum and unprotected transactions allow undetected - errors and disrupted file transfers. - - + Only one file can be sent per command. The file name has to be given - twice, first to the sending program and then again to the receiving - program. - - + The transmitted file accumulates as many as 127 extraneous bytes. - - + The modification date and other file attributes are lost. - - + XMODEM requires complete 8 bit transparency, all 256 codes. XMODEM - will not operate over some networks that need flow control. - -A number of other protocols have been developed over the years, but none -have displaced XMODEM to date. - - + Lack of public domain documentation and example programs have kept - proprietary protocols such as MNP, Blast, and others tightly bound to - the fortunes of their suppliers. - - + Hardware and/or software complexity discourages the widespread - application of BISYNC, SDLC, HDLC, X.25, and X.PC protocols. - - - - - -Chapter 5 rev051486 Printed 5-16-86 3 - - - - - - - -Chapter 5 rev051486 Printed 5-16-86 4 - - - - + Link level protocols such as X.25, X.PC, and MNP do not manage - application to application file transfers. - - + The Kermit protocol was developed to allow file transfers in - environments hostile to XMODEM. The performance compromises - necessary to accomodate non transparent environments limit Kermit's - efficiency. Even with completely transparent channels, Kermit - control character quoting limits the efficiency of binary file - transfers to about 75 per cent.[1] - - Kermit Sliding Windows ("SuperKermit") improves throughput over - networks at the cost of increased complexity. SuperKermit state - transitions are encoded in a special language "wart" which requires a - C compiler. The SuperKermit C code requires full duplex - communications and the ability to check for the presence of - characters in the input queue, precluding its implementation on some - operating systems. - - A number of submodes are used in various Kermit programs, including - different methods of transferring binary files. Two Kermit programs - will mysteriously fail to operate with each other if these submodes - are not matched. - -A number of extensions to the XMODEM protocol have been made under the -collective name YMODEM. - - + YMODEM-k uses 1024 byte blocks to reduce the overhead from transmission - delays by 87 per cent compared to XMODEM, but network delays can still - degrade performance. Some networks may not be transmit the 1024 byte - packets unmodified. - - + The handling of files that are not a multiple of 1024 or 128 bytes is - awkward, especially if the file length is not known, or changes during - transmission. - - + YMODEM-g provides efficient batch file transfers, preserving the exact - file length and file modification date. YMODEM-g is essentially - insensitive to network delays. Because it does not support error - recovery, YMODEM-g is usually used hardwired or with a reliable link - level protocol. IF YMODEM-g detects a CRC error, data transfers are - aborted. YMODEM-g is easy to implement because it closely resembles - XMODEM-CRC. - -Another XMODEM "extension" is protocol cheating, referred to as "Turbo -Download" and OverThruster. [2] These sometimes improve XMODEM throughput - - -__________ - - 1. Some Kermit programs support run length encoding. - - - - -Chapter 5 rev051486 Printed 5-16-86 4 - - - - - - - -Chapter 5 rev051486 Printed 5-16-86 5 - - - -at the expense of error recovery. - -The ZMODEM Protocol is proposed as a means of addressing the weaknesses -described above while maintaining as much of XMODEM's simplicity and prior -art as possible. - - - -6. ZMODEM Protocol Design Criteria - -The design of a file transfer protocol is an engineering compromise -between conflicting requirements: - -6.1 Ease of Use - - + ZMODEM allows either program to initiate file transfers, passing - commands and/or modifiers to the other program. - - + File names need be entered only once, menu selections are possible. - - + Wild Card names may be used with batch transfers. - - + Minimum keystrokes required to initiate transfers. - - + ZRQINIT packet sent by sending program can trigger automatic downloads. - - + ZMODEM can step down to YMODEM if the other end does not support - ZMODEM.[1] - -6.2 Throughput - -ZMODEM is designed for optimum performance with minimum degradation caused -by delays introduced by packet switched networks and timesharing systems. - -ZMODEM is optimized for best throughput when line hits occur infrequently. -This assumption markedly reduces code complexity and memory requirements. -ZMODEM protocol features enhance rapid error recovery compared to network -compatible XMODEM implementations. - -It is assumed that many transfers will originate from a timesharing system -connected to a packet switched network. ZMODEM provides features to allow -for simple, efficient implementation on timesharing hosts. - - - -__________________________________________________________________________ - - 2. Omen Technology Trademark - - 1. Provided the transmission medium accomodates YMODEM. - - - - -Chapter 6 rev051486 Printed 5-16-86 5 - - - - - - - -Chapter 6 rev051486 Printed 5-16-86 6 - - - -File transfers begin immediately regardless of which program is started -first, without the 10 second delay associated with XMODEM. - - -6.3 Integrity and Robustness - -All packets are protected with 16 bit CRC. Proprietary alogrithyms[2] are -not needed for reliable transfers. - -A security challenge guards againgst Trojan Horse messages. - -6.4 Ease of Implementation - -ZMODEM accomodates a wide variety of systems: - - + Microcomputers that cannot overlap disk and serial i/o - - + Microcomputers that cannot overlap serial send and receive - - + Computers and/or networks requiring XON/XOFF flow control - - + Computers that cannot check the serial input queue for the presence of - data without having to wait for the data to arrive. - -Although ZMODEM provides "hooks" for multiple "threads", ZMODEM is not -intended to replace link level protocols such as X.25. - -ZMODEM accomodates network and timesharing system delays by continuously -transmitting data unless the receiver interrupts the sender to request -retransmission of garbled data. ZMODEM in effect uses the entire file as -a window.[3] - -ZMODEM provides a general purpose application to application file transfer -protocol which may be used directly or with with reliable link level -protocols such as X.25, MNP, Fastlink, etc. - - -7. ZMODEM BASICS - - - - - - - -__________ - - 2. Unique to Professional-YAM, PowerCom, etc. - - 3. Streaming strategey is discussed in a coming chapter. - - - - -Chapter 7 rev051486 Printed 5-16-86 6 - - - - - - - -Chapter 7 rev051486 Printed 5-16-86 7 - - - -7.1 Packetization - -ZMODEM frames somewhat different from X/YMODEM blocks. X/YMODEM blocks -are not used for the following reasons: - - + Block numbers are limited to 256 - - + No provision for variable length blocks - - + Line hits corrupt protocol signals, causing failed file transfers. In - particular, modem errors sometimes generate false block numbers, false - EOTs and false ACKs. False ACKs are the most troublesome as they cause - the sender to lose synchronization with the receiver. - - State of the art X/YMODEM programs such as Professional-YAM and - PowerCom overcome some of these weaknesses with clever proprietary - code, but a stronger protocol is desired. - - + It is difficult to determine the beginning and ends of X/YMODEM blocks - when line hits cause a loss of synchronization. This precludes rapid - error recovery. - -7.2 Link Escape Encoding - -ZMODEM acheives data transparency by extending the 8 bit character set -(256 codes) with escape sequences based on the ZMODEM data link escape -character ZDLE.[1] - -Link Escape coding permits variable length data packets without the -overhead of a separate byte count. It allows the beginning of frames to -be detected without special timing techniques, facilitating rapid error -recovery. - -Link Escape coding does add some overhead. The worst case, a file -consisting entirely of ZDLE characters, would incur a 50% overhead. - -The ZDLE character is special. ZDLE represents a control sequence of some -sort. If a ZDLE character appears in the data sent within a binary -packet, it is prefixed with ZDLE, then sent as ZDLEE. - -The value for ZDLE is octal 030 (ASCII CAN). This particular value was -chosen to allow a string of CAN characters to abort a ZMODEM session, -compatible with X/YMODEM session abort. - - - -__________ - - 1. This and other constants are defined in the zmodem.h include file. - Please note that constants with a leading 0 are octal constants in C. - - - - -Chapter 7 rev051486 Printed 5-16-86 7 - - - - - - - -Chapter 7 rev051486 Printed 5-16-86 8 - - - -Since CAN is not used for normal terminal operations, communications -programs can monitor the data flow for ZDLE. The following characters can -be scanned to detect the ZRQINIT packet, the invitation to automatically -download commands or files. - -Two successive CAN characters will abort a ZMODEM session. Experience -with YMODEM file transfers suggests that this does not impair the -robustness of the protocol. A minimum of 8 CAN are sent, so the ZMODEM -subroutines can be modified to require more successive CAN characters to -signal an abort. - -The receiving program will decode any sequence of ZDLE followed by a byte -with bit 6 set and bit 5 reset (upper case letter, either parity) to the -equivalent control character by inverting bit 6. This allows the -transmitter to escape any control character that cannot be sent by the -communications medium. The ZMODEM software currently escapes ZDLE, 021, -0221, 023, and 0223. In addition, the receiver recognizes escapes for -0177 and 0377 should these characters need to be escaped. - -7.3 Header Packet Information - -All ZMODEM frames begin with a header packet which may be sent in binary -or HEX form. ZMODEM uses a single routine to recognize binary and hex -header packets. Either form of the header packet contains the same raw -information: - - + A type byte[2] Future extensions to ZMODEM may use the high order bits - of the type byte to indicate thread selection. - - + Four bytes of data indicating flags and/or numeric quantities depending - on the packet type - - Figure 1. Order of Bytes in Header Packet - - - TYPE: packet Type - F0: Flags least significant byte - P0: file Position least significant - P3: file Position most significant - - TYPE F3 F2 F1 F0 - -------------- - TYPE P0 P1 P2 P3 - - - -__________ - - 2. The packet types are cardinal numbers beginning with 0 to minimize - state transition table memory requirements. - - - - -Chapter 7 rev051486 Printed 5-16-86 8 - - - - - - - -Chapter 7 rev051486 Printed 5-16-86 9 - - - -7.4 Binary Header Packet - -A binary header packet is only sent by the sending program to the -receiving program. - -A binary header packet begins with the sequence ZPAD, ZDLE, ZBIN. - -The frame type byte is ZDLE encoded. - -The four position/flags bytes are ZDLE encoded. - -A two byte CRC of the frame type and position/flag bytes is ZDLE encoded. - -0 or more binary data packets will follow depending on the frame type. - -The function zsbhdr transmits a binary header packet. The function -zgethdr receives a binary or hex header packet. - - Figure 2. Binary Header Packet - * * ZDLE TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 - - -7.5 HEX Header Packet - -The receiver sends responses in hex header packets. The sender also uses -hex header packets when they are not followed by binary data packets. - -Hex encoding is required to support XON/XOFF flow control. The hex header -receiving routine ignores flow control characters. - -Use of Kermit style encoding for control and paritied characters was -considered and rejected because of increased possibility of interacting -with some timesharing systems's line edit functions. Use of HEX packets -from the receiving program allows control characters to be used to -interrupt the sender when errors are detected. Except for header packet -types that imply data packets to follow, a HEX header packet may be used -in place of a binary header packet. - -A hex header packet begins with the sequence ZPAD, ZPAD, ZDLE, ZHEX. The -zgethdr routine synchronizes in the ZPAD-ZDELE sequence. The extra ZPAD -allows other parts of the program to detect a ZMODEM packet and then call -zgethdr to receive the packet. - -The type byte, the four position/flag bytes, and the CRC thereof are sent -in hex using the character set 01234567890abcdef. Upper case hex digits -are not allowed; they false trigger X/YMODEM programs. - -A carriage return, line feed, and XON are appended to the HEX header -packet but are not considered to be part of it. The CR/LF aids debugging -from printouts. The XON releases the sender from spurious XOFF flow -control characters generated by line noise, a common occurrence. - - - -Chapter 7 rev051486 Printed 5-16-86 9 - - - - - - - -Chapter 7 rev051486 Printed 5-16-86 10 - - - -0 or more ASCII Encoded data packets will follow depending on the frame -type. - -The function zshhdr sends a hex header packet. - - Figure 3. HEX Header Packet - * * ZDLE TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON - -(TYPE, F3...F0, CRC-1, and CRC-2 are each sent as two hex digits.) - - -7.6 Binary Data Packets - -Binary data packets immediately follow the associated binary header -packet. A binary data packet contains 0 to 1024 bytes of data. -Recommended length values are 256 bytes below 4800 bps, 1024 above 4800 -bps or when the data link is known to be relatively error free. - -No padding is used with binary data packets. The data bytes are ZDLE -encoded and transmitted. A ZDLE and frameend are then sent, followed by -two ZDLE encoded CRC bytes. The CRC accumulates the data bytes and -frameend. - -The function zsbdata sends a binary data packet. The function zrbdata -receives a binary data packet. - -7.7 ASCII Encoded Data Packet - -The format of ASCII Encoded data packets is not currently specified. -These would be used for server commands, etc. - - -8. PROTOCOL TRANSACTION OVERVIEW - -As with the XMODEM recommendation, ZMODEM timing is receiver driven. The -transmitter should not time out at all, except to abort the program if no -packets are received for an extended period of time, say one minute.[1] - -To start a ZMODEM file transfer session, the sending program is called -with the names of the desired file(s) and option(s). - -The sending program sends the string "rz\r" to invoke the receiving -program from a possible command mode. The "rz" followed by carriage -return activates a ZMODEM receive program or command if it were not -already active. - - -__________ - - 1. Special considerations apply when sending commands. - - - - -Chapter 8 rev051486 Printed 5-16-86 10 - - - - - - - -Chapter 8 rev051486 Printed 5-16-86 11 - - - -The sender may then display a message intended for human consumption, such -as a list of the files requested, etc. - -Then the sender sends a ZRQINIT packet. The ZRQINIT packet causes a -previously started receive program to send its ZRINIT packet without -delay. - -In an interactive or conversational mode, the receiving application may -monitor the data stream for ZDLE. The following characters may be scanned -for B000000 indicating a ZRQINIT packet, a command to download a command -or data. - -The sending program awaits a command from the receiving program to start -file transfers. If a "C", "G", or NAK is received, an XMODEM or YMODEM -file transfer is indicated, and file transfer(s) use the X/YMODEM -protocol. Note: With ZMODEM and YMODEM Batch, the sending program -provides the file name, but not with XMODEM. - -When the ZMODEM receive program starts, it immediately sends a ZRINIT -packet to initiate ZMODEM file transfers, or a ZCHALLENGE packet to verify -the sending program. The receive program resends its packet at repsonse -time intervals for a suitable period of time (40 seconds typical) before -falling back to X/YMODEM protocol. If the receiving program receives a -ZRQINIT packet, it resends the ZRINIT packet. If the sending program -receives the ZCHALLENGE packet, it places the data in ZP0...ZP3 in an -answering ZACK packet. - -If the receiving program receives a ZRINIT packet, it is an echo -indicating that the sending program is not operational. - -Eventually the sending program correctly receives the ZRINIT packet. - -The sender may then respond with an optional ZSINIT frame to set the -receiving program's Attention string. The receiver sends a ZACK packet in -response, containing the serial number of the receiving program, or 0. - -The sender then sends a ZFILE header with ZMODEM Conversion, Management, -and Transport options[2] followed by a ZCRCW data packet containing the -file name, file length, modification date, and other information identical -to that used by YMODEM Batch. - -The receiving program should insure the pathname and options are -compatible with its operating environment and local security requirements. - - - - -__________ - - 2. See below, under ZFILE packet type. - - - - -Chapter 8 rev051486 Printed 5-16-86 11 - - - - - - - -Chapter 8 rev051486 Printed 5-16-86 12 - - - - If the receiver has a file with the same name and length, - it may respond with a ZCRC packet, which requires the - sender to permorm a 16 bit CRC on the file and transmit the - CRC in ZP0...ZP1 of a ZCRC packet. The receiver uses this - information to determine whether to accept the file or skip - it. This sequence is triggered by the ZMCRC Management - Option. - -The receiver may then respond with a ZSKIP packet, which causes the -sender to process the next file (if any) in the batch. - -A ZRPOS packet from the receiver initiates transmission of the file data -starting at the offset in the file specified in the ZRPOS packet. -Normally the receiver specifies the data transfer begin begin at offset 0 -in the file. - The receiver may start the transfer further down in the - file. This allows a file transfer interrupted by a loss - or carrier or system crash to be completed on the next - connection without requiring the entire file to be - retransmitted.[3] If downloading a file from a timesharing - system that becomes sluggish, the transfer can be - interrupted and resumed later with no loss of data. - -The sender sends a ZDATA binary header packet (with file position) -followed by one or more data packets. - -The receiver compares the file position in the ZDATA header with the -number of characters successfully received to the file. If they do not -agree, a ZRPOS error response is generated to force the sender to the -right position within the file.[4] - -A data packet terminated by ZCRCGO and CRC does not elicit a response -unless an error is detected; more data packet(s) follow immediately. - - ZCRCQ data packets expect a ZACK response (with the file - offset) if no error, otherwise a ZRPOS response (with the - last good file offset). Another data packet continues - immediately. ZCRCQ packets are not used if the receiver - does not indicate FDX ability with the CANFDX bit. - -ZCRCW data packets expect a response before the next frame is sent. If -the receiver does not indicate overlapped I/O capability with the - - -__________ - - 3. This does not apply to files that have been translated. - - 4. If the ZMSPARS option is used, the receiver instead seeks to position - in the ZDATA packet. - - - - -Chapter 8 rev051486 Printed 5-16-86 12 - - - - - - - -Chapter 8 rev051486 Printed 5-16-86 13 - - - -CANOVIO bit, or by setting a buffer size, the sender uses the ZCRCW to -allow the receiver to write its buffer before sending more data. - - A zero length data frame may be used as a sending idle - packet to prevent the receiver from timing out in case - data is not immediately available to the sender. - -In the absence of fatal error, the sender eventually encounters end of -file. If the end of file is encountered within a frame, the frame is -closed with a ZCRCE data packet which does not elicit a response -except in case of error. - -The sender sends a ZEOF packet with the file ending offset equal to -the number of characters in the file. The receiver compares this -number with the number of characters received. If the receiver has -received all of the file, it closes the file. If the file close was -satisfactory, the receiver responds with ZRINIT. If the receiver has -not received all the bytes of the file, the receiver sends ZRPOS with -the current file offset, forcing the sender to resend the missing -data. (If the receiver cannot properly close the file, a ZFERR packet -is sent.) - - After all files are processed, any further protocol - errors should not prevent the sending program from - returning with a success status. - -The sender closes the session with a ZEXIT header packet. The -receiver acknowledges this with its own ZEXIT packet. - -When the sender receives the acknowledging packet, it sends two -characters, "OO" (Over and Out) and exits to the operating system or -application that invoked it. The receiver waits briefly for the "O" -characters, then exits whether they were received or not. - -8.1 Session Cancel Packet - -The Cancel packet consists of two ZPAD characters, eight CAN -characters, and an optional ten backspace characters. First, the -Attn sequence is executed if the receiving program has been receiving -data in streaming mode. The ZPAD characters allow sending programs -that sample the reverse data stream to check for a single character -code indicating a packet from the receiver. The trailing backspace -characters attempt to erase the effects of the other characters if -they are received by a command interpreter. - - static char canistr[] = { -ZPAD,ZPAD,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0 }; - - - - - - - -Chapter 9 rev051486 Printed 5-16-86 13 - - - - - - - -Chapter 9 rev051486 Printed 5-16-86 14 - - - -9. ZMODEM STREAMING TECHNIQUES - -ZMODEM allows choices of several data streaming methods selected -according to the limitations of the sending environment, receiving -environment, and transmission channel(s). - - -9.1 Full Streaming with Sampling - -If the computers can overlap serial I/O with disk I/O, and if the -sender can sample the reverse channel for the presence of data -without having to wait, full streaming can be used with no Attn -sequence required. The sender begins data transmission with a ZDATA -header and continuous ZCRCG data packets. When the receiver detects -an error, it executes the Attn sequence and then sends a ZRPOS packet -to force the sender back to the correct position within the file. At -the end of each transmitted packet, the sender checks for the -presence of an error packet from the receiver. To do this, the -sender may sample the reverse data stream for the presence of a ZPAD -character. - -Such a program would sample the reverse channel for ZPAD. If seen, -an empty ZCRCW data packet is sent (in case the receiver was still -reading packets) and then the receiver's response packet is read and -acted upon. The code fragment in sz.c beginning at NOTDEF_DOS would -perform this function. - - -9.2 Full Streaming with Interrupt - -The method above cannot be used if if the reverse data stream cannot -be sampled without entering an I/O wait. An alternate method is to -instruct the receiver to interrupt the sending program when an error -is detected. - -The receiver can interrupt the sender with a control character, break -signal, or combination thereof, as specified in the ZSINIT frame sent -by the sending program. - -When the sending program "catches" this interrupt, it reads a HEX -packet (normally ZRPOS) from the receiver and takes appropriate -action. The Unix sb.c program uses a setjmp/longjmp call and the -getinsync() function to read the receiver's error packet and take -appropriate action. - - - - - - - - - - -Chapter 9 rev051486 Printed 5-16-86 14 - - - - - - - -Chapter 9 rev051486 Printed 5-16-86 15 - - - -9.3 Full Streaming with a Sliding Window - -If none of the above methods is applicable, hope is not yet lost. If -the sender can buffer responses from the receiver, the sender can use -ZCRCQ packets to get ACKs from the receiver without interrupting the -transmission of data. After a sufficient number of ZCRCQ packets -have been sent, the sender can read one of the one or more packets -that should have arrived in it's receive interrupt buffer. - -A problem with this method is the probability of wasting an excessive -amount of time responding to the receiver's error packet. - -9.4 No Streaming - -If the receiver cannot overlap serial and disk I/O, it uses the -ZRINIT frame to specify a buffer length which the sender will not -overflow. The sending program sends a ZCRCW packet and waits for an -ZACK packet before sending the next segment of the file. - -If the sending program supports reverse data stream sampling or -interrupt, error recovery will be faster (on average) than a protocol -(such as YMODEM) that sends "monolithic" blocks. - - -10. ATTENTION SEQUENCE - -The receiving program sends the Attn sequence whenever it detects an -error and needs to interrupt the sending program. - -The default Attn string value is empty (no Attn sequence). The -receiving program resets Attn to the empty default before each -transfer session. - -The sender speficies the Attn sequence in its optional ZSINIT frame. -The Attn string is terminated with a null. - -Two meta-characters perform special functions: - - + \335 (octal) Sends a break signal - - + \336 (octal) Pauses one second - - -11. PACKET/FRAME TYPES - -The numeric values for the values shown in boldface are given in -zmodem.h. - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 15 - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 16 - - - -11.1 ZRQINIT - -Sent once by the sending program, to trigger the receiving program to -send its ZRINIT packet. This aviods the aggravatimg startup delay -associated with XMODEM and Kermit transfers. - -ZF0 contains ZCOMMAND if the program is attempting to send a command, -0 otherwise. - -11.2 ZRINIT - -Sent by the receiving program. ZF0 and ZF1 contain the bitwise or -of the receiver capability flags: -#define CANFDX 1 /* Rx can send and receive FDX */ -#define CANOVIO 2 /* Rx can receive during disk I/O */ -#define CANBRK 4 /* Rx can send a break signal */ -#define CANCRY 8 /* Receiver can decrypt */ - -ZP0 and ZP1 contain the size of the receiver's buffer in bytes, or 0 -if nonstop I/O is allowed. - -11.3 ZSINIT - -Sender sends capability flags (currently all 0) (none currently -defined) followed by a binary data packet terminated with ZCRCW. The -data packet contains the null terminated Attn sequence, maximum -length 32 bytes including the terminating null. - -11.4 ZACK - -Acknowedgement to ZSINIT header packet, ZCHALLENGE header packet, or -ZCRCW data packet. ZP0 to ZP3 contain file offset. Response to -ZCHALLENGE contains the same 32 bits as received. - -11.5 ZFILE - -This packet denotes the beginning of a file transmission attempt. -ZF0, ZF1, and ZF2 may contain options. A value of 0 in each of these -bytes implies no special treatment. If options are specified to the -reciever, they override options specified to the sender with the -exception of the ZCBIN option, which overrides any other Conversion -Option. - - -11.5.1 ZF0: Conversion Option -If the receiver does not recognize the Conversion Option, an -application dependent default conversion may apply. - -ZCBIN "Binary" transfer - inhibit conversion unconditionally - - - - - -Chapter 11 rev051486 Printed 5-16-86 16 - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 17 - - - -ZCNL Convert received end of line to local end of line convention. - The suported end line conventions are CR/LF (most ASCII based - operating systems except Unix and Macintosh), and NL (Unix). - Neither of these two end of line conventions violate the - permissible ASCII definitions for Carriage Return and Line - Feed/New Line. - -ZCRECOV Recover interrupted file transfer; start transfer at location - corresponding to the receiver's end of file. This option does - not apply if the source file is shorter. Files that have been - converted (e.g., ZCNL) or subject to a single ended Transport - Option cannot have their transfers recovered. - -11.5.2 ZF1: Management Option -If the receiver does not recognize the Management Option, the file -should be transferred normally. - -ZMNEW Compare the source and destination files. Transfer file if - source newer or different length - -ZMCRC Compare the source and destination files. Transfer if - different file length or CRC - -ZMAPND Append source file contents to existing destination file (if - any) - -ZMCLOB Replace existing destination file (if any) - -ZTSPARS Special processing for sparse file; each file segment is - transmitted as a separate frame, where the frames are not - necessarily contiguous. - -11.5.3 ZF2: Transport Option -If the receiver does not implement the particular transport option, -the file is copied without conversion for later processing. - -ZTLZW Lempel-Ziv compression. Transmitted data will be identical to - that produced by compress 4.0 operating on a computer with VAX - byte ordering, using 12 bit encoding. - -ZTCRYPT Encryption. An initial null terminated string identifies the - key. Details to be determined. - -ZTRLE Run Length encoding Details to be determined. - -A ZCRCW data packet follows with file name, file length, modification -date, and other information described in a later chapter. - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 17 - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 18 - - - -11.6 ZSKIP - -Sent by the receiver in response to ZFILE, makes the sender skip to -the next file. - -11.7 ZNAK - -Indicates last packet header was garbled. (See also ZRPOS). - -11.8 ZABORT - -Sent by receiver to terminate batch file transfers when requested by -the user. Sender initiates a ZFIN sequence.[1] - -11.9 ZFIN - -Sent by sending program to terminate a ZMODEM session. Receiver -responds with ZFIN. - -11.10 ZRPOS - -Sent by receiver to force file transfer to resume at file offset -given in ZP0...ZP3. - -11.11 ZDATA - -ZP0...ZP3 contain file offset. One or more data packets follow. - -11.12 ZEOF - -Sender reports End of File. ZP0...ZP3 contain the ending file -offset. - -11.13 ZFERR - -Error in reading or writing file, protocol equivalent to ZABORT. - -11.14 ZCRC - -Request (receiver) and response (sender) for file CRC. ZP0 and ZP1 -contain 16 bit file CRC. - - - - - - -__________ - - 1. Or ZCOMPL in case of server mode. - - - - -Chapter 11 rev051486 Printed 5-16-86 18 - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 19 - - - -11.15 ZCHALLENGE - -Request to echo a random number in ZP0...ZP3 in a ZACK frame. Sent -by the receiving program to the sending program to verify that it is -connected to an operating program, and was not activated by spurious -data or a Trojan Horse message. - -11.16 ZCOMPL - -Request now completed. - -11.17 ZCAN - -This is a pseudo frame type returned by gethdr() in response to a -Cancel sequence. - -11.18 ZFREECNT - -Sending program requests a ZACK frame with ZP0...ZP3 containing the -number of free bytes on the current file system. A value of 0 -represents an indefinite amount of free space. - -11.19 ZCOMMAND - -ZCOMMAND is only sent as a binary header packet. ZP0...ZP2 contain a -unique cardinal number to differentiate this command from other -commands[2]. ZF0 contains 0 or ZCACK1. - - -A ZCRCW data packet follows, with the ASCII text command string -terminated with a NULL character. If the command is intended to be -executed by the operating system hosting the receiving program (e.g., -"shell escape"), it must have "!" as the first character. Otherwise -the command is meant to be executed by the application program which -received the command. - -If ZF0 contained ZCACK1, the receiver immediately responds with a -ZCOMPL header. Otherwise, the receiver responds with a ZCOMPL header -when the operation is completed. - -The exit status of the completed command is stored in ZP0...ZP3 (0 if -ZCACK1). A 0 exit status implies nominal completion of the command. - -If the command caused a file to be transmitted, the command sender -will see a ZRQINIT frame from the other computer attempting to send - - -__________ - - 2. Currently unused. - - - - -Chapter 11 rev051486 Printed 5-16-86 19 - - - - - - - -Chapter 11 rev051486 Printed 5-16-86 20 - - - -data. - -The sender examines ZF0 of the received ZRQINIT packet to determine -it is not an echo of its own ZRQINIT packet. It is illegal for the -sending program to command the receiving program to send a command. - - - -12. TRANSACTION EXAMPLE - -12.1 A simple file transfer - -A simple transaction, one file, no errors, no CHALLENGE, overlapped -I/O: - -Sender Receiver - -"rz\r" -ZRQINIT(0) - ZRINIT -ZFILE - ZRPOS -ZDATA data ... -ZEOF - ZRINIT -ZFIN - ZFIN -OO - - -12.2 Challenge and Command Download - - -Sender Receiver - -"rz\r" -ZRQINIT(ZCOMMAND) - ZCHALLENGE(rnd) -ZACK(same-rnd) - ZRINIT -ZCOMMAND - (Perform Command) - ZCOMPL -ZFIN - ZFIN -OO - - - - - - - - -Chapter 13 rev051486 Printed 5-16-86 20 - - - - - - - -Chapter 13 rev051486 Printed 5-16-86 21 - - - -13. ZFILE FRAME FILE INFORMATION - -ZMODEM sends the same file information with the ZFILE frame data that -YMODEM Batch sends in its block 0. - -N.B.: Only the pathname (file name) part is s required for batch -transfers. - -Pathname The pathname (conventionally, the file name) is sent as a - null terminated ASCII string. This is the filename format used - by the handle oriented MSDOS(TM) functions and C library fopen - functions. An assembly language example follows: - DB 'foo.bar',0 - No spaces are included in the pathname. Normally only the file - name stem (no directory prefix) is transmitted unless the sender - has selected YAM's f option to send the full relative pathname. - The source drive designator (A:, B:, etc.) is not sent. - - Filename Considerations: - - + File names should be translated to lower case unless the - sending system supports upper/lower case file names. This - is a convenience for users of systems (such as Unix) which - store filenames in upper and lower case. - - + The receiver should accommodate file names in lower and - upper case. - - + The rb(1) program on Unix systems normally translates the - filename to lower case unless one or more letters in the - filename are already in lower case. - - + When transmitting files between different operating - systems, file names must be acceptable to both the sender - and receiving operating systems. - - If directories are included, they are delimited by /; i.e., - "subdir/foo" is acceptable, "subdir\foo" is not. - -Length The file length and each of the succeeding fields are - optional.[1] The length field is stored as a decimal string - counting the number of data bytes in the file. - - With ZMODEM, the receiver uses the file length only for display - (progress reporting) purposes; the actual length is determined - - -__________ - - 1. Fields may not be skipped. - - - - -Chapter 13 rev051486 Printed 5-16-86 21 - - - - - - - -Chapter 13 rev051486 Printed 5-16-86 22 - - - - by the data transfer. - -Modification Date A single space separates the modification date from - the file length. - - The mod date is optional, and the filename and length may be - sent without requiring the mod date to be sent. - - The mod date is sent as an octal number giving the time the - contents of the file were last changed measured in seconds from - Jan 1 1970 Universal Coordinated Time (GMT). A date of 0 - implies the modification date is unknown and should be left as - the date the file is received. - - This standard format was chosen to eliminate ambiguities arising - from transfers between different time zones. - - Two Microsoft blunders complicate the use of modification dates - in file transfers with MSDOS(TM) systems. The first is the lack - of timezone standardization in MS-DOS. A file's creation time - can not be known unless the timezone of the system that wrote - the file[2] is known. Unix solved this problem (for planet - Earth, anyway) by stamping files with Universal Time (GMT). - Microsoft would have to include the timezone of origin in the - directory entries, but does not. Professional-YAM gets around - this problem by using the z parameter which is set to the number - of minutes local time lags GMT. For files known to originate - from a different timezone, the -zT option may be used to specify - T as the timezone for an individual file transfer. - - The second problem is the lack of a separate file creation date - in DOS. Since some backup schemes used with DOS rely on the - file creation date to select files to be copied to the archive, - back-dating the file modification date could interfere with the - safety of the transferred files. For this reason, - Professional-YAM does not modify the date of received files with - the header information unless the d parameter is non zero. - - -Mode A single space separates the file mode from the modification - date. The file mode is stored as an octal string. Unless the - file originated from a Unix system, the file mode is set to 0. - rb(1) checks the file mode for the 0x8000 bit which indicates a - Unix type regular file. Files with the 0x8000 bit set are - assumed to have been sent from another Unix (or similar) system - - -__________ - - 2. Not necessarily that of the transmitting system! - - - - -Chapter 13 rev051486 Printed 5-16-86 22 - - - - - - - -Chapter 13 rev051486 Printed 5-16-86 23 - - - - which uses the same file conventions. Such files are not - translated in any way. - - -Serial Number A single space separates the serial number from the - file mode. The serial number of the transmitting program is - stored as an octal string. Programs which do not have a serial - number should omit this field, or set it to 0. The receiver's - use of this field is optional. - -The file information is terminated by a null. If only the pathname -is sent, the pathname will be terminated by two nulls. The length of -the file information packet, including the trailing null, must not -exceed 1024 bytes; a typical length is less than 64 bytes. - - -14. PERFORMANCE RESULTS - -14.1 Throughput - -Between two single task PC-XT computrers, on a Telenet link through -the local Telenet, SuperKermit gave 72 ch/sec throughput at 1200 -baud. YMODEM-k yielded 85 chars/sec, and ZMODEM provided 113 chat -sec. ZMODEM was not measured, but would have given much less. - -14.2 Error Recovery - -Some tests of ZMODEM protocol performance have been made. A PC-AT -with SCO SYS V Xenix or DOS 3.1 was connected to a PC with DOS 2.1 -either directly at 9600 bps or with unbuffered dial-up 1200 bps -modems. The ZMODEM software was configured to use 1024 byte packet -lengths above 2400 bps, 256 otherwise. - -Because no time delays are necessary in normal file transfers, per -file negotiations are much faster than with YMODEM, the only observed -impidiment being the time required by the program(s) to update -logging files. - -During a file transfer, a short line hit seen by the receiver usually -induces a CRC error. The interrupt packet is usually seen by the -sender before the next packet is sent, and the resultant loss of data -throughput averages about half a packet. At 1200 bps this is would -be about .75 second lost per hit. At 10-5 error rate, this would -degrade throughput by about 9 per cent. The throughput degradation -increases with the channel delay, as the packets in transit through -the channel are discarded on error. - -A longer noise burst that affects both the receiver and the sender's -reception of the interrupt packet usually causes the sender to remain -silent until the receiver times out in 10 seconds. If the round trip -channel delay exceeds the receiver's 10 second timeout, recovery from - - - -Chapter 14 rev051486 Printed 5-16-86 23 - - - - - - - -Chapter 14 rev051486 Printed 5-16-86 24 - - - -this type of error may become difficult. - -Noise affecting only the sender is usually ignored, with one common -exception. Spurious XOFF characters generated by noise stop the -sender until the receiver times out and sends an interrupt packet -which concludes with an XON. - -In summation, ZMODEM performance in the presence of errors resembles -that of X.PC and SuperKermit. Short bursts cause minimuml data loss. -Long bursts (such as pulse dialing noises) often require a timeout -error to restore the flow of data. - - -15. PACKET SWITCHED NETWORK CONSIDERATIONS - -Flow control is necessary for printing messages and directories, and -for streaming file transfer protocols including Kermit Sliding -Windows and ZMODEM. A non transparent flow control is incompatible -with XMODEM and YMODEM transfers. XMODEM and YMODEM protocols -require complete transparency of all 256 8 bit codes to operate -properly. - -The most desireable flow control (when X.25 or hardware CTS is -unavailable) does not "eat" any characters at all. When the PAD's -buffer almost fills up, an XOFF should be emitted. When the buffer -is no longer nearly full, send an XON. Otherwise, the network should -neither generate nor eat XON or XOFF control characters. - -On Telenet, this can be met by setting CCIT X3 5:1 and 12:0 at both -ends of the network. For best throughput, parameter 64 (advance ACK) -should be set to something like 4. Packets should be sent when the -packet is a full 128 bytes, or after a moderate delay (3:0,4:10,6:0). - -For YMODEM, PAD buffering should guarantee that a minimum of 1040 -characters can be sent in a burst without loss of data or generation -of flow control characters. Failure to provide this buffering will -generate excessive retries with YMODEM. - - Figure 4. Flow Control Compatibility - - Connectivity Interactive XMODEM KERMIT ZMODEM - -Direct Connection YES YES YES YES -Network, no flow control NO YES (1) (1) -Network, transparent f.c. YES YES YES YES -Network, semi-transparent f.c. YES NO YES YES -Network, 7 bit YES NO YES(2) NO(3) - -(1) Cannot operate in streaming mode. Kermit is very slow because of -96 byte max packet size. ZMODEM can adjust burst length to maximum -for faster transfers. - - - -Chapter 15 rev051486 Printed 5-16-86 24 - - - - - - - -Chapter 15 rev051486 Printed 5-16-86 25 - - - -(2) Parity bits must be encoded, slowing binary transfers. - -(3) Extension possible for encoding data to 7 bits. - - - -16. PERFORMANCE COMPARISION TABLES - - -"Round Trip Delay Time" includes the time for the last byte in a -packet to propagate through the operating systems and network to the -receiver, plus the time for the receiver's response to that packet to -propogate back to the sender. - -The figures shown below are calculated for round trip delay times of -40 milliseconds and 5 seconds. Shift registers in the two computers -and a pair of 212 modems generate a round trip delay time on the -order of 40 milliseconds. Operation with busy timesharing computers -and networks can easily generate round trip delays of five seconds. -Because the round trip delays cause visible interruptions of data -transfer when using XMODEM protocol, the subjective effect of these -delays is greatly exaggerated, especially when the user is paying for -connect time. - -A 102400 byte binary file with randomly distributed codes is sent at -1200 bps 8 data bits, 1 stop bit. The calculations assume no -transmission errors. For each of the protocols, only the per file -functions are considered. Processor and I/O overhead are not -included. YM-k refers to YMODEM with 1024 byte packets. YM-g refers -to the YMODEM "g" option. ZMODEM uses 256 byte packets for this -example. SuperKermit uses maximum packet size, 8 bit transparent -transmission, no run length compression. - -For comparison, a straight "dump" of the file contents with no file -management or error checking takes 853 seconds. - - Figure 5. Protocol Overhead Information - - Protocol XMODEM YM-k YM-g ZMODEM S-Kermit - -Protocol Round Trips 803 103 5 5 5 -Trip Time at 40ms 32s 4s 0 0 0 -Trip Time at 5s 4015s 515s 25s 25s 25 - -Overhead Characters 4803 603 503 3600 38280 - -Transfer Time at 0s 893s 858s 857s 883s 1172s -Transfer Time at 40ms 925s 862s 857s 883s 1172s -Transfer Time at 5s 5761s 1373s 882s 918s 1197s - - - - - -Chapter 16 rev051486 Printed 5-16-86 25 - - - - - - - -Chapter 16 rev051486 Printed 5-16-86 26 - - - - Figure 6. Transmission Time Comparision - (5 Second Round Trip) - -************************************************** XMODEM -************ YMODEM-K -********** SuperKermit (Sliding Windows) -******* YMODEM-G -******* ZMODEM - - Figure 7. Y/ZMODEM Header Information usage - - - Program Batch Length Date Mode S/N YMODEM-g ZMODEM - Unix rb/sb yes yes yes yes no sb only no - Unix rz/sz yes yes yes yes no sz only yes - VMS rb/sb yes yes no no no no no - Pro-YAM yes yes yes no yes yes yes - CP/M YAM yes no no no no no no - KMD/IMP yes yes- no no no no no - MEX no no no no no no no - - -17. MORE INFORMATION - -More information may be obtained by calling Telegodzilla at -503-621-3746. - -UUCP sites can obtain the nroff/troff source to this file with - uucp omen!/usr/caf/public/zmodem.mm /tmp -A continually updated list of available files is stored in -/usr/spool/uucppublic/FILES. - -The following L.sys line calls site "omen" yia UUCP. Telegodzilla -uses Pro-YAM in host operation. - -In response to "Name Please:" uucico gives the Pro-YAM "link" command -as a user name. The password (Giznoid) controls access to the Xenix -system connected to the IBM PC's other serial port. Communications -between Pro-YAM and Xenix use 9600 bps; YAM converts this to the -caller's speed. - -Finally, the calling uucico logs in as uucp. - - omen Any ACU 1200 1-503-621-3746 e:--e: link d: Giznoid n:--n: uucp - - - - - - - - - - -Chapter 18 rev051486 Printed 5-16-86 26 - - - - - - - -Chapter 18 rev051486 Printed 5-16-86 27 - - - -18. ZMODEM PROGRAMS - -A demonstration version of Professional-YAM is available as -YAMDEMO.ARC on TeleGodzilla.. This file must be unpacked with the -"ARC" program, version 5 or later. A copy of ARC is available as -"ARC.EXE" or "ARC510.COM" on TeleGodzilla. - - -This may be used to test ZMODEM and YMODEM implementations. A -flash-up tree structured help file and processor are provided in -YAMHELP.LQR. - - - -19. YMODEM PROGRAMS - -Unix programs supporting the YMODEM protocol are available on -Telegodzilla in the "upgrade" subdirectory as RBSB.SHQ (a SQueezed -shell archive). Most Unix like systems are supported, including V7, -Sys III, 4.2 BSD, SYS V, Idris, Coherent, and Regulus. - -A version for VAX-VMS is available in VRBSB.SHQ, in the same -directory. - -Irv Hoff has added YMODEM 1k packets and YMODEM batch transfers to -the KMD and IMP series programs, which replace the XMODEM and -MODEM7/MDM7xx series respectively. Overlays are available for a wide -variety of CP/M systems. - -Many other programs, including MEX and MEX-PC also support some of -the YMODEM extensions. - -Questions about YMODEM, the Professional-YAM communications program, -and requests for evaluation copies may be directed to: - - Chuck Forsberg - Omen Technology Inc - 17505-V Sauvie Island Road - Portland Oregon 97231 - Voice: 503-621-3406 - Modem (Telegodzilla): 503-621-3746 - Usenet: ...!tektronix!reed!omen!caf - Compuserve: 70715,131 - Source: TCE022 - - Yours very truly, - - - - - - - - -Chapter 19 rev051486 Printed 5-16-86 27 - - - - - - - - - - - - CONTENTS - - - 1. INTENDED AUDIENCE................................................ 2 - - 2. ACKNOWLEDGMENTS.................................................. 2 - - 3. RELATED DOCUMENTS................................................ 2 - - 4. ROSETTA STONE.................................................... 2 - - 5. WHY DEVELOP ZMODEM?.............................................. 3 - - 6. ZMODEM Protocol Design Criteria.................................. 5 - 6.1 Ease of Use............................................... 5 - 6.2 Throughput................................................ 5 - 6.3 Integrity and Robustness.................................. 6 - 6.4 Ease of Implementation.................................... 6 - - 7. ZMODEM BASICS.................................................... 6 - 7.1 Packetization............................................. 7 - 7.2 Link Escape Encoding...................................... 7 - 7.3 Header Packet Information................................. 8 - 7.4 Binary Header Packet...................................... 9 - 7.5 HEX Header Packet......................................... 9 - 7.6 Binary Data Packets....................................... 10 - 7.7 ASCII Encoded Data Packet................................. 10 - - 8. PROTOCOL TRANSACTION OVERVIEW.................................... 10 - 8.1 Session Cancel Packet..................................... 13 - - 9. ZMODEM STREAMING TECHNIQUES...................................... 14 - 9.1 Full Streaming with Sampling.............................. 14 - 9.2 Full Streaming with Interrupt............................. 14 - 9.3 Full Streaming with a Sliding Window...................... 15 - 9.4 No Streaming.............................................. 15 - -10. ATTENTION SEQUENCE............................................... 15 - -11. PACKET/FRAME TYPES............................................... 15 - 11.1 ZRQINIT................................................... 16 - 11.2 ZRINIT.................................................... 16 - 11.3 ZSINIT.................................................... 16 - 11.4 ZACK...................................................... 16 - 11.5 ZFILE..................................................... 16 - 11.6 ZSKIP..................................................... 18 - 11.7 ZNAK...................................................... 18 - 11.8 ZABORT.................................................... 18 - 11.9 ZFIN...................................................... 18 - 11.10 ZRPOS..................................................... 18 - 11.11 ZDATA..................................................... 18 - - - - - i - - - - - - - - - - - - - 11.12 ZEOF...................................................... 18 - 11.13 ZFERR..................................................... 18 - 11.14 ZCRC...................................................... 18 - 11.15 ZCHALLENGE................................................ 19 - 11.16 ZCOMPL.................................................... 19 - 11.17 ZCAN...................................................... 19 - 11.18 ZFREECNT.................................................. 19 - 11.19 ZCOMMAND.................................................. 19 - -12. TRANSACTION EXAMPLE.............................................. 20 - 12.1 A simple file transfer.................................... 20 - 12.2 Challenge and Command Download............................ 20 - -13. ZFILE FRAME FILE INFORMATION..................................... 21 - -14. PERFORMANCE RESULTS.............................................. 23 - 14.1 Throughput................................................ 23 - 14.2 Error Recovery............................................ 23 - -15. PACKET SWITCHED NETWORK CONSIDERATIONS........................... 24 - -16. PERFORMANCE COMPARISION TABLES................................... 25 - -17. MORE INFORMATION................................................. 26 - -18. ZMODEM PROGRAMS.................................................. 27 - -19. YMODEM PROGRAMS.................................................. 27 - - - - - - - - - - - - - - - - - - - - - - - - - - - - ii - - - - - - - - - - - - - - - - LIST OF FIGURES - - -Figure 1. Order of Bytes in Header Packet............................ 8 - -Figure 2. Binary Header Packet....................................... 9 - -Figure 3. HEX Header Packet.......................................... 10 - -Figure 4. Flow Control Compatibility................................. 24 - -Figure 5. Protocol Overhead Information.............................. 25 - -Figure 6. Transmission Time Comparision.............................. 26 - -Figure 7. Y/ZMODEM Header Information usage.......................... 26 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - iii - - - - - - - - - - - The ZMODEM Asynchronous Inter Application File Transfer Protocol - - Chuck Forsberg - - Omen Technology Inc - - - ABSTRACT - - - -The ZMODEM file transfer protocol greatly simplifies file transfers -compared to XMODEM. In addition to supporting a transparent user -interface, ZMODEM provides Personal Computer and other users an efficient, -accurate, robust file transfer method. - -ZMODEM provides especially efficient file transfers with timesharing -systems, satellite relays, and wide area packet switched networks. A -choice of buffering and windowing modes allow ZMODEM to operate -efficiently on systems that cannot support some other streaming protocols. - -ZMODEM provides advanced file management features including AutoDownload, -remote file compare, aborted transfer recovery, selective file transfers, -and security verified command downloading. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -sא[ E 0bsu@;w`R00 -Xv{u P -eQBm -Ї0h+0  [ 0 s0O0y8`Y80 OPcX 0sPPh O;>P]İp 0jǠ> t F (P H%upNj&k` Ǎ@TհʠAEP]  r6E%wrpp A$@X@rI&p o@%Fs - - f^ s -F - `pgt Y3),`ƠH'0%yr+i0P  8l(Ҁ?iB[i^9Dgjɖ,9or