home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 182_01 / umodem40.c < prev    next >
Text File  |  1990-07-31  |  46KB  |  1,194 lines

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