xmodem v3.6 (1 of 3)

egray at fthood.UUCP egray at fthood.UUCP
Fri Jul 15 05:09:00 AEST 1988


Hello netlanders!

Here is Steve Grandi's xmodem version 3.6.  (I've once again taken the
stand that cross posting source from comp.source.* to unix-pc.source is
justified and generally a good idea.)

I've made a few changes to suit my tastes, but did it in such a way that
you can choose the flavor of xmodem by editing the Makefile.  There is a
Readme.local file that describes the changes I've made.

Emmet P. Gray				US Army, HQ III Corps & Fort Hood
...!uunet!uiucuxc!fthood!egray		Attn: AFZF-DE-ENV
					Directorate of Engineering & Housing
					Environmental Management Office
					Fort Hood, TX 76544-5057

-----------------------------------------------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Header
#	README
#	Readme.local
#	Makefile
#	batch.c
#	getput.bsd.c
#	getput.c
#	getput.sysv.c
# This archive created: Thu Jul 14 13:12:40 1988
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'Header'" '(1427 characters)'
if test -f 'Header'
then
	echo shar: "will not over-write existing file 'Header'"
else
sed 's/^X//' << \SHAR_EOF > 'Header'
XSubmitted-by: Steve Grandi <grandi at noao.arizona.edu>
XPosting-number: Volume 15, Issue 70
XArchive-name: xmodem3.6/part01
X
X
XHere is version 3.6 of my Unix "full-featured" xmodem program.  It
Xincorporates fixes and enhancements from people who used it when it was
Xlast posted in March.  Since that version was posted with missing pieces,
XI'm submitting this version rather quickly so the "archives" will have a
Xcomplete version.
X
XAfter unpacking, you should have the following files:
X
X-rw-r--r--  1 grandi        933 Apr 14 15:01 Makefile
X-rw-r--r--  1 grandi       4367 Apr 14 07:56 README
X-rw-r--r--  1 grandi       4735 Mar 28 15:25 batch.c
X-rw-r--r--  1 grandi      12045 Apr 14 06:57 getput.c
X-rw-r--r--  1 grandi      10898 Apr 13 10:37 getput.sysv.c
X-rw-r--r--  1 grandi       4076 Apr 11 08:59 misc.c
X-rw-r--r--  1 grandi      12880 Apr 14 07:15 receive.c
X-rw-r--r--  1 grandi       9886 Apr 14 10:07 send.c
X-rw-r--r--  1 grandi      14301 Jan  7 14:30 tip.diffs
X-rw-r--r--  1 grandi       9209 Apr 14 09:41 update.doc
X-rw-r--r--  1 grandi       7948 Apr 14 07:53 xmodem.1
X-rw-r--r--  1 grandi       6834 Apr 14 07:19 xmodem.c
X-rw-r--r--  1 grandi       3240 Apr 11 07:39 xmodem.h
X
XSteve Grandi, National Optical Astronomy Observatories, Tucson AZ, 602-325-9228
XUUCP: {arizona,decvax,ncar,ihnp4}!noao!grandi or uunet!noao.arizona.edu!grandi
XInternet: grandi at noao.arizona.edu    SPAN/HEPNET: 5355::GRANDI or NOAO::GRANDI
X
X
SHAR_EOF
if test 1427 -ne "`wc -c < 'Header'`"
then
	echo shar: "error transmitting 'Header'" '(should have been 1427 characters)'
