Annotation of 43BSDReno/contrib/isode-beta/vt/vt.c, revision 1.1.1.1

1.1       root        1: /* vt.c - VT initiator */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/vt/RCS/vt.c,v 7.2 90/01/11 18:38:13 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/vt/RCS/vt.c,v 7.2 90/01/11 18:38:13 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       vt.c,v $
                     12:  * Revision 7.2  90/01/11  18:38:13  mrose
                     13:  * real-sync
                     14:  * 
                     15:  * Revision 7.1  89/11/30  23:51:38  mrose
                     16:  * pa2str
                     17:  * 
                     18:  * Revision 7.0  89/11/23  22:31:49  mrose
                     19:  * Release 6.0
                     20:  * 
                     21:  */
                     22: 
                     23: /*
                     24:  *                               NOTICE
                     25:  *
                     26:  *    Acquisition, use, and distribution of this module and related
                     27:  *    materials are subject to the restrictions of a license agreement.
                     28:  *    Consult the Preface in the User's Manual for the full terms of
                     29:  *    this agreement.
                     30:  *
                     31:  */
                     32: 
                     33: 
                     34: #include <signal.h>
                     35: #include "vtpm.h"
                     36: #include "sector1.h"
                     37: #include "tailor.h"
                     38: 
                     39: #include <sys/ioctl.h>
                     40: #ifdef BSD44
                     41: #include <sys/termios.h>
                     42: #endif
                     43: #include <ctype.h>
                     44: #include <setjmp.h>
                     45: #include <varargs.h>
                     46: 
                     47: #define        strip(x)        ((x)&0177)
                     48: #define TBUFSIZ                1024
                     49: 
                     50: char   ttyobuf[TBUFSIZ], *tfrontp = ttyobuf, *tbackp = ttyobuf;
                     51: char   netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
                     52: 
                     53: int    connected;
                     54: int    net;
                     55: int    showoptions = 0;
                     56: int    options;
                     57: int    debug = 0;
                     58: int    crmod = 0;
                     59: char   escape = ']' & 037;
                     60: static char *escapestr = "^]";
                     61: 
                     62: VT_PROFILE vtp_profile;
                     63: int rflag = 0;
                     64: char erase_char;       /*Unix Erase*/
                     65: char erase_line;       /*Unix Kill*/
                     66: char intr_char;                /*Unix Interrupt*/
                     67: char *my_displayobj = "K";     /*Initiator's Display Object Name*/
                     68: char *my_echo_obj = "NI";      /*Initiator's Negotiation Control Object*/
                     69: char *my_signal_obj = "KB";    /*Initiator's Signal Control Object*/
                     70: char *his_echo_obj = "NA";     /*Acceptor's Negotiation Control Object*/
                     71: char *his_signal_obj = "DI";   /*Acceptor's Signal Control Object*/
                     72: int my_right = INITIATOR;
                     73: char kb_image;                 /*KB Control Object Image*/
                     74: char di_image;                 /*DI Control Image*/
                     75: char ni_image;                 /*NI Control Object Image*/
                     76: char na_image;                 /*NA Control Object Image*/
                     77: char nego_state;               /*Current state of NI affected options*/
                     78: char sync_image;               /*SY Control Object*/
                     79: char ga_image;
                     80: int transparent = 0;           /*Transparent Repertoire switch*/
                     81: int telnet_profile = 1;
                     82: int do_break = 1;              /*If VT-BREAK Functional Unit agreed to*/
                     83: char *myhostname;
                     84: char peerhost[BUFSIZ];
                     85: struct PSAPaddr ts_bound;
                     86: int pty;                       /*Kludge for single map.c (sorry)*/
                     87: 
                     88: char   line[BUFSIZ];
                     89: 
                     90: jmp_buf        toplevel;
                     91: jmp_buf        peerdied;
                     92: 
                     93: extern int errno;
                     94: 
                     95: 
                     96: struct dispatch {
                     97:     char   *ds_name;
                     98:     IFP            ds_fnx;
                     99: 
                    100:     int            ds_flags;
                    101: #define        DS_NULL         0x00
                    102: #define        DS_OPEN         0x01    /* association required */
                    103: #define        DS_CLOSE        0x02    /* association avoided */
                    104: 
                    105:     char   *ds_help;
                    106: };
                    107: 
                    108: struct dispatch *getds ();
                    109: 
                    110: 
                    111: int    vt_open (), vt_close (), vt_quit (), vt_status (), vt_suspend ();
                    112: int    vt_ayt (), vt_break (), vt_escape ();
                    113: int    vt_set (), vt_help ();
                    114: 
                    115: 
                    116: static struct dispatch dispatches[] = {
                    117:     "ayt", vt_ayt, DS_OPEN,
                    118:     "send \"are you there?\"",
                    119: 
                    120:     "break", vt_break, DS_OPEN,
                    121:     "send break",
                    122: 
                    123:     "close", vt_close, DS_OPEN,
                    124:     "release association with terminal service",
                    125: 
                    126:     "escape", vt_escape, DS_NULL,
                    127:     "set escape character (depreciated)",
                    128: 
                    129:     "help", vt_help, DS_NULL,
                    130:     "print help information",
                    131: 
                    132:     "open", vt_open, DS_CLOSE,
                    133:     "associate with terminal service",
                    134: 
                    135:     "quit", vt_quit, DS_NULL,
                    136:     "release association with terminal service and exit",
                    137: 
                    138:     "set", vt_set, DS_NULL,
                    139:     "display or change variables",
                    140: 
                    141:     "status", vt_status, DS_OPEN,
                    142:     "show current status",
                    143: 
                    144:     "suspend", vt_suspend, DS_OPEN,
                    145:     "suspend vtp",
                    146: 
                    147:     NULL
                    148: };
                    149: 
                    150: 
                    151: SFD    intr(), deadpeer();
                    152: char   *control(), *strdup ();
                    153: 
                    154: #ifdef BSD44
                    155: struct termios oterm;
                    156: #else
                    157: struct tchars otc;
                    158: struct ltchars oltc;
                    159: struct sgttyb ottyb;
                    160: #endif
                    161: 
                    162: static int runcom = 0;
                    163: char   *myname;
                    164: static char *myhome;
                    165: int    tmode();
                    166: 
                    167: LLog    _vt_log = {
                    168:     "./vt.log", NULLCP, NULLCP,
                    169:     LLOG_NONE, LLOG_NONE, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK 
                    170: };
                    171: LLog   *vt_log = &_vt_log;
                    172: 
                    173: main(argc, argv)
                    174:        int argc;
                    175:        char *argv[];
                    176: {
                    177:        int     i,
                    178:                fflag;
                    179:        char   *logname,
                    180:                buffer[BUFSIZ],
                    181:               *vec[NVEC + 1];
                    182:        FILE   *fp;
                    183: 
                    184:     if (myname = rindex (*argv, '/'))
                    185:        myname++;
                    186:     if (myname == NULL || *myname == NULL)
                    187:        myname = *argv;
                    188: 
                    189:     isodetailor (myname, 1);
                    190: 
                    191:     ll_hdinit (vt_log, myname);
                    192: 
                    193:        fflag = 0;
                    194:        logname = 0;
                    195:        myhostname = PLocalHostName ();
                    196:        peerhost[0] = NULL;
                    197:        acc = &accs;
                    198:        acr = &acrs;
                    199:        aci = &acis;
                    200: 
                    201: #ifdef BSD44
                    202:        if (tcgetattr(0, &oterm) == -1)
                    203:                perror("tcgetattr");
                    204:        erase_char = oterm.c_cc[VERASE];
                    205:        erase_line = oterm.c_cc[VKILL];
                    206:        intr_char = oterm.c_cc[VINTR];
                    207: #else
                    208:        if (ioctl(0, TIOCGETP, (char *)&ottyb) == -1) {
                    209:                perror("ioctl");
                    210:                adios(NULLCP, "ioctl failed");
                    211:        }
                    212:        if (ioctl(0, TIOCGETC, (char *)&otc) == -1) {
                    213:                perror("ioctl");
                    214:                adios(NULLCP, "ioctl failed");
                    215:        }
                    216:        if (ioctl(0, TIOCGLTC, (char *)&oltc) == -1) {
                    217:                perror("ioctl");
                    218:                adios(NULLCP, "ioctl failed");
                    219:        }
                    220:        erase_char = ottyb.sg_erase;
                    221:        erase_line = ottyb.sg_kill;
                    222:        intr_char = otc.t_intrc;
                    223: #endif
                    224: 
                    225: 
                    226:        setbuf(stdin, NULLCP);
                    227:        setbuf(stdout, NULLCP);
                    228: 
                    229:        bzero ((char *) &vtp_profile, sizeof vtp_profile);
                    230:        vtp_profile.profile_name = "telnet";
                    231:        vtp_profile.arg_val.tel_arg_list.x_window = ncols (stdin);
                    232:        vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
                    233: 
                    234:        for(i=1; i<argc; i++)
                    235:        {
                    236:                if (peerhost[0] == NULL && (*argv[i] != '-'))
                    237:                {
                    238:                        (void) strcpy(peerhost,argv[i]);
                    239:                }
                    240:                else if(!strcmp(argv[i], "-g"))
                    241:                {
                    242:                        vtp_profile.arg_val.tel_arg_list.full_ascii = 0;
                    243:                        advise(LLOG_DEBUG,NULLCP,"using ASCII GO repertoire");
                    244:                }
                    245:                else if(!strcmp(argv[i], "-D"))
                    246:                {
                    247:                        vtp_profile.profile_name = "default";
                    248:                        telnet_profile = 0;
                    249:                        my_displayobj = "DISPLAY-OBJECT-2";
                    250:                        advise(LLOG_DEBUG,NULLCP,"using default profile");
                    251:                }
                    252:                else if(!strcmp(argv[i],"-B"))
                    253:                {
                    254:                        advise(LLOG_DEBUG,NULLCP,"VT-BREAK not chosen");
                    255:                        do_break = 0;
                    256:                }
                    257:                else if(!strcmp(argv[i], "-f"))
                    258:                    fflag++;
                    259:                else if(!strcmp(argv[i], "-F"))
                    260:                {
                    261:                        if ((logname = argv[++i]) == NULL || *logname == '-')
                    262:                            adios (NULLCP, "usage: %s -F logfile", myname);
                    263:                        vt_log -> ll_file = logname;
                    264:                        (void) ll_close (vt_log);
                    265:                        advise(LLOG_DEBUG,NULLCP, "logging to %s",logname);
                    266:                }
                    267:                else
                    268:                    adios("usage: %s [-g] [-D] [-B] [-f] [-F logfile] [hostname]",
                    269:                          myname);
                    270:        }
                    271: 
                    272: 
                    273:     runcom = 1;
                    274: 
                    275:     rcinit ();
                    276:     (void) sprintf (buffer, "%s/.vtrc", myhome);
                    277:     if (!fflag && (fp = fopen (buffer, "r"))) {
                    278:        register char   *bp;
                    279:        
                    280:        while (fgets (buffer, sizeof buffer, fp)) {
                    281:            if (bp = index (buffer, '\n'))
                    282:                *bp = NULL;
                    283: 
                    284:            bzero ((char *) vec, sizeof vec);
                    285:            if (str2vec (buffer, vec) < 1)
                    286:                continue;
                    287: 
                    288:            if (vtploop (vec, NOTOK) == NOTOK && peerhost[0])
                    289:                exit (1);
                    290:        }
                    291: 
                    292:        (void) fclose (fp);
                    293:     }
                    294: 
                    295:     runcom = 0;
                    296: 
                    297:        if (peerhost[0] != NULL) {
                    298:                if (setjmp(toplevel) != 0)
                    299:                        exit(0);
                    300:                do_vt();
                    301:        }
                    302:        (void) setjmp(toplevel);
                    303:        for (;;)
                    304:                command(1);
                    305: }
                    306: 
                    307: /*    DISPATCH */
                    308: 
                    309: command(top)
                    310:        int top;
                    311: {
                    312:        int eof,oldmode;
                    313:        char *vec[NVEC + 1];
                    314: 
                    315:        oldmode = tmode(0);
                    316:        if (!top)
                    317:                (void) putchar('\n');
                    318:        else
                    319:            (void) signal (SIGINT, SIG_DFL);
                    320:        eof = 0;
                    321:        for (;;) {
                    322:                if (getline ("%s> ", line) == NOTOK) {
                    323:                    if (eof) {
                    324:                        if (!connected)
                    325:                            exit (0);
                    326:                        (void) vt_status (NULLVP);
                    327:                        break;
                    328:                    }
                    329: 
                    330:                    eof = 1;
                    331:                    continue;
                    332:                }
                    333:                eof = 0;
                    334: 
                    335:                bzero ((char *) vec, sizeof vec);
                    336:                if (str2vec (line, vec) < 1)
                    337:                    break;
                    338: 
                    339:                if (vtploop (vec, NOTOK) != DONE)
                    340:                    break;
                    341:        }
                    342:        if (!top) {
                    343:                if (!connected)
                    344:                        longjmp(toplevel, 1);
                    345:                (void) fflush (stdout);
                    346:                (void) fflush (stderr);
                    347:                (void) tmode(oldmode);
                    348:        }
                    349: }
                    350: 
                    351: /*  */
                    352: 
                    353: static int vtploop (vec, error)
                    354: char  **vec;
                    355: int    error;
                    356: {
                    357:     register struct dispatch *ds;
                    358: 
                    359:     if ((ds = getds (strcmp (*vec, "?") ? *vec : "help")) == NULL)
                    360:        return error;
                    361: 
                    362:     if (!connected) {
                    363:        if (ds -> ds_flags & DS_OPEN) {
                    364:            advise (LLOG_NOTICE,NULLCP,  "not associated with terminal service");
                    365:            return error;
                    366:            }
                    367:     }
                    368:     else
                    369:        if (ds -> ds_flags & DS_CLOSE) {
                    370:            advise (LLOG_NOTICE,NULLCP, 
                    371:                    "already associated with terminal service");
                    372:            return error;
                    373:        }
                    374: 
                    375:     switch ((*ds -> ds_fnx) (vec)) {
                    376:        case NOTOK:
                    377:            return error;
                    378: 
                    379:        case OK:
                    380:        default:
                    381:            return OK;
                    382: 
                    383:        case DONE:
                    384:            return DONE;
                    385:        }
                    386: }
                    387: 
                    388: /*  */
                    389: 
                    390: int    getline (prompt, buffer)
                    391: char   *prompt,
                    392:        *buffer;
                    393: {
                    394:     register int    i;
                    395:     register char  *cp,
                    396:                    *ep;
                    397:     static int  sticky = 0;
                    398: 
                    399:     if (sticky) {
                    400:        sticky = 0;
                    401:        return NOTOK;
                    402:     }
                    403: 
                    404:     (void)printf (prompt, connected ? peerhost : myname);
                    405:     (void) fflush (stdout);
                    406: 
                    407:     for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) {
                    408:        if (i == EOF) {
                    409:            (void)printf ("\n");
                    410:            clearerr (stdin);
                    411:            if (cp == buffer)
                    412:                return NOTOK;
                    413: 
                    414:            sticky++;
                    415:            break;
                    416:        }
                    417: 
                    418:        if (cp < ep)
                    419:            *cp++ = i;
                    420:     }
                    421:     *cp = NULL;
                    422:     
                    423:     return OK;
                    424: }
                    425: 
                    426: /*  */
                    427: 
                    428: struct dispatch *getds (name)
                    429: register char *name;
                    430: {
                    431:     register int    longest,
                    432:                     nmatches;
                    433:     register char  *p,
                    434:                    *q;
                    435:     char    buffer[BUFSIZ];
                    436:     register struct dispatch   *ds,
                    437:                                *fs;
                    438: 
                    439:     longest = nmatches = 0;
                    440:     for (ds = dispatches; p = ds -> ds_name; ds++) {
                    441:        for (q = name; *q == *p++; q++)
                    442:            if (*q == NULL)
                    443:                return ds;
                    444:        if (*q == NULL)
                    445:            if (q - name > longest) {
                    446:                longest = q - name;
                    447:                nmatches = 1;
                    448:                fs = ds;
                    449:            }
                    450:            else
                    451:                if (q - name == longest)
                    452:                    nmatches++;
                    453:     }
                    454: 
                    455:     switch (nmatches) {
                    456:        case 0: 
                    457:            advise (LLOG_NOTICE,NULLCP,  "unknown operation \"%s\"", name);
                    458:            return NULL;
                    459: 
                    460:        case 1: 
                    461:            return fs;
                    462: 
                    463:        default: 
                    464:            for (ds = dispatches, p = buffer; q = ds -> ds_name; ds++)
                    465:                if (strncmp (q, name, longest) == 0) {
                    466:                    (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
                    467:                    p += strlen (p);
                    468:                }
                    469:            advise (LLOG_NOTICE,NULLCP, 
                    470:                    "ambiguous operation, it could be one of:%s",
                    471:                        buffer);
                    472:            return NULL;
                    473:     }
                    474: }
                    475: 
                    476: /*    OPERATIONS */
                    477: 
                    478: static int  vt_open (vec)
                    479: char  **vec;
                    480: {
                    481:     if (*++vec == NULL) {
                    482:        if (getline ("host: ", line) == NOTOK || str2vec (line, vec) < 1)
                    483:            return NOTOK;
                    484:     }
                    485: 
                    486:     (void) strcpy (peerhost, *vec);
                    487:     do_vt ();
                    488: 
                    489:     return OK;
                    490: }
                    491: 
                    492: 
                    493: do_vt()
                    494: {
                    495:        (void) signal(SIGINT, intr);
                    496:        (void) signal(SIGPIPE, deadpeer);
                    497:        (void)printf("Trying...\n");
                    498:        (void)fflush(stdout);
                    499: 
                    500:        if ((fd = con_req()) < 0)
                    501:            return;
                    502: 
                    503:        connected++;
                    504:        (void) vt_status (NULLVP);
                    505:        (void)printf ("escape character is '%s'\n", escapestr);
                    506:        if (setjmp(peerdied) == 0)
                    507:                vt(fd);
                    508:        adios (NULLCP, "association terminated by peer");
                    509: }
                    510: 
                    511: /*  */
                    512: 
                    513: /* ARGSUSED */
                    514: 
                    515: static int  vt_close (vec)
                    516: char  **vec;
                    517: {
                    518:     (void) tmode(0);
                    519:     vrelreq();
                    520:     if (getch () >= -1) {
                    521:        advise (LLOG_DEBUG,NULLCP,  "flushing input queue...");
                    522:        while (getch () >= -1)
                    523:            continue;
                    524:     }
                    525: 
                    526:     /* read network events until the release sequence reached
                    527:        the point where the other side shuts down
                    528:      */
                    529: 
                    530:     (void)printf ("association released\n");
                    531:     (void)fflush (stdout);
                    532:     connected = 0;
                    533:     /* reset his options */
                    534: 
                    535:     return OK;
                    536: }
                    537: 
                    538: /*  */
                    539: 
                    540: /* ARGSUSED */
                    541: 
                    542: static int  vt_quit (vec)
                    543: char  *vec;
                    544: {
                    545:     if (connected)
                    546:        (void) vt_close (NULLVP);
                    547: 
                    548:     exit(0);   /* NOTREACHED */
                    549: }
                    550: 
                    551: /*  */
                    552: 
                    553: /* ARGSUSED */
                    554: 
                    555: static int  vt_status (vec)
                    556: char  **vec;
                    557: {
                    558:     (void) printf ("associated with terminal service on \"%s\"\n  at %s\n",
                    559:                   peerhost, pa2str (&ts_bound));
                    560:     (void) printf ("  using %s profile\n", vtp_profile.profile_name);
                    561: 
                    562:     return OK;
                    563: }
                    564: 
                    565: /*  */
                    566: 
                    567: /* ARGSUSED */
                    568: 
                    569: static int  vt_suspend (vec)
                    570: char  **vec;
                    571: {
                    572:        register int save;
                    573: 
                    574:        save = tmode(0);
                    575:        (void)kill(0, SIGTSTP);
                    576: 
                    577:        /* reget parameters in case they were changed */
                    578: #ifdef BSD44
                    579:        if (tcgetattr(0, &oterm) == -1)
                    580:                perror("tcgetattr");
                    581: #else
                    582:        if (ioctl(0, TIOCGETP, (char *)&ottyb) == -1) {
                    583:                perror("ioctl"); 
                    584:                adios(NULLCP, "ioctl failed");
                    585:        }
                    586:        if (ioctl(0, TIOCGETC, (char *)&otc) == -1) {
                    587:                perror("ioctl"); 
                    588:                adios(NULLCP, "ioctl failed"); 
                    589:        } 
                    590:        if (ioctl(0, TIOCGLTC, (char *)&oltc) == -1) { 
                    591:                perror("ioctl"); 
                    592:                adios(NULLCP, "ioctl failed");
                    593:        }
                    594: #endif
                    595:        (void) tmode(save);
                    596: 
                    597:        return OK;
                    598: }
                    599: 
                    600: /*  */
                    601: 
                    602: static int  vt_escape (vec)
                    603: char  **vec;
                    604: {
                    605:     char   c;
                    606: 
                    607:     if (*++vec == NULL) {
                    608:        if (getline ("new escape character: ", line) == NOTOK
                    609:                || str2vec (line, vec) < 1)
                    610:            return NOTOK;
                    611:     }
                    612: 
                    613:     if ((c = *vec[0]) != NULL) {
                    614:        char   *cp = control (escape = c);
                    615: 
                    616:        free (escapestr);
                    617:        escapestr = strdup (cp);
                    618:     }
                    619:     (void)printf ("escape character is '%s'\n", escapestr);
                    620: 
                    621:     return OK;
                    622: }
                    623: 
                    624: /*    VARIABLES */
                    625: 
                    626: static char *debug_val[] = {
                    627:        "0", "1", "2", "3", "4", "5", "6", "7", NULL
                    628: };
                    629: 
                    630: static char *bool[] = {
                    631:     "off", "on", NULL
                    632: };
                    633: 
                    634: static char *emodes[] = {
                    635:     "local", "remote", NULL
                    636: };
                    637: 
                    638: static char *rmodes[] = {
                    639:     "ascii", "transparent", NULL
                    640: };
                    641: 
                    642: static char *xsaplevels[] = {
                    643:     "none", "fatal", "exceptions", "notice", "pdus", "trace", "debug", NULL
                    644: };
                    645: 
                    646: 
                    647: struct var {
                    648:     char   *v_name;
                    649:     IP     v_value;
                    650: 
                    651:     char   *v_dname;
                    652:     char  **v_dvalue;
                    653:     char   *v_mask;
                    654: 
                    655:     IFP            v_hook;
                    656: };
                    657: 
                    658: struct var *getvar ();
                    659: 
                    660: 
                    661: static int   echo = 0;
                    662: static int   repertoire = 0;
                    663: static int   verbose = 0;
                    664: 
                    665: int    set_debug (), set_echo (), set_escape (), set_repertoire ();
                    666: 
                    667: 
                    668: static struct var vars[] = {
                    669:     "acsaplevel", &_acsap_log.ll_events, "ACSAP logging", xsaplevels,
                    670:        LLOG_MASK, NULLIFP,
                    671:     "acsapfile", NULLIP, "ACSAP trace file", &_acsap_log.ll_file, NULLCP,
                    672:        NULLIFP,
                    673: 
                    674:     "addrlevel", &_addr_log.ll_events, "address logging", xsaplevels,
                    675:        LLOG_MASK, NULLIFP,
                    676:     "addrfile", NULLIP, "address trace file", &_addr_log.ll_file, NULLCP,
                    677:        NULLIFP,
                    678: 
                    679:     "compatlevel", &_compat_log.ll_events, "COMPAT logging", xsaplevels,
                    680:        LLOG_MASK, NULLIFP,
                    681:     "compatfile", NULLIP, "COMPAT trace file", &_compat_log.ll_file, NULLCP,
                    682:        NULLIFP,
                    683: 
                    684:     "crmod", &crmod, "map CR on output", bool, NULLCP, NULLIFP,
                    685: 
                    686:     "debug", &debug, "debug VT", debug_val, NULLCP, set_debug,
                    687: 
                    688:     "echo", &echo, "local or remote echoing", emodes, NULLCP, set_echo,
                    689: 
                    690:     "escape", NULLIP, "escape character", &escapestr, NULLCP, set_escape,
                    691: 
                    692:     "options", &showoptions, "show option processing", bool, NULLCP, NULLIFP,
                    693: 
                    694:     "psaplevel", &_psap_log.ll_events, "PSAP logging", xsaplevels,
                    695:        LLOG_MASK, NULLIFP,
                    696:     "psapfile", NULLIP, "PSAP trace file", &_psap_log.ll_file, NULLCP,
                    697:        NULLIFP,
                    698: 
                    699:     "psap2level", &_psap2_log.ll_events, "PSAP2 logging", xsaplevels,
                    700:        LLOG_MASK, NULLIFP,
                    701:     "psap2file", NULLIP, "PSAP2 trace file", &_psap2_log.ll_file, NULLCP,
                    702:        NULLIFP,
                    703: 
                    704:     "repertoire", &repertoire, "terminal repertoire", rmodes, NULLCP,
                    705:        set_repertoire,
                    706: 
                    707:     "ssaplevel", &_ssap_log.ll_events, "SSAP logging", xsaplevels,
                    708:        LLOG_MASK, NULLIFP,
                    709:     "ssapfile", NULLIP, "SSAP trace file", &_ssap_log.ll_file, NULLCP,
                    710:        NULLIFP,
                    711: 
                    712:     "tracelevel", &_vt_log.ll_events, "VT logging", xsaplevels,
                    713:        LLOG_MASK, NULLIFP,
                    714:     "tracefile", NULLIP, "VT trace file", &_vt_log.ll_file, NULLCP,
                    715:        NULLIFP,
                    716: 
                    717:     "tsaplevel", &_tsap_log.ll_events, "TSAP logging", xsaplevels,
                    718:        LLOG_MASK, NULLIFP,
                    719:     "tsapfile", NULLIP, "TSAP trace file", &_tsap_log.ll_file, NULLCP,
                    720:        NULLIFP,
                    721: 
                    722:     "verbose", &verbose, "verbose interaction", bool, NULLCP, NULLIFP,
                    723: 
                    724:     NULL
                    725: };
                    726: 
                    727: 
                    728: static int varwidth1;
                    729: static int varwidth2;
                    730: 
                    731: char    **getval ();
                    732: 
                    733: /*  */
                    734: 
                    735: static int  vt_set (vec)
                    736: char  **vec;
                    737: {
                    738:     register int    i,
                    739:                    j;
                    740:     int     value,
                    741:            vflag;
                    742:     register char **cp,
                    743:                   *dp;
                    744:     register struct var *v;
                    745: 
                    746:     if (*++vec == NULL) {
                    747:        register int    w;
                    748:        int     columns,
                    749:                width,
                    750:                lines;
                    751:        register struct var *u;
                    752: 
                    753:        for (u = vars; u -> v_name; u++)
                    754:            continue;
                    755:        width = varwidth1;
                    756: 
                    757:        if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)
                    758:            columns = 1;
                    759:        lines = ((u - vars) + columns - 1) / columns;
                    760: 
                    761:        (void)printf ("Variables:\n");
                    762:        for (i = 0; i < lines; i++)
                    763:            for (j = 0; j < columns; j++) {
                    764:                v = vars + j * lines + i;
                    765:                (void)printf ("%s", v -> v_name);
                    766:                if (v + lines >= u) {
                    767:                    (void)printf ("\n");
                    768:                    break;
                    769:                }
                    770:                for (w = strlen (v -> v_name); w < width; w = (w + 8) & ~7)
                    771:                    (void) putchar ('\t');
                    772:            }
                    773: 
                    774:        return DONE;
                    775:     }
                    776: 
                    777:     echo = (nego_state & ECHO_OBJ) ? 1 : 0;
                    778:     repertoire = transparent ? 1 : 0;
                    779: 
                    780:     if (strcmp (*vec, "?") == 0) {
                    781:        for (v = vars; v -> v_name; v++)
                    782:            printvar (v);
                    783: 
                    784:        return DONE;
                    785:     }
                    786: 
                    787:     if ((v = getvar (*vec)) == NULL)
                    788:        return DONE;
                    789: 
                    790:     if (*++vec == NULL) {
                    791:        printvar (v);
                    792: 
                    793:        return DONE;
                    794:     }
                    795: 
                    796:     if (strcmp (*vec, "?") == 0) {
                    797:        if (v -> v_value && (cp = v -> v_dvalue)) {
                    798:            printf ("use %s of:", v -> v_mask ? "any" : "one");
                    799:            for (i = 0; *cp; cp++)
                    800:                printf ("%s \"%s\"", i++ ? "," : "", *cp);
                    801:            if (v -> v_mask)
                    802:                printf (";\n\tor  \"all\";\n\tor a hexadecimal number from 0 to 0x%x\n",
                    803:                    (1 << (i - 1)) - 1);
                    804:            else
                    805:                printf (";\n\tor a number from 0 to %d\n",
                    806:                    cp - v -> v_dvalue - 1);
                    807:        }
                    808:        else
                    809:            (void)printf ("use any %s value\n",
                    810:                    v -> v_value ? "integer" : "string");
                    811: 
                    812:        return DONE;
                    813:     }
                    814: 
                    815:     if (v -> v_value == NULLIP) {
                    816:        register int    w;
                    817: 
                    818:        if (*v -> v_dvalue)
                    819:            free (*v -> v_dvalue);
                    820:        *v -> v_dvalue = strdup (*vec);
                    821:        if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)
                    822:            varwidth2 = w;
                    823:        if (v -> v_hook)
                    824:            (*v -> v_hook) (v);
                    825:        if (verbose)
                    826:            printvar (v);
                    827:        return DONE;
                    828:     }
                    829: 
                    830:     if (v -> v_mask) {
                    831:        if (strcmp (dp = *vec, "all") == 0 && (cp = v -> v_dvalue)) {
                    832:            i = 1;
                    833:            while (*++cp)
                    834:                i <<= 1;
                    835:            value = i - 1;
                    836:            j = 1;
                    837:        }
                    838:        else {
                    839:            if (strncmp (dp = *vec, "0x", 2) == 0)
                    840:                dp += 2;
                    841:            for (j = sscanf (dp, "%x", &value); *dp; dp++)
                    842:                if (!isxdigit (*dp)) {
                    843:                    j = 0;
                    844:                    break;
                    845:                }
                    846:        }
                    847:     }
                    848:     else
                    849:        j = sscanf (*vec, "%d", &value);
                    850: 
                    851:     if (j == 1) {
                    852:        if (cp = v -> v_dvalue) {
                    853:            if (v -> v_mask) {
                    854:                i = 1;
                    855:                while (*++cp)
                    856:                    i <<= 1;
                    857:                if (value >= i)
                    858:                    goto out_of_range;
                    859:            }
                    860:            else {
                    861:                for (; *cp; cp++)
                    862:                    continue;
                    863:                if (value >= cp - v -> v_dvalue) {
                    864: out_of_range: ;
                    865:                    advise (LLOG_NOTICE,NULLCP, 
                    866:                            "value out of range \"%s\"", *vec);
                    867: 
                    868:                    return DONE;
                    869:                }
                    870:            }
                    871:        }
                    872: 
                    873:        vflag = verbose;
                    874:        *v -> v_value = value;
                    875:        if (v -> v_hook)
                    876:            (*v -> v_hook) (v);
                    877:        if (vflag)
                    878:            printvar (v);
                    879: 
                    880:        return DONE;
                    881:     }
                    882: 
                    883:     if (v -> v_mask) {
                    884:        i = 0;
                    885:        for (; *vec; vec++) {
                    886:            if (!(cp = getval (*vec, v -> v_dvalue))) {
                    887:                advise (LLOG_NOTICE,NULLCP,  "bad value \"%s\"", *vec);
                    888: 
                    889:                return DONE;
                    890:            }
                    891:            if ((j = cp - v -> v_dvalue) <= 0)
                    892:                continue;
                    893: 
                    894:            i |= 1 << (j - 1);
                    895:        }
                    896: 
                    897:        vflag = verbose;
                    898:        *v -> v_value = i;
                    899:        if (v -> v_hook)
                    900:            (*v -> v_hook) (v);
                    901:        if (vflag)
                    902:            printvar (v);
                    903: 
                    904:        return DONE;
                    905:     }
                    906: 
                    907:     if (v -> v_dvalue && (cp = getval (*vec, v -> v_dvalue))) {
                    908:        vflag = verbose;
                    909:        *v -> v_value = cp - v -> v_dvalue;
                    910:        if (v -> v_hook)
                    911:            (*v -> v_hook) (v);
                    912:        if (vflag)
                    913:            printvar (v);
                    914:     }
                    915:     else
                    916:        if (!v -> v_dvalue)
                    917:            advise (LLOG_NOTICE,NULLCP,  "bad value \"%s\"", *vec);
                    918: 
                    919:     return DONE;
                    920: }
                    921: 
                    922: /*  */
                    923: 
                    924: static printvar (v)
                    925: register struct var *v;
                    926: {
                    927:     int            i;
                    928:     char    buffer[BUFSIZ];
                    929: 
                    930:     if (runcom)
                    931:        return;
                    932: 
                    933:     (void)printf ("%-*s = ", varwidth1, v -> v_name);
                    934:     if (v -> v_value) {
                    935:        i = *v -> v_value;
                    936: 
                    937:        if (v -> v_mask) {
                    938:            if (v -> v_dvalue) {
                    939:                if (i == 0)
                    940:                    (void)printf ("%-*s", varwidth2, v -> v_dvalue[i]);
                    941:                else {
                    942:                    (void) strcpy (buffer, sprintb (i, v -> v_mask));
                    943:                    if (strlen (buffer) <= varwidth2)
                    944:                        (void)printf ("%-*s", varwidth2, buffer);
                    945:                    else
                    946:                        (void)printf ("%s\n%*s", buffer, varwidth1 + varwidth2 + 3,
                    947:                                "");
                    948:                }
                    949:            }
                    950:            else
                    951:                (void)printf ("0x%-*x", varwidth2 - 2, i);
                    952:        }
                    953:        else {
                    954:            if (v -> v_dvalue)
                    955:                (void)printf ("%-*s", varwidth2, v -> v_dvalue[i]);
                    956:            else
                    957:                (void)printf ("%-*d", varwidth2, i);
                    958:        }
                    959:     }
                    960:     else
                    961:        if (*v -> v_dvalue) {
                    962:            (void) sprintf (buffer, "\"%s\"", *v -> v_dvalue);
                    963:            (void)printf ("%-*s", varwidth2, buffer);
                    964:        }
                    965:     (void)printf ("    - %s\n", v -> v_dname);
                    966: }
                    967: 
                    968: /*  */
                    969: 
                    970: /* ARGSUSED */
                    971: 
                    972: static int  set_debug (v)
                    973: struct var *v;
                    974: {
                    975:     if (debug)
                    976:        ll_dbinit (vt_log, myname);
                    977:     else
                    978:        vt_log -> ll_stat &= ~LLOGTTY;
                    979: }
                    980: 
                    981: 
                    982: /* ARGSUSED */
                    983: 
                    984: static int  set_echo (v)
                    985: struct var *v;
                    986: {
                    987:     if (!connected) {
                    988:        advise (LLOG_NOTICE,NULLCP,  "not associated with terminal service");
                    989:        return;
                    990:     }
                    991: 
                    992:     vt_echo (echo);
                    993: }
                    994: 
                    995: 
                    996: /* ARGSUSED */
                    997: 
                    998: static int  set_escape (v)
                    999: struct var *v;
                   1000: {
                   1001:     if (*escapestr) {
                   1002:        char   *cp = control (escape = *escapestr);
                   1003: 
                   1004:        free (escapestr);
                   1005:        escapestr = strdup (cp);
                   1006:     }
                   1007: }
                   1008: 
                   1009: 
                   1010: /* ARGSUSED */
                   1011: 
                   1012: static int  set_repertoire (v)
                   1013: struct var *v;
                   1014: {
                   1015:     if (!connected) {
                   1016:        advise (LLOG_NOTICE,NULLCP,  "not associated with terminal service");
                   1017:        return;
                   1018:     }
                   1019: 
                   1020:     vt_repertoire (repertoire);
                   1021: }
                   1022: 
                   1023: /*  */
                   1024: 
                   1025: static char **getval (name, choices)
                   1026: register char *name;
                   1027: char   **choices;
                   1028: {
                   1029:     register int    longest,
                   1030:                     nmatches;
                   1031:     register char  *p,
                   1032:                    *q,
                   1033:                   **cp,
                   1034:                   **fp;
                   1035:     char    buffer[BUFSIZ];
                   1036: 
                   1037:     longest = nmatches = 0;
                   1038:     for (cp = choices; p = *cp; cp++) {
                   1039:        for (q = name; *q == *p++; q++)
                   1040:            if (*q == NULL)
                   1041:                return cp;
                   1042:        if (*q == NULL)
                   1043:            if (q - name > longest) {
                   1044:                longest = q - name;
                   1045:                nmatches = 1;
                   1046:                fp = cp;
                   1047:            }
                   1048:            else
                   1049:                if (q - name == longest)
                   1050:                    nmatches++;
                   1051:     }
                   1052: 
                   1053:     switch (nmatches) {
                   1054:        case 0: 
                   1055:            advise (LLOG_NOTICE,NULLCP,  "unknown value \"%s\"", name);
                   1056:            return NULL;
                   1057: 
                   1058:        case 1: 
                   1059:            return fp;
                   1060: 
                   1061:        default: 
                   1062:            for (cp = choices, p = buffer; q = *cp; cp++)
                   1063:                if (strncmp (q, name, longest) == 0) {
                   1064:                    (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
                   1065:                    p += strlen (p);
                   1066:                }
                   1067:            advise (LLOG_NOTICE,NULLCP,  "ambiguous value, it could be one of:%s",
                   1068:                    buffer);
                   1069:            return NULL;
                   1070:     }
                   1071: }
                   1072: 
                   1073: /*  */
                   1074: 
                   1075: static struct var *getvar (name)
                   1076: register char *name;
                   1077: {
                   1078:     register int    longest,
                   1079:                     nmatches;
                   1080:     register char  *p,
                   1081:                    *q;
                   1082:     char    buffer[BUFSIZ];
                   1083:     register struct var *v,
                   1084:                        *f;
                   1085: 
                   1086:     longest = nmatches = 0;
                   1087:     for (v = vars; p = v -> v_name; v++) {
                   1088:        for (q = name; *q == *p++; q++)
                   1089:            if (*q == NULL)
                   1090:                return v;
                   1091:        if (*q == NULL)
                   1092:            if (q - name > longest) {
                   1093:                longest = q - name;
                   1094:                nmatches = 1;
                   1095:                f = v;
                   1096:            }
                   1097:            else
                   1098:                if (q - name == longest)
                   1099:                    nmatches++;
                   1100:     }
                   1101: 
                   1102:     switch (nmatches) {
                   1103:        case 0: 
                   1104:            advise (LLOG_NOTICE,NULLCP,  "unknown variable \"%s\"", name);
                   1105:            return NULL;
                   1106: 
                   1107:        case 1: 
                   1108:            return f;
                   1109: 
                   1110:        default: 
                   1111:            for (v = vars, p = buffer; q = v -> v_name; v++)
                   1112:                if (strncmp (q, name, longest) == 0) {
                   1113:                    (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
                   1114:                    p += strlen (p);
                   1115:                }
                   1116:            advise (LLOG_NOTICE,NULLCP, 
                   1117:                    "ambiguous variable, it could be one of:%s", buffer);
                   1118:            return NULL;
                   1119:     }
                   1120: }
                   1121: 
                   1122: /*    HELP */
                   1123: 
                   1124: static int helpwidth = 0;
                   1125: 
                   1126: 
                   1127: static int  vt_help (vec)
                   1128: char  **vec;
                   1129: {
                   1130:     register int    i,
                   1131:                     j,
                   1132:                     w;
                   1133:     int     columns,
                   1134:             width,
                   1135:             lines;
                   1136:     register struct dispatch   *ds,
                   1137:                                *es;
                   1138: 
                   1139:     for (es = dispatches; es -> ds_name; es++)
                   1140:        continue;
                   1141:     width = helpwidth;
                   1142: 
                   1143:     if (*++vec == NULL) {
                   1144:        if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)
                   1145:            columns = 1;
                   1146:        lines = ((es - dispatches) + columns - 1) / columns;
                   1147: 
                   1148:        (void)printf ("Operations:\n");
                   1149:        for (i = 0; i < lines; i++)
                   1150:            for (j = 0; j < columns; j++) {
                   1151:                ds = dispatches + j * lines + i;
                   1152:                (void)printf ("%s", ds -> ds_name);
                   1153:                if (ds + lines >= es) {
                   1154:                    (void)printf ("\n");
                   1155:                    break;
                   1156:                }
                   1157:                for (w = strlen (ds -> ds_name); w < width; w = (w + 8) & ~7)
                   1158:                    (void) putchar ('\t');
                   1159:            }
                   1160: 
                   1161:        (void)printf ("\n");
                   1162: 
                   1163:        return DONE;
                   1164:     }
                   1165: 
                   1166:     for (; *vec; vec++)
                   1167:        if (strcmp (*vec, "?") == 0) {
                   1168:            for (ds = dispatches; ds -> ds_name; ds++)
                   1169:                (void)printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help);
                   1170: 
                   1171:            break;
                   1172:        }
                   1173:        else
                   1174:            if (ds = getds (*vec))
                   1175:                (void)printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help);
                   1176: 
                   1177:     return DONE;
                   1178: }
                   1179: 
                   1180: 
                   1181: #ifndef        TIOCGWINSZ
                   1182: /* ARGSUSED */
                   1183: #endif
                   1184: 
                   1185: static int    ncols (fp)
                   1186: FILE *fp;
                   1187: {
                   1188: #ifdef TIOCGWINSZ
                   1189:     int            i;
                   1190:     struct winsize win;
                   1191: 
                   1192:     if (ioctl (fileno (fp), TIOCGWINSZ, (char *) &win) != NOTOK
                   1193:            && (i = win.ws_col) > 0)
                   1194:        return i;
                   1195: #endif
                   1196: 
                   1197:     return 80;
                   1198: }
                   1199: 
                   1200: /*  */
                   1201: 
                   1202: char   *strdup (s)
                   1203: char   *s;
                   1204: {
                   1205:     char    *p;
                   1206: 
                   1207:     if ((p = malloc((unsigned) (strlen (s) + 1))) == NULL)
                   1208:        adios (NULLCP, "out of memory");
                   1209: 
                   1210:     (void) strcpy (p, s);
                   1211: 
                   1212:     return p;
                   1213: }
                   1214: 
                   1215: /*  */
                   1216: 
                   1217: static rcinit ()
                   1218: {
                   1219:     register int    w;
                   1220:     register char **cp;
                   1221:     register struct dispatch *ds;
                   1222:     register struct var *v;
                   1223: 
                   1224:     if ((myhome = getenv ("HOME")) == NULL)
                   1225:        myhome = ".";           /* could do passwd search... */
                   1226: 
                   1227:     escapestr = strdup (control (escape));
                   1228:     for (ds = dispatches, helpwidth = 0; ds -> ds_name; ds++)
                   1229:        if ((w = strlen (ds -> ds_name)) > helpwidth)
                   1230:            helpwidth = w;
                   1231: 
                   1232:     for (v = vars, varwidth1 = 0; v -> v_name; v++) {
                   1233:        if ((w = strlen (v -> v_name)) > varwidth1)
                   1234:            varwidth1 = w;
                   1235: 
                   1236:        if (v -> v_value) {
                   1237:            if (cp = v -> v_dvalue) {
                   1238:                if (v -> v_mask) {
                   1239: #ifdef notdef
                   1240:                    w = 1;
                   1241:                    while (*++cp)
                   1242:                        w <<= 1;
                   1243:                    w--;
                   1244:                    if ((w = strlen (sprintb (w, v -> v_mask))) > varwidth2)
                   1245:                        varwidth2 = w;
                   1246: #endif
                   1247:                }
                   1248:                else
                   1249:                    for (; *cp; cp++)
                   1250:                        if ((w = strlen (*cp)) > varwidth2)
                   1251:                            varwidth2 = w;
                   1252:            }
                   1253:        }
                   1254:        else
                   1255:            if (*v -> v_dvalue) {
                   1256:                *v -> v_dvalue = strdup (*v -> v_dvalue);
                   1257:                if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)
                   1258:                    varwidth2 = w;
                   1259:            }
                   1260:     }
                   1261: }
                   1262: 
                   1263: char   sibuf[BUFSIZ << 3], *sbp;
                   1264: char   tibuf[BUFSIZ], *tbp;
                   1265: int    tcc;
                   1266: 
                   1267: /*
                   1268:  * Select from tty and network...
                   1269:  */
                   1270: vt(s)
                   1271:        int s;
                   1272: {
                   1273:        register int c;
                   1274:        int tin = fileno(stdin), tout = fileno(stdout);
                   1275:        int nfds, result;
                   1276: 
                   1277:        if ((nfds = (tin > tout ? tin : tout)) < s)
                   1278:            nfds = s;
                   1279:        nfds++;
                   1280: 
                   1281:        nego_state = 0;
                   1282:        if(telnet_profile)
                   1283:        {
                   1284:                (void) tmode(2);
                   1285:                vt_rem_echo(&ni_image);         /*Request Remote Echo*/
                   1286:                vt_sup_ga(&ni_image);           /*Request Suppress Go Ahead*/
                   1287:                repertoire = 1;
                   1288:                vt_repertoire(repertoire);
                   1289:        }
                   1290:        else (void) tmode(1);
                   1291: 
                   1292:        for (;;) {
                   1293:                fd_set    ibits, obits;
                   1294: 
                   1295:                FD_ZERO (&ibits);
                   1296: 
                   1297:                FD_ZERO (&obits);
                   1298:                FD_SET (tout, &obits);
                   1299:                FD_SET (s, &obits);
                   1300: 
                   1301:                if (nfrontp - nbackp)
                   1302:                    FD_SET (s, &obits);
                   1303:                else
                   1304:                    FD_SET (tin, &ibits);
                   1305: 
                   1306:                if (tfrontp - tbackp)
                   1307:                    FD_SET (tout, &obits);
                   1308:                else
                   1309:                    FD_SET (s, &ibits);
                   1310:                if (FD_ISSET (s, &ibits) && data_pending()) {
                   1311:                        FD_CLR (s, &ibits);
                   1312:                        result = xselect(nfds, &ibits, &obits,
                   1313:                                         (fd_set *)NULL, OK);
                   1314:                        if (result == -1)
                   1315:                            adios ("failed", "xselect");
                   1316:                        FD_SET (s, &ibits);
                   1317:                }
                   1318:                else {                  
                   1319:                        result = xselect(nfds, &ibits, &obits,
                   1320:                                         (fd_set *)NULL, NOTOK);
                   1321:                        if (result == -1)
                   1322:                            adios ("failed", "xselect");
                   1323:                }
                   1324:                if (!FD_ISSET (s, &ibits)
                   1325:                        && !FD_ISSET (tin, &ibits)
                   1326:                        && !FD_ISSET (s, &obits)
                   1327:                        && !FD_ISSET (tout, &obits)) {
                   1328:                        sleep(5);
                   1329:                        continue;
                   1330:                }
                   1331: 
                   1332:                /*
                   1333:                 * Something to read from the network...
                   1334:                 */
                   1335:                if (FD_ISSET (s, &ibits)) {
                   1336: 
                   1337:                        while ( (c = getch()) > 0){
                   1338:                                *tfrontp++ = c;
                   1339:                                if(tfrontp >= &ttyobuf[TBUFSIZ-1]) break;
                   1340:                        }
                   1341: 
                   1342:                        if (c == E_EOF) {
                   1343:                                break;
                   1344:                        }
                   1345:                }
                   1346: 
                   1347:                /*
                   1348:                 * Something to read from the tty...
                   1349:                 */
                   1350:                if (FD_ISSET (tin, &ibits)) {
                   1351:                        tcc = read(tin, tibuf, sizeof (tibuf));
                   1352:                        if (tcc < 0 && errno == EWOULDBLOCK)
                   1353:                                tcc = 0;
                   1354:                        else {
                   1355:                                if (tcc <= 0) {
                   1356:                                        advise(LLOG_NOTICE,NULLCP,  "error: read from terminal returned %d", tcc);
                   1357:                                        break;
                   1358:                                }
                   1359:                                tbp = tibuf;
                   1360:                        }
                   1361:                }
                   1362: 
                   1363:                while (tcc > 0) {
                   1364:                        register int ch;
                   1365: 
                   1366:                        if ((&netobuf[BUFSIZ] - nfrontp) < 2)
                   1367:                                break;
                   1368:                        ch = *tbp++ & 0377, tcc--;
                   1369:                        if (strip(ch) == escape) {
                   1370:                                command(0);
                   1371:                                tcc = 0;
                   1372:                                break;
                   1373:                        }
                   1374:                        *nfrontp++ = ch;
                   1375:                }
                   1376:                if (FD_ISSET (s, &obits) && (nfrontp - nbackp) > 0)
                   1377:                        netflush(s);
                   1378:                if (FD_ISSET (tout, &obits) && (tfrontp - tbackp) > 0)
                   1379:                        ttyflush(tout);
                   1380:        }
                   1381:        (void) tmode(0);
                   1382: }
                   1383: 
                   1384: /*
                   1385:  * Construct a control character sequence
                   1386:  * for a special character.
                   1387:  */
                   1388: char *
                   1389: control(c)
                   1390:        register int c;
                   1391: {
                   1392:        static char buf[3];
                   1393: 
                   1394:        if (c == 0177)
                   1395:                return ("^?");
                   1396:        if (c >= 040) {
                   1397:                buf[0] = c;
                   1398:                buf[1] = 0;
                   1399:        } else {
                   1400:                buf[0] = '^';
                   1401:                buf[1] = '@'+c;
                   1402:                buf[2] = 0;
                   1403:        }
                   1404:        return (buf);
                   1405: }
                   1406: 
                   1407: SFD    deadpeer()
                   1408: {
                   1409:        (void) tmode(0);
                   1410:        longjmp(peerdied, -1);
                   1411: }
                   1412: 
                   1413: SFD    intr()
                   1414: {
                   1415:        (void) tmode(0);
                   1416:        longjmp(toplevel, -1);
                   1417: }
                   1418: 
                   1419: ttyflush(dd)
                   1420: int    dd;
                   1421: {
                   1422:        int n;
                   1423: 
                   1424:        if ((n = tfrontp - tbackp) > 0) {
                   1425: 
                   1426:                n = write(dd, tbackp, n);
                   1427: 
                   1428:        }
                   1429:        if (n < 0)
                   1430:        {
                   1431:                advise(LLOG_NOTICE,NULLCP,  "ttyflush(): Negative returned from write");
                   1432:                return;
                   1433:        }
                   1434:        tbackp += n;
                   1435:        if (tbackp == tfrontp)
                   1436:                tbackp = tfrontp = ttyobuf;
                   1437: }
                   1438: 
                   1439: netflush(dd)
                   1440: int    dd;
                   1441: {
                   1442:        register char *cp;
                   1443:        int n, i, j;
                   1444:        int nl_flag;            /*If current PDU includes newline, follow it
                   1445:                                  with a Deliver Request*/
                   1446: 
                   1447:        nl_flag = 0;
                   1448:        if ((n = nfrontp - nbackp) > 0) {
                   1449:                if(transparent)
                   1450:                {
                   1451:                        if (vt_text(nbackp,n) != OK)
                   1452:                                advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1453:                        vtsend();
                   1454:                        cp = nbackp;
                   1455:                        for(i=0; i<n; i++)
                   1456:                        {
                   1457:                                if( (*cp == '\r') ||
                   1458:                                    (*cp == '\n') )
                   1459:                                {
                   1460:                                        vdelreq(FALSE);
                   1461:                                        break;
                   1462:                                }
                   1463:                                ++cp;
                   1464:                        }
                   1465:                        nbackp += n;
                   1466:                }
                   1467:                else
                   1468:                {
                   1469:                    cp = nbackp;
                   1470:                    for(i=0,j=0; i<n; i++)
                   1471:                    {
                   1472:                        if(*cp == '\r')
                   1473:                        {
                   1474:                            if(j) 
                   1475:                                        if (vt_text(nbackp,j) != OK) 
                   1476:                                                advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1477:                            nbackp += (j+1);
                   1478:                            cp = nbackp;
                   1479:                            j = 0;
                   1480:                            rflag = 1;
                   1481:                            vt_newline();
                   1482:                            ++nl_flag;
                   1483:                        }
                   1484:                        else if(*cp == '\n')
                   1485:                        {
                   1486:                            if(!rflag) /*If preceeding char was not CR*/
                   1487:                            {
                   1488:                                if(j) 
                   1489:                                        if (vt_text(nbackp,j) != OK)
                   1490:                                                advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1491:                                nbackp += (j+1);
                   1492:                                cp = nbackp;
                   1493:                                j = 0;
                   1494:                                vt_newline();
                   1495:                                ++nl_flag;
                   1496:                            }
                   1497:                            else /*Preceeding char was CR so already sent
                   1498:                                   the Update.  Remove this LF from buffer*/
                   1499:                            {
                   1500:                                ++nbackp;
                   1501:                                ++cp;
                   1502:                                rflag = 0;
                   1503:                            }
                   1504:                        } 
                   1505:                        else if(telnet_profile)
                   1506:                        {
                   1507:                            rflag = 0;
                   1508:                            if(*cp == erase_char)
                   1509:                            {
                   1510:                                    if(j) 
                   1511:                                                if (vt_text(nbackp,j) != OK)
                   1512:                                                        advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1513:                                    nbackp += (j+1);
                   1514:                                    cp = nbackp;
                   1515:                                    j = 0;
                   1516:                                    vt_char_erase();
                   1517:                            }
                   1518:                            else if(*cp == erase_line)
                   1519:                            {
                   1520:                                    if(j) 
                   1521:                                                if (vt_text(nbackp,j) != OK)
                   1522:                                                        advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1523:                                    nbackp += (j+1);
                   1524:                                    cp = nbackp;
                   1525:                                    j = 0;
                   1526:                                    vt_line_erase();
                   1527:                            }
                   1528:                            else if(*cp == intr_char)
                   1529:                            {
                   1530:                                    if(j) 
                   1531:                                                if (vt_text(nbackp,j) != OK)
                   1532:                                                        advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1533:                                    nbackp += (j+1);
                   1534:                                    cp = nbackp;
                   1535:                                    j = 0;
                   1536:                                    vt_interrupt();
                   1537:                            }
                   1538:                            else if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
                   1539:                                        /*If ASCII GO, dump ctrl chars*/
                   1540:                            {
                   1541:                                if((*cp < 0x20) || (*cp > 0x7e))
                   1542:                                {
                   1543:                                    if(j) 
                   1544:                                                if (vt_text(nbackp,j) != OK)
                   1545:                                                        advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1546:                                    nbackp += (j+1);
                   1547:                                    cp = nbackp;
                   1548:                                    j = 0;
                   1549:                                }
                   1550:                                else
                   1551:                                {
                   1552:                                    ++j;
                   1553:                                    ++cp;
                   1554:                                }
                   1555:                            }
                   1556:                            else
                   1557:                            {
                   1558:                                ++j;
                   1559:                                ++cp;
                   1560:                            }
                   1561:                        }
                   1562:                        else    /*Else Default Profile*/
                   1563:                        {
                   1564:                            if((*cp < 0x20) || (*cp > 0x7e))
                   1565:                            {
                   1566:                                if(j) 
                   1567:                                        if (vt_text(nbackp,j) != OK)
                   1568:                                                        advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1569:                                nbackp += (j+1);
                   1570:                                cp = nbackp;
                   1571:                                j = 0;
                   1572:                            }
                   1573:                            else
                   1574:                            {
                   1575:                                ++j; ++cp;
                   1576:                            }
                   1577:                        }
                   1578:                    }           /*End for loop*/
                   1579:                    if(j) 
                   1580:                                if (vt_text(nbackp,j) != OK) /*Load anything left if CR or LF
                   1581:                                                        wasn't last char in buffer*/
                   1582:                                                advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
                   1583:                    nbackp += j;
                   1584:                    vtsend();   /*Send the whole NDQ*/
                   1585:                    if(nl_flag && telnet_profile) vdelreq(FALSE);
                   1586:                    rflag = 0;
                   1587:                }
                   1588: 
                   1589:        }
                   1590:        if (n < 0) {
                   1591:                if (errno != ENOBUFS && errno != EWOULDBLOCK) {
                   1592:                        (void) tmode(0);
                   1593:                        perror(peerhost);
                   1594:                        (void)close(dd);
                   1595:                        longjmp(peerdied, -1);
                   1596:                        /*NOTREACHED*/
                   1597:                }
                   1598:                n = 0;
                   1599:        }
                   1600:        if (nbackp == nfrontp)
                   1601:                nbackp = nfrontp = netobuf;
                   1602: }
                   1603: 
                   1604: flushbufs()
                   1605: {
                   1606:        tcc = 0;
                   1607:        tbp = tibuf;
                   1608:        nfrontp = nbackp = netobuf;
                   1609:        while (getch() > 0)
                   1610:            continue;
                   1611:        tfrontp = tbackp = ttyobuf;
                   1612: }
                   1613:        
                   1614: /*    ERRORS */
                   1615: 
                   1616: void   finalbye ()
                   1617: {
                   1618:     (void) tmode (0);
                   1619: }
                   1620: 
                   1621: 
                   1622: #ifndef        lint
                   1623: void   adios (va_alist)
                   1624: va_dcl
                   1625: {
                   1626:     int            code;
                   1627:     va_list ap;
                   1628:     static int latched = 0;
                   1629: 
                   1630:     va_start (ap);
                   1631: 
                   1632:     code = va_arg (ap, int);
                   1633: 
                   1634:     (void) _ll_log (vt_log, code, ap);
                   1635: 
                   1636:     va_end (ap);
                   1637: 
                   1638:     if (connected && latched++ == 0)
                   1639:        (void) vt_close (NULLVP);
                   1640: 
                   1641:     _exit (1);
                   1642: }
                   1643: #else
                   1644: /* VARARGS2 */
                   1645: 
                   1646: void   adios (what, fmt)
                   1647: char   *what,
                   1648:        *fmt;
                   1649: {
                   1650:     adios (what, fmt);
                   1651: }
                   1652: #endif
                   1653: 
                   1654: 
                   1655: #ifndef        lint
                   1656: void   advise (va_alist)
                   1657: va_dcl
                   1658: {
                   1659:     int            code,
                   1660:            flags;
                   1661:     char    buffer[BUFSIZ];
                   1662:     va_list ap;
                   1663: 
                   1664:     va_start (ap);
                   1665: 
                   1666:     code = va_arg (ap, int);
                   1667: 
                   1668:     asprintf (buffer, ap);
                   1669: 
                   1670:     flags = vt_log -> ll_stat;
                   1671: 
                   1672:     if (code & (LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE)) {
                   1673:        (void) fflush (stdout);
                   1674: 
                   1675:        fprintf (stderr, "%s: ", myname);
                   1676:        (void) fputs (buffer, stderr);
                   1677:        (void) fputc ('\n', stderr);
                   1678: 
                   1679:        (void) fflush (stderr);
                   1680: 
                   1681:        vt_log -> ll_stat &= ~LLOGTTY;
                   1682:     }
                   1683: 
                   1684:     (void) ll_log (vt_log, code, NULLCP, "%s", buffer);
                   1685: 
                   1686:     vt_log -> ll_stat = flags;
                   1687: 
                   1688:     va_end (ap);
                   1689: }
                   1690: #else
                   1691: /* VARARGS3 */
                   1692: 
                   1693: void   advise (code, what, fmt)
                   1694: int    code;
                   1695: char   *what,
                   1696:        *fmt;
                   1697: {
                   1698:     advise (code, what, fmt);
                   1699: }
                   1700: #endif
                   1701: 
                   1702: /* XXX -- why is this stubbed ? */
                   1703: #ifdef BSD44
                   1704: ptyecho(on)
                   1705: {
                   1706: }
                   1707: #else
                   1708: /*ARGSUSED*/
                   1709: setmode(on, off)
                   1710: {
                   1711: }
                   1712: #endif

unix.superglobalmegacorp.com

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