v23i078: Xmodem file transfer program, revision3.9, Part02/03

Rich Salz rsalz at bbn.com
Thu Dec 6 04:34:06 AEST 1990


Submitted-by: Steve Grandi <grandi at noao.edu>
Posting-number: Volume 23, Issue 78
Archive-name: xmodem3.9/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents:  getput.c getput.sysv.c send.c update.doc
# Wrapped by rsalz at litchi.bbn.com on Wed Dec  5 12:31:57 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 2 (of 3)."'
if test -f 'getput.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getput.c'\"
else
  echo shar: Extracting \"'getput.c'\" \(12356 characters\)
  sed "s/^X//" >'getput.c' <<'END_OF_FILE'
X/*
X * Contains system routines to get and put bytes, change tty modes, etc
X * Most of the routines are VERY 4.2BSD Specific!!!
X */
X
X#include "xmodem.h"
X
X/*
X *
X *	Get a byte from the specified file.  Buffer the read so we don't
X *	have to use a system call for each character.
X *
X */
Xgetbyte(fildes, ch)				/* Buffered disk read */
Xint fildes;
Xchar *ch;
X
X	{
X	static char buf[BUFSIZ];	/* Remember buffer */
X	static char *bufp = buf;	/* Remember where we are in buffer */
X	
X	if (nbchr == 0)			/* Buffer exausted; read some more */
X		{
X		if ((nbchr = read(fildes, buf, BUFSIZ)) < 0)
X			error("File Read Error", TRUE);
X		bufp = buf;		/* Set pointer to start of array */
X		}
X	if (--nbchr >= 0)
X		{
X		*ch = *bufp++;
X		return(0);
X		}
X	else
X		{
X		return(EOF);
X		}
X	}
X
X/* Count the number of newlines in a file so we know the REAL file size */
X
Xlong
Xcountnl(fd)
Xint fd;
X{
X	char buf[BUFSIZ];
X	char *bufp;
X	long nltot = 0;
X	int numchar;
X	long lseek();
X
X	while (numchar = read(fd, buf, BUFSIZ))		/* cycle through file */
X		for (bufp=buf; numchar--; bufp++)
X			if (*bufp == '\n')
X				nltot++;
X
X	(void) lseek (fd, 0l, 0);			/* rewind file */
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: countnl--%ld newlines counted\n", nltot);
X	return (nltot);
X}
X
X/*   CRC-16 constant array...
X     from Usenet contribution by Mark G. Mendel, Network Systems Corp.
X     (ihnp4!umn-cs!hyper!mark)
X*/
X
X/* crctab as calculated by initcrctab() */
Xunsigned short crctab[1<<B] = { 
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/* get a byte from data stream -- timeout if "seconds" elapses */
X/* This routine is VERY 4.2 specific */
X
Xint
Xreadbyte(seconds)
Xint seconds;
X	{
X	int readfd;
X	char c;
X	struct timeval tmout;
X
X	tmout.tv_sec = seconds;
X	tmout.tv_usec = 0;
X
X	readfd = 1<<0;
X
X	if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
X		{
X		if (DEBUG)
X			fprintf(LOGFP, "DEBUG: readbyte TIMEOUT\n");
X		return(TIMEOUT);
X		}
X
X	read(0, &c, 1);
X
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
X
X	return(c & 0xff);  /* return the char */
X	}
X
X/* flush input stream by reading pending characters */
X
Xflushin()
X	{
X	int readfd;
X	char inbuf[BBUFSIZ];
X	struct timeval tmout;
X
X	/* set up a usec timeout on stdin */
X	tmout.tv_sec = 0;
X	tmout.tv_usec = 1;
X	readfd = 1<<0;
X
X	/* any characters pending?; return if none */
X	if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
X		return;
X
X	/* read the characters to flush them (assume there are fewer than BBUFSIZ */
X	(void) read(0, inbuf, BBUFSIZ);
X	}
X
X/* 
X get a buffer (length bufsize) from data stream -- timeout if "seconds" elapses.
X Read bunches of characters to save system overhead;
X Further process data while kernel is reading stream (calculating "checksum").
X Try to nap long enough so kernel collects 100 characters or so until we wake up
X unless TOOBUSY is set.
X*/
X
X/* This routine is VERY 4.2 specific */
X
Xint
Xreadbuf(bufsize, seconds, tmode, amode, recvsectcnt, checksum, bufctr)
X
Xint bufsize,	/* number of chars to be read */
Xseconds, 	/* timeout period for each read */
Xtmode, 		/* transmission mode: TRUE if text */
Xamode, 		/* transmission mode: TRUE if apple macintosh */
X*checksum, 	/* pointer to checksum value */
X*bufctr;	/* length of actual data string in buffer */
Xlong recvsectcnt;	/* running sector count (128 byte sectors) */
X
X{
X	int readfd;		/* mask for select call */
X	struct timeval tmout;	/* timeout structure for select */
X	int numread;		/* number of chars read */
X	int left;		/* number of chars left to read */
X	int recfin = FALSE;		/* flag that EOF read */
X	char inbuf[BBUFSIZ];	/* buffer for incoming packet */
X	register unsigned char c;	/* character being processed */
X	register unsigned short chksm;	/* working copy of checksum */
X	register int bfctr;	/* working copy of bufctr */
X	int j;			/* loop index */
X	char *sectdisp();
X
X	tmout.tv_sec = seconds;
X	tmout.tv_usec = 0;
X	readfd = 1<<0;
X	chksm = 0;
X	bfctr = 0;
X
X	for (left = bufsize; left > 0;) {
X
X		/* read however many chars are waiting */
X
X		if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
X			return(TIMEOUT);
X
X		numread = read(0, inbuf, left);
X		left -= numread;
X
X		if (DEBUG)
X			fprintf(LOGFP, "DEBUG: readbuf--read %d characters\n", numread);
X
X		/* now process part of packet we just read */
X
X		for (j =  0; j < numread; j++) 
X			{  
X				buff[bfctr] = c = inbuf[j] & 0xff;
X				fileread++;
X
X				if (CRCMODE)  /* CRC */
X					chksm = (chksm<<B) ^ crctab[(chksm>>(W-B)) ^ c];
X
X				else        /* checksum */
X		       			chksm = ((chksm+c) & 0xff);
X
X				if (CHECKLENGTH && fileread > filelength)	/* past EOF ? */
X					continue;
X
X				if (tmode) 		/* text mode processing */
X					{
X					buff[bfctr] &= 0x7f;	/* nuke bit 8 */
X					if (c == CR || c == 0)	/* skip CRs and nulls */
X						continue;
X					else if (c == CTRLZ)	/* CP/M EOF char */
X						{  
X						recfin = TRUE;
X		       				continue;
X		       				}
X		       			else if (!recfin)	/* don't increment if past EOF */
X						bfctr++;
X					}
X				else if (amode) 	/* Apple macintosh text mode processing */
X					{
X					buff[bfctr] &= 0x7f;	/* nuke bit 8 */
X					if (c == 0)		/* skip nulls */
X						continue;
X					else if (c == CR)	/* translate CR to LF */
X						buff[bfctr] = LF;
X					else if (c == CTRLZ)	/* CP/M EOF char */
X						{  
X						recfin = TRUE;
X		       				continue;
X		       				}
X		       			if (!recfin)		/* don't increment if past EOF */
X						bfctr++;
X					}
X				else			/* binary */
X					bfctr++;
X
X		     	}	
X
X		/* go to sleep to save uneeded system calls while kernel
X		   is reading data from serial line; 
X		   fudge constant from 10000 to 9000 to avoid sleeping too long.
X		*/
X		if (left && !TOOBUSY)
X		    napms( (left<SLEEPNUM ? left:SLEEPNUM) * 9000/ttyspeed);
X
X	}
X
X	if (CHECKLENGTH && fileread >= filelength)
X		logitarg("File end from YMODEM length found in sector %s\n",
X		  sectdisp(recvsectcnt,bufsize,1));
X	*checksum = chksm;
X	*bufctr = bfctr;
X	return(0);
X}
X
X/* send a byte to data stream */
X
Xsendbyte(data)
Xchar data;
X	{
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
X
X	if (write(1, &data, 1) != 1)  	/* write the byte (assume it goes NOW; no flushing needed) */
X		error ("Write error on stream", TRUE);
X	return;
X	}
X
X/* send a buffer to data stream */
X
Xwritebuf(buffer, nbytes)
Xchar *buffer;
Xint  nbytes;
X	{
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
X
X	if (write(1, buffer, nbytes) != nbytes)		/* write the buffer (assume no TIOCFLUSH needed) */
X		error ("Write error on stream", TRUE);
X	return;
X	}
X
X/*
X * "nap" for specified time -- VERY 4.2BSD specific
X */
X
Xnapms (milliseconds)
Xint	milliseconds;
X{
X	struct	timeval	timeout;
X	int readfd;
X
X	if (milliseconds == 0)
X		return;
X	if (DEBUG)
X		fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
X	timeout.tv_sec = 0;
X	timeout.tv_usec = milliseconds * 1000;
X	readfd = 0;
X
X	(void) select(1, &readfd, (int *)0, (int *)0, &timeout);
X}
X
X 
X/* set and restore tty modes for XMODEM transfers */
X/* These routines are 4.2/v7(?) specific */
X
Xstruct sgttyb ttys, ttysnew;	/* for stty terminal mode calls */
Xstruct stat statbuf;		/* for terminal message on/off control */
X
Xint wason;			/* holds status of tty read write/modes */
Xchar *tty;			/* current tty name */
X
X
Xsetmodes()
X	{
X	char *ttyname();
X
X	int n;
X
X	extern onintr();
X
X	sleep(2);			/* let the output appear */
X	if (ioctl(0,TIOCGETP,&ttys)<0)  /* get tty params [V7] */
X		error("Can't get TTY Parameters", TRUE);
X
X	tty = ttyname(0);  /* identify current tty */
X	
X	ttysnew.sg_ispeed = ttys.sg_ispeed;	/* copy input speed */
X	ttysnew.sg_ospeed = ttys.sg_ospeed;	/* copy input speed */
X	ttysnew.sg_flags |= RAW;	/* set for RAW Mode */
X	ttysnew.sg_flags &= ~ECHO;	/* set for no echoing */
X	ttysnew.sg_flags &= ~TANDEM;	/* turn off flow control */
X
X	/* set new paramters */
X	if (ioctl(0,TIOCSETP,&ttysnew) < 0)
X		error("Can't set new TTY Parameters", TRUE);
X
X	/* Flush characters waiting for read or write */
X	n = 0;
X	if (ioctl(0,TIOCFLUSH,&n) < 0)
X		error("Can't flush terminal queue", TRUE);
X
X	if (stat(tty, &statbuf) < 0)	/* get tty modes */ 
X		{
X		logit("Can't get your TTY Status\n");
X		tlogit("Can't get your TTY Status\n");
X		wason = FALSE;
X		}
X	else
X		{
X		if (statbuf.st_mode & 022)
X			{
X			if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
X				{
X				logit("Can't change TTY mode\n");
X				tlogit("Can't change TTY mode\n");
X				wason = FALSE;
X				}
X			else 
X				wason = TRUE;
X			}
X		else 
X			wason = FALSE;
X		}
X
X	/* set up signal catcher to restore tty state if we are KILLed */
X
X	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
X		signal(SIGTERM, onintr);
X	}
X
X/* restore normal tty modes */
X
Xrestoremodes(errcall)
Xint errcall;
X	{
X	if (wason)
X		if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
X			error("Can't change TTY mode", FALSE);
X	if (ioctl(0,TIOCSETP,&ttys) < 0)
X		{ if (!errcall)
X		   error("RESET - Can't restore normal TTY Params", FALSE);
X		else
X		     printf("RESET - Can't restore normal TTY Params\n");
X		}
X	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
X		signal(SIGTERM, SIG_DFL);
X	return;
X	}
X
X
X
X
X/* signal catcher */
Xonintr()
X	{
X	error("Kill signal; bailing out", TRUE);
X	}
X
X/* create string with a timestamp for log file */
X
Xchar *stamptime()
X{
X	char *asctime();		/* stuff to get timestamp */
X	struct tm *localtime(), *tp;
X	struct timeval tv;
X	struct timezone tz;
X
X	gettimeofday (&tv, &tz);		/* fill in timestamp */
X	tp = localtime ((time_t *)&tv.tv_sec);
X	return(asctime(tp));
X}
X
X
X
X/* get tty speed for time estimates */
X
Xgetspeed()
X	{
X	static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600, 
X	   1200, 1800, 2400, 4800, 9600, 19200, 0};
X	if (ioctl(0,TIOCGETP,&ttys) < 0)	/* get tty structure */
X		error("Can't get TTY parameters", FALSE);
X
X	if (ttys.sg_ispeed >= 0 && ttys.sg_ispeed <= 14)
X		{
X		ttyspeed = speedtbl[ttys.sg_ispeed];
X		logitarg ("Line speed = %d bits per second\n", ttyspeed);
X		}
X	else
X		{
X		ttyspeed = 1200;
X		logit ("Can't determine line speed; assuming 1200 bps\n");
X		}
X	}
X
X
X/* turn off keyboard stop signal so stray ^X don't put us in background */
X
Xstopsig()
X	{
X	signal(SIGTSTP, SIG_IGN);
X	}
END_OF_FILE
  if test 12356 -ne `wc -c <'getput.c'`; then
    echo shar: \"'getput.c'\" unpacked with wrong size!
  fi
  # end of 'getput.c'
