Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!apple!bionet!ames!elroy!usc!orion.cf.uci.edu!uci-ics!zardoz!dhw68k!bob From: bob@dhw68k.cts.com (Bob Best) Newsgroups: comp.os.minix Subject: zterm - background zmodem with dialer (Part 3/5) Message-ID: <23579@dhw68k.cts.com> Date: 8 Jun 89 13:36:07 GMT References: <23577@dhw68k.cts.com> Reply-To: bob@dhw68k.cts.com (Bob Best) Organization: Wolfskill & Dowling residence; Anaheim, CA (USA) Lines: 1221 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'sz.man' <<'END_OF_FILE' X X X X SZ(1) MINIX Version 1.3+ (OMEN) SZ(1) X X X X NAME X sx, sb, sz - XMODEM, YMODEM, ZMODEM file send X X SYNOPSIS X sz [-+abdefkLlNnopqTtuvyY] file ... X sb [-adfkqtuv] file ... X sx [-akqtuv] file X sz [-oqtv] -c COMMAND X sz [-oqtv] -i COMMAND X sz -TT X X DESCRIPTION X Sz uses the ZMODEM, YMODEM or XMODEM error correcting X protocol to send one or more files over a dial-in serial X port to a variety of programs running under PC-DOS, CP/M, X Unix, VMS, and other operating systems. X X While rz is smart enough to be called from cu(1), very few X versions of cu(1) are smart enough to allow sz to work X properly. Unix flavors of Professional-YAM are available X for such dial-out application. X X X Sz sends one or more files with ZMODEM protocol. X X ZMODEM greatly simplifies file transfers compared to XMODEM. X In addition to a friendly user interface, ZMODEM provides X Personal Computer and other users an efficient, accurate, X and robust file transfer method. X X ZMODEM provides complete END-TO-END data integrity between X application programs. ZMODEM's 32 bit CRC catches errors X that sneak into even the most advanced networks. X X Advanced file management features include AutoDownload X (Automatic file Download initiated without user X intervention), Display of individual and total file lengths X and transmission time estimates, Crash Recovery, selective X file transfers, and preservation of exact file date and X length. X X Output from another program may be piped to sz for X transmission by denoting standard input with "-": X ls -l | sz - X The program output is transmitted with the filename sPID.sz X where PID is the process ID of the sz program. If the X environment variable ONAME is set, that is used instead. In X this case, the Unix command: X ls -l | ONAME=con sz -ay - X will send a "file" to the PC-DOS console display. The -y X option instructs the receiver to open the file for writing X unconditionally. The -a option causes the receiver to X X X X Page 1 (printed 6/6/89) X X X X X X X SZ(1) MINIX Version 1.3+ (OMEN) SZ(1) X X X X convert Unix newlines to PC-DOS carriage returns and X linefeeds. X X X Sb batch sends one or more files with YMODEM or ZMODEM X protocol. The initial ZMODEM initialization is not sent. X When requested by the receiver, sb supports YMODEM-g with X "cbreak" tty mode, XON/XOFF flow control, and interrupt X character set to CAN (^X). YMODEM-g (Professional-YAM g X option) increases throughput over error free channels X (direct connection, X.PC, etc.) by not acknowledging each X transmitted sector. X X On Unix systems, additional information about the file is X transmitted. If the receiving program uses this X information, the transmitted file length controls the exact X number of bytes written to the output dataset, and the X modify time and file mode are set accordingly. X X X Sx sends a single file with XMODEM or XMODEM-1k protocol X (sometimes incorrectly called "ymodem"). The user must X supply the file name to both sending and receiving programs. X X Iff sz is invoked with $SHELL set and iff that variable X contains the string rsh or rksh (restricted shell), sz X operates in restricted mode. Restricted mode restricts X pathnames to the current directory and PUBDIR (usually X /usr/spool/uucppublic) and/or subdirectories thereof. X X X The fourth form sends a single COMMAND to a ZMODEM receiver X for execution. Sz exits with the COMMAND return value. If X COMMAND includes spaces or characters special to the shell, X it must be quoted. X X X The fifth form sends a single COMMAND to a ZMODEM receiver X for execution. Sz exits as soon as the receiver has X correctly received the command, before it is executed. X X X The sixth form (sz -TT) attempts to output all 256 code X combinations to the terminal. In you are having difficulty X sending files, this command lets you see which character X codes are being eaten by the operating system. X X X If sz is invoked with stdout and stderr to different X datasets, Verbose is set to 2, causing frame by frame X progress reports to stderr. This may be disabled with the q X option. X X X X Page 2 (printed 6/6/89) X X X X X X X SZ(1) MINIX Version 1.3+ (OMEN) SZ(1) X X X X The meanings of the available options are: X X \h|120u+0u(Reg.)(VMS) Force the next option letter to upper X case. X + Instruct the receiver to append transmitted data to an X existing file (ZMODEM only). X a Convert NL characters in the transmitted file to CR/LF. X This is done by the sender for XMODEM and YMODEM, by X the receiver for ZMODEM. X b (ZMODEM) Binary override: transfer file without any X translation. X c COMMAND X Send COMMAND to the receiver for execution, return with X COMMAND's exit status. X d Change all instances of "." to "/" in the transmitted X pathname. Thus, C.omenB0000 (which is unacceptable to X MSDOS or CP/M) is transmitted as C/omenB0000. If the X resultant filename has more than 8 characters in the X stem, a "." is inserted to allow a total of eleven. X e Escape all control characters; normally XON, XOFF, DLE, X CR-@-CR, and Ctrl-X are escaped. X f Send Full pathname. Normally directory prefixes are X stripped from the transmitted filename. X i COMMAND X Send COMMAND to the receiver for execution, return X Immediately upon the receiving program's successful X recption of the command. X k (XMODEM/YMODEM) Send files using 1024 byte blocks X rather than the default 128 byte blocks. 1024 byte X packets speed file transfers at high bit rates. X (ZMODEM streams the data for the best possible X throughput.) X L N Use ZMODEM sub-packets of length N. A larger N (32 <= X N <= 1024) gives slightly higher throughput, a smaller X N speeds error recovery. The default is 128 below 300 X baud, 256 above 300 baud, or 1024 above 2400 baud. X l N Wait for the receiver to acknowledge correct data every X N (32 <= N <= 1024) characters. This may be used to X avoid network overrun when XOFF flow control is X lacking. X n (ZMODEM) Send each file if destination file does not X exist. Overwrite destination file if source file is X newer than the destination file. X N (ZMODEM) Send each file if destination file does not X exist. Overwrite destination file if source file is X newer or longer than the destination file. X o (ZMODEM) Disable automatic selection of 32 bit CRC. X p (ZMODEM) Protect existing destination files by skipping X transfer if the destination file exists. X q Quiet suppresses verbosity. X r (ZMODEM) Resume interrupted file transfer. If the X source file is longer than the destination file, the X X X X Page 3 (printed 6/6/89) X X X X X X X SZ(1) MINIX Version 1.3+ (OMEN) SZ(1) X X X X transfer commences at the offset in the source file X that equals the length of the destination file. X t tim X Change timeout to tim tenths of seconds. X u Unlink the file after successful transmission. X w N Limit the transmit window size to N bytes (ZMODEM). X v Verbose causes a list of file names to be appended to X /tmp/szlog . More v's generate more output. X y Instruct a ZMODEM receiving program to overwrite any X existing file with the same name. X Y Instruct a ZMODEM receiving program to overwrite any X existing file with the same name, and to skip any X source files that do have a file with the same pathname X on the destination system. X X EXAMPLES X ZMODEM File Transfer (Unix to DSZ/ZCOMM/Professional-YAM) X % sz -a *.c X This single command transfers all .c files in the current X Unix directory with conversion (-a) to end of line X conventions appropriate to the receiving environment. With X ZMODEM AutoDownload enabled, Professional-YAM and ZCOMM X will automatically recieve the files after performing a X security check. X X % sz -Yan *.c *.h X Send only the .c and .h files that exist on both systems, X and are newer on the sending system than the corresponding X version on the receiving system, converting Unix to DOS text X format. X $ sz -\Yan file1.c file2.c file3.c foo.h baz.h (Reg.)(for X VMS) X X ZMODEM Command Download (Unix to Professional-YAM) X cpszall:all X sz -c "c:;cd /yam/dist" X sz -ya $(YD)/*.me X sz -yqb y*.exe X sz -c "cd /yam" X sz -i "!insms" X This Makefile fragment uses sz to issue commands to X Professional-YAM to change current disk and directory. X Next, sz transfers the .me files from the $YD directory, X commanding the receiver to overwrite the old files and to X convert from Unix end of line conventions to PC-DOS X conventions. The third line transfers some .exe files. The X fourth and fifth lines command Pro-YAM to change directory X and execute a PC-DOS batch file insms . Since the batch file X takes considerable time, the -i form is used to allow sz to X exit immediately. X X XMODEM File Transfer (Unix to Crosstalk) X X X X Page 4 (printed 6/6/89) X X X X X X X SZ(1) MINIX Version 1.3+ (OMEN) SZ(1) X X X X % sx -a foo.c X ESC X rx foo.c X The above three commands transfer a single file from Unix to X a PC and Crosstalk with sz translating Unix newlines to DOS X CR/LF. This combination is much slower and far less X reliable than ZMODEM. X X ERROR MESSAGES X "Caught signal 99" indicates the program was not properly X compiled, refer to "bibi(99)" in rbsb.c for details. X X SEE ALSO X rz(omen), ZMODEM.DOC, YMODEM.DOC, Professional-YAM, X crc(omen), sq(omen), todos(omen), tocpm(omen), tomac(omen), X yam(omen) X X Compile time options required for various operating systems X are described in the source file. X X VMS VERSION X The VMS version does not support wild cards. Because of VMS X DCL, upper case option letters muse be represented by \ X proceding the letter. X X The current VMS version does not support XMODEM, XMODEM-1k, X or YMODEM. X X VMS C Standard I/O and RMS may interact to modify the file X contents. X X FILES X 32 bit CRC code courtesy Gary S. Brown. X X sz.c, crctab.c, rbsb.c, zm.c, zmodem.h Unix source files X X sz.c, crctab.c, vrzsz.c, zm.c, zmodem.h, vmodem.h, X vvmodem.c, VMS source files. X X /tmp/szlog stores debugging output (sz -vv) (szlog on VMS). X X TESTING FEATURE X The command "sz -T file" exercises the Attn sequence error X recovery by commanding errors with unterminated packets. X The receiving program should complain five times about X binary data packets being too long. Each time sz is X interrupted, it should send a ZDATA header followed by X another defective packet. If the receiver does not detect X five long data packets, the Attn sequence is not X interrupting the sender, and the Myattn string in sz.c must X be modified. X X X X X Page 5 (printed 6/6/89) X X X X X X X SZ(1) MINIX Version 1.3+ (OMEN) SZ(1) X X X X After 5 packets, sz stops the "transfer" and prints the X total number of characters "sent" (Tcount). The difference X between Tcount and 5120 represents the number of characters X stored in various buffers when the Attn sequence is X generated. X X BUGS X Calling sz from most versions of cu(1) doesn't work because X cu's receive process fights sz for characters from the X modem. X X Programs that do not properly implement the specified file X transfer protocol may cause sz to "hang" the port for a X minute or two. Every reported instance of this problem has X been corrected by using ZCOMM, Pro-YAM, or other program X with a correct implementation of the specified protocol. X X Many programs claiming to support YMODEM only support XMODEM X with 1k blocks, and they often don't get that quite right. X X XMODEM transfers add up to 127 garbage bytes per file. X XMODEM-1k and YMODEM-1k transfers use 128 byte blocks to X avoid extra padding. X X YMODEM programs use the file length transmitted at the X beginning of the transfer to prune the file to the correct X length; this may cause problems with source files that grow X during the course of the transfer. This problem does not X pertain to ZMODEM transfers, which preserve the exact file X length unconditionally. X X Most ZMODEM options are merely passed to the receiving X program; some do not implement all these options. X X Circular buffering and a ZMODEM sliding window should be X used when input is from pipes instead of acknowledging X frames each 1024 bytes. If no files can be opened, sz sends X a ZMODEM command to echo a suitable complaint; perhaps it X should check for the presence of at least one accessible X file before getting hot and bothered. The test mode leaves X a zero length file on the receiving system. X X A few high speed modems have a firmware bug that drops X characters when the direction of high speed transmissson is X reversed. The environment variable ZNULLS may be used to X specify the number of nulls to send before a ZDATA frame. X Values of 101 for a 4.77 mHz PC and 124 for an AT are X typical. X X X X X X X X Page 6 (printed 6/6/89) X X X END_OF_FILE if test 13392 -ne `wc -c <'sz.man'`; then echo shar: \"'sz.man'\" unpacked with wrong size! fi # end of 'sz.man' fi if test -f 'zm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'zm.c'\" else echo shar: Extracting \"'zm.c'\" \(14903 characters\) sed "s/^X//" >'zm.c' <<'END_OF_FILE' X/* X * Z M . C X * ZMODEM protocol primitives X * 11-10-87 Chuck Forsberg Omen Technology Inc X * X * Entry point Functions: X * zsbhdr(type, hdr) send binary header X * zshhdr(type, hdr) send hex header X * zgethdr(hdr, eflag) receive header - binary or hex X * zsdata(buf, len, frameend) send data X * zrdata(buf, len) receive data X * stohdr(pos) store position data in Txhdr X * long rclhdr(hdr) recover position offset from header X */ X X#ifndef CANFDX X#include "zmodem.h" Xint Rxtimeout = 100; /* Tenths of seconds to wait for something */ X#endif X X#ifndef UNSL X#define UNSL X#endif X X X/* Globals used by ZMODEM functions */ Xint Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame received */ Xint Rxtype; /* Type of header received */ Xint Rxcount; /* Count of data bytes received */ Xchar Rxhdr[4]; /* Received header */ Xchar Txhdr[4]; /* Transmitted header */ Xlong Rxpos; /* Received file position */ Xlong Txpos; /* Transmitted file position */ Xint Txfcs32; /* TURE means send binary frames with 32 bit FCS */ Xint Crc32t; /* Display flag indicating 32 bit CRC being sent */ Xint Crc32; /* Display flag indicating 32 bit CRC being received */ Xint Znulls; /* Number of nulls to send at beginning of ZDATA hdr */ Xchar Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */ X Xstatic lastsent; /* Last char we sent */ Xstatic evenp; /* Even parity seen on header */ X Xstatic char *frametypes[] = { X "Carrier Lost", /* -3 */ X "TIMEOUT", /* -2 */ X "ERROR", /* -1 */ X#define FTOFFSET 3 X "ZRQINIT", X "ZRINIT", X "ZSINIT", X "ZACK", X "ZFILE", X "ZSKIP", X "ZNAK", X "ZABORT", X "ZFIN", X "ZRPOS", X "ZDATA", X "ZEOF", X "ZFERR", X "ZCRC", X "ZCHALLENGE", X "ZCOMPL", X "ZCAN", X "ZFREECNT", X "ZCOMMAND", X "ZSTDERR", X "xxxxx" X#define FRTYPES 22 /* Total number of frame types in this array */ X /* not including psuedo negative entries */ X}; X Xstatic char masked[] = "8 bit transparent path required"; Xstatic char badcrc[] = "Bad CRC"; X X/* Send ZMODEM binary header hdr of type type */ Xzsbhdr(type, hdr) Xregister char *hdr; X{ X register int n; X register unsigned short crc; X X vfile("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr)); X if (type == ZDATA) X for (n = Znulls; --n >=0; ) X xsendline(0); X X xsendline(ZPAD); xsendline(ZDLE); X X if (Crc32t=Txfcs32) X zsbh32(hdr, type); X else { X xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0); X X for (n=4; --n >= 0; ++hdr) { X zsendline(*hdr); X crc = updcrc((0377& *hdr), crc); X } X crc = updcrc(0,updcrc(0,crc)); X zsendline(crc>>8); X zsendline(crc); X } X if (type != ZDATA) X flushmo(); X} X X X/* Send ZMODEM binary header hdr of type type */ Xzsbh32(hdr, type) Xregister char *hdr; X{ X register int n; X register UNSL long crc; X X xsendline(ZBIN32); zsendline(type); X crc = 0xFFFFFFFFL; crc = UPDC32(type, crc); X X for (n=4; --n >= 0; ++hdr) { X crc = UPDC32((0377 & *hdr), crc); X zsendline(*hdr); X } X crc = ~crc; X for (n=4; --n >= 0;) { X zsendline((int)crc); X crc >>= 8; X } X} X X/* Send ZMODEM HEX header hdr of type type */ Xzshhdr(type, hdr) Xregister char *hdr; X{ X register int n; X register unsigned short crc; X X vfile("zshhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr)); X sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX); X zputhex(type); X Crc32t = 0; X X crc = updcrc(type, 0); X for (n=4; --n >= 0; ++hdr) { X zputhex(*hdr); crc = updcrc((0377 & *hdr), crc); X } X crc = updcrc(0,updcrc(0,crc)); X zputhex(crc>>8); zputhex(crc); X X /* Make it printable on remote machine */ X sendline(015); sendline(012); X /* X * Uncork the remote in case a fake XOFF has stopped data flow X */ X if (type != ZFIN && type != ZACK) X sendline(021); X flushmo(); X} X X/* X * Send binary array buf of length length, with ending ZDLE sequence frameend X */ Xstatic char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"}; Xzsdata(buf, length, frameend) Xregister char *buf; X{ X register unsigned short crc; X X vfile("zsdata: %d %s", length, Zendnames[frameend-ZCRCE&3]); X if (Crc32t) X zsda32(buf, length, frameend); X else { X crc = 0; X for (;--length >= 0; ++buf) { X zsendline(*buf); crc = updcrc((0377 & *buf), crc); X } X xsendline(ZDLE); xsendline(frameend); X crc = updcrc(frameend, crc); X X crc = updcrc(0,updcrc(0,crc)); X zsendline(crc>>8); zsendline(crc); X } X if (frameend == ZCRCW) { X xsendline(XON); flushmo(); X } X} X Xzsda32(buf, length, frameend) Xregister char *buf; X{ X register int c; X register UNSL long crc; X X crc = 0xFFFFFFFFL; X for (;--length >= 0; ++buf) { X c = *buf & 0377; X if (c & 0140) X xsendline(lastsent = c); X else X zsendline(c); X crc = UPDC32(c, crc); X } X xsendline(ZDLE); xsendline(frameend); X crc = UPDC32(frameend, crc); X X crc = ~crc; X for (length=4; --length >= 0;) { X zsendline((int)crc); crc >>= 8; X } X} X X/* X * Receive array buf of max length with ending ZDLE sequence X * and CRC. Returns the ending character or error code. X * NB: On errors may store length+1 bytes! X */ Xzrdata(buf, length) Xregister char *buf; X{ X register int c; X register unsigned short crc; X register char *end; X register int d; X X if (Rxframeind == ZBIN32) X return zrdat32(buf, length); X X crc = Rxcount = 0; end = buf + length; X while (buf <= end) { X if ((c = zdlread()) & ~0377) { Xcrcfoo: X switch (c) { X case GOTCRCE: X case GOTCRCG: X case GOTCRCQ: X case GOTCRCW: X crc = updcrc((d=c)&0377, crc); X if ((c = zdlread()) & ~0377) X goto crcfoo; X crc = updcrc(c, crc); X if ((c = zdlread()) & ~0377) X goto crcfoo; X crc = updcrc(c, crc); X if (crc & 0xFFFF) { X zperr(badcrc); X return ERROR; X } X Rxcount = length - (end - buf); X vfile("zrdata: %d %s", Rxcount, X Zendnames[d-GOTCRCE&3]); X return d; X case GOTCAN: X zperr("Sender Canceled"); X return ZCAN; X case TIMEOUT: X zperr("TIMEOUT"); X return c; X default: X zperr("Bad data subpacket"); X return c; X } X } X *buf++ = c; X crc = updcrc(c, crc); X } X zperr("Data subpacket too long"); X return ERROR; X} X Xzrdat32(buf, length) Xregister char *buf; X{ X register int c; X register UNSL long crc; X register char *end; X register int d; X X crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length; X while (buf <= end) { X if ((c = zdlread()) & ~0377) { Xcrcfoo: X switch (c) { X case GOTCRCE: X case GOTCRCG: X case GOTCRCQ: X case GOTCRCW: X d = c; c &= 0377; X crc = UPDC32(c, crc); X if ((c = zdlread()) & ~0377) X goto crcfoo; X crc = UPDC32(c, crc); X if ((c = zdlread()) & ~0377) X goto crcfoo; X crc = UPDC32(c, crc); X if ((c = zdlread()) & ~0377) X goto crcfoo; X crc = UPDC32(c, crc); X if ((c = zdlread()) & ~0377) X goto crcfoo; X crc = UPDC32(c, crc); X if (crc != 0xDEBB20E3) { X zperr(badcrc); X return ERROR; X } X Rxcount = length - (end - buf); X vfile("zrdat32: %d %s", Rxcount, X Zendnames[d-GOTCRCE&3]); X return d; X case GOTCAN: X zperr("Sender Canceled"); X return ZCAN; X case TIMEOUT: X zperr("TIMEOUT"); X return c; X default: X zperr("Bad data subpacket"); X return c; X } X } X *buf++ = c; X crc = UPDC32(c, crc); X } X zperr("Data subpacket too long"); X return ERROR; X} X X X/* X * Read a ZMODEM header to hdr, either binary or hex. X * eflag controls local display of non zmodem characters: X * 0: no display X * 1: display printing characters only X * 2: display all non ZMODEM characters X * On success, set Zmodem to 1, set Rxpos and return type of header. X * Otherwise return negative on error. X * Return ERROR instantly if ZCRCW sequence, for fast error recovery. X */ Xzgethdr(hdr, eflag) Xchar *hdr; X{ X register int c, n, cancount; X X n = Zrwindow + Baudrate; /* Max bytes before start of frame */ X Rxframeind = Rxtype = 0; X Xstartover: X cancount = 5; Xagain: X /* Return immediate ERROR if ZCRCW sequence seen */ X switch (c = readline(Rxtimeout)) { X case RCDO: X case TIMEOUT: X goto fifi; X case CAN: Xgotcan: X if (--cancount <= 0) { X c = ZCAN; goto fifi; X } X switch (c = readline(1)) { X case TIMEOUT: X goto again; X case ZCRCW: X c = ERROR; X /* **** FALL THRU TO **** */ X case RCDO: X goto fifi; X default: X break; X case CAN: X if (--cancount <= 0) { X c = ZCAN; goto fifi; X } X goto again; X } X /* **** FALL THRU TO **** */ X default: Xagn2: X if ( --n == 0) { X zperr("Garbage count exceeded"); X return(ERROR); X } X if (eflag && ((c &= 0177) & 0140)) X bttyout(c); X else if (eflag > 1) X bttyout(c); X#ifdef UNIX X fflush(stderr); X#endif X goto startover; X case ZPAD|0200: /* This is what we want. */ X case ZPAD: /* This is what we want. */ X evenp = c & 0200; X break; X } X cancount = 5; Xsplat: X switch (c = noxrd7()) { X case ZPAD: X goto splat; X case RCDO: X case TIMEOUT: X goto fifi; X default: X goto agn2; X case ZDLE: /* This is what we want. */ X break; X } X X switch (c = noxrd7()) { X case RCDO: X case TIMEOUT: X goto fifi; X case ZBIN: X Rxframeind = ZBIN; Crc32 = FALSE; X c = zrbhdr(hdr); X break; X case ZBIN32: X Crc32 = Rxframeind = ZBIN32; X c = zrbhdr32(hdr); X break; X case ZHEX: X Rxframeind = ZHEX; Crc32 = FALSE; X c = zrhhdr(hdr); X break; X case CAN: X goto gotcan; X default: X goto agn2; X } X Rxpos = hdr[ZP3] & 0377; X Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377); X Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377); X Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377); Xfifi: X switch (c) { X case GOTCAN: X c = ZCAN; X /* **** FALL THRU TO **** */ X case ZNAK: X case ZCAN: X case ERROR: X case TIMEOUT: X case RCDO: X zperr("Got %s", frametypes[c+FTOFFSET]); X /* **** FALL THRU TO **** */ X default: X if (c >= -3 && c <= FRTYPES) X vfile("zgethdr: %s %lx", frametypes[c+FTOFFSET], Rxpos); X else X vfile("zgethdr: %d %lx", c, Rxpos); X } X return c; X} X X/* Receive a binary style header (type and position) */ Xzrbhdr(hdr) Xregister char *hdr; X{ X register int c, n; X register unsigned short crc; X X if ((c = zdlread()) & ~0377) X return c; X Rxtype = c; X crc = updcrc(c, 0); X X for (n=4; --n >= 0; ++hdr) { X if ((c = zdlread()) & ~0377) X return c; X crc = updcrc(c, crc); X *hdr = c; X } X if ((c = zdlread()) & ~0377) X return c; X crc = updcrc(c, crc); X if ((c = zdlread()) & ~0377) X return c; X crc = updcrc(c, crc); X if (crc & 0xFFFF) { X if (evenp) X zperr(masked); X zperr(badcrc); X return ERROR; X } X#ifdef ZMODEM X Protocol = ZMODEM; X#endif X Zmodem = 1; X return Rxtype; X} X X/* Receive a binary style header (type and position) with 32 bit FCS */ Xzrbhdr32(hdr) Xregister char *hdr; X{ X register int c, n; X register UNSL long crc; X X if ((c = zdlread()) & ~0377) X return c; X Rxtype = c; X crc = 0xFFFFFFFFL; crc = UPDC32(c, crc); X#ifdef DEBUGZ X vfile("zrbhdr32 c=%X crc=%lX", c, crc); X#endif X X for (n=4; --n >= 0; ++hdr) { X if ((c = zdlread()) & ~0377) X return c; X crc = UPDC32(c, crc); X *hdr = c; X#ifdef DEBUGZ X vfile("zrbhdr32 c=%X crc=%lX", c, crc); X#endif X } X for (n=4; --n >= 0;) { X if ((c = zdlread()) & ~0377) X return c; X crc = UPDC32(c, crc); X#ifdef DEBUGZ X vfile("zrbhdr32 c=%X crc=%lX", c, crc); X#endif X } X if (crc != 0xDEBB20E3) { X if (evenp) X zperr(masked); X zperr(badcrc); X return ERROR; X } X#ifdef ZMODEM X Protocol = ZMODEM; X#endif X Zmodem = 1; X return Rxtype; X} X X X/* Receive a hex style header (type and position) */ Xzrhhdr(hdr) Xchar *hdr; X{ X register int c; X register unsigned short crc; X register int n; X X if ((c = zgethex()) < 0) X return c; X Rxtype = c; X crc = updcrc(c, 0); X X for (n=4; --n >= 0; ++hdr) { X if ((c = zgethex()) < 0) X return c; X crc = updcrc(c, crc); X *hdr = c; X } X if ((c = zgethex()) < 0) X return c; X crc = updcrc(c, crc); X if ((c = zgethex()) < 0) X return c; X crc = updcrc(c, crc); X if (crc & 0xFFFF) { X zperr(badcrc); return ERROR; X } X if (readline(1) == '\r') /* Throw away possible cr/lf */ X readline(1); X#ifdef ZMODEM X Protocol = ZMODEM; X#endif X Zmodem = 1; return Rxtype; X} X X/* Send a byte as two hex digits */ Xzputhex(c) Xregister int c; X{ X static char digits[] = "0123456789abcdef"; X X if (Verbose>8) X vfile("zputhex: %02X", c); X sendline(digits[(c&0xF0)>>4]); X sendline(digits[(c)&0xF]); X} X X/* X * Send character c with ZMODEM escape sequence encoding. X * Escape XON, XOFF. Escape CR following @ (Telenet net escape) X */ Xzsendline(c) X{ X X /* Quick check for non control characters */ X if (c & 0140) X xsendline(lastsent = c); X else { X switch (c &= 0377) { X case ZDLE: X xsendline(ZDLE); X xsendline (lastsent = (c ^= 0100)); X break; X case 015: X case 0215: X if (!Zctlesc && (lastsent & 0177) != '@') X goto sendit; X /* **** FALL THRU TO **** */ X case 020: X case 021: X case 023: X case 0220: X case 0221: X case 0223: X xsendline(ZDLE); X c ^= 0100; X sendit: X xsendline(lastsent = c); X break; X default: X if (Zctlesc && ! (c & 0140)) { X xsendline(ZDLE); X c ^= 0100; X } X xsendline(lastsent = c); X } X } X} X X/* Decode two lower case hex digits into an 8 bit byte value */ Xzgethex() X{ X register int c; X X c = zgeth1(); X if (Verbose>8) X vfile("zgethex: %02X", c); X return c; X} Xzgeth1() X{ X register int c, n; X X if ((c = noxrd7()) < 0) X return c; X n = c - '0'; X if (n > 9) X n -= ('a' - ':'); X if (n & ~0xF) X return ERROR; X if ((c = noxrd7()) < 0) X return c; X c -= '0'; X if (c > 9) X c -= ('a' - ':'); X if (c & ~0xF) X return ERROR; X c += (n<<4); X return c; X} X X/* X * Read a byte, checking for ZMODEM escape encoding X * including CAN*5 which represents a quick abort X */ Xzdlread() X{ X register int c; X Xagain: X /* Quick check for non control characters */ X if ((c = readline(Rxtimeout)) & 0140) X return c; X switch (c) { X case ZDLE: X break; X case 023: X case 0223: X case 021: X case 0221: X goto again; X default: X if (Zctlesc && !(c & 0140)) { X goto again; X } X return c; X } Xagain2: X if ((c = readline(Rxtimeout)) < 0) X return c; X if (c == CAN && (c = readline(Rxtimeout)) < 0) X return c; X if (c == CAN && (c = readline(Rxtimeout)) < 0) X return c; X if (c == CAN && (c = readline(Rxtimeout)) < 0) X return c; X switch (c) { X case CAN: X return GOTCAN; X case ZCRCE: X case ZCRCG: X case ZCRCQ: X case ZCRCW: X return (c | GOTOR); X case ZRUB0: X return 0177; X case ZRUB1: X return 0377; X case 023: X case 0223: X case 021: X case 0221: X goto again2; X default: X if (Zctlesc && ! (c & 0140)) { X goto again2; X } X if ((c & 0140) == 0100) X return (c ^ 0100); X break; X } X if (Verbose>1) X zperr("Bad escape sequence %x", c); X return ERROR; X} X X/* X * Read a character from the modem line with timeout. X * Eat parity, XON and XOFF characters. X */ Xnoxrd7() X{ X register int c; X X for (;;) { X if ((c = readline(Rxtimeout)) < 0) X return c; X switch (c &= 0177) { X case XON: X case XOFF: X continue; X default: X if (Zctlesc && !(c & 0140)) X continue; X case '\r': X case '\n': X case ZDLE: X return c; X } X } X} X X/* Store long integer pos in Txhdr */ Xstohdr(pos) Xlong pos; X{ X Txhdr[ZP0] = pos; X Txhdr[ZP1] = pos>>8; X Txhdr[ZP2] = pos>>16; X Txhdr[ZP3] = pos>>24; X} X X/* Recover a long integer from a header */ Xlong Xrclhdr(hdr) Xregister char *hdr; X{ X register long l; X X l = (hdr[ZP3] & 0377); X l = (l << 8) | (hdr[ZP2] & 0377); X l = (l << 8) | (hdr[ZP1] & 0377); X l = (l << 8) | (hdr[ZP0] & 0377); X return l; X} X X/* End of zm.c */ END_OF_FILE if test 14903 -ne `wc -c <'zm.c'`; then echo shar: \"'zm.c'\" unpacked with wrong size! fi # end of 'zm.c' fi echo shar: End of archive 3 \(of 5\). >ark3isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Bob Best uucp: {spsd, zardoz, felix}!dhw68k!bob InterNet: bob@dhw68k.cts.com