fi
fi
echo shar: "extracting 'README'" '(4367 characters)'
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XThis is version 3.6 (finished 4/88) of the xmodem program which includes a
Xfew bugfixes and some enhancements (requested by Macintosh users)
Xstimulated by the xmodem release through comp.sources.unix.  See the file
Xupdate.doc for details. 
X
X--------------------------------------------------------------------------------
X
XThis is version 3.4 (finished 10/87) of the xmodem program, a full-featured
XXMODEM implementation for 4.3BSD.  Since the previous release (version
X3.2, see volume 7 of the archives), substantial improvements have been
Xmade. See the file update.doc for details.  Also, some attempt has been
Xmade to support SysV Unix systems; see below.
X
XAs far as I am concerned, this program has reached the end of its evolution.
XNewer protocols (such as ZMODEM) will not be incorporated into xmodem.  Check
Xout Chuck Forsberg's rz/sz programs if you are interested in ZMODEM.
X
XTo answer one oft-asked question: No, I don't know how to tie this
Xfull-featured xmodem program into tip or cu for file transfers when calling
Xout from a 4.3BSD system.  4.3BSD tip does have some undocumented hooks
Xfor tying into other programs through redirecting file descriptors, but my
Xminimal attempts to utilize these hooks have failed.  However, several
Xyears back, I built a VERY early version of xmodem (lacking XMODEM/CRC,
XXMODEM-1K, MODEM7 batch or YMODEM) directly into 4.2BSD tip.  The changes
Xworked unmodified in 4.3BSD; the diff files are contained in the file
Xtip.diffs.
X
X--------------------------------------------------------------------------------
X
XThe xmodem program implements the Christensen (XMODEM) file transfer
Xprotocol for moving files between 4.2/4.3BSD Unix systems and microcomputers.
XThe XMODEM/CRC protocol, the MODEM7 batch protocol, the XMODEM-1K
Xblock protocol and the YMODEM batch protocol are all supported by xmodem.
XFor details of the protocols, see the document edited by Chuck Forsberg titled
XXMODEM/YMODEM Protocol Reference (the latest version is dated 8-4-87).
X
XThis program runs on 4.2/4.3BSD systems ONLY.  It has been tested on VAXes
Xand Suns against the MEX-PC program from Niteowl Software and the ZCOMM and
XDSZ programs from Omen Technology.
X
XI have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty structures,
Xgettimeofday system call, etc.) confined to the source file getput.c; but I 
Xmake no guarantees.  Also, I have made no attempt to keep variable names 
Xunder 7 characters.  A version of getput.c that MAY work on Sys V Unix
Xsystems is included.
X
X--------------------------------------------------------------------------------
X
XThanks to Emmet Gray (ihnp4!uiucuxc!fthood!egray) and John Rupley 
X(arizona!rupley!root) for the following notes about converting xmodem to Sys V.
XSince I don't have a Sys V system to test a Sys V version, I won't even try.
X
X1) Change the includes in xmodem.h from <sys/time.h> to <time.h>
X   and from <sgtty.h> to <termio.h>
X
X2) Convert the occurrences of rindex to strrchr in batch.c
X
X3) Substitute getput.sysv.c for getput.c
X
X--------------------------------------------------------------------------------
X
XProgram history:
X
XDescended from UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
X
XBased on XMODEM Version 1.0 by Brian Kantor, UCSD (3/84)  (Don't blame him 
Xfor what follows....)
X
XVersion 2.0 (CRC-16 and Modem7 batch file transfer) (5/85)
X
XVersion 2.1 (1K packets) (7/85)
X
XVersion 2.2 (general clean-ups and multi-character read speed-ups) (9/85)
X
XVersion 2.3 (nap while reading packets; split into several source files) (1/86)
X
XVersion 3.0 (Ymodem batch receive; associated changes) (2/86)
X
XVersion 3.1 (Ymodem batch send; associated changes) (8/86)
X
XVersion 3.2 (general cleanups) (9/86) 
X    (Released to the world 1/87)
X
XVersion 3.3 (general fixes and cleanups; see update.doc) (5/87)
X
XVersion 3.4 (general fixes and cleanups; see update.doc) (10/87) 
X    (Released to the world 3/88)
X
XVersion 3.5 (general fixes and cleanups; see update.doc) (3/88)
X
XVersion 3.6 (general fixes and cleanups; text file translation for Mac; 
X    see update.doc) (4/88) 
X    (Released to the world 4/88)
X
X--------------------------------------------------------------------------------
X
XPlease send bug fixes, additions and comments to:
XSteve Grandi, National Optical Astronomy Observatories (Tucson, Arizona)
X	{ihnp4,ncar,arizona,...}!noao!grandi  grandi at noao.arizona.edu
SHAR_EOF
if test 4367 -ne "`wc -c < 'README'`"
then
	echo shar: "error transmitting 'README'" '(should have been 4367 characters)'
fi
fi
echo shar: "extracting 'Readme.local'" '(1035 characters)'
if test -f 'Readme.local'
then
	echo shar: "will not over-write existing file 'Readme.local'"
