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

Defined functions

alarmfunc defined in line 1235; used 2 times
command defined in line 395; used 1 times
error defined in line 776; used 34 times
getbyte defined in line 805; used 1 times
gettype defined in line 510; used 2 times
help defined in line 466; used 2 times
infile defined in line 456; used 4 times
main defined in line 258; never used
prbaud defined in line 1352; used 6 times
prfilestat defined in line 1189; used 2 times
pryn defined in line 1316; used 8 times
pryn1 defined in line 1342; used 6 times
readbyte defined in line 1206; used 19 times
resetarpa defined in line 762; used 1 times
restoremodes defined in line 700; used 3 times
rfile defined in line 835; used 2 times
sendbyte defined in line 1225; used 37 times
setarpa defined in line 684; used 1 times
setmodes defined in line 520; used 2 times
sfile defined in line 1027; used 2 times
ttyparams defined in line 1242; used 2 times
yfile defined in line 791; used 2 times

Defined variables

ARPA defined in line 250; used 9 times
BIT7 defined in line 251; used 15 times
BITMASK defined in line 251; used 9 times
CMNDFLAG defined in line 250; used 5 times
DELFLAG defined in line 250; used 3 times
FTP1 defined in line 250; used 27 times
LOGFLAG defined in line 250; used 25 times
MUNGMODE defined in line 250; used 7 times
PMSG defined in line 250; used 5 times
RECVFLAG defined in line 250; used 6 times
SENDFLAG defined in line 250; used 6 times
STATDISP defined in line 251; used 3 times
XMITTYPE defined in line 249; used 8 times
buff defined in line 233; used 11 times
delay defined in line 252; used 12 times
env defined in line 255; used 2 times
filename defined in line 253; used 8 times
nbchr defined in line 234; used 4 times
pagelen defined in line 244; used 1 times
sccsid defined in line 2; never used
statbuf defined in line 230; used 12 times
tty defined in line 248; used 15 times
ttys defined in line 227; used 20 times
ttysnew defined in line 227; used 54 times
ttystemp defined in line 227; used 15 times
wason defined in line 236; used 9 times

Defined macros

ACK defined in line 170; used 8 times
BBUFSIZ defined in line 183; used 5 times
CAN defined in line 175; used 1 times
CR defined in line 172; used 2 times
CREATMODE defined in line 186; used 1 times
CTRLZ defined in line 177; used 2 times
DELDEFAULT defined in line 150; used 4 times
DO defined in line 209; used 1 times
DONT defined in line 210; used 1 times
ENQ defined in line 169; used 3 times
EOT defined in line 168; used 6 times
ERRORMAX defined in line 181; used 2 times
ESC defined in line 176; used 4 times
ETX defined in line 167; used 3 times
FALSE defined in line 156; used 39 times
IAC defined in line 208; used 4 times
LF defined in line 171; used 4 times
LOGDEFAULT defined in line 143; used 4 times
NAK defined in line 173; used 4 times
RETRYMAX defined in line 182; used 7 times
SOH defined in line 165; used 3 times
STX defined in line 166; used 3 times
SYN defined in line 174; used 3 times
TIMEOUT defined in line 180; used 8 times
TRBIN defined in line 213; used 4 times
TRUE defined in line 157; used 54 times
VERSION defined in line 155; used 4 times
WILL defined in line 211; used 1 times
WONT defined in line 212; used 1 times
Last modified: 1984-11-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2447
Valid CSS Valid XHTML 1.0 Strict