|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)umodem.c 1.1 (Berkeley) 11/2/84"; ! 3: #endif not lint ! 4: ! 5: /* ! 6: * UMODEM Version 3.7 ! 7: * ! 8: * UMODEM -- Implements the "CP/M User's Group XMODEM" protocol, ! 9: * the TERM II File Transfer Protocol (FTP) Number 1, ! 10: * and the TERM II File Transfer Protocol Number 4 for ! 11: * packetized file up/downloading. ! 12: * ! 13: * Note: UNIX System-Dependent values are indicated by the string [SD] ! 14: * in a comment field on the same line as the values. ! 15: * ! 16: * ! 17: * -- Lauren Weinstein, 6/81 ! 18: * -- (Version 2.0) Modified for JHU/UNIX by Richard Conn, 8/1/81 ! 19: * -- Version 2.1 Mods by Richard Conn, 8/2/81 ! 20: * . File Size Included on Send Option ! 21: * -- Version 2.2 Mods by Richard Conn, 8/2/81 ! 22: * . Log File Generation and Option Incorporated ! 23: * -- Version 2.3 Mods by Richard Conn, 8/3/81 ! 24: * . TERM II FTP 1 Supported ! 25: * . Error Log Reports Enhanced ! 26: * . CAN Function Added to FTP 3 ! 27: * . 'd' Option Added to Delete umodem.log File before starting ! 28: * -- Version 2.4 Mods by Richard Conn, 8/4/81 ! 29: * . 16K-extent sector number check error corrected ! 30: * . Count of number of received sectors added ! 31: * -- Version 2.5 Mods by Richard Conn, 8/5/81 ! 32: * . ARPA Net Flag added ! 33: * . ARPA Net parameter ('a') added to command line ! 34: * . ARPA Net BIS, BIE, BOS, BOE added ! 35: * . ARPA Net FFH escape added ! 36: * -- Version 2.6 Mods by Bennett Marks, 8/21/81 (Bucky @ CCA-UNIX) ! 37: * . mods for UNIX V7 (Note: for JHU compilation define ! 38: * the variable JHU during 'cc' ! 39: * . added 'mungmode' flag to protect from inadvertant ! 40: * overwrite on file receive ! 41: * . changed timeout handling prior to issuing checksum ! 42: * -- Version 2.7 Mods by Richard Conn, 8/25/81 (rconn @ BRL) ! 43: * . correct minor "ifndef" error in which ifndef had no arg ! 44: * . restructured "ifdef" references so that other versions ! 45: * of UNIX than Version 7 and JHU can be easily incorporated; ! 46: * previous ifdef references were for JHU/not JHU; ! 47: * to compile under Version 7 or JHU UNIX, the following ! 48: * command lines are recommended: ! 49: * "cc umodem.c -o umodem -DVER7" for Version 7 ! 50: * "cc -7 umodem.c -o umodem -DJHU" for JHU ! 51: * . added 'y' file status display option; this option gives ! 52: * the user an estimate of the size of the target file to ! 53: * send from the UNIX system in terms of CP/M records (128 ! 54: * bytes) and Kbytes (1024 byte units) ! 55: * . added '7' option which modifies the transmission protocols ! 56: * for 7 significant bits rather than 8; modifies both FTP 1 ! 57: * and FTP 3 ! 58: * -- Version 2.8 Mods by Richard Conn, 8/28/81 ! 59: * . corrected system-dependent reference to TIOCSSCR (for ! 60: * disabling page mode) and created the PAGEMODE flag which ! 61: * is to be set to TRUE to enable this ! 62: * . added -4 option which engages TERM II, FTP 4 (new release) ! 63: * -- Version 2.9 Mods by Richard Conn, 9/1/81 ! 64: * . internal documentation on ARPA Net protocols expanded ! 65: * . possible operator precedence problem with BITMASK corrected ! 66: * by redundant parentheses ! 67: * -- Version 3.0 Mods by Lauren Weinstein, 9/14/81 ! 68: * . fixed bug in PAGEMODE defines (removed PAGEMODE define ! 69: * line; now should be compiled with "-DPAGEMODE" if ! 70: * Page Mode is desired) ! 71: * . included forward declaration of ttyname() to avoid problems ! 72: * with newer V7 C compilers ! 73: * -- Version 3.1 Mods by Lauren Weinstein, 4/17/82 ! 74: * . avoids sending extraneous last sector when file EOF ! 75: * occurs on an exact sector boundary ! 76: * -- Version 3.2 Mods by Michael M Rubenstein, 5/26/83 ! 77: * . fixed bug in readbyte. assumed that int's are ordered ! 78: * from low significance to high ! 79: * . added LOGDEFAULT define to allow default logging to be ! 80: * off. compile with -DLOGDEFAULT=0 to set default to no ! 81: * logging. ! 82: * -- Version 3.3 Mod by Ben Goldfarb, 07/02/83 ! 83: * . Corrected problem with above implementation of "LOGDEFAULT". ! 84: * A bitwise, instead of a logical negation operator was ! 85: * used to complement LOGFLAG when the '-l' command line ! 86: * flag was specified. This can cause LOGFLAG to be true ! 87: * when it should be false. ! 88: * -- Version 3.4 Mods by David F. Hinnant, NCECS, 7/15/83 ! 89: * . placed log file in HOME directory in case user doesn't ! 90: * have write permission in working directory. ! 91: * . added DELDEFAULT define to allow default purge/no purge ! 92: * of logfile before starting. Compile with -DDELDEFAULT=0 ! 93: * to set default to NOT delete the log file before starting. ! 94: * . check log file for sucessful fopen(). ! 95: * . buffer disk read for sfile(). ! 96: * . turn messages off (standard v7) before starting. ! 97: * -- Version 3.5 Mods by Richard Conn, 08/27/83 ! 98: * . added equates for compilation under UNIX SYSTEM III ! 99: * to compile for SYSTEM III, use -DSYS3 instead of ! 100: * -DJHU or -DVER7 ! 101: * . added command mode (-c option) for continuous entry ! 102: * of commands ! 103: * -- Version 3.6 Mods by Ben Goldfarb (ucf-cs!goldfarb), 09/03/83 ! 104: * . added '#include <ctype.h>' since tolower() is used, but ! 105: * is not defined in umodem. This is necessary to compile ! 106: * on V7 systems. Also added a isupper() test because ! 107: * tolower() in /usr/include/ctype.h doesn't do that. ! 108: * . cleaned up all the improper bitwise complementation of ! 109: * logical constants and variables. ! 110: * -- Version 3.7 Mods by Noel J. Bergman, 02/27/84 ! 111: * . Corrected problem with ALARM signal in 4.2 BSD Unix. ! 112: * BSD Unix restarts system calls after signal is handled, ! 113: * so setjmp() and longjmp() are used to handle I/O timeout. ! 114: * Since this will work with all Unix systems, and is a lot ! 115: * cleaner than depending on side effects, there is no need ! 116: * to make this code conditional. ! 117: * ! 118: */ ! 119: ! 120: #include <stdio.h> ! 121: #include <sys/types.h> ! 122: #include <sys/stat.h> ! 123: #include <setjmp.h> ! 124: #include <ctype.h> ! 125: ! 126: /* JHU UNIX tty parameter file */ ! 127: #ifdef JHU ! 128: #include <stty.h> ! 129: #endif ! 130: ! 131: /* Version 7 UNIX tty parameter file */ ! 132: #ifdef VER7 ! 133: #include <sgtty.h> ! 134: #endif ! 135: ! 136: /* UNIX SYSTEM III tty parameter file */ ! 137: #ifdef SYS3 ! 138: #include <sgtty.h> ! 139: #endif ! 140: ! 141: /* log default define */ ! 142: #ifndef LOGDEFAULT ! 143: #define LOGDEFAULT 1 ! 144: #endif ! 145: ! 146: /* Delete logfile define. Useful on small systems with limited ! 147: * filesystem space and careless users. ! 148: */ ! 149: #ifndef DELDEFAULT ! 150: #define DELDEFAULT 1 ! 151: #endif ! 152: ! 153: #include <signal.h> ! 154: ! 155: #define VERSION 37 /* Version Number */ ! 156: #define FALSE 0 ! 157: #define TRUE 1 ! 158: ! 159: /* Compile with "-DPAGEMODE" if Page Mode (TIOCSSCR) is supported on your ! 160: * UNIX system. If it is supported, make sure that TIOCSSCR is the ! 161: * correct name for Page Mode engagement. ! 162: */ ! 163: ! 164: /* ASCII Constants */ ! 165: #define SOH 001 ! 166: #define STX 002 ! 167: #define ETX 003 ! 168: #define EOT 004 ! 169: #define ENQ 005 ! 170: #define ACK 006 ! 171: #define LF 012 /* Unix LF/NL */ ! 172: #define CR 015 ! 173: #define NAK 025 ! 174: #define SYN 026 ! 175: #define CAN 030 ! 176: #define ESC 033 ! 177: #define CTRLZ 032 /* CP/M EOF for text (usually!) */ ! 178: ! 179: /* UMODEM Constants */ ! 180: #define TIMEOUT -1 ! 181: #define ERRORMAX 10 /* maximum errors tolerated */ ! 182: #define RETRYMAX 10 /* maximum retries to be made */ ! 183: #define BBUFSIZ 128 /* buffer size -- do not change! */ ! 184: ! 185: /* [SD] Mode for Created Files */ ! 186: #define CREATMODE 0600 /* mode for created files */ ! 187: ! 188: /* ARPA Net Constants */ ! 189: /* The following constants are used to communicate with the ARPA ! 190: * Net SERVER TELNET and TIP programs. These constants are defined ! 191: * as follows: ! 192: * IAC <-- Is A Command; indicates that ! 193: * a command follows ! 194: * WILL/WONT <-- Command issued to SERVER TELNET ! 195: * (Host); WILL issues command ! 196: * and WONT issues negative of ! 197: * the command ! 198: * DO/DONT <-- Command issued to TIP; DO issues ! 199: * command and DONT issues ! 200: * negative of the command ! 201: * TRBIN <-- Transmit Binary Command ! 202: * Examples: ! 203: * IAC WILL TRBIN <-- Host is configured to transmit Binary ! 204: * IAC WONT TRBIN <-- Host is configured NOT to transmit binary ! 205: * IAC DO TRBIN <-- TIP is configured to transmit Binary ! 206: * IAC DONT TRBIN <-- TIP is configured NOT to transmit binary ! 207: */ ! 208: #define IAC 0377 /* Is A Command */ ! 209: #define DO 0375 /* Command to TIP */ ! 210: #define DONT 0376 /* Negative of Command to TIP */ ! 211: #define WILL 0373 /* Command to SERVER TELNET (Host) */ ! 212: #define WONT 0374 /* Negative of Command to SERVER TELNET */ ! 213: #define TRBIN 0 /* Transmit Binary Command */ ! 214: ! 215: /* JHU UNIX structures */ ! 216: #ifdef JHU ! 217: struct sttybuf ttys, ttysnew, ttystemp; /* for stty terminal mode calls */ ! 218: #endif ! 219: ! 220: /* Version 7 UNIX structures */ ! 221: #ifdef VER7 ! 222: struct sgttyb ttys, ttysnew, ttystemp; /* for stty terminal mode calls */ ! 223: #endif ! 224: ! 225: /* UNIX SYSTEM III structures */ ! 226: #ifdef SYS3 ! 227: struct sgttyb ttys, ttysnew, ttystemp; /* for stty terminal mode calls */ ! 228: #endif ! 229: ! 230: struct stat statbuf; /* for terminal message on/off control */ ! 231: char *strcat(); ! 232: FILE *LOGFP, *fopen(); ! 233: char buff[BBUFSIZ]; ! 234: int nbchr; /* number of chars read so far for buffered read */ ! 235: ! 236: int wason; ! 237: ! 238: #ifdef VER7 ! 239: int pagelen; ! 240: char *ttyname(); /* forward declaration for C */ ! 241: #endif ! 242: ! 243: #ifdef SYS3 ! 244: int pagelen; ! 245: char *ttyname(); /* forward declaration for C */ ! 246: #endif ! 247: ! 248: char *tty; ! 249: char XMITTYPE; ! 250: int ARPA, CMNDFLAG, RECVFLAG, SENDFLAG, FTP1, PMSG, DELFLAG, LOGFLAG, MUNGMODE; ! 251: int STATDISP, BIT7, BITMASK; ! 252: int delay; ! 253: char filename[256]; ! 254: ! 255: jmp_buf env; ! 256: void alarmfunc(); ! 257: ! 258: main(argc, argv) ! 259: int argc; ! 260: char **argv; ! 261: { ! 262: char *getenv(); ! 263: char *fname = filename; ! 264: char *logfile; ! 265: int index; ! 266: char flag; ! 267: ! 268: logfile = "umodem.log"; /* Name of LOG File */ ! 269: ! 270: printf("\nUMODEM Version %d.%d", VERSION/10, VERSION%10); ! 271: printf(" -- UNIX-Based Remote File Transfer Facility\n"); ! 272: ! 273: if (argc < 2 || *argv[1] != '-') ! 274: { ! 275: help(FALSE); ! 276: exit(-1); ! 277: } ! 278: ! 279: index = 1; /* set index for loop */ ! 280: delay = 3; /* assume FTP 3 delay */ ! 281: PMSG = FALSE; /* turn off flags */ ! 282: FTP1 = FALSE; /* assume FTP 3 (CP/M UG XMODEM2) */ ! 283: RECVFLAG = FALSE; /* not receive */ ! 284: SENDFLAG = FALSE; /* not send either */ ! 285: CMNDFLAG = FALSE; /* not command either */ ! 286: XMITTYPE = 't'; /* assume text */ ! 287: DELFLAG = DELDEFAULT; ! 288: LOGFLAG = LOGDEFAULT; ! 289: ARPA = FALSE; /* assume not on ARPA Net */ ! 290: MUNGMODE = FALSE; /* protect files from overwriting */ ! 291: STATDISP = FALSE; /* assume not a status display */ ! 292: BIT7 = FALSE; /* assume 8-bit communication */ ! 293: while ((flag = argv[1][index++]) != '\0') ! 294: switch (flag) { ! 295: case '1' : FTP1 = TRUE; /* select FTP 1 */ ! 296: delay = 5; /* FTP 1 delay constant */ ! 297: printf("\nUMODEM: TERM II FTP 1 Selected\n"); ! 298: break; ! 299: case '4' : FTP1 = TRUE; /* select FTP 1 (varient) */ ! 300: BIT7 = TRUE; /* transfer only 7 bits */ ! 301: delay = 5; /* FTP 1 delay constant */ ! 302: printf("\nUMODEM: TERM II FTP 4 Selected\n"); ! 303: break; ! 304: case '7' : BIT7 = TRUE; /* transfer only 7 bits */ ! 305: break; ! 306: case 'a' : ARPA = TRUE; /* set ARPA Net */ ! 307: break; ! 308: case 'c' : CMNDFLAG = TRUE; /* command mode */ ! 309: break; ! 310: case 'd' : DELFLAG = !DELDEFAULT; /* delete log file ? */ ! 311: break; ! 312: case 'l' : LOGFLAG = !LOGDEFAULT; /* turn off log ? */ ! 313: break; ! 314: case 'm' : MUNGMODE = TRUE; /* allow overwriting of files */ ! 315: break; ! 316: case 'p' : PMSG = TRUE; /* print all messages */ ! 317: break; ! 318: case 'r' : RECVFLAG = TRUE; /* receive file */ ! 319: XMITTYPE = gettype(argv[1][index++]); /* get t/b */ ! 320: break; ! 321: case 's' : SENDFLAG = TRUE; /* send file */ ! 322: XMITTYPE = gettype(argv[1][index++]); ! 323: break; ! 324: case 'y' : STATDISP = TRUE; /* display file status */ ! 325: break; ! 326: default : error("Invalid Flag", FALSE); ! 327: } ! 328: ! 329: if (BIT7 && (XMITTYPE == 'b')) ! 330: { printf("\nUMODEM: Fatal Error -- Both 7-Bit Transfer and "); ! 331: printf("Binary Transfer Selected"); ! 332: exit(-1); /* error exit to UNIX */ ! 333: } ! 334: ! 335: if (BIT7) /* set MASK value */ ! 336: BITMASK = 0177; /* 7 significant bits */ ! 337: else ! 338: BITMASK = 0377; /* 8 significant bits */ ! 339: ! 340: if (PMSG) ! 341: { printf("\nSupported File Transfer Protocols:"); ! 342: printf("\n\tTERM II FTP 1"); ! 343: printf("\n\tCP/M UG XMODEM2 (TERM II FTP 3)"); ! 344: printf("\n\tTERM II FTP 4"); ! 345: printf("\n\n"); ! 346: } ! 347: ! 348: if (CMNDFLAG) LOGFLAG = TRUE; /* if command mode, always log */ ! 349: if (LOGFLAG) ! 350: { ! 351: if ((fname = getenv("HOME")) == 0) /* Get HOME variable */ ! 352: error("Can't get Environment!", FALSE); ! 353: fname = strcat(fname, "/"); ! 354: fname = strcat(fname, logfile); ! 355: if (!DELFLAG) ! 356: LOGFP = fopen(fname, "a"); /* append to LOG file */ ! 357: else ! 358: LOGFP = fopen(fname, "w"); /* new LOG file */ ! 359: if (!LOGFP) ! 360: error("Can't Open Log File", FALSE); ! 361: fprintf(LOGFP,"\n\n++++++++\n"); ! 362: fprintf(LOGFP,"\nUMODEM Version %d.%d\n", VERSION/10, VERSION%10); ! 363: printf("\nUMODEM: LOG File '%s' is Open\n", fname); ! 364: } ! 365: ! 366: if (STATDISP) { ! 367: yfile(argv[2]); /* status of a file */ ! 368: exit(0); /* exit to UNIX */ ! 369: } ! 370: ! 371: if (RECVFLAG && SENDFLAG) ! 372: error("Both Send and Receive Functions Specified", FALSE); ! 373: if (!RECVFLAG && !SENDFLAG && !CMNDFLAG) ! 374: error("Send, Receive, or Command Functions NOT Given", FALSE); ! 375: ! 376: if (RECVFLAG) ! 377: { if(open(argv[2], 0) != -1) /* possible abort if file exists */ ! 378: { printf("\nUMODEM: Warning -- Target File Exists\n"); ! 379: if( MUNGMODE == FALSE ) ! 380: error("Fatal - Can't overwrite file\n",FALSE); ! 381: printf("UMODEM: Overwriting Target File\n"); ! 382: } ! 383: rfile(argv[2]); /* receive file */ ! 384: } ! 385: else { ! 386: if (SENDFLAG) sfile(argv[2]); /* send file */ ! 387: else command(); /* command mode */ ! 388: } ! 389: if (CMNDFLAG) LOGFLAG = TRUE; /* for closing log file */ ! 390: if (LOGFLAG) fclose(LOGFP); ! 391: exit(0); ! 392: } ! 393: ! 394: /* Major Command Mode */ ! 395: command() ! 396: { ! 397: char cmd, *fname; ! 398: char *infile(); ! 399: ! 400: printf("\nUMODEM Command Mode -- Type ? for Help"); ! 401: do { ! 402: printf("\n"); ! 403: printf(FTP1 ? "1" : "3"); /* FTP 1 or 3? */ ! 404: printf(BIT7 ? "7" : " "); /* BIT 7 or not? */ ! 405: printf(ARPA ? "A" : " "); /* ARPA Net or not? */ ! 406: printf(LOGFLAG ? "L" : " "); /* Log Entries or not? */ ! 407: printf(MUNGMODE ? "M" : " "); /* Mung Files or not? */ ! 408: printf(" UMODEM> "); ! 409: scanf("%s", filename); ! 410: cmd = isupper(filename[0]) ? tolower(filename[0]) : filename[0]; ! 411: switch (cmd) { ! 412: case '1' : FTP1 = TRUE; /* select FTP 1 */ ! 413: delay = 5; /* FTP 1 delay constant */ ! 414: printf("\nTERM FTP 1 Selected"); ! 415: break; ! 416: case '3' : FTP1 = FALSE; /* select FTP 3 */ ! 417: delay = 3; /* FTP 3 delay constant */ ! 418: printf("\nTERM FTP 3 Selected"); ! 419: break; ! 420: case '7' : BIT7 = !BIT7; /* toggle 7 bit transfer */ ! 421: printf("\n7-Bit Transfer %s Selected", ! 422: BIT7 ? "" : "NOT"); ! 423: break; ! 424: case 'a' : ARPA = !ARPA; /* toggle ARPA Net */ ! 425: printf("\nDDN Interface %s Selected", ! 426: ARPA ? "" : "NOT"); ! 427: break; ! 428: case 'l' : LOGFLAG = !LOGFLAG; /* toggle log flag */ ! 429: printf("\nEntry Logging %s Enabled", ! 430: LOGFLAG ? "" : "NOT"); ! 431: break; ! 432: case 'm' : MUNGMODE = !MUNGMODE; /* toggle file overwrite */ ! 433: printf("\nFile Overwriting %s Enabled", ! 434: MUNGMODE ? "" : "NOT"); ! 435: break; ! 436: case 'r' : RECVFLAG = TRUE; /* receive file */ ! 437: XMITTYPE = tolower(filename[1]); ! 438: fname = infile(); /* get file name */ ! 439: if (*fname != '\0') rfile(fname); ! 440: break; ! 441: case 's' : SENDFLAG = TRUE; /* send file */ ! 442: XMITTYPE = tolower(filename[1]); ! 443: fname = infile(); /* get file name */ ! 444: if (*fname != '\0') sfile(fname); ! 445: break; ! 446: case 'x' : break; ! 447: case 'y' : fname = infile(); /* get file name */ ! 448: if (*fname != '\0') yfile(fname); ! 449: break; ! 450: default : help(TRUE); ! 451: } ! 452: } while (cmd != 'x'); ! 453: } ! 454: ! 455: /* Get file name from user */ ! 456: char *infile() ! 457: { ! 458: char *startptr = filename; ! 459: ! 460: scanf("%s",startptr); ! 461: if (*startptr == '.') *startptr = '\0'; /* set NULL */ ! 462: return(startptr); ! 463: } ! 464: ! 465: /* Print Help Message */ ! 466: help(caller) ! 467: int caller; ! 468: { ! 469: if (!caller) { printf("\nUsage: \n\tumodem "); ! 470: printf("-[c!rb!rt!sb!st][options]"); ! 471: printf(" filename\n"); ! 472: } ! 473: else { ! 474: printf("\nUsage: r or s or option"); ! 475: } ! 476: printf("\nMajor Commands --"); ! 477: if (!caller) printf("\n\tc <-- Enter Command Mode"); ! 478: printf("\n\trb <-- Receive Binary"); ! 479: printf("\n\trt <-- Receive Text"); ! 480: printf("\n\tsb <-- Send Binary"); ! 481: printf("\n\tst <-- Send Text"); ! 482: printf("\nOptions --"); ! 483: printf("\n\t1 <-- (one) Employ TERM II FTP 1"); ! 484: if (caller) printf("\n\t3 <-- Enable TERM FTP 3 (CP/M UG)"); ! 485: if (!caller) printf("\n\t4 <-- Enable TERM FTP 4"); ! 486: printf("\n\t7 <-- Enable 7-bit transfer mask"); ! 487: printf("\n\ta <-- Turn ON ARPA Net Flag"); ! 488: if (!caller) ! 489: #if DELDEFAULT == 1 ! 490: printf("\n\td <-- Do not delete umodem.log file before starting"); ! 491: #else ! 492: printf("\n\td <-- Delete umodem.log file before starting"); ! 493: #endif ! 494: ! 495: if (!caller) ! 496: #if LOGDEFAULT == 1 ! 497: printf("\n\tl <-- (ell) Turn OFF LOG File Entries"); ! 498: #else ! 499: printf("\n\tl <-- (ell) Turn ON LOG File Entries"); ! 500: #endif ! 501: else printf("\n\tl <-- Toggle LOG File Entries"); ! 502: ! 503: printf("\n\tm <-- Allow file overwiting on receive"); ! 504: if (!caller) printf("\n\tp <-- Turn ON Parameter Display"); ! 505: if (caller) printf("\n\tx <-- Exit"); ! 506: printf("\n\ty <-- Display file status (size) information only"); ! 507: printf("\n"); ! 508: } ! 509: ! 510: gettype(ichar) ! 511: char ichar; ! 512: { ! 513: if (ichar == 't') return(ichar); ! 514: if (ichar == 'b') return(ichar); ! 515: error("Invalid Send/Receive Parameter - not t or b", FALSE); ! 516: return; ! 517: } ! 518: ! 519: /* set tty modes for UMODEM transfers */ ! 520: setmodes() ! 521: { ! 522: ! 523: /* Device characteristics for JHU UNIX */ ! 524: #ifdef JHU ! 525: if (gtty(0, &ttys) < 0) /* get current tty params */ ! 526: error("Can't get TTY Parameters", TRUE); ! 527: ! 528: tty = ttyname(0); /* identify current tty */ ! 529: ! 530: /* duplicate current modes in ttysnew structure */ ! 531: ttysnew.ispeed = ttys.ispeed; /* copy input speed */ ! 532: ttysnew.ospeed = ttys.ospeed; /* copy output speed */ ! 533: ttysnew.xflags = ttys.xflags; /* copy JHU/UNIX extended flags */ ! 534: ttysnew.mode = ttys.mode; /* copy standard terminal flags */ ! 535: ! 536: ttysnew.mode |= RAW; /* set for RAW Mode */ ! 537: /* This ORs in the RAW mode value, thereby ! 538: setting RAW mode and leaving the other ! 539: mode settings unchanged */ ! 540: ttysnew.mode &= ~ECHO; /* set for no echoing */ ! 541: /* This ANDs in the complement of the ECHO ! 542: setting (for NO echo), thereby leaving all ! 543: current parameters unchanged and turning ! 544: OFF ECHO only */ ! 545: ttysnew.mode &= ~XTABS; /* set for no tab expansion */ ! 546: ttysnew.mode &= ~LCASE; /* set for no upper-to-lower case xlate */ ! 547: ttysnew.mode |= ANYP; /* set for ANY Parity */ ! 548: ttysnew.mode &= ~NL3; /* turn off ALL delays - new line */ ! 549: ttysnew.mode &= ~TAB3; /* turn off tab delays */ ! 550: ttysnew.mode &= ~CR3; /* turn off CR delays */ ! 551: ttysnew.mode &= ~FF1; /* turn off FF delays */ ! 552: ttysnew.mode &= ~BS1; /* turn off BS delays */ ! 553: /* the following are JHU/UNIX xflags settings; they are [SD] */ ! 554: ttysnew.xflags &= ~PAGE; /* turn off paging */ ! 555: ttysnew.xflags &= ~STALL; /* turn off ^S/^Q recognition */ ! 556: ttysnew.xflags &= ~TAPE; /* turn off ^S/^Q input control */ ! 557: ttysnew.xflags &= ~FOLD; /* turn off CR/LF folding at col 72 */ ! 558: ttysnew.xflags |= NB8; /* turn on 8-bit input/output */ ! 559: ! 560: if (stty(0, &ttysnew) < 0) /* set new params */ ! 561: error("Can't set new TTY Parameters", TRUE); ! 562: ! 563: if (stat(tty, &statbuf) < 0) /* get tty status */ ! 564: error("Can't get your TTY Status", TRUE); ! 565: ! 566: if (statbuf.st_mode&011) /* messages are on [SD] */ ! 567: { wason = TRUE; ! 568: if (chmod(tty, 020600) < 0) /* turn off tty messages [SD] */ ! 569: error("Can't change TTY Mode", TRUE); ! 570: } ! 571: else ! 572: wason = FALSE; /* messages are already off */ ! 573: #endif ! 574: ! 575: /* Device characteristics for Version 7 UNIX */ ! 576: #ifdef VER7 ! 577: if (ioctl(0,TIOCGETP,&ttys)<0) /* get tty params [V7] */ ! 578: error("Can't get TTY Parameters", TRUE); ! 579: tty = ttyname(0); /* identify current tty */ ! 580: ! 581: /* transfer current modes to new structure */ ! 582: ttysnew.sg_ispeed = ttys.sg_ispeed; /* copy input speed */ ! 583: ttysnew.sg_ospeed = ttys.sg_ospeed; /* copy output speed */ ! 584: ttysnew.sg_erase = ttys.sg_erase; /* copy erase flags */ ! 585: ttysnew.sg_flags = ttys.sg_flags; /* copy flags */ ! 586: ttysnew.sg_kill = ttys.sg_kill; /* copy std terminal flags */ ! 587: ! 588: ! 589: ttysnew.sg_flags |= RAW; /* set for RAW Mode */ ! 590: /* This ORs in the RAW mode value, thereby ! 591: setting RAW mode and leaving the other ! 592: mode settings unchanged */ ! 593: ttysnew.sg_flags &= ~ECHO; /* set for no echoing */ ! 594: /* This ANDs in the complement of the ECHO ! 595: setting (for NO echo), thereby leaving all ! 596: current parameters unchanged and turning ! 597: OFF ECHO only */ ! 598: ttysnew.sg_flags &= ~XTABS; /* set for no tab expansion */ ! 599: ttysnew.sg_flags &= ~LCASE; /* set for no upper-to-lower case xlate */ ! 600: ttysnew.sg_flags |= ANYP; /* set for ANY Parity */ ! 601: ttysnew.sg_flags &= ~NL3; /* turn off ALL delays - new line */ ! 602: ttysnew.sg_flags &= ~TAB2; /* turn off tab delays */ ! 603: ttysnew.sg_flags &= ~CR3; /* turn off CR delays */ ! 604: ttysnew.sg_flags &= ~FF1; /* turn off FF delays */ ! 605: ttysnew.sg_flags &= ~BS1; /* turn off BS delays */ ! 606: ttysnew.sg_flags &= ~TANDEM; /* turn off flow control */ ! 607: ! 608: #ifdef PAGEMODE ! 609: /* make sure page mode is off */ ! 610: ioctl(0,TIOCSSCR,&pagelen); /* [SD] */ ! 611: #endif ! 612: ! 613: /* set new paramters */ ! 614: if (ioctl(0,TIOCSETP,&ttysnew) < 0) ! 615: error("Can't set new TTY Parameters", TRUE); ! 616: ! 617: if (stat(tty, &statbuf) < 0) /* get tty status */ ! 618: error("Can't get your TTY Status", TRUE); ! 619: if (statbuf.st_mode & 022) /* Need to turn messages off */ ! 620: if (chmod(tty, statbuf.st_mode & ~022) < 0) ! 621: error("Can't change TTY mode", TRUE); ! 622: else wason = TRUE; ! 623: else wason = FALSE; ! 624: #endif ! 625: ! 626: /* Device Characteristics for UNIX SYSTEM III */ ! 627: #ifdef SYS3 ! 628: if (gtty(0, &ttys) < 0) /* get current tty params */ ! 629: error("Can't get TTY Parameters", TRUE); ! 630: ! 631: tty = ttyname(0); /* identify current tty */ ! 632: ! 633: /* transfer current modes to new structure */ ! 634: ttysnew.sg_ispeed = ttys.sg_ispeed; /* copy input speed */ ! 635: ttysnew.sg_ospeed = ttys.sg_ospeed; /* copy output speed */ ! 636: ttysnew.sg_erase = ttys.sg_erase; /* copy erase flags */ ! 637: ttysnew.sg_flags = ttys.sg_flags; /* copy flags */ ! 638: ttysnew.sg_kill = ttys.sg_kill; /* copy std terminal flags */ ! 639: ! 640: ! 641: ttysnew.sg_flags |= RAW; /* set for RAW Mode */ ! 642: /* This ORs in the RAW mode value, thereby ! 643: setting RAW mode and leaving the other ! 644: mode settings unchanged */ ! 645: ttysnew.sg_flags &= ~ECHO; /* set for no echoing */ ! 646: /* This ANDs in the complement of the ECHO ! 647: setting (for NO echo), thereby leaving all ! 648: current parameters unchanged and turning ! 649: OFF ECHO only */ ! 650: ttysnew.sg_flags &= ~XTABS; /* set for no tab expansion */ ! 651: ttysnew.sg_flags &= ~LCASE; /* set for no upper-to-lower case xlate */ ! 652: ttysnew.sg_flags |= ANYP; /* set for ANY Parity */ ! 653: ttysnew.sg_flags &= ~NL3; /* turn off ALL delays - new line */ ! 654: ttysnew.sg_flags &= ~TAB0; /* turn off tab delays */ ! 655: ttysnew.sg_flags &= ~TAB1; ! 656: ttysnew.sg_flags &= ~CR3; /* turn off CR delays */ ! 657: ttysnew.sg_flags &= ~FF1; /* turn off FF delays */ ! 658: ttysnew.sg_flags &= ~BS1; /* turn off BS delays */ ! 659: ! 660: if (stty(0, &ttysnew) < 0) /* set new params */ ! 661: error("Can't set new TTY Parameters", TRUE); ! 662: ! 663: if (stat(tty, &statbuf) < 0) /* get tty status */ ! 664: error("Can't get your TTY Status", TRUE); ! 665: if (statbuf.st_mode & 022) /* Need to turn messages off */ ! 666: if (chmod(tty, statbuf.st_mode & ~022) < 0) ! 667: error("Can't change TTY mode", TRUE); ! 668: else wason = TRUE; ! 669: else wason = FALSE; ! 670: #endif ! 671: ! 672: if (PMSG) ! 673: { printf("\nUMODEM: TTY Device Parameters Altered"); ! 674: ttyparams(); /* print tty params */ ! 675: } ! 676: ! 677: if (ARPA) /* set 8-bit on ARPA Net */ ! 678: setarpa(); ! 679: ! 680: return; ! 681: } ! 682: ! 683: /* set ARPA Net for 8-bit transfers */ ! 684: setarpa() ! 685: { ! 686: sendbyte(IAC); /* Is A Command */ ! 687: sendbyte(WILL); /* Command to SERVER TELNET (Host) */ ! 688: sendbyte(TRBIN); /* Command is: Transmit Binary */ ! 689: ! 690: sendbyte(IAC); /* Is A Command */ ! 691: sendbyte(DO); /* Command to TIP */ ! 692: sendbyte(TRBIN); /* Command is: Transmit Binary */ ! 693: ! 694: sleep(3); /* wait for TIP to configure */ ! 695: ! 696: return; ! 697: } ! 698: ! 699: /* restore normal tty modes */ ! 700: restoremodes(errcall) ! 701: int errcall; ! 702: { ! 703: if (ARPA) /* if ARPA Net, reconfigure */ ! 704: resetarpa(); ! 705: ! 706: /* Device characteristic restoration for JHU UNIX */ ! 707: #ifdef JHU ! 708: if (wason) /* if messages were on originally */ ! 709: if (chmod(tty, 020611) < 0) /* [SD] */ ! 710: error("Can't change TTY Mode", FALSE); ! 711: ! 712: if (stty(0, &ttys) < 0) /* restore original tty modes */ ! 713: { if (!errcall) ! 714: error("RESET - Can't restore normal TTY Params", FALSE); ! 715: else ! 716: { printf("UMODEM: "); ! 717: printf("RESET - Can't restore normal TTY Params\n"); ! 718: } ! 719: } ! 720: #endif ! 721: ! 722: /* Device characteristic restoration for Version 7 UNIX */ ! 723: #ifdef VER7 ! 724: if (wason) ! 725: if (chmod(tty, statbuf.st_mode | 022) < 0) ! 726: error("Can't change TTY mode", FALSE); ! 727: if (ioctl(0,TIOCSETP,&ttys) < 0) ! 728: { if (!errcall) ! 729: error("RESET - Can't restore normal TTY Params", FALSE); ! 730: else ! 731: { printf("UMODEM: "); ! 732: printf("RESET - Can't restore normal TTY Params\n"); ! 733: } ! 734: } ! 735: #endif ! 736: ! 737: /* Device characteristic restoration for UNIX SYSTEM III */ ! 738: #ifdef SYS3 ! 739: if (wason) ! 740: if (chmod(tty, statbuf.st_mode | 022) < 0) ! 741: error("Can't change TTY mode", FALSE); ! 742: ! 743: if (stty(0, &ttys) < 0) /* restore original tty modes */ ! 744: { if (!errcall) ! 745: error("RESET - Can't restore normal TTY Params", FALSE); ! 746: else ! 747: { printf("UMODEM: "); ! 748: printf("RESET - Can't restore normal TTY Params\n"); ! 749: } ! 750: } ! 751: #endif ! 752: ! 753: if (PMSG) ! 754: { printf("\nUMODEM: TTY Device Parameters Restored"); ! 755: ttyparams(); /* print tty params */ ! 756: } ! 757: ! 758: return; ! 759: } ! 760: ! 761: /* reset the ARPA Net */ ! 762: resetarpa() ! 763: { ! 764: sendbyte(IAC); /* Is A Command */ ! 765: sendbyte(WONT); /* Negative Command to SERVER TELNET (Host) */ ! 766: sendbyte(TRBIN); /* Command is: Don't Transmit Binary */ ! 767: ! 768: sendbyte(IAC); /* Is A Command */ ! 769: sendbyte(DONT); /* Negative Command to TIP */ ! 770: sendbyte(TRBIN); /* Command is: Don't Transmit Binary */ ! 771: ! 772: return; ! 773: } ! 774: ! 775: /* print error message and exit; if mode == TRUE, restore normal tty modes */ ! 776: error(msg, mode) ! 777: char *msg; ! 778: int mode; ! 779: { ! 780: if (mode) ! 781: restoremodes(TRUE); /* put back normal tty modes */ ! 782: printf("UMODEM: %s\n", msg); ! 783: if (LOGFLAG & (int)LOGFP) ! 784: { fprintf(LOGFP, "UMODEM Fatal Error: %s\n", msg); ! 785: fclose(LOGFP); ! 786: } ! 787: exit(-1); ! 788: } ! 789: ! 790: /** print status (size) of a file **/ ! 791: yfile(name) ! 792: char *name; ! 793: { ! 794: printf("\nUMODEM File Status Display for %s\n", name); ! 795: ! 796: if (open(name,0) < 0) { ! 797: printf("File %s does not exist\n", name); ! 798: return; ! 799: } ! 800: ! 801: prfilestat(name); /* print status */ ! 802: printf("\n"); ! 803: } ! 804: ! 805: getbyte(fildes, ch) /* Buffered disk read */ ! 806: int fildes; ! 807: char *ch; ! 808: /* ! 809: * ! 810: * Get a byte from the specified file. Buffer the read so we don't ! 811: * have to use a system call for each character. ! 812: * ! 813: */ ! 814: ! 815: { ! 816: static char buf[BUFSIZ]; /* Remember buffer */ ! 817: static char *bufp = buf; /* Remember where we are in buffer */ ! 818: ! 819: if (nbchr == 0) /* Buffer exausted; read some more */ ! 820: { ! 821: if ((nbchr = read(fildes, buf, BUFSIZ)) < 0) ! 822: error("File Read Error", TRUE); ! 823: bufp = buf; /* Set pointer to start of array */ ! 824: } ! 825: if (--nbchr >= 0) ! 826: { ! 827: *ch = *bufp++; ! 828: return(0); ! 829: } ! 830: else ! 831: return(EOF); ! 832: } ! 833: ! 834: /** receive a file **/ ! 835: rfile(name) ! 836: char *name; ! 837: { ! 838: char mode; ! 839: int fd, j, firstchar, sectnum, sectcurr, tmode; ! 840: int sectcomp, errors, errorflag, recfin; ! 841: register int bufctr, checksum; ! 842: register int c; ! 843: int errorchar, fatalerror, startstx, inchecksum, endetx, endenq; ! 844: long recvsectcnt; ! 845: ! 846: mode = XMITTYPE; /* set t/b mode */ ! 847: if ((fd = creat(name, CREATMODE)) < 0) ! 848: error("Can't create file for receive", FALSE); ! 849: setmodes(); /* setup tty modes for xfer */ ! 850: printf("\r\nUMODEM: File Name: %s", name); ! 851: if (LOGFLAG) ! 852: { fprintf(LOGFP, "\n----\nUMODEM Receive Function\n"); ! 853: fprintf(LOGFP, "File Name: %s\n", name); ! 854: if (FTP1) ! 855: if (!BIT7) ! 856: fprintf(LOGFP, "TERM II File Transfer Protocol 1 Selected\n"); ! 857: else ! 858: fprintf(LOGFP, "TERM II File Transfer Protocol 4 Selected\n"); ! 859: else ! 860: fprintf(LOGFP, ! 861: "TERM II File Transfer Protocol 3 (CP/M UG) Selected\n"); ! 862: if (BIT7) ! 863: fprintf(LOGFP, "7-Bit Transmission Enabled\n"); ! 864: else ! 865: fprintf(LOGFP, "8-Bit Transmission Enabled\n"); ! 866: } ! 867: printf("\r\nUMODEM: "); ! 868: if (BIT7) ! 869: printf("7-Bit"); ! 870: else ! 871: printf("8-Bit"); ! 872: printf(" Transmission Enabled"); ! 873: printf("\r\nUMODEM: Ready to RECEIVE File\r\n"); ! 874: ! 875: recfin = FALSE; ! 876: sectnum = errors = 0; ! 877: fatalerror = FALSE; /* NO fatal errors */ ! 878: recvsectcnt = 0; /* number of received sectors */ ! 879: ! 880: if (mode == 't') ! 881: tmode = TRUE; ! 882: else ! 883: tmode = FALSE; ! 884: ! 885: if (FTP1) ! 886: { ! 887: while (readbyte(4) != SYN); ! 888: sendbyte(ACK); /* FTP 1 Sync */ ! 889: } ! 890: else sendbyte(NAK); /* FTP 3 Sync */ ! 891: ! 892: do ! 893: { errorflag = FALSE; ! 894: do { ! 895: firstchar = readbyte(6); ! 896: } while ((firstchar != SOH) && (firstchar != EOT) && (firstchar ! 897: != TIMEOUT)); ! 898: if (firstchar == TIMEOUT) ! 899: { if (LOGFLAG) ! 900: fprintf(LOGFP, "Timeout on Sector %d\n", sectnum); ! 901: errorflag = TRUE; ! 902: } ! 903: ! 904: if (firstchar == SOH) ! 905: { if (FTP1) readbyte(5); /* discard leading zero */ ! 906: sectcurr = readbyte(delay); ! 907: sectcomp = readbyte(delay); ! 908: if (FTP1) startstx = readbyte(delay); /* get leading STX */ ! 909: if ((sectcurr + sectcomp) == BITMASK) ! 910: { if (sectcurr == ((sectnum+1)&BITMASK)) ! 911: { checksum = 0; ! 912: for (j = bufctr = 0; j < BBUFSIZ; j++) ! 913: { buff[bufctr] = c = readbyte(delay); ! 914: checksum = ((checksum+c)&BITMASK); ! 915: if (!tmode) /* binary mode */ ! 916: { bufctr++; ! 917: continue; ! 918: } ! 919: if (c == CR) ! 920: continue; /* skip CR's */ ! 921: if (c == CTRLZ) /* skip CP/M EOF char */ ! 922: { recfin = TRUE; /* flag EOF */ ! 923: continue; ! 924: } ! 925: if (!recfin) ! 926: bufctr++; ! 927: } ! 928: if (FTP1) endetx = readbyte(delay); /* get ending ETX */ ! 929: inchecksum = readbyte(delay); /* get checksum */ ! 930: if (FTP1) endenq = readbyte(delay); /* get ENQ */ ! 931: if (checksum == inchecksum) /* good checksum */ ! 932: { errors = 0; ! 933: recvsectcnt++; ! 934: sectnum = sectcurr; /* update sector counter */ ! 935: if (write(fd, buff, bufctr) < 0) ! 936: error("File Write Error", TRUE); ! 937: else ! 938: { if (FTP1) sendbyte(ESC); /* FTP 1 requires <ESC> */ ! 939: sendbyte(ACK); ! 940: } ! 941: } ! 942: else ! 943: { if (LOGFLAG) ! 944: fprintf(LOGFP, "Checksum Error on Sector %d\n", ! 945: sectnum); ! 946: errorflag = TRUE; ! 947: } ! 948: } ! 949: else ! 950: { if (sectcurr == sectnum) ! 951: { while(readbyte(3) != TIMEOUT); ! 952: if (FTP1) sendbyte(ESC); /* FTP 1 requires <ESC> */ ! 953: sendbyte(ACK); ! 954: } ! 955: else ! 956: { if (LOGFLAG) ! 957: { fprintf(LOGFP, "Phase Error - Received Sector is "); ! 958: fprintf(LOGFP, "%d while Expected Sector is %d\n", ! 959: sectcurr, ((sectnum+1)&BITMASK)); ! 960: } ! 961: errorflag = TRUE; ! 962: fatalerror = TRUE; ! 963: if (FTP1) sendbyte(ESC); /* FTP 1 requires <ESC> */ ! 964: sendbyte(CAN); ! 965: } ! 966: } ! 967: } ! 968: else ! 969: { if (LOGFLAG) ! 970: fprintf(LOGFP, "Header Sector Number Error on Sector %d\n", ! 971: sectnum); ! 972: errorflag = TRUE; ! 973: } ! 974: } ! 975: if (FTP1 && !errorflag) ! 976: { if (startstx != STX) ! 977: { errorflag = TRUE; /* FTP 1 STX missing */ ! 978: errorchar = STX; ! 979: } ! 980: if (endetx != ETX) ! 981: { errorflag = TRUE; /* FTP 1 ETX missing */ ! 982: errorchar = ETX; ! 983: } ! 984: if (endenq != ENQ) ! 985: { errorflag = TRUE; /* FTP 1 ENQ missing */ ! 986: errorchar = ENQ; ! 987: } ! 988: if (errorflag && LOGFLAG) ! 989: { fprintf(LOGFP, "Invalid Packet-Control Character: "); ! 990: switch (errorchar) { ! 991: case STX : fprintf(LOGFP, "STX"); break; ! 992: case ETX : fprintf(LOGFP, "ETX"); break; ! 993: case ENQ : fprintf(LOGFP, "ENQ"); break; ! 994: default : fprintf(LOGFP, "Error"); break; ! 995: } ! 996: fprintf(LOGFP, "\n"); ! 997: } ! 998: } ! 999: if (errorflag == TRUE) ! 1000: { errors++; ! 1001: while (readbyte(3) != TIMEOUT); ! 1002: sendbyte(NAK); ! 1003: } ! 1004: } ! 1005: while ((firstchar != EOT) && (errors != ERRORMAX) && !fatalerror); ! 1006: if ((firstchar == EOT) && (errors < ERRORMAX)) ! 1007: { if (!FTP1) sendbyte(ACK); ! 1008: close(fd); ! 1009: restoremodes(FALSE); /* restore normal tty modes */ ! 1010: if (FTP1) ! 1011: while (readbyte(3) != TIMEOUT); /* flush EOT's */ ! 1012: sleep(3); /* give other side time to return to terminal mode */ ! 1013: if (LOGFLAG) ! 1014: { fprintf(LOGFP, "\nReceive Complete\n"); ! 1015: fprintf(LOGFP,"Number of Received CP/M Records is %ld\n", recvsectcnt); ! 1016: } ! 1017: printf("\n"); ! 1018: } ! 1019: else ! 1020: { if (LOGFLAG && FTP1 && fatalerror) fprintf(LOGFP, ! 1021: "Synchronization Error"); ! 1022: error("TIMEOUT -- Too Many Errors", TRUE); ! 1023: } ! 1024: } ! 1025: ! 1026: /** send a file **/ ! 1027: sfile(name) ! 1028: char *name; ! 1029: { ! 1030: char mode; ! 1031: int fd, attempts; ! 1032: int nlflag, sendfin, tmode; ! 1033: register int bufctr, checksum, sectnum; ! 1034: char c; ! 1035: int sendresp; /* response char to sent block */ ! 1036: ! 1037: nbchr = 0; /* clear buffered read char count */ ! 1038: mode = XMITTYPE; /* set t/b mode */ ! 1039: if ((fd = open(name, 0)) < 0) ! 1040: { if (LOGFLAG) fprintf(LOGFP, "Can't Open File\n"); ! 1041: error("Can't open file for send", FALSE); ! 1042: } ! 1043: setmodes(); /* setup tty modes for xfer */ ! 1044: printf("\r\nUMODEM: File Name: %s", name); ! 1045: if (LOGFLAG) ! 1046: { fprintf(LOGFP, "\n----\nUMODEM Send Function\n"); ! 1047: fprintf(LOGFP, "File Name: %s\n", name); ! 1048: } ! 1049: printf("\r\n"); prfilestat(name); /* print file size statistics */ ! 1050: if (LOGFLAG) ! 1051: { if (FTP1) ! 1052: if (!BIT7) ! 1053: fprintf(LOGFP, "TERM II File Transfer Protocol 1 Selected\n"); ! 1054: else ! 1055: fprintf(LOGFP, "TERM II File Transfer Protocol 4 Selected\n"); ! 1056: else ! 1057: fprintf(LOGFP, ! 1058: "TERM II File Transfer Protocol 3 (CP/M UG) Selected\n"); ! 1059: if (BIT7) ! 1060: fprintf(LOGFP, "7-Bit Transmission Enabled\n"); ! 1061: else ! 1062: fprintf(LOGFP, "8-Bit Transmission Enabled\n"); ! 1063: } ! 1064: printf("\r\nUMODEM: "); ! 1065: if (BIT7) ! 1066: printf("7-Bit"); ! 1067: else ! 1068: printf("8-Bit"); ! 1069: printf(" Transmission Enabled"); ! 1070: printf("\r\nUMODEM: Ready to SEND File\r\n"); ! 1071: ! 1072: if (mode == 't') ! 1073: tmode = TRUE; ! 1074: else ! 1075: tmode = FALSE; ! 1076: ! 1077: sendfin = nlflag = FALSE; ! 1078: attempts = 0; ! 1079: ! 1080: if (FTP1) ! 1081: { sendbyte(SYN); /* FTP 1 Synchronize with Receiver */ ! 1082: while (readbyte(5) != ACK) ! 1083: { if(++attempts > RETRYMAX*6) error("Remote System Not Responding", ! 1084: TRUE); ! 1085: sendbyte(SYN); ! 1086: } ! 1087: } ! 1088: else ! 1089: { while (readbyte(30) != NAK) /* FTP 3 Synchronize with Receiver */ ! 1090: if (++attempts > RETRYMAX) error("Remote System Not Responding", ! 1091: TRUE); ! 1092: } ! 1093: ! 1094: sectnum = 1; /* first sector number */ ! 1095: attempts = 0; ! 1096: ! 1097: do ! 1098: { for (bufctr=0; bufctr < BBUFSIZ;) ! 1099: { if (nlflag) ! 1100: { buff[bufctr++] = LF; /* leftover newline */ ! 1101: nlflag = FALSE; ! 1102: } ! 1103: if (getbyte(fd, &c) == EOF) ! 1104: { sendfin = TRUE; /* this is the last sector */ ! 1105: if (!bufctr) /* if EOF on sector boundary */ ! 1106: break; /* avoid sending extra sector */ ! 1107: if (tmode) ! 1108: buff[bufctr++] = CTRLZ; /* Control-Z for CP/M EOF */ ! 1109: else ! 1110: bufctr++; ! 1111: continue; ! 1112: } ! 1113: if (tmode && c == LF) /* text mode & Unix newline? */ ! 1114: { if (c == LF) /* Unix newline? */ ! 1115: { buff[bufctr++] = CR; /* insert carriage return */ ! 1116: if (bufctr < BBUFSIZ) ! 1117: buff[bufctr++] = LF; /* insert Unix newline */ ! 1118: else ! 1119: nlflag = TRUE; /* insert newline on next sector */ ! 1120: } ! 1121: continue; ! 1122: } ! 1123: buff[bufctr++] = c; /* copy the char without change */ ! 1124: } ! 1125: attempts = 0; ! 1126: ! 1127: if (!bufctr) /* if EOF on sector boundary */ ! 1128: break; /* avoid sending empty sector */ ! 1129: ! 1130: do ! 1131: { sendbyte(SOH); /* send start of packet header */ ! 1132: if (FTP1) sendbyte(0); /* FTP 1 Type 0 Packet */ ! 1133: sendbyte(sectnum); /* send current sector number */ ! 1134: sendbyte(-sectnum-1); /* and its complement */ ! 1135: if (FTP1) sendbyte(STX); /* send STX */ ! 1136: checksum = 0; /* init checksum */ ! 1137: for (bufctr=0; bufctr < BBUFSIZ; bufctr++) ! 1138: { sendbyte(buff[bufctr]); /* send the byte */ ! 1139: if (ARPA && (buff[bufctr]==0xff)) /* ARPA Net FFH esc */ ! 1140: sendbyte(buff[bufctr]); /* send 2 FFH's for one */ ! 1141: checksum = ((checksum+buff[bufctr])&BITMASK); ! 1142: } ! 1143: /* while (readbyte(3) != TIMEOUT); flush chars from line */ ! 1144: if (FTP1) sendbyte(ETX); /* send ETX */ ! 1145: sendbyte(checksum); /* send the checksum */ ! 1146: if (FTP1) sendbyte(ENQ); /* send ENQ */ ! 1147: attempts++; ! 1148: if (FTP1) ! 1149: { sendresp = NAK; /* prepare for NAK */ ! 1150: if (readbyte(10) == ESC) sendresp = readbyte(10); ! 1151: } ! 1152: else ! 1153: sendresp = readbyte(10); /* get response */ ! 1154: if ((sendresp != ACK) && LOGFLAG) ! 1155: { fprintf(LOGFP, "Non-ACK Received on Sector %d\n", ! 1156: sectnum); ! 1157: if (sendresp == TIMEOUT) ! 1158: fprintf(LOGFP, "This Non-ACK was a TIMEOUT\n"); ! 1159: } ! 1160: } while((sendresp != ACK) && (attempts != RETRYMAX)); ! 1161: sectnum++; /* increment to next sector number */ ! 1162: } while (!sendfin && (attempts != RETRYMAX)); ! 1163: ! 1164: if (attempts == RETRYMAX) ! 1165: error("Remote System Not Responding", TRUE); ! 1166: ! 1167: attempts = 0; ! 1168: if (FTP1) ! 1169: while (attempts++ < 10) sendbyte(EOT); ! 1170: else ! 1171: { sendbyte(EOT); /* send 1st EOT */ ! 1172: while ((readbyte(15) != ACK) && (attempts++ < RETRYMAX)) ! 1173: sendbyte(EOT); ! 1174: if (attempts >= RETRYMAX) ! 1175: error("Remote System Not Responding on Completion", TRUE); ! 1176: } ! 1177: ! 1178: close(fd); ! 1179: restoremodes(FALSE); ! 1180: sleep(5); /* give other side time to return to terminal mode */ ! 1181: if (LOGFLAG) ! 1182: { fprintf(LOGFP, "\nSend Complete\n"); ! 1183: } ! 1184: printf("\n"); ! 1185: ! 1186: } ! 1187: ! 1188: /* print file size status information */ ! 1189: prfilestat(name) ! 1190: char *name; ! 1191: { ! 1192: struct stat filestatbuf; /* file status info */ ! 1193: ! 1194: stat(name, &filestatbuf); /* get file status bytes */ ! 1195: printf(" Estimated File Size %ldK, %ld Records, %ld Bytes", ! 1196: (filestatbuf.st_size/1024)+1, (filestatbuf.st_size/128)+1, ! 1197: filestatbuf.st_size); ! 1198: if (LOGFLAG) ! 1199: fprintf(LOGFP,"Estimated File Size %ldK, %ld Records, %ld Bytes\n", ! 1200: (filestatbuf.st_size/1024)+1, (filestatbuf.st_size/128)+1, ! 1201: filestatbuf.st_size); ! 1202: return; ! 1203: } ! 1204: ! 1205: /* get a byte from data stream -- timeout if "seconds" elapses */ ! 1206: readbyte(seconds) ! 1207: unsigned seconds; ! 1208: { ! 1209: char c; ! 1210: ! 1211: signal(SIGALRM,alarmfunc); /* catch alarms */ ! 1212: alarm((unsigned) seconds); /* set the alarm clock */ ! 1213: if (setjmp(env) == 0) { /* if <> 0 then returned from timeout */ ! 1214: if (read(0, &c, 1) < 0) /* get a char; error means time out */ ! 1215: { ! 1216: return(TIMEOUT); ! 1217: } ! 1218: } ! 1219: else return(TIMEOUT); ! 1220: alarm((unsigned) 0); /* turn off the alarm */ ! 1221: return((c&BITMASK)); /* return the char */ ! 1222: } ! 1223: ! 1224: /* send a byte to data stream */ ! 1225: sendbyte(data) ! 1226: char data; ! 1227: { ! 1228: char dataout; ! 1229: dataout = (data&BITMASK); /* mask for 7 or 8 bits */ ! 1230: write(1, &dataout, 1); /* write the byte */ ! 1231: return; ! 1232: } ! 1233: ! 1234: /* function for alarm clock timeouts */ ! 1235: void alarmfunc() ! 1236: { ! 1237: longjmp(env,1); /* this is basically a dummy function to force error */ ! 1238: /* status return on the "read" call in "readbyte" */ ! 1239: } ! 1240: ! 1241: /* print data on TTY setting */ ! 1242: ttyparams() ! 1243: { ! 1244: ! 1245: /* Obtain TTY parameters for JHU UNIX */ ! 1246: #ifdef JHU ! 1247: gtty(0, &ttystemp); /* get current tty params */ ! 1248: #endif ! 1249: ! 1250: /* Obtain TTY parameters for Version 7 UNIX */ ! 1251: #ifdef VER7 ! 1252: ioctl(0,TIOCGETP,&ttystemp); ! 1253: #endif ! 1254: ! 1255: /* Obtain TTY parameters for UNIX SYSTEM III */ ! 1256: #ifdef SYS3 ! 1257: gtty(0, &ttystemp); /* get current tty params */ ! 1258: #endif ! 1259: ! 1260: tty = ttyname(0); /* get name of tty */ ! 1261: stat(tty, &statbuf); /* get more tty params */ ! 1262: ! 1263: printf("\r\n\nTTY Device Parameter Display"); ! 1264: printf("\r\n\tTTY Device Name is %s\r\n\n", tty); ! 1265: printf("\tAny Parity Allowed "); pryn(ANYP); ! 1266: printf("\tEven Parity Allowed"); pryn(EVENP); ! 1267: printf("\tOdd Parity Allowed "); pryn(ODDP); ! 1268: printf("\tEcho Enabled "); pryn(ECHO); ! 1269: printf("\tLower Case Map "); pryn(LCASE); ! 1270: printf("\tTabs Expanded "); pryn(XTABS); ! 1271: printf("\tCR Mode Enabled "); pryn(CRMOD); ! 1272: printf("\tRAW Mode Enabled "); pryn(RAW); ! 1273: ! 1274: /* Print extended terminal characteristics for JHU UNIX */ ! 1275: #ifdef JHU ! 1276: printf("\tBinary Mode Enabled"); pryn1(NB8); ! 1277: printf("\tCR/LF in Col 72 "); pryn1(FOLD); ! 1278: printf("\tRecognize ^S/^Q "); pryn1(STALL); ! 1279: printf("\tSend ^S/^Q "); pryn1(TAPE); ! 1280: printf("\tTerminal can BS "); pryn1(SCOPE); ! 1281: printf("\r\n"); /* New line to separate topics */ ! 1282: printf("\tTerminal Paging is "); pryn1(PAGE); ! 1283: if (ttystemp.xflags&PAGE) ! 1284: printf("\t Lines/Page is %d\r\n", ttystemp.xflags&PAGE); ! 1285: printf("\r\n"); /* New line to separate topics */ ! 1286: printf("\tTTY Input Rate : "); ! 1287: prbaud(ttystemp.ispeed); /* print baud rate */ ! 1288: printf("\tTTY Output Rate : "); ! 1289: prbaud(ttystemp.ospeed); /* print output baud rate */ ! 1290: printf("\r\n"); /* New line to separate topics */ ! 1291: printf("\tMessages Enabled "); ! 1292: if (statbuf.st_mode&011) ! 1293: printf(": Yes\r\n"); ! 1294: else ! 1295: printf(": No\r\n"); ! 1296: #endif ! 1297: ! 1298: /* Print extended characteristics for Version 7 UNIX */ ! 1299: #ifdef VER7 ! 1300: printf("\tTTY Input Rate : "); ! 1301: prbaud(ttystemp.sg_ispeed); ! 1302: printf("\tTTY Output Rate : "); ! 1303: prbaud(ttystemp.sg_ospeed); /* print output baud rate */ ! 1304: #endif ! 1305: ! 1306: /* Print extended characteristics for UNIX SYSTEM III */ ! 1307: #ifdef SYS3 ! 1308: printf("\tTTY Input Rate : "); ! 1309: prbaud(ttystemp.sg_ispeed); ! 1310: printf("\tTTY Output Rate : "); ! 1311: prbaud(ttystemp.sg_ospeed); /* print output baud rate */ ! 1312: #endif ! 1313: ! 1314: } ! 1315: ! 1316: pryn(iflag) ! 1317: int iflag; ! 1318: { ! 1319: ! 1320: /* JHU UNIX flag test */ ! 1321: #ifdef JHU ! 1322: if (ttystemp.mode&iflag) ! 1323: #endif ! 1324: ! 1325: /* Version 7 UNIX flag test */ ! 1326: #ifdef VER7 ! 1327: if (ttystemp.sg_flags&iflag) ! 1328: #endif ! 1329: ! 1330: /* UNIX SYSTEM III flag test */ ! 1331: #ifdef SYS3 ! 1332: if (ttystemp.sg_flags&iflag) ! 1333: #endif ! 1334: ! 1335: printf(": Yes\r\n"); ! 1336: else ! 1337: printf(": No\r\n"); ! 1338: } ! 1339: ! 1340: /* Extended flag test for JHU UNIX only */ ! 1341: #ifdef JHU ! 1342: pryn1(iflag) ! 1343: int iflag; ! 1344: { ! 1345: if (ttystemp.xflags&iflag) ! 1346: printf(": Yes\r\n"); ! 1347: else ! 1348: printf(": No\r\n"); ! 1349: } ! 1350: #endif ! 1351: ! 1352: prbaud(speed) ! 1353: char speed; ! 1354: { ! 1355: switch (speed) { ! 1356: ! 1357: /* JHU UNIX speed flag cases */ ! 1358: #ifdef JHU ! 1359: case B0050 : printf("50"); break; ! 1360: case B0075 : printf("75"); break; ! 1361: case B0110 : printf("110"); break; ! 1362: case B0134 : printf("134.5"); break; ! 1363: case B0150 : printf("150"); break; ! 1364: case B0200 : printf("200"); break; ! 1365: case B0300 : printf("300"); break; ! 1366: case B0600 : printf("600"); break; ! 1367: case B1200 : printf("1200"); break; ! 1368: case B1800 : printf("1800"); break; ! 1369: case B2400 : printf("2400"); break; ! 1370: case B4800 : printf("4800"); break; ! 1371: case B9600 : printf("9600"); break; ! 1372: case EXT_A : printf("External A"); break; ! 1373: case EXT_B : printf("External B"); break; ! 1374: #endif ! 1375: ! 1376: /* Version 7 UNIX speed flag cases */ ! 1377: #ifdef VER7 ! 1378: case B50 : printf("50"); break; ! 1379: case B75 : printf("75"); break; ! 1380: case B110 : printf("110"); break; ! 1381: case B134 : printf("134.5"); break; ! 1382: case B150 : printf("150"); break; ! 1383: case B200 : printf("200"); break; ! 1384: case B300 : printf("300"); break; ! 1385: case B600 : printf("600"); break; ! 1386: case B1200 : printf("1200"); break; ! 1387: case B1800 : printf("1800"); break; ! 1388: case B2400 : printf("2400"); break; ! 1389: case B4800 : printf("4800"); break; ! 1390: case B9600 : printf("9600"); break; ! 1391: case EXTA : printf("External A"); break; ! 1392: case EXTB : printf("External B"); break; ! 1393: #endif ! 1394: ! 1395: /* UNIX SYSTEM III speed flag cases */ ! 1396: #ifdef SYS3 ! 1397: case B50 : printf("50"); break; ! 1398: case B75 : printf("75"); break; ! 1399: case B110 : printf("110"); break; ! 1400: case B134 : printf("134.5"); break; ! 1401: case B150 : printf("150"); break; ! 1402: case B200 : printf("200"); break; ! 1403: case B300 : printf("300"); break; ! 1404: case B600 : printf("600"); break; ! 1405: case B1200 : printf("1200"); break; ! 1406: case B1800 : printf("1800"); break; ! 1407: case B2400 : printf("2400"); break; ! 1408: case B4800 : printf("4800"); break; ! 1409: case B9600 : printf("9600"); break; ! 1410: case EXTA : printf("External A"); break; ! 1411: case EXTB : printf("External B"); break; ! 1412: #endif ! 1413: ! 1414: default : printf("Error"); break; ! 1415: } ! 1416: printf(" Baud\r\n"); ! 1417: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.