home *** CD-ROM | disk | FTP | other *** search
- 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
-
-