wht@gatech.edu@tridom.UUCP (Warren H. Tucker) (05/30/90)
Posting-number: Volume 13, Issue 15 Submitted-by: wht@gatech.edu@tridom.UUCP (Warren H. Tucker) Archive-name: tipx/part03 #!/bin/sh # This is part 03 of tipx if touch 2>&1 | fgrep 'mmdd' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= xfer/tipsz.c ============== echo "x - extracting xfer/tipsz.c (Text)" sed 's/^X//' << 'SHAR_EOF' > xfer/tipsz.c && Xchar *numeric_revision = "tipsz 1.00"; X#define BUFFERED_WRITE X/*+------------------------------------------------------------------------- X tipsz.c - X/Y/ZMODEM send program X Derived from public domain source by Chuck Forsberg, Omen Technologies X wht%n4hgf@emory.mathcs.emory.edu X X Usage: tipsz [-X -Y -Z] [-12+abdefkLlNnquvwy] [-] file ... X (Y) = Option applies to YMODEM only X (Z) = Option applies to ZMODEM only X a (ASCII) change NL to CR/LF X b Binary file transfer override X f send Full pathname (Y/Z) X k Send 1024 byte packets (Y) X L N Limit subpacket length to N bytes (Z) X l N Limit frame length to N bytes (l>=L) (Z) X n send file if source newer (Z) X N send file if source newer or longer (Z) X o Use 16 bit CRC instead of 32 bit CRC (Z) X p Protect existing destination file (Z) X r Resume/Recover interrupted file transfer (Z) X q Quiet (no progress reports) X u Unlink file after transmission X w N Window is N bytes (Z) X y Yes,overwrite existing file (Z) X @file reads a list of filenames from 'file' X X Defined functions: X SIGALRM_handler() X bye_bye(sig) X cancel_transaction(sig) X determine_transaction_time() X flushline() X get_file_list_name(namep) X getinsync(flag) X getnak() X getzrxinit() X log_packet_buffer(buf,len) X main(argc,argv) X onintr() X purgeline() X readline(n) X readock(timeout,count) X report_rcvr_cancelled(place_happened) X report_rcvr_skipped() X report_send_stats(filepos) X report_send_transaction() X rewind_file_list() X saybibi() X send_cancel() X sendline(ch) X sendzsinit() X set_file_list(pathc,pathv) X substr(s,t) X usage() X wcputsec(buf,sectnum,cseclen) X wcs(oname) X wcsend() X wctx(flen) X wctxpn(name) X xbuf_build(buf,count) X xsendline(ch) X zbuf_build(buf,count) X zsendfdata() X zsendfile(buf,blen) X X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:05-21-1990-16:00-wht@tridom-adapt ecu xfer protocols for tipwht */ X X/* X Error return conditions X 255: usage X 254: protocol failed (bad line conditions,brain dead remote) X 253: could not open any files X 128-192: process terminated with signal==code-128 (64 signals allowed for) X signal 0 == program logic error (see cancel_transaction) X 127: 127 or more files not transmitted (see ~/.tip/log) X 1-126: count of files not transmitted (see ~/.tip/log) X 0: file transfer completely successful X*/ X Xchar *substr(),*getenv(); X X#include <stdio.h> X#include <signal.h> X#include <setjmp.h> X#include <ctype.h> X#include <fcntl.h> X#include "zmodem.h" X#include "zlint.h" X Xextern char *sys_errlist[]; Xextern unsigned short crctab[]; /* wht */ Xextern unsigned long total_data_chars_xfered; /* zcurses.c */ Xextern int errno; Xextern int show_window; Xextern int Rxtimeout; /* Tenths of seconds to wait for something */ Xextern char Rxhdr[4]; /* Received header */ Xextern char Txhdr[4]; /* Transmitted header */ Xextern int Txfcs32; /* TURE means send binary frames with 32 bit FCS */ Xextern long Rxpos; /* Received file position */ Xextern long Txpos; /* Transmitted file position */ Xextern char *frametypes[]; Xextern char Attn[]; /* Attention string rx sends to tx on err */ Xextern char s256[]; X X#define RETRYMAX 10 /* non-zmodem retry count on block send */ X#define VMIN_COUNT 2 /* must not exceed 255 */ Xunsigned char vmin_count = VMIN_COUNT; Xint iofd = 0; /* line io fd */ X#ifdef BUFFERED_WRITE XFILE *iofp; Xchar iofpbuf[256]; X#endif X X X/* X * Attention string to be extipted by receiver to interrupt streaming data X * when an error is detected. A pause (0336) may be needed before the X * ^C (03) or after it. X */ X#if defined(READCHECK) Xchar Myattn[] = { 0 }; X#else X#if defined(M_SYS5) Xchar Myattn[] = { 03,0336,0 }; X#else Xchar Myattn[] = { 0 }; X#endif X#endif X XFILE *in; X Xchar *Cmdstr; /* Pointer to the command string */ Xchar *bottom_label = (char *)0; Xchar Crcflg; Xchar Lastrx; Xchar Lzconv; /* Local ZMODEM file conversion request */ Xchar Lzmanag; /* Local ZMODEM file management request */ Xchar Lztrans; Xchar Pathname[PATHLEN]; Xchar curr_dir[256]; Xchar s128[128]; Xchar txbuf[1024]; Xchar zconv; /* ZMODEM file conversion request */ Xchar zmanag; /* ZMODEM file management request */ Xchar ztrans; /* ZMODEM file transport request */ Xint Ascii=0; /* Add CR's for brain damaged programs */ Xint Cmdack1; /* Rx ACKs command,then do it */ Xint Cmdtries = 11; Xint Command = 0; /* Send a command,then exit. */ Xint Dontread; /* Don't read the buffer,it's still there */ Xint Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */ Xint Exitcode = 0; Xint Filcnt=0; /* count of number of files opened */ Xint FilesTotal; Xint Filesleft; Xint Fullname=0; /* transmit full pathname */ Xint Lastn; /* Count of last buffer read or -1 */ Xint Lfseen=0; Xint Noeofseen; Xint Nozmodem = 0; Xint Optiong; /* no wait for block ACK's */ Xint Quiet=0; /* overrides logic that would otherwise set verbose */ Xint Rxflags = 0; Xint SameZrposAgain=0; /* How many times we've been ZRPOS'd same place (wht) */ Xint Tframlen = 0; /* Override for tx frame length */ Xint Totsecs; /* total number of blocks this file */ Xint Twostop = 0; /* use two stop bits */ Xint Unlinkafter=0; /* Unlink file after it is sent */ Xint Wantfcs32 = TRUE; /* want to send 32 bit FCS */ Xint Xmodem=0; /* XMODEM Protocol - don't send pathnames */ Xint Zctlesc; /* Encode control characters */ Xint Zmodem=0; /* ZMODEM protocol requested by receiver */ Xint Zrwindow = 1400; /* RX window size (controls garbage count) */ Xint blklen=128; /* length of transmitted records */ Xint blklen_original; Xint blkopt=0; /* Override value for zmodem blklen */ Xint tipsz_flag = 1; Xint skip_count = 0; /* skipped files */ Xint errors; Xint firstsec; Xint log_packets = 0; Xint no_files = 0; Xint npats = 0; Xlong Lastread; /* Beginning offset of last buffer read */ Xlong Lastsync; /* Last offset to which we got a ZRPOS */ Xlong Lrxpos; /* Receiver's last reported offset */ Xlong TotalLeft; Xlong TotalToSend; Xlong bytcnt; Xlong rx_char_count = 0L; Xlong this_file_length; Xlong tx_char_count = 0L; Xunsigned Baudrate; Xunsigned Rxbuflen = 16384; /* Receiver's max buffer length */ Xunsigned Txwcnt; /* Counter used to space ack requests */ Xunsigned Txwindow; /* Control the size of the transmitted window */ Xunsigned Txwspac; /* Spacing between zcrcq requests */ Xunsigned int bad_condx_blklen = 0; /* if <>0,blklen has been reduced (wht) */ Xunsigned int bad_condx_frame_count = 0; /* frame # last SameZrposAgain (wht) */ Xunsigned int this_file_frame_count; /* count of frames sent this file (wht) */ X X#define MAX_PATHS 512 Xchar *paths[MAX_PATHS]; X Xjmp_buf tohere; /* For the interrupt on RX timeout */ Xjmp_buf intrjmp; /* For the interrupt on RX CAN */ X Xint file_list_pathc; Xint file_list_path_current; Xchar **file_list_pathv; Xint required_type = 0; XFILE *fpflst = (FILE *)0; X X/*+------------------------------------------------------------------------- X log_packet_buffer(buf,len) X--------------------------------------------------------------------------*/ Xvoid Xlog_packet_buffer(buf,len) Xregister unsigned char *buf; Xregister int len; X{ Xchar xbuf[32]; X X while(len--) X { X sprintf(xbuf,"%02x ",*buf++); X write(log_packets,xbuf,strlen(xbuf)); X } X write(log_packets,"\n",1); X X} /* end of log_packet_buffer */ X X/*+------------------------------------------------------------------------- X rewind_file_list() X--------------------------------------------------------------------------*/ Xvoid Xrewind_file_list() X{ X file_list_path_current = 0; X if(fpflst) X { X fclose(fpflst); X fpflst = (FILE *)0; X } X} /* end of rewind_file_list */ X X/*+------------------------------------------------------------------------- X set_file_list(pathc,pathv) X--------------------------------------------------------------------------*/ Xvoid Xset_file_list(pathc,pathv) Xint pathc; Xchar **pathv; X{ X X file_list_pathc = pathc; X file_list_pathv = pathv; X rewind_file_list(); X} /* end of set_file_list */ X X/*+------------------------------------------------------------------------- X get_file_list_name(namep) X--------------------------------------------------------------------------*/ Xget_file_list_name(namep) Xchar **namep; X{ Xregister char *cptr; Xstatic char name[256]; X Xtry_fpflst: X if(fpflst) X { X if(fgets(name,sizeof(name),fpflst) != NULL) X { X name[strlen(name) - 1] = 0; X *namep = name; X return(1); X } X fclose(fpflst); X fpflst = (FILE *)0; X } X Xnext_arg: X if(file_list_path_current == file_list_pathc) X return(0); X cptr = file_list_pathv[file_list_path_current++]; X if(*cptr != '@') X { X *namep = cptr; X return(1); X } X cptr++; X if((fpflst = fopen(cptr,"r")) == NULL) X goto next_arg; X goto try_fpflst; X X} /* end of get_file_list_name */ X X/*+------------------------------------------------------------------------- X bye_bye(sig) X--------------------------------------------------------------------------*/ Xvoid Xbye_bye(sig) Xint sig; X{ X exit(sig+128); X} /* end of bye_bye */ X X/*+------------------------------------------------------------------------- X cancel_transaction(sig) Xcalled by signal interrupt or terminate to clean things up X--------------------------------------------------------------------------*/ Xvoid Xcancel_transaction(sig) X{ X if(Zmodem) X zmputs(Attn); X send_cancel(); X mode(0); X if(sig >= 0) X { X sprintf(s128,"tipsz aborted (signal %d)",sig); X report_str(s128,0); X } X report_tx_ind(0); X report_rx_ind(0); X report_uninit(0); X bye_bye(sig); X} /* end of cancel_transaction */ X X/* Called when ZMODEM gets an interrupt (^X) */ Xonintr() X{ X signal(SIGINT,SIG_IGN); X#if defined(M_SYS5) X report_rx_ind(0); X report_tx_ind(0); X#endif X longjmp(intrjmp,-1); X} X X X/*+------------------------------------------------------------------------- X report_send_transaction() X--------------------------------------------------------------------------*/ Xvoid Xreport_send_transaction() X{ X if(Xmodem) X { X long blocks = (TotalToSend >> 7) + ((TotalToSend % 128) != 0); X long secs = 7 /* slightly worse than average first nak delay */ X + (blocks / 5L) /* assume .2 sec ack time */ X + ((blocks * (128L + 16L)) / (Baudrate / 10)); X if(!secs) X secs = 10L; X sprintf(s128,"Sending %ld blocks time ~= %ld:%02ld", X blocks,secs/60,secs % 60); X } X else X { X long min_100 = X (FilesTotal * 2L) + (((TotalToSend * 11L)) * 10L) / (Baudrate * 6L); X if(!min_100) X min_100 = 4L; X#if defined(M_I286) /* slower */ X else if(Baudrate > 4800) X { X min_100 *= 13; X min_100 /= 9; /* yech ... empirical */ X } X#endif X sprintf(s128,"Sending %ld bytes total time ~= %2lu:%02lu", X TotalToSend,min_100 / 100,((min_100 % 100) * 60L) / 100L); X } X report_transaction(s128); X X} /* end of report_send_transaction */ X X/*+------------------------------------------------------------------------- X report_send_stats(filepos) X--------------------------------------------------------------------------*/ Xvoid Xreport_send_stats(filepos) Xlong filepos; X{ X X if(Xmodem) X sprintf(s128,"File %d%% complete", X (this_file_length == 0) ? (int)100 : X (int)((filepos * 100L) / this_file_length)); X else X sprintf(s128,"This file %d%%, transaction %d%% complete", X (this_file_length == 0) ? (int)100 : X (int)((filepos * 100L)/this_file_length), X (TotalToSend == 0) ? (int)100 : X (int)(((total_data_chars_xfered + filepos) * 100L) X / TotalToSend)); X report_str(s128,0); X report_txpos(filepos); X X} /* end of report_send_stats */ X X/*+------------------------------------------------------------------------- X report_rcvr_cancelled(place_happened) X--------------------------------------------------------------------------*/ Xvoid Xreport_rcvr_cancelled(place_happened) Xchar *place_happened; X{ X strcpy(s128,"SEND CANCELLED"); X report_str(s128 + 5,1); X skip_count++; X report_error_count(); X} /* end of report_rcvr_cancelled */ X X/*+------------------------------------------------------------------------- X report_rcvr_skipped() X--------------------------------------------------------------------------*/ Xvoid Xreport_rcvr_skipped() X{ X sprintf(s128,"SEND skipped: %s",Pathname); X report_str(s128 + 5,-1); X skip_count++; X report_error_count(); X TotalToSend -= this_file_length; X report_send_transaction(); X} /* end of report_rcvr_skipped */ X X X/*+------------------------------------------------------------------------- X xsendline(ch) X--------------------------------------------------------------------------*/ Xxsendline(ch) Xchar ch; X{ X#ifdef BUFFERED_WRITE X fputc(ch,iofp); X#else X write(iofd,&ch,1); X#endif X ++tx_char_count; X} /* end of xsendline */ X X/*+------------------------------------------------------------------------- X sendline(ch) X--------------------------------------------------------------------------*/ Xsendline(ch) Xchar ch; X{ X xsendline(ch); X} /* end of sendline */ X Xflushline() X{ X#ifdef BUFFERED_WRITE X fflush(iofp); X#endif X} X Xmain(argc,argv) Xchar *argv[]; X{ Xregister char *cp; Xlong min_100; Xchar **patts = paths; Xchar **gargv = argv; Xint gargc = argc; X X signal(SIGINT,bye_bye); X signal(SIGTERM,bye_bye); X X get_curr_dir(curr_dir,sizeof(curr_dir)); X X Rxtimeout = 600; X npats=0; X if(argc<2) X usage(); X while(--argc) X { X cp = *++argv; X if(*cp == '-') X { X cp++; X switch(*cp++) X { X case 'X': X required_type = 1; X Xmodem = TRUE; X break; X case 'Y': X required_type = 1; X Nozmodem = TRUE; X blklen=1024; X break; X case 'Z': X show_window = 1; X required_type = 1; X break; X X case '+': X Lzmanag = ZMAPND; X break; X case 'a': X Lzconv = ZCNL; X Ascii = TRUE; X break; X case 'b': X Lzconv = ZCBIN; X break; X case 'd': X ++Dottoslash; X /* **** FALL THROUGH TO **** */ X case 'f': X Fullname=TRUE; X break; X case ',': X log_packets = 1; X break; X case '/': X if(--argc < 1) X usage(); X strcpy(curr_dir,*++argv); X break; X case '.': X if(--argc < 1) X usage(); X iofd = atoi(*++argv); X break; X case 'C': X if(--argc < 1) X usage("no label after -C"); X bottom_label = *++argv; X break; X case 'e': X Zctlesc = 1; X break; X case 'k': X blklen=1024; X break; X case 'L': X if(--argc < 1) X { X usage(); X } X blkopt = atoi(*++argv); X if(blkopt<24 || blkopt>1024) X usage(); X break; X case 'l': X if(--argc < 1) X { X usage(); X } X Tframlen = atoi(*++argv); X if(Tframlen<32 || Tframlen>1024) X usage(); X break; X case 'N': X Lzmanag = ZMNEWL; X break; X case 'n': X Lzmanag = ZMNEW; X break; X case 'o': X Wantfcs32 = FALSE; X break; X case 'p': X Lzmanag = ZMPROT; X break; X case 'r': X Lzconv = ZCRESUM; X case 't': X if(--argc < 1) X { X usage(); X } X Rxtimeout = atoi(*++argv); X if(Rxtimeout<10 || Rxtimeout>1000) X usage(); X break; X case 'u': X ++Unlinkafter; X break; X case 'w': X if(--argc < 1) X { X usage(); X } X Txwindow = atoi(*++argv); X if(Txwindow < 256) X Txwindow = 256; X Txwindow = (Txwindow/64) * 64; X Txwspac = Txwindow/4; X if(blkopt > Txwspac || (!blkopt && Txwspac < 1024)) X blkopt = Txwspac; X break; X case 'y': X Lzmanag = ZMCLOB; X break; X default: X usage(); X } X } X else if(argc > 0) X { X if(npats < MAX_PATHS) X { X npats++; X *patts++ = cp; X } X else X { X printf("too many filenames to send\n"); X exit(255); X } X } X } X if(!required_type || !iofd) X { X printf("can only be run by tip\n"); X exit(255); X } X X if(npats < 1 && !Command) X usage(); X X set_file_list(npats,paths); X sprintf(s128,"%s",numeric_revision); X X if(log_packets) X { X char log_packets_name[64]; X FILE *ftmp; X int iargv; X sprintf(log_packets_name,"/tmp/sz%05d.plog",getpid()); X unlink(log_packets_name); X ftmp = fopen(log_packets_name,"w"); X fclose(ftmp); X log_packets = open(log_packets_name,O_WRONLY,0644); X if(log_packets < 0) X log_packets = 0; X else X { X write(log_packets,"exec: ",6); X for(iargv = 0; iargv < gargc; iargv++) X { X write(log_packets,gargv[iargv],strlen(gargv[iargv])); X write(log_packets," ",1); X } X write(log_packets,"\n",1); X } X } X X report_init(s128); X mode(1); X X if(signal(SIGINT,cancel_transaction) == SIG_IGN) X signal(SIGINT,SIG_IGN); X else X signal(SIGINT,cancel_transaction); X signal(SIGTERM,cancel_transaction); X X report_str("calculating transaction time",-1); X determine_transaction_time(); X#ifdef BUFFERED_WRITE X iofp = fdopen(iofd,"w"); X setbuffer(iofp,iofpbuf,sizeof(iofpbuf)); X#endif X if(!Xmodem) X { X TotalToSend = TotalLeft; X report_send_transaction(); X report_str("starting remote receiver",-1); X if(!Nozmodem) X write(iofd,"rz\r",3); X else /* wht -- why not? */ X write(iofd,"rb\r",3); /* wht */ X sleep(2); X report_str("beginning transfer",-1); X if(!Nozmodem) X { X stohdr(0L); X zshhdr(ZRQINIT,Txhdr); X } X } X else X report_str("beginning transfer",-1); X X if(wcsend()==ERROR) X { X Exitcode=254; /*wht was 0200 */ X send_cancel(); X } X mode(0); X report_uninit(0); X if(no_files) X Exitcode = 253; X exit(Exitcode ? Exitcode : (skip_count > 127) ? 127 : skip_count); X /*NOTREACHED*/ X} X X/*+------------------------------------------------------------------------- X wcsend(argc,argp) -- send group of files X--------------------------------------------------------------------------*/ Xwcsend() X{ X register n; X char *name; X X Crcflg=FALSE; X firstsec=TRUE; X bytcnt = -1; X rewind_file_list(); X while(get_file_list_name(&name)) X { X Totsecs = 0; X if(wcs(name)==ERROR) X return(ERROR); X } X Totsecs = 0; X if(Filcnt==0) X { /* bitch if we couldn't open ANY files */ X send_cancel(); X strcpy(s128,"SEND cannot open any requested files"); X report_str(s128 + 5,1); X sleep(2); /* allow time for other rz to get ready */ X no_files = 1; X return(ERROR); /* ... then cancel */ X } X if(Zmodem) X saybibi(); X else if(!Xmodem) X wctxpn(""); X return(OK); X} X X/*+------------------------------------------------------------------------- X wcs(oname) -- send a file X--------------------------------------------------------------------------*/ Xwcs(oname) Xchar *oname; X{ Xregister c; Xregister char *p; Xstruct stat f; X X strcpy(Pathname,oname); /* global copy of name */ X X if((in=fopen(oname,"r"))==NULL) X { X sprintf(s128,"SEND %s: %s",sys_errlist[errno],oname); X report_str(s128 + 5,1); X skip_count++; X report_error_count(); X return(OK); /* pass over it,there may be others */ X } X ++Noeofseen; X Lastread = 0; X Lastn = -1; X Dontread = FALSE; X /* Check for directory or block special files */ X fstat(fileno(in),&f); X c = f.st_mode & S_IFMT; X if(c == S_IFDIR || c == S_IFBLK) X { X sprintf(s128,"SEND %s: %s", X (c == S_IFDIR) ? "directory" : "block device",oname); X report_str(s128 + 5,1); X skip_count++; X report_error_count(); X fclose(in); X return(OK); X } X f.st_mode &= ~(S_ISUID | S_ISGID); X Filcnt++; X report_file_send_open(oname,&f); X this_file_length = f.st_size; X report_send_stats(0L); X switch(wctxpn(Pathname)) X { X case ERROR: X sprintf(s128,"SEND protocol failure: %s",oname); X report_str(s128 + 5,1); X skip_count++; X report_error_count(); X report_file_close(); X fclose(in); X return(ERROR); X case ZSKIP: X report_rcvr_skipped(); X return(OK); X } X if(!Zmodem && wctx(f.st_size)==ERROR) X return(ERROR); X if(Unlinkafter) X unlink(oname); X return(0); X} X X/* X * generate and transmit pathname block consisting of X * pathname (null terminated), X * file length,mode time and file mode in octal X * as provided by the Unix fstat call. X * N.B.: modifies the passed name,may extend it! X */ Xwctxpn(name) Xchar *name; X{ X register char *p,*q; X char name2[PATHLEN]; X struct stat f; X X if(Xmodem) X { X if((in!=stdin) && *name && fstat(fileno(in),&f)!= -1) X { X TotalToSend = f.st_size; X report_protocol_type("XMODEM"); X report_send_transaction(); X report_xfer_mode((Ascii) ? "ASCII" : "BINARY"); X report_last_txhdr("Waiting on NAK",0); X } X return(OK); X } X if(!Zmodem) X { X report_last_txhdr("START PENDING",0); X if(getnak()) X { X report_str("Timeout on pathname nak",1); X return(ERROR); X } X } X X q = (char *) 0; X if(Dottoslash) X { /* change . to . */ X for(p=name; *p; ++p) X { X if(*p == '/') X q = p; X else if(*p == '.') X *(q=p) = '/'; X } X if(q && strlen(++q) > 8) X { /* If name>8 chars */ X q += 8; /* make it .ext */ X strcpy(name2,q); /* save excess of name */ X *q = '.'; X strcpy(++q,name2); /* add it back */ X } X } X X for(p=name,q=txbuf ; *p; ) X if((*q++ = *p++) == '/' && !Fullname) X q = txbuf; X *q++ = 0; X p=q; X while(q < (txbuf + 1024)) X *q++ = 0; X if(!Ascii && (in != stdin) && *name && !fstat(fileno(in),&f)) X sprintf(p,"%lu %lo %o 0 %d %ld",f.st_size,f.st_mtime, X f.st_mode &= ~(S_ISUID | S_ISGID), X Filesleft,TotalLeft); X report_xfer_mode((Lzconv == ZCNL) ? "ASCII" : "BINARY"); X TotalLeft -= f.st_size; X if(--Filesleft <= 0) X TotalLeft = 0; X if(TotalLeft < 0) X TotalLeft = 0; X X /* force 1k blocks if name won't fit in 128 byte block */ X if(txbuf[125]) X blklen=1024; X else X { /* A little goodie for IMP/KMD */ X txbuf[127] = (f.st_size + 127) >>7; X txbuf[126] = (f.st_size + 127) >>15; X } X if(Zmodem) X return(zsendfile(txbuf,1+strlen(p)+(p-txbuf))); X report_protocol_type("YMODEM"); X if(wcputsec(txbuf,0,128)==ERROR) X return(ERROR); X return(OK); X} X Xgetnak() X{ X register firstch; X X Lastrx = 0; X for(;;) X { X switch(firstch = readock(50,1)) /* 50 was 800 (80 secs!!) wht */ X { X case ZPAD: X if(getzrxinit()) X return(ERROR); X Ascii = 0; /* Receiver does the conversion */ X return(FALSE); X case TIMEOUT: X report_str("Timeout",1); X return(TRUE); X case WANTG: X#if defined(MODE2OK) X mode(2); /* Set cbreak,XON/XOFF,etc. */ X#endif X Optiong = TRUE; X blklen=1024; X case WANTCRC: X Crcflg = TRUE; X case NAK: X return(FALSE); X case CAN: X if((firstch = readock(20,1)) == CAN && Lastrx == CAN) X return(TRUE); X default: X break; X } X Lastrx = firstch; X } X} X X/*+------------------------------------------------------------------------- X wctx(flen) X--------------------------------------------------------------------------*/ Xwctx(flen) Xlong flen; X{ Xregister int thisblklen; Xregister int firstch; Xregister int sectnum; Xregister int attempts; Xlong charssent; X X charssent = 0; X firstsec=TRUE; X thisblklen = blklen; X report_txblklen(blklen); X X attempts = 8; X while(((firstch = readock(Rxtimeout,2)) != NAK) && X (firstch != WANTCRC) && (firstch != WANTG) && X (firstch != TIMEOUT) && (firstch != CAN)) X { X if(!--attempts) X { X report_str("bad start stimulus",1); X send_cancel(); X return(ERROR); X } X } X X if(firstch==CAN) X { X report_str("receiver CAN",1); X return(ERROR); X } X X if((firstch==WANTCRC) || (firstch==WANTG)) X Crcflg=TRUE; X X report_protocol_crc_type((Crcflg) X ? ((firstch== WANTG) ? "/CRC-g" : "/CRC") X : "/CHK"); X X sectnum=0; X for(;;) X { X if(flen <= (charssent + 896L)) X { X thisblklen = 128; X report_txblklen(thisblklen); X } X if(!xbuf_build(txbuf,thisblklen)) X break; X if(wcputsec(txbuf,++sectnum,thisblklen)==ERROR) X return(ERROR); X charssent += thisblklen; X } X X /* file transfer completed */ X report_file_byte_io(this_file_length); X report_file_close(); X fclose(in); X X attempts=0; X do X { X purgeline(); X sendline(EOT); X flushline(); X report_last_txhdr("EOT",0); X ++attempts; X } while((firstch=(readock(Rxtimeout,1)) != ACK) && attempts < RETRYMAX); X if(attempts == RETRYMAX) X { X report_str("No ACK on EOT",1); X return(ERROR); X } X else X return(OK); X} X Xwcputsec(buf,sectnum,cseclen) Xunsigned char *buf; Xint sectnum; Xint cseclen; /* data length of this block to send */ X{ X register int checksum; X register int wcj; X register unsigned char *cp; X unsigned short oldcrc; X int firstch; X int attempts; X X firstch=0; /* part of logic to detect CAN CAN */ X X sprintf(s128,"Sending block %d",sectnum); X report_last_txhdr(s128,0); X if(log_packets) X { X log_packet_buffer(buf,cseclen); X } X X for(attempts=0; attempts <= RETRYMAX; attempts++) X { X Lastrx= firstch; X sendline(cseclen == 1024 ? STX : SOH); X sendline(sectnum); X sendline(-sectnum - 1); X oldcrc=checksum=0; X X for(wcj = cseclen,cp = buf; --wcj >= 0; ) X { X sendline(*cp); X oldcrc=updcrc(*cp,oldcrc); X checksum += *cp++; X } X if(Crcflg) X { X oldcrc=updcrc(0,updcrc(0,oldcrc)); X sendline((int)(oldcrc >> 8)); X sendline((int)(oldcrc & 0xFF)); X } X else X sendline(checksum); X flushline(); X X if(Optiong) X { X firstsec = FALSE; X return(OK); X } X firstch = readock(Rxtimeout,(Noeofseen&§num) ? 2:1); Xgotnak: X switch(firstch) X { X case CAN: X if(Lastrx == CAN) X { Xcancan: X report_last_rxhdr("CAN",1); X return(ERROR); X } X break; X case TIMEOUT: X report_last_rxhdr("Timeout",1); X continue; X case WANTCRC: X if(firstsec) X Crcflg = TRUE; X case NAK: X report_last_rxhdr("NAK",1); X continue; X case ACK: X report_last_rxhdr("ACK",0); X firstsec=FALSE; X Totsecs += (cseclen>>7); X return(OK); X case ERROR: X report_last_rxhdr("Noise",0); X break; X default: X sprintf(s128,"0x%02x ???",firstch); X report_last_rxhdr(s128,1); X break; X } X for(;;) X { X Lastrx = firstch; X if((firstch = readock(Rxtimeout,2)) == TIMEOUT) X break; X if(firstch == NAK || firstch == WANTCRC) X goto gotnak; X if(firstch == CAN && Lastrx == CAN) X goto cancan; X } X } X report_str("retry count exceeded",1); X return(ERROR); 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/*+------------------------------------------------------------------------- X zbuf_build(buf,count) - fill buf with count chars X--------------------------------------------------------------------------*/ Xzbuf_build(buf,count) Xregister char *buf; Xint count; X{ Xregister 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} /* end of zbuf_build */ X X/*+------------------------------------------------------------------------- X SIGALRM_handler() X--------------------------------------------------------------------------*/ XSIGALRM_handler() X{ X#if defined(M_SYS5) X report_rx_ind(0); X report_tx_ind(0); X#endif X longjmp(tohere,-1); X} /* end of SIGALRM_handler */ X X/*+------------------------------------------------------------------------- X readock(timeout,count) Xtimeout is in tenths of seconds reads character(s) from file Xdescriptor 'fd' read 'count' characters, (1 <= count <= 3) if more than Xone received, return ERROR unless all are CAN normal response is NAK, XACK, CAN, G or C X--------------------------------------------------------------------------*/ Xreadock(timeout,count) Xint timeout; Xint 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} /* end of readock */ X X X/*+------------------------------------------------------------------------- X readline(n) X--------------------------------------------------------------------------*/ Xreadline(n) Xint n; X{ X return(readock(n,1)); X} /* end of readline */ X X X X/*+------------------------------------------------------------------------- X purgeline() X--------------------------------------------------------------------------*/ Xpurgeline() X{ X#if defined(M_SYS5) X ioctl(iofd,TCFLSH,0); X#else X lseek(iofd,0L,2); X#endif X} /* end of purgeline */ X X X/*+------------------------------------------------------------------------- X send_cancel() - send cancel to remote X--------------------------------------------------------------------------*/ 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} /* end of send_cancel */ X X X/*+------------------------------------------------------------------------- X substr(str,substr) - searches for substr in string str X--------------------------------------------------------------------------*/ Xchar * Xsubstr(str,substr) Xregister char *str,*substr; X{ Xregister char *sptr; Xregister char *ssptr; X X for(sptr = str; *str; str++) X { X if(*str == *substr) X { X sptr = str; X ssptr = substr; X while(1) X { X if(*ssptr == 0) X return(str); X if(*sptr++ != *ssptr++) X break; X } X } X } X return(NULL); X} /* end of substr */ X X/*+------------------------------------------------------------------------- X usage() X--------------------------------------------------------------------------*/ Xusage() X{ X exit(255); X} /* end of usage */ X X/*+------------------------------------------------------------------------- X getzrxinit() - 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_SYS5) 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} /* end of getzrxinit */ X X X/*+------------------------------------------------------------------------- X sendzsinit() - send send-init information X--------------------------------------------------------------------------*/ 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} /* end of sendzsinit */ X X/*+------------------------------------------------------------------------- X zsendfile(buf,blen) - send file name & info X--------------------------------------------------------------------------*/ Xzsendfile(buf,blen) Xchar *buf; Xint blen; X{ X register c; X X for(;;) X { X blklen = blklen_original; X report_txblklen(blklen); 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} /* end of zsendfile */ X X/*+------------------------------------------------------------------------- X zsendfdata() - send data in the file X--------------------------------------------------------------------------*/ 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 { X blklen *= 2; X report_txblklen(blklen); X } 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 report_str(s128 + 5,1); X skip_count++; X report_error_count(); X report_file_byte_io(this_file_length); X report_file_close(); X fclose(in); X return(ERROR); X } X } X} /* end of zsendfdata */ X X/*+------------------------------------------------------------------------- X getinsync(flag) - 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 { X blklen /= 2; /* wht - original code */ X report_txblklen(blklen); X } 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 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} /* end of getinsync */ X X/*+------------------------------------------------------------------------- X saybibi() - Say "bibi" to the receiver, try to do it cleanly X--------------------------------------------------------------------------*/ 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} /* end of saybibi */ X X/*+------------------------------------------------------------------------- X determine_transaction_time() 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} /* end of determine_transaction_time */ X X/* vi: set tabstop=4 shiftwidth=4: */ X/* end of tipsz.c */ SHAR_EOF $TOUCH -am 0521192790 xfer/tipsz.c && chmod 0644 xfer/tipsz.c || echo "restore of xfer/tipsz.c failed" set `wc -c xfer/tipsz.c`;Wc_c=$1 if test "$Wc_c" != "40783"; then echo original size 40783, current size $Wc_c fi # ============= xfer/zcommon.c ============== echo "x - extracting xfer/zcommon.c (Text)" sed 's/^X//' << 'SHAR_EOF' > xfer/zcommon.c && X/*+------------------------------------------------------------------------- X zcommon.c - tiprz/tipsz common code X derived from public domain code by Chuck Forsberg X tip adaptation by wht%n4hgf@emory.mathcs.emory.edu X X Defined functions: X cancel_transaction(0) X get_curr_dir(currdir,currdir_max) X get_home_dir(home_dir) X getspeed(code) X mode(new_mode) X rdchk(f) X rdchk(f) X sendbrk() X zmputs(str) X X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:05-21-1990-16:00-wht@tridom-adapt ecu xfer protocols for tipwht */ X X#include <stdio.h> X#include <signal.h> X#include <setjmp.h> X#include <ctype.h> X#include <pwd.h> X#include "zmodem.h" X Xextern unsigned char vmin_count; Xextern int Zmodem; Xextern unsigned Baudrate; Xextern int Twostop; /* Use two stop bits */ X X#if defined(LLITOUT) Xlong Locmode; /* Saved "local mode" for 4.x BSD "new driver" */ Xlong Locbit = LLITOUT; /* Bit SUPPOSED to disable output translations */ X#endif X Xstruct X{ X unsigned baudr; X int speedcode; X} speeds[] = X{ X 110, B110, X 300, B300, X 600, B600, X 1200, B1200, X 2400, B2400, X 4800, B4800, X 9600, B9600, X 19200, EXTA, X 38400, EXTB, X 0, X}; X X/* crctab calculated by Mark G. Mendel,Network Systems Corporation */ Xunsigned short crctab[256] = X{ X 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, X 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, X 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, X 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, X 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, X 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, X 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, X 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, X 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, X 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, X 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, X 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, X 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, X 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, X 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, X 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, X 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, X 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, X 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, X 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, X 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, X 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, X 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, X 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, X 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, X 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, X 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, X 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, X 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, X 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, X 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, X 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 X}; X X#if defined(WANT_UPDCRC_HERE) /* wht -- moved to zmodem.h */ X/* X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. X * NOTE: First srgument must be in range 0 to 255. X * Second argument is referenced twice. X * X * Programmers may incorporate any or all code into their programs, X * giving proper credit within the source. Publication of the X * source routines is permitted so long as proper credit is given X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, X * Omen Technology. X */ X X#define updcrc(cp,crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp) X#endif X X/* X First,the polynomial itself and its table of feedback terms. The X polynomial is: X X X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 X X Note that we take it "backwards" and put the highest-order term in the X lowest-order bit. The X^32 term is "implied"; the LSB is the X^31 X term,etc. The X^0 term (usually shown as "+1") results in the MSB being X 1. Note that the usual hardware shift register implementation,which is X what we're using (we're merely optimizing it by doing eight-bit chunks at X a time) shifts bits into the lowest-order term. In our X implementation,that means shifting towards the right. Why do we do it X this way? Because the calculated CRC must be transmitted in order from X highest-order term to lowest-order term. UARTs transmit characters in X order from LSB to MSB. By storing the CRC this way, we hand it to the X UART in the order low-byte to high-byte; the UART sends each low-bit to X hight-bit; and the result is transmission bit by bit from highest- to X lowest-order term without requiring any bit shuffling on our part. X Reception works similarly. X X The feedback terms table consists of 256 32-bit entries. Notes: X X The macro for using the table is UPDC32 is located in zmodem.h X X It might not be obvious,but the feedback terms simply represent the X results of eight shift/xor opera- tions for all combinations of data X and CRC register values. X X The values must be right-shifted by eight bits by the "UPDC32" logic; X the shift must be unsigned (bring in zeroes). On some hardware you X could probably optimize the shift in assembler by using byte-swap X instructions. X*/ X Xlong cr3tab[] = /* CRC polynomial 0xedb88320 */ X{ X 0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535,0x9e6495a3, X 0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91, X 0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7, X 0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5, X 0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b, X 0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59, X 0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116,0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f, X 0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d, X 0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433, X 0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01, X 0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457, X 0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c,0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65, X 0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2,0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb, X 0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9, X 0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,0x5768b525,0x206f85b3,0xb966d409,0xce61e49f, X 0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad, X 0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,0xead54739,0x9dd277af,0x04db2615,0x73dc1683, X 0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1, X 0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7, X 0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5, X 0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b, X 0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79, X 0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f, X 0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d, X 0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,0x9c0906a9,0xeb0e363f,0x72076785,0x05005713, X 0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38,0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21, X 0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e,0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777, X 0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c,0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45, X 0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db, X 0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9, X 0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,0xbad03605,0xcdd70693,0x54de5729,0x23d967bf, X 0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d X}; X X#if defined(FIONREAD) X/* X * Return non 0 iff something to read from io descriptor f X */ Xrdchk(f) X{ X static long lf; X X ioctl(f,FIONREAD,&lf); X return((int) lf); X} X#endif X X#if defined(SV) X#include <fcntl.h> X Xchar checked = '\0' ; X/* X * Nonblocking I/O is a bit different in System V,Release 2 X */ Xrdchk(f) X{ X int lf,savestat; X X savestat = fcntl(f,F_GETFL) ; X fcntl(f,F_SETFL,savestat | O_NDELAY) ; X lf = read(f,&checked,1) ; X fcntl(f,F_SETFL,savestat) ; X return(lf) ; X} X#endif X X Xstatic unsigned Xgetspeed(code) X{ X register n; X X for(n=0; speeds[n].baudr; ++n) X if(speeds[n].speedcode == code) X return(speeds[n].baudr); X return(38400); /* Assume fifo if ioctl failed */ X} X X X X#if defined(ICANON) Xstruct termio oldtty,tty; X#else Xstruct sgttyb oldtty,tty; Xstruct tchars oldtch,tch; X#endif X Xextern int iofd; /* File descriptor for ioctls & reads */ X X/* X * mode(n) X * 3: save old tty stat, set raw mode with flow control X * 2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g X * 1: save old tty stat, set raw mode X * 0: restore original tty mode X */ Xmode(new_mode) X{ X static did0 = FALSE; X report_mode(new_mode); X switch(new_mode) X { X#if defined(M_SYS5) X case 2: /* Un-raw mode used by sz,sb when -g detected */ X if(!did0) X (void) ioctl(iofd,TCGETA,&oldtty); X tty = oldtty; X tty.c_iflag &= ~(IXON | IXOFF | IXANY); X X#if defined(RTSFLOW) X if(tty.c_cflag & (RTSFLOW | CTSFLOW)) X tty.c_iflag = BRKINT; X else X tty.c_iflag = BRKINT|IXON; X#else X tty.c_iflag = BRKINT|IXON; X#endif X X tty.c_oflag = 0; /* Transparent output */ X X tty.c_cflag &= ~PARENB; /* Disable parity */ X tty.c_cflag |= CS8; /* Set character size = 8 */ X if(Twostop) X tty.c_cflag |= CSTOPB; /* Set two stop bits */ X X X#if defined(READCHECK) X tty.c_lflag = Zmodem ? 0 : ISIG; X tty.c_cc[VINTR] = Zmodem ? -1:030; /* Interrupt char */ X#else X tty.c_lflag = ISIG; X tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */ X#endif X tty.c_cc[VQUIT] = -1; /* Quit char */ X#if defined(NFGVMIN) X tty.c_cc[VMIN] = 1; X#else X tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */ X#endif X tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */ X X (void) ioctl(iofd,TCSETAW,&tty); X did0 = TRUE; X return(OK); X case 1: X case 3: X if(!did0) X (void) ioctl(iofd,TCGETA,&oldtty); X tty = oldtty; X tty.c_iflag &= ~(IXON | IXOFF | IXANY); X X#if defined(RTSFLOW) X tty.c_iflag = new_mode == 3 ? (IGNBRK | RTSFLOW) : IGNBRK; X#else X tty.c_iflag = new_mode == 3 ? (IGNBRK | IXOFF) : IGNBRK; X#endif X X /* No echo,crlf mapping,INTR,QUIT,delays,no erase/kill */ X tty.c_lflag &= ~(ECHO | ICANON | ISIG); X X tty.c_oflag = 0; /* Transparent output */ X X tty.c_cflag &= ~PARENB; /* Same baud rate,disable parity */ X tty.c_cflag |= CS8; /* Set character size = 8 */ X if(Twostop) X tty.c_cflag |= CSTOPB; /* Set two stop bits */ X#if defined(NFGVMIN) X tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */ X#else X tty.c_cc[VMIN] = vmin_count; /* This many chars satisfies reads */ X#endif X tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */ X (void) ioctl(iofd,TCSETAW,&tty); X did0 = TRUE; X Baudrate = getspeed(tty.c_cflag & CBAUD); X report_comm_baud_rate(Baudrate); X return(OK); X#endif X#if defined(pyr) X /* X * NOTE: this should transmit all 8 bits and at the same time X * respond to XOFF/XON flow control. If no FIONREAD or other X * READCHECK alternative,also must respond to INTRRUPT char X * This doesn't work with BSD4. It should work with LLITOUT, X * but LLITOUT was broken on the machine I tried it on. X */ X case 2: /* Un-raw mode used by sz,sb when -g detected */ X if(!did0) X { X ioctl(iofd,TIOCEXCL,0); X ioctl(iofd,TIOCGETP,&oldtty); X ioctl(iofd,TIOCGETC,&oldtch); X#if defined(LLITOUT) X ioctl(TIOCLGET,&Locmode); /* Get "local mode" */ X#endif X } X tty = oldtty; X tch = oldtch; X#if defined(READCHECK) X tch.t_intrc = Zmodem ? -1:030; /* Interrupt char */ X#else X tch.t_intrc = Zmodem ? 03:030; /* Interrupt char */ X#endif X tty.sg_flags |= (ODDP|EVENP|CBREAK); X tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE); X ioctl(iofd,TIOCSETP,&tty); X ioctl(iofd,TIOCSETC,&tch); X#if defined(LLITOUT) X ioctl(TIOCLBIS,&Locbit); X#endif X/* un-raw doesn't work w/o lit out *//*wht code was 99 */ X cancel_transaction(0); X did0 = TRUE; X return(OK); X case 1: X case 3: X if(!did0) X { X ioctl(iofd,TIOCEXCL,0); X ioctl(iofd,TIOCGETP,&oldtty); X ioctl(iofd,TIOCGETC,&oldtch); X#if defined(LLITOUT) X ioctl(TIOCLGET,&Locmode); /* Get "local mode" */ X#endif X } X tty = oldtty; X tty.sg_flags |= RAW; X tty.sg_flags &= ~ECHO; X ioctl(iofd,TIOCSETP,&tty); X did0 = TRUE; X Baudrate = getspeed(tty.sg_ospeed); X report_comm_baud_rate(Baudrate); X return(OK); X#endif X case 0: X if(!did0) X return(ERROR); X#if defined(M_SYS5) X (void) ioctl(iofd,TCSBRK,1); /* Wait for output to drain */ X (void) ioctl(iofd,TCFLSH,1); /* Flush input queue */ X (void) ioctl(iofd,TCSETAW,&oldtty); /* Restore modes */ X (void) ioctl(iofd,TCXONC,1); /* Restart output */ X#endif X#if defined(pyr) X ioctl(iofd,TIOCSETP,&oldtty); X ioctl(iofd,TIOCSETC,&oldtch); X ioctl(iofd,TIOCNXCL,0); X#if defined(LLITOUT) X ioctl(TIOCLSET,&Locmode); /* Restore "local mode" */ X#endif X#endif X X return(OK); X default: X return(ERROR); X } X} X X/*+------------------------------------------------------------------------- X sendbrk() X--------------------------------------------------------------------------*/ Xsendbrk() X{ X#if defined(pyr) X sleep(1); X ioctl(iofd,TIOCSBRK,0); X sleep(1); X ioctl(iofd,TIOCCBRK,0); X#endif X#if defined(M_SYS5) X ioctl(iofd,TCSBRK,0); X#endif X} /* end of sendbrk */ X X/*+------------------------------------------------------------------------- X get_curr_dir(currdir,currdir_max) X--------------------------------------------------------------------------*/ Xvoid Xget_curr_dir(currdir,currdir_max) Xchar *currdir; Xint currdir_max; X{ X#if defined(pyr) X getwd(currdir); X#endif X X#if defined(M_SYS5) X getcwd(currdir,currdir_max); X#endif X X} /* end of get_curr_dir */ X X/*+------------------------------------------------------------------------- X zmputs(str) - send a string to the modem X Xprocessing for \336 (sleep 1 sec) and \335 (break signal) X--------------------------------------------------------------------------*/ Xzmputs(str) Xregister char *str; X{ Xregister char strch; X X while(strch = *str++) X { X switch(strch) X { X case '\336': X sleep(1); X continue; X case '\335': X sendbrk(); X continue; X default: X sendline(strch); X } X } X} /* end of zmputs */ X X/*+----------------------------------------------------------------------- X get_home_dir(home_dir): leave plenty of room for result! X------------------------------------------------------------------------*/ Xget_home_dir(home_dir) Xchar *home_dir; X{ Xstatic char home_directory[256] = ""; Xstruct passwd *pwent; Xstruct passwd *getpwuid(); X X if(home_directory[0]) X { X strcpy(home_dir,home_directory); X return(0); X } X X if(!(pwent = getpwuid(getuid()))) X { X perror("cannot get pwent for you!!"); X exit(1); X } X strcpy(home_directory,pwent->pw_dir); X strcpy(home_dir,pwent->pw_dir); X endpwent(); X return(0); X X} /* end of get_home_dir */ X X/* end of zcommon.c */ X/* vi: set tabstop=4 shiftwidth=4: */ SHAR_EOF $TOUCH -am 0521180090 xfer/zcommon.c && chmod 0644 xfer/zcommon.c || echo "restore of xfer/zcommon.c failed" set `wc -c xfer/zcommon.c`;Wc_c=$1 if test "$Wc_c" != "15622"; then echo original size 15622, current size $Wc_c fi echo "End of part 3, continue with part 4" exit 0 ------------------------------------------------------------------ Warren Tucker, Tridom Corporation ...!gatech!emory!tridom!wht home address: ...!gatech!n4hgf!wht