Annotation of 43BSD/contrib/umodem/umodem.c, revision 1.1.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.