fi
if test -f 'getput.sysv.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getput.sysv.c'\"
else
  echo shar: Extracting \"'getput.sysv.c'\" \(11185 characters\)
  sed "s/^X//" >'getput.sysv.c' <<'END_OF_FILE'
X/*
X * Contains system routines to get and put bytes, change tty modes, etc
X * Sys V version.  UNTESTED!!!!!!
X */
X
X#include "xmodem.h"
X
X/*
X *
X *	Get a byte from the specified file.  Buffer the read so we don't
X *	have to use a system call for each character.
X *
X */
Xgetbyte(fildes, ch)				/* Buffered disk read */
Xint fildes;
Xchar *ch;
X
X	{
X	static char buf[BUFSIZ];	/* Remember buffer */
X	static char *bufp = buf;	/* Remember where we are in buffer */
X	
X	if (nbchr == 0)			/* Buffer exausted; read some more */
X		{
X		if ((nbchr = read(fildes, buf, BUFSIZ)) < 0)
X			error("File Read Error", TRUE);
X		bufp = buf;		/* Set pointer to start of array */
X		}
X	if (--nbchr >= 0)
X		{
X		*ch = *bufp++;
X		return(0);
X		}
X	else
X		{
X		return(EOF);
X		}
X	}
X
X/* Count the number of newlines in a file so we know the REAL file size */
X
Xlong
Xcountnl(fd)
Xint fd;
X{
X	char buf[BUFSIZ];
X	char *bufp;
X	long nltot = 0;
X	int numchar;
X	long lseek();
X
X	while (numchar = read(fd, buf, BUFSIZ))		/* cycle through file */
X		for (bufp=buf; numchar--; bufp++)
X			if (*bufp == '\n')
X				nltot++;
X
X	(void) lseek (fd, 0l, 0);			/* rewind file */
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: countnl--%ld newlines counted\n", nltot);
X	return (nltot);
X}
X
X/*   CRC-16 constant array...
X     from Usenet contribution by Mark G. Mendel, Network Systems Corp.
X     (ihnp4!umn-cs!hyper!mark)
X*/
X
X/* crctab as calculated by initcrctab() */
Xunsigned short crctab[1<<B] = { 
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/* get a byte from data stream -- timeout if "seconds" elapses */
X
Xint timedout;
X 
Xint
Xreadbyte(seconds)
Xint seconds;
X{
X	int force_it();
X	char c;
X	signal(SIGALRM, force_it);
X
X	timedout = 0;
X	alarm(seconds);
X	read(0, &c, 1);
X	alarm(0);
X	if (timedout)
X		{
X		if (DEBUG)
X			fprintf(LOGFP, "DEBUG: readbyte TIMEOUT\n");
X		return(TIMEOUT);
X		}
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
X	return(c & 0xff);
X}
X
Xint
Xforce_it()
X{
X	timedout++;
X	return;
X}
X
X
X/* flush input stream */
X
Xflushin()
X	{
X/* No good way to do this without select */
X/* Perhaps....but we waste 1 second with every call!
X	while (readbyte(1) != TIMEOUT)
X		;
X*/
X	}
X
X/* 
X get a buffer (length bufsize) from data stream -- timeout if "seconds" elapses.
X Read bunches of characters to save system overhead;
X Further process data while kernel is reading stream (calculating "checksum").
X Try to nap long enough so kernel collects 100 characters or so until we wake up
X unless TOOBUSY is set.
X*/
X
X
Xint
Xreadbuf(bufsize, seconds, tmode, amode, recvsectcnt, checksum, bufctr)
X
Xint bufsize,	/* number of chars to be read */
Xseconds, 	/* timeout period for each read */
Xtmode, 		/* transmission mode: TRUE if text */
Xamode, 		/* transmission mode: TRUE if apple macintosh */
X*checksum, 	/* pointer to checksum value */
X*bufctr;	/* length of actual data string in buffer */
Xlong recvsectcnt;	/* running sector count (128 byte sectors) */
X
X{
X	int force_it();
X	int numread;		/* number of chars read */
X	int left;		/* number of chars left to read */
X	int recfin = 0;		/* flag that EOF read */
X	char inbuf[BBUFSIZ];	/* buffer for incoming packet */
X	register unsigned char c;	/* character being processed */
X	register unsigned short chksm;	/* working copy of checksum */
X	register int bfctr;	/* working copy of bufctr */
X	int j;			/* loop index */
X	char *sectdisp();
X
X	signal(SIGALRM, force_it);
X	chksm = 0;
X	bfctr = 0;
X
X	for (left = bufsize; left > 0;) {
X
X		/* read however many chars are waiting */
X		timedout = 0;
X		alarm(seconds);
X		numread = read(0, inbuf, left);
X		alarm(0);
X		if (timedout)
X			return(TIMEOUT);
X		left -= numread;
X
X		if (DEBUG)
X			fprintf(LOGFP, "DEBUG: readbuf--read %d characters\n", numread);
X
X		/* now process part of packet we just read */
X
X		for (j =  0; j < numread; j++) 
X			{  
X				buff[bfctr] = c = inbuf[j] & 0xff;
X				fileread++;
X
X				if (CRCMODE)  /* CRC */
X					chksm = (chksm<<B) ^ crctab[(chksm>>(W-B)) ^ c];
X
X				else        /* checksum */
X		       			chksm = ((chksm+c) & 0xff);
X
X				if (CHECKLENGTH && fileread > filelength)	/* past EOF ? */
X					continue;
X
X				if (tmode) 		/* text mode processing */
X					{
X					buff[bfctr] &= 0x7f;	/* nuke bit 8 */
X					if (c == CR || c == 0)	/* skip CRs and nulls */
X						continue;
X					else if (c == CTRLZ)	/* CP/M EOF char */
X						{  
X						recfin = TRUE;
X		       				continue;
X		       				}
X		       			else if (!recfin)	/* don't increment if past EOF */
X						bfctr++;
X					}
X				else if (amode) 	/* Apple macintosh text mode processing */
X					{
X					buff[bfctr] &= 0x7f;	/* nuke bit 8 */
X					if (c == 0)		/* skip nulls */
X						continue;
X					else if (c == CR)	/* translate CR to LF */
X						buff[bfctr] = LF;
X					else if (c == CTRLZ)	/* CP/M EOF char */
X						{  
X						recfin = TRUE;
X		       				continue;
X		       				}
X		       			if (!recfin)	/* don't increment if past EOF */
X						bfctr++;
X					}
X				else			/* binary */
X					bfctr++;
X
X		     	}	
X
X		/* go to sleep to save uneeded system calls while kernel
X		   is reading data from serial line, fudge constant from 10 to
X		   9 to avoid sleeping too long
X		*/
X		if (left && !TOOBUSY)
X			sleep ((left<SLEEPNUM ? left:SLEEPNUM) * 9/ttyspeed);
X	}
X
X	if (CHECKLENGTH && fileread >= filelength)
X		logitarg("File end from YMODEM length found in sector %s\n",
X		  sectdisp(recvsectcnt,bufsize,1));
X	*checksum = chksm;
X	*bufctr = bfctr;
X	return(0);
X}
X
X/* send a byte to data stream */
X
Xsendbyte(data)
Xchar data;
X	{
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
X
X	if (write(1, &data, 1) != 1)  	/* write the byte (assume it goes NOW; no flushing needed) */
X		error ("Write error on stream", TRUE);
X	return;
X	}
X
X/* send a buffer to data stream */
X
Xwritebuf(buffer, nbytes)
Xchar *buffer;
Xint  nbytes;
X	{
X	if (DEBUG)
X		fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
X
X	if (write(1, buffer, nbytes) != nbytes)		/* write the buffer (assume no TIOCFLUSH needed) */
X		error ("Write error on stream", TRUE);
X	return;
X	}
X
X/* set and restore tty modes for XMODEM transfers */
X
Xstruct termio ttys;
Xstruct stat statbuf;		/* for terminal message on/off control */
X
Xint wason;			/* holds status of tty read write/modes */
Xchar *tty;			/* current tty name */
X
X
Xsetmodes()
X	{
X	char *ttyname();
X	struct termio ttysnew;
X
X	extern onintr();
X
X	sleep(2);			/* let the output appear */
X	if (ioctl(0,TCGETA,&ttys)<0)  /* get tty params */
X		error("Can't get TTY Parameters", TRUE);
X
X	tty = ttyname(0);  /* identify current tty */
X	
X	if (ioctl(0,TCGETA,&ttysnew)<0)  /* get tty params */
X		error("Can't get TTY Parameters", TRUE);
X	ttysnew.c_cc[4] = 1;		/* VMIN */
X	ttysnew.c_cc[5] = 0;		/* VTIME */
X	ttysnew.c_iflag = 0;
X	ttysnew.c_oflag = 0;
X	ttysnew.c_lflag = 0;
X	ttysnew.c_cflag &= ~CSIZE;
X	ttysnew.c_cflag |= CS8;
X	ttysnew.c_cflag &= ~PARENB;
X	if (ioctl(0,TCSETA,&ttysnew)<0)  /* set new paramters */
X		error("Can't set new TTY Parameters", TRUE);
X
X	if (stat(tty, &statbuf) < 0)	/* get tty modes */ 
X		{
X		logit("Can't get your TTY Status\n");
X		tlogit("Can't get your TTY Status\n");
X		wason = FALSE;
X		}
X	else
X		{
X		if (statbuf.st_mode & 022)
X			{
X			if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
X				{
X				logit("Can't change TTY mode\n");
X				tlogit("Can't change TTY mode\n");
X				wason = FALSE;
X				}
X			else 
X				wason = TRUE;
X			}
X		else 
X			wason = FALSE;
X		}
X
X
X	/* set up signal catcher to restore tty state if we are KILLed */
X
X	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
X		signal(SIGTERM, onintr);
X	}
X
X/* restore normal tty modes */
X
Xrestoremodes(errcall)
Xint errcall;
X	{
X	if (wason)
X		if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
X			error("Can't change TTY mode", FALSE);
X	if (ioctl(0,TCSETA,&ttys) < 0)
X		{ if (!errcall)
X		   error("RESET - Can't restore normal TTY Params", FALSE);
X		else
X		     printf("RESET - Can't restore normal TTY Params\n");
X		}
X	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
X		signal(SIGTERM, SIG_DFL);
X	return;
X	}
X
X
X
X
X/* signal catcher */
Xonintr()
X	{
X	error("Kill signal; bailing out", TRUE);
X	}
X
X/* create string with a timestamp for log file */
X
Xchar *stamptime()
X{
X	char *asctime();		/* stuff to get timestamp */
X	struct tm *localtime(), *tp;
X	long now;
X
X	time(&now);
X	tp = localtime(&now);
X	return(asctime(tp));
X}
X
X
X
X/* get tty speed for time estimates */
X
Xgetspeed()
X	{
X	static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
X	1200, 1800, 2400, 4800, 9600, 19200, 0};
X	struct termio ttystemp;
X
X	if (ioctl(0,TCGETA,&ttystemp) < 0)	/* get tty structure */
X		error("Can't get TTY parameters", FALSE);
X	if ((ttystemp.c_cflag & 017) >= 0 && (ttystemp.c_cflag & 017) <= 14)
X		{
X		ttyspeed = speedtbl[ttystemp.c_cflag & 017];
X		logitarg ("Line speed = %d bits per second\n", ttyspeed);
X		}
X	else
X		{
X		ttyspeed = 1200;
X		logit ("Can't determine line speed; assuming 1200 bps\n");
X		}
X	}
X
X
X/* turn off keyboard stop signal so stray ^X don't put us in background */
X
Xstopsig()
X	{
X	}
END_OF_FILE
  if test 11185 -ne `wc -c <'getput.sysv.c'`; then
    echo shar: \"'getput.sysv.c'\" unpacked with wrong size!
  fi
  # end of 'getput.sysv.c'
