Annotation of coherent/e/bin/ckermit/ckucon.c, revision 1.1

1.1     ! root        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 ([email protected], [email protected]),
        !             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 COHERENT
        !           611:                "Local COHERENT system"
        !           612: #else
        !           613: #endif /* COHERENT */
        !           614: 
        !           615: #ifdef UNIX
        !           616:               "local UNIX system"
        !           617: #else
        !           618:               "local system"
        !           619: #endif /* UNIX */
        !           620:               );
        !           621:        }
        !           622:        printf("\n");
        !           623:        what = W_NOTHING;               /* So console modes are set right. */
        !           624: #ifndef NOCSETS
        !           625:        language = langsv;              /* Restore language */
        !           626: #endif /* NOCSETS */
        !           627:        parent_id = (PID_T) 0;          /* Clean up */
        !           628: #ifdef DYNAMIC
        !           629:        if (temp) free(temp);           /* Free allocated memory */
        !           630:        if (ibuf) free(ibuf);
        !           631:        if (obuf) free(obuf);
        !           632: #endif /* DYNAMIC */
        !           633:        return(1);
        !           634:     }
        !           635:     if (pid) {                         /* Top fork reads, sends keystrokes */
        !           636:        what = W_CONNECT;               /* Keep track of what we're doing */
        !           637:        active = 1;
        !           638:        debug(F101,"CONNECT keyboard fork duplex","",duplex);
        !           639: 
        !           640:        /* Catch communication errors or mode changes in lower fork */
        !           641: 
        !           642:        if (setjmp(con_env) == 0) {     /* Normal entry... */
        !           643:            sjval = 0;                  /* Initialize setjmp return code. */
        !           644:            signal(SIGUSR1,conn_int);   /* Routine for child process exit. */
        !           645:            signal(SIGUSR2,mode_chg);   /* Routine for mode change. */
        !           646: #ifdef SUNX25
        !           647:            if (network && nettype == NET_SX25) {
        !           648:                obufl = 0;
        !           649:                bzero (x25obuf,sizeof(x25obuf)) ;
        !           650:            }
        !           651: #endif /* SUNX25 */
        !           652: 
        !           653: /*
        !           654:   Here is the big loop that gets characters from the keyboard and sends them
        !           655:   out the communication device.  There are two components to the communication
        !           656:   path: the connection from the keyboard to C-Kermit, and from C-Kermit to
        !           657:   the remote computer.  The treatment of the 8th bit of keyboard characters 
        !           658:   is governed by SET COMMAND BYTESIZE (cmdmsk).  The treatment of the 8th bit
        !           659:   of characters sent to the remote is governed by SET TERMINAL BYTESIZE
        !           660:   (cmask).   This distinction was introduced in edit 5A(164).
        !           661: */
        !           662:            while (active) {
        !           663: #ifndef NOSETKEY
        !           664:                if (kmptr) {            /* Have current macro? */
        !           665:                    debug(F100,"kmptr non NULL","",0);
        !           666:                    if ((c = (CHAR) *kmptr++) == NUL) { /* Get char from it */
        !           667:                        kmptr = NULL;   /* If no more chars,  */
        !           668:                        debug(F100,"macro empty, continuing","",0);
        !           669:                        continue;       /* reset pointer and continue */
        !           670:                    }
        !           671:                    debug(F000,"char from macro","",c);
        !           672:                } else                  /* No macro... */
        !           673: #endif /* NOSETKEY */
        !           674:                  c = congks(0);        /* Read from keyboard */
        !           675: 
        !           676:                debug(F111,"** KEYB",dbchr(c),c);
        !           677: 
        !           678:                 if (c == -1) {         /* If read() got an error... */
        !           679: #ifdef COMMENT
        !           680: /*
        !           681:  This seems to cause problems.  If read() returns -1, the signal has already
        !           682:  been delivered, and nothing will wake up the pause().
        !           683: */
        !           684:                    pause();            /* Wait for transmitter to finish. */
        !           685: #else
        !           686: #ifdef A986
        !           687: /*
        !           688:   On Altos machines with Xenix 3.0, pressing DEL in connect mode brings us
        !           689:   here (reason unknown).  The console line discipline at this point has
        !           690:   intr = ^C.  The communications tty has intr = DEL but we get here after
        !           691:   pressing DEL on the keyboard, even when the remote system has been set not
        !           692:   to echo.  With A986 defined, we stay in the read loop and beep only if the
        !           693:   offending character is not DEL.
        !           694: */
        !           695:                    if ((c & 127) != 127) conoc(BEL);
        !           696: #else
        !           697:                    conoc(BEL);         /* Beep */
        !           698:                    active = 0;         /* and terminate the read loop */
        !           699:                    continue;
        !           700: #endif /* A986 */
        !           701: #endif /* COMMENT */
        !           702:                }
        !           703:                c &= cmdmsk;            /* Do any requested masking */
        !           704: #ifndef NOSETKEY
        !           705: /*
        !           706:   Note: kmptr is NULL if we got character c from the keyboard, and it is
        !           707:   not NULL if it came from a macro.  In the latter case, we must avoid
        !           708:   expanding it again.
        !           709: */
        !           710:                if (!kmptr && macrotab[c]) { /* Macro definition for c? */
        !           711:                    kmptr = macrotab[c];     /* Yes, set up macro pointer */
        !           712:                    continue;                /* and restart the loop, */
        !           713:                } else c = keymap[c];        /* else use single-char keymap */
        !           714: #endif /* NOSETKEY */
        !           715:                if (
        !           716: #ifndef NOSETKEY
        !           717:                    !kmptr &&
        !           718: #endif /* NOSETKEY */
        !           719:                    ((c & 0x7f) == escape)) { /* Escape character? */
        !           720:                    debug(F000,"connect got escape","",c);
        !           721:                    c = congks(0) & 0177; /* Got esc, get its arg */
        !           722:                    /* No key mapping here */
        !           723:                    doesc((char) c);    /* Now process it */
        !           724: 
        !           725:                } else {                /* It's not the escape character */
        !           726:                    csave = c;          /* Save it before translation */
        !           727:                                        /* for local echoing. */
        !           728: #ifndef NOCSETS
        !           729: #ifndef SKIPESC
        !           730:                    /* Translate character sets */
        !           731:                    if (sxo) c = (*sxo)(c); /* From local to intermediate. */
        !           732:                    if (rxo) c = (*rxo)(c); /* From intermediate to remote. */
        !           733: #else
        !           734:                    if (inesc == ES_NORMAL) { /* If not inside escape seq.. */
        !           735:                        /* Translate character sets */
        !           736:                        if (sxo) c = (*sxo)((char)c); /* Local-intermediate */
        !           737:                        if (rxo) c = (*rxo)((char)c); /* Intermediate-remote */
        !           738:                    }
        !           739:                    if (skipesc) chkaes((char)c); /* Check escape seq status */
        !           740: #endif /* SKIPESC */
        !           741: #endif /* NOCSETS */
        !           742: /*
        !           743:  If Shift-In/Shift-Out is selected and we have a 7-bit connection,
        !           744:  handle shifting here.
        !           745: */
        !           746:                    if (sosi) {              /* Shift-In/Out selected? */
        !           747:                        if (cmask == 0177) { /* In 7-bit environment? */
        !           748:                            if (c & 0200) {          /* 8-bit character? */
        !           749:                                if (outshift == 0) { /* If not shifted, */
        !           750:                                    ttoc(dopar(SO)); /* shift. */
        !           751:                                    outshift = 1;
        !           752:                                }
        !           753:                            } else {
        !           754:                                if (outshift == 1) { /* 7-bit character */
        !           755:                                    ttoc(dopar(SI)); /* If shifted, */
        !           756:                                    outshift = 0;    /* unshift. */
        !           757:                                }
        !           758:                            }
        !           759:                        }
        !           760:                        if (c == SO) outshift = 1;   /* User typed SO */
        !           761:                        if (c == SI) outshift = 0;   /* User typed SI */
        !           762:                    }
        !           763:                    c &= cmask;         /* Apply Kermit-to-host mask now. */
        !           764: #ifdef SUNX25
        !           765:                     if (network && nettype == NET_SX25) {
        !           766:                         if (padparms[PAD_ECHO]) {
        !           767:                             if (debses)
        !           768:                              conol(dbchr(c)) ;
        !           769:                             else
        !           770:                              if ((c != padparms[PAD_CHAR_DELETE_CHAR])   &&
        !           771:                                  (c != padparms[PAD_BUFFER_DELETE_CHAR]) &&
        !           772:                                  (c != padparms[PAD_BUFFER_DISPLAY_CHAR]))
        !           773:                                 conoc(c) ;
        !           774:                             if (seslog) logchar(c);
        !           775:                         }
        !           776:                        if (c == CR && (padparms[PAD_LF_AFTER_CR] == 4 ||
        !           777:                                        padparms[PAD_LF_AFTER_CR] == 5)) {
        !           778:                             if (debses)
        !           779:                              conol(dbchr(LF)) ;
        !           780:                             else
        !           781:                              conoc(LF) ;
        !           782:                             if (seslog) logchar(LF);
        !           783:                         }
        !           784:                         if (c == padparms[PAD_BREAK_CHARACTER])
        !           785:                          breakact();
        !           786:                         else if (padparms[PAD_DATA_FORWARD_TIMEOUT]) {
        !           787:                             tosend = 1;
        !           788:                             x25obuf [obufl++] = c;
        !           789:                         } else if (((c == padparms[PAD_CHAR_DELETE_CHAR])  ||
        !           790:                                    (c == padparms[PAD_BUFFER_DELETE_CHAR]) ||
        !           791:                                    (c == padparms[PAD_BUFFER_DISPLAY_CHAR])) 
        !           792:                                   && (padparms[PAD_EDITING]))
        !           793:                          if (c == padparms[PAD_CHAR_DELETE_CHAR])
        !           794:                            if (obufl > 0) {
        !           795:                                conol("\b \b"); obufl--;
        !           796:                            } else {}
        !           797:                          else if (c == padparms[PAD_BUFFER_DELETE_CHAR]) {
        !           798:                              conol ("\r\nPAD Buffer Deleted\r\n");
        !           799:                              obufl = 0;
        !           800:                          }
        !           801:                          else if (c == padparms[PAD_BUFFER_DISPLAY_CHAR]) {
        !           802:                              conol("\r\n");
        !           803:                              conol(x25obuf);
        !           804:                              conol("\r\n");
        !           805:                          } else {} 
        !           806:                         else {
        !           807:                             x25obuf [obufl++] = c;
        !           808:                             if (obufl == MAXOX25) tosend = 1;
        !           809:                             else if (c == CR) tosend = 1;
        !           810:                         }
        !           811:                         if (tosend) 
        !           812:                          if (ttol(x25obuf,obufl) < 0) {
        !           813:                              perror ("\r\nCan't send characters");
        !           814:                              active = 0;
        !           815:                          } else {
        !           816:                              bzero (x25obuf,sizeof(x25obuf));
        !           817:                              obufl = 0;
        !           818:                              tosend = 0;
        !           819:                          } else {};
        !           820:                     } else {
        !           821: #endif /* SUNX25 */ 
        !           822: 
        !           823: /* If we have a CR, handle CR/CRLF mapping... */
        !           824: 
        !           825:                    if (c == '\015') {
        !           826:                        if (tnlm        /* TERMINAL NEWLINE ON */
        !           827: #ifdef TNCODE                          /* And for TELNET... */
        !           828:                        || (network && ttnproto == NP_TELNET)
        !           829: #endif /* TNCODE */
        !           830:                        ) {
        !           831:                            ttoc(dopar('\015'));        /* Send CR */
        !           832:                            if (duplex) conoc('\015');  /* Maybe echo CR */
        !           833: #ifdef TNCODE
        !           834:                            if (network && !tn_nlm && ttnproto == NP_TELNET)
        !           835:                              c = '\0';         /* Stuff NUL */
        !           836:                            else
        !           837: #endif /* TNCODE */
        !           838:                              c = '\012';       /* Stuff LF */
        !           839:                            csave = c;
        !           840:                        }
        !           841:                    }                   /* Now process the LF or NUL... */
        !           842: #ifdef TNCODE
        !           843: /* If user types the 0xff character (TELNET IAC), it must be doubled. */
        !           844:                    else
        !           845:                      if (c == IAC && network && ttnproto == NP_TELNET) {
        !           846:                                        /* Send one copy now */
        !           847:                        ttoc((char)IAC); /* and the other one just below. */
        !           848:                    }
        !           849: #endif /* TNCODE */
        !           850: 
        !           851:                    /* Send the character */
        !           852: 
        !           853:                    if (ttoc((char)dopar((CHAR) c)) > -1) {
        !           854:                        if (duplex) {   /* If half duplex, must echo */
        !           855:                            if (debses)
        !           856:                              conol(dbchr(csave)); /* the original char */
        !           857:                            else                   /* not the translated one */
        !           858:                              conoc((char)csave);
        !           859:                            if (seslog) { /* And maybe log it too */
        !           860:                                c2 = csave;
        !           861:                                if (sessft == 0 && csave == '\r')
        !           862:                                  c2 = '\n';
        !           863:                                logchar((char)c2);
        !           864:                            }
        !           865:                        }
        !           866:                    } else {
        !           867:                        perror("\r\nCan't send character");
        !           868:                        active = 0;
        !           869:                    }
        !           870: #ifdef SUNX25
        !           871:                } 
        !           872: #endif /* SUNX25 */
        !           873:                }
        !           874:            }
        !           875:        }                               /* Come here on death of child */
        !           876:        debug(F100,"CONNECT killing port fork","",0);
        !           877:        kill(pid,9);                    /* Done, kill inferior fork. */
        !           878:        wait((WAIT_T *)0);              /* Wait till gone. */
        !           879:        if (sjval == 1) {               /* Read error on comm device */
        !           880:            dohangup = 1;
        !           881: #ifdef NETCONN
        !           882:            if (network) {
        !           883:                ttclos(0);
        !           884: #ifdef SUNX25
        !           885:                if (nettype == NET_SX25) initpad();
        !           886: #endif /* SUNX25 */
        !           887:            }
        !           888: #endif /* NETCONN */
        !           889:        }
        !           890:        if (sjval == 2)                 /* If it was a mode change, go back */
        !           891:          goto newfork;                 /* and coordinate with other fork. */
        !           892:        conres();                       /* Reset the console. */
        !           893:        if (quitnow) doexit(GOOD_EXIT,xitsta); /* Exit now if requested. */
        !           894:        if (dohangup > 0) {             /* If hangup requested, do that. */
        !           895: #ifndef NODIAL
        !           896:            if (dohangup > 1)           /* User asked for it */
        !           897:              if (mdmhup() < 1)         /* Maybe hang up via modem */
        !           898: #endif /* NODIAL */
        !           899:              tthang();                 /* And make sure we don't hang up */
        !           900:            dohangup = 0;               /* again unless requested again. */
        !           901:        }
        !           902: #ifdef SUNX25
        !           903:        if (dox25clr) {                 /* If X.25 clear requested */
        !           904:            x25clear();                 /* do that. */
        !           905:            initpad();
        !           906:            dox25clr = 0;               /* But only once. */
        !           907:        }
        !           908: #endif /* SUNX25 */
        !           909:        if (!quiet)
        !           910: #ifdef COHERENT
        !           911:          printf("(Back at %s)", *myhost ? myhost : "local COHERENT system");
        !           912: #else
        !           913:          printf("(Back at %s)", *myhost ? myhost : "local UNIX system");
        !           914: #endif /* COHERENT */
        !           915:        printf("\n");
        !           916:        what = W_NOTHING;               /* So console modes set right. */
        !           917: #ifndef NOCSETS
        !           918:        language = langsv;              /* Restore language */
        !           919: #endif /* NOCSETS */
        !           920:        parent_id = (PID_T) 0;
        !           921: #ifdef DYNAMIC
        !           922:        if (temp) free(temp);           /* Free allocated memory */
        !           923:        if (ibuf) free(ibuf);
        !           924:        if (obuf) free(obuf);
        !           925: #endif /* DYNAMIC */
        !           926:        return(1);
        !           927: 
        !           928:     } else {                           /* Inferior reads, prints port input */
        !           929: 
        !           930: #ifndef OXOS
        !           931:        if (priv_can()) {               /* Cancel all privs */
        !           932:            printf("?setuid error - fatal\n");
        !           933:            doexit(BAD_EXIT,-1);
        !           934:        }
        !           935: #endif /* OXOS */
        !           936:        signal(SIGINT, SIG_IGN);        /* In case these haven't been */
        !           937:        signal(SIGQUIT, SIG_IGN);       /* inherited from above... */
        !           938: 
        !           939:        inshift = outshift = 0;         /* Initial SO/SI shift state. */
        !           940:        sleep(1);                       /* Wait for parent's handler setup.  */
        !           941:        ibp = ibuf;                     /* Initialize input buffering */
        !           942:        ibc = 0;                        /* And output buffering. */
        !           943:        obp = obuf;
        !           944:        obc = 0;
        !           945:        debug(F100,"CONNECT starting port fork","",0);
        !           946:        while (1) {                     /* Fresh read, wait for a character. */
        !           947: #ifdef SUNX25
        !           948:            if (network && (nettype == NET_SX25)) {
        !           949:                bzero(x25ibuf,sizeof(x25ibuf)) ;
        !           950:                if ((ibufl = ttxin(MAXIX25,x25ibuf)) < 0) {
        !           951:                    if (ibufl == -2) {  /* PAD parms changes */
        !           952:                        write(padpipe[1],padparms,MAXPADPARMS);
        !           953:                        kill(parent_id,SIGUSR2);
        !           954:                    } else {
        !           955:                        if (!quiet)
        !           956:                          printf("\r\nCommunications disconnect ");
        !           957:                        kill(parent_id,SIGUSR1);
        !           958:                    }
        !           959:                    pause();
        !           960:                }
        !           961:                if (debses) {           /* Debugging output */
        !           962:                    p = x25ibuf ;
        !           963:                         while (ibufl--) { c = *p++; conol(dbchr(c)); }
        !           964:                } else {
        !           965:                    if (sosi
        !           966: #ifndef NOCSETS
        !           967:                        || tcsl != tcsr
        !           968: #endif /* NOCSETS */
        !           969:                        ) { /* Character at a time */
        !           970:                        for (i = 1; i < ibufl; i++) {
        !           971:                            c = x25ibuf[i] & cmask;
        !           972:                            if (sosi) { /* Handle SI/SO */
        !           973:                                if (c == SO) {
        !           974:                                    inshift = 1;
        !           975:                                    continue;
        !           976:                                } else if (c == SI) {
        !           977:                                    inshift = 0;
        !           978:                                    continue;
        !           979:                                }
        !           980:                                if (inshift)
        !           981:                                  c |= 0200;
        !           982:                            }
        !           983: #ifndef NOCSETS
        !           984: #ifndef SKIPESC
        !           985:                    /* Translate character sets */
        !           986:                    if (sxo) c = (*sxo)(c); /* From local to intermediate. */
        !           987:                    if (rxo) c = (*rxo)(c); /* From intermediate to remote. */
        !           988: 
        !           989: #else /* Skipping escape sequences... */
        !           990: 
        !           991:                    if (inesc == ES_NORMAL) { /* If not inside escape seq.. */
        !           992:                        /* Translate character sets */
        !           993:                        if (sxo) c = (*sxo)(c); /* Local to intermediate. */
        !           994:                        if (rxo) c = (*rxo)(c); /* Intermediate to remote. */
        !           995:                    }
        !           996:                    if (skipesc) chkaes(c); /* Check escape sequence status */
        !           997: #endif /* SKIPESC */
        !           998: #endif /* NOCSETS */
        !           999:                            c &= cmdmsk; /* Apply command mask. */
        !          1000:                            conoc(c);    /* Output to screen */
        !          1001:                            logchar(c);  /* and session log */
        !          1002:                        }
        !          1003:                    } else {             /* All at once */
        !          1004:                        for (i = 1; i < ibufl; i++)
        !          1005:                          x25ibuf[i] &= (cmask & cmdmsk);
        !          1006:                        conxo(ibufl,x25ibuf);
        !          1007:                        if (seslog) zsoutx(ZSFILE,x25ibuf,ibufl);
        !          1008:                    }
        !          1009:                }
        !          1010:                continue;
        !          1011: 
        !          1012:            } else {                    /* Not X.25... */
        !          1013: #endif /* SUNX25 */
        !          1014: /*
        !          1015:   Get the next communication line character from our internal buffer.
        !          1016:   If the buffer is empty, refill it.
        !          1017: */
        !          1018:                c = ckcgetc(0);         /* Get next character */
        !          1019:                /* debug(F101,"CONNECT c","",c); */
        !          1020:                if (c < 0) {
        !          1021:                    if (!quiet) {       /* Failed... */
        !          1022:                        printf("\r\nCommunications disconnect ");
        !          1023:                        if ( c == -3
        !          1024: #ifdef UTEK
        !          1025: /* This happens on UTEK if there's no carrier */
        !          1026:                            && errno != EWOULDBLOCK
        !          1027: #endif /* UTEK */
        !          1028:                            )
        !          1029:                          perror("\r\nCan't read character");
        !          1030:                    }
        !          1031:                    tthang();           /* Hang up the connection */
        !          1032:                    kill(parent_id,SIGUSR1); /* Notify parent */
        !          1033:                    for (;;) pause();   /* and wait to be killed */
        !          1034:                }
        !          1035:                debug(F111,"** PORT",dbchr(c),c);
        !          1036: #ifdef TNCODE
        !          1037:                /* Handle TELNET negotiations here */   
        !          1038:                if (c == IAC && network && ttnproto == NP_TELNET) {
        !          1039:                    ckcputf();          /* Dump output buffer */
        !          1040:                    if ((tx = tn_doop((CHAR)(c & 0xff),duplex,ckcgetc)) == 0) {
        !          1041:                        continue;
        !          1042:                    } else if (tx == -1) { /* I/O error */
        !          1043:                        if (!quiet)
        !          1044:                          printf("\r\nCommunications disconnect ");
        !          1045:                        kill(parent_id,SIGUSR1); /* Notify parent. */
        !          1046:                        for (;;) pause(); /* Wait to be killed. */
        !          1047:                    } else if ((tx == 1) && (!duplex)) { /* ECHO change */
        !          1048:                        kill(parent_id,SIGUSR2); /* Tell the parent fork */
        !          1049:                        duplex = 1;
        !          1050:                    } else if ((tx == 2) && (duplex)) { /* ECHO change */
        !          1051:                        kill(parent_id,SIGUSR2); 
        !          1052:                        duplex = 0;
        !          1053:                    } else if (tx == 3) { /* Quoted IAC */
        !          1054:                        c = 255;
        !          1055:                    } else continue;    /* Negotiation OK, get next char. */
        !          1056:                }
        !          1057: #endif /* TNCODE */
        !          1058:                if (debses) {           /* Output character to screen */
        !          1059:                    char *s;            /* Debugging display... */
        !          1060:                    s = dbchr(c);
        !          1061:                    while (*s)
        !          1062:                      ckcputc(*s++);
        !          1063:                } else {                /* Regular display ... */
        !          1064:                    c &= cmask;         /* Apply Kermit-to-remote mask */
        !          1065:                    if (sosi) {         /* Handle SI/SO */
        !          1066:                        if (c == SO) {  /* Shift Out */
        !          1067:                            inshift = 1;
        !          1068:                            continue;
        !          1069:                        } else if (c == SI) { /* Shift In */
        !          1070:                            inshift = 0;
        !          1071:                            continue;
        !          1072:                        }
        !          1073:                        if (inshift) c |= 0200; 
        !          1074:                    }
        !          1075: #ifndef NOCSETS
        !          1076: #ifndef SKIPESC
        !          1077:                    /* Translate character sets */
        !          1078:                    if (sxi) c = (*sxi)((CHAR)c);
        !          1079:                    if (rxi) c = (*rxi)((CHAR)c);
        !          1080: #else
        !          1081:                    if (inesc == ES_NORMAL) {
        !          1082:                        /* Translate character sets */
        !          1083:                        if (sxi) c = (*sxi)((CHAR)c);
        !          1084:                        if (rxi) c = (*rxi)((CHAR)c);
        !          1085:                    }
        !          1086:                    /* Adjust escape sequence status */
        !          1087:                    if (skipesc) chkaes((char)c);
        !          1088: #endif /* SKIPESC */
        !          1089: #endif /* NOCSETS */
        !          1090:                    c &= cmdmsk;        /* Apply command mask. */
        !          1091:                    if (c == CR && tt_crd) { /* SET TERM CR-DISPLAY CRLF ? */
        !          1092:                        ckcputc(c);          /* Yes, output CR */
        !          1093:                        if (seslog) logchar((char)c);
        !          1094:                        c = LF;              /* and insert a linefeed */
        !          1095:                    }
        !          1096:                    ckcputc(c);         /* Output character to screen */
        !          1097:                    if (seslog) logchar((char)c); /* Do session log */
        !          1098:                }
        !          1099: #ifdef SUNX25
        !          1100:            }   
        !          1101: #endif /* SUNX25 */    
        !          1102:        }
        !          1103:     }
        !          1104: }
        !          1105: 
        !          1106: 
        !          1107: /*  H C O N N E  --  Give help message for connect.  */
        !          1108: 
        !          1109: int
        !          1110: hconne() {
        !          1111:     int c;
        !          1112:     static char *hlpmsg[] = {
        !          1113: "\r\n  ? for this message",
        !          1114: "\r\n  0 (zero) to send a null",
        !          1115: "\r\n  B to send a BREAK",
        !          1116: #ifdef CK_LBRK
        !          1117: "\r\n  L to send a Long BREAK",
        !          1118: #endif /* CK_LBRK */
        !          1119: #ifdef NETCONN
        !          1120: "\r\n  I to send a network interrupt packet",
        !          1121: #ifdef TCPSOCKET
        !          1122: "\r\n  A to send Are You There?",
        !          1123: #endif /* TCPSOCKET */
        !          1124: #ifdef SUNX25
        !          1125: "\r\n  R to reset X.25 virtual circuit",
        !          1126: #endif /* SUNX25 */
        !          1127: #endif /* NETCONN */
        !          1128: "\r\n  H to hangup and close the connection",
        !          1129: "\r\n  Q to hangup and quit Kermit",
        !          1130: "\r\n  S for status",
        !          1131: "\r\n  ! to push to local shell",
        !          1132: "\r\n  Z to suspend",
        !          1133: "\r\n  \\ backslash code:",
        !          1134: "\r\n    \\nnn  decimal character code",
        !          1135: "\r\n    \\Onnn octal character code",
        !          1136: "\r\n    \\Xhh  hexadecimal character code",
        !          1137: "\r\n    terminate with carriage return.",
        !          1138: "\r\n Type the escape character again to send the escape character, or",
        !          1139: "\r\n press the space-bar to resume the CONNECT command.\r\n\r\n",
        !          1140: "" };
        !          1141:     conol("\r\nPress C to return to ");
        !          1142:     conol(*myhost ? myhost : "the C-Kermit prompt");
        !          1143:     conol(", or:");
        !          1144:     conola(hlpmsg);                    /* Print the help message. */
        !          1145:     conol("Command>");                 /* Prompt for command. */
        !          1146:     c = congks(0) & 0177;              /* Get character, strip any parity. */
        !          1147:     /* No key mapping or translation here */
        !          1148:     if (c != CMDQ)
        !          1149:       conoll("");
        !          1150:     return(c);                         /* Return it. */
        !          1151: }
        !          1152: 
        !          1153: 
        !          1154: /*  D O E S C  --  Process an escape character argument  */
        !          1155: 
        !          1156: VOID
        !          1157: #ifdef CK_ANSIC
        !          1158: doesc(char c)
        !          1159: #else
        !          1160: doesc(c) char c;
        !          1161: #endif /* CK_ANSIC */
        !          1162: /* doesc */ {
        !          1163:     CHAR d;
        !          1164:   
        !          1165:     while (1) {
        !          1166:        if (c == escape) {              /* Send escape character */
        !          1167:            d = dopar((CHAR) c); ttoc((char) d); return;
        !          1168:        } else                          /* Or else look it up below. */
        !          1169:            if (isupper(c)) c = tolower(c);
        !          1170: 
        !          1171:        switch(c) {
        !          1172: 
        !          1173:        case 'c':                       /* Escape back to prompt */
        !          1174:        case '\03':
        !          1175:            active = 0; conol("\r\n"); return;
        !          1176: 
        !          1177:        case 'b':                       /* Send a BREAK signal */
        !          1178:        case '\02':
        !          1179:            ttsndb(); return;
        !          1180: 
        !          1181: #ifdef NETCONN
        !          1182:        case 'i':                       /* Send Interrupt */
        !          1183:        case '\011':
        !          1184: #ifdef TCPSOCKET
        !          1185: #ifndef IP
        !          1186: #define IP 244
        !          1187: #endif /* IP */
        !          1188:            if (network && ttnproto == NP_TELNET) { /* TELNET */
        !          1189:                temp[0] = IAC;          /* I Am a Command */
        !          1190:                temp[1] = IP;           /* Interrupt Process */
        !          1191:                temp[2] = NUL;
        !          1192:                ttol((CHAR *)temp,2);
        !          1193:            } else 
        !          1194: #endif /* TCPSOCKET */
        !          1195: #ifdef SUNX25
        !          1196:             if (network && (nettype == NET_SX25)) { /* X.25 */
        !          1197:                (VOID) x25intr(0);                  /* X.25 interrupt packet */
        !          1198:                conol("\r\n");
        !          1199:            } else
        !          1200: #endif /* SUNX25 */
        !          1201:              conoc(BEL);
        !          1202:            return;
        !          1203: 
        !          1204: #ifdef TCPSOCKET
        !          1205:        case 'a':                       /* "Are You There?" */
        !          1206:        case '\01':
        !          1207: #ifndef AYT
        !          1208: #define AYT 246
        !          1209: #endif /* AYT */
        !          1210:            if (network && ttnproto == NP_TELNET) {
        !          1211:                temp[0] = IAC;          /* I Am a Command */
        !          1212:                temp[1] = AYT;          /* Are You There? */
        !          1213:                temp[2] = NUL;
        !          1214:                ttol((CHAR *)temp,2);
        !          1215:            } else conoc(BEL);
        !          1216:            return;
        !          1217: #endif /* TCPSOCKET */
        !          1218: #endif /* NETCONN */
        !          1219: 
        !          1220: #ifdef CK_LBRK
        !          1221:        case 'l':                       /* Send a Long BREAK signal */
        !          1222:            ttsndlb(); return;
        !          1223: #endif /* CK_LBRK */
        !          1224: 
        !          1225:        case 'h':                       /* Hangup */
        !          1226:        case '\010':
        !          1227: #ifdef SUNX25
        !          1228:             if (network && (nettype == NET_SX25)) dox25clr = 1;
        !          1229:             else
        !          1230: #endif /* SUNX25 */
        !          1231:            dohangup = 2; active = 0; conol("\r\nHanging up "); return;
        !          1232: 
        !          1233: #ifdef SUNX25
        !          1234:         case 'r':                       /* Reset the X.25 virtual circuit */
        !          1235:         case '\022':
        !          1236:             if (network && (nettype == NET_SX25)) (VOID) x25reset();
        !          1237:             conol("\r\n"); return;
        !          1238: #endif /* SUNX25 */
        !          1239:  
        !          1240:        case 'q':                       /* Quit */
        !          1241:            quitnow = 1; active = 0; conol("\r\n"); return;
        !          1242: 
        !          1243:        case 's':                       /* Status */
        !          1244:            sprintf(temp,
        !          1245:                    "\r\nConnected %s %s", network ? "to" : "through", ttname);
        !          1246:            conol(temp);
        !          1247: #ifdef SUNX25
        !          1248:             if (network && (nettype == NET_SX25)) {
        !          1249:                 sprintf(temp,", Link ID %d, LCN %d",linkid,lcn); conol(temp);
        !          1250:            }
        !          1251: #endif /* SUNX25 */
        !          1252:            if (speed >= 0L) {
        !          1253:                sprintf(temp,", speed %ld", speed);
        !          1254:                conoll(temp);
        !          1255:            } else conoll("");
        !          1256:            sprintf(temp,
        !          1257:                    "Terminal bytesize: %d, Command bytesize: %d, Parity: ",
        !          1258:                    (cmask  == 0177) ? 7 : 8,
        !          1259:                    (cmdmsk == 0177) ? 7 : 8 );
        !          1260:            conol(temp);
        !          1261: 
        !          1262:            switch (parity) {
        !          1263:              case  0:  conoll("none");  break;
        !          1264:              case 'e': conoll("even");  break;
        !          1265:              case 'o': conoll("odd");   break;
        !          1266:              case 's': conoll("space"); break;
        !          1267:              case 'm': conoll("mark");  break;
        !          1268:            }
        !          1269:            sprintf(temp,"Terminal echo: %s", duplex ? "local" : "remote");
        !          1270:            conoll(temp);
        !          1271:            if (seslog) {
        !          1272:                conol("Logging to: "); conoll(sesfil);
        !          1273:             }
        !          1274:            if (!network) shomdm();
        !          1275:            return;
        !          1276: 
        !          1277:        case '?':                       /* Help */
        !          1278:            c = hconne(); continue;
        !          1279: 
        !          1280:        case '0':                       /* Send a null */
        !          1281:            c = '\0'; d = dopar((CHAR) c); ttoc((char) d); return;
        !          1282: 
        !          1283: #ifndef NOPUSH
        !          1284:        case 'z': case '\032':          /* Suspend */
        !          1285:            stptrap(0); return;
        !          1286: 
        !          1287:        case '@':                       /* Start inferior command processor */
        !          1288:        case '!':
        !          1289:            conres();                   /* Put console back to normal */
        !          1290:            zshcmd("");                 /* Fork a shell. */
        !          1291:            if (conbin((char)escape) < 0) {
        !          1292:                printf("Error resuming CONNECT session\n");
        !          1293:                active = 0;
        !          1294:            }
        !          1295:            return;
        !          1296: #endif /* NOPUSH */
        !          1297: 
        !          1298:        case SP:                        /* Space, ignore */
        !          1299:            return;
        !          1300: 
        !          1301:        default:                        /* Other */
        !          1302:            if (c == CMDQ) {            /* Backslash escape */
        !          1303:                int x;
        !          1304:                kbp = kbuf;
        !          1305:                *kbp++ = c;
        !          1306:                while (((c = (congks(0) & cmdmsk)) != '\r') && (c != '\n'))
        !          1307:                  *kbp++ = c;
        !          1308:                *kbp = NUL; kbp = kbuf;
        !          1309:                x = xxesc(&kbp);        /* Interpret it */
        !          1310:                if (x >= 0) {           /* No key mapping here */
        !          1311:                    c = dopar((CHAR) x);
        !          1312:                    ttoc((char) c);
        !          1313:                    return;
        !          1314:                } else {                /* Invalid backslash code. */
        !          1315:                    conoc(BEL);
        !          1316:                    return;
        !          1317:                }
        !          1318:            }
        !          1319:            conoc(BEL); return;         /* Invalid esc arg, beep */
        !          1320:        }
        !          1321:     }
        !          1322: }
        !          1323: 
        !          1324: VOID
        !          1325: #ifdef CK_ANSIC
        !          1326: logchar(char c)
        !          1327: #else
        !          1328: logchar(c) char c;
        !          1329: #endif /* CK_ANSIC */
        !          1330: /* logchar */ {                        /* Log character c to session log */
        !          1331:     if (seslog) 
        !          1332:       if ((sessft != 0) ||
        !          1333:          (c != '\r' &&
        !          1334:           c != '\0' &&
        !          1335:           c != XON &&
        !          1336:           c != XOFF))
        !          1337:        if (zchout(ZSFILE,c) < 0) {
        !          1338:            conoll("");
        !          1339:            conoll("ERROR WRITING SESSION LOG, LOG CLOSED!");
        !          1340:            seslog = 0;
        !          1341:        }
        !          1342: }

unix.superglobalmegacorp.com

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