else
sed 's/^X//' << \SHAR_EOF > 'Readme.local'
XHello netlanders!
X
XThis is Steve Grandi's xmodem version 3.6 with a few enhancements and
Xlocal modifications.  You can pick and choose the flavor of xmodem
Xyou want by editing the Makefile preprocessor definitons:
X
X	SYSV		Compile for AT&T Unix system V and friends.
X
X	NOCLOBBER	If not a batch protocol, prompt the user before
X			overwriting an existing file.  If batch, create
X			unique names.
X
X	LOCAL		Change a bunch of default settings:
X
X			1) binary xfers assumed, 'b' option is optional.
X			2) CRC is assumed, 'c' option is now for checksum
X			3) loging defaults to off, 'l' turns it on.
X
XThe manual page with a lower case 'l' is edited to reflect the NOCLOBBER
Xand LOCAL options.
X
XFor users of the AT&T Unix PC 7300/3b1, there is a line in the Makefile
Xthat will allow the program to be compiled with shared libraries.
X
XEmmet P. Gray				US Army, HQ III Corps & Fort Hood
X...!uunet!uiucuxc!fthood!egray		Attn: AFZF-DE-ENV
X					Directorate of Engineering & Housing
X					Environmental Management Office
X					Fort Hood, TX 76544-5057
SHAR_EOF
if test 1035 -ne "`wc -c < 'Readme.local'`"
then
	echo shar: "error transmitting 'Readme.local'" '(should have been 1035 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(1141 characters)'
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
XOBJECTS = xmodem.o getput.o misc.o send.o receive.o batch.o
XLDFLAGS = -s
X#CFLAGS = -O
X# see the Readme.local file for what these do.
XCFLAGS = -O -DSYSV -DNOCLOBBER -DLOCAL
X
Xxmodem: $(OBJECTS)
X# for users of AT&T Unix PC 7300/3b1
X	$(LD) $(LDFLAGS) $(OBJECTS) /lib/crt0s.o /lib/shlib.ifile -o xmodem
X#	cc $(LDFLAGS) $(OBJECTS) -o xmodem
X
X$(OBJECTS): xmodem.h
X
Xprint: 
X	lpr -p -Pvmslp xmodem.h xmodem.c getput.c receive.c send.c batch.c \
X	misc.c Makefile update.doc README xmodem.1 getput.sysv.c
X
Xlint:
X	lint xmodem.c getput.c receive.c send.c batch.c misc.c | imprint
X
Xshar:
X	shar README update.doc Makefile xmodem.1 xmodem.h > xmodem.shar.1
X	shar xmodem.c receive.c misc.c > xmodem.shar.2
X	shar getput.c getput.sysv.c > xmodem.shar.3
X	shar batch.c send.c > xmodem.shar.4
X	shar tip.diffs > xmodem.shar.5
X
Xbigshar: 
X	shar README update.doc Makefile xmodem.1 xmodem.h xmodem.c getput.c \
X	getput.sysv.c receive.c misc.c batch.c send.c tip.diffs > xmodem.shar
X
Xtarz: 
X	tar cvf xmodem.tar README update.doc Makefile xmodem.1 xmodem.h \
X	xmodem.c getput.c getput.sysv.c receive.c misc.c batch.c send.c \
X	tip.diffs ymodem.doc
X	compress xmodem.tar
SHAR_EOF
if test 1141 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 1141 characters)'
fi
fi
echo shar: "extracting 'batch.c'" '(5485 characters)'
if test -f 'batch.c'
then
	echo shar: "will not over-write existing file 'batch.c'"
