# 2.11BSD#431 - /usr/src/new/kermit5.188/ckucon.c

##### Functions

    chkaes            X
    ckcgetc           X
    ckcputc           X
    ckcputf           X
    conect            X
    doesc             X
    hconne            X
    logchar           X

##### Variables

    VOID              X
    active            X
    connv             X
    ibufl             X
    lcn               X
    linkid            X
    obufl             X
    padparms          X
    tosend            X
    x25ibuf           X
    x25obuf           X

##### Macros

    AYT               X
    ES_ESCSEQ         X
    ES_GOTCSI         X
    ES_GOTESC         X
    ES_NORMAL         X
    ES_STRING         X
    ES_TERMIN         X
    IBUFL             X
    IP                X
    OBUFL             X
    SIGUSR1           X
    SIGUSR2           X
    SKIPESC           X
    TMPLEN            X

       1: char *connv = "CONNECT Command for UNIX, 5A(047) 23 Nov 92";
       2:
       3: /*  C K U C O N  --  Dumb terminal connection to remote system, for UNIX  */
       4: /*
       5:   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
       6:   Columbia University Center for Computing Activities.
       7:   First released January 1985.
       8:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
       9:   York.  Permission is granted to any individual or institution to use this
      10:   software as long as it is not sold for profit.  This copyright notice must be
      11:   retained.  This software may not be included in commercial products without
      12:   written permission of Columbia University.
      13: */
      14:
      15: #include "ckcdeb.h"         /* Common things first */
      16:
      17: #ifdef NEXT
      18: #undef NSIG
      19: #include <sys/wait.h>           /* For wait() */
      20: #endif /* NEXT */
      21:
      22: #include <signal.h>         /* Signals */
      23: #include <errno.h>          /* Error numbers */
      24:
      25: #ifdef ZILOG                /* Longjumps */
      26: #include <setret.h>
      27: #else
      28: #include <setjmp.h>
      29: #endif /* ZILOG */
      30:
      31: /* Kermit-specific includes */
      32:
      33: #include "ckcasc.h"         /* ASCII characters */
      34: #include "ckcker.h"         /* Kermit things */
      35: #include "ckucmd.h"         /* For xxesc() prototype */
      36: #include "ckcnet.h"         /* Network symbols */
      37: #ifndef NOCSETS
      38: #include "ckcxla.h"         /* Character set translation */
      39: #endif /* NOCSETS */
      40:
      41: /* Internal function prototypes */
      42:
      43: _PROTOTYP( VOID doesc, (char) );
      44: _PROTOTYP( VOID logchar, (char) );
      45: _PROTOTYP( int hconne, (void) );
      46: _PROTOTYP( VOID shomdm, (void) );
      47:
      48: #ifndef SIGUSR1             /* User-defined signals */
      49: #define SIGUSR1 30
      50: #endif /* SIGUSR1 */
      51:
      52: #ifndef SIGUSR2
      53: #define SIGUSR2 31
      54: #endif /* SIGUSR2 */
      55:
      56: /* External variables */
      57:
      58: extern int local, escape, duplex, parity, flow, seslog, sessft, debses,
      59:  mdmtyp, ttnproto, cmask, cmdmsk, network, nettype, deblog, sosi, tnlm,
      60:  xitsta, what, ttyfd, quiet, backgrd, pflag, tt_crd, tn_nlm;
      61: extern long speed;
      62: extern char ttname[], sesfil[], myhost[], *ccntab[];
      63:
      64: #ifndef NOSETKEY            /* Keyboard mapping */
      65: extern KEY *keymap;         /* Single-character key map */
      66: extern MACRO *macrotab;         /* Key macro pointer table */
      67: static MACRO kmptr = NULL;      /* Pointer to current key macro */
      68: #endif /* NOSETKEY */
      69:
      70: /* Global variables local to this module */
      71:
      72: static int quitnow = 0,         /* <esc-char>Q was typed */
      73:   dohangup = 0,             /* <esc-char>H was typed */
      74:   sjval = 0,                /* Setjump return value */
      75:   goterr = 0,               /* I/O error flag */
      76: #ifndef SUNX25
      77:   active = 0,               /* Lower fork active flag */
      78: #endif /* SUNX25 */
      79:   inshift = 0,              /* SO/SI shift states */
      80:   outshift = 0;
      81:
      82: static char kbuf[10], *kbp;     /* Keyboard buffer & pointer */
      83: static PID_T parent_id = (PID_T)0;  /* Process id of keyboard fork */
      84:
      85: static char *ibp;           /* Input buffer pointer */
      86: static int ibc = 0;         /* Input buffer count */
      87: #ifdef pdp11
      88: #define IBUFL 1536          /* Input buffer length */
      89: #else
      90: #define IBUFL 4096
      91: #endif /* pdp11 */
      92:
      93: static char *obp;           /* Output buffer pointer */
      94: static int obc = 0;         /* Output buffer count */
      95: #define OBUFL 1024          /* Output buffer length */
      96:
      97: #define TMPLEN 200          /* Temporary message buffer length */
      98: #ifdef DYNAMIC
      99: static char *ibuf = NULL, *obuf = NULL, *temp = NULL; /* Buffers */
     100: #else
     101: static char ibuf[IBUFL], obuf[OBUFL], temp[TMPLEN];
     102: #endif /* DYNAMIC */
     103:
     104: /* SunLink X.25 items */
     105:
     106: #ifdef SUNX25
     107: static char *p;             /* General purpose pointer */
     108: char x25ibuf[MAXIX25];          /* Input buffer */
     109: char x25obuf[MAXOX25];          /* Output buffer */
     110: int active = 0;             /* Lower fork active flag */
     111: int ibufl;              /* Length of input buffer */
     112: int obufl;              /* Length of output buffer */
     113: unsigned char tosend = 0;
     114: int linkid, lcn;
     115: static int dox25clr = 0;
     116: CHAR padparms[MAXPADPARMS+1];
     117: static int padpipe[2];          /* Pipe descriptor to pass PAD parms */
     118: #endif /* SUNX25 */
     119:
     120: /* Character-set items */
     121:
     122: #ifndef NOCSETS
     123: #ifdef CK_ANSIC /* ANSI C prototypes... */
     124: extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
     125: extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
     126: static CHAR (*sxo)(CHAR);   /* Local translation functions */
     127: static CHAR (*rxo)(CHAR);   /* for output (sending) terminal chars */
     128: static CHAR (*sxi)(CHAR);   /* and for input (receiving) terminal chars. */
     129: static CHAR (*rxi)(CHAR);
     130: #else /* Not ANSI C... */
     131: extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
     132: extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
     133: static CHAR (*sxo)();       /* Local translation functions */
     134: static CHAR (*rxo)();       /* for output (sending) terminal chars */
     135: static CHAR (*sxi)();       /* and for input (receiving) terminal chars. */
     136: static CHAR (*rxi)();
     137: #endif /* CK_ANSIC */
     138: extern int language;        /* Current language. */
     139: static int langsv;      /* For remembering language setting. */
     140: extern struct csinfo fcsinfo[]; /* File character set info. */
     141: extern int tcsr, tcsl;      /* Terminal character sets, remote & local. */
     142: static int tcs;         /* Intermediate ("transfer") character set. */
     143:
     144: #ifndef NOESCSEQ
     145: /*
     146:   As of edit 178, the CONNECT command will skip past ANSI escape sequences
     147:   to avoid translating the characters within them.  This allows the CONNECT
     148:   command to work correctly when connected to a remote host that uses a
     149:   7-bit ISO 646 national character set, in which characters like '[' would
     150:   normally be translated into accented characters, ruining the terminal's
     151:   interpretation (and generation) of escape sequences.
     152:
     153:   Escape sequences of non-ANSI/ISO-compliant terminals are not handled.
     154: */
     155: #ifndef SKIPESC
     156: #define SKIPESC
     157: #endif /* SKIPESC */
     158: /*
     159:   States for the escape-sequence recognizer.
     160: */
     161: #define ES_NORMAL 0         /* Normal, not in escape sequence */
     162: #define ES_GOTESC 1         /* Current character is ESC */
     163: #define ES_ESCSEQ 2         /* Inside an escape sequence */
     164: #define ES_GOTCSI 3         /* Inside a control sequence */
     165: #define ES_STRING 4         /* Inside DCS,OSC,PM, or APC string */
     166: #define ES_TERMIN 5         /* 1st char of string terminator */
     167:
     168: static int
     169:   skipesc = 0,              /* Skip over ANSI escape sequences */
     170:   inesc = ES_NORMAL;            /* State of sequence recognizer */
     171: /*
     172:   ANSI escape sequence handling.  Only the 7-bit form is treated, because
     173:   translation is not a problem in the 8-bit environment, in which all GL
     174:   characters are ASCII and no translation takes place.  So we don't check
     175:   for the 8-bit single-character versions of CSI, DCS, OSC, APC, or ST.
     176:   Here is the ANSI sequence recognizer state table, followed by the code
     177:   that implements it.
     178:
     179:   Definitions:
     180:     CAN = Cancel                       01/08         Ctrl-X
     181:     SUB = Substitute                   01/10         Ctrl-Z
     182:     DCS = Device Control Sequence      01/11 05/00   ESC P
     183:     CSI = Control Sequence Introducer  01/11 05/11   ESC [
     184:     ST  = String Terminator            01/11 05/12   ESC \
     185:     OSC = Operating System Command     01/11 05/13   ESC ]
     186:     PM  = Privacy Message              01/11 05/14   ESC ^
     187:     APC = Application Program Command  01/11 05/15   ESC _
     188:
     189:   ANSI escape sequence recognizer:
     190:
     191:     State    Input  New State  ; Commentary
     192:
     193:     NORMAL   (start)           ; Start in NORMAL state
     194:
     195:     (any)    CAN    NORMAL     ; ^X cancels
     196:     (any)    SUB    NORMAL     ; ^Z cancels
     197:
     198:     NORMAL   ESC    GOTESC     ; Begin escape sequence
     199:     NORMAL   other             ; NORMAL control or graphic character
     200:
     201:     GOTESC   ESC               ; Start again
     202:     GOTESC   [      GOTCSI     ; CSI
     203:     GOTESC   P      STRING     ; DCS introducer, consume through ST
     204:     GOTESC   ]      STRING     ; OSC introducer, consume through ST
     205:     GOTESC   ^      STRING     ; PM  introducer, consume through ST
     206:     GOTESC   _      STRING     ; APC introducer, consume through ST
     207:     GOTESC   0..~   NORMAL     ; 03/00 through 17/14 = Final character
     208:     GOTESC   other  ESCSEQ     ; Intermediate or ignored control character
     209:
     210:     ESCSEQ   ESC    GOTESC     ; Start again
     211:     ESCSEQ   0..~   NORMAL     ; 03/00 through 17/14 = Final character
     212:     ESCSEQ   other             ; Intermediate or ignored control character
     213:
     214:     GOTCSI   ESC    GOTESC     ; Start again
     215:     GOTCSI   @..~   NORMAL     ; 04/00 through 17/14 = Final character
     216:     GOTCSI   other             ; Intermediate char or ignored control char
     217:
     218:     STRING   ESC    TERMIN     ; Maybe have ST
     219:     STRING   other             ; Consume all else
     220:
     221:     TERMIN   \      NORMAL     ; End of string
     222:     TERMIN   other  STRING     ; Still in string
     223: */
     224: /*
     225:   chkaes() -- Check ANSI Escape Sequence.
     226:   Call with EACH character in input stream.
     227:   Sets global inesc variable according to escape sequence state.
     228: */
     229: VOID
     230: #ifdef CK_ANSIC
     231: chkaes(char c)
     232: #else
     233: chkaes(c) char c;
     234: #endif /* CK_ANSIC */
     235: /* chkaes */ {
     236:
     237:     if (c == CAN || c == SUB)       /* CAN and SUB cancel any sequence */
     238:       inesc = ES_NORMAL;
     239:     else                /* Otherwise */
     240:       switch (inesc) {          /* enter state switcher */
     241:
     242:     case ES_NORMAL:         /* NORMAL state */
     243:       if (c == ESC)         /* Got an ESC */
     244:         inesc = ES_GOTESC;      /* Change state to GOTESC */
     245:       break;            /* Otherwise stay in NORMAL state */
     246:
     247:     case ES_GOTESC:         /* GOTESC state */
     248:       if (c == '[')         /* Left bracket after ESC is CSI */
     249:         inesc = ES_GOTCSI;      /* Change to GOTCSI state */
     250:       else if (c > 057 && c < 0177) /* Final character '0' thru '~' */
     251:         inesc = ES_NORMAL;      /* Back to normal */
     252:       else if (c == 'P' || (c > 0134 && c < 0140)) /* P, [, ^, or _ */
     253:         inesc = ES_STRING;      /* Switch to STRING-absorption state */
     254:       else if (c != ESC)        /* ESC in an escape sequence... */
     255:         inesc = ES_ESCSEQ;      /* starts a new escape sequence */
     256:       break;            /* Intermediate or ignored ctrl char */
     257:
     258:     case ES_ESCSEQ:         /* ESCSEQ -- in an escape sequence */
     259:       if (c > 057 && c < 0177)  /* Final character '0' thru '~' */
     260:         inesc = ES_NORMAL;      /* Return to NORMAL state. */
     261:       else if (c == ESC)        /* ESC ... */
     262:         inesc = ES_GOTESC;      /* starts a new escape sequence */
     263:       break;            /* Intermediate or ignored ctrl char */
     264:
     265:     case ES_GOTCSI:         /* GOTCSI -- In a control sequence */
     266:       if (c > 077 && c < 0177)  /* Final character '@' thru '~' */
     267:         inesc = ES_NORMAL;      /* Return to NORMAL. */
     268:       else if (c == ESC)        /* ESC ... */
     269:         inesc = ES_GOTESC;      /* starts over. */
     270:       break;            /* Intermediate or ignored ctrl char */
     271:
     272:     case ES_STRING:         /* Inside a string */
     273:       if (c == ESC)         /* ESC may be 1st char of terminator */
     274:         inesc = ES_TERMIN;      /* Go see. */
     275:       break;            /* Absorb all other characters. */
     276:
     277:     case ES_TERMIN:         /* May have a string terminator */
     278:       if (c == '\\')        /* which must be backslash */
     279:         inesc = ES_NORMAL;      /* If so, back to NORMAL */
     280:       else              /* Otherwise */
     281:         inesc = ES_STRING;      /* Back to string absorption. */
     282:       }
     283: }
     284: #endif /* NOESCSEQ */
     285: #endif /* NOCSETS */
     286:
     287: /* Connect state parent/child communication signal handlers */
     288:
     289: static jmp_buf con_env;      /* Environment pointer for connect errors */
     290: /*
     291:   Note: Some C compilers (e.g. Cray UNICOS) interpret the ANSI C standard
     292:   about setjmp() in a way that disallows constructions like:
     293:
     294:     if ((var = setjmp(env)) == 0) ...
     295:
     296:   which prevents the value returned by longjmp() from being used at all.
     297:   So the following handlers set a global variable instead.
     298: */
     299: static
     300: SIGTYP
     301: conn_int(foo) int foo; {        /* Modem read failure handler, */
     302:     signal(SIGUSR1,SIG_IGN);        /* Disarm the interrupt */
     303:     sjval = 1;              /* Set global variable */
     304:     longjmp(con_env,sjval);     /* Notifies parent process to stop */
     305: }
     306:
     307: static
     308: SIGTYP
     309: mode_chg(foo) int foo; {
     310:     signal(SIGUSR2,mode_chg);       /* Re-arm the signal immediately. */
     311:
     312: #ifdef SUNX25               /* X.25 read new params from pipe */
     313:     if (nettype == NET_SX25) {
     314:         read(padpipe[0],padparms,MAXPADPARMS);
     315:         debug(F100,"pad_chg","",0);
     316: /*
     317:   NOTE: we can probably skip this longjmp, just as we do in the "else" case.
     318:   But I don't (yet) have any way to test this.
     319: */
     320:     sjval = 2;          /* Set global variable. */
     321:     longjmp(con_env,sjval);
     322:     debug(F100,"mode_chg X.25","",0);
     323:     } else {
     324: #endif /* SUNX25 */
     325:     duplex = 1 - duplex;        /* Toggle duplex mode. */
     326:     debug(F101,"mode_chg duplex","",duplex);
     327: #ifdef SUNX25
     328:     }
     329: #endif /* SUNX25 */
     330: }
     331:
     332: /*  C K C P U T C  --  C-Kermit CONNECT Put Character to Screen  */
     333: /*
     334:   Output is buffered to avoid slow screen writes on fast connections.
     335: */
     336: int
     337: ckcputf() {             /* Dump the output buffer */
     338:     int x = 0;
     339:     if (obc > 0)            /* If we have any characters, */
     340:       x = conxo(obc,obuf);      /* dump them, */
     341:     obp = obuf;             /* reset the pointer */
     342:     obc = 0;                /* and the counter. */
     343:     return(x);              /* Return conxo's return code */
     344: }
     345:
     346: int
     347: ckcputc(c) int c; {
     348:     int x;
     349:
     350:     *obp++ = c & 0xff;          /* Deposit the character */
     351:     obc++;              /* Count it */
     352:     if (ibc == 0 ||         /* If input buffer about empty */
     353:     obc == OBUFL) {         /* or output buffer full */
     354:     debug(F101,"CKCPUTC obc","",obc);
     355:     x = conxo(obc,obuf);        /* dump the buffer, */
     356:     obp = obuf;         /* reset the pointer */
     357:     obc = 0;            /* and the counter. */
     358:     return(x);          /* Return conxo's return code */
     359:     } else return(0);
     360: }
     361:
     362: /*  C K C G E T C  --  C-Kermit CONNECT Get Character  */
     363: /*
     364:   Buffered read from communication device.
     365:   Returns the next character, refilling the buffer if necessary.
     366:   On error, returns ttinc's return code (see ttinc() description).
     367:   Dummy argument for compatible calling conventions with ttinc().
     368: */
     369: int
     370: ckcgetc(dummy) int dummy; {
     371:     int c, n;
     372:
     373:     debug(F101,"CKCGETC 1 ibc","",ibc); /* Log */
     374:     if (ibc < 1) {          /* Need to refill buffer? */
     375:     ibc = 0;            /* Yes, reset count */
     376:     ibp = ibuf;         /* and buffer pointer */
     377:     debug(F100,"CKCGETC 1 calling ttinc(0)","",0); /* Log */
     378:     c = ttinc(0);           /* Read one character, blocking */
     379:     debug(F101,"CKCGETC 1 ttinc(0)","",c); /* Log */
     380:     if (c < 0) {            /* If error, return error code */
     381:         return(c);
     382:     } else {            /* Otherwise, got one character */
     383:         *ibp++ = c;         /* Advance buffer pointer */
     384:         ibc++;          /* and count. */
     385:     }
     386:
     387:     /* Now quickly read any more that might have arrived */
     388:
     389:     if ((n = ttchk()) > 0) {    /* Any more waiting? */
     390:         if (n > (IBUFL - ibc))  /* Get them all at once. */
     391:           n = IBUFL - ibc;      /* Don't overflow buffer */
     392:         if ((n = ttxin(n,(CHAR *)ibp)) > 0) {
     393:         ibp += n;       /* Advance pointer */
     394:         ibc += n;       /* and counter */
     395:         } else return(-1);
     396:     }
     397:     debug(F101,"CKCGETC 2 ibc","",ibc); /* Log how many */
     398:     ibp = ibuf;
     399:     }
     400:     c = *ibp++ & 0xff;          /* Get next character from buffer */
     401:     ibc--;              /* Reduce buffer count */
     402:     return(c);              /* Return the character */
     403: }
     404:
     405: /*  C O N E C T  --  Perform terminal connection  */
     406:
     407: int
     408: conect() {
     409:     PID_T pid;          /* Process id of child (modem reader) */
     410:     int n;          /* General purpose counter */
     411:
     412:     int c;          /* c is a character, but must be signed
     413: 				   integer to pass thru -1, which is the
     414: 				   modem disconnection signal, and is
     415: 				   different from the character 0377 */
     416:     int c2;         /* A copy of c */
     417:     int csave;          /* Another copy of c */
     418:     int tx;         /* tn_doop() return code */
     419: #ifdef SUNX25
     420:     int i;          /* Worker for X.25 code*/
     421: #endif /* SUNX25 */
     422:
     423: #ifdef DYNAMIC
     424:     if (!(ibuf = malloc(IBUFL+1))) {    /* Allocate input line buffer */
     425:     printf("Sorry, CONNECT input buffer can't be allocated\n");
     426:     return(0);
     427:     }
     428:     if (!(obuf = malloc(OBUFL+1))) {    /* Allocate input line buffer */
     429:     printf("Sorry, CONNECT output buffer can't be allocated\n");
     430:     free(ibuf);
     431:     return(0);
     432:     }
     433:     if (!(temp = malloc(TMPLEN+1))) {    /* Allocate temporary buffer */
     434:     printf("Sorry, CONNECT temporary buffer can't be allocated\n");
     435:     free(obuf);
     436:     return(0);
     437:     }
     438: #endif /* DYNAMIC */
     439:
     440:     if (!local) {
     441: #ifdef NETCONN
     442:     printf("Sorry, you must SET LINE or SET HOST first\n");
     443: #else
     444:     printf("Sorry, you must SET LINE first\n");
     445: #endif /* NETCONN */
     446:     return(0);
     447:     }
     448:     if (speed < 0L && network == 0) {
     449:     printf("Sorry, you must SET SPEED first\n");
     450:     return(0);
     451:     }
     452: #ifdef TCPSOCKET
     453:     if (network && (nettype != NET_TCPB)
     454: #ifdef SUNX25
     455:         && (nettype != NET_SX25)
     456: #endif /* SUNX25 */
     457:     ) {
     458:     printf("Sorry, network type not supported\n");
     459:     return(0);
     460:     }
     461: #endif /* TCPSOCKET */
     462:
     463:     if (ttyfd < 0) {            /* If communication device not open */
     464:     debug(F111,"ckucon opening",ttname,0); /* Open it now */
     465:     if (ttopen(ttname,
     466:            &local,
     467:            network ? -nettype : mdmtyp,
     468:            0
     469:            ) < 0) {
     470:         sprintf(temp,"Sorry, can't open %s",ttname);
     471:         perror(temp);
     472:         debug(F110,"ckucon open failure",temp,0);
     473:         return(0);
     474:     }
     475:     }
     476:     dohangup = 0;           /* Hangup not requested yet */
     477: #ifdef SUNX25
     478:     dox25clr = 0;           /* X.25 clear not requested yet */
     479: #endif /* SUNX25 */
     480:
     481:     if (!quiet) {
     482: #ifdef NETCONN
     483:     if (network) {
     484:         printf("Connecting to host %s",ttname);
     485: #ifdef SUNX25
     486:         if (nettype == NET_SX25)
     487:           printf(", Link ID %d, LCN %d",linkid,lcn);
     488: #endif /* SUNX25 */
     489:     } else {
     490: #endif /* NETCONN */
     491:         printf("Connecting to %s",ttname);
     492:         if (speed > -1L) printf(", speed %ld",speed);
     493: #ifdef NETCONN
     494:     }
     495: #endif /* NETCONN */
     496:     printf(".\r\nThe escape character is Ctrl-%c (ASCII %d, %s)\r\n",
     497:            ctl(escape), escape, (escape == 127 ? "DEL" : ccntab[escape]));
     498:     printf("Type the escape character followed by C to get back,\r\n");
     499:     printf("or followed by ? to see other options.\r\n");
     500:     if (seslog) {
     501:         printf("(Session logged to %s, ",sesfil);
     502:         printf("%s)\r\n", sessft ? "binary" : "text");
     503:     }
     504:     if (debses) printf("Debugging Display...)\r\n");
     505:     fflush(stdout);
     506:     }
     507:
     508: /* Condition console terminal and communication line */
     509:
     510:     if (conbin((char)escape) < 0) {
     511:     printf("Sorry, can't condition console terminal\n");
     512:     return(0);
     513:     }
     514:     debug(F101,"connect cmask","",cmask);
     515:     debug(F101,"connect cmdmsk","",cmdmsk);
     516:     goterr = 0;
     517:     if ((n = ttvt(speed,flow)) < 0) {   /* Enter "virtual terminal" mode */
     518:     debug(F101,"CONNECT ttvt","",n);
     519:     goterr = 1;         /* Error recovery... */
     520:     tthang();           /* Hang up and close the device. */
     521:     ttclos(0);
     522:     if (ttopen(ttname,      /* Open it again... */
     523:            &local,
     524:            network ? -nettype : mdmtyp,
     525:            0
     526:            ) < 0) {
     527:         sprintf(temp,"Sorry, can't reopen %s",ttname);
     528:         perror(temp);
     529:         return(0);
     530:     }
     531:     if (ttvt(speed,flow) < 0) { /* Try virtual terminal mode again. */
     532:         conres();           /* Failure this time is fatal. */
     533:         printf("Sorry, Can't condition communication line\n");
     534:         return(0);
     535:     }
     536: #ifdef NETCONN
     537:     if (network && ttnproto == NP_TELNET)
     538:       tn_ini();         /* Just in case ttopen didn't... */
     539: #endif /* NETCONN */
     540:     }
     541:     debug(F101,"connect ttvt ok, escape","",escape);
     542:
     543: #ifndef NOCSETS
     544: /* Set up character set translations */
     545:
     546:     tcs = gettcs(tcsr,tcsl);        /* Get intermediate set. */
     547:
     548:     if (tcsr == tcsl) {         /* Remote and local sets the same? */
     549:     sxo = rxo = NULL;       /* If so, no translation. */
     550:     sxi = rxi = NULL;
     551:     } else {                /* Otherwise, set up */
     552:     sxo = xls[tcs][tcsl];       /* translation function */
     553:     rxo = xlr[tcs][tcsr];       /* pointers for output functions */
     554:     sxi = xls[tcs][tcsr];       /* and for input functions. */
     555:     rxi = xlr[tcs][tcsl];
     556:     }
     557: /*
     558:   This is to prevent use of zmstuff() and zdstuff() by translation functions.
     559:   They only work with disk i/o, not with communication i/o.  Luckily Russian
     560:   translation functions don't do any stuffing...
     561: */
     562:     langsv = language;
     563: #ifndef NOCYRIL
     564:     if (language != L_RUSSIAN)
     565: #endif /* NOCYRIL */
     566:       language = L_USASCII;
     567:
     568: #ifdef SKIPESC
     569: /*
     570:   We need to activate the "skip escape sequence" feature when:
     571:   (a) translation is elected, and
     572:   (b) the local and/or remote set is a 7-bit set other than US ASCII.
     573: */
     574:     skipesc = (tcs != TC_TRANSP) && /* Not transparent */
     575:       (fcsinfo[tcsl].size == 128 || fcsinfo[tcsr].size == 128) && /* 7 bits */
     576:     (fcsinfo[tcsl].code != FC_USASCII); /* But not ASCII */
     577:     inesc = ES_NORMAL;          /* Initial state of recognizer */
     578: #ifdef COMMENT
     579:     debug(F101,"tcs","",tcs);
     580:     debug(F101,"tcsl","",tcsl);
     581:     debug(F101,"tcsr","",tcsr);
     582:     debug(F101,"fcsinfo[tcsl].size","",fcsinfo[tcsl].size);
     583:     debug(F101,"fcsinfo[tcsr].size","",fcsinfo[tcsr].size);
     584: #endif /* COMMENT */
     585:     debug(F101,"skipesc","",skipesc);
     586: #endif /* SKIPESC */
     587: #endif /* NOCSETS */
     588:
     589: /*
     590:   This is a label we jump back to when the lower fork sensed the need
     591:   to change modes.  As of 5A(178), this is used only by X.25 code
     592:   (perhaps unnecessarily? -- The X.25 code needs a lot of testing and
     593:   cleaning up...)
     594: */
     595: newfork:
     596:     debug(F100,"CONNECT newfork","",0);
     597:     parent_id = getpid();       /* Get parent id for signalling */
     598:     signal(SIGUSR1,SIG_IGN);        /* Don't kill myself */
     599: #ifdef SUNX25
     600:     pipe(padpipe);                      /* Create pipe to pass PAD parms */
     601: #endif /* SUNX25 */
     602:     pid = fork();           /* All ok, make a fork */
     603:     if (pid == (PID_T) -1) {        /* Can't create it. */
     604:     conres();           /* Reset the console. */
     605:     perror("Can't create keyboard fork");
     606:     if (!quiet) {
     607:     printf("\r\nCommunications disconnect (Back at %s)\r\n",
     608:            *myhost ?
     609:            myhost :
     610: #ifdef UNIX
     611:            "local UNIX system"
     612: #else
     613:            "local system"
     614: #endif /* UNIX */
     615:            );
     616:     }
     617:     printf("\n");
     618:     what = W_NOTHING;       /* So console modes are set right. */
     619: #ifndef NOCSETS
     620:     language = langsv;      /* Restore language */
     621: #endif /* NOCSETS */
     622:     parent_id = (PID_T) 0;      /* Clean up */
     623: #ifdef DYNAMIC
     624:     if (temp) free(temp);       /* Free allocated memory */
     625:     if (ibuf) free(ibuf);
     626:     if (obuf) free(obuf);
     627: #endif /* DYNAMIC */
     628:     return(1);
     629:     }
     630:     if (pid) {              /* Top fork reads, sends keystrokes */
     631:     what = W_CONNECT;       /* Keep track of what we're doing */
     632:     active = 1;
     633:     debug(F101,"CONNECT keyboard fork duplex","",duplex);
     634:
     635:     /* Catch communication errors or mode changes in lower fork */
     636:
     637:     if (setjmp(con_env) == 0) { /* Normal entry... */
     638:         sjval = 0;          /* Initialize setjmp return code. */
     639:         signal(SIGUSR1,conn_int);   /* Routine for child process exit. */
     640:         signal(SIGUSR2,mode_chg);   /* Routine for mode change. */
     641: #ifdef SUNX25
     642:         if (network && nettype == NET_SX25) {
     643:         obufl = 0;
     644:         bzero (x25obuf,sizeof(x25obuf)) ;
     645:         }
     646: #endif /* SUNX25 */
     647:
     648: /*
     649:   Here is the big loop that gets characters from the keyboard and sends them
     650:   out the communication device.  There are two components to the communication
     651:   path: the connection from the keyboard to C-Kermit, and from C-Kermit to
     652:   the remote computer.  The treatment of the 8th bit of keyboard characters
     653:   is governed by SET COMMAND BYTESIZE (cmdmsk).  The treatment of the 8th bit
     654:   of characters sent to the remote is governed by SET TERMINAL BYTESIZE
     655:   (cmask).   This distinction was introduced in edit 5A(164).
     656: */
     657:         while (active) {
     658: #ifndef NOSETKEY
     659:         if (kmptr) {        /* Have current macro? */
     660:             debug(F100,"kmptr non NULL","",0);
     661:             if ((c = (CHAR) *kmptr++) == NUL) { /* Get char from it */
     662:             kmptr = NULL;   /* If no more chars,  */
     663:             debug(F100,"macro empty, continuing","",0);
     664:             continue;   /* reset pointer and continue */
     665:             }
     666:             debug(F000,"char from macro","",c);
     667:         } else          /* No macro... */
     668: #endif /* NOSETKEY */
     669:           c = congks(0);    /* Read from keyboard */
     670:
     671:         debug(F111,"** KEYB",dbchr(c),c);
     672:
     673:                 if (c == -1) {      /* If read() got an error... */
     674: #ifdef COMMENT
     675: /*
     676:  This seems to cause problems.  If read() returns -1, the signal has already
     677:  been delivered, and nothing will wake up the pause().
     678: */
     679:             pause();        /* Wait for transmitter to finish. */
     680: #else
     681: #ifdef A986
     682: /*
     683:   On Altos machines with Xenix 3.0, pressing DEL in connect mode brings us
     684:   here (reason unknown).  The console line discipline at this point has
     685:   intr = ^C.  The communications tty has intr = DEL but we get here after
     686:   pressing DEL on the keyboard, even when the remote system has been set not
     687:   to echo.  With A986 defined, we stay in the read loop and beep only if the
     688:   offending character is not DEL.
     689: */
     690:             if ((c & 127) != 127) conoc(BEL);
     691: #else
     692:             conoc(BEL);     /* Beep */
     693:             active = 0;     /* and terminate the read loop */
     694:             continue;
     695: #endif /* A986 */
     696: #endif /* COMMENT */
     697:         }
     698:         c &= cmdmsk;        /* Do any requested masking */
     699: #ifndef NOSETKEY
     700: /*
     701:   Note: kmptr is NULL if we got character c from the keyboard, and it is
     702:   not NULL if it came from a macro.  In the latter case, we must avoid
     703:   expanding it again.
     704: */
     705:         if (!kmptr && macrotab[c]) { /* Macro definition for c? */
     706:             kmptr = macrotab[c];     /* Yes, set up macro pointer */
     707:             continue;            /* and restart the loop, */
     708:         } else c = keymap[c];        /* else use single-char keymap */
     709: #endif /* NOSETKEY */
     710:         if (
     711: #ifndef NOSETKEY
     712:             !kmptr &&
     713: #endif /* NOSETKEY */
     714:             ((c & 0x7f) == escape)) { /* Escape character? */
     715:             debug(F000,"connect got escape","",c);
     716:             c = congks(0) & 0177; /* Got esc, get its arg */
     717:             /* No key mapping here */
     718:             doesc((char) c);    /* Now process it */
     719:
     720:         } else {        /* It's not the escape character */
     721:             csave = c;      /* Save it before translation */
     722:                     /* for local echoing. */
     723: #ifndef NOCSETS
     724: #ifndef SKIPESC
     725:             /* Translate character sets */
     726:             if (sxo) c = (*sxo)(c); /* From local to intermediate. */
     727:             if (rxo) c = (*rxo)(c); /* From intermediate to remote. */
     728: #else
     729:             if (inesc == ES_NORMAL) { /* If not inside escape seq.. */
     730:             /* Translate character sets */
     731:             if (sxo) c = (*sxo)((char)c); /* Local-intermediate */
     732:             if (rxo) c = (*rxo)((char)c); /* Intermediate-remote */
     733:             }
     734:             if (skipesc) chkaes((char)c); /* Check escape seq status */
     735: #endif /* SKIPESC */
     736: #endif /* NOCSETS */
     737: /*
     738:  If Shift-In/Shift-Out is selected and we have a 7-bit connection,
     739:  handle shifting here.
     740: */
     741:             if (sosi) {          /* Shift-In/Out selected? */
     742:             if (cmask == 0177) { /* In 7-bit environment? */
     743:                 if (c & 0200) {          /* 8-bit character? */
     744:                 if (outshift == 0) { /* If not shifted, */
     745:                     ttoc(dopar(SO)); /* shift. */
     746:                     outshift = 1;
     747:                 }
     748:                 } else {
     749:                 if (outshift == 1) { /* 7-bit character */
     750:                     ttoc(dopar(SI)); /* If shifted, */
     751:                     outshift = 0;    /* unshift. */
     752:                 }
     753:                 }
     754:             }
     755:             if (c == SO) outshift = 1;   /* User typed SO */
     756:             if (c == SI) outshift = 0;   /* User typed SI */
     757:             }
     758:             c &= cmask;     /* Apply Kermit-to-host mask now. */
     759: #ifdef SUNX25
     760:                     if (network && nettype == NET_SX25) {
     761:                         if (padparms[PAD_ECHO]) {
     762:                             if (debses)
     763:                   conol(dbchr(c)) ;
     764:                             else
     765:                   if ((c != padparms[PAD_CHAR_DELETE_CHAR])   &&
     766:                   (c != padparms[PAD_BUFFER_DELETE_CHAR]) &&
     767:                   (c != padparms[PAD_BUFFER_DISPLAY_CHAR]))
     768:                                 conoc(c) ;
     769:                             if (seslog) logchar(c);
     770:                         }
     771:             if (c == CR && (padparms[PAD_LF_AFTER_CR] == 4 ||
     772:                     padparms[PAD_LF_AFTER_CR] == 5)) {
     773:                             if (debses)
     774:                   conol(dbchr(LF)) ;
     775:                             else
     776:                   conoc(LF) ;
     777:                             if (seslog) logchar(LF);
     778:                         }
     779:                         if (c == padparms[PAD_BREAK_CHARACTER])
     780:               breakact();
     781:                         else if (padparms[PAD_DATA_FORWARD_TIMEOUT]) {
     782:                             tosend = 1;
     783:                             x25obuf [obufl++] = c;
     784:                         } else if (((c == padparms[PAD_CHAR_DELETE_CHAR])  ||
     785:                     (c == padparms[PAD_BUFFER_DELETE_CHAR]) ||
     786:                     (c == padparms[PAD_BUFFER_DISPLAY_CHAR]))
     787:                    && (padparms[PAD_EDITING]))
     788:               if (c == padparms[PAD_CHAR_DELETE_CHAR])
     789:                 if (obufl > 0) {
     790:                 conol("\b \b"); obufl--;
     791:                 } else {}
     792:               else if (c == padparms[PAD_BUFFER_DELETE_CHAR]) {
     793:                   conol ("\r\nPAD Buffer Deleted\r\n");
     794:                   obufl = 0;
     795:               }
     796:               else if (c == padparms[PAD_BUFFER_DISPLAY_CHAR]) {
     797:                   conol("\r\n");
     798:                   conol(x25obuf);
     799:                   conol("\r\n");
     800:               } else {}
     801:                         else {
     802:                             x25obuf [obufl++] = c;
     803:                             if (obufl == MAXOX25) tosend = 1;
     804:                             else if (c == CR) tosend = 1;
     805:                         }
     806:                         if (tosend)
     807:               if (ttol(x25obuf,obufl) < 0) {
     808:                   perror ("\r\nCan't send characters");
     809:                   active = 0;
     810:               } else {
     811:                   bzero (x25obuf,sizeof(x25obuf));
     812:                   obufl = 0;
     813:                   tosend = 0;
     814:               } else {};
     815:                     } else {
     816: #endif /* SUNX25 */
     817:
     818: /* If we have a CR, handle CR/CRLF mapping... */
     819:
     820:             if (c == '\015') {
     821:             if (tnlm    /* TERMINAL NEWLINE ON */
     822: #ifdef TNCODE               /* And for TELNET... */
     823:             || (network && ttnproto == NP_TELNET)
     824: #endif /* TNCODE */
     825:             ) {
     826:                 ttoc(dopar('\015'));    /* Send CR */
     827:                 if (duplex) conoc('\015');  /* Maybe echo CR */
     828: #ifdef TNCODE
     829:                 if (network && !tn_nlm && ttnproto == NP_TELNET)
     830:                   c = '\0';     /* Stuff NUL */
     831:                 else
     832: #endif /* TNCODE */
     833:                   c = '\012';   /* Stuff LF */
     834:                 csave = c;
     835:             }
     836:             }           /* Now process the LF or NUL... */
     837: #ifdef TNCODE
     838: /* If user types the 0xff character (TELNET IAC), it must be doubled. */
     839:             else
     840:               if (c == IAC && network && ttnproto == NP_TELNET) {
     841:                     /* Send one copy now */
     842:             ttoc((char)IAC); /* and the other one just below. */
     843:             }
     844: #endif /* TNCODE */
     845:
     846:             /* Send the character */
     847:
     848:             if (ttoc((char)dopar((CHAR) c)) > -1) {
     849:                 if (duplex) {   /* If half duplex, must echo */
     850:                 if (debses)
     851:                   conol(dbchr(csave)); /* the original char */
     852:                 else               /* not the translated one */
     853:                   conoc((char)csave);
     854:                 if (seslog) { /* And maybe log it too */
     855:                 c2 = csave;
     856:                 if (sessft == 0 && csave == '\r')
     857:                   c2 = '\n';
     858:                 logchar((char)c2);
     859:                 }
     860:             }
     861:                     } else {
     862:             perror("\r\nCan't send character");
     863:             active = 0;
     864:             }
     865: #ifdef SUNX25
     866:         }
     867: #endif /* SUNX25 */
     868:         }
     869:         }
     870:     }               /* Come here on death of child */
     871:     debug(F100,"CONNECT killing port fork","",0);
     872:     kill(pid,9);            /* Done, kill inferior fork. */
     873:     wait((WAIT_T *)0);      /* Wait till gone. */
     874:     if (sjval == 1) {       /* Read error on comm device */
     875:         dohangup = 1;
     876: #ifdef NETCONN
     877:         if (network) {
     878:         ttclos(0);
     879: #ifdef SUNX25
     880:         if (nettype == NET_SX25) initpad();
     881: #endif /* SUNX25 */
     882:         }
     883: #endif /* NETCONN */
     884:     }
     885:     if (sjval == 2)         /* If it was a mode change, go back */
     886:       goto newfork;         /* and coordinate with other fork. */
     887:     conres();           /* Reset the console. */
     888:     if (quitnow) doexit(GOOD_EXIT,xitsta); /* Exit now if requested. */
     889:     if (dohangup > 0) {     /* If hangup requested, do that. */
     890: #ifndef NODIAL
     891:         if (dohangup > 1)       /* User asked for it */
     892:           if (mdmhup() < 1)     /* Maybe hang up via modem */
     893: #endif /* NODIAL */
     894:           tthang();         /* And make sure we don't hang up */
     895:         dohangup = 0;       /* again unless requested again. */
     896:     }
     897: #ifdef SUNX25
     898:     if (dox25clr) {         /* If X.25 clear requested */
     899:         x25clear();         /* do that. */
     900:         initpad();
     901:         dox25clr = 0;       /* But only once. */
     902:     }
     903: #endif /* SUNX25 */
     904:     if (!quiet)
     905:       printf("(Back at %s)", *myhost ? myhost : "local UNIX system");
     906:     printf("\n");
     907:     what = W_NOTHING;       /* So console modes set right. */
     908: #ifndef NOCSETS
     909:     language = langsv;      /* Restore language */
     910: #endif /* NOCSETS */
     911:     parent_id = (PID_T) 0;
     912: #ifdef DYNAMIC
     913:     if (temp) free(temp);       /* Free allocated memory */
     914:     if (ibuf) free(ibuf);
     915:     if (obuf) free(obuf);
     916: #endif /* DYNAMIC */
     917:     return(1);
     918:
     919:     } else {                /* Inferior reads, prints port input */
     920:
     921: #ifndef OXOS
     922:     if (priv_can()) {       /* Cancel all privs */
     923:         printf("?setuid error - fatal\n");
     924:         doexit(BAD_EXIT,-1);
     925:     }
     926: #endif /* OXOS */
     927:     signal(SIGINT, SIG_IGN);    /* In case these haven't been */
     928:     signal(SIGQUIT, SIG_IGN);   /* inherited from above... */
     929:
     930:     inshift = outshift = 0;     /* Initial SO/SI shift state. */
     931:     sleep(1);           /* Wait for parent's handler setup.  */
     932:     ibp = ibuf;         /* Initialize input buffering */
     933:     ibc = 0;            /* And output buffering. */
     934:     obp = obuf;
     935:     obc = 0;
     936:     debug(F100,"CONNECT starting port fork","",0);
     937:     while (1) {         /* Fresh read, wait for a character. */
     938: #ifdef SUNX25
     939:         if (network && (nettype == NET_SX25)) {
     940:         bzero(x25ibuf,sizeof(x25ibuf)) ;
     941:         if ((ibufl = ttxin(MAXIX25,x25ibuf)) < 0) {
     942:             if (ibufl == -2) {  /* PAD parms changes */
     943:             write(padpipe[1],padparms,MAXPADPARMS);
     944:             kill(parent_id,SIGUSR2);
     945:             } else {
     946:             if (!quiet)
     947:               printf("\r\nCommunications disconnect ");
     948:             kill(parent_id,SIGUSR1);
     949:             }
     950:             pause();
     951:         }
     952:         if (debses) {       /* Debugging output */
     953:             p = x25ibuf ;
     954:                         while (ibufl--) { c = *p++; conol(dbchr(c)); }
     955:         } else {
     956:             if (sosi
     957: #ifndef NOCSETS
     958:             || tcsl != tcsr
     959: #endif /* NOCSETS */
     960:             ) { /* Character at a time */
     961:             for (i = 1; i < ibufl; i++) {
     962:                 c = x25ibuf[i] & cmask;
     963:                 if (sosi) { /* Handle SI/SO */
     964:                 if (c == SO) {
     965:                     inshift = 1;
     966:                     continue;
     967:                 } else if (c == SI) {
     968:                     inshift = 0;
     969:                     continue;
     970:                 }
     971:                 if (inshift)
     972:                   c |= 0200;
     973:                 }
     974: #ifndef NOCSETS
     975: #ifndef SKIPESC
     976:             /* Translate character sets */
     977:             if (sxo) c = (*sxo)(c); /* From local to intermediate. */
     978:             if (rxo) c = (*rxo)(c); /* From intermediate to remote. */
     979:
     980: #else /* Skipping escape sequences... */
     981:
     982:             if (inesc == ES_NORMAL) { /* If not inside escape seq.. */
     983:             /* Translate character sets */
     984:             if (sxo) c = (*sxo)(c); /* Local to intermediate. */
     985:             if (rxo) c = (*rxo)(c); /* Intermediate to remote. */
     986:             }
     987:             if (skipesc) chkaes(c); /* Check escape sequence status */
     988: #endif /* SKIPESC */
     989: #endif /* NOCSETS */
     990:                 c &= cmdmsk; /* Apply command mask. */
     991:                 conoc(c);    /* Output to screen */
     992:                 logchar(c);  /* and session log */
     993:             }
     994:             } else {         /* All at once */
     995:             for (i = 1; i < ibufl; i++)
     996:               x25ibuf[i] &= (cmask & cmdmsk);
     997:             conxo(ibufl,x25ibuf);
     998:             if (seslog) zsoutx(ZSFILE,x25ibuf,ibufl);
     999:             }
    1000:         }
    1001:         continue;
    1002:
    1003:         } else {            /* Not X.25... */
    1004: #endif /* SUNX25 */
    1005: /*
    1006:   Get the next communication line character from our internal buffer.
    1007:   If the buffer is empty, refill it.
    1008: */
    1009:         c = ckcgetc(0);     /* Get next character */
    1010:         /* debug(F101,"CONNECT c","",c); */
    1011:         if (c < 0) {
    1012:             if (!quiet) {   /* Failed... */
    1013:             printf("\r\nCommunications disconnect ");
    1014:             if ( c == -3
    1015: #ifdef UTEK
    1016: /* This happens on UTEK if there's no carrier */
    1017:                 && errno != EWOULDBLOCK
    1018: #endif /* UTEK */
    1019:                 )
    1020:               perror("\r\nCan't read character");
    1021:             }
    1022:             tthang();       /* Hang up the connection */
    1023:             kill(parent_id,SIGUSR1); /* Notify parent */
    1024:             for (;;) pause();   /* and wait to be killed */
    1025:         }
    1026:         debug(F111,"** PORT",dbchr(c),c);
    1027: #ifdef TNCODE
    1028:         /* Handle TELNET negotiations here */
    1029:         if (c == IAC && network && ttnproto == NP_TELNET) {
    1030:             ckcputf();      /* Dump output buffer */
    1031:             if ((tx = tn_doop((CHAR)(c & 0xff),duplex,ckcgetc)) == 0) {
    1032:             continue;
    1033:             } else if (tx == -1) { /* I/O error */
    1034:             if (!quiet)
    1035:               printf("\r\nCommunications disconnect ");
    1036:             kill(parent_id,SIGUSR1); /* Notify parent. */
    1037:             for (;;) pause(); /* Wait to be killed. */
    1038:             } else if ((tx == 1) && (!duplex)) { /* ECHO change */
    1039:             kill(parent_id,SIGUSR2); /* Tell the parent fork */
    1040:             duplex = 1;
    1041:             } else if ((tx == 2) && (duplex)) { /* ECHO change */
    1042:             kill(parent_id,SIGUSR2);
    1043:             duplex = 0;
    1044:             } else if (tx == 3) { /* Quoted IAC */
    1045:             c = 255;
    1046:             } else continue;    /* Negotiation OK, get next char. */
    1047:         }
    1048: #endif /* TNCODE */
    1049:         if (debses) {       /* Output character to screen */
    1050:             char *s;        /* Debugging display... */
    1051:             s = dbchr(c);
    1052:             while (*s)
    1053:               ckcputc(*s++);
    1054:         } else {        /* Regular display ... */
    1055:             c &= cmask;     /* Apply Kermit-to-remote mask */
    1056:             if (sosi) {     /* Handle SI/SO */
    1057:             if (c == SO) {  /* Shift Out */
    1058:                 inshift = 1;
    1059:                 continue;
    1060:             } else if (c == SI) { /* Shift In */
    1061:                 inshift = 0;
    1062:                 continue;
    1063:             }
    1064:             if (inshift) c |= 0200;
    1065:             }
    1066: #ifndef NOCSETS
    1067: #ifndef SKIPESC
    1068:             /* Translate character sets */
    1069:             if (sxi) c = (*sxi)((CHAR)c);
    1070:             if (rxi) c = (*rxi)((CHAR)c);
    1071: #else
    1072:             if (inesc == ES_NORMAL) {
    1073:             /* Translate character sets */
    1074:             if (sxi) c = (*sxi)((CHAR)c);
    1075:             if (rxi) c = (*rxi)((CHAR)c);
    1076:             }
    1077:             /* Adjust escape sequence status */
    1078:             if (skipesc) chkaes((char)c);
    1079: #endif /* SKIPESC */
    1080: #endif /* NOCSETS */
    1081:             c &= cmdmsk;    /* Apply command mask. */
    1082:             if (c == CR && tt_crd) { /* SET TERM CR-DISPLAY CRLF ? */
    1083:             ckcputc(c);      /* Yes, output CR */
    1084:             if (seslog) logchar((char)c);
    1085:             c = LF;          /* and insert a linefeed */
    1086:             }
    1087:             ckcputc(c);     /* Output character to screen */
    1088:             if (seslog) logchar((char)c); /* Do session log */
    1089:         }
    1090: #ifdef SUNX25
    1091:         }
    1092: #endif /* SUNX25 */
    1093:     }
    1094:     }
    1095: }
    1096:
    1097:
    1098: /*  H C O N N E  --  Give help message for connect.  */
    1099:
    1100: int
    1101: hconne() {
    1102:     int c;
    1103:     static char *hlpmsg[] = {
    1104: "\r\n  ? for this message",
    1105: "\r\n  0 (zero) to send a null",
    1106: "\r\n  B to send a BREAK",
    1107: #ifdef CK_LBRK
    1108: "\r\n  L to send a Long BREAK",
    1109: #endif /* CK_LBRK */
    1110: #ifdef NETCONN
    1111: "\r\n  I to send a network interrupt packet",
    1112: #ifdef TCPSOCKET
    1113: "\r\n  A to send Are You There?",
    1114: #endif /* TCPSOCKET */
    1115: #ifdef SUNX25
    1116: "\r\n  R to reset X.25 virtual circuit",
    1117: #endif /* SUNX25 */
    1118: #endif /* NETCONN */
    1119: "\r\n  H to hangup and close the connection",
    1120: "\r\n  Q to hangup and quit Kermit",
    1121: "\r\n  S for status",
    1122: "\r\n  ! to push to local shell",
    1123: "\r\n  Z to suspend",
    1124: "\r\n  \\ backslash code:",
    1125: "\r\n    \\nnn  decimal character code",
    1126: "\r\n    \\Onnn octal character code",
    1127: "\r\n    \\Xhh  hexadecimal character code",
    1128: "\r\n    terminate with carriage return.",
    1129: "\r\n Type the escape character again to send the escape character, or",
    1130: "\r\n press the space-bar to resume the CONNECT command.\r\n\r\n",
    1131: "" };
    1132:     conol("\r\nPress C to return to ");
    1133:     conol(*myhost ? myhost : "the C-Kermit prompt");
    1134:     conol(", or:");
    1135:     conola(hlpmsg);         /* Print the help message. */
    1136:     conol("Command>");          /* Prompt for command. */
    1137:     c = congks(0) & 0177;       /* Get character, strip any parity. */
    1138:     /* No key mapping or translation here */
    1139:     if (c != CMDQ)
    1140:       conoll("");
    1141:     return(c);              /* Return it. */
    1142: }
    1143:
    1144:
    1145: /*  D O E S C  --  Process an escape character argument  */
    1146:
    1147: VOID
    1148: #ifdef CK_ANSIC
    1149: doesc(char c)
    1150: #else
    1151: doesc(c) char c;
    1152: #endif /* CK_ANSIC */
    1153: /* doesc */ {
    1154:     CHAR d;
    1155:
    1156:     while (1) {
    1157:     if (c == escape) {      /* Send escape character */
    1158:         d = dopar((CHAR) c); ttoc((char) d); return;
    1159:         } else              /* Or else look it up below. */
    1160:         if (isupper(c)) c = tolower(c);
    1161:
    1162:     switch(c) {
    1163:
    1164:     case 'c':           /* Escape back to prompt */
    1165:     case '\03':
    1166:         active = 0; conol("\r\n"); return;
    1167:
    1168:     case 'b':           /* Send a BREAK signal */
    1169:     case '\02':
    1170:         ttsndb(); return;
    1171:
    1172: #ifdef NETCONN
    1173:     case 'i':           /* Send Interrupt */
    1174:     case '\011':
    1175: #ifdef TCPSOCKET
    1176: #ifndef IP
    1177: #define IP 244
    1178: #endif /* IP */
    1179:         if (network && ttnproto == NP_TELNET) { /* TELNET */
    1180:         temp[0] = IAC;      /* I Am a Command */
    1181:         temp[1] = IP;       /* Interrupt Process */
    1182:         temp[2] = NUL;
    1183:         ttol((CHAR *)temp,2);
    1184:         } else
    1185: #endif /* TCPSOCKET */
    1186: #ifdef SUNX25
    1187:             if (network && (nettype == NET_SX25)) { /* X.25 */
    1188:         (VOID) x25intr(0);              /* X.25 interrupt packet */
    1189:         conol("\r\n");
    1190:         } else
    1191: #endif /* SUNX25 */
    1192:           conoc(BEL);
    1193:         return;
    1194:
    1195: #ifdef TCPSOCKET
    1196:     case 'a':           /* "Are You There?" */
    1197:     case '\01':
    1198: #ifndef AYT
    1199: #define AYT 246
    1200: #endif /* AYT */
    1201:         if (network && ttnproto == NP_TELNET) {
    1202:         temp[0] = IAC;      /* I Am a Command */
    1203:         temp[1] = AYT;      /* Are You There? */
    1204:         temp[2] = NUL;
    1205:         ttol((CHAR *)temp,2);
    1206:         } else conoc(BEL);
    1207:         return;
    1208: #endif /* TCPSOCKET */
    1209: #endif /* NETCONN */
    1210:
    1211: #ifdef CK_LBRK
    1212:     case 'l':           /* Send a Long BREAK signal */
    1213:         ttsndlb(); return;
    1214: #endif /* CK_LBRK */
    1215:
    1216:     case 'h':           /* Hangup */
    1217:     case '\010':
    1218: #ifdef SUNX25
    1219:             if (network && (nettype == NET_SX25)) dox25clr = 1;
    1220:             else
    1221: #endif /* SUNX25 */
    1222:         dohangup = 2; active = 0; conol("\r\nHanging up "); return;
    1223:
    1224: #ifdef SUNX25
    1225:         case 'r':                       /* Reset the X.25 virtual circuit */
    1226:         case '\022':
    1227:             if (network && (nettype == NET_SX25)) (VOID) x25reset();
    1228:             conol("\r\n"); return;
    1229: #endif /* SUNX25 */
    1230:
    1231:     case 'q':           /* Quit */
    1232:         quitnow = 1; active = 0; conol("\r\n"); return;
    1233:
    1234:     case 's':           /* Status */
    1235:         sprintf(temp,
    1236:             "\r\nConnected %s %s", network ? "to" : "through", ttname);
    1237:         conol(temp);
    1238: #ifdef SUNX25
    1239:             if (network && (nettype == NET_SX25)) {
    1240:                 sprintf(temp,", Link ID %d, LCN %d",linkid,lcn); conol(temp);
    1241:         }
    1242: #endif /* SUNX25 */
    1243:         if (speed >= 0L) {
    1244:         sprintf(temp,", speed %ld", speed);
    1245:         conoll(temp);
    1246:         } else conoll("");
    1247:         sprintf(temp,
    1248:             "Terminal bytesize: %d, Command bytesize: %d, Parity: ",
    1249:             (cmask  == 0177) ? 7 : 8,
    1250:             (cmdmsk == 0177) ? 7 : 8 );
    1251:         conol(temp);
    1252:
    1253:         switch (parity) {
    1254:           case  0:  conoll("none");  break;
    1255:           case 'e': conoll("even");  break;
    1256:           case 'o': conoll("odd");   break;
    1257:           case 's': conoll("space"); break;
    1258:           case 'm': conoll("mark");  break;
    1259:         }
    1260:         sprintf(temp,"Terminal echo: %s", duplex ? "local" : "remote");
    1261:         conoll(temp);
    1262:         if (seslog) {
    1263:         conol("Logging to: "); conoll(sesfil);
    1264:             }
    1265:         if (!network) shomdm();
    1266:         return;
    1267:
    1268:     case '?':           /* Help */
    1269:         c = hconne(); continue;
    1270:
    1271:     case '0':           /* Send a null */
    1272:         c = '\0'; d = dopar((CHAR) c); ttoc((char) d); return;
    1273:
    1274: #ifndef NOPUSH
    1275:     case 'z': case '\032':      /* Suspend */
    1276:         stptrap(0); return;
    1277:
    1278:     case '@':           /* Start inferior command processor */
    1279:     case '!':
    1280:         conres();           /* Put console back to normal */
    1281:         zshcmd("");         /* Fork a shell. */
    1282:         if (conbin((char)escape) < 0) {
    1283:         printf("Error resuming CONNECT session\n");
    1284:         active = 0;
    1285:         }
    1286:         return;
    1287: #endif /* NOPUSH */
    1288:
    1289:     case SP:            /* Space, ignore */
    1290:         return;
    1291:
    1292:     default:            /* Other */
    1293:         if (c == CMDQ) {        /* Backslash escape */
    1294:         int x;
    1295:         kbp = kbuf;
    1296:         *kbp++ = c;
    1297:         while (((c = (congks(0) & cmdmsk)) != '\r') && (c != '\n'))
    1298:           *kbp++ = c;
    1299:         *kbp = NUL; kbp = kbuf;
    1300:         x = xxesc(&kbp);    /* Interpret it */
    1301:         if (x >= 0) {       /* No key mapping here */
    1302:             c = dopar((CHAR) x);
    1303:             ttoc((char) c);
    1304:             return;
    1305:         } else {        /* Invalid backslash code. */
    1306:             conoc(BEL);
    1307:             return;
    1308:         }
    1309:         }
    1310:         conoc(BEL); return;     /* Invalid esc arg, beep */
    1311:         }
    1312:     }
    1313: }
    1314:
    1315: VOID
    1316: #ifdef CK_ANSIC
    1317: logchar(char c)
    1318: #else
    1319: logchar(c) char c;
    1320: #endif /* CK_ANSIC */
    1321: /* logchar */ {         /* Log character c to session log */
    1322:     if (seslog)
    1323:       if ((sessft != 0) ||
    1324:       (c != '\r' &&
    1325:        c != '\0' &&
    1326:        c != XON &&
    1327:        c != XOFF))
    1328:     if (zchout(ZSFILE,c) < 0) {
    1329:         conoll("");
    1330:         conoll("ERROR WRITING SESSION LOG, LOG CLOSED!");
    1331:         seslog = 0;
    1332:     }
    1333: }

