home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume15
/
xmodem3.6
/
part02
< prev
next >
Wrap
Text File
|
1988-06-13
|
25KB
|
932 lines
Subject: v15i071: Xmodem release 3.6, Part02/05
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Steve Grandi <grandi@noao.arizona.edu>
Posting-number: Volume 15, Issue 71
Archive-name: xmodem3.6/part02
: This is a shar archive. Extract with sh, not csh.
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 * See the README file for some notes on SYS V adaptations.
X * The program has been successfully run on VAXes (4.3BSD) and SUN-3/4s
X * (SunOS 3.x) against MEX-PC and ZCOMM/DSZ.
X *
X * See the README and update.doc files for history and change notes.
X *
X * Please send bug fixes, additions and comments to:
X * {ihnp4,ncar}!noao!grandi grandi@noao.arizona.edu
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 char *prtype();
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 TOOBUSY = FALSE; /* not too busy for sleeping in packet read */
X
X fprintf(stderr, "XMODEM Version %d.%d", VERSION/10, VERSION%10);
X fprintf(stderr, " -- UNIX-Microcomputer 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' :
X case 'x' : DEBUG = TRUE; /* turn on debugging log */
X break;
X case 'C' :
X case 'c' : CRCMODE = TRUE; /* enable CRC on receive */
X break;
X case 'D' :
X case 'd' : DELFLAG = TRUE; /* delete log file */
X break;
X case 'L' :
X case 'l' : LOGFLAG = FALSE; /* turn off log */
X break;
X case 'm' :
X case 'M' : MDM7BAT = TRUE; /* turn on MODEM7 batch protocol */
X BATCH = TRUE;
X break;
X case 'y' :
X case 'Y' : YMDMBAT = TRUE; /* turn on YMODEM batch protocol */
X BATCH = TRUE;
X break;
X case 'k' :
X case 'K' : LONGPACK = TRUE; /* use 1K packets on transmit */
X break;
X case 't' :
X case 'T' : TOOBUSY = TRUE; /* turn off sleeping */
X break;
X case 'R' :
X case 'r' : RECVFLAG = TRUE; /* receive file */
X XMITTYPE = gettype(argv[1][index++]); /* get t/b */
X break;
X case 'S' :
X case 's' : SENDFLAG = TRUE; /* send file */
X XMITTYPE = gettype(argv[1][index++]);
X break;
X default : fprintf(stderr, "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 fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
X for (index=2; index<argc; ++index)
X fprintf(LOGFP, " %s", argv[index]);
X fprintf(LOGFP, "\n");
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 /* assume we really want CRC-16 in batch, unless we specify MODEM7 mode */
X CRCMODE = MDM7BAT ? FALSE : TRUE;
X fprintf(stderr, "Ready for BATCH RECEIVE");
X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
X fprintf(stderr, "Send several Control-X characters to cancel\n");
X logit("Batch Receive Started");
X logitarg(" in %s mode\n", prtype(XMITTYPE));
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 fprintf(stderr, "Warning -- Target File Exists and is Being Overwritten\n");
X }
X fprintf(stderr, "Ready to RECEIVE File %s", argv[2]);
X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
X fprintf(stderr, "Send several Control-X characters to cancel\n");
X logitarg("Receiving in %s mode\n", prtype(XMITTYPE));
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 flushin();
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 fprintf(stderr, "Ready to YMODEM BATCH SEND");
X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
X logit("YMODEM Batch Send Started");
X logitarg(" in %s mode\n", prtype(XMITTYPE));
X }
X else if (MDM7BAT)
X {
X fprintf(stderr, "Ready to MODEM7 BATCH SEND");
X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
X logit("MODEM7 Batch Send Started");
X logitarg(" in %s mode\n", prtype(XMITTYPE));
X }
X fprintf(stderr, "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 flushin();
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 fprintf(stderr, "File %s Ready to SEND", argv[2]);
X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
X fprintf(stderr, "Estimated File Size %ldK, %ld Sectors, %ld Bytes\n",
X (filestatbuf.st_size/1024)+1, expsect,
X filestatbuf.st_size);
X projtime(expsect, stdout);
X fprintf(stderr, "Send several Control-X characters to cancel\n");
X logitarg("Sending in %s mode\n", prtype(XMITTYPE));
X
X setmodes();
X sfile(argv[2]);
X flushin();
X restoremodes(FALSE);
X
X sleep(2);
X exit(0);
X }
X}
!Funky!Stuff!
echo x - receive.c
sed -e 's/^X//' > receive.c << '!Funky!Stuff!'
X#include "xmodem.h"
X
X/** receive a file **/
X
X/* returns TRUE if in the midst of a batch transfer */
X/* returns FALSE if no more files are coming */
X
X/* This routine is one HUGE do-while loop with far to many indented levels.
X * I chose this route to facilitate error processing and to avoid GOTOs.
X * Given the troubles I've had keeping the nested IF statements straight,
X * I was probably mistaken...
X */
X
Xrfile(name)
Xchar *name;
X{
X
Xchar *sectdisp();
Xchar *cpm_unix();
Xchar *strcpy();
Xchar *ctime();
Xtime_t time();
X
Xint fd, /* file descriptor for created file */
Xchecksum, /* packet checksum */
Xfirstchar, /* first character of a packet */
Xsectnum, /* number of last received packet (modulo 128) */
Xsectcurr, /* second byte of packet--should be packet number (mod 128) */
Xsectcomp, /* third byte of packet--should be complement of sectcurr */
Xtmode, /* text mode if true */
Xamode, /* apple mode if true */
Xerrors, /* count of errors for each packet */
Xsterrors, /* count of errors during startup handshake */
Xerrorflag, /* set true when packet (or first char of putative packet) is invalid */
Xfatalerror, /* set within main "read-packet" Do-While when bad error found */
Xinchecksum, /* incoming checksum or CRC */
Xexpsect, /* expected number of sectors (YMODEM batch) */
Xfirstwait, /* seconds to wait for first character in a packet */
Xbufsize; /* packet size (128 or 1024) */
Xlong recvsectcnt; /* running sector count (128 byte sectors) */
Xlong modtime; /* Unix style file mod time from YMODEM header */
Xint filemode; /* Unix style file mode from YMODEM header */
Xlong readbackup; /* "backup" value for characters read in file */
Xtime_t timep[2]; /* used in setting mod time of received file */
Xchar *p; /* generic pointer */
Xint bufctr; /* number of real chars in read packet */
Xunsigned char *nameptr; /* ptr in filename for MODEM7 protocol */
Xtime_t start; /* starting time of transfer */
Xint openflag = FALSE; /* is file open for writing? */
X
Xlogit("----\nXMODEM File Receive Function\n");
Xif (CRCMODE)
Xlogit("CRC mode requested\n");
X
XBATCH = FALSE; /* don't know if really are in batch mode ! */
Xfatalerror = FALSE;
Xfirstwait = WAITFIRST; /* For first packet, wait short time */
Xsectnum = errors = recvsectcnt = 0;
Xbufsize = 128;
Xmodtime = 0l; filemode = 0;
Xfilelength = 0l; fileread =0l; CHECKLENGTH = FALSE;
X
Xtmode = (XMITTYPE == 't') ? TRUE : FALSE;
Xamode = (XMITTYPE == 'a') ? TRUE : FALSE;
X
X/* start up transfer */
X
Xsterrors = 0;
Xflushin(); /* flush input queue */
X
Xif (CRCMODE)
X{
X sendbyte(CRCCHR);
X if (LONGPACK && !MDM7BAT)
X sendbyte(KCHR);
X}
Xelse
X sendbyte(NAK);
X
X
Xdo /* start of MAIN Do-While loop to read packets */
X{
X errorflag = FALSE;
X do /* start by reading first byte in packet */
X {
X firstchar = readbyte(firstwait);
X }
X while ((firstchar != SOH)
X && (firstchar != STX)
X && (firstchar != EOT)
X && (firstchar != ACK || recvsectcnt > 0)
X && (firstchar != TIMEOUT)
X && (firstchar != CAN || recvsectcnt > 0));
X
X if (firstchar == EOT) /* check for REAL EOT */
X {
X flushin();
X sendbyte(NAK); /* NAK the EOT */
X if ((firstchar = readbyte(3)) != EOT) /* check next character */
X {
X logit("Spurious EOT detected; ignored\n");
X if ((firstchar == SOH) || (firstchar == STX) ||
X (firstchar == ACK && recvsectcnt == 0) ||
X (firstchar == CAN && recvsectcnt == 0) ||
X (firstchar == TIMEOUT))
X break;
X else
X {
X firstchar = 0;
X errorflag = TRUE;
X }
X }
X }
X
X if (firstchar == TIMEOUT) /* timeout? */
X {
X if (recvsectcnt > 0)
X logitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1));
X errorflag = TRUE;
X }
X
X if (firstchar == CAN) /* bailing out? (only at beginning) */
X {
X if ((readbyte(3) & 0x7f) == CAN)
X error("Reception canceled at user's request",TRUE);
X else
X {
X errorflag = TRUE;
X logit("Received single CAN character\n");
X }
X }
X
X if (firstchar == ACK) /* MODEM7 batch? (only at beginning) */
X {
X int i,c;
X
X logit("MODEM7 Batch Protocol\n");
X nameptr = buff;
X checksum = 0;
X
X for (i=0; i<NAMSIZ; i++)
X {
X c = readbyte(3);
X
X if (c == CAN)
X {
X if (readbyte(3) == CAN)
X error("Program Canceled by User", TRUE);
X else
X {
X logit("Received single CAN character in MODEM7 filename\n");
X errorflag = TRUE;
X break;
X }
X }
X
X if (c == EOT && i == 0)
X {
X sendbyte(ACK); /* acknowledge EOT */
X logit("MODEM7 Batch Receive Complete\n");
X return (FALSE);
X }
X
X if (c == TIMEOUT)
X {
X logit("Timeout waiting for MODEM7 filename character\n");
X errorflag = TRUE;
X break;
X }
X
X if (c == BAD_NAME)
X {
X logit("Error during MODEM7 filename transfer\n");
X errorflag = TRUE;
X break;
X }
X
X *nameptr++ = c;
X checksum += c;
X sendbyte(ACK);
X }
X
X if (!errorflag)
X {
X c = readbyte(3);
X if (c == CTRLZ) /* OK; end of string found */
X {
X sendbyte(checksum + CTRLZ);
X if (readbyte(15) == ACK) /* file name found! */
X {
X xmdebug("MODEM7 file name OK");
X *nameptr = '\000'; /* unixify the file name */
X name = cpm_unix(buff);
X BATCH = TRUE;
X logitarg("MODEM7 file name: %s\n", name);
X errors = 0; /* restart crc handshake */
X sleep(2); /* give other side a chance */
X }
X else
X {
X logit("Checksum error in MODEM7 filename\n");
X errorflag = TRUE;
X }
X }
X else
X {
X logit("Length error in MODEM7 filename\n");
X errorflag = TRUE;
X }
X }
X }
X
X
X if (firstchar == SOH || firstchar == STX) /* start reading packet */
X {
X bufsize = (firstchar == SOH) ? 128 : 1024;
X
X if (recvsectcnt == 0) /* 1st data packet, initialize */
X {
X if (bufsize == 1024)
X logit("1K packet mode chosen\n");
X start = time((time_t *) 0);
X errors = 0;
X firstwait = 5;
X }
X
X sectcurr = readbyte(3);
X sectcomp = readbyte(3);
X if ((sectcurr + sectcomp) == 0xff) /* is packet number checksum correct? */
X {
X if (sectcurr == ((sectnum+1) & 0xff)) /* is packet number correct? */
X {
X if (DEBUG)
X fprintf(LOGFP,"DEBUG: packet %d started\n", sectnum);
X
X /* Read, process and calculate checksum for a buffer of data */
X
X readbackup = fileread;
X if (readbuf(bufsize, 1, tmode, amode, recvsectcnt, &checksum, &bufctr) != TIMEOUT)
X {
X
X /* verify checksum or CRC */
X
X if (CRCMODE)
X {
X checksum &= 0xffff;
X inchecksum = readbyte(3); /* get 16-bit CRC */
X inchecksum = (inchecksum<<8) | readbyte(3);
X }
X
X else
X inchecksum = readbyte(3); /* get simple 8-bit checksum */
X
X if (inchecksum == checksum) /* good checksum, hence good packet */
X {
X xmdebug("checksum ok");
X errors = 0;
X recvsectcnt += (bufsize == 128) ? 1 : 8;
X sectnum = sectcurr;
X
X if (!openflag) /* open output file if necessary */
X {
X openflag = TRUE;
X if ((fd = creat(name, CREATMODE)) < 0)
X {
X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X error("Can't create file for receive", TRUE);
X }
X if (!BATCH)
X logitarg("File Name: %s\n", name);
X }
X
X if (write(fd, (char *) buff, bufctr) != bufctr)
X {
X close(fd);
X unlink(name);
X error("File Write Error", TRUE);
X }
X else
X {
X flushin(); /* flush input */
X sendbyte(ACK); /* ACK the received packet */
X }
X }
X
X /* Start handling various errors and special conditions */
X
X else /* bad checksum */
X {
X logitarg("Checksum Error on Sector %s: ", sectdisp(recvsectcnt,bufsize,1));
X logitarg("sent=%x ", inchecksum);
X logitarg("recvd=%x\n", checksum);
X fileread = readbackup;
X errorflag = TRUE;
X }
X }
X
X else /* read timeout */
X {
X logitarg("Timeout while reading sector %s\n",sectdisp(recvsectcnt,bufsize,1));
X fileread = readbackup;
X errorflag = TRUE;
X }
X }
X
X else /* sector number is wrong OR Ymodem filename */
X {
X if (sectcurr == 0 && recvsectcnt == 0) /* Ymodem file-name packet */
X {
X logit("YMODEM Batch Protocol\n");
X
X /* Read and process a file-name packet */
X
X if (readbuf(bufsize, 1, FALSE, FALSE, recvsectcnt, &checksum, &bufctr) != TIMEOUT)
X {
X
X /* verify checksum or CRC */
X
X if (CRCMODE)
X {
X checksum &= 0xffff;
X inchecksum = readbyte(3); /* get 16-bit CRC */
X inchecksum = (inchecksum<<8) | readbyte(3);
X }
X
X else
X inchecksum = readbyte(3); /* get simple 8-bit checksum */
X
X if (inchecksum == checksum) /* good checksum, hence good filename */
X {
X xmdebug("checksum ok");
X strcpy(name, (char *)buff);
X expsect = ((buff[bufsize-1]<<8) | buff[bufsize-2]);
X BATCH = TRUE;
X YMDMBAT = TRUE;
X if (strlen(name) == 0) /* check for no more files */
X {
X flushin(); /* flush input */
X sendbyte(ACK); /* ACK the packet */
X logit("YMODEM Batch Receive Complete\n");
X return (FALSE);
X }
X unixify(name); /* make filename canonical */
X
X /* read rest of YMODEM header */
X p = (char *)buff + strlen((char *)buff) + 1;
X sscanf(p, "%ld%lo%o", &filelength, &modtime, &filemode);
X logitarg("YMODEM file name: %s\n", name);
X fileread = 0l;
X if (filelength)
X {
X CHECKLENGTH = TRUE;
X logitarg("YMODEM file size: %ld\n", filelength);
X }
X else if (expsect)
X logitarg("YMODEM estimated file length %d sectors\n", expsect);
X if (modtime)
X {
X logitarg("YMODEM file date: %s", ctime(&modtime));
X }
X if (filemode)
X logitarg("YMODEM file mode: %o", filemode);
X
X sendbyte(ACK); /* ACK the packet */
X firstwait = WAITFIRST; /* reset to negotiate */
X }
X
X else /* bad filename checksum */
X {
X logit("checksum error on filename sector\n");
X errorflag = TRUE;
X }
X }
X else
X {
X logit("Timeout while reading filename packet\n");
X errorflag = TRUE;
X }
X }
X
X else if (sectcurr == sectnum) /* duplicate sector? */
X {
X logitarg("Duplicate sector %s flushed\n", sectdisp(recvsectcnt,bufsize,0));
X flushin(); /* REALLY flush input */
X while(readbyte(1) != TIMEOUT)
X ;
X sendbyte(ACK);
X }
X else /* no, real phase error */
X {
X logitarg("Phase Error - Expected packet is %s\n", sectdisp(recvsectcnt,bufsize,1));
X errorflag = TRUE;
X fatalerror = TRUE;
X }
X }
X }
X
X else /* bad packet number checksum */
X {
X logitarg("Header Sector Number Error on Sector %s\n", sectdisp(recvsectcnt, bufsize,1));
X errorflag = TRUE;
X }
X
X } /* END reading packet loop */
X
X if (errorflag && !fatalerror && recvsectcnt != 0) /* Handle errors */
X {
X errors++;
X
X if (errors >= ERRORMAX) /* over error limit? */
X fatalerror = TRUE;
X else /* flush input and NAK the packet */
X {
X flushin();
X while (readbyte(1) != TIMEOUT) /* wait for line to settle */
X ;
X sendbyte(NAK);
X }
X }
X
X if (recvsectcnt == 0 && errorflag && firstchar != EOT) /* handle startup handshake */
X {
X sterrors++;
X
X if (sterrors >= STERRORMAX)
X fatalerror = TRUE;
X
X else if (CRCMODE && sterrors == CRCSWMAX && !YMDMBAT)
X {
X CRCMODE = FALSE;
X logit("Sender not accepting CRC request, changing to checksum\n");
X sendbyte(NAK);
X }
X
X else if (!CRCMODE && sterrors == CRCSWMAX && !YMDMBAT)
X {
X CRCMODE = TRUE;
X logit("Sender not accepting checksum request, changing to CRC\n");
X sendbyte(CRCCHR);
X if (LONGPACK && !MDM7BAT)
X sendbyte(KCHR);
X }
X
X else if (CRCMODE)
X {
X sendbyte(CRCCHR);
X if (LONGPACK && !MDM7BAT)
X sendbyte(KCHR);
X }
X
X else
X sendbyte(NAK);
X }
X}
Xwhile ((firstchar != EOT) && !fatalerror); /* end of MAIN Do-While */
X
Xif ((firstchar == EOT) && !fatalerror) /* normal exit? */
X{
X if (openflag) /* close the file */
X close(fd);
X sendbyte(ACK); /* ACK the EOT */
X logit("Receive Complete\n");
X prtime (recvsectcnt, time((time_t *) 0) - start);
X
X if (openflag && modtime) /* set file modification time */
X {
X timep[0] = time((time_t *) 0);
X timep[1] = modtime;
X utime(name, timep);
X }
X
X if (BATCH) /* send appropriate return code */
X return(TRUE);
X else
X return(FALSE);
X}
Xelse /* no, error exit */
X{
X if (openflag)
X {
X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X close(fd);
X unlink(name);
X error("ABORTED -- Too Many Errors--deleting file", TRUE);
X }
X else if (recvsectcnt != 0)
X error("ABORTED -- Too Many Errors", TRUE);
X else
X error("ABORTED -- Remote system is not responding", TRUE);
X}
Xreturn(FALSE);
X
X}
!Funky!Stuff!
echo x - misc.c
sed -e 's/^X//' > misc.c << '!Funky!Stuff!'
X#include "xmodem.h"
X
X/* Print Help Message */
Xhelp()
X {
X fprintf(stderr, "\nUsage: \n\txmodem ");
X fprintf(stderr, "-[rb!rt!ra!sb!st!sa][options] filename\n");
X fprintf(stderr, "\nMajor Commands --");
X fprintf(stderr, "\n\trb <-- Receive Binary");
X fprintf(stderr, "\n\trt <-- Receive Text");
X fprintf(stderr, "\n\tra <-- Receive Apple macintosh text");
X fprintf(stderr, "\n\tsb <-- Send Binary");
X fprintf(stderr, "\n\tst <-- Send Text");
X fprintf(stderr, "\n\tsa <-- Send Apple macintosh text");
X fprintf(stderr, "\nOptions --");
X fprintf(stderr, "\n\ty <-- Use YMODEM Batch Mode on transmit");
X fprintf(stderr, "\n\tm <-- Use MODEM7 Batch Mode on transmit");
X fprintf(stderr, "\n\tk <-- Use 1K packets on transmit");
X fprintf(stderr, "\n\tc <-- Select CRC mode on receive");
X fprintf(stderr, "\n\tt <-- Indicate a TOO BUSY Unix system");
X fprintf(stderr, "\n\td <-- Delete xmodem.log file before starting");
X fprintf(stderr, "\n\tl <-- (ell) Turn OFF Log File Entries");
X fprintf(stderr, "\n\tx <-- Include copious debugging information in log file");
X fprintf(stderr, "\n");
X }
X
X/* get type of transmission requested (text or binary) */
Xgettype(ichar)
Xchar ichar;
X {
X if (ichar == 't' || ichar == 'T')
X return('t');
X else if (ichar == 'b' || ichar == 'B')
X return('b');
X else if (ichar == 'a' || ichar == 'A')
X return('a');
X else
X error("Invalid Send/Receive Parameter - not t or b", FALSE);
X return('\0');
X }
X
X/* return a string containing transmission type */
Xchar *
Xprtype(ichar)
Xchar ichar;
X {
X if (ichar == 't' || ichar == 'T')
X return("text");
X else if (ichar == 'b' || ichar == 'B')
X return("binary");
X else if (ichar == 'a' || ichar == 'A')
X return("apple");
X else
X return("");
X }
X
X/* print error message and exit; if mode == TRUE, restore normal tty modes */
Xerror(msg, mode)
Xchar *msg;
Xint mode;
X {
X if (mode)
X restoremodes(TRUE); /* put back normal tty modes */
X fprintf(stderr, "\r\n%s\n", msg);
X if ((LOGFLAG || DEBUG) && (LOGFP != NULL))
X {
X fprintf(LOGFP, "XMODEM Fatal Error: %s\n", msg);
X fclose(LOGFP);
X }
X exit(-1);
X }
X
X
X/* Construct a proper (i.e. pretty) sector count for messages */
X
Xchar
X*sectdisp(recvsectcnt, bufsize, plus1)
Xlong recvsectcnt;
Xint bufsize, plus1;
X {
X static char string[20];
X if (plus1)
X recvsectcnt += (bufsize == 128) ? 1 : 8;
X if (bufsize == 128 || recvsectcnt == 0)
X sprintf (string, "%d", recvsectcnt);
X else
X sprintf (string, "%d-%d", recvsectcnt-7, recvsectcnt);
X return(string);
X }
X
X/* type out debugging info */
Xxmdebug(str)
Xchar *str;
X {
X if (DEBUG && (LOGFP != NULL))
X fprintf(LOGFP,"DEBUG: '%s'\n",str);
X }
X
X/* print elapsed time and rate of transfer in logfile */
X
Xint quant[] = { 60, 60, 24};
Xchar sep[3][10] = { "second", "minute", "hour" };
X
Xprtime (numsect, seconds)
Xlong numsect;
Xtime_t seconds;
X
X{
X register int i;
X register int Seconds;
X int nums[3];
X int rate;
X
X if (!LOGFLAG || numsect == 0)
X return(0);
X
X Seconds = (int)seconds;
X Seconds = (Seconds > 0) ? Seconds : 0;
X
X rate = (Seconds != 0) ? 128 * numsect/Seconds : 0;
X
X for (i=0; i<3; i++) {
X nums[i] = (Seconds % quant[i]);
X Seconds /= quant[i];
X }
X
X fprintf (LOGFP, "%ld Sectors Transfered in ", numsect);
X
X if (rate == 0)
X fprintf (LOGFP, "0 seconds");
X else
X while (--i >= 0)
X if (nums[i])
X fprintf (LOGFP, "%d %s%c ", nums[i], &sep[i][0],
X nums[i] == 1 ? ' ' : 's');
X fprintf (LOGFP, "\n");
X
X if (rate != 0)
X fprintf (LOGFP, "Transfer Rate = %d Characters per Second\n", rate);
X
X return(0);
X}
X
X/* Print elapsed time estimate */
X
Xprojtime (numsect, fd)
Xlong numsect;
XFILE *fd;
X {
X register int i;
X register int seconds;
X int nums[3];
X
X if (numsect == 0)
X return (0);
X
X/* constant below should really be 1280; reduced to 90% to account for time lost in overhead */
X
X seconds = 1422 * numsect / ttyspeed + 1;
X
X for (i=0; i<3; i++) {
X nums[i] = (seconds % quant[i]);
X seconds /= quant[i];
X }
X
X fprintf (fd, "Estimated transmission time ");
X
X while (--i >= 0)
X if (nums[i])
X fprintf (fd, "%d %s%c ", nums[i], &sep[i][0],
X nums[i] == 1 ? ' ' : 's');
X fprintf (fd, "\n");
X return (0);
X }
!Funky!Stuff!
exit