home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit4e / ckucon.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  8KB  |  279 lines

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