home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ncr9800 / ckvus3.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  40KB  |  1,354 lines

  1. /*  C K V U S 3 --  "User Interface" for NCR-VRX Kermit, part 3  */
  2.  
  3. /**********************************************************************
  4. *                                                                     *
  5. * IVS / MCS-Kermit REL 2                                              *
  6. * source code                                                         *
  7. *                                                                     *
  8. * Change History:                                                     *
  9. *                                                                     *
  10. *                1. Modify C-Kermit(4E) source code to                *
  11. *                   produce new module for MCS/IVS-Kermit             *
  12. *                   ORIGINAL RELEASE                                  *
  13. *                   June 22, 1990                                     *
  14. *                                                                     *
  15. *                                                                     *
  16. ***********************************************************************/
  17.  
  18.  
  19. /*
  20.  Author: Frank da Cruz (fdc@cunixc.cc.columbia.edu, FDCCU@CUVMA.BITNET),
  21.  Columbia University Center for Computing Activities.
  22.  First released January 1985.
  23.  Copyright (C) 1985, 1989, Trustees of Columbia University in the City of New
  24.  York.  Permission is granted to any individual or institution to use, copy, or
  25.  redistribute this software so long as it is not sold for profit, provided this
  26.  copyright notice is retained.
  27. */
  28.  
  29. /*  SET and REMOTE commands; screen, debug, interrupt, and logging functions */
  30.  
  31. /* Includes */
  32.  
  33. #include "ckcdeb.h"
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include "ckcker.h"
  37. #include "ckucmd.h"
  38. #include "ckuusr.h"
  39. #ifdef MCS_FLAG
  40. #include "mcs.h"
  41. #endif
  42.  
  43. /* Variables */
  44.  
  45. int userpad = SNDPADC;   /* storage for the user specified pad char
  46.                   used in spack to reset any SI packet
  47.                   pad char while in server mode          */
  48.  
  49. extern int     size, spsiz, rpsiz, urpsiz, npad, timint, rtimo, speed,
  50.                local, server, lpcapr, fmask, cmask, backgrd,
  51.                send_id, recv_id, send_num,  recv_num, send_renum,
  52.                recv_renum, send_addnum, recv_addnum, rptflg,
  53.                flow, displa, binary, fncnv, delay, parity, deblog,
  54.                escape, xargc, turn, duplex, cxseen, czseen, nfils,
  55.                ckxech, pktlog, seslog, tralog,  stdouf, turnch, bctr,
  56.                bctu, dfloc, mdmtyp, keep, maxtry,
  57.                rptflg, ebqflg, /* warn,*/ quiet, cnflg, timef,
  58.                spsizf, mypadn;
  59.  
  60. extern long     filcnt, tlci, tlco, ffc, tfc, fsize;
  61.  
  62. extern char     *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
  63. extern char     *cmarg, *cmarg2, **xargv, **cmlist;
  64. extern CHAR     stchr, mystch, sstate, padch, mypadc, eol, seol, ctlq;
  65. extern CHAR     filnam[], ttname[];
  66. char            *strcpy();
  67.  
  68. extern void errhdlr();
  69.  
  70. /* Declarations from cmd package */
  71.  
  72. extern char     cmdbuf[];                   /* Command buffer */
  73. extern char     atmbuf[];                   /* Atom buffer */
  74.  
  75. /* From main ckuser module... */
  76.  
  77. extern char     line[100], *lp;        /* Character buffer for anything */
  78. extern char     debfil[50],            /* Debugging log file name */
  79. pktfil[50],                            /* Packet log file name */
  80. sesfil[50],                            /* Session log file name */
  81. trafil[50];                            /* Transaction log file name */
  82.  
  83. extern int     tlevel;                  /* Take Command file level */
  84. extern FILE *tfile[];                   /* Array of take command fd's */
  85.  
  86.  
  87. /* Keyword tables for SET commands */
  88.  
  89. /* Block checks */
  90.  
  91. struct keytab blktab[] = {
  92.      "1", 1, 0,
  93.      "2", 2, 0,
  94.      "3", 3, 0
  95. };
  96.  
  97.  
  98. /* Duplex keyword table */
  99.  
  100. struct keytab dpxtab[] = {
  101.      "full",      0, 0,
  102.      "half",      1, 0
  103. };
  104.  
  105.  
  106. struct keytab filtab[] = {
  107.      "display", XYFILD, CM_INV,
  108.      "names",   XYFILN, 0,
  109.      "type",    XYFILT, 0
  110. };
  111.  
  112.  
  113. int     nfilp = (sizeof(filtab)
  114.  / sizeof(struct keytab )
  115. );
  116.  
  117. /* Send/Receive Parameters */
  118.  
  119. struct keytab srtab[] = {
  120.      "add-linenum", XYADD, CM_INV,
  121.      "id-fields", XYID, CM_INV,
  122.      "line-numbers", XYNUM, CM_INV,
  123.      "end-of-packet", XYEOL, 0,
  124.      "packet-length", XYLEN, 0,
  125.      "pad-character", XYPADC, 0,
  126.      "padding", XYNPAD, 0,
  127.      "renumber", XYRNUM, CM_INV,
  128.      "start-of-packet", XYMARK, 0,
  129.      "timeout", XYTIMO, 0
  130. };
  131.  
  132.  
  133. int     nsrtab = (sizeof(srtab)
  134.  / sizeof(struct keytab )
  135. );
  136.  
  137. /* Flow Control */
  138.  
  139. struct keytab flotab[] = {
  140.      "none",     0, 0,
  141.      "xon/xoff", 1, 0
  142. };
  143.  
  144.  
  145. int     nflo = (sizeof(flotab)
  146.  / sizeof(struct keytab )
  147. );
  148.  
  149. /*  Handshake characters  */
  150.  
  151. struct keytab hshtab[] = {
  152.      "bell", 007, 0,
  153.      "cr",   015, 0,
  154.      "esc",  033, 0,
  155.      "lf",   012, 0,
  156.      "none", 999, 0,                     /* (can't use negative numbers) */
  157.      "xoff", 023, 0,
  158.      "xon",  021, 0
  159. };
  160.  
  161.  
  162. int     nhsh = (sizeof(hshtab)
  163.  / sizeof(struct keytab )
  164. );
  165.  
  166. struct keytab fntab[] = {               /* File naming */
  167.      "converted", 1, 0,
  168.      "literal",   0, 0
  169. };
  170.  
  171.  
  172. struct keytab fttab[] = {               /* File types */
  173.      "binary",    1, 0,
  174.      "text",      0, 0
  175. };
  176.  
  177.  
  178. extern struct keytab mdmtab[] ;         /* Modem types (in module ckudia.c) */
  179. extern int     nmdm;
  180.  
  181. /* Parity keyword table */
  182.  
  183. struct keytab partab[] = {
  184.      "even",    'e', 0,
  185.      "mark",    'm', 0,
  186.      "none",      0, 0,
  187.      "odd",     'o', 0,
  188.      "space",   's', 0
  189. };
  190.  
  191.  
  192. int     npar = (sizeof(partab)
  193.  / sizeof(struct keytab )
  194. );
  195.  
  196.  
  197. /* On/Off table */
  198.  
  199. struct keytab onoff[] = {
  200.      "off",       0, 0,
  201.      "on",        1, 0
  202. };
  203.  
  204.  
  205. /* Incomplete File Disposition table */
  206.  
  207. struct keytab ifdtab[] = {
  208.      "discard",   0, 0,
  209.      "keep",      1, 0
  210. };
  211.  
  212.  
  213. /* Terminal parameters table */
  214.  
  215. struct keytab trmtab[] = {
  216.      "bytesize",  0, 0
  217. };
  218.  
  219.  
  220. /*  D O P R M  --  Set a parameter.  */
  221. /*
  222.  Returns:
  223.   -2: illegal input
  224.   -1: reparse needed
  225.    0: success
  226. */
  227. doprm(xx)
  228. int     xx;
  229. {
  230.      int     x, y, z;
  231.      char     *s;
  232.  
  233.      switch (xx) {
  234.  
  235.  
  236.      case XYEOL:     /* These have all been moved to set send/receive... */
  237.      case XYLEN:     /* Let the user know what to do. */
  238.      case XYMARK:
  239.      case XYNPAD:
  240.      case XYPADC:
  241.      case XYTIMO:
  242.      case XYID:
  243.      case XYNUM:
  244.      case XYRNUM:
  245.      case XYADD:
  246. #ifndef MCS_FLAG
  247.           printf("...Use 'set send' or 'set receive' instead.\n");
  248.           printf("Type 'help set send' / 'help set receive' for info.\n");
  249. #else
  250.           mcs_printf("...Use 'set send' or 'set receive' instead.\n");
  251.           mcs_printf("Type 'help set send' / 'help set receive' for info.\n");
  252. #endif
  253.           return(0);
  254.  
  255.      case XYIFD:                             /* Incomplete file disposition */
  256.           if ((y = cmkey(ifdtab, 2, "", "discard")) < 0)
  257.                return(y);
  258.           if ((x = cmcfm()) < 0)
  259.                return(x);
  260.           keep = y;
  261.           return(0);
  262.  
  263. /*   case XYLINE:
  264. *         if ((x = cmtxt("Device name", dftty, &s)) < 0)
  265. *              return(x);
  266. *         ttclos();                     * close old line, if any was open *
  267. *
  268. *         * Maybe let ttopen figure it out... *
  269. *         x = strcmp(s, dftty) ? -1 : dfloc;
  270. *         if (ttopen(s, &x, mdmtyp) < 0 ) {     * Can we open the new line? *
  271. *               errhdlr("doprm: Sorry, can't open line");
  272. *               return(-2);                     * If not, give bad return *
  273. *          }
  274. *          if (x > -1)
  275. *               local = x;              * Set local/remote status. *
  276. *          strcpy(ttname, s);           * OK, copy name into real place. *
  277. *          if (!local)
  278. *               speed = -1;             * If remote, say speed unknown. *
  279. *          if (deblog)
  280. *               debug(F111, "set line ", ttname, local);
  281. *          return(0);
  282. */
  283.      case XYCHKT:
  284.           if ((y = cmkey(blktab, 3, "", "1")) < 0)
  285.                return(y);
  286.           if ((x = cmcfm()) < 0)
  287.                return(x);
  288.           bctr = y;
  289.           return(0);
  290.  
  291.      case XYDEBU:
  292.           return(seton(&deblog));
  293.  
  294. /*    case XYDELA:
  295. *          y = cmnum("Number of seconds before starting to send",
  296. *               "5", 10, &x);
  297. *          if (deblog)
  298. *               debug(F101, "XYDELA: y", "", y);
  299. *          return(setnum(&delay, x, y, 94));
  300. */
  301.      case XYDUPL:
  302.           if ((y = cmkey(dpxtab, 2, "", "full")) < 0)
  303.                return(y);
  304.           if ((x = cmcfm()) < 0)
  305.                return(x);
  306.           duplex = y;
  307.           return(0);
  308.  
  309.      case XYESC:
  310.           y = cmnum("Decimal ASCII code for escape character",
  311.                "", 10, &x);
  312.           return(setcc(&escape, x, y));
  313.  
  314.      case XYFILE:
  315.           if ((y = cmkey(filtab, nfilp, "File parameter", "")) <
  316.               0)
  317.                return(y);
  318.           switch (y) {
  319.                int     z;
  320. /*        case XYFILD:                     * Display *
  321. *              y = seton(&z);
  322. *              if (y < 0)
  323. *                   return(y);
  324. *              quiet = !z;
  325. *              return(0);
  326. */
  327.           case XYFILN:                    /* Names */
  328.                if ((x = cmkey(fntab, 2, "how to handle filenames",
  329.                     "converted")) < 0)
  330.                     return(x);
  331.                if ((z = cmcfm()) < 0)
  332.                     return(z);
  333.                fncnv = x;
  334.                return(0);
  335.  
  336.           case XYFILT:                    /* Type */
  337.                if ((x = cmkey(fttab, 2, "type of file", "text")) <
  338.                    0)
  339.                     return(x);
  340.                if ((y = cmnum("file byte size (7 or 8)", "8",
  341.                     10, &z)) < 0)
  342.                     return(y);
  343.                if (z != 7 && z != 8) {
  344. #ifndef MCS_FLAG
  345.                     printf("\n?The choices are 7 and 8\n");
  346. #else
  347.                     mcs_printf("\n?The choices are 7 and 8\n");
  348. #endif
  349.                     return(-2);
  350.                }
  351.                if ((y = cmcfm()) < 0)
  352.                     return(y);
  353.                binary = x;
  354.                if (z == 7)
  355.                     fmask = 0177;
  356.                else if (z == 8)
  357.                     fmask = 0377;
  358.                return(0);
  359.  
  360.                /* case XYFILW:                     *  Warning/Write-Protect *
  361.             return(seton(&warn));   */
  362.  
  363.           default:
  364. #ifndef MCS_FLAG
  365.                printf("?unexpected file parameter\n");
  366. #else
  367.                mcs_printf("?unexpected file parameter\n");
  368. #endif
  369.                return(-2);
  370.           }
  371.  
  372.      case XYFLOW:                            /* Flow control */
  373.           if ((y = cmkey(flotab, nflo, "", "xon/xoff")) < 0)
  374.                return(y);
  375.           if ((x = cmcfm()) < 0)
  376.                return(x);
  377.           flow = y;
  378.           return(0);
  379.  
  380.      case XYHAND:                            /* Handshake */
  381.           if ((y = cmkey(hshtab, nhsh, "", "none")) < 0)
  382.                return(y);
  383.           if ((x = cmcfm()) < 0)
  384.                return(x);
  385.           turn = (y > 0127) ? 0 : 1 ;
  386.           turnch = y;
  387.           return(0);
  388.  
  389. /*    case XYMODM:
  390. *          if ((x = cmkey(mdmtab, nmdm, "type of modem, direct means none",
  391. *               "direct")) < 0)
  392. *               return(x);
  393. *          if ((z = cmcfm()) < 0)
  394. *               return(z);
  395. *          mdmtyp = x;
  396. *          return(0);
  397. */
  398.      case XYPARI:                            /* Parity */
  399.           if ((y = cmkey(partab, npar, "", "none")) < 0)
  400.                return(y);
  401.           if ((x = cmcfm()) < 0)
  402.                return(x);
  403.  
  404.           /* If parity not none, then we also want 8th-bit prefixing */
  405.  
  406.           if (parity = y)
  407.                ebqflg = 1;
  408.           else
  409.                ebqflg = 0;
  410.           return(0);
  411.  
  412.      case XYPROM:
  413. #ifndef MCS_FLAG
  414.           if ((x = cmtxt("Program's command prompt", "IVS-Kermit>",
  415. #else
  416.           if ((x = cmtxt("Program's command prompt", "MCS-Kermit>",
  417. #endif
  418.                &s)) < 0)
  419.                return(x);
  420.  
  421.           if (*s == '\42') {             /* Quoted string? */
  422.                x = strlen(s) - 1;        /* Yes, strip quotes. */
  423.                if (*(s + x) == '\42')    /* This allows leading or trailing */
  424.                     *(s + x) = '\0';     /* blanks. */
  425.                s++;
  426.           }
  427.           cmsetp(s);
  428.           return(0);
  429.  
  430.      case XYRETR:                            /* Per-packet retry limit */
  431.           y = cmnum("Maximum retries per packet", "10", 10, &x);
  432.           return(setnum(&maxtry, x, y, 94));
  433.  
  434.      case XYTERM:                            /* Terminal parameters */
  435.           if ((y = cmkey(trmtab, 1, "", "bytesize")) < 0)
  436.                return(y);
  437.           switch (y) {
  438.           case 0:
  439.                if ((y = cmnum("bytesize for terminal connection",
  440.                     "8", 10, &x)) < 0)
  441.                     return(y);
  442.                if (x != 7 && x != 8) {
  443. #ifndef MCS_FLAG
  444.                     printf("\n?The choices are 7 and 8\n");
  445. #else
  446.                     mcs_printf("\n?The choices are 7 and 8\n");
  447. #endif
  448.                     return(-2);
  449.                }
  450.                if ((y = cmcfm()) < 0)
  451.                     return(y);
  452.                if (x == 7)
  453.                     cmask = 0177;
  454.                else if (x == 8)
  455.                     cmask = 0377;
  456.                return(y);
  457.           default:       /* Add more cases when we think of more parameters */
  458.                return(-2);
  459.           }
  460.  
  461.           /* SET SEND/RECEIVE... */
  462.  
  463.      case XYRECV:
  464.      case XYSEND:
  465.           if (xx == XYRECV)
  466.                strcpy(line, "Parameter for inbound packets");
  467.           else
  468.                strcpy(line, "Parameter for outbound packets");
  469.  
  470.           if ((y = cmkey(srtab, nsrtab, line, "")) < 0)
  471.                return(y);
  472.           switch (y) {
  473.  
  474.           case XYEOL:
  475.                y = cmnum("Decimal ASCII code for packet terminator",
  476.                     "13", 10, &x);
  477.                if ((y = setcc(&z, x, y)) < 0)
  478.                     return(y);
  479.                if (xx == XYRECV)
  480.                     eol = z;
  481.                else
  482.                     seol = z;
  483.                return(y);
  484.  
  485.           case XYLEN:
  486.                y = cmnum("Maximum number of characters in a packet",
  487.                     "90", 10, &x);
  488.                if (xx == XYRECV) {                 /* Receive... */
  489.                     if ((y = setnum(&z, x, y, MAXRP)) < 0)
  490.                          return(y);
  491.                     urpsiz = z;
  492.                     rpsiz =  (z > 94) ? 94 : z;
  493.                } else {                            /* Send... */
  494.                     if ((y = setnum(&z, x, y, MAXSP)) < 0)
  495.                          return(y);
  496.                     spsiz = z;        /*   Set it and flag that it was set */
  497.                     spsizf = 1;       /*   to allow overriding Send-Init. */
  498.                }
  499.                if (z > 94 && !backgrd)
  500. #ifndef MCS_FLAG
  501.                     printf("Extended-length packets requested\n");
  502. #else
  503.                     mcs_printf("Extended-length packets requested\n");
  504. #endif
  505.                return(y);
  506.  
  507.           case XYMARK:
  508.                y = cmnum("Decimal ASCII code for packet-start character",
  509.                     "1", 10, &x);
  510.                if ((y = setcc(&z, x, y)) < 0)
  511.                     return(y);
  512.                if (xx == XYRECV)
  513.                     stchr = z;
  514.                else
  515.                     mystch = z;
  516.                return(y);
  517.  
  518.           case XYNPAD:                            /* Padding */
  519.                y = cmnum("How many padding characters for inbound packets",
  520.                     "0", 10, &x);
  521.                if ((y = setnum(&z, x, y, 94)) < 0)
  522.                     return(y);
  523.                if (xx == XYRECV)
  524.                     mypadn = z;
  525.                else
  526.                     npad = z;
  527.                return(y);
  528.  
  529.           case XYPADC:                            /* Pad character */
  530.                y = cmnum("Decimal ASCII code for inbound pad character",
  531.                     "0", 10, &x);
  532.                if ((y = setcc(&z, x, y)) < 0)
  533.                     return(y);
  534.                if (xx == XYRECV)
  535.                     mypadc = z;
  536.                else {                 /* disabling \0 padd char
  537.                                          to prevent mcs errors
  538.                                          PEG May 16, 1990         */
  539.                     if (z == 0) {
  540. #ifndef MCS_FLAG
  541.                         printf("\nvalid send pad-char 1 - 31 and 127.\n");
  542. #else
  543.                         mcs_printf("\nvalid send pad-char 1 - 31 and 127.\n");
  544. #endif
  545.                         return (-2);
  546.                     }
  547.                     else padch = userpad = z;
  548.                }
  549.                return(y);
  550.  
  551.           case XYTIMO:
  552.                y = cmnum("Interpacket timeout interval", "5",
  553.                     10, &x);
  554.                if ((y = setnum(&z, x, y, 94)) < 0)
  555.                     return(y);
  556.                if (xx == XYRECV) {
  557.                     timef = 1;
  558.                     timint = z;
  559.                } else
  560.                     rtimo = z;
  561.                return(y);
  562.  
  563. /*         case XYID:  * Flag for id-fields in SPUR files *
  564. *               if ((y = cmkey(ifdtab, 2, "", "keep")) < 0)
  565. *                    return(y);
  566. *               if ((x = cmcfm()) < 0)
  567. *                    return(x);
  568. *               if (xx == XYRECV)
  569. *                    recv_id = y;
  570. *               else
  571. *                    send_id = y;
  572. *               return(0);
  573. *          case XYNUM:  * Flag for line number fields in SPUR files *
  574. *               if ((y = cmkey(ifdtab, 2, "", "keep")) < 0)
  575. *                    return(y);
  576. *               if ((x = cmcfm()) < 0)
  577. *                    return(x);
  578. *               if (xx == XYRECV)
  579. *                    recv_num = y;
  580. *               else
  581. *                    send_num = y;
  582. *               return(0);
  583. *
  584. *                * Flag for renumbering line number fields in SPUR files *
  585. *          case XYRNUM:
  586. *               if ((y = cmkey(onoff, 2, "", "off")) < 0)
  587. *                    return(y);
  588. *               if ((x = cmcfm()) < 0)
  589. *                    return(x);
  590. *               if (xx == XYRECV)
  591. *                    recv_renum = y;
  592. *               else
  593. *                    send_renum = y;
  594. *               return(0);
  595. *          case XYADD:  * Flag for adding line number fields in SPUR files *
  596. *               if ((y = cmkey(onoff, 2, "", "off")) < 0)
  597. *                    return(y);
  598. *               if ((x = cmcfm()) < 0)
  599. *                    return(x);
  600. *               if (xx == XYRECV)
  601. *                    recv_addnum = y;
  602. *               else
  603. *                    send_addnum = y;
  604. *               return(0);
  605. */
  606.           }
  607.  
  608. /*   case XYSPEE:
  609. *         if (!local) {
  610. *            printf("\nSpeed setting can only be done on an external line\n");
  611. *            printf("You must 'set line' before issuing this command\n");
  612. *            return(0);
  613. *         }
  614. *         lp = line;
  615. *         sprintf(lp, "Baud rate for %s", ttname);
  616. *         if ((y = cmnum(line, "", 10, &x)) < 0)
  617. *              return(y);
  618. *         if (y = (cmcfm()) < 0)
  619. *              return(y);
  620. *         y = chkspd(x);
  621. *         if (y < 0)
  622. *              printf("?Unsupported line speed - %d\n", x);
  623. *         else {
  624. *              speed = y;
  625. *              if (!backgrd)
  626. *                   printf("%s: %d baud\n", ttname, speed);
  627. *         }
  628. */        return(0);
  629.  
  630.      default:
  631.           if ((x = cmcfm()) < 0)
  632.                return(x);
  633. #ifndef MCS_FLAG
  634.           printf("V-Kermit does not support: %s\n", cmdbuf);
  635. #else
  636.           sprintf(print_str,"V-Kermit does not support: %s\n", cmdbuf);
  637.           mcs_printf(print_str);
  638. #endif
  639.           return(0);
  640.      }
  641. }
  642.  
  643.  
  644. /*  C H K S P D  --  Check if argument is a valid baud rate  */
  645.  
  646. chkspd(x)
  647. int     x;
  648. {
  649.      switch (x) {
  650.      case 0:
  651.      case 110:
  652.      case 150:
  653.      case 300:
  654.      case 600:
  655.      case 1200:
  656.      case 1800:
  657.      case 2400:
  658.      case 4800:
  659.      case 9600:
  660.      case 19200:
  661.           return(x);
  662.      default:
  663.           return(-1);
  664.      }
  665. }
  666.  
  667.  
  668. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  669.  
  670. seton(prm)
  671. int     *prm;
  672. {
  673.      int     x, y;
  674.      if ((y = cmkey(onoff, 2, "", "on")) < 0)
  675.           return(y);
  676.      if ((x = cmcfm()) < 0)
  677.           return(x);
  678.      *prm = y;
  679.      return(0);
  680. }
  681.  
  682.  
  683. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  684. /*
  685.  Call with x - number from cnum parse, y - return code from cmnum
  686. */
  687. setnum(prm, x, y, max)
  688. int     x, y, *prm, max;
  689. {
  690.      if (deblog)
  691.           debug(F101, "setnum", "", y);
  692.  
  693.      if (y < 0)
  694.           return(y);
  695.  
  696.      if (x > max) {
  697. #ifndef MCS_FLAG
  698.           printf("\n?Sorry, %d is the maximum\n", max);
  699. #else
  700.           sprintf(print_str,"\n?Sorry, %d is the maximum\n", max);
  701.           mcs_printf(print_str);
  702. #endif
  703.           return(-2);
  704.      }
  705.  
  706. #ifdef MCS_FLAG
  707.      if (x == -562)         /* value that indicates invalid number */
  708.        sprintf(print_str,"\n?not a number - %s\n",atmbuf);
  709. #endif
  710.  
  711.      if ((y = cmcfm()) < 0)
  712.           return(y);
  713.  
  714. #ifdef MCS_FLAG
  715.      /* If we got to here and if something other then a number
  716.       * was entered, then no back spaces were entered on the line.
  717.       * So, reparsing is not necessary. Just put out an error msg. */
  718.  
  719.       if (x == -562) {
  720.         mcs_printf(print_str);
  721.         return(-2);
  722.       }
  723. #endif
  724.  
  725.      *prm = x;
  726.      return(0);
  727. }
  728.  
  729.  
  730. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  731.  
  732. setcc(prm, x, y)
  733. int     x, y, *prm;
  734. {
  735.      if (y < 0)
  736.           return(y);
  737.      if ((x > 037) && (x != 0177)) {
  738. #ifndef MCS_FLAG
  739.           printf("\n?Not in ASCII control range - %d\n", x);
  740. #else
  741.           sprintf(print_str,"\n?Not in ASCII control range - %d\n", x);
  742.           mcs_printf(print_str);
  743. #endif
  744.           return(-2);
  745.      }
  746.      if ((y = cmcfm()) < 0)
  747.           return(y);
  748.      *prm = x;
  749.      return(0);
  750. }
  751.  
  752.  
  753. /*  D O R M T  --  Do a remote command  */
  754.  
  755. dormt(xx)
  756. int     xx;
  757. {
  758.    return(-2);   /* stub for deleted featured this function
  759.                     should never be called but just in case..
  760. *
  761. *    int     x;
  762. *    char     *s, sbuf[50], *s2;
  763. *
  764. *    if (xx < 0)
  765. *         return(xx);
  766. *    switch (xx) {
  767. *
  768. *     case XZCWD:                              * CWD *
  769. *          if ((x = cmtxt("Remote directory name", "", &s)) < 0)
  770. *               return(x);
  771. *          if (deblog)
  772. *               debug(F111, "XZCWD: ", s, x);
  773. *          *sbuf = NUL;
  774. *          s2 = sbuf;
  775. *          if (*s != NUL) {                     * If directory name given, *
  776. *                * get password on separate line. *
  777. *               if (tlevel > -1) {               * From take file... *
  778. *
  779. *                    if (fgets(sbuf, 50, tfile[tlevel]) ==
  780. *                        NULL)
  781. *                         fatal("take file ends prematurely in 'remote cwd'");
  782. *                    if (deblog)
  783. *                         debug(F110, " pswd from take file",
  784. *                              s2, 0);
  785. *                    for (x = strlen(sbuf);  x > 0 && (sbuf[x-1] ==
  786. *                        '\n' || sbuf[x-1] == '\r');  x--)
  787. *                         sbuf[x-1] = '\0';
  788. *
  789. *               } else {                         * From terminal... *
  790. *
  791. *                    printf(" Password: ");               * get a password *
  792. *                    while (((x = getchar()) != NL) && (x !=
  793. *                        CR)) {  * with no echo *
  794. *                         if ((x &= 0177) == '?') {
  795. *                            printf("Remote directory Password: ");
  796. *                              s2 = sbuf;
  797. *                              *sbuf = NUL;
  798. *
  799. *                            * Mini command line editor... *
  800. *                         } else if (x == ESC)
  801. *                              putchar(BEL);
  802. *                         else if (x == BS || x == 0177)
  803. *                              s2--;
  804. *                         else if (x == 025) {     * Ctrl-U *
  805. *                              s2 = sbuf;
  806. *                              *sbuf = NUL;
  807. *                         } else
  808. *                              *s2++ = x;
  809. *                    }
  810. *                    *s2 = NUL;
  811. *                    putchar('\n');
  812. *               }
  813. *               s2 = sbuf;
  814. *          } else
  815. *               s2 = "";
  816. *          if (deblog)
  817. *               debug(F110, " password", s2, 0);
  818. *          sstate = setgen('C', s, s2, "");
  819. *          return(0);
  820. *
  821. *     case XZDEL:                              * Delete *
  822. *          if ((x = cmtxt("Name of remote file(s) to delete", "",
  823. *               &s)) < 0)
  824. *               return(x);
  825. *          return(sstate = rfilop(s, 'E'));
  826. *
  827. *     case XZDIR:                              * Directory *
  828. *          if ((x = cmtxt("Remote directory or file specification",
  829. *               "", &s)) < 0)
  830. *               return(x);
  831. *          return(sstate = setgen('D', s, "", ""));
  832. *
  833. *     case XZHLP:                              * Help *
  834. *          if (x = (cmcfm()) < 0)
  835. *               return(x);
  836. *          sstate = setgen('H', "", "", "");
  837. *          return(0);
  838. *
  839. *     case XZHOS:                              * Host *
  840. *          if ((x = cmtxt("Command for remote system", "", &cmarg)) <
  841. *              0)
  842. *               return(x);
  843. *          return(sstate = 'c');
  844. *
  845. *     case XZPRI:                              * Print *
  846. *          if ((x = cmtxt("Remote file(s) to print on remote printer",
  847. *               "", &s)) < 0)
  848. *               return(x);
  849. *          return(sstate = rfilop(s, 'S'));
  850. *
  851. *     case XZSPA:                              * Space *
  852. *          if ((x = cmtxt("Confirm, or remote directory name",
  853. *              "", &s)) < 0)
  854. *               return(x);
  855. *          return(sstate = setgen('U', s, "", ""));
  856. *
  857. *     case XZTYP:                              * Type *
  858. *          if ((x = cmtxt("Remote file specification", "", &s)) <
  859. *              0)
  860. *               return(x);
  861. *          return(sstate = rfilop(s, 'T'));
  862. *
  863. *     case XZWHO:
  864. *          if ((x = cmtxt("Remote user name, or carriage return",
  865. *               "", &s)) < 0)
  866. *               return(x);
  867. *          return(sstate = setgen('W', s, "", ""));
  868. *
  869. *     default:
  870. *          if (x = (cmcfm()) < 0)
  871. *               return(x);
  872. *         printf("not working yet - %s\n", cmdbuf);
  873. *         return(-2);
  874. *    }
  875. */
  876.  
  877. }
  878.  
  879. /*  R F I L O P  --  Remote File Operation  */
  880.  
  881. rfilop(s, t)
  882. char     *s, t;
  883. {
  884.      if (*s == NUL) {
  885. #ifndef MCS_FLAG
  886.           printf("?File specification required\n");
  887. #else
  888.           mcs_printf("?File specification required\n");
  889. #endif
  890.           return(-2);
  891.      }
  892.      if (deblog)
  893.           debug(F111, "rfilop", s, t);
  894.      return(setgen(t, s, "", ""));
  895. }
  896.  
  897.  
  898. /*  S C R E E N  --  Screen display function  */
  899.  
  900. /*  screen(f,c,n,s)
  901.       f - argument descriptor
  902.       c - a character or small integer
  903.       n - a long integer
  904.       s - a string.
  905.  Fill in this routine with the appropriate display update for the system.
  906.  This version is for a dumb tty.
  907. */
  908. screen(f, c, n, s)
  909. int     f;
  910. long     n;
  911. char     c;
  912. char     *s;
  913. {
  914.      static int     p = 0;                   /* Screen position */
  915.      int     len;                            /* Length of string */
  916.      char     buf[80];                       /* Output buffer */
  917.      len = strlen(s);                    /* Length of string */
  918.      if (!displa || quiet)
  919.           return;       /* No update if display flag off */
  920.  
  921.      switch (f) {
  922.  
  923.      case SCR_FN:                            /* filename */
  924.           conoll("");
  925.           conol(s);
  926.           conoc(SP);
  927.           p = len + 1;
  928.           return;
  929.  
  930.      case SCR_AN:                            /* as-name */
  931.           if (p + len > 75) {
  932.                conoll("");
  933.                p = 0;
  934.           }
  935.           conol("=> ");
  936.           conol(s);
  937.           if ((p += (len + 3)) > 78) {
  938.                conoll("");
  939.                p = 0;
  940.           }
  941.           return;
  942.  
  943.      case SCR_FS:                            /* file-size */
  944.           sprintf(buf, ", Size: %ld", n);
  945.           conoll(buf);
  946.           p = 0;
  947.           return;
  948.  
  949.      case SCR_XD:                            /* x-packet data */
  950.           conoll("");
  951.           conoll(s);
  952.           p = 0;
  953.           return;
  954.  
  955.      case SCR_ST:                            /* File status */
  956.           switch (c) {
  957.           case ST_OK:                     /*  Transferred OK */
  958.                if ((p += 5) > 78) {
  959.                     conoll("");
  960.                     p = 0;
  961.                }
  962.                conoll(" [OK]");
  963.                p += 5;
  964.                return;
  965.  
  966.           case ST_DISC:                   /*  Discarded */
  967.                if ((p += 12) > 78) {
  968.                     conoll("");
  969.                     p = 0;
  970.                }
  971.                conoll(" [discarded]");
  972.                p += 12;
  973.                return;
  974.  
  975.           case ST_INT:                    /*  Interrupted */
  976.                if ((p += 14) > 78) {
  977.                     conoll("");
  978.                     p = 0;
  979.                }
  980.                conoll(" [interrupted]");
  981.                p += 14;
  982.                return;
  983.  
  984.           case ST_SKIP:                   /*  Skipped */
  985.                conoll("");
  986.                conol("Skipping ");
  987.                conoll(s);
  988.                p = 0;
  989.                return;
  990.  
  991.           default:
  992.                conoll("*** screen() called with bad status ***");
  993.                p = 0;
  994.                return;
  995.           }
  996.  
  997.      case SCR_PN:                            /* Packet number */
  998.           sprintf(buf, "%s: %ld", s, n);
  999.           conol(buf);
  1000.           p += strlen(buf);
  1001.           return;
  1002.  
  1003.      case SCR_PT:                    /* Packet type or pseudotype */
  1004.           if (c == 'Y')
  1005.                return;               /* Don't bother with ACKs */
  1006.           if (c == 'D') {            /* Only show every 4th data packet */
  1007.                if (n % 4)
  1008.                     return;
  1009.                c = '.';
  1010.           }
  1011.           conoc(c);                  /* Display the character. */
  1012.           return;
  1013.  
  1014.      case SCR_TC:                    /* transaction complete */
  1015.           conoc(BEL);
  1016.           return;
  1017.  
  1018.      case SCR_EM:                            /* Error message */
  1019.           conoll("");
  1020.           conoc('?');
  1021.           conoll(s);
  1022.           p = 0;
  1023.           return;           /* +1   */
  1024.  
  1025.      case SCR_WM:                            /* Warning message */
  1026.           conoll("");
  1027.           conoll(s);
  1028.           p = 0;
  1029.           return;
  1030.  
  1031.      case SCR_TU:                            /* Undelimited text */
  1032.           if ((p += len) > 78) {
  1033.                conoll("");
  1034.                p = len;
  1035.           }
  1036.           conol(s);
  1037.           return;
  1038.  
  1039.      case SCR_TN:                            /* Text delimited at beginning */
  1040.           conoll("");
  1041.           conol(s);
  1042.           p = len;
  1043.           return;
  1044.  
  1045.      case SCR_TZ:                            /* Text delimited at end */
  1046.           if ((p += len) > 78) {
  1047.                conoll("");
  1048.                p = len;
  1049.           }
  1050.           conoll(s);
  1051.           return;
  1052.  
  1053.      case SCR_QE:                            /* Quantity equals */
  1054.           sprintf(buf, "%s: %ld", s, n);
  1055.           conoll(buf);
  1056.           p = 0;
  1057.           return;
  1058.  
  1059.      default:
  1060.           conoll("*** screen() called with bad object ***");
  1061.           p = 0;
  1062.           return;
  1063.      }
  1064. }
  1065.  
  1066.  
  1067. /*  I N T M S G  --  Issue message about terminal interrupts  */
  1068.  
  1069. intmsg(n)
  1070. long     n;
  1071. {
  1072.      extern char     *chstr();
  1073.      char     buf[80];
  1074.  
  1075.      if ((!displa) || (quiet))
  1076.           return;
  1077.      if (n == 1) {
  1078.           screen(SCR_TN, 0, 0l,
  1079.                  "CTRL-F to cancel file,  CTRL-R to resend current packet");
  1080.           screen(SCR_TN, 0, 0l,
  1081.                  "CTRL-B to cancel batch, CTRL-A for status report: ");
  1082.      } else
  1083.           screen(SCR_TU, 0, 0l, " ");
  1084. }
  1085.  
  1086.  
  1087. /*  C H K I N T  --  Check for console interrupts  */
  1088.  
  1089. /*** should rework not to destroy typeahead ***/
  1090.  
  1091. chkint()
  1092. {
  1093.      int     ch, cn;
  1094.  
  1095.      if ((!local) || (quiet))
  1096.           return(0); /* Only do this if local & not quiet */
  1097.  
  1098.      cn = conchk();                      /* Any input waiting? */
  1099.  
  1100.      if (deblog)
  1101.           debug(F101, "conchk", "", cn);
  1102.  
  1103.      while (cn > 0) {                    /* Yes, read it. */
  1104.           cn--;
  1105.           /* give read 5 seconds for interrupt character */
  1106.  
  1107.           if ((ch = coninc(5)) < 0)
  1108.                return(0);
  1109.  
  1110.           switch (ch & 0177) {
  1111.           case 0001:                  /* CTRL-A */
  1112.                screen(SCR_TN, 0, 0l, "^A  Status report:");
  1113.                screen(SCR_TN, 0, 0l, " file type: ");
  1114.                if (binary)
  1115.                     screen(SCR_TZ, 0, 0l, "binary");
  1116.                else
  1117.                     screen(SCR_TZ, 0, 0l, "text");
  1118.                screen(SCR_QE, 0, (long)filcnt, " file number");
  1119.                screen(SCR_QE, 0, (long)ffc,   " characters ");
  1120.                screen(SCR_QE, 0, (long)bctu,  " block check");
  1121.                screen(SCR_QE, 0, (long)rptflg, " compression");
  1122.                screen(SCR_QE, 0, (long)ebqflg, " 8th-bit prefixing");
  1123.                continue;
  1124.           case 0002:                  /* CTRL-B */
  1125.                screen(SCR_TN, 0, 0l, "^B - Cancelling Batch ");
  1126.                czseen = 1;
  1127.                continue;
  1128.           case 0006:                  /* CTRL-F */
  1129.                screen(SCR_TN, 0, 0l, "^F - Cancelling File ");
  1130.                cxseen = 1;
  1131.                continue;
  1132.           case 0022:                  /* CTRL-R */
  1133.                screen(SCR_TN, 0, 0l, "^R - Resending ");
  1134.                resend();
  1135.                return(1);
  1136.           default:                    /* Anything else, just ignore */
  1137.                screen(SCR_TU, 0, 0l, " [Ignored] ");
  1138.                continue;
  1139.           }
  1140.      }
  1141.      return(0);
  1142. }
  1143.  
  1144.  
  1145. #define TBUFL 300
  1146. /*  T L O G  --  Log a record in the transaction file  */
  1147. /*
  1148.  Call with a format and 3 arguments: two strings and a number:
  1149.    f  - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
  1150.    s1,s2 - String arguments 1 and 2.
  1151.    n  - Int, argument 3.
  1152. */
  1153. tlog(f, s1, s2, n)
  1154. int     f;
  1155. long     n;
  1156. char     *s1, *s2;
  1157. {
  1158.      static char     s[TBUFL];
  1159.      char     *sp = s;
  1160.      int     x;
  1161.  
  1162.      if (!tralog)
  1163.           return;                /* If no transaction log, don't */
  1164.      switch (f) {
  1165.      case F000:                      /* 0 (special) "s1 n s2"  */
  1166.           if (strlen(s1) + strlen(s2) + 15 > TBUFL)
  1167.                sprintf(sp, "?T-Log string too long\n");
  1168.           else
  1169.                sprintf(sp, "%s %ld %s\n", s1, n, s2);
  1170.           zsout(ZTFILE, s);
  1171.           break;
  1172.      case F001:                      /* 1, " n" */
  1173.           sprintf(sp, " %ld\n", n);
  1174.           zsout(ZTFILE, s);
  1175.           break;
  1176.      case F010:                      /* 2, "[s2]" */
  1177.           x = strlen(s2);
  1178.           if (s2[x] == '\n')
  1179.                s2[x] = '\0';
  1180.           if (x + 6 > TBUFL)
  1181.                sprintf(sp, "?T-Log string too long\n");
  1182.           else
  1183.                sprintf(sp, "[%s]\n", s2);
  1184.           zsout(ZTFILE, "");
  1185.           break;
  1186.      case F011:                      /* 3, "[s2] n" */
  1187.           x = strlen(s2);
  1188.           if (s2[x] == '\n')
  1189.                s2[x] = '\0';
  1190.           if (x + 6 > TBUFL)
  1191.                sprintf(sp, "?T-Log string too long\n");
  1192.           else
  1193.                sprintf(sp, "[%s] %ld\n", s2, n);
  1194.           zsout(ZTFILE, s);
  1195.           break;
  1196.      case F100:                      /* 4, "s1" */
  1197.           zsoutl(ZTFILE, s1);
  1198.           break;
  1199.      case F101:                      /* 5, "s1: n" */
  1200.           if (strlen(s1) + 15 > TBUFL)
  1201.                sprintf(sp, "?T-Log string too long\n");
  1202.           else
  1203.                sprintf(sp, "%s: %ld\n", s1, n);
  1204.           zsout(ZTFILE, s);
  1205.           break;
  1206.      case F110:                      /* 6, "s1 s2" */
  1207.           x = strlen(s2);
  1208.           if (s2[x] == '\n')
  1209.                s2[x] = '\0';
  1210.           if (strlen(s1) + x + 4 > TBUFL)
  1211.                sprintf(sp, "?T-Log string too long\n");
  1212.           else
  1213.                sprintf(sp, "%s %s\n", s1, s2);
  1214.           zsout(ZTFILE, s);
  1215.           break;
  1216.      case F111:                      /* 7, "s1 s2: n" */
  1217.           x = strlen(s2);
  1218.           if (s2[x] == '\n')
  1219.                s2[x] = '\0';
  1220.           if (strlen(s1) + x + 15 > TBUFL)
  1221.                sprintf(sp, "?T-Log string too long\n");
  1222.           else
  1223.                sprintf(sp, "%s %s: %ld\n", s1, s2, n);
  1224.           zsout(ZTFILE, s);
  1225.           break;
  1226.      default:
  1227.           sprintf(sp, "\n?Invalid format for tlog() - %ld\n",
  1228.               n);
  1229.           zsout(ZTFILE, s);
  1230.      }
  1231. }
  1232.  
  1233.  
  1234. /*  D E B U G  --  Enter a record in the debugging log  */
  1235.  
  1236. /*
  1237.  Call with a format, two strings, and a number:
  1238.    f  - Format, a bit string in range 0-7.
  1239.         If bit x is on, then argument number x is printed.
  1240.    s1 - String, argument number 1.  If selected, printed as is.
  1241.    s2 - String, argument number 2.  If selected, printed in brackets.
  1242.    n  - Int, argument 3.  If selected, printed preceded by equals sign.
  1243.  
  1244.    f=0 is special: print s1,s2, and interpret n as a char.
  1245. */
  1246. #define DBUFL 1400
  1247.  
  1248. debug(f,s1,s2,n) int f, n; char *s1, *s2; {
  1249.     static char s[DBUFL];
  1250.     char *sp = s;
  1251.  
  1252.     if (!deblog) return;        /* If no debug log, don't */
  1253.     switch (f) {
  1254.  
  1255.       case F000:            /* 0, print both strings, */
  1256.         if (strlen(s1) + strlen(s2) + 3 > DBUFL)
  1257.           sprintf(sp,"DEBUG string too long\n");
  1258.         else
  1259.           sprintf(sp,"%s%s%c\n",s1,s2,n); /* interpret n as a char */
  1260.         zsout(ZDFILE,s);
  1261.         break;
  1262.  
  1263.         case F001:            /* 1, "=n" */
  1264.         sprintf(sp,"=%d\n",n);
  1265.         zsout(ZDFILE,s);
  1266.         break;
  1267.  
  1268.       case F010:            /* 2, "[s2]" */
  1269.         if (strlen(s2) + 4 > DBUFL)
  1270.           sprintf(sp,"DEBUG string too long\n");
  1271.         else
  1272.           sprintf(sp,"[%s]\n",s2);
  1273.         zsout(ZDFILE,"");
  1274.         break;
  1275.  
  1276.       case F011:            /* 3, "[s2]=n" */
  1277.         if (strlen(s2) + 15 > DBUFL)
  1278.           sprintf(sp,"DEBUG string too long\n");
  1279.         else
  1280.           sprintf(sp,"[%s]=%d\n",s2,n);
  1281.         zsout(ZDFILE,s);
  1282.         break;
  1283.  
  1284.       case F100:            /* 4, "s1" */
  1285.         zsoutl(ZDFILE,s1);
  1286.         break;
  1287.  
  1288.       case F101:            /* 5, "s1=n" */
  1289.         if (strlen(s1) + 15 > DBUFL)
  1290.           sprintf(sp,"DEBUG string too long\n");
  1291.         else
  1292.           sprintf(sp,"%s=%d\n",s1,n);
  1293.         zsout(ZDFILE,s);
  1294.         break;
  1295.  
  1296.       case F110:            /* 6, "s1[s2]" */
  1297.         if (strlen(s1) + strlen(s2) + 4 > DBUFL)
  1298.           sprintf(sp,"DEBUG string too long\n");
  1299.         else
  1300.           sprintf(sp,"%s[%s]\n",s1,s2);
  1301.         zsout(ZDFILE,s);
  1302.         break;
  1303.  
  1304.       case F111:            /* 7, "s1[s2]=n" */
  1305.         if (strlen(s1) + strlen(s2) + 15 > DBUFL)
  1306.           sprintf(sp,"DEBUG string too long\n");
  1307.         else
  1308.           sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
  1309.         zsout(ZDFILE,s);
  1310.         break;
  1311.  
  1312.      /* the interface to call debug() with V110
  1313.          debug(V110,string1,string2,n);
  1314.                string -> char *
  1315.                n      -> strlen(string2) || with binary 0 padding
  1316.                          the length returned by MCS
  1317.                                                                     */
  1318.       case V110:
  1319.            {
  1320.                static char     stmp[DBUFL];
  1321.                char            *cptr;
  1322.                int             i, j;
  1323.                static char     hexchar[]={ '0','1','2','3','4','5','6',
  1324.                                            '7','8','9','A','B','C','D',
  1325.                                            'E','F'};
  1326.  
  1327.                if (n <= 0 || (strlen(s2)+n*2)>DBUFL)
  1328.                      sprintf (stmp, "V110 error (n)length=0");
  1329.                else
  1330.                      for (j = 0,i = 0, cptr=s2;
  1331.                           j <= n, *cptr=='\0'; j++) {
  1332.  
  1333.                          if (*cptr < 0x10)
  1334.                              stmp[i++] = '0';
  1335.                          else
  1336.                              stmp[i++] = hexchar[(int)*cptr++ / 0x10];
  1337.  
  1338.                          if (*cptr == 0x00)
  1339.                              stmp[i++] = '0';
  1340.                          else
  1341.                              stmp[i++]= hexchar[(int)*cptr++ % 0x10];
  1342.                      }
  1343.                stmp[i] = '\0';
  1344.                sprintf(sp, "<%s>%s\n", s1, stmp);
  1345.           }
  1346.           zsout(ZDFILE, s);
  1347.           break;
  1348.  
  1349.     default:
  1350.         sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
  1351.         zsout(ZDFILE,s);
  1352.     }
  1353. }
  1354.