Submitted-by: michaeli@stout.atd.ucar.edu Archive-name: xmodem/part03 #!/bin/sh # this is xmodem.03 (part 3 of xmodem) # do not concatenate these parts, unpack them in order with /bin/sh # file xmodem/getput.c continued # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo 'WARNING: not restoring timestamps' fi rm -f 1231235999 $$.touch # if test ! -r _sharseq.tmp; then echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sharseq.tmp` if test "$shar_sequence" != 3; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping xmodem/getput.c' else echo 'x - continuing file xmodem/getput.c' sed 's/^X//' << 'SHAR_EOF' >> 'xmodem/getput.c' && X X } X X if (CHECKLENGTH && fileread >= filelength) X logitarg("File end from YMODEM length found in sector %s\n", X sectdisp(recvsectcnt,bufsize,1)); X *checksum = chksm; X *bufctr = bfctr; X return(0); } X /* send a byte to data stream */ X void sendbyte(char 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 /* send a buffer to data stream */ X void writebuf(char *buffer, int 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 * "nap" for specified time -- VERY vxWorks specific X */ X void napms (int milliseconds) { X if (milliseconds == 0) X return; X if (DEBUG) X fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds); X taskDelay((sysClkRateGet() * milliseconds) / 1000); X } X X /* set and restore tty modes for XMODEM transfers */ /* These routines are VERY vxWorks specific */ X int ttyOptions, ttyNewOptions; /* vxWorks tty options */ SIGVEC origSignal, newSignal; X void setmodes(void) X { X X extern void onintr(); X X sleep(2); /* let the output appear */ X X /* vxWorks change - the original options captured in stopsig */ X X ioctl(0, FIOSETOPTIONS, OPT_RAW); X X /* Flush characters waiting for read or write */ X if (ioctl(0, FIOFLUSH,0) != 0) X { X logit("Can't flush terminal queue\n"); X tlogit("Can't flush terminal queue\n"); X } X X /* set up signal catcher to restore tty state if we are KILLed */ X X sigvec(SIGTERM, (SIGVEC *) NULL, &origSignal); X newSignal.sv_handler = onintr; X newSignal.sv_mask = 0; X newSignal.sv_flags = 0; X sigvec(SIGTERM, &newSignal, NULL); X } X /* restore normal tty modes */ X void restoremodes(int errcall) X { X if (ioctl(0,FIOSETOPTIONS, ttyOptions) != 0) X { 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 sigvec(SIGTERM, &origSignal, NULL); X return; X } X X X X /* signal catcher */ void onintr() X { X error("Kill signal; bailing out", TRUE); X } X /* create string with a timestamp for log file */ X char *stamptime() { X /* Completely unconventional calls I generated X * for my own uses. X */ X return rtcConvUnixTime(rtcUnixTime((time_t *) 0)); } X X X /* get tty speed for time estimates */ X void getspeed(void) X { X /* This routine needs some more work in vxWorks. X There is no system call to get the value. X Should be pretty easy to create one though... X X Also, using 1200 baud even though I plan on using this X at 9600 baud. X */ X ttyspeed = ERROR; /* ioctl(0, FIOGET_BAUDRATE, 0); */ X if (ttyspeed == ERROR) X { X ttyspeed = 1200; X logit ("Can't determine line speed; assuming 1200 bps\n"); X } X } X X /* turn off keyboard stop signal so stray ^X doesn't restart vxWorks */ X void stopsig(void) X { X ttyOptions = ioctl(0, FIOGETOPTIONS,0); X ttyNewOptions = ttyOptions & ~OPT_MON_TRAP; X ioctl(0, FIOSETOPTIONS, ttyNewOptions); X } X SHAR_EOF echo 'File xmodem/getput.c is complete' && $shar_touch -am 0812110694 'xmodem/getput.c' && chmod 0644 'xmodem/getput.c' || echo 'restore of xmodem/getput.c failed' shar_count="`wc -c < 'xmodem/getput.c'`" test 11162 -eq "$shar_count" || echo "xmodem/getput.c: original size 11162, current size $shar_count" rm -f _sharnew.tmp fi # ============= xmodem/receive.c ============== if test -f 'xmodem/receive.c' && test X"$1" != X"-c"; then echo 'x - skipping xmodem/receive.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting xmodem/receive.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xmodem/receive.c' && #include "xmodem.h" X /** receive a file **/ X /* returns TRUE if in the midst of a batch transfer */ /* returns FALSE if no more files are coming */ 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 /* External and forward references */ X extern void flushin(void); extern void sendbyte(char); extern int readbyte(int); extern void error(char *, int); extern void xmdebug(char *); extern int readbuf(int, int, int, int, long, int *, int *); extern void unixify(char *); extern void reallyflush(void); extern int prtime(long, time_t, FILE *); X int rfile(char *name) { X char *sectdisp(); char *cpm_unix(); char *strcpy(); X int fd, /* file descriptor for created file */ checksum, /* packet checksum */ firstchar, /* first character of a packet */ sectnum, /* number of last received packet (modulo 128) */ sectcurr, /* second byte of packet--should be packet number (mod 128) */ sectcomp, /* third byte of packet--should be complement of sectcurr */ tmode, /* text mode if true */ amode, /* apple mode if true */ errors, /* count of errors for each packet */ sterrors, /* count of errors during startup handshake */ errorflag, /* set true when packet (or first char of putative packet) is invalid */ fatalerror, /* set within main "read-packet" Do-While when bad error found */ inchecksum, /* incoming checksum or CRC */ expsect, /* expected number of sectors (YMODEM batch) */ firstwait, /* seconds to wait for first character in a packet */ nocancanabort, /* if true, don't allow CAN-CAN abort */ bufsize; /* packet size (128 or 1024) */ long recvsectcnt; /* running sector count (128 byte sectors) */ long modtime; /* Unix style file mod time from YMODEM header */ int filemode; /* Unix style file mode from YMODEM header */ int serial; /* serial # from YMODEM header */ int filesleft; /* # of files left from YMODEM header */ long totalleft; /* # of bytes left from YMODEM header */ int yfiletype; /* file type from YMODEM header */ long readbackup; /* "backup" value for characters read in file */ time_t timep[2]; /* used in setting mod time of received file */ char *p; /* generic pointer */ int bufctr; /* number of real chars in read packet */ unsigned char *nameptr; /* ptr in filename for MODEM7 protocol */ time_t start; /* starting time of transfer */ int openflag = FALSE; /* is file open for writing? */ X logit("----\nXMODEM File Receive Function\n"); tlogit("----\nXMODEM File Receive Function\n"); if (CRCMODE) X { X logit("CRC mode requested on command line\n"); X tlogit("CRC mode requested on command line\n"); X } X if (YMODEMG) X { X logit("YMODEM-G mode requested on command line\n"); X tlogit("YMODEM-G mode requested on command line\n"); X } X BATCH = FALSE; /* don't know if really are in batch mode ! */ fatalerror = FALSE; firstwait = WAITFIRST; /* For first packet, wait short time */ sectnum = errors = recvsectcnt = 0; bufsize = 128; modtime = 0l; filemode = 0; serial = 0; filesleft = 0; totalleft = 0l; yfiletype = 0; filelength = 0l; fileread =0l; CHECKLENGTH = FALSE; nocancanabort = FALSE; X tmode = (XMITTYPE == 't') ? TRUE : FALSE; amode = (XMITTYPE == 'a') ? TRUE : FALSE; X /* start up transfer */ X sterrors = 0; flushin(); /* flush input queue */ X if (YMODEMG) X sendbyte(GCHR); else if (CRCMODE && !MDM7BAT) { X sendbyte(CRCCHR); X if (LONGPACK && !MDM7BAT) X sendbyte(KCHR); } else X sendbyte(NAK); X X do /* start of MAIN Do-While loop to read packets */ { 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 || nocancanabort)); X X if (firstchar == EOT && !NOEOT) /* check for REAL EOT */ X { X flushin(); X sendbyte(NAK); /* NAK the EOT */ X if ((firstchar = readbyte(5)) != EOT) /* check next character */ X { X logit("Spurious EOT detected; ignored\n"); X tlogit("Spurious EOT detected; ignored\n"); X if ((firstchar == SOH) || (firstchar == STX) || X (firstchar == ACK && recvsectcnt == 0) || X (firstchar == CAN && !nocancanabort) || X (firstchar == TIMEOUT)) X ; X else X { X firstchar = 0; X errorflag = TRUE; X } X } X } X X if (firstchar == TIMEOUT) /* timeout? */ X { X if (recvsectcnt > 0) X { X logitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1)); X tlogitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1)); X } X errorflag = TRUE; X } X X if (firstchar == CAN) /* bailing out? (only at beginning or if CANCAN flag set) */ X { X if ((readbyte(3) & 0x7f) == CAN) X { X if (openflag) X { X close(fd); X unlink(name); X error("Reception Canceled by CAN-CAN; partial file deleted",TRUE); X } X else X error("Reception Canceled by CAN-CAN",TRUE); X } X else X { X errorflag = TRUE; X logit("Received single CAN character\n"); X tlogit("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 tlogit("MODEM7 Batch Protocol\n"); X nameptr = buff; X checksum = 0; X X for (i=0; i= ERRORMAX) /* over error limit? */ X fatalerror = TRUE; X else /* flush input and NAK the packet */ X { X reallyflush(); X sendbyte(NAK); X } X } X X if (recvsectcnt == 0 && errorflag && !fatalerror && firstchar != EOT) /* handle startup handshake */ X { X sterrors++; X firstwait = WAITFIRST + sterrors; X X if (sterrors >= STERRORMAX) X fatalerror = TRUE; X X else if (CRCMODE && MDM7BAT && !BATCH) X sendbyte(NAK); X X else if (CRCMODE && sterrors == CRCSWMAX && !YMDMBAT) X { X CRCMODE = FALSE; X logit("Sender not accepting CRC request, changing to checksum\n"); X tlogit("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 tlogit("Sender not accepting checksum request, changing to CRC\n"); X sendbyte(CRCCHR); X if (LONGPACK && !MDM7BAT) X sendbyte(KCHR); X } X X else if (YMODEMG) X sendbyte(GCHR); X X else if (CRCMODE) X { X sendbyte(CRCCHR); X if (LONGPACK && !MDM7BAT) X sendbyte(KCHR); X } X X else X sendbyte(NAK); X } } while ((firstchar != EOT) && !fatalerror); /* end of MAIN Do-While */ X if ((firstchar == EOT) && !fatalerror) /* normal exit? */ { X if (openflag) /* close the file */ X close(fd); X sendbyte(ACK); /* ACK the EOT */ X logit("Receive Complete\n"); X tlogit("Receive Complete\n"); X if (LOGFLAG) X prtime (recvsectcnt, time((time_t *) 0) - start, LOGFP); X if (TIPFLAG) X prtime (recvsectcnt, time((time_t *) 0) - start, stderr); X X if (openflag && modtime) /* set file modification time */ X { X /* NO vxWorks capability to easily set file mod time now */ 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); } else /* no, error exit */ { X if (openflag) X { X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); X close(fd); X unlink(name); X reallyflush(); /* wait for line to settle */ X error("ABORTED -- Too Many Errors -- Deleting File", TRUE); X } X else if (recvsectcnt != 0) X { X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); X reallyflush(); /* wait for line to settle */ X error("ABORTED -- Too Many Errors", TRUE); X } X else X { X reallyflush(); /* wait for line to settle */ X error("ABORTED -- Remote system is not responding", TRUE); X } X } X return(FALSE); } SHAR_EOF $shar_touch -am 0812084894 'xmodem/receive.c' && chmod 0644 'xmodem/receive.c' || echo 'restore of xmodem/receive.c failed' shar_count="`wc -c < 'xmodem/receive.c'`" test 18033 -eq "$shar_count" || echo "xmodem/receive.c: original size 18033, current size $shar_count" rm -f _sharnew.tmp fi # ============= xmodem/misc.c ============== if test -f 'xmodem/misc.c' && test X"$1" != X"-c"; then echo 'x - skipping xmodem/misc.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting xmodem/misc.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xmodem/misc.c' && #include "xmodem.h" /* forward and external references */ void error(char *, int); extern void restoremodes(int); extern void flushin(void); extern int readbyte(int); X /* Print Help Message */ void xmhelp(void) X { X fprintf(stderr, "Usage: \txmodem "); X fprintf(stderr, " -[rb!rt!ra!sb!st!sa][options] filename... 0\n"); X fprintf(stderr, "Major 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\tg <-- Select YMODEM-G Mode on receive"); 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\tp <-- Use with SunOS tip ~C command"); X fprintf(stderr, "\n\tw <-- Wait before initial handshake"); X fprintf(stderr, "\n\te <-- Supress EOT confirmation"); X fprintf(stderr, "\n\tn <-- Allow mid-transfer CAN-CAN aborts"); X fprintf(stderr, "\n"); X } X /* get type of transmission requested (text or binary) */ int gettype(char 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", TRUE); /* was false */ X return('\0'); X } X /* return a string containing transmission type */ char *prtype(char 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 /* print error message and exit; if mode == TRUE, restore normal tty modes */ extern jmp_buf xmEnv; void error(char *msg, int 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 longjmp(xmEnv, -1); /* was an exit(-1) */ X } X X /* Construct a proper (i.e. pretty) sector count for messages */ X char *sectdisp(long recvsectcnt, int bufsize, int 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 /* type out debugging info */ void xmdebug(char *str) X { X if (DEBUG && (LOGFP != NULL)) X fprintf(LOGFP,"DEBUG: '%s'\n",str); X } X /* print elapsed time and rate of transfer in logfile */ X int quant[] = { 60, 60, 24}; char sep[3][10] = { "second", "minute", "hour" }; X int prtime (long numsect, time_t seconds, FILE *fileid) X { X register int i; X register int Seconds; X int nums[3]; X int rate; X X if (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 (fileid, "%ld Sectors Transfered in ", numsect); X X if (rate == 0) X fprintf (fileid, "0 seconds"); X else X while (--i >= 0) X if (nums[i]) X fprintf (fileid, "%d %s%c ", nums[i], &sep[i][0], X nums[i] == 1 ? ' ' : 's'); X fprintf (fileid, "\n"); X X if (rate != 0) X fprintf (fileid, "Transfer Rate = %d Characters per Second\n", rate); X X return(0); } X /* Print elapsed time estimate */ X int projtime (long numsect, FILE *fd) X { X register int i; X register int seconds; X int nums[3]; X X if (numsect == 0) X return (0); 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 } X /* Really flush input by waiting for line to clear */ X void reallyflush(void) { X if (DEBUG) X fprintf(LOGFP,"DEBUG: Waiting for line to clear\n"); flushin(); while(readbyte(1) != TIMEOUT) X ; if (DEBUG) X fprintf(LOGFP,"DEBUG: Line is clear\n"); } SHAR_EOF $shar_touch -am 0812084894 'xmodem/misc.c' && chmod 0644 'xmodem/misc.c' || echo 'restore of xmodem/misc.c failed' shar_count="`wc -c < 'xmodem/misc.c'`" test 4810 -eq "$shar_count" || echo "xmodem/misc.c: original size 4810, current size $shar_count" rm -f _sharnew.tmp fi # ============= xmodem/batch.c ============== if test -f 'xmodem/batch.c' && test X"$1" != X"-c"; then echo 'x - skipping xmodem/batch.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting xmodem/batch.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xmodem/batch.c' && /* X * Various routines for batch transfer X */ X #include "xmodem.h" X /* External and forward references */ X extern void error(char *, int); extern void xmdebug(char *); extern void sendbyte(char); extern int readbyte(int); X /* make sure filename sent or received in YMODEM batch is canonical. */ X /* Incoming: Turn Unix '/' into CP/M ':' and translate to all lower case. X * Remove trailing dot. X */ X void unixify (char *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 } X /* make sure filename sent or received in YMODEM batch is canonical. */ 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 char * cpmify (name) char *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 /* 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 char *cpm_unix (char *string) { 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 return (filename); } 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 X int send_name(char *name) { 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 tlogit("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 tlogit("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 tlogit("Bad checksum while sending MODEM7 filename\n"); X sendbyte(BAD_NAME); X return (-1); X } X X sendbyte(ACK); X return (0); } 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 char *unix_cpm(char *string) { 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); } SHAR_EOF $shar_touch -am 0812084894 'xmodem/batch.c' && chmod 0644 'xmodem/batch.c' || echo 'restore of xmodem/batch.c failed' shar_count="`wc -c < 'xmodem/batch.c'`" test 5027 -eq "$shar_count" || echo "xmodem/batch.c: original size 5027, current size $shar_count" rm -f _sharnew.tmp fi # ============= xmodem/send.c ============== if test -f 'xmodem/send.c' && test X"$1" != X"-c"; then echo 'x - skipping xmodem/send.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting xmodem/send.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xmodem/send.c' && /** send a file **/ X /* X * Operation of this routine depends on on MDM7BAT and YMDMBAT flags. X * X * If "name" is NULL; close out the BATCH send. X */ X #include "xmodem.h" X /* External and forward references */ X extern void sendbyte(char); extern void error(char *, int); extern int projtime(long, FILE *); extern int readbyte(int); extern void flushin(void); extern int send_name(char *); extern int getbyte(int, char *); extern int prtime(long, time_t, FILE *); X extern void writebuf(char *, int); X void sfile(char *name) X { X X char *sectdisp(); X char *strcpy(); X char *unix_cpm(); X char *cpmify(); X long countnl(); X X extern unsigned short crctab[1< NAKMAX) X { X if (MDM7BAT && startup) X { X sendbyte(ACK); sendbyte(EOT); X } X error("Remote System Not Responding", TRUE); X } X X if ((firstchar & 0x7f) == CAN) X if (readbyte(3) == CAN) X error("Send Canceled by CAN-CAN",TRUE); X X if (firstchar == GCHR) X { X CRCMODE = TRUE; X YMODEMG = TRUE; X CANCAN = TRUE; X if (!closeout) X { X logit("Receiver invoked YMODEM-G and CRC modes\n"); X tlogit("Receiver invoked YMODEM-G and CRC modes\n"); X } X } X if (firstchar == CRCCHR) X { X CRCMODE = TRUE; X if (!closeout) X { SHAR_EOF : || echo 'restore of xmodem/send.c failed' fi echo 'End of xmodem part 3' echo 'File xmodem/send.c is continued in part 4' echo 4 > _sharseq.tmp exit 0