#### Defined functions

chkaes defined in line 229; used 3 times

- in line 734, 987, 1078

ckcgetc defined in line 369; used 2 times

- in line 1009, 1031

ckcputc defined in line 346; used 3 times

- in line 1053, 1083-1087(2)

ckcputf defined in line 336; used 1 times

- in line 1030

conect defined in line 407; used 4 times

- in /usr/src/new/kermit5.188/ckcmai.c line 851, 860, 866
- in /usr/src/new/kermit5.188/ckuus4.c line 1526

conn_int defined in line 299; used 1 times

- in line 639

doesc defined in line 1147; used 2 times

- in line 43, 718

hconne defined in line 1100; used 2 times

- in line 45, 1269

logchar defined in line 1315; used 7 times

- in line 44, 769, 777, 858, 992, 1084-1088(2)

mode_chg defined in line 307; used 2 times

- in line 310, 640

#### Defined variables

VOID defined in line 1147; never used
active defined in line 110; used 10 times

- in line 77, 632, 657, 693, 809, 863, 1166, 1222, 1232, 1284

con_env defined in line 289; used 3 times

- in line 304, 321, 637

connv defined in line 1; used 1 times

- in /usr/src/new/kermit5.188/ckuus5.c line 1601

dox25clr defined in line 115; used 4 times

