ecu - SCO XENIX V/{2,3}86 Extended CU part 27/47
Warren Tucker
wht at tridom.uucp
Wed Oct 11 05:40:07 AEST 1989
---- Cut Here and unpack ----
#!/bin/sh
# this is part 27 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file z/ecusz.c continued
#
CurArch=27
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file z/ecusz.c"
sed 's/^X//' << 'SHAR_EOF' >> z/ecusz.c
X}
X
X/* fill buf with count chars padding with ^Z for CPM */
Xxbuf_build(buf,count)
Xregister char *buf;
X{
Xregister c,m;
Xlong lseek();
Xlong X_txpos = lseek(fileno(in),0L,1);
Xchar diag_str[64];
X
X report_send_stats(X_txpos);
X if( !Ascii)
X {
X m = read(fileno(in),buf,count);
X if(log_packets)
X {
X sprintf(diag_str,"read rtnd %d of %d",m,count);
X report_str(diag_str,1);
X }
X if(m <= 0)
X return(0);
X while(m < count)
X buf[m++] = 032;
X return(count);
X }
X m=count;
X if(Lfseen)
X {
X *buf++ = 012;
X --m;
X Lfseen = 0;
X }
X while((c=getc(in))!=EOF)
X {
X if(c == 012)
X {
X *buf++ = 015;
X if(--m == 0)
X {
X Lfseen = TRUE;
X break;
X }
X }
X *buf++ =c;
X if(--m == 0)
X break;
X }
X if(m==count)
X return(0);
X else
X while(--m>=0)
X *buf++ = CPMEOF;
X return(count);
X}
X
X/* fill buf with count chars */
Xzbuf_build(buf,count)
Xregister char *buf;
X{
X register c,m;
X
X m=count;
X while((c=getc(in))!=EOF)
X {
X *buf++ =c;
X if(--m == 0)
X break;
X }
X return(count - m);
X}
X
X
XSIGALRM_handler()
X{
X#if defined(M_XENIX)
X report_rx_ind(0);
X report_tx_ind(0);
X#endif
X longjmp(tohere,-1);
X}
X
X
X/*
X * readock(timeout,count)
X * timeout is in tenths of seconds
X * reads character(s) from file descriptor 'fd'
X * read 'count' characters, (1 <= count <= 3)
X * if more than one received, return ERROR unless all are CAN
X * normal response is NAK, ACK, CAN, G or C
X */
Xreadock(timeout,count)
X{
X register int c;
X static char byt[5];
X
X if(setjmp(tohere))
X {
X report_str("TIMEOUT",1);
X return(TIMEOUT);
X }
X c = timeout/10;
X if(c<2)
X c = 2;
X signal(SIGALRM,SIGALRM_handler);
X alarm(c);
X#if defined(ONEREAD)
X c=read(iofd,byt,1); /* regulus raw read is unique */
X#else
X c=read(iofd,byt,count);
X#endif
X rx_char_count += c;
X alarm(0);
X if(c<1)
X return(TIMEOUT);
X if(c==1)
X return(byt[0]&0377);
X else
X while(c)
X if(byt[--c] != CAN)
X return(ERROR);
X return(CAN);
X}
X
Xreadline(n)
X{
X return(readock(n,1));
X}
X
X
Xpurgeline()
X{
X#if defined(M_XENIX)
X ioctl(iofd,TCFLSH,0);
X#else
X lseek(iofd,0L,2);
X#endif
X}
X
X/* send cancel string to get the other end to shut up */
Xsend_cancel()
X{
X static char canistr[] =
X {
X 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
X };
X register char *cptr = canistr;
X
X report_last_txhdr("^X CAN",1);
X while(*cptr)
X sendline(*cptr++);
X flushline();
X}
X
X/*
X * substr(string,token) searches for token in string s
X * returns pointer to token within string if found,NULL otherwise
X */
Xchar *
Xsubstr(s,t)
Xregister char *s,*t;
X{
X register char *ss,*tt;
X /* search for first char of token */
X for(ss=s; *s; s++)
X if(*s == *t)
X /* compare token with substring */
X for(ss=s,tt=t; ;)
X {
X if(*tt == 0)
X return(s);
X if(*ss++ != *tt++)
X break;
X }
X return(NULL);
X}
X
X
Xusage()
X{
X exit(255);
X}
X
X/*
X * Get the receiver's init parameters
X */
Xgetzrxinit()
X{
X register n;
X struct stat f;
X
X for(n=10; --n>=0; )
X {
X switch(zgethdr(Rxhdr,1))
X {
X case ZCHALLENGE: /* Echo receiver's challenge numbr */
X stohdr(Rxpos);
X zshhdr(ZACK,Txhdr);
X continue;
X case ZCOMMAND: /* They didn't see out ZRQINIT */
X stohdr(0L);
X zshhdr(ZRQINIT,Txhdr);
X continue;
X case ZRINIT:
X Rxflags = 0377 & Rxhdr[ZF0];
X Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
X report_protocol_type("ZMODEM");
X report_protocol_crc_type((Txfcs32) ? "/CRC32" : "/CRC16");
X Zctlesc |= Rxflags & TESCCTL;
X Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
X if( !(Rxflags & CANFDX))
X Txwindow = 0;
X#if defined(MODE2OK)
X mode(2); /* Set cbreak,XON/XOFF,etc. */
X#endif
X#if !defined(READCHECK)
X#if !defined(M_XENIX)
X /* Use 1024 byte frames if no sample/interrupt */
X if(Rxbuflen < 32 || Rxbuflen > 1024)
X {
X Rxbuflen = 1024;
X }
X#endif
X#endif
X /* Override to force shorter frame length */
X if(Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
X Rxbuflen = Tframlen;
X if( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
X Rxbuflen = Tframlen;
X
X /* If using a pipe for testing set lower buf len */
X fstat(iofd,&f);
X if((f.st_mode & S_IFMT) != S_IFCHR
X && (Rxbuflen == 0 || Rxbuflen > 4096))
X Rxbuflen = 4096;
X sprintf(s128,"Remote: CRC32 %c duplex %c",
X (Rxflags & CANFC32) ? 'y' : 'n',
X (Rxflags & CANFDX) ? 'y' : 'n');
X if(Rxbuflen)
X sprintf(&s128[strlen(s128)]," buflen %u",Rxbuflen);
X else
X strcat(s128," continuous stream y");
X report_str(s128,2);
X /*
X * If input is not a regular file,force ACK's each 1024
X * (A smarter strategey could be used here ...)
X */
X if( !Command)
X {
X fstat(fileno(in),&f);
X if(((f.st_mode & S_IFMT) != S_IFREG)
X && (Rxbuflen == 0 || Rxbuflen > 1024))
X Rxbuflen = 1024;
X }
X
X if(Baudrate > 300) /* Set initial subpacket len */
X blklen = 256;
X if(Baudrate > 1200)
X blklen = 512;
X if(Baudrate >= 2400) /* original code had > 2400 here ****/
X blklen = 1024;
X if(Rxbuflen && blklen>Rxbuflen)
X blklen = Rxbuflen;
X if(blkopt && blklen > blkopt)
X blklen = blkopt;
X blklen_original = blklen;
X report_txblklen(blklen);
X return(sendzsinit());
X case ZCAN:
X case TIMEOUT:
X return(ERROR);
X case ZRQINIT:
X if(Rxhdr[ZF0] == ZCOMMAND)
X continue;
X default:
X zshhdr(ZNAK,Txhdr);
X continue;
X }
X }
X return(ERROR);
X}
X
X/* Send send-init information */
Xsendzsinit()
X{
X register c;
X
X if(Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
X return(OK);
X errors = 0;
X for(;;)
X {
X stohdr(0L);
X if(Zctlesc)
X {
X Txhdr[ZF0] |= TESCCTL;
X zshhdr(ZSINIT,Txhdr);
X }
X else
X zsbhdr(ZSINIT,Txhdr);
X zsdata(Myattn,1+strlen(Myattn),ZCRCW);
X c = zgethdr(Rxhdr,1);
X switch(c)
X {
X case ZCAN:
X return(ERROR);
X case ZACK:
X return(OK);
X default:
X if(++errors > 19)
X return(ERROR);
X continue;
X }
X }
X}
X
X/* Send file name and related info */
Xzsendfile(buf,blen)
Xchar *buf;
X{
X register c;
X
X for(;;)
X {
X blklen = blklen_original;
X Txhdr[ZF0] = Lzconv; /* file conversion request */
X Txhdr[ZF1] = Lzmanag; /* file management request */
X Txhdr[ZF2] = Lztrans; /* file transport request */
X Txhdr[ZF3] = 0;
X zsbhdr(ZFILE,Txhdr);
X zsdata(buf,blen,ZCRCW);
Xagain:
X c = zgethdr(Rxhdr,1);
X switch(c)
X {
X case ZRINIT:
X while((c = readline(50)) > 0)
X if(c == ZPAD)
X {
X goto again;
X }
X /* **** FALL THRU TO **** */
X default:
X continue;
X case ZCAN:
X case TIMEOUT:
X case ZABORT:
X case ZFIN:
X return(ERROR);
X case ZSKIP:
X report_file_close();
X fclose(in);
X return(c);
X case ZRPOS:
X /*
X * Suppress zcrcw request otherwise triggered by
X * lastyunc==bytcnt
X */
X Lastsync = (bytcnt = Txpos = Rxpos) -1;
X fseek(in,Rxpos,0);
X Dontread = FALSE;
X report_send_stats(Txpos);
X return(zsendfdata());
X }
X }
X}
X
X/* Send the data in the file */
Xzsendfdata()
X{
Xregister c,e,n;
Xregister newcnt;
Xregister long tcount = 0;
Xint junkcount; /* Counts garbage chars received by TX */
Xstatic int tleft = 6; /* Counter for test mode */
Xint err;
X
X Lrxpos = 0;
X junkcount = 0;
X SameZrposAgain = FALSE; /* variable was named Beenhereb4 (wht) */
X this_file_frame_count = 0; /* we've sent no frames (wht) */
Xsomemore:
X if(setjmp(intrjmp))
X {
Xwaitack:
X junkcount = 0;
X c = getinsync(0);
Xgotack:
X switch(c)
X {
X default:
X case ZCAN:
X report_rcvr_cancelled("zfdata-1");
X report_file_close();
X fclose(in);
X return(ERROR);
X case ZSKIP:
X report_file_close();
X fclose(in);
X return(c);
X case ZACK:
X case ZRPOS:
X break;
X case ZRINIT:
X return(OK);
X }
X#if defined(READCHECK)
X /*
X * If the reverse channel can be tested for data,
X * this logic may be used to detect error packets
X * sent by the receiver,in place of setjmp/longjmp
X * rdchk(fdes) returns non 0 if a character is available
X */
X while(rdchk(iofd))
X {
X switch(readline(1))
X {
X case CAN:
X case ZPAD:
X c = getinsync(1);
X goto gotack;
X case XOFF: /* Wait a while for an XON */
X case XOFF|0200:
X readline(100);
X }
X }
X#endif
X }
X
X newcnt = Rxbuflen;
X Txwcnt = 0;
X stohdr(Txpos);
X zsbhdr(ZDATA,Txhdr);
X
X do
X {
X if(Dontread)
X {
X n = Lastn;
X } else
X {
X n = zbuf_build(txbuf,blklen);
X Lastread = Txpos;
X Lastn = n;
X }
X Dontread = FALSE;
X if(n < blklen)
X e = ZCRCE;
X else if(junkcount > 3)
X e = ZCRCW;
X else if(bytcnt == Lastsync)
X e = ZCRCW;
X else if(Rxbuflen && (newcnt -= n) <= 0)
X e = ZCRCW;
X else if(Txwindow && (Txwcnt += n) >= Txwspac)
X {
X Txwcnt = 0;
X e = ZCRCQ;
X }
X else
X e = ZCRCG;
X zsdata(txbuf,n,e);
X this_file_frame_count++; /* wht */
X if(bad_condx_blklen) /* wht */
X {
X /* if we have sent four frames since last ZRPOS to same pos (wht)*/
X if((this_file_frame_count - bad_condx_frame_count) > 4) /*wht*/
X {
X if(blklen == bad_condx_blklen)
X bad_condx_blklen = 0;
X else
X blklen *= 2;
X SameZrposAgain = 0;
X }
X }
X bytcnt = Txpos += n;
X report_send_stats(Txpos);
X if(e == ZCRCW)
X goto waitack;
X#if defined(READCHECK)
X /*
X * If the reverse channel can be tested for data,
X * this logic may be used to detect error packets
X * sent by the receiver,in place of setjmp/longjmp
X * rdchk(fdes) returns non 0 if a character is available
X */
X while(rdchk(iofd))
X {
X switch(readline(1))
X {
X case CAN:
X case ZPAD:
X c = getinsync(1);
X if(c == ZACK)
X break;
X#if defined(TCFLSH)
X ioctl(iofd,TCFLSH,1);
X#endif
X /* zcrce - dinna wanna starta ping-pong game */
X zsdata(txbuf,0,ZCRCE);
X goto gotack;
X
X case XOFF: /* Wait a while for an XON */
X case XOFF|0200:
X readline(100);
X
X default:
X ++junkcount;
X }
X }
X#endif /* READCHECK */
X if(Txwindow)
X {
X while((tcount = Txpos - Lrxpos) >= Txwindow)
X {
X if(e != ZCRCQ)
X zsdata(txbuf,0,e = ZCRCQ);
X c = getinsync(1);
X if(c != ZACK)
X {
X#if defined(TCFLSH)
X ioctl(iofd,TCFLSH,1);
X#endif
X zsdata(txbuf,0,ZCRCE);
X goto gotack;
X }
X }
X }
X } while(n == blklen);
X
X for(;;)
X {
X stohdr(Txpos);
X zsbhdr(ZEOF,Txhdr);
X switch(err = getinsync(0))
X {
X case ZACK:
X continue;
X case ZRPOS:
X goto somemore;
X case ZRINIT:
X return(OK);
X case ZSKIP:
X report_file_close();
X fclose(in);
X return(c);
X default:
X sprintf(s128,"SEND protocol sync error 0x%04x: %s",err,Pathname);
X ecu_log_event(s128); /* always log this */
X report_str(s128 + 5,1);
X if(FileRejectCount < 127)
X FileRejectCount++;
X report_file_byte_io(this_file_length);
X report_file_close();
X fclose(in);
X return(ERROR);
X }
X }
X}
X
X/*
X * Respond to receiver's complaint, get back in sync with receiver
X */
Xgetinsync(flag)
X{
X register c;
X
X for(;;)
X {
X switch(c = zgethdr(Rxhdr,0))
X {
X case ZCAN:
X case ZABORT:
X case ZFIN:
X case TIMEOUT:
X sprintf(s128,"Receiver %s",frametypes[c+FTOFFSET]);
X report_str(s128,1);
X return(ERROR);
X case ZRPOS:
X report_str("Receiver ZRPOS",1);
X /* ************************************* */
X /* If sending to a modem buffer,you */
X /* might send a break at this point to */
X /* dump the modem's buffer. */
X /* ************************************* */
X if(Lastn >= 0 && Lastread == Rxpos)
X {
X Dontread = TRUE;
X } else
X {
X clearerr(in); /* In case file EOF seen */
X fseek(in,Rxpos,0);
X }
X bytcnt = Lrxpos = Txpos = Rxpos;
X if(Lastsync == Rxpos) /* wht - original code */
X { /* wht - original code */
X /* save frame count at time of each occurrence (wht) */
X bad_condx_frame_count = this_file_frame_count; /* wht */
X /* save block length at time of error (wht) */
X if(++SameZrposAgain > 4) /* wht - original code */
X { /* wht */
X if(bad_condx_blklen == 0) /* wht */
X bad_condx_blklen = blklen; /* wht */
X if(blklen > 256) /* wht - 32->256 */
X blklen /= 2; /* wht - original code */
X } /* wht */
X } /* wht - original code */
X Lastsync = Rxpos;
X report_send_stats(Txpos);
X return(c);
X case ZACK:
X Lrxpos = Rxpos;
X if(flag || Txpos == Rxpos)
X return(ZACK);
X continue;
X
X case ZRINIT:
X#if defined(LOG_XFER)
X sprintf(s256,"SEND success: %s",Pathname);
X ecu_log_event(s256);
X#endif
X case ZSKIP:
X report_file_byte_io(this_file_length);
X report_file_close();
X fclose(in);
X return(c);
X case ERROR:
X default:
X report_str("Sending ZNAK",1);
X zsbhdr(ZNAK,Txhdr);
X continue;
X }
X }
X}
X
X
X/* Say "cancel_transaction" to the receiver,try to do it cleanly */
Xsaybibi()
X{
X for(;;)
X {
X stohdr(0L); /* CAF Was zsbhdr - minor change */
X zshhdr(ZFIN,Txhdr); /* to make debugging easier */
X switch(zgethdr(Rxhdr,0))
X {
X case ZFIN:
X sendline('O');
X sendline('O');
X flushline();
X case ZCAN:
X case TIMEOUT:
X return;
X }
X }
X}
X
Xdetermine_transaction_time()
X{
Xregister c;
Xstruct stat f;
Xchar *name;
X
X rewind_file_list();
X TotalLeft = 0;
X Filesleft = 0;
X while(get_file_list_name(&name))
X {
X f.st_size = -1;
X if((access(name,04) >= 0) && (stat(name,&f) >= 0))
X {
X c = f.st_mode & S_IFMT;
X if(c != S_IFDIR && c != S_IFBLK)
X {
X ++Filesleft;
X TotalLeft += f.st_size;
X }
X }
X }
X FilesTotal = Filesleft;
X rewind_file_list();
X}
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
echo "File z/ecusz.c is complete"
chmod 0644 z/ecusz.c || echo "restore of z/ecusz.c fails"
echo "x - extracting z/zmodem.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > z/zmodem.c &&
X/* CHK=0x2976 */
X/*+-------------------------------------------------------------------------
X zmodem.c - ZMODEM protocol primitives
X based on code by Chuck Forsberg
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 Defined functions:
X noxrd7()
X rclhdr(hdr)
X stohdr(pos)
X zdlread()
X zgeth1()
X zgethdr(hdr,eflag)
X zgethex()
X zputhex(c)
X zrbhdr(hdr)
X zrbhdr32(hdr)
X zrdat32(buf,length)
X zrdata(buf,length)
X zrhhdr(hdr)
X zsbh32(hdr,type)
X zsbhdr(type,hdr)
X zsda32(buf,length,frameend)
X zsdata(buf,length,frameend)
X zsendline(c)
X zshhdr(type,hdr)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-03-1989-22:58-wht------------- ecu 2.00 ---------------- */
X/*:06-24-1989-16:51-wht-flush edits --- ecu 1.95 */
X
X#include "zmodem.h" /* wht */
X#include "zlint.h"
X
Xextern char s128[]; /* wht */
Xextern int Zctlesc; /* wht */
Xextern int Zmodem; /* wht */
Xextern long cr3tab[]; /* wht */
Xextern unsigned Baudrate; /* wht */
Xextern unsigned short crctab[]; /* wht */
X
Xint Rxtimeout = 100; /* Tenths of seconds to wait for something */
X
X#if !defined(UNSL)
X#define UNSL
X#endif
X
X
X
Xstatic lastsent; /* Last char we sent */
Xstatic evenp; /* Even parity seen on header */
X
X/* Globals used by ZMODEM functions */
Xchar Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
Xchar Rxhdr[4]; /* Received header */
Xchar Txhdr[4]; /* Transmitted header */
Xint Crc32; /* Display flag indicating 32 bit CRC being received */
Xint Crc32t; /* Display flag indicating 32 bit CRC being sent */
Xint Rxcount; /* Count of data bytes received */
Xint Rxframeind; /* ZBIN ZBIN32,or ZHEX type of frame received */
Xint Rxtimeout; /* Tenths of seconds to wait for something */
Xint Rxtype; /* Type of header received */
Xint Txfcs32; /* TURE means send binary frames with 32 bit FCS */
Xint Zrwindow; /* RX window size (controls garbage count) */
Xlong Rxpos; /* Received file position */
Xlong Txpos; /* Transmitted file position */
X
Xchar *frametypes[] =
X{
X "Carrier Lost", /* -3 */
X "TIMEOUT", /* -2 */
X "ERROR", /* -1 */
X/* #define FTOFFSET 3 moved to zmodem.h */
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 unsigned char *hdr;
X{
X register int n;
X register unsigned crc;
X
X report_tx_ind(1);
X sprintf(s128,"hdr %s %08lx",frametypes[type+FTOFFSET],rclhdr(hdr));
X report_last_txhdr(s128,0);
X
X xsendline(ZPAD);
X xsendline(ZDLE);
X
X if(Crc32t=Txfcs32)
X zsbh32(hdr,type);
X else
X {
X xsendline(ZBIN);
X zsendline(type);
X crc = updcrc(type,0);
X
X for(n=4; --n >= 0; ++hdr)
X {
X zsendline(*hdr);
X crc = updcrc(*hdr,crc);
X }
X crc = updcrc(0,updcrc(0,crc));
X zsendline(crc>>8);
X zsendline(crc);
X }
X if(type != ZDATA)
X flushline();
X report_tx_ind(0);
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 report_tx_ind(1);
X xsendline(ZBIN32);
X zsendline(type);
X crc = 0xFFFFFFFFL;
X crc = UPDC32(type,crc);
X
X for(n=4; --n >= 0; ++hdr)
X {
X crc = UPDC32((0377 & *hdr),crc);
X zsendline(*hdr);
X }
X crc = ~crc;
X for(n=4; --n >= 0;)
X {
X zsendline((int)crc);
X crc >>= 8;
X }
X report_tx_ind(0);
X}
X
X/* Send ZMODEM HEX header hdr of type type */
Xzshhdr(type,hdr)
Xregister unsigned char *hdr;
X{
X register int n;
X register unsigned short crc;
X
X report_tx_ind(1);
X
X sprintf(s128,"hdr %s %08lx",frametypes[type+FTOFFSET],rclhdr(hdr));
X report_last_txhdr(s128,0);
X sendline(ZPAD);
X sendline(ZPAD);
X sendline(ZDLE);
X sendline(ZHEX);
X zputhex(type);
X Crc32t = 0;
X
X crc = updcrc(type,0);
X for(n=4; --n >= 0; ++hdr)
X {
X zputhex(*hdr);
X crc = updcrc(*hdr,crc);
X/* crc = updcrc((0377 & *hdr),crc); original - wht */
X }
X crc = updcrc(0,updcrc(0,crc));
X zputhex(crc>>8);
X zputhex(crc);
X
X /* Make it printable on remote machine */
X sendline(015);
X 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 flushline();
X report_tx_ind(0);
X}
X
X/*
X * Send binary array buf of length length,with ending ZDLE sequence frameend
X */
Xstatic char *Zendnames[] = { "ZCRCE","ZCRCG","ZCRCQ","ZCRCW"};
X
Xzsdata(buf,length,frameend)
Xregister unsigned char *buf;
X{
X register unsigned short crc;
X
X report_tx_ind(1);
X
X sprintf(s128,"data %s %d bytes",Zendnames[frameend-ZCRCE&3],length);
X report_last_txhdr(s128,0);
X if(Crc32t)
X zsda32(buf,length,frameend);
X else
X {
X crc = 0;
X for(;--length >= 0; ++buf)
X {
X zsendline(*buf);
X crc = updcrc(*buf,crc);
X }
X xsendline(ZDLE);
X xsendline(frameend);
X crc = updcrc(frameend,crc);
X
X crc = updcrc(0,updcrc(0,crc));
X zsendline(crc>>8);
X zsendline(crc);
X }
X if(frameend == ZCRCW)
X {
X xsendline(XON);
X flushline();
X }
X report_tx_ind(0);
X
X}
X
Xzsda32(buf,length,frameend)
Xregister char *buf;
X{
X register int c;
X register UNSL long crc;
X
X report_tx_ind(1);
X
X crc = 0xFFFFFFFFL;
X for(;--length >= 0; ++buf)
X {
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);
X xsendline(frameend);
X crc = UPDC32(frameend,crc);
X
X crc = ~crc;
X for(length=4; --length >= 0;)
X {
X zsendline((int)crc);
X crc >>= 8;
X }
X report_tx_ind(0);
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 report_rx_ind(1);
X
X if(Rxframeind == ZBIN32)
X {
X report_rx_ind(0);
X return(zrdat32(buf,length));
X }
X
X crc = Rxcount = 0;
X end = buf + length;
X while(buf <= end)
X {
X if((c = zdlread()) & ~0377)
X {
Xcrcfoo:
X switch(c)
X {
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 {
X report_str(badcrc,1);
X report_rx_ind(0);
X return(ERROR);
X }
X Rxcount = length - (end - buf);
X report_rxblklen(Rxcount);
X sprintf(s128,"data %s %d bytes",
X Zendnames[d-GOTCRCE&3],Rxcount);
X report_last_rxhdr(s128,0);
X report_rx_ind(0);
X return(d);
X case GOTCAN:
X report_str("Sender Cancelled",1);
X report_rx_ind(0);
X return(ZCAN);
X case TIMEOUT:
X report_str("TIMEOUT",1);
X report_rx_ind(0);
X return(c);
X default:
X report_str("Bad data subpacket",1);
X report_rx_ind(0);
X return(c);
X }
X }
X *buf++ = c;
X crc = updcrc(c,crc);
X }
X report_str("Data subpacket too long",1);
X report_rx_ind(0);
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 report_rx_ind(1);
X crc = 0xFFFFFFFFL;
X Rxcount = 0;
X end = buf + length;
X while(buf <= end)
X {
X if((c = zdlread()) & ~0377)
X {
Xcrcfoo:
X switch(c)
X {
X case GOTCRCE:
X case GOTCRCG:
X case GOTCRCQ:
X case GOTCRCW:
X d = c;
X 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 {
X report_str(badcrc,1);
X report_rx_ind(0);
X return(ERROR);
X }
X Rxcount = length - (end - buf);
X report_rxblklen(Rxcount);
X sprintf(s128,"data %s %d bytes",
X Zendnames[d-GOTCRCE&3],Rxcount);
X report_last_rxhdr(s128,0);
X report_rx_ind(0);
X return(d);
X case GOTCAN:
X report_str("Sender Canceled",1);
X report_rx_ind(0);
X return(ZCAN);
X case TIMEOUT:
X report_str("TIMEOUT",1);
X report_rx_ind(0);
X return(c);
X default:
X report_str("Bad data subpacket",1);
X report_rx_ind(0);
X return(c);
X }
X }
X *buf++ = c;
X crc = UPDC32(c,crc);
X }
X report_str("Data subpacket too long",1);
X report_rx_ind(0);
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{
Xregister int c,n,cancount;
X
X report_rx_ind(1);
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 {
X case RCDO:
X case TIMEOUT:
X goto fifi;
X case CAN:
Xgotcan:
X if(--cancount <= 0)
X {
X c = ZCAN;
X goto fifi;
X }
X switch(c = readline(1))
X {
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 {
X c = ZCAN;
X goto fifi;
X }
X goto again;
X }
X /* **** FALL THRU TO **** */
X default:
Xagn2:
X if( --n == 0)
X {
X report_str("Garbage count exceeded",1);
X report_last_rxhdr("Noise",0);
X report_rx_ind(0);
X return(ERROR);
X }
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 {
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 {
X case RCDO:
X case TIMEOUT:
X goto fifi;
X case ZBIN:
X Rxframeind = ZBIN;
X 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;
X 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 {
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 sprintf(s128,"Got %s",frametypes[c+FTOFFSET]);
X report_str(s128,1);
X /* **** FALL THRU TO **** */
X default:
X if(c >= -3 && c <= FRTYPES)
X sprintf(s128,"hdr %s %08lx",frametypes[c+FTOFFSET],Rxpos);
X else
X sprintf(s128,"hdr 0x%02x? %08lx",c,Rxpos);
X report_last_rxhdr(s128,0);
X }
X report_rx_ind(0);
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 {
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 {
X if(evenp)
X report_str(masked,1);
X report_str(badcrc,1);
X return(ERROR);
X }
X#if defined(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;
X crc = UPDC32(c,crc);
X
X for(n=4; --n >= 0; ++hdr)
X {
X if((c = zdlread()) & ~0377)
X return(c);
X crc = UPDC32(c,crc);
X *hdr = c;
X }
X for(n=4; --n >= 0;)
X {
X if((c = zdlread()) & ~0377)
X return(c);
X crc = UPDC32(c,crc);
X }
X if(crc != 0xDEBB20E3)
X {
X if(evenp)
X report_str(masked,1);
X report_str(badcrc,1);
X return(ERROR);
X }
X#if defined(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 {
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 {
X report_str(badcrc,1);
X return(ERROR);
X }
X if(readline(1) == '\r') /* Throw away possible cr/lf */
X readline(1);
X#if defined(ZMODEM)
X Protocol = ZMODEM;
X#endif
X Zmodem = 1;
X 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 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 {
X switch(c &= 0377)
X {
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:
SHAR_EOF
echo "End of part 27"
echo "File z/zmodem.c is continued in part 28"
echo "28" > s2_seq_.tmp
exit 0
--
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation ...!gatech!emory!tridom!wht
Ker-au'-lo-phon. An 8-foot partial flue-stop, having metal pipes
surmounted by adjustable rings, and with a hole bored near the top
of each pipe, producing a soft and "reedy" tone.
More information about the Alt.sources
mailing list