else
sed 's/^X//' << \SHAR_EOF > 'batch.c'
X/*
X *  Various routines for batch transfer
X */
X
X#include "xmodem.h"
X
X/* make sure filename sent or received in YMODEM batch is canonical. */
X
X/* Incoming: Turn Unix '/' into CP/M ':' and translate to all lower case.
X * Remove trailing dot.
X */
X
Xunixify (name)
Xchar *name;
X	{
X	char *ptr;
X
X	/* change '/' to ':' and convert to lower case */
X	for (ptr=name; *ptr; ++ptr)
X		{
X		if (*ptr == '/')
X			*ptr = ':';
X		if (isupper (*ptr))
X			*ptr |= 040;
X		}
X
X	/* remove trailing dot if present */
X	ptr--;
X	if (*ptr == '.')
X		*ptr = '\0';
X#ifdef NOCLOBBER
X	chg_name(name);
X#endif /* NOCLOBBER */
X	}
X
X/* make sure filename sent or received in YMODEM batch is canonical. */
X
X/* Outgoing: Turn ':' into '/' (for symmetry!) and turn into all lower case.
X * Remove everything before last '/'.  Use "filename" to hold final name.
X */
X
Xchar *
Xcpmify (name)
Xchar *name;
X	{
X	char *ptr, *slash;
X	char *strcpy();
X
X	/* find last '/' and copy rest of name */
X
X	slash = name;
X	for (ptr=name; *ptr; ++ptr)
X		if (*ptr == '/')
X			slash = ptr + 1;
X	strcpy (filename, slash);
X
X	/* change ':' to '/' and covert to all lower case */
X
X	for (ptr=filename; *ptr; ++ptr)
X		{
X		if (*ptr == ':')
X			*ptr = '/';
X		if (isupper (*ptr))
X			*ptr |= 040;
X		}
X	return (filename);
X	}
X
X
X/* convert a CP/M file name received in a MODEM7 batch transfer
X * into a unix file name mapping '/' into ':', converting to all
X * upper case and adding dot in proper place.  
X * Use "filename" to hold name.
X * Code stolen from D. Thompson's (IRTF) xmodem.c
X */
X
Xchar *
Xcpm_unix (string)
Xunsigned char *string;
X{
X	register int i;
X	unsigned char *iptr, temp;
X	register char *optr;
X
X	if (*string == '\0')
X		error("Null file name in MODEM7 batch receive", TRUE);
X
X	for (iptr=string; (temp = *iptr) ; ) {
X		temp &= 0177;			/* strips bit 7 */
X		if (isupper(temp))
X			temp |= 040;		/* set bit 5 for lower case */
X		if (temp == '/') 
X			temp=':';		/* map / into : */
X		*iptr++ = temp;
X	}
X
X	/* put in main part of name */
X	iptr=string;
X	optr=filename;
X	for (i=0; i<8; i++) {
X		if (*iptr != ' ')
X			*optr++ = *iptr++;
X	}
X
X	/* add dot if necessary */
X	if (string[8] != ' ' || string[9] != ' ' || string[10] != ' ')
X		*optr++ = '.';
X
X	/* put in extension */
X	iptr = &string[8];
X	for (i=0; i<3; i++) {
X		if (*iptr != ' ')
X			*optr++ = *iptr++;
X	}
X
X	*optr++ = '\000';
X#ifdef NOCLOBBER
X	chg_name(filename);
X#endif /* NOCLOBBER */
X	return (filename);
X}
X
X/* Send 11 character CP/M filename for MODEM7 batch transmission
X * Returns -1 for a protocol error; 0 if successful
X * NOTE: we tromp a little on the argument string!
X * code stolen from D. Thompson's (IRTF) xmodem.c
X */
X
Xsend_name(name)
Xchar *name;
X{
X	register int cksum;
X	register char *ptr;
X
X	xmdebug("send_name");
X
X	/* append cp/m EOF */
X	name[NAMSIZ] = CTRLZ;
X	name[NAMSIZ+1] = '\000';
X
X	/* create checksum */
X	ptr = name;
X	cksum = 0;
X	while (*ptr)
X		cksum += *ptr++;
X	cksum &= 0x00FF;
X
X	/* send filename */
X
X	sendbyte(ACK);
X	ptr = name;
X	sendbyte(*ptr++);
X
X	while (*ptr) {
X
X			switch (readbyte(15)) {
X
X			case ACK: break;
X
X			case TIMEOUT: {
X				logit("Timeout while sending MODEM7 filename\n");
X				sendbyte(BAD_NAME);
X				return (-1);
X			}
X
X			default: {
X				logit("Error while sending MODEM7 filename\n");
X				sendbyte(BAD_NAME);
X				return (-1);
X			}
X		}	
X
X		sendbyte (*ptr++);
X	}
X
X	/* Check checksum returned by other side against my value */
X	if (readbyte(16) != cksum) {
X		logit("Bad checksum while sending MODEM7 filename\n");
X		sendbyte(BAD_NAME);
X		return (-1);
X	}
X
X	sendbyte(ACK);
X	return (0);
X}
X
X/* Convert Unix filename to 11 character CP/M file name (8 char name,
X * 3 char extension, dot in between is not included).
X * map ':' into '/'; Use filename to hold name.
X * code stolen from D. Thompson's (IRTF) xmodem.c
X */
X
Xchar *
Xunix_cpm(string)
Xchar *string;
X{
X	register char *iptr, *optr, temp;
X	int i;
X
X	char *rindex();
X	char *strcpy();
X
X	/* blank 11 character name */
X	(void) strcpy (filename,"           ");
X
X	/* strip off any path name */
X	if ((iptr = rindex(string,'/')))
X		iptr++;
X	else
X		iptr=string;
X
X	/* skip leading '.'s */
X	while (*iptr == '.')
X		iptr++;
X
X	/* copy main part of name */
X	optr = filename;
X	i = 8;
X	while ((i--) && (*iptr) && (*iptr != '.'))
X		*optr++ = *iptr++;
X
X	/* advance to unix extension, or end of unix name */
X	while ((*iptr != '.') && (*iptr))
X		iptr++;
X
X	/* skip over the  '.' */
X	while (*iptr == '.')
X		iptr++;
X
X	/* copy extension */
X	optr = &filename[8];
X	i=3;
X	while ((i--) && (*iptr) && (*iptr != '.'))
X		*optr++ = *iptr++;
X
X	filename[NAMSIZ] = '\000';
X
X	/* Fuss with name */
X	for (iptr=filename; (temp = *iptr) ;) {
X		temp &= 0177;			/* strip bit 7 (parity bit) */
X		if (islower(temp))
X			temp &= ~040;		/* make upper case */
X		if (temp == ':')
X			temp ='/';		/* map ':' into '/' */
X		*iptr++ = temp;
X	}
X
X	if (DEBUG)
X		fprintf (LOGFP, "DEBUG: File %s sent as %s\n", string, filename);
X
X	return(filename);
X}
X
X#ifdef NOCLOBBER
X/*
X * Handle file name collisions.  Prepend an 'X' to the name until you find
X * a name that doesn't already exist.
X */
X
Xchg_name(str)
Xchar *str;
X{
X	register int i;
X	char temp[15], ans[15], *s, *rindex(), *strcpy(), *strncat();
X
X					/* dissect the name component */
X	if ((s = rindex(str, '/')))
X		strcpy(temp, s++);
X	else
X		strcpy(temp, str);
X
X	strcpy(ans, temp);
X					/* prepend up to 13 'X's */
X	for (i=1; i<14; i++) {
X		if (access(ans, 0)) {
X			strcpy(str, ans);
X			return(0);
X		}
X
X		strcpy(temp, "X");
X		strncat(temp, ans, 13);
X		temp[14] = NULL;
X		strcpy(ans, temp);
X	}
X	return(-1);
X}
X#endif /* NOCLOBBER */
SHAR_EOF
if test 5485 -ne "`wc -c < 'batch.c'`"
then
	echo shar: "error transmitting 'batch.c'" '(should have been 5485 characters)'
