Path: utzoo!utgpu!water!watmath!uunet!lll-winken!pacbell!att!mtune!ethos!pcid!gizzmo!fthood!egray From: egray@fthood.UUCP Newsgroups: unix-pc.sources Subject: xmodem v3.6 (1 of 3) Message-ID: <6800080@fthood> Date: 14 Jul 88 19:09:00 GMT Lines: 1856 Nf-ID: #N:fthood:6800080:000:52716 Nf-From: fthood.UUCP!egray Jul 14 14:09:00 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 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@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 to X and from to 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@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< 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<>(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= 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< 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<>(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= 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< 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<>(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= 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