[alt.sources] ecu - SCO XENIX V/{2,3}86 Extended CU part 26/47

wht@tridom.uucp (Warren Tucker) (10/11/89)

---- Cut Here and unpack ----
#!/bin/sh
# this is part 26 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file z/ecurz.c continued
#
CurArch=26
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		printf("can only be run by ecu\n");
X		exit(255);
X	}
X
X	if(log_packets)
X	{
X		char log_packets_name[64];
X		FILE *ftmp;
X		int iargv;
X		sprintf(log_packets_name,"/tmp/rz%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
X	if(Batch && npats)
X		usage("Cannot specify batch receive and filename");
X	if(npats > 1)
X		usage("only one filename allowed");
X	sprintf(s128,"%s",numeric_revision);
X	report_init(s128);
X	mode(1);
X	signal(SIGINT,cancel_transaction);
X	signal(SIGTERM,cancel_transaction);
X	signal(SIGQUIT,cancel_transaction);
X	if(wcreceive(npats,patts)==ERROR)
X	{
X		exitcode=0200;
X		send_cancel();
X	}
X	mode(0);
X	if(exitcode && !Zmodem)	/* bellow again with all thy might. */
X		send_cancel();
X	report_uninit(0);
X	exit(exitcode);
X}
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of ecurz.c */
SHAR_EOF
echo "File z/ecurz.c is complete"
chmod 0644 z/ecurz.c || echo "restore of z/ecurz.c fails"
echo "x - extracting z/ecusz.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > z/ecusz.c &&
X/* CHK=0x7F75 */
X#define VERSION "ecusz 2.21"
Xchar *numeric_revision = VERSION;
X#define BUFFERED_WRITE
X/*+-------------------------------------------------------------------------
X	ecusz.c - X/Y/ZMODEM send program
X  Derived from public domain source by Chuck Foresberg, Omen Technologies
X  Adaptation for ecu Copyright 1989, Warren H. Tucker, III
X
X	Usage:	ecusz [-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	cancel_transaction(n)
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/*:07-03-1989-22:58-wht------------- ecu 2.00 ---------------- */
X/*:06-26-1989-23:24-wht-exclude "!! " from error messages on screen */
X/*:06-24-1989-16:51-wht-flush edits --- ecu 1.95 */
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 call in rbsb.c)
X	127:     127 or more files not transmitted (see ~/.eculog)
X	1-126:   count of files not transmitted (see ~/.eculog)
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 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;
X#endif
X
X
X/*
X * Attention string to be executed 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_XENIX)
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 FileRejectCount=0;		/* number of files not sent */
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 ecusz_flag = 1;
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(n)
Xcalled by signal interrupt or terminate to clean things up
X--------------------------------------------------------------------------*/
Xvoid
Xcancel_transaction(n)
X{
X	if(Zmodem)
X		zmputs(Attn);
X	send_cancel();
X	mode(0);
X	if(n >= 0)
X	{
X		sprintf(s128,"ecusz received signal %d: exiting",n);
X		report_str(s128,0);
X	}
X	report_tx_ind(0);
X	report_rx_ind(0);
X	report_uninit(0);
X	bye_bye(n);
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_XENIX)
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#ifdef LOG_XFER
X	strcat(s128," (");
X	strcat(s128,place_happened);
X	strcat(s128,")");
X	ecu_log_event(s128);
X#endif
X	if(FileRejectCount < 127)
X		FileRejectCount++;
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#ifdef LOG_XFER
X	ecu_log_event(s128);
X#endif
X	if(FileRejectCount < 127)
X		FileRejectCount++;
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				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 ecu\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	report_init(s128);
X	mode(1);
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	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#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		nap(1500L);
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 : FileRejectCount);
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#ifdef LOG_XFER
X		ecu_log_event(s128);
X#endif
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#ifdef LOG_XFER
X		ecu_log_event(s128);
X#endif
X		report_str(s128 + 5,1);
X		if(FileRejectCount < 127)
X			++FileRejectCount;
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#ifdef LOG_XFER
X		ecu_log_event(s128);
X#endif
X		if(FileRejectCount < 127)
X			++FileRejectCount;
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#ifdef LOG_XFER
X		ecu_log_event(s128);
X#endif
X		if(FileRejectCount < 127)
X			++FileRejectCount;
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#if defined(LOG_XFER)
X	sprintf(s256,"SEND success: %s",Pathname);
X	ecu_log_event(s256);
X#endif
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)
Xchar *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&&sectnum) ? 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);
SHAR_EOF
echo "End of part 26"
echo "File z/ecusz.c is continued in part 27"
echo "27" > 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.