- in line 478, 898-901(2), 1219

ibc defined in line 86; used 11 times

- in line 352, 373-375(3), 384, 390-401(5), 933

ibp defined in line 85; used 7 times

- in line 376, 383, 392-400(4), 932

ibuf defined in line 101; used 9 times

- in line 376, 398, 424, 430, 625(2), 914(2), 932

ibufl defined in line 111; used 7 times

- in line 941-942(2), 954, 961, 995-998(3)

kbp defined in line 82; used 6 times

- in line 1295-1300(6)

kbuf defined in line 82; used 2 times

- in line 1295-1299(2)

kmptr defined in line 67; used 6 times

- in line 659-662(3), 705-706(2), 712

langsv defined in line 139; used 3 times

- in line 562, 620, 909

lcn defined in line 114; used 2 times

- in line 487, 1240

linkid defined in line 114; used 2 times

- in line 487, 1240

obc defined in line 94; used 9 times

- in line 339-342(3), 351-357(5), 935

obp defined in line 93; used 4 times

- in line 341, 350, 356, 934

obuf defined in line 101; used 12 times

- in line 99, 340-341(2), 355-356(2), 428, 435, 626(2), 915(2), 934

obufl defined in line 112; used 9 times

- in line 643, 783, 789-794(3), 802-812(4)

