Annotation of researchv10dc/lbin/kermit/ckucon.c, revision 1.1.1.1

1.1       root        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: char *chstr();
                     45: char temp[50];
                     46: 
                     47: #define LBUFL 200                      /* Line buffer */
                     48: char lbuf[LBUFL];
                     49: 
                     50: /* Connect state parent/child communication signal handlers */
                     51: 
                     52: static jmp_buf env_con;                        /* Envir ptr for connect errors */
                     53: 
                     54: static
                     55: conn_int() {                           /* Modem read failure handler, */
                     56:     longjmp(env_con,1);                        /* notifies parent process to stop */
                     57: }
                     58: 
                     59: /*  C O N E C T  --  Perform terminal connection  */
                     60: 
                     61: conect() {
                     62:     int pid,                   /* process id of child (modem reader) */
                     63:        parent_id,              /* process id of parent (keyboard reader) */
                     64:        n;
                     65:     int c;                     /* c is a character, but must be signed 
                     66:                                   integer to pass thru -1, which is the
                     67:                                   modem disconnection signal, and is
                     68:                                   different from the character 0377 */
                     69:     char errmsg[50], *erp;
                     70: 
                     71:        if (!local) {
                     72:            printf("Sorry, you must 'set line' first\n");
                     73:            return(-2);
                     74:        }
                     75:        if (speed < 0) {
                     76:            printf("Sorry, you must 'set speed' first\n");
                     77:            return(-2);
                     78:         }
                     79:        if ((escape < 0) || (escape > 0177)) {
                     80:            printf("Your escape character is not ASCII - %d\n",escape);
                     81:            return(-2);
                     82:        }
                     83:        if (ttopen(ttname,&local,mdmtyp) < 0) {
                     84:            erp = errmsg;
                     85:            sprintf(erp,"Sorry, can't open %s",ttname);
                     86:            perror(errmsg);
                     87:            return(-2);
                     88:        }
                     89:        printf("Connecting thru %s, speed %d.\r\n",ttname,speed);
                     90:        printf("The escape character is %s (%d).\r\n",chstr(escape),escape);
                     91:        printf("Type the escape character followed by C to get back,\r\n");
                     92:        printf("or followed by ? to see other options.\r\n");
                     93:        if (seslog) printf("(Session logged to %s.)\r\n",sesfil);
                     94: 
                     95: /* Condition console terminal and communication line */            
                     96: 
                     97:        if (conbin(escape) < 0) {
                     98:            printf("Sorry, can't condition console terminal\n");
                     99:            return(-2);
                    100:        }
                    101:        if (ttvt(speed,flow) < 0) {
                    102:            conres();
                    103:            printf("Sorry, Can't condition communication line\n");
                    104:            return(-2);
                    105:        }
                    106: 
                    107: /* cont'd... */
                    108: 
                    109: /* ...connect, cont'd */
                    110: 
                    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:        if (pid) {                      
                    122:          active = 1;                   /* This fork reads, sends keystrokes */
                    123:          if (!setjmp(env_con)) {       /* comm error in child process */
                    124:            signal(SIGUSR1,conn_int);   /* routine for child process exit */
                    125:            while (active) {
                    126:                c = coninc(0) & cmask;  /* Get character from keyboard */
                    127:                if ((c & 0177) == escape) { /* Look for escape char */
                    128:                    c = coninc(0) & 0177;   /* Got esc, get its arg */
                    129:                    doesc(c);               /* And process it */
                    130:                } else {                /* Ordinary character */
                    131:                    if (ttoc(dopar(c)) > -1) {
                    132:                        if (duplex) {       /* Half duplex? */
                    133:                            conoc(c);       /* Yes, also echo it. */
                    134:                            if (seslog)     /* And maybe log it. */
                    135:                                if (zchout(ZSFILE,c) < 0) seslog = 0;
                    136:                        }
                    137:                    } else {
                    138:                        perror("\r\nCan't send character");
                    139:                        active = 0;
                    140:                    }
                    141:                }
                    142:              }
                    143:            }                           /* Come here on death of child */
                    144:            kill(pid,9);                /* Done, kill inferior fork. */
                    145:            wait((int *)0);             /* Wait till gone. */
                    146:            conres();                   /* Reset the console. */
                    147:            printf("[Back at Local System]\n");
                    148:            return(0);
                    149: 
                    150:        } else {                        /* Inferior reads, prints port input */
                    151: 
                    152:            sleep(1);                   /* Wait for parent's handler setup */
                    153:            while (1) {                 /* Fresh read, wait for a character */
                    154:                if ((c = ttinc(0)) < 0) { /* Comm line hangup detected */
                    155:                    if (errno == 9999)  /* this value set by ckutio.c myread */
                    156:                         printf("\r\nCommunications disconnect ");
                    157:                    else perror("\r\nCan't get character");
                    158:                    kill(parent_id,SIGUSR1);    /* notify parent. */
                    159:                    pause();            /* Wait to be killed by parent. */
                    160:                 }
                    161:                c &= cmask;             /* Got a char, strip parity, etc */
                    162:                conoc(c);               /* Put it on the screen. */
                    163:                if (seslog) zchout(ZSFILE,c);   /* If logging, log it. */
                    164:                while ((n = ttchk()) > 0) {     /* Any more left in buffer? */
                    165:                    if (n > LBUFL) n = LBUFL;   /* Get them all at once. */
                    166:                    if ((n = ttxin(n,lbuf)) > 0) {
                    167:                        for (i = 0; i < n; i++) lbuf[i] &= cmask;  /* Strip */
                    168:                        conxo(n,lbuf);                             /* Output */
                    169:                        if (seslog) zsoutx(ZSFILE,lbuf,n);         /* Log */
                    170:                    }
                    171:                }
                    172:            }
                    173:        }
                    174: }
                    175: 
                    176: /*  H C O N N E  --  Give help message for connect.  */
                    177: 
                    178: hconne() {
                    179:     int c;
                    180:     static char *hlpmsg[] = {"\
                    181: \r\nC to close the connection, or:",
                    182: "\r\n  0 (zero) to send a null",
                    183: "\r\n  B to send a BREAK",
                    184: "\r\n  H to hangup and close connection",
                    185: "\r\n  S for status",
                    186: "\r\n  ? for help",
                    187: "\r\n escape character twice to send the escape character.\r\n\r\n",
                    188: "" };
                    189: 
                    190:     conola(hlpmsg);                    /* Print the help message. */
                    191:     conol("Command>");                 /* Prompt for command. */
                    192:     c = coninc(0) & 0177;              /* Get character, strip any parity. */
                    193:     conoc(c);                          /* Echo it. */
                    194:     conoll("");
                    195:     return(c);                         /* Return it. */
                    196: }
                    197: 
                    198: 
                    199: /*  C H S T R  --  Make a printable string out of a character  */
                    200: 
                    201: char *
                    202: chstr(c) int c; {
                    203:     static char s[8];
                    204:     char *cp = s;
                    205: 
                    206:     if (c < SP) {
                    207:        sprintf(cp,"CTRL-%c",ctl(c));
                    208:     } else sprintf(cp,"'%c'\n",c);
                    209:     cp = s;
                    210:     return(cp);
                    211: }
                    212: 
                    213: /*  D O E S C  --  Process an escape character argument  */
                    214: 
                    215: doesc(c) char c; {
                    216:     CHAR d;
                    217:   
                    218:     while (1) {
                    219:        if (c == escape) {              /* Send escape character */
                    220:            d = dopar(c); ttoc(d); return;
                    221:        } else                          /* Or else look it up below. */
                    222:            if (isupper(c)) c = tolower(c);
                    223: 
                    224:        switch (c) {
                    225: 
                    226:        case 'c':                       /* Close connection */
                    227:        case '\03':
                    228:            active = 0; conol("\r\n"); return;
                    229: 
                    230:        case 'b':                       /* Send a BREAK signal */
                    231:        case '\02':
                    232:            ttsndb(); return;
                    233: 
                    234:        case 'h':                       /* Hangup */
                    235:        case '\010':
                    236:            tthang(); active = 0; conol("\r\n"); return;
                    237: 
                    238:        case 's':                       /* Status */
                    239:            conol("\r\nConnected thru ");
                    240:            conol(ttname);
                    241:            if (speed >= 0) {
                    242:                sprintf(temp,", speed %d",speed); conol(temp);
                    243:            }
                    244:            sprintf(temp,", %d bits",(cmask == 0177) ? 7 : 8);
                    245:            if (parity) {
                    246:                conol(", ");
                    247:                switch (parity) {
                    248:                    case 'e': conol("even");  break;
                    249:                    case 'o': conol("odd");   break;
                    250:                    case 's': conol("space"); break;
                    251:                    case 'm': conol("mark");  break;
                    252:                }
                    253:                conol(" parity");
                    254:            }
                    255:            if (seslog) {
                    256:                conol(", logging to "); conol(sesfil);
                    257:             }
                    258:            conoll(""); return;
                    259: 
                    260:        case '?':                       /* Help */
                    261:            c = hconne(); continue;
                    262: 
                    263:        case '0':                       /* Send a null */
                    264:            c = '\0'; d = dopar(c); ttoc(d); return;
                    265: 
                    266:        case SP:                        /* Space, ignore */
                    267:            return;
                    268: 
                    269:        default:                        /* Other */
                    270:            conoc(BEL); return;         /* Invalid esc arg, beep */
                    271:        }           
                    272:     }
                    273: }    

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.