|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.