home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ncr9800 / ckvcon.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  13KB  |  382 lines

  1. char     *connv = "Connect Command for VRX/E, V4E(017) 10 May 90";
  2.  
  3. /*  C K V C O N  --  Dumb terminal connection to remote system, for NCR-VRX  */
  4.  
  5. /**********************************************************************
  6. *                                                                      *
  7. * IVS / MCS-Kermit REL 2                                              *
  8. * source code                                                         *
  9. *                                                                     *
  10. * Change History:                                                     *
  11. *                                                                     *
  12. *                1. Modify C-Kermit(4E) source code to                *
  13. *                   produce new module for MCS/IVS-Kermit             *
  14. *                   ORIGINAL RELEASE                                  *
  15. *                   June 22, 1990                                     *
  16. *                                                                     *
  17. *                                                                     *
  18. ***********************************************************************/
  19.  
  20.  
  21. /*
  22.  This module should work under all versions of NCR-VRX.  It calls externally
  23.  defined system-dependent functions for i/o, but depends upon the existence
  24.  of the FORK() function.
  25.  
  26.  Author: Frank da Cruz (SY.FDC@CU20B),
  27.  Columbia University Center for Computing Activities, January 1985.
  28.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  29.  Permission is granted to any individual or institution to use, copy, or
  30.  redistribute this software so long as it is not sold for profit, provided this
  31.  copyright notice is retained.
  32.  
  33.  Enhanced by H. Fischer to detect when child process (modem reader)
  34.  reports that the communications line has been broken and hang up.
  35.  Also enhanced to allow escaping from connect state to command
  36.  interpreter, to allow sending/receiving without breaking connection.
  37. */
  38.  
  39. #include <stdio.h>
  40. #include <ctype.h>                      /* Character types */
  41. #include "ckcdeb.h"
  42. #include "ckcker.h"
  43. #include <signal.h>
  44. #include "kermisc.h"
  45. #include <setjmp.h>                     /* Longjumps */
  46. #ifdef MCS_FLAG
  47. #include "mcs.h"
  48. #endif
  49.  
  50. #ifndef SIGUSR1
  51. #define SIGUSR1 16
  52. #endif
  53.  
  54. extern int     local, speed, escape, duplex, parity, flow, seslog, mdmtyp;
  55. extern int     errno, cmask, fmask, deblog;
  56. extern char     ttname[], sesfil[];
  57. extern CHAR dopar();
  58. extern void errhdlr();
  59.  
  60. int     i, active;             /* Variables global to this module */
  61. int     io_retry = 0;
  62. char     *chstr();
  63. char     temp[50];
  64.  
  65. #define LBUFL 200                       /* Line buffer */
  66. char     lbuf[LBUFL];
  67.  
  68. /* Connect state parent/child communication signal handlers */
  69.  
  70. static jmp_buf env_con;                 /* Envir ptr for connect errors */
  71.  
  72. static
  73. conn_int()
  74. {                            /* Modem read failure handler, */
  75.      longjmp(env_con, 1);    /* notifies parent process to stop */
  76. }
  77.  
  78.  
  79. /*  C O N E C T  --  Perform terminal connection  */
  80.  
  81. conect()
  82. {
  83.      int     pid,                    /* process id of child (modem reader) */
  84.      parent_id,              /* process id of parent (keyboard reader) */
  85.      n;
  86.      int     c;                      /* c is a character, but must be signed
  87.                                    integer to pass thru -1, which is the
  88.                                    modem disconnection signal, and is
  89.                                         different from the character 0377 */
  90.      char     errmsg[50], *erp;
  91.  
  92.      if (!local) {
  93. #ifndef MCS_FLAG
  94.           printf("Sorry, you must 'set line' first\n");
  95. #else
  96.           mcs_printf("Sorry, you must 'set line' first\n");
  97. #endif
  98.           return(-2);
  99.      }
  100.      if (speed < 0) {
  101. #ifndef MCS_FLAG
  102.           printf("Sorry, you must 'set speed' first\n");
  103. #else
  104.           mcs_printf("Sorry, you must 'set speed' first\n");
  105. #endif
  106.           return(-2);
  107.      }
  108.      if ((escape < 0) || (escape > 0177)) {
  109. #ifndef MCS_FLAG
  110.           printf("Your escape character is not ASCII - %d\n",
  111.               escape);
  112. #else
  113.           sprintf(print_str,"Your escape character is not ASCII - %d\n",
  114.               escape);
  115.           mcs_printf(print_str);
  116. #endif
  117.           return(-2);
  118.      }
  119.      if (ttopen(ttname, &local, mdmtyp) < 0) {
  120.           erp = errmsg;
  121.           sprintf(erp, "conect: Sorry, can't open %s", ttname);
  122.           errhdlr(errmsg);
  123.           return(-2);
  124.      }
  125. #ifndef MCS_FLAG
  126.      printf("Connecting thru %s, speed %d.\r\n", ttname, speed);
  127.      printf("The escape character is %s (%d).\r\n", chstr(escape),
  128.           escape);
  129.      printf("Type the escape character followed by C to get back,\r\n");
  130.      printf("or followed by ? to see other options.\r\n");
  131. #else
  132.      sprintf(print_str,"Connecting thru %s, speed %d.\r\n", ttname, speed);
  133.      mcs_printf(print_str);
  134.      sprintf(print_str,"The escape character is %s (%d).\r\n", chstr(escape),
  135.           escape);
  136.      mcs_printf(print_str);
  137.      mcs_printf("Type the escape character followed by C to get back,\r\n");
  138.      mcs_printf("or followed by ? to see other options.\r\n");
  139. #endif
  140.  
  141.      /* Condition console terminal and communication line */
  142.  
  143.      if (conbin(escape) < 0) {
  144. #ifndef MCS_FLAG
  145.           printf("Sorry, can't condition console terminal\n");
  146. #else
  147.           mcs_printf("Sorry, can't condition console terminal\n");
  148. #endif
  149.           return(-2);
  150.      }
  151.      if (ttvt(speed, flow) < 0) {
  152.           conres();
  153. #ifndef MCS_FLAG
  154.           printf("Sorry, Can't condition communication line\n");
  155. #else
  156.           mcs_printf("Sorry, Can't condition communication line\n");
  157. #endif
  158.           return(-2);
  159.      }
  160.  
  161.      parent_id = getpid();           /* Get parent id for signalling */
  162.      SIGNAL(SIGUSR1, SIG_IGN);        /* Don't KILL parent */
  163.      pid = FORK();                   /* All ok, make a FORK */
  164.      if (pid == -1) {
  165.           conres();                   /* Reset the console. */
  166.           errhdlr("conect: Can't create keyboard FORK");
  167. #ifndef MCS_FLAG
  168.           printf("[Back at Local System]\n");
  169. #else
  170.           mcs_printf("[Back at Local System]\n");
  171. #endif
  172.           return(0);
  173.      }
  174.      io_retry = 0;
  175.      if (pid) {
  176.           active = 1;                   /* This FORK reads, sends keystrokes */
  177.           if (!setjmp(env_con)) {       /* comm error in child process */
  178.                SIGNAL(SIGUSR1, conn_int); /* routine for child process exit */
  179.                while (active) {
  180.                     c = coninc(0) & cmask;  /* Get character from keyboard */
  181.                     if ((c & 0177) == escape) { /* Look for escape char */
  182.                          c = coninc(0) & 0177;   /* Got esc, get its arg */
  183.                          doesc(c);               /* And process it */
  184.                     } else {                /* Ordinary character */
  185.                          if (ttoc(dopar(c)) > -1) {
  186.                               if (duplex) {       /* Half duplex? */
  187.                                    conoc(c);       /* Yes, also echo it. */
  188.                                    if (seslog)     /* And maybe log it. */
  189. /* code folded from here */
  190.      if (zchout(ZSFILE, c) < 0)
  191.           seslog = 0;
  192. /* unfolding */
  193.                               }
  194.                          } else {
  195.                               errhdlr("conect: Can't send character");
  196.                               active = 0;
  197.                          }
  198.                     }
  199.                }
  200.           }                           /* Come here on death of child */
  201.           KILL(pid, 9);                /* Done, KILL inferior FORK. */
  202.           WAIT((int *)0);             /* Wait till gone. */
  203.           conres();                   /* Reset the console. */
  204. #ifndef MCS_FLAG
  205.           printf("\r[Back at Local System]\n");
  206. #else
  207.           mcs_printf("\r[Back at Local System]\n");
  208. #endif
  209.           return(0);
  210.  
  211.      } else {                        /* Inferior reads, prints port input */
  212.  
  213.           sleep(1);                   /* Wait for parent's handler setup */
  214.           while (1) {                 /* Fresh read, WAIT for a character */
  215.                if ((c = ttinc(0)) < 0) { /* Comm line hangup detected */
  216.                     if (errno == 9999)  /* this value set by myread() */
  217. #ifndef MCS_FLAG
  218.                          printf("\r\nCommunications disconnect ");
  219. #else
  220.                          mcs_printf("\r\nCommunications disconnect ");
  221. #endif
  222.                     else if (io_retry++ < 3) {
  223.                          tthang();
  224.                          continue;
  225.                     }
  226.                     errhdlr("conect: Can't get character");
  227.                     KILL(parent_id, SIGUSR1); /* notify parent. */
  228.                     PAUSE();            /* Wait to be KILLed by parent. */
  229.                }
  230.                c &= cmask;             /* Got a char, strip parity, etc */
  231.                conoc(c);               /* Put it on the screen. */
  232.                if (seslog)
  233.                     zchout(ZSFILE, c);   /* If logging, log it. */
  234.                while ((n = ttchk()) > 0) {     /* Any more left in buffer? */
  235.                     if (n > LBUFL)
  236.                          n = LBUFL;   /* Get them all at once. */
  237.                     if ((n = ttxin(n, lbuf)) > 0) {
  238.                          for (i = 0; i < n; i++)
  239.                               lbuf[i] &= cmask;  /* Strip */
  240.                          conxo(n, lbuf);         /* Output */
  241.                          if (seslog)
  242.                               zsoutx(ZSFILE, lbuf,
  243.                                    n);         /* Log */
  244.                     }
  245.                }
  246.           }
  247.      }
  248. }
  249.  
  250.  
  251. /*  H C O N N E  --  Give help message for connect.  */
  252.  
  253. hconne()
  254. {
  255.      int     c;
  256.      static char     *hlpmsg[] = {
  257.           "\r\n  C to close the connection, or:",
  258.           "\r\n  0 (zero) to send a null",
  259.           "\r\n  B to send a BREAK",
  260.           "\r\n  H to hangup and close connection",
  261.           "\r\n  S for status",
  262.           "\r\n  ? for help",
  263.           "\r\n escape character twice to send the escape character.\r\n\r\n",
  264.                ""      };
  265.  
  266.      conola(hlpmsg);                     /* Print the help message. */
  267.      conol("Command>");                  /* Prompt for command. */
  268.      c = coninc(0) & 0177;               /* Get character, strip any parity. */
  269.      conoc(c);                           /* Echo it. */
  270.      conoll("");
  271.      return(c);                          /* Return it. */
  272. }
  273.  
  274.  
  275. /*  C H S T R  --  Make a printable string out of a character  */
  276.  
  277. char     *
  278. chstr(c)
  279. int     c;
  280. {
  281.      static char     s[8];
  282.      char     *cp = s;
  283.  
  284.      if (c < SP) {
  285.           sprintf(cp, "CTRL-%c", ctl(c));
  286.      } else
  287.           sprintf(cp, "'%c'\n", c);
  288.      cp = s;
  289.      return(cp);
  290. }
  291.  
  292.  
  293. /*  D O E S C  --  Process an escape character argument  */
  294.  
  295. doesc(c)
  296. char     c;
  297. {
  298.      CHAR d;
  299.  
  300.      while (1) {
  301.           if (c == escape) {              /* Send escape character */
  302.                d = dopar(c);
  303.                ttoc(d);
  304.                return;
  305.           } else if /* Or else look it up below. */
  306.           (isupper(c))
  307.                c = tolower(c);
  308.  
  309.           switch (c) {
  310.  
  311.           case 'c':                       /* Close connection */
  312.           case '\03':
  313.                active = 0;
  314.                conol("\r\n");
  315.                return;
  316.  
  317.           case 'b':                       /* Send a BREAK signal */
  318.           case '\02':
  319.                ttsndb();
  320.                return;
  321.  
  322.           case 'h':                       /* Hangup */
  323.           case '\010':
  324.                tthang();
  325.                active = 0;
  326.                conol("\r\n");
  327.                return;
  328.  
  329.           case 's':                       /* Status */
  330.                conol("\r\nConnected thru ");
  331.                conol(ttname);
  332.                if (speed >= 0) {
  333.                     sprintf(temp, ", speed %d", speed);
  334.                     conol(temp);
  335.                }
  336.                sprintf(temp, ", %d bits", (cmask == 0177) ?
  337.                    7 : 8);
  338.                if (parity) {
  339.                     conol(", ");
  340.                     switch (parity) {
  341.                     case 'e':
  342.                          conol("even");
  343.                          break;
  344.                     case 'o':
  345.                          conol("odd");
  346.                          break;
  347.                     case 's':
  348.                          conol("space");
  349.                          break;
  350.                     case 'm':
  351.                          conol("mark");
  352.                          break;
  353.                     }
  354.                     conol(" parity");
  355.                }
  356.                if (seslog) {
  357.                     conol(", logging to ");
  358.                     conol(sesfil);
  359.                }
  360.                conoll("");
  361.                return;
  362.  
  363.           case '?':                       /* Help */
  364.                c = hconne();
  365.                continue;
  366.  
  367.           case '0':                       /* Send a null */
  368.                c = '\0';
  369.                d = dopar(c);
  370.                ttoc(d);
  371.                return;
  372.  
  373.           case SP:                        /* Space, ignore */
  374.                return;
  375.  
  376.           default:                        /* Other */
  377.                conoc(BEL);
  378.                return;         /* Invalid esc arg, beep */
  379.           }
  380.      }
  381. }
  382.