home *** CD-ROM | disk | FTP | other *** search
- Subject: v12i022: Zmodem file transfer programs, Part02/03
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: omen!caf
- Posting-number: Volume 12, Issue 22
- Archive-name: zmodem/part02
-
- Source code for Unix ZMODEM programs rz.c and sz.c and related files follows.
- ZMODEM is the ideal protocol for file transfer to and from Unix systems
- using a serial port. The source code has also been used for numerous ZMODEM
- versions, including the Opus bulletin board (Fido replacemet). ZMODEM's
- pleasant user interface with automatic file and command download allows a
- Makefile to control a DOS machine running Pro-YAM, dor example.
-
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./README`
- then
- echo "Writing ./README"
- cat > ./README << '\Rogue\Monster\'
- RZSZ.ZOO is designed to be uploaded to a Unix or Xenix system by
- ZCOMM, Professional-YAM or Powercom using the supplied zupl.t script.
- Connect to your Unix/Xenix system, select an empty directory, and then
- give the YAM/ZCOMM/PowerCom command: "source zupl.t". This will
- upload minirb.c, compile it, and then use minirb to upload the rz/sz
- files. At this time you should study rz.c, sz.c, and rbsb.c to
- determine which compile time flags are necessary for your system.
-
- Compile instructions are located in the comments at the beginning of
- the rz.c ans sz.c files. The main compiler flags are -DV7 for V7 and
- BSD systems and -DSVR2 for sVr2. Other #ifdefs in the files may be
- activated to deal with various types of kernel brain damage if you
- have a mutant system.
-
- Naturally, rz ans sz work best with comm programs that seamlessly
- support ZMODEM command and file AutoDownload (PowerCOm, Pro-YAM and
- ZCOMM). Ths DOS "DSZ" sub-program allows ZMODEM file transfers with
- older programs, but it must be called manually. DSZ provides a "mini
- term function" that supports ZMODEM AutoDownload. DSZ (DSZ.ZOO) and
- the ZMODEM protocol description (YZMODEM.ZOO) are on TeleGodzilla and
- other bulletin boards. They may be obtained via UUCP from site
- "omen", for which a direct UUCP login and telephone number are
- provided below. You may uucp ~uucp/FILES first to determine the
- pathnames for the "goodies".
-
- Chuck Forsberg WA7KGX Author of Pro-YAM communications Tools for PCDOS and Unix
- ..!tektronix!reed!omen!caf Omen Technology Inc "The High Reliability Software"
- 17505-V Northwest Sauvie Island Road Portland OR 97231 Voice: 503-621-3406
- TeleGodzilla BBS: 621-3746 2400/1200 CIS:70007,2304 Genie:CAF Source:TCE022
- omen Any ACU 1200 1-503-621-3746 se:--se: link ord: Giznoid in:--in: uucp
- omen!/usr/spool/uucppublic/FILES lists all uucp-able files, updated hourly
- \Rogue\Monster\
- else
- echo "will not over write ./README"
- fi
- if [ `wc -c ./README | awk '{printf $1}'` -ne 1873 ]
- then
- echo `wc -c ./README | awk '{print "Got " $1 ", Expected " 1873}'`
- fi
- if `test ! -s ./Makefile`
- then
- echo "Writing ./Makefile"
- cat > ./Makefile << '\Rogue\Monster\'
- # Makefile for Unix/Xenix rz and sz programs
- # the makefile is not too well tested yet
-
- nothing:
- @echo
- @echo "Please study the #ifdef's in rbsb.c, rz.c and sz.c,"
- @echo "then type 'make system' where system is one of:"
- @echo " sysv SYSTEM 5 Unix"
- @echo " xenix SYSTEM 3/5 Xenix"
- @echo " x386 386 Xenix"
- @echo " bsd Berkeley 4.x BSD, and Ultrix"
- @echo
-
- usenet:
- shar -f /tmp/rzsz README Makefile zmodem.h zm.c sz.c rz.c rbsb.c \
- minirb.c *.1 gz ptest.sh zupl.t
-
- shar:
- shar -f /tmp/rzsz1et2 -m 1000000 README Makefile zmodem.h zm.c \
- sz.c rz.c rbsb.c minirb.c *.1 gz ptest.sh zupl.t
-
- arc:
- rm -f /tmp/rzsz.arc
- arc a /tmp/rzsz README Makefile zmodem.h zm.c sz.c rz.c \
- rbsb.c *.1 gz ptest.sh zupl.t minirb.c
- chmod og-w /tmp/rzsz.arc
- ln /tmp/rzsz.arc /usr/spool/uucppublic
- mv /tmp/rzsz.arc /t/yam
-
- zoo:
- rm -f /tmp/rzsz.zoo
- zoo a /tmp/rzsz README Makefile zmodem.h zm.c sz.c rz.c \
- rbsb.c *.1 gz ptest.sh zupl.t minirb.c
- chmod og-w /tmp/rzsz.zoo
- ln /tmp/rzsz.zoo /usr/spool/uucppublic
- mv /tmp/rzsz.zoo /t/yam
-
- .PRECIOUS:rz sz
-
- xenix:
- cc -M0 -Ox -K -i -DNFGVMIN -DREADCHECK sz.c -lx -o sz
- size sz
- -ln sz sb
- -ln sz sx
- cc -M0 -Ox -K -i rz.c -o rz
- size rz
- -ln rz rb
- -ln rz rx
-
- x386:
- cc -Ox rz.c -o rz
- size rz
- -ln rz rb
- -ln rz rx
- cc -Ox -DNFGVMIN -DREADCHECK sz.c -lx -o sz
- size sz
- -ln sz sb
- -ln sz sx
-
- sysv:
- cc -O rz.c -o rz
- size rz
- -ln rz rb
- -ln rz rx
- cc -DSVR2 -O -DNFGVMIN sz.c -o sz
- size sz
- -ln sz sb
- -ln sz sx
-
- bsd:
- cc -DV7 -O rz.c -o rz
- size rz
- -ln rz rb
- -ln rz rx
- cc -DV7 -O -DNFGVMIN sz.c -o sz
- size sz
- -ln sz sb
- -ln sz sx
-
- sz: nothing
- sb: nothing
- rz: nothing
- rb: nothing
- \Rogue\Monster\
- else
- echo "will not over write ./Makefile"
- fi
- if [ `wc -c ./Makefile | awk '{printf $1}'` -ne 1640 ]
- then
- echo `wc -c ./Makefile | awk '{print "Got " $1 ", Expected " 1640}'`
- fi
- if `test ! -s ./zmodem.h`
- then
- echo "Writing ./zmodem.h"
- cat > ./zmodem.h << '\Rogue\Monster\'
- /*
- * Z M O D E M . H Manifest constants for ZMODEM
- * application to application file transfer protocol
- * 05-23-87 Chuck Forsberg Omen Technology Inc
- */
- #define ZPAD '*' /* 052 Padding character begins frames */
- #define ZDLE 030 /* Ctrl-X Zmodem escape - `ala BISYNC DLE */
- #define ZDLEE (ZDLE^0100) /* Escaped ZDLE as transmitted */
- #define ZBIN 'A' /* Binary frame indicator */
- #define ZHEX 'B' /* HEX frame indicator */
- #define ZBIN32 'C' /* Binary frame with 32 bit FCS */
-
- /* Frame types (see array "frametypes" in zm.c) */
- #define ZRQINIT 0 /* Request receive init */
- #define ZRINIT 1 /* Receive init */
- #define ZSINIT 2 /* Send init sequence (optional) */
- #define ZACK 3 /* ACK to above */
- #define ZFILE 4 /* File name from sender */
- #define ZSKIP 5 /* To sender: skip this file */
- #define ZNAK 6 /* Last packet was garbled */
- #define ZABORT 7 /* Abort batch transfers */
- #define ZFIN 8 /* Finish session */
- #define ZRPOS 9 /* Resume data trans at this position */
- #define ZDATA 10 /* Data packet(s) follow */
- #define ZEOF 11 /* End of file */
- #define ZFERR 12 /* Fatal Read or Write error Detected */
- #define ZCRC 13 /* Request for file CRC and response */
- #define ZCHALLENGE 14 /* Receiver's Challenge */
- #define ZCOMPL 15 /* Request is complete */
- #define ZCAN 16 /* Other end canned session with CAN*5 */
- #define ZFREECNT 17 /* Request for free bytes on filesystem */
- #define ZCOMMAND 18 /* Command from sending program */
- #define ZSTDERR 19 /* Output to standard error, data follows */
-
- /* ZDLE sequences */
- #define ZCRCE 'h' /* CRC next, frame ends, header packet follows */
- #define ZCRCG 'i' /* CRC next, frame continues nonstop */
- #define ZCRCQ 'j' /* CRC next, frame continues, ZACK expected */
- #define ZCRCW 'k' /* CRC next, ZACK expected, end of frame */
- #define ZRUB0 'l' /* Translate to rubout 0177 */
- #define ZRUB1 'm' /* Translate to rubout 0377 */
-
- /* zdlread return values (internal) */
- /* -1 is general error, -2 is timeout */
- #define GOTOR 0400
- #define GOTCRCE (ZCRCE|GOTOR) /* ZDLE-ZCRCE received */
- #define GOTCRCG (ZCRCG|GOTOR) /* ZDLE-ZCRCG received */
- #define GOTCRCQ (ZCRCQ|GOTOR) /* ZDLE-ZCRCQ received */
- #define GOTCRCW (ZCRCW|GOTOR) /* ZDLE-ZCRCW received */
- #define GOTCAN (GOTOR|030) /* CAN*5 seen */
-
- /* Byte positions within header array */
- #define ZF0 3 /* First flags byte */
- #define ZF1 2
- #define ZF2 1
- #define ZF3 0
- #define ZP0 0 /* Low order 8 bits of position */
- #define ZP1 1
- #define ZP2 2
- #define ZP3 3 /* High order 8 bits of file position */
-
- /* Bit Masks for ZRINIT flags byte ZF0 */
- #define CANFDX 01 /* Rx can send and receive true FDX */
- #define CANOVIO 02 /* Rx can receive data during disk I/O */
- #define CANBRK 04 /* Rx can send a break signal */
- #define CANCRY 010 /* Receiver can decrypt */
- #define CANLZW 020 /* Receiver can uncompress */
- #define CANFC32 040 /* Receiver can use 32 bit Frame Check */
- #define ESCCTL 0100 /* Receiver expects ctl chars to be escaped */
- #define ESC8 0200 /* Receiver expects 8th bit to be escaped */
-
- /* Parameters for ZSINIT frame */
- #define ZATTNLEN 32 /* Max length of attention string */
- /* Bit Masks for ZSINIT flags byte ZF0 */
- #define TESCCTL 0100 /* Transmitter expects ctl chars to be escaped */
- #define TESC8 0200 /* Transmitter expects 8th bit to be escaped */
-
- /* Parameters for ZFILE frame */
- /* Conversion options one of these in ZF0 */
- #define ZCBIN 1 /* Binary transfer - inhibit conversion */
- #define ZCNL 2 /* Convert NL to local end of line convention */
- #define ZCRESUM 3 /* Resume interrupted file transfer */
- /* Management include options, one of these ored in ZF1 */
- #define ZMSKNOLOC 0200 /* Skip file if not present at rx */
- /* Management options, one of these ored in ZF1 */
- #define ZMMASK 037 /* Mask for the choices below */
- #define ZMNEWL 1 /* Transfer if source newer or longer */
- #define ZMCRC 2 /* Transfer if different file CRC or length */
- #define ZMAPND 3 /* Append contents to existing file (if any) */
- #define ZMCLOB 4 /* Replace existing file */
- #define ZMNEW 5 /* Transfer if source newer */
- /* Number 5 is alive ... */
- #define ZMDIFF 6 /* Transfer if dates or lengths different */
- #define ZMPROT 7 /* Protect destination file */
- /* Transport options, one of these in ZF2 */
- #define ZTLZW 1 /* Lempel-Ziv compression */
- #define ZTCRYPT 2 /* Encryption */
- #define ZTRLE 3 /* Run Length encoding */
- /* Extended options for ZF3, bit encoded */
- #define ZXSPARS 64 /* Encoding for sparse file operations */
-
- /* Parameters for ZCOMMAND frame ZF0 (otherwise 0) */
- #define ZCACK1 1 /* Acknowledge, then do command */
-
- long rclhdr();
-
- /* Globals used by ZMODEM functions */
- extern Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame received */
- extern Rxtype; /* Type of header received */
- extern Rxcount; /* Count of data bytes received */
- extern Zrwindow; /* RX window size (controls garbage count) */
- extern Rxtimeout; /* Tenths of seconds to wait for something */
- extern char Rxhdr[4]; /* Received header */
- extern char Txhdr[4]; /* Transmitted header */
- extern long Rxpos; /* Received file position */
- extern long Txpos; /* Transmitted file position */
- extern Txfcs32; /* TURE means send binary frames with 32 bit FCS */
- extern Crc32t; /* Display flag indicating 32 bit CRC being sent */
- extern Crc32; /* Display flag indicating 32 bit CRC being received */
- extern Znulls; /* Number of nulls to send at beginning of ZDATA hdr */
- extern char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
-
- /* End of ZMODEM.H */
- \Rogue\Monster\
- else
- echo "will not over write ./zmodem.h"
- fi
- if [ `wc -c ./zmodem.h | awk '{printf $1}'` -ne 5487 ]
- then
- echo `wc -c ./zmodem.h | awk '{print "Got " $1 ", Expected " 5487}'`
- fi
- if `test ! -s ./zm.c`
- then
- echo "Writing ./zm.c"
- cat > ./zm.c << '\Rogue\Monster\'
- /*
- * Z M . C
- * ZMODEM protocol primitives
- * 07-28-87 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
- * zsdata(buf, len, frameend) send data
- * zrdata(buf, len) receive 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
-
- #ifndef UNSL
- #define UNSL
- #endif
-
-
- /* Globals used by ZMODEM functions */
- int Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame received */
- int Rxtype; /* Type of header received */
- int Rxcount; /* Count of data bytes received */
- char Rxhdr[4]; /* Received header */
- char Txhdr[4]; /* Transmitted header */
- long Rxpos; /* Received file position */
- long Txpos; /* Transmitted file position */
- int Txfcs32; /* TURE means send binary frames with 32 bit FCS */
- int Crc32t; /* Display flag indicating 32 bit CRC being sent */
- int Crc32; /* Display flag indicating 32 bit CRC being received */
- int Znulls; /* Number of nulls to send at beginning of ZDATA hdr */
- char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
-
-
- static char *frametypes[] = {
- "Carrier Lost", /* -3 */
- "TIMEOUT", /* -2 */
- "ERROR", /* -1 */
- #define FTOFFSET 3
- "ZRQINIT",
- "ZRINIT",
- "ZSINIT",
- "ZACK",
- "ZFILE",
- "ZSKIP",
- "ZNAK",
- "ZABORT",
- "ZFIN",
- "ZRPOS",
- "ZDATA",
- "ZEOF",
- "ZFERR",
- "ZCRC",
- "ZCHALLENGE",
- "ZCOMPL",
- "ZCAN",
- "ZFREECNT",
- "ZCOMMAND",
- "ZSTDERR",
- "xxxxx"
- #define FRTYPES 22 /* Total number of frame types in this array */
- /* not including psuedo negative entries */
- };
-
- /* Send ZMODEM binary header hdr of type type */
- zsbhdr(type, hdr)
- register char *hdr;
- {
- register n;
- register unsigned short crc;
-
- vfile("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
- if (type == ZDATA)
- for (n = Znulls; --n >=0; )
- zsendline(0);
-
- xsendline(ZPAD); xsendline(ZDLE);
-
- if (Crc32t=Txfcs32)
- zsbh32(hdr, type);
- else {
- xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);
-
- for (n=4; --n >= 0; ++hdr) {
- zsendline(*hdr);
- crc = updcrc((0377& *hdr), crc);
- }
- crc = updcrc(0,updcrc(0,crc));
- zsendline(crc>>8);
- zsendline(crc);
- }
- if (type != ZDATA)
- flushmo();
- }
-
-
- /* Send ZMODEM binary header hdr of type type */
- zsbh32(hdr, type)
- register char *hdr;
- {
- register n;
- register UNSL long crc;
-
- xsendline(ZBIN32); zsendline(type);
- crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
-
- for (n=4; --n >= 0; ++hdr) {
- crc = UPDC32((0377 & *hdr), crc);
- zsendline(*hdr);
- }
- crc = ~crc;
- for (n=4; --n >= 0;) {
- zsendline((int)crc);
- crc >>= 8;
- }
- }
-
- /* Send ZMODEM HEX header hdr of type type */
- zshhdr(type, hdr)
- register char *hdr;
- {
- register n;
- register unsigned short crc;
-
- vfile("zshhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
- sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX);
- zputhex(type);
- Crc32t = 0;
-
- crc = updcrc(type, 0);
- for (n=4; --n >= 0; ++hdr) {
- zputhex(*hdr); crc = updcrc((0377 & *hdr), crc);
- }
- crc = updcrc(0,updcrc(0,crc));
- zputhex(crc>>8); zputhex(crc);
-
- /* Make it printable on remote machine */
- sendline(015); sendline(012);
- /*
- * Uncork the remote in case a fake XOFF has stopped data flow
- */
- if (type != ZFIN && type != ZACK)
- sendline(021);
- flushmo();
- }
-
- /*
- * Send binary array buf of length length, with ending ZDLE sequence frameend
- */
- zsdata(buf, length, frameend)
- register char *buf;
- {
- register unsigned short crc;
-
- vfile("zsdata: length=%d end=%x", length, frameend);
- if (Crc32t)
- zsda32(buf, length, frameend);
- else {
- crc = 0;
- for (;--length >= 0; ++buf) {
- zsendline(*buf); crc = updcrc((0377 & *buf), crc);
- }
- xsendline(ZDLE); xsendline(frameend);
- crc = updcrc(frameend, crc);
-
- crc = updcrc(0,updcrc(0,crc));
- zsendline(crc>>8); zsendline(crc);
- }
- if (frameend == ZCRCW) {
- xsendline(XON); flushmo();
- }
- }
-
- zsda32(buf, length, frameend)
- register char *buf;
- {
- register UNSL long crc;
-
- crc = 0xFFFFFFFFL;
- for (;--length >= 0;++buf) {
- crc = UPDC32((0377 & *buf), crc);
- zsendline(*buf);
- }
- xsendline(ZDLE); xsendline(frameend);
- crc = UPDC32(frameend, crc);
-
- crc = ~crc;
- for (length=4; --length >= 0;) {
- zsendline((int)crc); crc >>= 8;
- }
- }
-
- /*
- * Receive array buf of max length with ending ZDLE sequence
- * and CRC. Returns the ending character or error code.
- * NB: On errors may store length+1 bytes!
- */
- zrdata(buf, length)
- register char *buf;
- {
- register c;
- register unsigned short crc;
- register char *end;
- register d;
-
- if (Rxframeind == ZBIN32)
- return zrdat32(buf, length);
-
- crc = Rxcount = 0; end = buf + length;
- while (buf <= end) {
- if ((c = zdlread()) & ~0377) {
- crcfoo:
- switch (c) {
- case GOTCRCE:
- case GOTCRCG:
- case GOTCRCQ:
- case GOTCRCW:
- crc = updcrc((d=c)&0377, crc);
- if ((c = zdlread()) & ~0377)
- goto crcfoo;
- crc = updcrc(c, crc);
- if ((c = zdlread()) & ~0377)
- goto crcfoo;
- crc = updcrc(c, crc);
- if (crc & 0xFFFF) {
- zperr("Bad data CRC");
- return ERROR;
- }
- Rxcount = length - (end - buf);
- vfile("zrdata: cnt = %d ret = %x", Rxcount, d);
- return d;
- case GOTCAN:
- zperr("Sender Canceled");
- return ZCAN;
- case TIMEOUT:
- zperr("TIMEOUT");
- return c;
- default:
- zperr("Bad data subpacket");
- return c;
- }
- }
- *buf++ = c;
- crc = updcrc(c, crc);
- }
- zperr("Data subpacket too long");
- return ERROR;
- }
-
- zrdat32(buf, length)
- register char *buf;
- {
- register c;
- register UNSL long crc;
- register char *end;
- register d;
-
- crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
- while (buf <= end) {
- if ((c = zdlread()) & ~0377) {
- crcfoo:
- switch (c) {
- case GOTCRCE:
- case GOTCRCG:
- case GOTCRCQ:
- case GOTCRCW:
- d = c; c &= 0377;
- crc = UPDC32(c, crc);
- if ((c = zdlread()) & ~0377)
- goto crcfoo;
- crc = UPDC32(c, crc);
- if ((c = zdlread()) & ~0377)
- goto crcfoo;
- crc = UPDC32(c, crc);
- if ((c = zdlread()) & ~0377)
- goto crcfoo;
- crc = UPDC32(c, crc);
- if ((c = zdlread()) & ~0377)
- goto crcfoo;
- crc = UPDC32(c, crc);
- if (crc != 0xDEBB20E3) {
- zperr("Bad data CRC");
- return ERROR;
- }
- Rxcount = length - (end - buf);
- vfile("zrdat32: cnt = %d ret = %x", Rxcount, d);
- return d;
- case GOTCAN:
- zperr("Sender Canceled");
- return ZCAN;
- case TIMEOUT:
- zperr("TIMEOUT");
- return c;
- default:
- zperr("Bad data subpacket");
- return c;
- }
- }
- *buf++ = c;
- crc = UPDC32(c, crc);
- }
- zperr("Data subpacket too long");
- return ERROR;
- }
-
-
- /*
- * 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, set Rxpos and return type of header.
- * Otherwise return negative on error.
- * Return ERROR instantly if ZCRCW sequence, for fast error recovery.
- */
- zgethdr(hdr, eflag)
- char *hdr;
- {
- register c, n, cancount;
-
- n = Zrwindow + Baudrate; /* Max bytes before start of frame */
- Rxframeind = Rxtype = 0;
-
- startover:
- cancount = 5;
- again:
- /* Return immediate ERROR if ZCRCW sequence seen */
- switch (c = readline(Rxtimeout)) {
- case RCDO:
- case TIMEOUT:
- goto fifi;
- case CAN:
- gotcan:
- if (--cancount <= 0) {
- c = ZCAN; goto fifi;
- }
- switch (c = readline(1)) {
- case TIMEOUT:
- goto again;
- case ZCRCW:
- c = ERROR;
- /* **** FALL THRU TO **** */
- case RCDO:
- goto fifi;
- default:
- break;
- case CAN:
- if (--cancount <= 0) {
- c = ZCAN; goto fifi;
- }
- goto again;
- }
- /* **** FALL THRU TO **** */
- default:
- agn2:
- if ( --n == 0) {
- zperr("Garbage count exceeded");
- return(ERROR);
- }
- if (eflag && ((c &= 0177) & 0140))
- bttyout(c);
- else if (eflag > 1)
- bttyout(c);
- goto startover;
- case ZPAD|0200: /* This is what we want. */
- case ZPAD: /* This is what we want. */
- break;
- }
- cancount = 5;
- splat:
- switch (c = noxrd7()) {
- case ZPAD:
- goto splat;
- case RCDO:
- case TIMEOUT:
- goto fifi;
- default:
- goto agn2;
- case ZDLE: /* This is what we want. */
- break;
- }
-
- switch (c = noxrd7()) {
- case RCDO:
- case TIMEOUT:
- goto fifi;
- case ZBIN:
- Rxframeind = ZBIN; Crc32 = FALSE;
- c = zrbhdr(hdr);
- break;
- case ZBIN32:
- Crc32 = Rxframeind = ZBIN32;
- c = zrbhdr32(hdr);
- break;
- case ZHEX:
- Rxframeind = ZHEX; Crc32 = FALSE;
- c = zrhhdr(hdr);
- break;
- case CAN:
- goto gotcan;
- default:
- goto agn2;
- }
- 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:
- case RCDO:
- zperr("Got %s", frametypes[c+FTOFFSET]);
- /* **** FALL THRU TO **** */
- default:
- if (c >= -3 && c <= FRTYPES)
- vfile("zgethdr: %s %lx", frametypes[c+FTOFFSET], Rxpos);
- else
- vfile("zgethdr: %d %lx", c, Rxpos);
- }
- return c;
- }
-
- /* Receive a binary style header (type and position) */
- zrbhdr(hdr)
- register char *hdr;
- {
- register c, n;
- register unsigned short crc;
-
- if ((c = zdlread()) & ~0377)
- return c;
- Rxtype = c;
- crc = updcrc(c, 0);
-
- for (n=4; --n >= 0; ++hdr) {
- if ((c = zdlread()) & ~0377)
- return c;
- crc = updcrc(c, crc);
- *hdr = c;
- }
- if ((c = zdlread()) & ~0377)
- return c;
- crc = updcrc(c, crc);
- if ((c = zdlread()) & ~0377)
- return c;
- crc = updcrc(c, crc);
- if (crc & 0xFFFF) {
- zperr("Bad Header CRC"); return ERROR;
- }
- Zmodem = 1;
- return Rxtype;
- }
-
- /* Receive a binary style header (type and position) with 32 bit FCS */
- zrbhdr32(hdr)
- register char *hdr;
- {
- register c, n;
- register UNSL long crc;
-
- if ((c = zdlread()) & ~0377)
- return c;
- Rxtype = c;
- crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
- #ifdef DEBUGZ
- vfile("zrbhdr32 c=%X crc=%lX", c, crc);
- #endif
-
- for (n=4; --n >= 0; ++hdr) {
- if ((c = zdlread()) & ~0377)
- return c;
- crc = UPDC32(c, crc);
- *hdr = c;
- #ifdef DEBUGZ
- vfile("zrbhdr32 c=%X crc=%lX", c, crc);
- #endif
- }
- for (n=4; --n >= 0;) {
- if ((c = zdlread()) & ~0377)
- return c;
- crc = UPDC32(c, crc);
- #ifdef DEBUGZ
- vfile("zrbhdr32 c=%X crc=%lX", c, crc);
- #endif
- }
- if (crc != 0xDEBB20E3) {
- zperr("Bad Header CRC"); return ERROR;
- }
- Zmodem = 1;
- return Rxtype;
- }
-
-
- /* Receive a hex style header (type and position) */
- zrhhdr(hdr)
- char *hdr;
- {
- register c;
- register unsigned short crc;
- register n;
-
- if ((c = zgethex()) < 0)
- return c;
- Rxtype = c;
- crc = updcrc(c, 0);
-
- for (n=4; --n >= 0; ++hdr) {
- if ((c = zgethex()) < 0)
- return c;
- crc = updcrc(c, crc);
- *hdr = c;
- }
- if ((c = zgethex()) < 0)
- return c;
- crc = updcrc(c, crc);
- if ((c = zgethex()) < 0)
- return c;
- crc = updcrc(c, crc);
- if (crc & 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 */
- zputhex(c)
- register c;
- {
- static char digits[] = "0123456789abcdef";
-
- if (Verbose>8)
- vfile("zputhex: %02X", c);
- sendline(digits[(c&0xF0)>>4]);
- sendline(digits[(c)&0xF]);
- }
-
- /*
- * Send character c with ZMODEM escape sequence encoding.
- * Escape XON, XOFF. Escape CR following @ (Telenet net escape)
- */
- zsendline(c)
- register c;
- {
- static lastsent;
-
- switch (c &= 0377) {
- case ZDLE:
- xsendline(ZDLE);
- xsendline (lastsent = (c ^= 0100));
- break;
- case 015:
- case 0215:
- if (!Zctlesc && (lastsent & 0177) != '@')
- goto sendit;
- /* **** FALL THRU TO **** */
- case 020:
- case 021:
- case 023:
- case 0220:
- case 0221:
- case 0223:
- xsendline(ZDLE);
- c ^= 0100;
- sendit:
- xsendline(lastsent = c);
- break;
- default:
- if (Zctlesc && ! (c & 0140)) {
- xsendline(ZDLE);
- c ^= 0100;
- }
- xsendline(lastsent = c);
- }
- }
-
- /* Decode two lower case hex digits into an 8 bit byte value */
- zgethex()
- {
- register c;
-
- c = zgeth1();
- if (Verbose>8)
- vfile("zgethex: %02X", c);
- return c;
- }
- zgeth1()
- {
- register c, n;
-
- if ((c = noxrd7()) < 0)
- return c;
- n = c - '0';
- if (n > 9)
- n -= ('a' - ':');
- if (n & ~0xF)
- return ERROR;
- if ((c = noxrd7()) < 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*5 which represents a quick abort
- */
- zdlread()
- {
- register c;
-
- again:
- switch (c = readline(Rxtimeout)) {
- case ZDLE:
- break;
- case 023:
- case 0223:
- case 021:
- case 0221:
- goto again;
- default:
- if (Zctlesc && !(c & 0140)) {
- goto again;
- }
- return c;
- }
- again2:
- if ((c = readline(Rxtimeout)) < 0)
- return c;
- if (c == CAN && (c = readline(Rxtimeout)) < 0)
- return c;
- if (c == CAN && (c = readline(Rxtimeout)) < 0)
- return c;
- if (c == CAN && (c = readline(Rxtimeout)) < 0)
- return c;
- switch (c) {
- case CAN:
- return GOTCAN;
- case ZCRCE:
- case ZCRCG:
- case ZCRCQ:
- case ZCRCW:
- return (c | GOTOR);
- case ZRUB0:
- return 0177;
- case ZRUB1:
- return 0377;
- case 023:
- case 0223:
- case 021:
- case 0221:
- goto again2;
- default:
- if (Zctlesc && ! (c & 0140)) {
- goto again2;
- }
- if ((c & 0140) == 0100)
- return (c ^ 0100);
- break;
- }
- zperr("Bad escape sequence %x", c);
- return ERROR;
- }
-
- /*
- * Read a character from the modem line with timeout.
- * Eat parity, XON and XOFF characters.
- */
- noxrd7()
- {
- register c;
-
- for (;;) {
- if ((c = readline(Rxtimeout)) < 0)
- return c;
- switch (c &= 0177) {
- case XON:
- case XOFF:
- continue;
- default:
- if (Zctlesc && !(c & 0140))
- continue;
- case '\r':
- case '\n':
- case ZDLE:
- return c;
- }
- }
- }
-
- /* Store long integer pos in Txhdr */
- stohdr(pos)
- long pos;
- {
- Txhdr[ZP0] = pos;
- Txhdr[ZP1] = pos>>8;
- Txhdr[ZP2] = pos>>16;
- Txhdr[ZP3] = pos>>24;
- }
-
- /* Recover a long integer from a header */
- long
- rclhdr(hdr)
- register char *hdr;
- {
- register long 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;
- }
-
- /* End of zm.c */
- \Rogue\Monster\
- else
- echo "will not over write ./zm.c"
- fi
- if [ `wc -c ./zm.c | awk '{printf $1}'` -ne 14087 ]
- then
- echo `wc -c ./zm.c | awk '{print "Got " $1 ", Expected " 14087}'`
- fi
- echo "Finished archive 3 of 3"
- exit
-
-