fi
fi
echo shar: "extracting 'getput.bsd.c'" '(12045 characters)'
if test -f 'getput.bsd.c'
then
	echo shar: "will not over-write existing file 'getput.bsd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getput.bsd.c'
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		return(TIMEOUT);
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	/* get tty status */ 
X	if (stat(tty, &statbuf) < 0)  
X		error("Can't get your TTY Status", TRUE);
X
X	if (statbuf.st_mode & 022)	/* Need to turn messages off */
X		if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
X			error("Can't change  TTY mode", TRUE);
X		else 
X			wason = TRUE;
X	else 
X		wason = FALSE;
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	}
SHAR_EOF
if test 12045 -ne "`wc -c < 'getput.bsd.c'`"
then
	echo shar: "error transmitting 'getput.bsd.c'" '(should have been 12045 characters)'
fi
fi
echo shar: "extracting 'getput.c'" '(10863 characters)'
if test -f 'getput.c'
then
	echo shar: "will not over-write existing file 'getput.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getput.c'
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		return(TIMEOUT);
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 status */ 
X		error("Can't get your TTY Status", TRUE);
X
X	if (statbuf.st_mode & 022)	/* Need to turn messages off */
X		if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
X			error("Can't change  TTY mode", TRUE);
X		else 
X			wason = TRUE;
X	else 
X		wason = FALSE;
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)<=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	}
SHAR_EOF
if test 10863 -ne "`wc -c < 'getput.c'`"
then
	echo shar: "error transmitting 'getput.c'" '(should have been 10863 characters)'
fi
fi
echo shar: "extracting 'getput.sysv.c'" '(10863 characters)'
if test -f 'getput.sysv.c'
then
	echo shar: "will not over-write existing file 'getput.sysv.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getput.sysv.c'
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		return(TIMEOUT);
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 status */ 
X		error("Can't get your TTY Status", TRUE);
X
X	if (statbuf.st_mode & 022)	/* Need to turn messages off */
X		if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
X			error("Can't change  TTY mode", TRUE);
X		else 
X			wason = TRUE;
X	else 
X		wason = FALSE;
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)<=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	}
SHAR_EOF
if test 10863 -ne "`wc -c < 'getput.sysv.c'`"
then
	echo shar: "error transmitting 'getput.sysv.c'" '(should have been 10863 characters)'
fi
fi
exit 0
#	End of shell archive



More information about the Unix-pc.sources mailing list