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: }