fi
if test -f 'send.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'send.c'\"
else
  echo shar: Extracting \"'send.c'\" \(12219 characters\)
  sed "s/^X//" >'send.c' <<'END_OF_FILE'
X/**  send a file  **/
X
X/*
X * Operation of this routine depends on on MDM7BAT and YMDMBAT flags.
X *
X * If "name" is NULL; close out the BATCH send.
X */
X
X#include "xmodem.h"
X
Xsfile(name)
Xchar *name;
X	{
X
X	char *sectdisp();
X	time_t time();
X	char *strcpy();
X	char *unix_cpm();
X	char *cpmify();
X	long countnl();
X
X	extern unsigned short crctab[1<<B];	/* CRC-16 constant values, see getput.c */
X
X	register int bufctr, 		/* array index for data buffer */
X	sectnum;			/* packet number for packet header */
X
X	register unsigned short checksum; 	/* checksum/crc */
X
X	char blockbuf[BBUFSIZ+6];	/* holds packet as it is constructed */
X
X	struct stat filestatbuf;	/* file status info */
X
X	int fd, 		/* file descriptor for file being transmitted */
X	attempts,		/* number of attempts made to transmit a packet */
X	nlflag, 		/* flag that we have to send a LF in next packet */
X	sendfin, 		/* flag that we are sending the last packet */
X	closeout,		/* flag that we are closing out batch send */
X	startup,		/* flag that we are starting batch send */
X	tmode,			/* TRUE for text mode */
X	amode,			/* TRUE for apple mode */
X	filepack,		/* TRUE when sending first packet */
X	buf1024,		/* TRUE when sending 1K packets */
X	bbufcnt,		/* array index for packet */
X	firstchar,		/* first character in protocol transaction */
X	bufsize,		/* packet size (128 or 1024) */
X	sendresp;  		/* response char to sent block received from remote*/
X	long sentsect;		/* count of 128 byte sectors actually sent */
X	long expsect;		/* count of 128 byte sectors expected to be sent */
X	time_t start;		/* starting time of transfer */
X	char c;
X
X	nbchr = 0;  /* clear buffered read char count */
X
X	CRCMODE = FALSE;	/* Receiver determines use of crc or checksum */
X	YMODEMG = FALSE;	/* Receiver determines use YMODEM-G */
X
X	buf1024 = LONGPACK;	/* set packet size flag to command line switch */
X
X	closeout = FALSE; startup = TRUE; filepack = FALSE;	/* indicate state of batch transfer */
X
X	tmode = (XMITTYPE == 't') ? TRUE : FALSE;	/* set text mode */
X	amode = (XMITTYPE == 'a') ? TRUE : FALSE;	/* set apple mode */
X
X	/* Check on NULL file name */
X	if (strcmp(name,"") == 0)
X		{
X		if (BATCH)
X			closeout = TRUE;
X		else
X			{
X			sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X			error("NULL file name in send", TRUE);
X			}
X		}
X
X	if (!closeout)		/* Are we closing down batch? */
X		{			/* no; let's send a file */
X		logit("----\nXMODEM Send Function\n");
X		tlogit("----\nXMODEM Send Function\n");
X
X		if ((fd = open(name, 0)) < 0)	
X			{  
X			sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X     	   		error("Can't open file for send", TRUE);
X			}
X	
X		stat(name, &filestatbuf);  /* get file status bytes */
X		if (tmode)		   /* count up NLs */
X			filestatbuf.st_size += countnl(fd);
X		expsect = (filestatbuf.st_size/128) + 1;
X	
X		if (LOGFLAG)
X			{   
X		    	fprintf(LOGFP, "File Name: %s\n", name);
X		  	fprintf(LOGFP,"File Size %ldK, %ld Records, %ld Bytes\n",
X		  	  (filestatbuf.st_size/1024)+1, expsect, filestatbuf.st_size);
X			projtime(expsect, LOGFP);
X			}
X		if (TIPFLAG)
X			{
X    			fprintf(stderr, "File Name: %s\n", name);
X  			fprintf(stderr,"File Size %ldK, %ld Records, %ld Bytes\n",
X			  (filestatbuf.st_size/1024)+1, expsect, filestatbuf.st_size);
X			projtime(expsect, stderr);
X			}
X		}
X	else
X		{
X		logit("----\nXMODEM Send Function\n");
X		logit("Closing down Batch Transmission\n");
X		tlogit("Closing down Batch Transmission\n");
X		}
X
X
X	bufsize = buf1024 ? 1024 : 128;		/* set sector size */
X	if (buf1024 && !closeout)
X		{
X		logit("1K packet mode chosen on command line\n");
X		tlogit("1K packet mode chosen on command line\n");
X		}
X
X        sendfin = nlflag = FALSE;
X  	attempts = 0;
X
X	/* wait for and read startup character */
Xrestart:
X	do
X		{
X		while (((firstchar=readbyte(1)) != NAK) && (firstchar != CRCCHR) && (firstchar != GCHR) && (firstchar != CAN))
X			if (++attempts > NAKMAX)
X				{
X				if (MDM7BAT && startup)
X					{
X					sendbyte(ACK); sendbyte(EOT);
X					}
X				error("Remote System Not Responding", TRUE);
X				}
X
X		if ((firstchar & 0x7f) == CAN)
X			if (readbyte(3) == CAN)
X				error("Send Canceled by CAN-CAN",TRUE);
X
X		if (firstchar == GCHR)
X			{
X			CRCMODE = TRUE;
X			YMODEMG = TRUE;
X			CANCAN = TRUE;
X			if (!closeout)
X				{
X				logit("Receiver invoked YMODEM-G and CRC modes\n");
X				tlogit("Receiver invoked YMODEM-G and CRC modes\n");
X				}
X			}
X		if (firstchar == CRCCHR)
X			{
X			CRCMODE = TRUE;
X			if (!closeout)
X				{
X				logit("Receiver invoked CRC mode\n");
X				tlogit("Receiver invoked CRC mode\n");
X				}
X			if (readbyte(1) == KCHR)
X				{
X				buf1024 = TRUE;
X				logit("Receiver invoked 1K packet mode\n");
X				tlogit("Receiver invoked 1K packet mode\n");
X				}
X			}
X		}
X	while (firstchar != NAK && firstchar != CRCCHR && firstchar != GCHR);
X
X	if (MDM7BAT && closeout)	/* close out MODEM7 batch */
X		{
X		sendbyte(ACK); sendbyte (EOT);
X		flushin(); readbyte(2); 	/* flush junk */
X		return;
X		}
X
X	if (MDM7BAT && startup)		/* send MODEM7 file name */
X		{
X		if (send_name(unix_cpm(name)) == -1)
X			{
X			attempts = 0;
X			goto restart;
X			}
X		startup = FALSE;
X		attempts = 0;
X		goto restart;
X		}
X
X	sectnum = 1;
X
X	if (YMDMBAT)	/* Fudge for YMODEM transfer (to send name packet) */
X		{
X		sectnum = 0;
X		bufsize = 128;
X		filepack = TRUE;
X		}
X
X	attempts = sentsect = 0;
X	start = time((time_t *) 0);
X
X        do 			/* outer packet building/sending loop; loop till whole file is sent */
X		{   
X
X		if (closeout && YMDMBAT && sectnum == 1)	/* close out YMODEM */
X			return;
X
X		if (YMDMBAT && sectnum == 1)			/* get set to send YMODEM data packets */
X			{
X			bufsize = buf1024 ? 1024 : 128;
X
X			do		/* establish handshaking again */
X				{
X				while (((firstchar=readbyte(2)) != CRCCHR) && (firstchar != GCHR) && (firstchar != NAK) && (firstchar != CAN))
X					if (++attempts > ERRORMAX)
X						error("YMODEM protocol botch, C or G expected", TRUE);
X				if ((firstchar&0x7f) == CAN)
X					if (readbyte(3) == CAN)
X						error("Send Canceled by CAN-CAN", TRUE);
X				}
X			while ((firstchar != CRCCHR) &&  (firstchar != GCHR) && (firstchar != NAK));
X
X			attempts = 0;
X			}
X
X		if ((bufsize == 1024) && (attempts > KSWMAX))
X			{
X			logit("Reducing packet size to 128 due to excessive errors\n");
X			tlogit("Reducing packet size to 128 due to excessive errors\n");
X			bufsize = 128;
X			}
X
X		if ((bufsize == 1024) && ((expsect - sentsect) < 8))
X			{
X			logit("Reducing packet size to 128 for tail end of file\n");
X			tlogit("Reducing packet size to 128 for tail end of file\n");
X			bufsize = 128;
X			}
X
X		if (sectnum > 0)	/* data packet */
X			{
X			for (bufctr=0; bufctr < bufsize;)
X	    			{
X				if (nlflag)
X	       	 			{  
X					buff[bufctr++] = LF;  /* leftover newline */
X	       	    			nlflag = FALSE;
X	        			}
X				if (getbyte(fd, &c) == EOF)
X					{ 
X					sendfin = TRUE;  /* this is the last sector */
X		   			if (!bufctr)  /* if EOF on sector boundary */
X		      				break;  /* avoid sending extra sector */
X		      			buff[bufctr++] = CTRLZ;  /* pad with Ctrl-Z for CP/M EOF (even do for binary files) */
X		   			continue;
X		      			}
X	
X				if (tmode && c == LF)  /* text mode & Unix newline? */
X		    			{
X					buff[bufctr++] = CR;  /* insert carriage return */
X			     		if (bufctr < bufsize)
X		                		buff[bufctr++] = LF;  /* insert LF */
X		 	      		else
X			        		nlflag = TRUE;  /* insert on next sector */
X		   			}	
X				else if (amode && c == LF)   /* Apple mode & Unix newline? */
X					buff[bufctr++] = CR; /* substitute CR */
X				else
X					buff[bufctr++] = c;  /* copy the char without change */
X		    		}
X
X	    		if (!bufctr)  /* if EOF on sector boundary */
X   	       			break;  /* avoid sending empty sector */
X			}	
X
X		else		/* YMODEM filename packet */
X			{
X			for (bufctr=0; bufctr<1024; bufctr++)  /* zero packet */
X				buff[bufctr]=0;
X			if (!closeout)
X				{
X				strcpy((char *)buff, cpmify(name));
X				
X					/* put in file name, length, mode, */
X					/* dummy SN, files, bytes remaining and file type */
X					{
X					register char *p;
X					p = (char *)buff + strlen(buff) + 1;
X					sprintf(p, "%lu %lo %o 0 %d %ld 0", filestatbuf.st_size, 
X					  filestatbuf.st_mtime, filestatbuf.st_mode,
X					  yfilesleft, ytotleft);
X					if (DEBUG)
X						fprintf(LOGFP, "DEBUG: YMODEM header information: %s %s\n", buff, p);
X					}
X				if (buff[125])		/* need to have long packet? */
X					{
X					bufsize = 1024;
X					if (DEBUG)
X						fprintf(LOGFP, "DEBUG: YMODEM header sent in 1024 byte packet\n");
X					}
X				buff[bufsize-2]	= (expsect & 0xff);        /* put in KMD kludge information */
X				buff[bufsize-1] = ((expsect >> 8) & 0xff);
X
X				/* update totals */
X				ytotleft -= filestatbuf.st_size;
X				if (--yfilesleft <= 0)
X					ytotleft = 0;
X				if (ytotleft < 0)
X					ytotleft = 0;
X				}
X			}
X
X		bbufcnt = 0;		/* start building block to be sent */
X		blockbuf[bbufcnt++] = (bufsize == 1024) ? STX : SOH;    /* start of packet char */
X		blockbuf[bbufcnt++] = sectnum;	    /* current sector # */
X		blockbuf[bbufcnt++] = ~sectnum;   /* and its complement */
X
X               	checksum = 0;  /* initialize checksum */
X               	for (bufctr=0; bufctr < bufsize; bufctr++)
X       			{
X			blockbuf[bbufcnt++] = buff[bufctr];
X
X			if (CRCMODE)
X				checksum = (checksum<<B) ^ crctab[(checksum>>(W-B)) ^ buff[bufctr]];
X
X			else
X               			checksum = ((checksum+buff[bufctr]) & 0xff);
X         		}
X
X		if (CRCMODE)		/* put in CRC */
X			{
X			checksum &= 0xffff;
X			blockbuf[bbufcnt++] = ((checksum >> 8) & 0xff);
X			blockbuf[bbufcnt++] = (checksum & 0xff);
X			}
X		else			/* put in checksum */
X			blockbuf[bbufcnt++] = checksum;
X
X            	attempts = 0;
X	
X            	do				/* inner packet loop */
X            		{
X
X			writebuf(blockbuf, bbufcnt);	/* write the block */
X			if (!YMODEMG)
X				flushin();              /* purge anything in input queue */
X
X			if (DEBUG)
X				fprintf (LOGFP, "DEBUG: %d byte Packet %02xh (%02xh) sent, checksum %02xh %02xh\n", 
X				bbufcnt, blockbuf[1]&0xff, blockbuf[2]&0xff, blockbuf[bufsize+3]&0xff, blockbuf[bufsize+4]&0xff);
X
X                	attempts++;
X			sendresp = (YMODEMG) ? ACK : readbyte(10);	/* get response from remote  (or fake it for YMODEM-G) */
X
X			if (sendresp != ACK)
X		   		{
X				if (sendresp == TIMEOUT)
X					{
X		   			logitarg("Timeout on sector %s\n",sectdisp(sentsect,bufsize,1));
X		   			tlogitarg("Timeout on sector %s\n",sectdisp(sentsect,bufsize,1));
X					}
X				if (sendresp == CAN)
X					{
X					if (CANCAN)
X						{
X						if (readbyte(3) == CAN)
X							error("Send Canceled by CAN-CAN",TRUE);
X						}
X					else
X						{
X		   			logitarg("ignored CAN on sector %s\n",sectdisp(sentsect,bufsize,1));
X		   			tlogitarg("ignored CAN on sector %s\n",sectdisp(sentsect,bufsize,1));
X						}
X					}
X				else if (sendresp == NAK)
X					{
X		   			logitarg("NAK on sector %s\n",sectdisp(sentsect,bufsize,1));
X		   			tlogitarg("NAK on sector %s\n",sectdisp(sentsect,bufsize,1));
X					}
X				else
X					{
X		   			logitarg("Non-ACK on sector %s\n",sectdisp(sentsect,bufsize,1));
X		   			tlogitarg("Non-ACK on sector %s\n",sectdisp(sentsect,bufsize,1));
X					}
X		   		}
X            		}
X			while((sendresp != ACK) && (attempts < ERRORMAX));	/* close of inner loop */
X
X       		sectnum++;  /* increment to next sector number */
X		if (!filepack)
X			sentsect += (bufsize == 128) ? 1 : 8;
X		filepack = FALSE;
X		if (TIPFLAG && sentsect % 32 == 0)
X			tlogitarg("Sector %s sent\n", sectdisp(sentsect,bufsize,0));
X    		}
X		while (!sendfin && ( attempts < ERRORMAX));	/* end of outer loop */
X
X	if (attempts >= ERRORMAX)
X		{
X		sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X		error ("Too many errors in transmission", TRUE);
X		}
X
X    	sendbyte(EOT);  /* send 1st EOT to close down transfer */
X    	attempts = 0;
X	
X    	while ((readbyte(15) != ACK) && (attempts++ < EOTMAX)) 	/* wait for ACK of EOT */
X		{
X		if (attempts > 1)
X			{
X			logitarg("EOT not ACKed, try %d\n", attempts);
X			tlogitarg("EOT not ACKed, try %d\n", attempts);
X			}
X	   	sendbyte(EOT);
X		}
X
X    	if (attempts >= RETRYMAX)
X	   	error("Remote System Not Responding on Completion", TRUE);
X
X    	close(fd);
X
X    	logit("Send Complete\n");
X    	tlogit("Send Complete\n");
X	if (LOGFLAG)
X		prtime(sentsect, time((time_t *) 0) - start, LOGFP);
X	if (TIPFLAG)
X		prtime(sentsect, time((time_t *) 0) - start, stderr);
X	}
END_OF_FILE
  if test 12219 -ne `wc -c <'send.c'`; then
    echo shar: \"'send.c'\" unpacked with wrong size!
  fi
  # end of 'send.c'
