ecu - SCO XENIX V/{2,3}86 Extended CU part 25/47
Warren Tucker
wht at tridom.uucp
Tue Oct 10 09:39:12 AEST 1989
---- Cut Here and unpack ----
#!/bin/sh
# this is part 25 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file z/ecurz.c continued
#
CurArch=25
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/ecurz.c"
sed 's/^X//' << 'SHAR_EOF' >> z/ecurz.c
X{
X} /* end of flushline */
X
X/*+-------------------------------------------------------------------------
X purgeline() - purge the modem input queue of all characters
X--------------------------------------------------------------------------*/
Xpurgeline()
X{
X Lleft = 0;
X#if defined(M_XENIX)
X ioctl(iofd,TCFLSH,0);
X#else
X lseek(iofd,0L,2);
X#endif
X} /* end of purgeline */
X
X/*+-------------------------------------------------------------------------
X wcreceive(argc,argp)
X--------------------------------------------------------------------------*/
Xwcreceive(argc,argp)
Xint argc;
Xchar **argp;
X{
Xregister c;
X
X if(Batch || argc==0)
X {
X Crcflg=1;
X c=tryz();
X if(Zmodem)
X {
X report_protocol_type("ZMODEM");
X report_protocol_crc_type((Crc32) ? "/CRC32" : "/CRC16");
X }
X if(c)
X {
X if(c == ZCOMPL)
X return(OK);
X if(c == ERROR)
X goto fubar;
X c = rzfiles();
X if(c)
X goto fubar;
X } else
X {
X report_protocol_type("YMODEM");
X report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK");
X for(;;)
X {
X if(wcrxpn(secbuf)== ERROR)
X goto fubar;
X if(secbuf[0]==0)
X return(OK);
X if(procheader(secbuf) == ERROR)
X goto fubar;
X report_str("Receiving data",0);
X if(wcrx()==ERROR)
X goto fubar;
X }
X }
X }
X else
X {
X report_protocol_type("XMODEM");
X report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK");
X Bytesleft = DEFBYTL;
X Filemode = 0;
X Modtime = 0L;
X procheader("");
X strcpy(Pathname,*argp);
X if((fout=fopen(Pathname,"w")) == NULL)
X return(ERROR);
X report_file_rcv_started( Pathname,0L,Modtime,Filemode);
X this_file_length = 0;
X report_rxpos(0L);
X report_str("Receiving data",0);
X if(wcrx()==ERROR)
X goto fubar;
X }
X return(OK);
Xfubar:
X send_cancel();
X if(fout)
X {
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_file_byte_io((long)fout_stat.st_size);
X report_file_close();
X fclose(fout);
X }
X return(ERROR);
X} /* end of wcreceive */
X
X/*+-------------------------------------------------------------------------
X wcgetsec(rxbuf,maxtime)
X
X Wcgetsec fetches a Ward Christensen type sector. Returns sector
X number encountered or ERROR if valid sector not received, or CAN CAN
X received or WCEOT if eot sector time is timeout for first char,set to
X 4 seconds thereafter. NO ACK IS SENT IF SECTOR IS RECEIVED OK. Caller
X must do that when he is good and ready to get next sector.
X--------------------------------------------------------------------------*/
Xunsigned int
Xwcgetsec(rxbuf,maxtime)
Xchar *rxbuf;
Xint maxtime;
X{
Xregister unsigned int firstch;
Xregister unsigned short oldcrc;
Xregister unsigned char checksum;
Xregister wcj;
Xregister char *p;
Xint sectcurr;
X
X for(Lastrx=errors=0; errors<RETRYMAX; errors++)
X {
X
X firstch=readline(maxtime);
X if((firstch == STX) || (firstch == SOH))
X {
X oldBlklen = Blklen;
X if(firstch == STX)
X Blklen=1024;
X else
X Blklen=128;
X if(oldBlklen != Blklen)
X report_rxblklen(Blklen);
X
X sectcurr=readline(1);
X if((sectcurr + (oldcrc=readline(1))) == 0xFF)
X {
X oldcrc=checksum=0;
X for(p=rxbuf,wcj=Blklen; --wcj>=0; )
X {
X if((firstch=readline(1)) < 0)
X goto bilge;
X oldcrc=updcrc(firstch,oldcrc);
X checksum += (*p++ = firstch);
X }
X if((firstch=readline(1)) < 0)
X goto bilge;
X if(Crcflg)
X {
X oldcrc=updcrc(firstch,oldcrc);
X if((firstch=readline(1)) < 0)
X goto bilge;
X oldcrc=updcrc(firstch,oldcrc);
X if(oldcrc)
X {
X sprintf(s128,"CRC error = 0x%04x",oldcrc);
X report_str(s128,1);
X }
X else
X {
X Firstsec=0;
X return(sectcurr);
X }
X }
X else if((checksum-firstch)==0)
X {
X Firstsec=0;
X return(sectcurr);
X }
X else
X report_str("checksum error",1);
X }
X else
X {
X report_last_txhdr("Noise",0);
X sprintf(s128,"Sector garbled 0x%x 0x%x",sectcurr,oldcrc);
X report_str(s128,1);
X }
X }
X /* make sure eot really is eot and not just mixmash */
X#if defined(NFGVMIN)
X else if(firstch==EOT && readline(1)==TIMEOUT)
X return(WCEOT);
X#else
X else if(firstch==EOT && Lleft==0)
X return(WCEOT);
X#endif
X else if(firstch==EOT)
X {
X report_str("Noisy EOT",2);
X }
X else if(firstch==CAN)
X {
X if(Lastrx==CAN)
X {
X report_str("Sender CANcelled",1);
X report_last_rxhdr("CAN",1);
X return(ERROR);
X } else
X {
X Lastrx=CAN;
X continue;
X }
X }
X else if(firstch==TIMEOUT)
X {
X if(Firstsec)
X goto humbug;
Xbilge:
X report_str("Timeout",1);
X }
X else
X {
X sprintf(s128,"Got 0x%02x sector header",firstch);
X report_str(s128,1);
X }
X
Xhumbug:
X Lastrx=0;
X while(readline(1)!=TIMEOUT)
X ;
X if(Firstsec)
X {
X sendline(Crcflg?WANTCRC:NAK);
X report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
X Lleft=0; /* Do read next time ... */
X } else
X {
X maxtime=40;
X sendline(NAK);
X report_last_txhdr("NAK",1);
X Lleft=0; /* Do read next time ... */
X }
X }
X /* try to stop the bubble machine. */
X send_cancel();
X return(ERROR);
X} /* end of wcgetsec */
X
X/*+-------------------------------------------------------------------------
X wcrxpn(rpn)
X
X Fetch a pathname from the other end. Length is indeterminate as long
X as less than Blklen. During YMODEM xfers, a null string represents no
X more files.
X--------------------------------------------------------------------------*/
Xwcrxpn(rpn)
Xchar *rpn; /* receive a pathname */
X{
Xregister c;
X
X#if defined(NFGVMIN)
X readline(1);
X#else
X purgeline();
X#endif
X
Xet_tu:
X Firstsec=1;
X Eofseen=0;
X sendline(Crcflg?WANTCRC:NAK);
X report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
X Lleft=0; /* Do read next time ... */
X while((c = wcgetsec(rpn,100)) != 0)
X {
X if(c == WCEOT)
X {
X sprintf(s128,"Pathname fetch returned %d",c);
X report_str(s128,1);
X sendline(ACK);
X report_last_txhdr("ACK",0);
X Lleft=0; /* Do read next time ... */
X readline(1);
X goto et_tu;
X }
X return(ERROR);
X }
X sendline(ACK);
X report_last_txhdr("ACK",0);
X return(OK);
X} /* end of wcrxpn */
X
X/*+-------------------------------------------------------------------------
X write_sec_to_disk(buf,n)
X
X Putsec writes the n characters of buf to receive file fout. If not in
X binary mode, carriage returns, and all characters starting with CPMEOF
X are discarded.
X--------------------------------------------------------------------------*/
Xwrite_sec_to_disk(buf,n)
Xchar *buf;
Xregister n;
X{
Xregister char *p;
X
X if(n == 0)
X return(OK);
X if(Thisbinary)
X {
X for(p=buf; --n>=0; )
X putc( *p++,fout);
X }
X else
X {
X if(Eofseen)
X return(OK);
X for(p=buf; --n>=0; ++p )
X {
X if( *p == '\r')
X continue;
X if(*p == CPMEOF)
X {
X Eofseen=1;
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_rxpos(fout_stat.st_size);
X return(OK);
X }
X putc(*p ,fout);
X }
X }
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_rxpos(fout_stat.st_size);
X if(this_file_length != 0)
X {
X sprintf(s128,"Receiving data (%u%% complete)",
X (unsigned int)(
X ((unsigned long)fout_stat.st_size * (unsigned long)100)
X / this_file_length));
X report_str(s128,0);
X }
X return(OK);
X} /* end of write_sec_to_disk */
X
X/*+-------------------------------------------------------------------------
X wcrx() - receive an X/YMODEM sector
X
X Adapted from CMODEM13.C,written by Jack M. Wierda and Roderick W. Hart
X--------------------------------------------------------------------------*/
Xint
Xwcrx()
X{
Xregister unsigned int sectnum,sectcurr;
Xregister unsigned char sendchar;
Xregister unsigned char *p;
Xint cblklen; /* bytes to dump this block */
X
X Firstsec=1;
X sectnum=0;
X Eofseen=0;
X sendchar=Crcflg ? WANTCRC : NAK;
X report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
X
X for(;;)
X {
X sendline(sendchar); /* send it now,we're ready! */
X if(sendchar == ACK)
X report_last_txhdr("ACK",0);
X Lleft=0; /* Do read next time ... */
X sectcurr=wcgetsec(secbuf,(sectnum&0177)?50:130);
X sprintf(s128,"Block %d received",sectnum);
X report_last_rxhdr(s128,0);
X fstat(fileno(fout),&fout_stat);
X report_rxpos(fout_stat.st_size);
X if(sectcurr == (sectnum+1 & 0xFF))
X {
X sectnum++;
X cblklen = Bytesleft>Blklen ? Blklen : Bytesleft;
X if(write_sec_to_disk(secbuf,cblklen) == ERROR)
X return(ERROR);
X if((Bytesleft-=cblklen) < 0)
X Bytesleft = 0;
X sendchar=ACK;
X }
X else if(sectcurr == sectnum)
X {
X report_str("Received duplicate Sector",-1);
X sendchar = ACK;
X }
X else if(sectcurr == WCEOT)
X {
X if(close_and_report())
X return(ERROR);
X sendline(ACK);
X report_last_txhdr("ACK",0);
X Lleft=0; /* Do read next time ... */
X return(OK);
X }
X else if(sectcurr==ERROR)
X return(ERROR);
X else
X {
X report_str( "Sync Error",1);
X return(ERROR);
X }
X }
X} /* end of wcrx */
X
X/*+-------------------------------------------------------------------------
X readline(timeout)
X
X read one or more characters timeout is in tenths of seconds
X--------------------------------------------------------------------------*/
Xreadline(timeout)
Xint timeout;
X{
Xregister n;
Xstatic unsigned char *cdq; /* pointer for removing chars from linbuf */
X
X#ifndef bad_problem
X if(--Lleft >= 0)
X return(*cdq++);
X
X n = timeout/10;
X if(n < 2)
X n = 3;
X if(setjmp(tohere))
X {
X Lleft = 0;
X return(TIMEOUT);
X }
X signal(SIGALRM,SIGALRM_handler);
X alarm(n);
X Lleft = read(iofd,cdq = linbuf,Readnum);
X alarm(0);
X rx_char_count += Lleft;
X
X if(Lleft < 1)
X return(TIMEOUT);
X
X --Lleft;
X return(*cdq++);
X#else
Xint rtnv;
X
X if(--Lleft >= 0)
X {
X rtnv = *cdq++;
X goto LOG_AND_RETURN;
X }
X
X n = timeout/10;
X if(n < 2)
X n = 3;
X if(setjmp(tohere))
X {
X Lleft = 0;
X rtnv = *cdq++;
X goto LOG_AND_RETURN;
X }
X signal(SIGALRM,SIGALRM_handler);
X alarm(n);
X Lleft = read(iofd,cdq = linbuf,Readnum);
X alarm(0);
X rx_char_count += Lleft;
X
X if(Lleft < 1)
X {
X rtnv = TIMEOUT;
X goto LOG_AND_RETURN;
X }
X --Lleft;
X rtnv = *cdq++;
X
XLOG_AND_RETURN:
X if(log_packets)
X {
X sprintf(s128,"rl: l=%3d ch=%x\n",Lleft,rtnv);
X write(log_packets,s128,strlen(s128));
X }
X return(rtnv);
X
X#endif
X
X} /* end of readline */
X
X/*+-------------------------------------------------------------------------
X mkdir(dpath,dmode)
X Directory-creating routines from Public Domain TAR by John Gilmore
X Make a directory. Compatible with the mkdir() system call on 4.2BSD.
X--------------------------------------------------------------------------*/
X#if defined(MD)
X#if (MD != 2)
X#define TERM_SIGNAL(status) ((status) & 0x7F)
X#define TERM_COREDUMP(status) (((status) & 0x80) != 0)
X#define TERM_VALUE(status) ((status) >> 8)
Xmkdir(dpath,dmode)
Xchar *dpath;
Xint dmode;
X{
X int cpid,status;
X struct stat statbuf;
X
X if(stat(dpath,&statbuf) == 0)
X {
X errno = EEXIST; /* Stat worked,so it already exists */
X return(-1);
X }
X
X /* If stat fails for a reason other than non-existence,return error */
X if(errno != ENOENT)
X return(-1);
X
X switch(cpid = fork())
X {
X
X case -1: /* Error in fork() */
X return(-1); /* Errno is set already */
X
X case 0: /* Child process */
X /*
X * Cheap hack to set mode of new directory. Since this
X * child process is going away anyway,we zap its umask.
X * FIXME,this won't suffice to set SUID,SGID,etc. on this
X * directory. Does anybody care?
X */
X status = umask(0); /* Get current umask */
X status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
X execl("/bin/mkdir","mkdir",dpath,(char *)0);
X _exit(-1); /* Can't exec /bin/mkdir */
X
X default: /* Parent process */
X while(cpid != wait(&status)) ; /* Wait for kid to finish */
X }
X
X if(TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0)
X {
X errno = EIO; /* We don't know why,but */
X return(-1); /* /bin/mkdir failed */
X }
X
X return(0);
X} /* end of mkdir */
X#endif /* MD != 2 */
X#endif /* if defined(MD) */
X
X/*+-------------------------------------------------------------------------
X make_dirs(pathname)
X
X Directory-creating routines from Public Domain TAR by John Gilmore
X After a file/link/symlink/dir creation has failed, see if it's because
X some required directory was not present, and if so, create all
X required dirs.
X--------------------------------------------------------------------------*/
X#if defined(MD)
Xmake_dirs(pathname)
Xregister char *pathname;
X{
X register char *p; /* Points into path */
X int madeone = 0; /* Did we do anything yet? */
X int save_errno = errno; /* Remember caller's errno */
X
X if(errno != ENOENT)
X return(0); /* Not our problem */
X
X for(p = strchr(pathname,'/'); p != NULL; p = strchr(p+1,'/'))
X {
X /* Avoid mkdir of empty string,if leading or double '/' */
X if(p == pathname || p[-1] == '/')
X continue;
X /* Avoid mkdir where last part of path is '.' */
X if(p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
X continue;
X *p = 0; /* Truncate the path there */
X if( !mkdir(pathname,0777))
X { /* Try to create it as a dir */
X sprintf(s128,"Made directory %s",pathname);
X report_str(s128,-1);
X madeone++; /* Remember if we made one */
X *p = '/';
X continue;
X }
X *p = '/';
X if(errno == EEXIST) /* Directory already exists */
X continue;
X /*
X * Some other error in the mkdir. We return to the caller.
X */
X break;
X }
X errno = save_errno; /* Restore caller's errno */
X return(madeone); /* Tell them to retry if we made one */
X} /* end of make_dirs */
X#endif /* MD */
X
X/*+-------------------------------------------------------------------------
X uncaps(str) - make string str lower case
X--------------------------------------------------------------------------*/
Xvoid
Xuncaps(str)
Xregister char *str;
X{
Xregister int itmp;
X
X while(itmp = *str)
X {
X if(isupper(itmp))
X *str = tolower(itmp);
X str++;
X }
X} /* end of uncaps */
X
X/*+-------------------------------------------------------------------------
X isanylc(str) - returns 1 if string str has any lower case letters
X--------------------------------------------------------------------------*/
Xint
Xisanylc(str)
Xregister char *str;
X{
X while(*str)
X {
X if(islower(*str))
X return(1);
X str++;
X }
X return(0);
X} /* end of isanylc */
X
X/*+-------------------------------------------------------------------------
X procheader(name) - process incoming file information header
X--------------------------------------------------------------------------*/
Xint
Xprocheader(name)
Xchar *name;
X{
Xregister char *openmode,*p,**pp;
X
X /* set default parameters and overrides */
X openmode = "w";
X Thisbinary = (!Rxascii) || Rxbinary;
X if(Lzmanag)
X zmanag = Lzmanag;
X
X /*
X * Process ZMODEM remote file management requests
X */
X if(!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
X Thisbinary = 0;
X if(zconv == ZCBIN) /* Remote Binary override */
X Thisbinary = 1;
X else if(zmanag == ZMAPND)
X openmode = "a";
X
X report_xfer_mode(Thisbinary ? "BINARY" : "ASCII");
X this_file_errors = 0;
X
X Bytesleft = DEFBYTL;
X Filemode = 0;
X Modtime = 0L;
X this_file_length = 0;
X
X if(strlen(name))
X p = name + 1 + strlen(name);
X else
X p = name;
X if(*p)
X { /* file coming from Unix or DOS system */
X int sscanf_count;
X int SerialNumber;
X int Filesleft;
X long TotalLeft;
X
X sscanf_count = sscanf(p,"%ld%lo%o%d&d&ld",
X &Bytesleft,&Modtime,&Filemode,&SerialNumber,
X &Filesleft,&TotalLeft);
X
X switch(sscanf_count)
X {
X case 6: /* TotalLeft */
X if(!TotalToReceive)
X TotalToReceive = TotalLeft;
X case 5: /* Filesleft */
X if(!npats)
X npats = Filesleft;
X default:
X break;
X }
X
X if((zmanag & ZMMASK) == ZMNEW)
X {
X if(stat(name,&fout_stat) == 0) /* if file accessable ... */
X {
X if(Modtime <= fout_stat.st_mtime) /* ... and not older */
X {
X sprintf(s128,"RECEIVE skipped: %s (same or later date)",
X name);
X report_str(s128 + 8,-1);
X#ifdef LOG_XFER
X ecu_log_event(s128);
X#endif
X return(ERROR);
X }
X }
X }
X /* Check for existing file */
X else if(!Rxclob && ((zmanag & ZMMASK) != ZMCLOB) &&
X (fout=fopen(name,"r")))
X {
X fclose(fout);
X sprintf(s128,"RECEIVE skipped: %s (already exists)",name);
X report_str(s128 + 8,-1);
X#ifdef LOG_XFER
X ecu_log_event(s128);
X#endif
X return(ERROR);
X }
X
X if(Filemode & UNIXFILE)
X ++Thisbinary;
X ++Filcnt;
X if(Bytesleft != DEFBYTL)
X report_file_rcv_started( name,Bytesleft,Modtime,Filemode);
X report_rxpos(0L);
X report_str("",0); /* get rid of End of File */
X if(Bytesleft != DEFBYTL)
X {
X long min_100;
X this_file_length = Bytesleft;
X min_100 = 2L + (((Bytesleft * 11L)) * 10L) / (Baudrate * 6L);
X sprintf(s128,"Receive time this file ~= %2lu:%02lu",
X min_100 / 100,((min_100 % 100) * 60L) / 100L);
X if(TotalToReceive)
X {
X min_100 = 2L +
X (((TotalToReceive * 11L)) * 10L) / (Baudrate * 6L);
X if(Baudrate > 4800)
X {
X min_100 *= 13;
X min_100 /= 9; /* yech ... empirical */
X }
X sprintf(&s128[strlen(s128)],", transaction ~= %2lu:%02lu",
X min_100 / 100,((min_100 % 100) * 60L) / 100L);
X }
X report_transaction(s128);
X sprintf(s128,"Receiving data (%d%% complete)",(int)0);
X report_str(s128,0);
X }
X }
X else
X { /* File coming from CP/M system */
X for(p=name; *p; ++p) /* change / to _ */
X {
X if( *p == '/')
X *p = '_';
X }
X
X if( *--p == '.') /* zap trailing period */
X *p = 0;
X }
X
X if(!Zmodem && MakeLCPathname && !isanylc(name) && !(Filemode&UNIXFILE))
X uncaps(name);
X
X strcpy(Pathname,name);
X report_xfer_mode(Thisbinary?"BINARY":"ASCII");
X fout = fopen(name,openmode);
X#if defined(MD)
X if( !fout)
X if(make_dirs(name))
X fout = fopen(name,openmode);
X#endif
X if( !fout)
X return(ERROR);
X this_file_errors = 0;
X return(OK);
X} /* end of procheader */
X
X/*+-------------------------------------------------------------------------
X send_cancel() - send cancel string
X--------------------------------------------------------------------------*/
Xsend_cancel()
X{
Xstatic 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};
Xregister char *cptr = canistr;
X
X report_str("",0);
X report_last_txhdr("^X CAN",1);
X while(*cptr)
X sendline(*cptr++);
X Lleft=0;
X} /* end of send_cancel */
X
X/*+-------------------------------------------------------------------------
X tryz()
X
X Initialize for Zmodem receive attempt, try to activate Zmodem sender
X Handles ZSINIT frame
X Return ZFILE if Zmodem filename received,-1 on error,
X ZCOMPL if transaction finished, else 0
X--------------------------------------------------------------------------*/
Xint
Xtryz()
X{
Xregister c,n;
X
X if(Nozmodem) /* Check for "rb" program name */
X return(0);
X
X for(n=Zmodem?15:5; --n>=0; )
X {
X /* Set buffer length (0) and capability flags */
X stohdr(0L);
X#if defined(CANBREAK)
X Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
X#else
X Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
X#endif
X if(Zctlesc)
X Txhdr[ZF0] |= TESCCTL;
X zshhdr(tryzhdrtype,Txhdr);
X if(tryzhdrtype == ZSKIP) /* Don't skip too far */
X tryzhdrtype = ZRINIT; /* CAF 8-21-87 */
Xagain:
X switch(zgethdr(Rxhdr,0))
X {
X case ZRQINIT:
X continue;
X case ZEOF:
X continue;
X case TIMEOUT:
X continue;
X case ZFILE:
X zconv = Rxhdr[ZF0];
X zmanag = Rxhdr[ZF1];
X ztrans = Rxhdr[ZF2];
X
X strcpy(s128,"Transfer: ");
X switch(zmanag & ZMMASK)
X {
X case 0:
X strcat(s128,"if destination nonexistent");
X break;
X case ZMAPND: /* Append contents to existing file (if any) */
X strcat(s128,"append to destination");
X break;
X case ZMCLOB: /* Replace existing file */
X strcat(s128,"absolute (overwrite)");
X break;
X case ZMNEW:
X strcat(s128,"if source newer");
X break;
X default:
X sprintf(s128 + strlen(s128),
X "absolute (%02x)",zmanag & ZMMASK);
X break;
X }
X report_str(s128,2);
X
X tryzhdrtype = ZRINIT;
X c = zrdata(secbuf,1024);
X mode(3);
X if(c == GOTCRCW)
X return(ZFILE);
X zshhdr(ZNAK,Txhdr);
X goto again;
X case ZSINIT:
X Zctlesc = TESCCTL & Rxhdr[ZF0];
X if(zrdata(Attn,ZATTNLEN) == GOTCRCW)
X {
X stohdr(1L);
X zshhdr(ZACK,Txhdr);
X goto again;
X }
X zshhdr(ZNAK,Txhdr);
X goto again;
X case ZFREECNT:
X stohdr(getfree());
X zshhdr(ZACK,Txhdr);
X goto again;
X case ZCOMMAND:
X if(zrdata(secbuf,1024) == GOTCRCW)
X {
X stohdr(-1L);
X purgeline(); /* dump impatient questions */
X while(errors < 20)
X {
X zshhdr(ZCOMPL,Txhdr);
X if(zgethdr(Rxhdr,1) == ZFIN)
X break;
X }
X send_ZFIN_and_exit();
X return(ZCOMPL);
X }
X zshhdr(ZNAK,Txhdr);
X goto again;
X case ZCOMPL:
X goto again;
X default:
X continue;
X case ZFIN:
X send_ZFIN_and_exit();
X return(ZCOMPL);
X case ZCAN:
X return(ERROR);
X }
X }
X return(0);
X} /* end of tryz */
X
X/*+-------------------------------------------------------------------------
X rzfile() - receive a file with ZMODEM protocol
X
X assumes file name frame is in secbuf
X--------------------------------------------------------------------------*/
Xrzfile()
X{
Xregister c,n;
Xlong rxbytes;
X
X Eofseen=0;
X if(procheader(secbuf) == ERROR)
X {
X return(tryzhdrtype = ZSKIP);
X }
X
X n = 20;
X rxbytes = 0l;
X
X for(;;)
X {
X stohdr(rxbytes);
X zshhdr(ZRPOS,Txhdr);
X if(rxbytes)
X report_str("Sending ZRPOS",1);
Xnxthdr:
X switch(c = zgethdr(Rxhdr,0))
X {
X default:
X sprintf(s128,"zgethdr returned %02x",c);
X report_str(s128,1);
X return(ERROR);
X case ZNAK:
X case TIMEOUT:
X if( --n < 0)
X {
X sprintf(s128,"zgethdr returned %02x",c);
X report_str(s128,1);
X return(ERROR);
X }
X case ZFILE:
X zrdata(secbuf,1024);
X continue;
X case ZEOF:
X if(rclhdr(Rxhdr) != rxbytes)
X {
X /*
X * Ignore eof if it's at wrong place - force
X * a timeout because the eof might have gone
X * out before we sent our zrpos.
X */
X errors = 0;
X goto nxthdr;
X }
X if(close_and_report())
X {
X tryzhdrtype = ZFERR;
X return(ERROR);
X }
X report_str("End of file",0);
X return(c);
X case ERROR: /* Too much garbage in header search error */
X if( --n < 0)
X {
X sprintf(s128,"zgethdr returned %02x",c);
X report_str(s128,1);
X return(ERROR);
X }
X zmputs(Attn);
X continue;
X case ZSKIP:
X close_and_report();
X sprintf(s128,"rzfile: Sender SKIPPED file");
X report_str(s128,1);
X return(c);
X case ZDATA:
X if(rclhdr(Rxhdr) != rxbytes)
X {
X if( --n < 0)
X {
X return(ERROR);
X }
X zmputs(Attn);
X continue;
X }
Xmoredata:
X switch(c = zrdata(secbuf,1024))
X {
X case ZCAN:
X sprintf(s128,"zgethdr returned %02x",c);
X report_str(s128,1);
X return(ERROR);
X case ERROR: /* CRC error */
X if( --n < 0)
X {
X sprintf(s128,"zgethdr returned %02x",c);
X report_str(s128,1);
X return(ERROR);
X }
X zmputs(Attn);
X continue;
X case TIMEOUT:
X if( --n < 0)
X {
X sprintf(s128,"zgethdr returned %02x",c);
X report_str(s128,1);
X return(ERROR);
X }
X continue;
X case GOTCRCW:
X n = 20;
X write_sec_to_disk(secbuf,Rxcount);
X rxbytes += Rxcount;
X stohdr(rxbytes);
X zshhdr(ZACK,Txhdr);
X sendline(XON);
X goto nxthdr;
X case GOTCRCQ:
X n = 20;
X write_sec_to_disk(secbuf,Rxcount);
X rxbytes += Rxcount;
X stohdr(rxbytes);
X zshhdr(ZACK,Txhdr);
X goto moredata;
X case GOTCRCG:
X n = 20;
X write_sec_to_disk(secbuf,Rxcount);
X rxbytes += Rxcount;
X goto moredata;
X case GOTCRCE:
X n = 20;
X write_sec_to_disk(secbuf,Rxcount);
X rxbytes += Rxcount;
X goto nxthdr;
X }
X }
X }
X} /* end of rzfile */
X
X/*+-------------------------------------------------------------------------
X rzfiles() - receive file(s) with ZMODEM protocol
X--------------------------------------------------------------------------*/
Xrzfiles()
X{
Xregister c;
X
X for(;;)
X {
X switch(c = rzfile())
X {
X case ZEOF:
X case ZSKIP:
X switch(tryz())
X {
X case ZCOMPL:
X return(OK);
X default:
X return(ERROR);
X case ZFILE:
X break;
X }
X continue;
X default:
X return(c);
X case ERROR:
X return(ERROR);
X }
X }
X} /* end of rzfiles */
X
X/*+-------------------------------------------------------------------------
X close_and_report() - close the received file, set mod time and chmod
X(specifically exclude set uid and gid from chmod)
X--------------------------------------------------------------------------*/
Xclose_and_report()
X{
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_file_byte_io((long)fout_stat.st_size);
X report_file_close();
X
X if(fclose(fout)==ERROR)
X return(ERROR);
X
X#if defined(LOG_XFER)
X sprintf(s256,"RECEIVE success: %s",Pathname);
X ecu_log_event(s256);
X#endif
X
X if(Modtime)
X {
X timep[0] = time(NULL);
X timep[1] = Modtime;
X utime(Pathname,timep);
X }
X
X if((Filemode & S_IFMT) == S_IFREG)
X {
X Filemode &= ~(S_ISUID | S_ISGID);
X chmod(Pathname,(07777 & Filemode));
X }
X
X return(OK);
X
X} /* end of close_and_report */
X
X/*+-------------------------------------------------------------------------
X send_ZFIN_and_exit() - send ZFIN packet and wait for "OO" ack
X--------------------------------------------------------------------------*/
Xsend_ZFIN_and_exit()
X{
Xregister n;
X
X Readnum = 1;
X stohdr(0L);
X for(n = 0; n < 4; n++)
X {
X purgeline();
X zshhdr(ZFIN,Txhdr);
X switch(readline(100))
X {
X case 'O':
X readline(1); /* Discard 2nd 'O' */
X return;
X case RCDO:
X return;
X case TIMEOUT:
X default:
X break;
X }
X }
X} /* end of send_ZFIN_and_exit */
X
X/*+-------------------------------------------------------------------------
X sys2(shellcmd) - execute shell command
X
X Strip leading ! if present
X--------------------------------------------------------------------------*/
Xsys2(shellcmd)
Xregister char *shellcmd;
X{
X if(*shellcmd == '!')
X ++shellcmd;
X return(system(shellcmd));
X} /* end of sys2 */
X
X/*+-------------------------------------------------------------------------
X main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xregister char *cp;
Xchar **patts;
Xchar *getenv();
Xint exitcode;
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 = 100;
X
X npats = 0;
X while(--argc)
X {
X cp = *++argv;
X if(*cp == '-')
X {
X while( *++cp)
X {
X switch(*cp)
X {
X case 'X':
X required_type = 1;
X Batch = 0;
X break;
X case 'Y':
X required_type = 1;
X Nozmodem = 1;
X Batch = 1;
X break;
X case 'Z':
X required_type = 1;
X Nozmodem = 0;
X Batch = 1;
X break;
X case '+':
X Lzmanag = ZMAPND;
X break;
X case 'a':
X Rxascii=1;
X break;
X case 'b':
X Rxbinary=1;
X break;
X case 'c':
X Crcflg=1;
X break;
X case 'e':
X Zctlesc = 1;
X break;
X case 'p':
X Lzmanag = ZMPROT;
X break;
X case ',':
X log_packets = 1;
X break;
X case '.':
X if(--argc < 1)
X {
X usage("no iofd after -.");
X }
X iofd = atoi(*++argv);
X break;
X case 't':
X if(--argc < 1)
X {
X usage("no rcvr timeout after -t");
X }
X Rxtimeout = atoi(*++argv);
X if(Rxtimeout<10 || Rxtimeout>1000)
X usage("illegal timeout: must be 10 <= t <= 1000");
X break;
X case 'w':
X if(--argc < 1)
X {
X usage("no Zrwindow after -w");
X }
X Zrwindow = 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 'u':
X MakeLCPathname=0;
X break;
X case 'y':
X Rxclob=1;
X break;
X default:
X sprintf(s128,"Unknown switch -%c",*cp);
X usage(s128);
X }
X }
X }
X else if( !npats && argc>0)
X {
X if(argv[0][0])
X {
X npats=argc;
X patts=argv;
X }
X }
X }
X
X if(!required_type || !iofd)
X {
SHAR_EOF
echo "End of part 25"
echo "File z/ecurz.c is continued in part 26"
echo "26" > 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