p defined in line 107; used 2 times

- in line 953-954(2)

padparms defined in line 116; used 42 times

- in line 314, 761-772(6), 779-796(9), 943
- in /usr/src/new/kermit5.188/ckcnet.c line 1274-1292(19), 1307, 1326, 1394, 1404
- in /usr/src/new/kermit5.188/ckuus4.c line 1247
- in /usr/src/new/kermit5.188/ckuus7.c line 1761

padpipe defined in line 117; used 3 times

- in line 314, 600, 943

quitnow defined in line 72; used 2 times

- in line 888, 1232

skipesc defined in line 169; used 5 times

- in line 574, 585, 734, 987, 1078

tcs defined in line 142; used 7 times

- in line 546, 552-555(4), 574-579(2)

temp defined in line 101; used 29 times

- in line 99, 433, 470-472(3), 527-528(2), 624(2), 913(2), 1180-1183(4), 1202-1205(4), 1235-1251(8), 1260-1261(2)

tosend defined in line 113; used 5 times

- in line 782, 803-806(3), 813

x25ibuf defined in line 108; used 8 times

- in line 940-941(3), 953, 962, 996-998(3)

x25obuf defined in line 109; used 8 times

- in line 644(2), 783, 798-811(5)

#### Defined macros

AYT defined in line 1199; used 2 times

- in line 1198-1203(2)

ES_ESCSEQ defined in line 163; used 1 times

- in line 255

ES_GOTCSI defined in line 164; used 1 times

- in line 249

ES_GOTESC defined in line 162; used 3 times

- in line 244, 262, 269

ES_NORMAL defined in line 161; used 10 times

- in line 170, 238, 251, 260, 267, 279, 577, 729, 982, 1072

ES_STRING defined in line 165; used 2 times

- in line 253, 281

ES_TERMIN defined in line 166; used 1 times

- in line 274

IBUFL defined in line 90; used 4 times

- in line 101, 390-391(2), 424

IP defined in line 1177; used 2 times

- in line 1176-1181(2)

OBUFL defined in line 95; used 3 times

- in line 101, 353, 428

SIGUSR1 defined in line 49; used 7 times

- in line 48, 302, 598, 639, 948, 1023, 1036

SIGUSR2 defined in line 53; used 6 times

- in line 52, 310, 640, 944, 1039-1042(2)

SKIPESC defined in line 156; used 5 times

- in line 155, 568, 724, 975, 1067

TMPLEN defined in line 97; used 2 times

- in line 101, 433

Last modified: 1992-11-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3983 |