fi
if test -f 'update.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'update.doc'\"
else
  echo shar: Extracting \"'update.doc'\" \(12797 characters\)
  sed "s/^X//" >'update.doc' <<'END_OF_FILE'
XChanges leading to version 3.3
X
X1) "Better" handshaking for MODEM7 batch transfers (5/19/87).
X
X2) If reception of a file is aborted due to errors, delete incomplete file
X(5/19/87).
X
X3) If an "impossible" tty speed is detected, assume 1200 bps (5/19/87).
X
X4) Disallow CAN-CAN abort during file send or receive except at beginning of
Xfile transfer (during batch transfers, CAN-CAN abort is allowed at beginning
Xof each file transfer) (5/19/87).
X
X5) Uncouple total allowed errors during the reception of a single packet 
X(ERRORMAX, now made 10) and errors allowed when starting transfer (STERRORMAX, 
Xset to 10) (5/19/87).
X
X6) Fix some bugs when receiving an empty file and when a phase error occurs
Xduring a file reception (5/19/87).
X
X7) Portability fix in prtime and projtime; they also handle pathological
Xcases better (5/19/87).
X
X8) During file reception an EOT is not believed unless it is sent again in
Xresponse to a NAK (5/25/87).
X
X9) Modified cpm_unix and unixify so a filename without an extension will not
Xhave a trailing dot in its filename after being received in a MODEM7 or
XYMODEM batch transfer (5/25/87).
X
X10) Allowable errors during transmission of a single packet now set to
XERRORMAX (5/27/87).
X
X11) When transferring a binary file, the YMODEM file length field is filled
Xin on transmit and (if present) used to truncate the file on reception.
XA new truncate function (truncfile) added to getput.c to do the deed (5/28/87).
XThe file mode field is also set but is ignored on file reception.
X
X12) In a batch receive (xmodem -rt), program can be forced into checksum mode
Xby specifying the "M" flag indicating a MODEM7 transfer (5/30/87).
X
X13) Changed the "B" option to "M" to indicate MODEM7 batch.  Made all option
Xflags case insensitive.  Command line is now recorded in the log file
X(5/30/87).
X
X14) The "KND/IMP" convention of using "CK" to invoke 1K packets during YMODEM
Xbatch transfers was installed.  This code will be sent during a batch receive 
Xif "K" is included on the command line unless "M" is also present.  This code
Xwill be recognized when sending under all circumstances (5/30/87).
X
X------------------------------------------------------------------------------
X
XChanges leading to version 3.4
X
X1) Fix usage message (10/2/87).
X
X2) Sender will now try up to 10 times (EOTMAX) to send an EOT to terminate a
Xtransmission.  Used to be 5 times, but Chuck Forsberg's "official" minimum
Xrequirements for YMODEM mandate 10 (10/2/87).
X
X3) Handle YMODEM file modification times if present in header on reception of
Xboth binary and text files (10/2/87).  Retracted when can't seem to get
Xproper times when playing with dsz (10/3/87).  Found bug and reinstalled
Xfeature (10/16/87).  Found REAL bug (10/21/87).
X
X4) Null bytes are now stripped out of files when received as text files (MEX
Xdoesn't seem to want to put in the terminating control-Z) (10/3/87).
X
X5) Slightly modified terminal parameter setting to explicitly turn off CRMOD
Xand to flush read queue; ideas stolen from Kermit.  Will it fly on Pyramid?
X(10/3/87).
X
X6) Decreased time between "startup" characters sent when starting a file
Xreceive operation.  This should increase perceived response.  Now waits 
XWAITFIRST seconds (set to 1) instead of 6 (waits for 5 seconds for 
Xsubsequent packets.  STERRORMAX now 60, CRCSWMAX now 30.  
XTimeouts on 1st sector no longer reported in log (10/5/87).
X
X7) Once again played with kernel sleeps in readbuf() (packet reading
Xroutine).  On busy system could cause real problems.  Now supply flag (t)
Xto suppress sleeping on Too Busy systems.  No longer suppress sleep when
Xspeeds are over 4800 bps.  Sleep kludge DOES help: on an empty 750 running
X4.3BSD, a file reception at 2400 bps used 6% of the CPU with the sleep
Xkludge and 24% without it (data transfer rates were the the same)
X(10/5/87). 
X
X8) Actually count characters as they are being read for a file reception.
XWhen YMODEM file length is set, stop writing characters when reach length.
XThis will allow YMODEM file lengths to work for text files and the
Xelimination of truncfile() in getput.c (which was impossible for SYS V)
X(10/5/87).
X
X9) Another attempt at tty modes.  Now do nothing but set speeds, set mode to
Xraw, and turn off echoing and tandem (10/6/87).
X
X------------------------------------------------------------------------------
X
XChanges leading to version 3.5
X
X1) Following the suggestion of Bill Carpenter (ho5cad!wjc), I changed every
Xprintf("") to fprintf(stderr, "") so one can use xmodem on either end of unix
Xto unix link. (3/24/88).
X
X2) Again, thanks to Bill Carpenter, corrected typo in stamptime() in
Xgetput.sysv.c (3/24/88).
X
X3) Thanks to Steve Lebowitz (prcpto!pdvshl), fixed a && that should have been
Xa & in getput.sysv.c (3/25/88).
X
X4) Thanks to Leo Pilachowski, who managed to fool xmodem by "preplacing" ACKS
Xin the VAX's input queue (improves throughput by 20%, says Leo, but makes
Xerror recovery a tad dicey...!).  Implemented a flushin() function in
Xgetput.c to flush any pending characters.  flushin is called in send.c just
Xafter sending a packet to make sure a proper ACK or NAK is received (I hope 
Xfast machines don't beat me to it and get their ACKS flushed!).  In
Xreceive.c, flushin is called prior to the "startup" characters, prior to
Xsending the packet acknowledgment ACK and prior to the NAK prompting for
Xconfirming EOT.  Now how does one implement flushin() on Sys V? (3/25/88).
X
X5) Fixed pair of bugs in send.c:  YMODEM test enforcing CRC was testing
Xnumber of attempts against STERRORMAX instead of ERRORMAX (also shortened
Xtimeout interval on this read) and a "timeout" during packet send was not
Xnoticed (due to a > instead of a >=) thus program started sending EOTs which
Xfurther delayed abort (3/28/88).
X
X6) Modified send.c and cpmify function in batch.c to strip path names on file
Xnames transmitted as part of YMODEM batch (3/28/88).
X
X7) Hacked receive.c to make end of loop processing clearer and improve
Xgarbage flushing when errors are detected (3/28/88).
X
X8) Pulled out of decision restricting YMODEM batch send to use CRC only.  Will 
Xnow gladly use checksum if told to and will respond to NAK as well as the 
Xproper C when starting up data transfer (3/28/88).  Turns out this patch fixes 
Xproblem with Red Ryder (4/10/88).
X
X9) Tested MODEM7 batch against MEX-PC.  Confirmation of EOT during filename
Xtransmission was not working, so xmodem wasn't shutting down a MODEM7 batch
Xreceive.  Removed code to NAK first EOT and wait for second EOT in MODEM7
Xfilename transfers (3/28/88).
X
X10) Added code to count number of newlines in a text file to get an accurate
Xfile size.  I thought it would take too long; but seems to be quite nimble
X(see countnl in getput.c).  We now transmit YMODEM file length and mode
Xinformation for text as well as binary files (3/29/88).
X
X11) After a YMODEM file name packet was received, forgot to reset "wait" time
Xfor receiving first character of data packet which definitely slowed
Xperceived performance.  (See note 6 for v. 3.4).  Fixed (4/7/88).
X
X------------------------------------------------------------------------------
X
XChanges leading to version 3.6
X
X1) Added two new major commands (sa and ra) to send and receive text files
Xfor Apple Macintoshs which use CR as EOL character instead of the MS/DOS CR
XLF pair.  Thanks to Dave Nowak (djnowak at iseesun.DPL.SCG.HAC.COM) for the
Xinspiration (4/11/88).
X
X2) Experiences with Red Ryder 10.3.  Fixed botch in receive.c that led to an
Xinfinite loop when a checksum failed on YMODEM file name packet.  Now have
Xseperate variables for packet errors and "startup" errors.  Prevent CRC to
Xchecksum switch during receive startup if YMDMBAT flag is true.  This insures
Xthat no such transition will ever take place on second or subsequent file
Xtransfer; can be set on first file by including Y option on command line.  No
Xlonger print "0" expected sectors if both YMODEM file length and KMD file
Xlength are both 0 (4/12/88).
X
X3) Cleaned up ifs in readbuf.  Removed void declaration on flushin (will
Xbreak 4.2BSD compiler?).  Corrected "number of sent sectors" on YMODEM
Xtransfer (was counting filename packet) (4/12/88).
X
X4) More experiences with Red Ryder.  Removed line flush before every CRCCHR
Xor NAK trying to start a receive (RR YMODEM batch send to the VAX now seems
Xto work).  Fixed KMD "1K reception flag" to work properly on a receive. 
XAdded a flushin just before program exits in a futile effort to eliminate
XRR's nasty habit of sending a final EOT down the line.  Rearranged
Xvariables in send.c so longpackets requested by the KMD flag are not
X"sticky" from file to file in a batch.  RR is a real DOG: only gets about 133
Xcps when downloading to a Mac over a 9600 bps line! (4/14/88). 
X
X------------------------------------------------------------------------------
X
XChanges leading to version 3.7
X
X1) More strange and wonderful PC xmodem programs!  Dave Jaksha's program
Xwon't send send another EOT when first EOT is NAKed.  Raised timeout
Xthreshold from 3 to 5 seconds and fixed silly bug in receive.c that prevented
Xany more NAKs from being sent in this situation (5/10/88).
X
X------------------------------------------------------------------------------
X
XChanges leading to version 3.8
X
X1) Added some fields to YMODEM filename record as per Forsberg's revised
Xspec.  Correct some nits in the way the filename record is handled (11/1/88).
X
X------------------------------------------------------------------------------
X
XChanges leading to version 3.9
X
X1) Better debug message about "packet starting" (10/17/90).
X
X2) Added debug error message when readbyte times out (10/17/90).
X
X3) Now flush input before ACK of received YMODEM filename packet.
X(Will this break Red Ryder? Tough.) (10/17/90).
X
X4) Now explicitly, after receiving YMODEM filename packet, send NAK or
XCRCCHR.  Also, check that output file can be opened before ACKING receipt
Xof YMODEM file name packet.  Both these are required by "True" YMODEM spec.
XAlso, I think this may cure some of the problems seen with various programs
Xtrying YMODEM batch transfers. (10/17/90). 
X
X5) Added some status messages to be printed to stderr under control of the -P
Xflag so we can tell the progress of a transfer when invoked with the "~C"
Xcommand of SunOS tip.  Also added -W flag to slow startup handshake so 
Xfunny characters don't trash input while one is typing the "~C" command string
X(via TIPDELAY define, set to 15 seconds).  Utilizes new tlogit and tlogitarg 
Xmacros. (10/18/90).
X
X6) Made a failure to change the mode bits of the tty a non-fatal error
Xsince, in some systems, uucp owns the device.  Also allows someone who has
Xsu'd to run Xmodem (10/24/90). 
X
X7) Changed error messages about transmissions being canceled "at user's
Xrequest" to "by CAN-CAN" (10/26/90).
X
X8) Go hog-wild with options!  Added "e" option to suppress EOT verification
Xwhen receiving files (should make some brain-damaged PC programs work with
Xxmodem).  Added "n" option to allow CAN-CAN aborts any time during a file
Xtransfer and not just at the beginning.  (10/29/90). 
X
X9) Added a one-liner function (stopsig) to getput.c to ignore keyboard stop
Xsignals so stray ^X characters absorbed during an abort don't put xmodem
Xinto background!  (10/31/90). 
X
X10) Added support for YMODEM-G variant of YMODEM via the "g" flag.
X(11/1/90).
X
X11) Made the "cm" option combination on a receive command force checksum
X"handshaking" during file-name negotiations and CRC-16 use during file
Xtransfer.  Why am I still worried about MODEM7?  (11/1/90).
X
X12) Revised some status messages to indicate that the option (CRC, 1K
Xpackets, YMODEM-G) were invoked from the command line rather than through
X"protocol negotiation."  (11/1/90)
X
X13) Don't send "start-up handshake" character when you get a fatal error in a
Xdata block! (11/2/90)
X
X14) Try to REALLY flush input when die with fatal error in data block. 
XTrying YMODEM-G receptions on a very busy VAX 750 shows up some problems! 
X(11/2/90). 
X
X15) Include a date in the version banner: Version 3.9 (November 1990).
X(11/5/90).
X
X------------------------------------------------------------------------------
X
XThanks to Keith Peterson (w8sdz at simtel20.arpa), John Rupley
X(arizona!rupley!root), Emmet Gray (ihnp4!uiucuxc!fthood!egray), Bob
XBickford (lll-crg!well!rab), Doug Moore (moore at svax.cs.cornell.edu), David
XBrown (jdb at ncsc.arpa), Bill Carpenter (ho5cad!wjc), Steve Lebowitz
X(prcpto!pdvshl), Leo Pilachowski, Dave Nowak
X(djnowak at iseesun.DPL.SCG.HAC.COM), David Elliot (pyramid!boulder!stan!dce),
XBenson Margulis (benson at odi.com), Kit Bingham (kb at umnstat.stat.umn.edu),
XBob Bownes (beowulf!bownes), Bill Stubblebine (hplabs!hp-lsd!was), Chert
XPellett (spdyne!root) and Chuck Forsberg's documents and ZCOMM/DSZ/rz/sz
Xprograms for ideas, suggestions and comments.  Thanks to D'Anne Thompson
Xfor code. 
END_OF_FILE
  if test 12797 -ne `wc -c <'update.doc'`; then
    echo shar: \"'update.doc'\" unpacked with wrong size!
  fi
  # end of 'update.doc'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list