Annotation of 43BSD/contrib/umodem/umodem.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.