v07i092: Full-featured XMODEM, Part01/02

sources-request at mirror.TMC.COM sources-request at mirror.TMC.COM
Tue Jan 20 00:08:52 AEST 1987


Submitted by: seismo!noao!grandi (Steve Grandi)
Mod.sources: Volume 7, Issue 92
Archive-name: xmodem/Part01

[  Sorry.  If I vanish again, I'll at least let you folks know.  --r$  ]

: This is a shar archive.  Extract with sh, not csh.
echo x - README
sed -e 's/^X//' > README << '!Funky!Stuff!'
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.
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.
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.
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
X
X
XPlease send bug fixes, additions and comments to:
XSteve Grandi, National Optical Astronomy Observatories (Tucson, Arizona)
X	{ihnp4,seismo,hao,arizona,...}!noao!grandi 
!Funky!Stuff!
echo x - xmodem.1
sed -e 's/^X//' > xmodem.1 << '!Funky!Stuff!'
X.TH XMODEM LOCAL "August 26, 1986"
X.UC 4.2
X.SH NAME
Xxmodem \- Christensen protocol file transfer utility
X.SH SYNOPSIS
X.B xmodem
X[\fBst|sb|rt|rb\fR][\fBYBKcdlx\fR]
X[file...]
X.br
X.SH DESCRIPTION
XThe
X.I xmodem
Xprogram 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 
X.IR xmodem .
XFor details of the protocols,
Xsee the document edited by Chuck Forsberg titled
X.I
XXMODEM/YMODEM Protocol Reference.
X.sp
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.
X.PP
X.SH PARAMETERS
XExactly one of the following must be selected:
X.TP
X.B rb  
XReceive Binary - files are placed on the Unix disk without conversion.
X.I Xmodem
Xwill silently destroy existing files of the same name.
X.TP
X.B rt  
XReceive Text - files are converted from the CP/M format of CR-LF pairs to the Unix
Xconvention of 
X.I newline 
Xcharacters only between lines.  
XBit 8 of each character is stripped (which makes Wordstar files much
Xmore readable).
XThe resulting file
Xis acceptable to the Unix editors and compilers, and is usually slightly
Xsmaller than the original CP/M file.
X.I Xmodem
Xwill silently destroy existing files of the same name.
X.TP
X.B sb  
XSend Binary - files are sent without conversion as they exist on the Unix disk.
X.TP
X.B st  
XSend Text - newline characters in the file are converted to CR-LF pairs
Xin accord with the CP/M conventions for text files.  The file grows
Xslightly as this occurs so the estimate of file transmission size and
Xtime are always optimistically low.
X.PP
X.SH OPTIONS
X.TP
X.B Y
XSelect the YMODEM batch protocol for sending files; a list of files specified
Xon the command line will be sent in sequence.  The YMODEM batch protocol is 
Xused automatically for file reception if the sending program requests it.
X.TP
X.B B
XSelect the MODEM7 batch protocol for sending files; a list of files specified
Xon the command line will be sent in sequence.  The MODEM7 batch protocol is 
Xused automatically for file reception if the sending program requests it.
X.TP
X.B K
XSelect the XMODEM-1K file transfer mode for sending files. Use of 1K packets on
Xlow-error lines increases throughput.  1K packets are automatically
Xused for file reception if the sending program requests it.
X.TP
X.B c   
XSelect the CRC-16 error-checking protocol on receive.  CRC mode is better at catching
Xtransmission errors that occur than the alternative checksum protocol.  
XCRC mode is automatically selected for file
Xtransmission if the receiving modem program requests it.
X.TP
X.B d   
XDelete the 
X.I xmodem.log
Xfile before file transfer is begun.
X.TP
X.B l   
XDo NOT write to the log file.  If logging is selected, a file
X.I xmodem.log 
Xwill be created (or appended to), with entries for significant events, errors
Xand retries.  This can be useful to see why things went wrong
Xwhen they do.
X.TP
X.B x
XToggle on debug mode.  If debug mode is selected, copious and possibly
Xuseful debugging information will be placed in 
X.IR xmodem.log .
X.SH "FILE NAMES"
XFiles transmitted using one of the batch modes
Xwill be stored on the remote machine under a CP/M-ified name (limited
Xto eight characters plus a three character extension; ":" characters will
Xbe turned into "/" characters; all characters will be in monocase).  Files received using one of the batch modes
Xwill be stored under their transmitted names (except that any "/" characters
Xin the file name will be converted into ":" characters and all upper-case
Xcharacters will be translated into lower case).
X.PP
XWhen a batch receive is requested,
X.I xmodem
Xtakes a wait and see attitude and can adapt to either batch protocol or even
Xa classic XMODEM transfer (note that CRC-16 mode is automatically set under
Xthese circumstances).
XIf a classic, "non-batch" XMODEM file reception takes place, 
Xthe received file is stored as
X.IR xmodem.in .
XFile names present on the command line for a batch receive are ignored.
X.SH NOTES
XWhile waiting for the beginning of a transfer or the beginning of a packet,
X.I xmodem
Xtreats two CAN (Cntrl-X) characters that are received within 3 seconds
Xas a request to abort.
X.PP
XSqueezed CP/M files must be transferred in binary mode, even if they
Xcontain text.
X.PP
XIf you use 
X.I xmodem
Xover a 
X.I rlogin
Xlink, you must use the flag
X.IR "rlogin machine -8" .
X.SH EXAMPLES
XTo receive a text file transmitted from a micro (using CRC-16
Xerror-checking) and store it under the
Xname 
X.IR file.name ,
Xuse the command line
X.RS
X.B "xmodem rtc file.name"
X.RE
XNote that if the transmitting program on the micro uses the 1K packet
Xprotocol or either batch protocol,
X.I xmodem
Xdetects this automatically and takes appropriate action.  Further
Xnote that if one of the batch protocols is used, the received file(s)
Xwill be stored under their own names and the name on the command line
X(if any) will be ignored.
X.PP
XTo send a set of text files to a microcomputer using 1K packets and the
XYMODEM batch protocol, use the command line
X.RS
X.B "xmodem stYK *.txt"
X.RE
X.SH FILES
Xxmodem.log (if logging is enabled)
X.SH BUGS
XBatch mode could be smarter about bad file-names in the midst of a
Xbatch transmit/receive.
X.PP
XBatch mode could allow a mixture of binary and text files.
X.PP
XThe file lengths and creation times embedded in the YMODEM batch protocol are
Xneither set on transmit nor used on receive.  However, the "IMP/KMD record
Xcount" field is utilized.
X.SH SEE ALSO
Xkermit(1)
X.SH AUTHOR
XSteve Grandi, National Optical Astronomy Observatories.  Based on
X.I xmodem
Xby Brian Kantor, University of California at San Diego.
XThis, in turn, was based on
X.I umodem
Xby Lauren Weinstein, Richard Conn and others.
!Funky!Stuff!
echo x - Makefile
sed -e 's/^X//' > Makefile << '!Funky!Stuff!'
XOBJECTS = xmodem.o getput.o misc.o send.o receive.o batch.o
XCFLAGS = -O
X
Xxmodem: $(OBJECTS)
X	cc $(CFLAGS) $(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 misc.c Makefile
!Funky!Stuff!
echo x - xmodem.h
sed -e 's/^X//' > xmodem.h << '!Funky!Stuff!'
X#include <ctype.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/time.h>
X#include <sgtty.h>
X#include <signal.h>
X
X/* define macros to print messages in log file */
X#define  logit(string) if(LOGFLAG)fprintf(LOGFP,string)
X#define  logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
X
X#define	     VERSION	32	/* Version Number */
X#define      FALSE      0
X#define      TRUE       1
X
X
X/*  ASCII Constants  */
X#define      SOH  	001 
X#define	     STX	002
X#define	     ETX	003
X#define      EOT	004
X#define	     ENQ	005
X#define      ACK  	006
X#define	     LF		012   /* Unix LF/NL */
X#define	     CR		015  
X#define      NAK  	025
X#define	     SYN	026
X#define	     CAN	030
X#define	     ESC	033
X
X/*  XMODEM Constants  */
X#define      TIMEOUT  	-1
X#define      ERRORMAX  	10    /* maximum errors tolerated */
X#define      NAKMAX	2     /* maximum times to wait for initial NAK when sending */
X#define      RETRYMAX  	5     /* maximum retries to be made */
X#define      CRCSWMAX	4     /* maximum time to try CRC mode before switching */
X#define      KSWMAX	5     /* maximum errors before switching to 128 byte packets */
X#define      SLEEPNUM	100   /* target number of characters to collect during sleepy time */
X#define	     BBUFSIZ	1024  /* buffer size */
X#define      NAMSIZ	11    /* length of a CP/M file name string */
X#define	     CTRLZ	032   /* CP/M EOF for text (usually!) */
X#define      CRCCHR	'C'   /* CRC request character */
X#define      BAD_NAME	'u'   /* Bad filename indicator */
X
X#define      CREATMODE	0644  /* mode for created files */
X
X/* GLOBAL VARIABLES */
X
Xint ttyspeed;		/* tty speed (bits per second) */
Xunsigned char buff[BBUFSIZ];	/* buffer for data */
Xint nbchr;		/* number of chars read so far for buffered read */
Xchar filename[256];	/* place to construct filenames */
XFILE *LOGFP;		/* descriptor for LOG file */
X
X/* option flags and state variables */
Xchar	XMITTYPE;	/* text or binary? */
Xint	DEBUG;		/* keep debugging info in log? */
Xint	RECVFLAG;	/* receive? */
Xint	SENDFLAG;	/* send? */
Xint	BATCH;		/* batch? (Now used as a state variable) */
Xint	CRCMODE;	/* CRC or checksums? */
Xint	DELFLAG;	/* don't delete old log file? */
Xint	LOGFLAG;	/* keep log? */
Xint	LONGPACK; 	/* do not use long packets on transmit? */
Xint	MDM7BAT;	/* MODEM7 batch protocol */
Xint	YMDMBAT;	/* YMODEM batch protocol */
X
X
X/*   CRC-16 constants.  From Usenet contribution by Mark G. Mendel, 
X     Network Systems Corp.  (ihnp4!umn-cs!hyper!mark)
X*/
X
X    /* the CRC polynomial. */
X#define	P	0x1021
X
X    /* number of bits in CRC */
X#define W	16
X
X    /* this the number of bits per char */
X#define B	8
!Funky!Stuff!
echo x - xmodem.c
sed -e 's/^X//' > xmodem.c << '!Funky!Stuff!'
X/*
X *  XMODEM -- Implements the Christensen XMODEM protocol, 
X *            for packetized file up/downloading.    
X *
X *	This version runs on 4.2/4.3BSD ONLY!  It won't work ANYWHERE else.  
X *
X *	I have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty
X *	structures, gettimeofday system call, etc.) in the source file
X *	getput.c; but I make no guarantees.  Also, I have made no attempt to
X *	keep variable names under 7 characters (although a cursory check
X *	shows that all variables are unique within 7 first characters).
X *	The program has been successfully run on VAXes (4.2/4.3BSD) and SUNs
X *	(2.0/3.0) against MEX-PC.
X *
X *   -- Based on UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
X *
X *  XMODEM Version 1.0  - by Brian Kantor, UCSD (3/84)
X *
X *  Version 2.0 (CRC-16 and Modem7 batch file transfer) -- Steve Grandi, NOAO (5/85)
X *
X *  Version 2.1 (1K packets) -- Steve Grandi, NOAO (7/85)
X *
X *  Version 2.2 (general clean-ups and multi-character read speed-ups) -- Steve Grandi, NOAO (9/85)
X *
X *  Version 2.3 (napping while reading packet; split into several source files) -- Steve Grandi, NOAO (1/86)
X *
X *  Version 3.0 (Ymodem batch receive; associated changes) -- Steve Grandi, NOAO (2/86)
X *
X *  Version 3.1 (Ymodem batch send; associated changes) -- Steve Grandi, NOAO (8/86)
X *
X *  Version 3.2 (general cleanups) -- Steve Grandi, NOAO (9/86)
X *
X *  Please send bug fixes, additions and comments to:
X *	{ihnp4,seismo,hao}!noao!grandi 
X */
X
X#include "xmodem.h"
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	char *getenv();
X	FILE *fopen();
X	char *unix_cpm();
X	char *strcpy();
X	char *strcat();
X	
X	char *fname = filename;		/* convenient place to stash file names */
X	char *logfile = "xmodem.log";	/* Name of LOG File */
X	
X	char *stamptime();		/* for timestamp */
X
X	char *defname = "xmodem.in";	/* default file name if none given */
X
X	struct stat filestatbuf;	/* file status info */
X
X	int index;
X	char flag;
X	long expsect;
X
X	/* initialize option flags */
X
X	XMITTYPE = 't';		/* assume text transfer */
X	DEBUG = FALSE;		/* keep debugging info in log */
X	RECVFLAG = FALSE;	/* not receive */
X	SENDFLAG = FALSE;	/* not send either */
X	BATCH = FALSE;		/* nor batch */
X	CRCMODE = FALSE;	/* use checksums for now */
X	DELFLAG = FALSE;	/* don't delete old log file */
X	LOGFLAG = TRUE;		/* keep log */
X	LONGPACK = FALSE; 	/* do not use long packets on transmit */
X	MDM7BAT = FALSE;	/* no MODEM7 batch mode */
X	YMDMBAT = FALSE;	/* no YMODEM batch mode */
X
X	printf("XMODEM Version %d.%d", VERSION/10, VERSION%10);
X	printf(" -- UNIX-CP/M Remote File Transfer Facility\n");
X
X	if (argc == 1)
X		{
X		help();
X		exit(-1);
X		}
X
X	index = 0;		/* set index for flag loop */
X
X	while ((flag = argv[1][index++]) != '\0')
X	    switch (flag) {
X		case '-' : break;
X		case 'x' : DEBUG = TRUE;  /* turn on debugging log */
X			   break;
X		case 'c' : CRCMODE = TRUE; /* enable CRC on receive */
X			   break;
X		case 'd' : DELFLAG = TRUE;  /* delete log file */
X			   break;
X		case 'l' : LOGFLAG = FALSE;  /* turn off log  */
X			   break;
X		case 'B' : MDM7BAT = TRUE;  /* turn on MODEM7 batch protocol */
X			   BATCH   = TRUE;
X			   break;
X		case 'Y' : YMDMBAT = TRUE;  /* turn on YMODEM batch protocol */
X			   BATCH   = TRUE;
X			   break;
X		case 'K' : LONGPACK = TRUE;  /* use 1K packets on transmit */
X			   break;
X		case 'r' : RECVFLAG = TRUE;  /* receive file */
X			   XMITTYPE = gettype(argv[1][index++]);  /* get t/b */
X			   break;
X		case 's' : SENDFLAG = TRUE;  /* send file */
X			   XMITTYPE = gettype(argv[1][index++]);
X			   break;
X		default  : printf ("Invalid Flag %c ignored\n", flag);
X			   break;
X	   }
X
X	if (DEBUG)
X		LOGFLAG = TRUE;
X
X	if (LOGFLAG)
X	   { 
X	     if ((fname = getenv("HOME")) == 0)	/* Get HOME variable */
X		error("Fatal - Can't get Environment!", FALSE);
X	     fname = strcat(fname, "/");
X	     fname = strcat(fname, logfile);
X	     if (!DELFLAG)
X		LOGFP = fopen(fname, "a");  /* append to LOG file */
X	     else
X		LOGFP = fopen(fname, "w");  /* new LOG file */
X	     if (!LOGFP)
X		error("Fatal - Can't Open Log File", FALSE);
X
X	     fprintf(LOGFP,"\n++++++++  %s", stamptime());
X	     fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
X	   }
X
X	getspeed();		/* get tty-speed for time estimates */
X
X	if (RECVFLAG && SENDFLAG)
X		error("Fatal - Both Send and Receive Functions Specified", FALSE);
X
X	if (MDM7BAT && YMDMBAT)
X		error("Fatal - Both YMODEM and MODEM7 Batch Protocols Specified", FALSE);
X
X	if (!RECVFLAG && !SENDFLAG)
X		error("Fatal - Either Send or Receive Function must be chosen!",FALSE);
X	
X	if (SENDFLAG && argc==2)
X		error("Fatal - No file specified to send",FALSE);
X
X	if (RECVFLAG && argc==2)
X		{
X		CRCMODE = TRUE;		/* assume we really want CRC-16 in batch */
X		printf("Ready for BATCH RECEIVE");
X		printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X		printf("Send several Control-X characters to cancel\n");
X		logit("Batch Receive Started");
X		logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X		strcpy(fname, defname);
X		}
X
X	if (RECVFLAG && argc>2)
X		{
X		if(open(argv[2], 0) != -1)  /* check for overwriting */
X			{
X			logit("Warning -- Target File Exists and is Being Overwritten\n");
X			printf("Warning -- Target File Exists and is Being Overwritten\n");
X			}
X		printf("Ready to RECEIVE File %s", argv[2]);
X		printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X		printf("Send several Control-X characters to cancel\n");
X		logitarg("Receiving in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X		strcpy(fname,argv[2]);
X		}
X
X	if (RECVFLAG)
X		{  
X		setmodes();		/* set tty modes for transfer */
X
X		while(rfile(fname) != FALSE);  /* receive files */
X
X		restoremodes(FALSE);	/* restore normal tty modes */
X
X		sleep(2);		/* give other side time to return to terminal mode */
X		exit(0);
X		}
X
X	if (SENDFLAG && BATCH) 
X		{
X		if (YMDMBAT)
X			{
X			printf("Ready to YMODEM BATCH SEND");
X			printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X			logit("YMODEM Batch Send Started");
X			logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X			}
X		else if (MDM7BAT)
X			{
X			printf("Ready to MODEM7 BATCH SEND");
X			printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X			logit("MODEM7 Batch Send Started");
X			logitarg(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X			}
X		printf("Send several Control-X characters to cancel\n");
X
X		setmodes();
X		for (index=2; index<argc; index++) {
X			if (stat(argv[index], &filestatbuf) < 0) {
X				logitarg("\nFile %s not found\n", argv[index]);
X				continue;
X			}
X			sfile(argv[index]);
X		}
X		sfile("");
X		restoremodes(FALSE);
X
X		logit("Batch Send Complete\n");
X		sleep(2);
X		exit (0);
X		}
X
X	if (SENDFLAG && !BATCH) 
X		{
X		if (stat(argv[2], &filestatbuf) < 0)
X			error("Can't find requested file", FALSE);
X		expsect = (filestatbuf.st_size/128)+1;
X			
X		printf("File %s Ready to SEND", argv[2]);
X		printf(" in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X		printf("Estimated File Size %ldK, %ld Records, %ld Bytes\n",
X	    	  (filestatbuf.st_size/1024)+1, expsect,
X	  	  filestatbuf.st_size);
X		projtime(expsect, stdout);
X		printf("Send several Control-X characters to cancel\n");
X		logitarg("Sending in %s mode\n", (XMITTYPE == 't') ? "text" : "binary");
X
X		setmodes();
X		sfile(argv[2]);
X		restoremodes(FALSE);
X
X		sleep(2);
X		exit(0);
X		}
X}
!Funky!Stuff!
echo x - getput.c
sed -e 's/^X//' > getput.c << '!Funky!Stuff!'
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/*   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/* 
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*/
X
X/* This routine is VERY 4.2 specific */
X
Xint
Xreadbuf(bufsize, seconds, tmode, checksum, bufctr)
X
Xint bufsize,	/* number of chars to be read */
Xseconds, 	/* timeout period for each read */
Xtmode, 		/* transmission mode: TRUE if text, FALSE if binary */
X*checksum, 	/* pointer to checksum value */
X*bufctr;	/* length of actual data string in buffer */
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 = 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
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
X				if (CRCMODE)  /* CRC */
X					chksm = (chksm<<B) ^ crctab[(chksm>>(W-B)) ^ c];
X
X				else        /* checksum */
X		       			chksm = ((chksm+c) & 0xff);
X
X				/* binary mode */
X				if (!tmode)
X					{  
X					bfctr++;
X		       			continue;
X		       			}
X
X				/* text mode */
X				buff[bfctr] &= 0x7f; /* nuke bit 8 */
X				if (c == CR)       /* skip CR's */
X				continue;
X				if (c == CTRLZ)  /* CP/M EOF char */
X					{  
X					recfin = TRUE;
X		       			continue;
X		       			}
X		       		if (!recfin)
X					bfctr++;
X		     	}	
X
X		/* go to sleep to save uneeded system calls while kernel
X		   is reading data from serial line; forget this when we
X		   running at 9600 bps; also fudge constant from 10000 to
X		   9000 to avoid sleeping too long
X		*/
X		if (ttyspeed < 9600)
X			napms ( (left<SLEEPNUM ? left:SLEEPNUM) * 9000/ttyspeed);
X	}
X
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 */
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	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	/* transfer current modes to new structure */
X	ttysnew.sg_ispeed = ttys.sg_ispeed;	/* copy input speed */
X	ttysnew.sg_ospeed = ttys.sg_ospeed;	/* copy output speed */
X	ttysnew.sg_erase  = ttys.sg_erase;	/* copy erase flags */
X	ttysnew.sg_flags  = ttys.sg_flags;	/* copy flags */
X 	ttysnew.sg_kill   = ttys.sg_kill;	/* copy std terminal flags */
X
X	ttysnew.sg_flags |= RAW;    /* set for RAW Mode */
X	ttysnew.sg_flags &= ~ECHO;  /* set for no echoing */
X	ttysnew.sg_flags &= ~XTABS;  /* set for no tab expansion */
X	ttysnew.sg_flags &= ~LCASE;  /* set for no upper-to-lower case xlate */
X	ttysnew.sg_flags |= ANYP;  /* set for ANY Parity */
X	ttysnew.sg_flags &= ~NL3;  /* turn off ALL 3s - new line */
X	ttysnew.sg_flags &= ~TAB2; /* turn off tab 3s */
X	ttysnew.sg_flags &= ~CR3;  /* turn off CR 3s */
X	ttysnew.sg_flags &= ~FF1;  /* turn off FF 3s */
X	ttysnew.sg_flags &= ~BS1;  /* turn off BS 3s */
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	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,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, 1200, 1800,
X			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	ttyspeed = speedtbl[ttys.sg_ispeed];
X	logitarg ("Line speed = %d bits per second\n", ttyspeed);
X	}
X
!Funky!Stuff!
exit



More information about the Mod.sources mailing list