1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)telnet.c 5.49 (Berkeley) 06/20/90"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 14 #ifdef KERBEROS 15 #include <sys/socket.h> 16 #include <netinet/in.h> 17 #include <kerberosIV/des.h> 18 #include <kerberosIV/krb.h> 19 #include "krb4-proto.h" 20 #endif 21 22 #if defined(unix) 23 #include <signal.h> 24 /* By the way, we need to include curses.h before telnet.h since, 25 * among other things, telnet.h #defines 'DO', which is a variable 26 * declared in curses.h. 27 */ 28 #endif /* defined(unix) */ 29 30 #include <arpa/telnet.h> 31 32 #include <string.h> 33 34 #include <ctype.h> 35 36 #include "ring.h" 37 38 #include "defines.h" 39 #include "externs.h" 40 #include "types.h" 41 #include "general.h" 42 43 44 #define strip(x) ((x)&0x7f) 45 46 47 static char subbuffer[SUBBUFSIZE], 48 *subpointer, *subend; /* buffer for sub-options */ 49 #define SB_CLEAR() subpointer = subbuffer; 50 #define SB_TERM() subend = subpointer; 51 #define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \ 52 *subpointer++ = (c); \ 53 } 54 55 char options[256]; /* The combined options */ 56 char do_dont_resp[256]; 57 char will_wont_resp[256]; 58 59 int 60 connected, 61 showoptions, 62 In3270, /* Are we in 3270 mode? */ 63 ISend, /* trying to send network data in */ 64 #ifdef KERBEROS 65 kerberized = 0, /* Are we using Kerberos authentication ? */ 66 #endif 67 debug = 0, 68 crmod, 69 netdata, /* Print out network data flow */ 70 crlf, /* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */ 71 #if defined(TN3270) 72 noasynchtty = 0,/* User specified "-noasynch" on command line */ 73 noasynchnet = 0,/* User specified "-noasynch" on command line */ 74 askedSGA = 0, /* We have talked about suppress go ahead */ 75 #endif /* defined(TN3270) */ 76 telnetport, 77 SYNCHing, /* we are in TELNET SYNCH mode */ 78 flushout, /* flush output */ 79 autoflush = 0, /* flush output when interrupting? */ 80 autosynch, /* send interrupt characters with SYNCH? */ 81 localflow, /* we handle flow control locally */ 82 localchars, /* we recognize interrupt/quit */ 83 donelclchars, /* the user has set "localchars" */ 84 donebinarytoggle, /* the user has put us in binary */ 85 dontlecho, /* do we suppress local echoing right now? */ 86 globalmode; 87 88 #define CONTROL(x) ((x)&0x1f) /* CTRL(x) is not portable */ 89 90 unsigned char *prompt = 0; 91 92 cc_t escape, echoc; 93 94 /* 95 * Telnet receiver states for fsm 96 */ 97 #define TS_DATA 0 98 #define TS_IAC 1 99 #define TS_WILL 2 100 #define TS_WONT 3 101 #define TS_DO 4 102 #define TS_DONT 5 103 #define TS_CR 6 104 #define TS_SB 7 /* sub-option collection */ 105 #define TS_SE 8 /* looking for sub-option end */ 106 107 static int telrcv_state; 108 109 jmp_buf toplevel = { 0 }; 110 jmp_buf peerdied; 111 112 int flushline; 113 int linemode; 114 115 #ifdef KLUDGELINEMODE 116 int kludgelinemode = 1; 117 #endif 118 119 /* 120 * The following are some clocks used to decide how to interpret 121 * the relationship between various variables. 122 */ 123 124 Clocks clocks; 125 126 #ifdef notdef 127 Modelist modelist[] = { 128 { "telnet command mode", COMMAND_LINE }, 129 { "character-at-a-time mode", 0 }, 130 { "character-at-a-time mode (local echo)", LOCAL_ECHO|LOCAL_CHARS }, 131 { "line-by-line mode (remote echo)", LINE | LOCAL_CHARS }, 132 { "line-by-line mode", LINE | LOCAL_ECHO | LOCAL_CHARS }, 133 { "line-by-line mode (local echoing suppressed)", LINE | LOCAL_CHARS }, 134 { "3270 mode", 0 }, 135 }; 136 #endif 137 138 139 /* 140 * Initialize telnet environment. 141 */ 142 143 init_telnet() 144 { 145 SB_CLEAR(); 146 ClearArray(options); 147 148 connected = In3270 = ISend = localflow = donebinarytoggle = 0; 149 150 SYNCHing = 0; 151 152 /* Don't change NetTrace */ 153 154 escape = CONTROL(']'); 155 echoc = CONTROL('E'); 156 157 flushline = 1; 158 telrcv_state = TS_DATA; 159 } 160 161 162 #include <varargs.h> 163 164 /*VARARGS*/ 165 static void 166 printring(va_alist) 167 va_dcl 168 { 169 va_list ap; 170 char buffer[100]; /* where things go */ 171 char *ptr; 172 char *format; 173 char *string; 174 Ring *ring; 175 int i; 176 177 va_start(ap); 178 179 ring = va_arg(ap, Ring *); 180 format = va_arg(ap, char *); 181 ptr = buffer; 182 183 while ((i = *format++) != 0) { 184 if (i == '%') { 185 i = *format++; 186 switch (i) { 187 case 'c': 188 *ptr++ = va_arg(ap, int); 189 break; 190 case 's': 191 string = va_arg(ap, char *); 192 ring_supply_data(ring, buffer, ptr-buffer); 193 ring_supply_data(ring, string, strlen(string)); 194 ptr = buffer; 195 break; 196 case 0: 197 ExitString("printring: trailing %%.\n", 1); 198 /*NOTREACHED*/ 199 default: 200 ExitString("printring: unknown format character.\n", 1); 201 /*NOTREACHED*/ 202 } 203 } else { 204 *ptr++ = i; 205 } 206 } 207 ring_supply_data(ring, buffer, ptr-buffer); 208 } 209 210 /* 211 * These routines are in charge of sending option negotiations 212 * to the other side. 213 * 214 * The basic idea is that we send the negotiation if either side 215 * is in disagreement as to what the current state should be. 216 */ 217 218 send_do(c, init) 219 register int c, init; 220 { 221 if (init) { 222 if (((do_dont_resp[c] == 0) && my_state_is_do(c)) || 223 my_want_state_is_do(c)) 224 return; 225 set_my_want_state_do(c); 226 do_dont_resp[c]++; 227 } 228 NET2ADD(IAC, DO); 229 NETADD(c); 230 printoption("SENT", "do", c); 231 } 232 233 void 234 send_dont(c, init) 235 register int c, init; 236 { 237 if (init) { 238 if (((do_dont_resp[c] == 0) && my_state_is_dont(c)) || 239 my_want_state_is_dont(c)) 240 return; 241 set_my_want_state_dont(c); 242 do_dont_resp[c]++; 243 } 244 NET2ADD(IAC, DONT); 245 NETADD(c); 246 printoption("SENT", "dont", c); 247 } 248 249 void 250 send_will(c, init) 251 register int c, init; 252 { 253 if (init) { 254 if (((will_wont_resp[c] == 0) && my_state_is_will(c)) || 255 my_want_state_is_will(c)) 256 return; 257 set_my_want_state_will(c); 258 will_wont_resp[c]++; 259 } 260 NET2ADD(IAC, WILL); 261 NETADD(c); 262 printoption("SENT", "will", c); 263 } 264 265 void 266 send_wont(c, init) 267 register int c, init; 268 { 269 if (init) { 270 if (((will_wont_resp[c] == 0) && my_state_is_wont(c)) || 271 my_want_state_is_wont(c)) 272 return; 273 set_my_want_state_wont(c); 274 will_wont_resp[c]++; 275 } 276 NET2ADD(IAC, WONT); 277 NETADD(c); 278 printoption("SENT", "wont", c); 279 } 280 281 282 void 283 willoption(option) 284 int option; 285 { 286 char *fmt; 287 int new_state_ok = 0; 288 289 if (do_dont_resp[option]) { 290 --do_dont_resp[option]; 291 if (do_dont_resp[option] && my_state_is_do(option)) 292 --do_dont_resp[option]; 293 } 294 295 if ((do_dont_resp[option] == 0) && my_want_state_is_dont(option)) { 296 297 switch (option) { 298 299 case TELOPT_ECHO: 300 # if defined(TN3270) 301 /* 302 * The following is a pain in the rear-end. 303 * Various IBM servers (some versions of Wiscnet, 304 * possibly Fibronics/Spartacus, and who knows who 305 * else) will NOT allow us to send "DO SGA" too early 306 * in the setup proceedings. On the other hand, 307 * 4.2 servers (telnetd) won't set SGA correctly. 308 * So, we are stuck. Empirically (but, based on 309 * a VERY small sample), the IBM servers don't send 310 * out anything about ECHO, so we postpone our sending 311 * "DO SGA" until we see "WILL ECHO" (which 4.2 servers 312 * DO send). 313 */ 314 { 315 if (askedSGA == 0) { 316 askedSGA = 1; 317 if (my_want_state_is_dont(TELOPT_SGA)) 318 send_do(TELOPT_SGA, 1); 319 } 320 } 321 /* Fall through */ 322 case TELOPT_EOR: 323 #endif /* defined(TN3270) */ 324 case TELOPT_BINARY: 325 case TELOPT_SGA: 326 settimer(modenegotiated); 327 /* FALL THROUGH */ 328 case TELOPT_STATUS: 329 new_state_ok = 1; 330 break; 331 332 case TELOPT_TM: 333 if (flushout) 334 flushout = 0; 335 /* 336 * Special case for TM. If we get back a WILL, 337 * pretend we got back a WONT. 338 */ 339 set_my_want_state_dont(option); 340 set_my_state_dont(option); 341 return; /* Never reply to TM will's/wont's */ 342 343 case TELOPT_LINEMODE: 344 default: 345 break; 346 } 347 348 if (new_state_ok) { 349 set_my_want_state_do(option); 350 send_do(option, 0); 351 setconnmode(0); /* possibly set new tty mode */ 352 } else { 353 do_dont_resp[option]++; 354 send_dont(option, 0); 355 } 356 } 357 set_my_state_do(option); 358 } 359 360 void 361 wontoption(option) 362 int option; 363 { 364 char *fmt; 365 366 if (do_dont_resp[option]) { 367 --do_dont_resp[option]; 368 if (do_dont_resp[option] && my_state_is_dont(option)) 369 --do_dont_resp[option]; 370 } 371 372 if ((do_dont_resp[option] == 0) && my_want_state_is_do(option)) { 373 374 switch (option) { 375 376 #ifdef KLUDGELINEMODE 377 case TELOPT_SGA: 378 if (!kludgelinemode) 379 break; 380 /* FALL THROUGH */ 381 #endif 382 case TELOPT_ECHO: 383 settimer(modenegotiated); 384 break; 385 386 case TELOPT_TM: 387 if (flushout) 388 flushout = 0; 389 set_my_want_state_dont(option); 390 set_my_state_dont(option); 391 return; /* Never reply to TM will's/wont's */ 392 393 default: 394 break; 395 } 396 set_my_want_state_dont(option); 397 send_dont(option, 0); 398 setconnmode(0); /* Set new tty mode */ 399 } else if (option == TELOPT_TM) { 400 /* 401 * Special case for TM. 402 */ 403 if (flushout) 404 flushout = 0; 405 set_my_want_state_dont(option); 406 } 407 set_my_state_dont(option); 408 } 409 410 static void 411 dooption(option) 412 int option; 413 { 414 char *fmt; 415 int new_state_ok = 0; 416 417 if (will_wont_resp[option]) { 418 --will_wont_resp[option]; 419 if (will_wont_resp[option] && my_state_is_will(option)) 420 --will_wont_resp[option]; 421 } 422 423 if (will_wont_resp[option] == 0) { 424 if (my_want_state_is_wont(option)) { 425 426 switch (option) { 427 428 case TELOPT_TM: 429 /* 430 * Special case for TM. We send a WILL, but pretend 431 * we sent WONT. 432 */ 433 send_will(option, 0); 434 set_my_want_state_wont(TELOPT_TM); 435 set_my_state_wont(TELOPT_TM); 436 return; 437 438 #ifdef KERBEROS 439 case TELOPT_AUTHENTICATION: 440 if (kerberized) 441 new_state_ok = 1; 442 break; 443 #endif 444 # if defined(TN3270) 445 case TELOPT_EOR: /* end of record */ 446 # endif /* defined(TN3270) */ 447 case TELOPT_BINARY: /* binary mode */ 448 case TELOPT_NAWS: /* window size */ 449 case TELOPT_TSPEED: /* terminal speed */ 450 case TELOPT_LFLOW: /* local flow control */ 451 case TELOPT_TTYPE: /* terminal type option */ 452 case TELOPT_SGA: /* no big deal */ 453 new_state_ok = 1; 454 break; 455 456 case TELOPT_LINEMODE: 457 #ifdef KLUDGELINEMODE 458 kludgelinemode = 0; 459 #endif 460 set_my_want_state_will(TELOPT_LINEMODE); 461 send_will(option, 0); 462 set_my_state_will(TELOPT_LINEMODE); 463 slc_init(); 464 return; 465 466 case TELOPT_ECHO: /* We're never going to echo... */ 467 default: 468 break; 469 } 470 471 if (new_state_ok) { 472 set_my_want_state_will(option); 473 send_will(option, 0); 474 } else { 475 will_wont_resp[option]++; 476 send_wont(option, 0); 477 } 478 } else { 479 /* 480 * Handle options that need more things done after the 481 * other side has acknowledged the option. 482 */ 483 switch (option) { 484 case TELOPT_LINEMODE: 485 #ifdef KLUDGELINEMODE 486 kludgelinemode = 0; 487 #endif 488 set_my_state_will(option); 489 slc_init(); 490 return; 491 } 492 } 493 } 494 set_my_state_will(option); 495 } 496 497 static void 498 dontoption(option) 499 int option; 500 { 501 502 if (will_wont_resp[option]) { 503 --will_wont_resp[option]; 504 if (will_wont_resp[option] && my_state_is_wont(option)) 505 --will_wont_resp[option]; 506 } 507 508 if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) { 509 switch (option) { 510 case TELOPT_LINEMODE: 511 linemode = 0; /* put us back to the default state */ 512 break; 513 } 514 /* we always accept a DONT */ 515 set_my_want_state_wont(option); 516 send_wont(option, 0); 517 setconnmode(0); /* Set new tty mode */ 518 } 519 set_my_state_wont(option); 520 } 521 522 /* 523 * Given a buffer returned by tgetent(), this routine will turn 524 * the pipe seperated list of names in the buffer into an array 525 * of pointers to null terminated names. We toss out any bad, 526 * duplicate, or verbose names (names with spaces). 527 */ 528 529 static char *unknown[] = { "UNKNOWN", 0 }; 530 531 char ** 532 mklist(buf, name) 533 char *buf, *name; 534 { 535 register int n; 536 register char c, *cp, **argvp, *cp2, **argv; 537 char *malloc(); 538 539 if (name) { 540 if (strlen(name) > 40) 541 name = 0; 542 else { 543 unknown[0] = name; 544 upcase(name); 545 } 546 } 547 /* 548 * Count up the number of names. 549 */ 550 for (n = 1, cp = buf; *cp && *cp != ':'; cp++) { 551 if (*cp == '|') 552 n++; 553 } 554 /* 555 * Allocate an array to put the name pointers into 556 */ 557 argv = (char **)malloc((n+3)*sizeof(char *)); 558 if (argv == 0) 559 return(unknown); 560 561 /* 562 * Fill up the array of pointers to names. 563 */ 564 *argv = 0; 565 argvp = argv+1; 566 n = 0; 567 for (cp = cp2 = buf; (c = *cp); cp++) { 568 if (c == '|' || c == ':') { 569 *cp++ = '\0'; 570 /* 571 * Skip entries that have spaces or are over 40 572 * characters long. If this is our environment 573 * name, then put it up front. Otherwise, as 574 * long as this is not a duplicate name (case 575 * insensitive) add it to the list. 576 */ 577 if (n || (cp - cp2 > 41)) 578 ; 579 else if (name && (strncasecmp(name, cp2, cp-cp2) == 0)) 580 *argv = cp2; 581 else if (is_unique(cp2, argv+1, argvp)) 582 *argvp++ = cp2; 583 if (c == ':') 584 break; 585 /* 586 * Skip multiple delimiters. Reset cp2 to 587 * the beginning of the next name. Reset n, 588 * the flag for names with spaces. 589 */ 590 while ((c = *cp) == '|') 591 cp++; 592 cp2 = cp; 593 n = 0; 594 } 595 /* 596 * Skip entries with spaces or non-ascii values. 597 * Convert lower case letters to upper case. 598 */ 599 if ((c == ' ') || !isascii(c)) 600 n = 1; 601 else if (islower(c)) 602 *cp = toupper(c); 603 } 604 605 /* 606 * Check for an old V6 2 character name. If the second 607 * name points to the beginning of the buffer, and is 608 * only 2 characters long, move it to the end of the array. 609 */ 610 if ((argv[1] == buf) && (strlen(argv[1]) == 2)) { 611 *argvp++ = buf; 612 cp = *argv++; 613 *argv = cp; 614 } 615 616 /* 617 * Duplicate last name, for TTYPE option, and null 618 * terminate the array. If we didn't find a match on 619 * our terminal name, put that name at the beginning. 620 */ 621 cp = *(argvp-1); 622 *argvp++ = cp; 623 *argvp = 0; 624 625 if (*argv == 0) { 626 if (name) 627 *argv = name; 628 else 629 argv++; 630 } 631 if (*argv) 632 return(argv); 633 else 634 return(unknown); 635 } 636 637 is_unique(name, as, ae) 638 register char *name, **as, **ae; 639 { 640 register char **ap; 641 register int n; 642 643 n = strlen(name) + 1; 644 for (ap = as; ap < ae; ap++) 645 if (strncasecmp(*ap, name, n) == 0) 646 return(0); 647 return (1); 648 } 649 650 #ifdef TERMCAP 651 char termbuf[1024]; 652 setupterm(tname, fd, errp) 653 char *tname; 654 int fd, *errp; 655 { 656 if (tgetent(termbuf, tname) == 1) { 657 termbuf[1023] = '\0'; 658 if (errp) 659 *errp = 1; 660 return(0); 661 } 662 if (errp) 663 *errp = 0; 664 return(-1); 665 } 666 #else 667 #define termbuf ttytype 668 extern char ttytype[]; 669 #endif 670 671 char * 672 gettermname() 673 { 674 char *tname; 675 static int first = 1; 676 static char **tnamep; 677 static char **next; 678 char *getenv(); 679 int err; 680 681 if (first) { 682 first = 0; 683 if ((tname = getenv("TERM")) && 684 (setupterm(tname, 1, &err) == 0)) { 685 tnamep = mklist(termbuf, tname); 686 } else { 687 if (tname && (strlen(tname) <= 40)) { 688 unknown[0] = tname; 689 upcase(tname); 690 } 691 tnamep = unknown; 692 } 693 next = tnamep; 694 } 695 if (*next == 0) 696 next = tnamep; 697 return(*next++); 698 } 699 /* 700 * suboption() 701 * 702 * Look at the sub-option buffer, and try to be helpful to the other 703 * side. 704 * 705 * Currently we recognize: 706 * 707 * Terminal type, send request. 708 * Terminal speed (send request). 709 * Local flow control (is request). 710 * Linemode 711 */ 712 713 static void 714 suboption() 715 { 716 printsub('<', subbuffer, subend-subbuffer+2); 717 switch (subbuffer[0]&0xff) { 718 case TELOPT_TTYPE: 719 if (my_want_state_is_wont(TELOPT_TTYPE)) 720 return; 721 if ((subbuffer[1]&0xff) != TELQUAL_SEND) { 722 ; 723 } else { 724 char *name; 725 extern char *getenv(); 726 char temp[50]; 727 int len; 728 729 #if defined(TN3270) 730 if (tn3270_ttype()) { 731 return; 732 } 733 #endif /* defined(TN3270) */ 734 name = gettermname(); 735 len = strlen(name) + 4 + 2; 736 if (len < NETROOM()) { 737 sprintf(temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, 738 TELQUAL_IS, name, IAC, SE); 739 ring_supply_data(&netoring, temp, len); 740 printsub('>', &temp[2], len-2); 741 } else { 742 ExitString("No room in buffer for terminal type.\n", 1); 743 /*NOTREACHED*/ 744 } 745 } 746 break; 747 case TELOPT_TSPEED: 748 if (my_want_state_is_wont(TELOPT_TSPEED)) 749 return; 750 if ((subbuffer[1]&0xff) == TELQUAL_SEND) { 751 long ospeed,ispeed; 752 char temp[50]; 753 int len; 754 755 TerminalSpeeds(&ispeed, &ospeed); 756 757 sprintf(temp, "%c%c%c%c%d,%d%c%c", IAC, SB, TELOPT_TSPEED, 758 TELQUAL_IS, ospeed, ispeed, IAC, SE); 759 len = strlen(temp+4) + 4; /* temp[3] is 0 ... */ 760 761 if (len < NETROOM()) { 762 ring_supply_data(&netoring, temp, len); 763 printsub('>', temp+2, len - 2); 764 } 765 } 766 break; 767 case TELOPT_LFLOW: 768 if (my_want_state_is_wont(TELOPT_LFLOW)) 769 return; 770 if ((subbuffer[1]&0xff) == 1) { 771 localflow = 1; 772 } else if ((subbuffer[1]&0xff) == 0) { 773 localflow = 0; 774 } 775 setcommandmode(); 776 setconnmode(0); 777 break; 778 779 case TELOPT_LINEMODE: 780 if (my_want_state_is_wont(TELOPT_LINEMODE)) 781 return; 782 switch (subbuffer[1]&0xff) { 783 case WILL: 784 lm_will(&subbuffer[2], subend - &subbuffer[2]); 785 break; 786 case WONT: 787 lm_wont(&subbuffer[2], subend - &subbuffer[2]); 788 break; 789 case DO: 790 lm_do(&subbuffer[2], subend - &subbuffer[2]); 791 break; 792 case DONT: 793 lm_dont(&subbuffer[2], subend - &subbuffer[2]); 794 break; 795 case LM_SLC: 796 slc(&subbuffer[2], subend - &subbuffer[2]); 797 break; 798 case LM_MODE: 799 lm_mode(&subbuffer[2], subend - &subbuffer[2], 0); 800 break; 801 default: 802 break; 803 } 804 805 #ifdef KERBEROS 806 case TELOPT_AUTHENTICATION: 807 if ((subbuffer[1] & 0xff) == TELQUAL_SEND) { 808 register char *cp = &subbuffer[2]; 809 char tmp[256]; 810 int dokrb4 = 0, unknowntypes = 0, noresponse = 1; 811 812 while (cp < subend) { 813 switch (*cp) { 814 case TELQUAL_AUTHTYPE_KERBEROS_V4: 815 dokrb4 = 1; 816 break; 817 default: 818 unknowntypes++; 819 } 820 cp++; 821 } 822 823 if (noresponse && dokrb4) { 824 register unsigned char *ucp = (unsigned char *)cp; 825 char *krb_realm; 826 char hst_inst[INST_SZ]; 827 KTEXT_ST authent_st; 828 int space = 0; 829 int retval; 830 extern char *krb_realmofhost(), *krb_get_phost(); 831 832 fprintf(stderr, 833 "[Trying Kerberos V4 authentication]\n"); 834 835 krb_realm = krb_get_phost(hostname); 836 bzero(hst_inst, sizeof(hst_inst)); 837 if (krb_realm) 838 strncpy(hst_inst, krb_realm, sizeof(hst_inst)); 839 hst_inst[sizeof(hst_inst)-1] = '\0'; 840 if (!(krb_realm = krb_realmofhost(hst_inst))) { 841 fprintf(stderr, "no realm for %s\n", hostname); 842 goto cantsend4; 843 } 844 if (retval = krb_mk_req(&authent_st, "rcmd", hst_inst, 845 krb_realm, 0L)) { 846 fprintf(stderr, "mk_req failed: %s\n", 847 krb_err_txt[retval]); 848 goto cantsend4; 849 } 850 space = authent_st.length; 851 for (ucp = authent_st.dat; ucp < authent_st.dat + 852 authent_st.length; ucp++) { 853 if (*ucp == IAC) 854 space++; 855 } 856 if (NETROOM() < 6 + 1 + 2 + 857 space + 2) { 858 fprintf(stderr, 859 "no room to send V4 ticket/authenticator\n"); 860 cantsend4: 861 if (7 < NETROOM()) { 862 printring(&netoring, "%c%c%c%c%c%c%c", IAC, SB, 863 TELOPT_AUTHENTICATION, 864 TELQUAL_IS, TELQUAL_AUTHTYPE_NONE, IAC, SE); 865 sprintf(tmp, "%c%c%c%c%c", TELOPT_AUTHENTICATION, 866 TELQUAL_IS, TELQUAL_AUTHTYPE_NONE, IAC, SE); 867 printsub(">", tmp, 4+2-2-2); 868 } else 869 exit(1); 870 } else { 871 #ifdef notdef 872 printring(&netoring, "%c%c%c%c%c%c", IAC, SB, 873 TELOPT_AUTHENTICATION, 874 TELQUAL_IS, TELQUAL_AUTHTYPE_KERBEROS, 875 TELQUAL_AUTHTYPE_KERBEROS_V4); 876 sprintf(tmp, "%c%c%c%c%c%c", TELOPT_AUTHENTICATION, 877 TELQUAL_IS, TELQUAL_AUTHTYPE_KERBEROS, 878 TELQUAL_AUTHTYPE_KERBEROS_V4, IAC, SE); 879 #else 880 printring(&netoring, "%c%c%c%c%c", IAC, SB, 881 TELOPT_AUTHENTICATION, 882 TELQUAL_IS, 883 TELQUAL_AUTHTYPE_KERBEROS_V4); 884 sprintf(tmp, "%c%c%c%c%c", TELOPT_AUTHENTICATION, 885 TELQUAL_IS, 886 TELQUAL_AUTHTYPE_KERBEROS_V4, IAC, SE); 887 #endif 888 printsub(">", tmp, 4+2-2-2); 889 ring_supply_bindata(&netoring, 890 (char *)authent_st.dat, authent_st.length, IAC); 891 printring(&netoring, "%c%c", IAC, SE); 892 } 893 noresponse = 0; 894 } 895 if (noresponse) { 896 if (NETROOM() < 7) { 897 ExitString("not enough room to reject unhandled authtype\n", 1); 898 } else { 899 fprintf(stderr,"[Sending empty auth info in response to request for %d unknown type(s):\n\t", unknowntypes); 900 #ifdef notdef 901 cp = &subbuffer[3]; 902 #else 903 cp = &subbuffer[2]; 904 #endif 905 while (cp < subend) { 906 switch (*cp) { 907 case TELQUAL_AUTHTYPE_KERBEROS_V4: 908 break; 909 default: 910 fprintf(stderr, "%d,", *cp); 911 break; 912 } 913 cp++; 914 } 915 fputs("]\n", stderr); 916 printring(&netoring, "%c%c%c%c%c%c%c", IAC, SB, 917 TELOPT_AUTHENTICATION, 918 TELQUAL_IS, TELQUAL_AUTHTYPE_NONE, IAC, SE); 919 } 920 } 921 } 922 break; 923 #endif /* KERBEROS */ 924 default: 925 break; 926 } 927 } 928 929 static char str_lm[] = { IAC, SB, TELOPT_LINEMODE, 0, 0, IAC, SE }; 930 931 lm_will(cmd, len) 932 char *cmd; 933 { 934 switch(cmd[0]) { 935 case LM_FORWARDMASK: /* We shouldn't ever get this... */ 936 default: 937 str_lm[3] = DONT; 938 str_lm[4] = cmd[0]; 939 if (NETROOM() > sizeof(str_lm)) { 940 ring_supply_data(&netoring, str_lm, sizeof(str_lm)); 941 printsub('>', &str_lm[2], sizeof(str_lm)-2); 942 } 943 /*@*/ else printf("lm_will: not enough room in buffer\n"); 944 break; 945 } 946 } 947 948 lm_wont(cmd, len) 949 char *cmd; 950 { 951 switch(cmd[0]) { 952 case LM_FORWARDMASK: /* We shouldn't ever get this... */ 953 default: 954 /* We are always DONT, so don't respond */ 955 return; 956 } 957 } 958 959 lm_do(cmd, len) 960 char *cmd; 961 { 962 switch(cmd[0]) { 963 case LM_FORWARDMASK: 964 default: 965 str_lm[3] = WONT; 966 str_lm[4] = cmd[0]; 967 if (NETROOM() > sizeof(str_lm)) { 968 ring_supply_data(&netoring, str_lm, sizeof(str_lm)); 969 printsub('>', &str_lm[2], sizeof(str_lm)-2); 970 } 971 /*@*/ else printf("lm_do: not enough room in buffer\n"); 972 break; 973 } 974 } 975 976 lm_dont(cmd, len) 977 char *cmd; 978 { 979 switch(cmd[0]) { 980 case LM_FORWARDMASK: 981 default: 982 /* we are always WONT, so don't respond */ 983 break; 984 } 985 } 986 987 static char str_lm_mode[] = { IAC, SB, TELOPT_LINEMODE, LM_MODE, 0, IAC, SE }; 988 989 lm_mode(cmd, len, init) 990 char *cmd; 991 int len, init; 992 { 993 if (len != 1) 994 return; 995 if ((linemode&(MODE_EDIT|MODE_TRAPSIG)) == *cmd) 996 return; 997 if (*cmd&MODE_ACK) 998 return; 999 linemode = (*cmd&(MODE_EDIT|MODE_TRAPSIG)); 1000 str_lm_mode[4] = linemode; 1001 if (!init) 1002 str_lm_mode[4] |= MODE_ACK; 1003 if (NETROOM() > sizeof(str_lm_mode)) { 1004 ring_supply_data(&netoring, str_lm_mode, sizeof(str_lm_mode)); 1005 printsub('>', &str_lm_mode[2], sizeof(str_lm_mode)-2); 1006 } 1007 /*@*/ else printf("lm_mode: not enough room in buffer\n"); 1008 setconnmode(0); /* set changed mode */ 1009 } 1010 1011 1012 1013 /* 1014 * slc() 1015 * Handle special character suboption of LINEMODE. 1016 */ 1017 1018 struct spc { 1019 cc_t val; 1020 cc_t *valp; 1021 char flags; /* Current flags & level */ 1022 char mylevel; /* Maximum level & flags */ 1023 } spc_data[NSLC+1]; 1024 1025 #define SLC_IMPORT 0 1026 #define SLC_EXPORT 1 1027 #define SLC_RVALUE 2 1028 static int slc_mode = SLC_EXPORT; 1029 1030 slc_init() 1031 { 1032 register struct spc *spcp; 1033 extern cc_t *tcval(); 1034 1035 localchars = 1; 1036 for (spcp = spc_data; spcp < &spc_data[NSLC+1]; spcp++) { 1037 spcp->val = 0; 1038 spcp->valp = 0; 1039 spcp->flags = spcp->mylevel = SLC_NOSUPPORT; 1040 } 1041 1042 #define initfunc(func, flags) { \ 1043 spcp = &spc_data[func]; \ 1044 if (spcp->valp = tcval(func)) { \ 1045 spcp->val = *spcp->valp; \ 1046 spcp->mylevel = SLC_VARIABLE|flags; \ 1047 } else { \ 1048 spcp->val = 0; \ 1049 spcp->mylevel = SLC_DEFAULT; \ 1050 } \ 1051 } 1052 1053 initfunc(SLC_SYNCH, 0); 1054 /* No BRK */ 1055 initfunc(SLC_AO, 0); 1056 initfunc(SLC_AYT, 0); 1057 /* No EOR */ 1058 initfunc(SLC_ABORT, SLC_FLUSHIN|SLC_FLUSHOUT); 1059 initfunc(SLC_EOF, 0); 1060 #ifndef SYSV_TERMIO 1061 initfunc(SLC_SUSP, SLC_FLUSHIN); 1062 #endif 1063 initfunc(SLC_EC, 0); 1064 initfunc(SLC_EL, 0); 1065 #ifndef SYSV_TERMIO 1066 initfunc(SLC_EW, 0); 1067 initfunc(SLC_RP, 0); 1068 initfunc(SLC_LNEXT, 0); 1069 #endif 1070 initfunc(SLC_XON, 0); 1071 initfunc(SLC_XOFF, 0); 1072 #ifdef SYSV_TERMIO 1073 spc_data[SLC_XON].mylevel = SLC_CANTCHANGE; 1074 spc_data[SLC_XOFF].mylevel = SLC_CANTCHANGE; 1075 #endif 1076 /* No FORW1 */ 1077 /* No FORW2 */ 1078 1079 initfunc(SLC_IP, SLC_FLUSHIN|SLC_FLUSHOUT); 1080 #undef initfunc 1081 1082 if (slc_mode == SLC_EXPORT) 1083 slc_export(); 1084 else 1085 slc_import(1); 1086 1087 } 1088 1089 slcstate() 1090 { 1091 printf("Special characters are %s values\n", 1092 slc_mode == SLC_IMPORT ? "remote default" : 1093 slc_mode == SLC_EXPORT ? "local" : 1094 "remote"); 1095 } 1096 1097 slc_mode_export() 1098 { 1099 slc_mode = SLC_EXPORT; 1100 if (my_state_is_will(TELOPT_LINEMODE)) 1101 slc_export(); 1102 } 1103 1104 slc_mode_import(def) 1105 { 1106 slc_mode = def ? SLC_IMPORT : SLC_RVALUE; 1107 if (my_state_is_will(TELOPT_LINEMODE)) 1108 slc_import(def); 1109 } 1110 1111 char slc_import_val[] = { 1112 IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE 1113 }; 1114 char slc_import_def[] = { 1115 IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE 1116 }; 1117 1118 slc_import(def) 1119 int def; 1120 { 1121 if (NETROOM() > sizeof(slc_import_val)) { 1122 if (def) { 1123 ring_supply_data(&netoring, slc_import_def, sizeof(slc_import_def)); 1124 printsub('>', &slc_import_def[2], sizeof(slc_import_def)-2); 1125 } else { 1126 ring_supply_data(&netoring, slc_import_val, sizeof(slc_import_val)); 1127 printsub('>', &slc_import_val[2], sizeof(slc_import_val)-2); 1128 } 1129 } 1130 /*@*/ else printf("slc_import: not enough room\n"); 1131 } 1132 1133 slc_export() 1134 { 1135 register struct spc *spcp; 1136 1137 TerminalDefaultChars(); 1138 1139 slc_start_reply(); 1140 for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) { 1141 if (spcp->mylevel != SLC_NOSUPPORT) { 1142 spcp->flags = spcp->mylevel; 1143 if (spcp->valp) 1144 spcp->val = *spcp->valp; 1145 slc_add_reply(spcp - spc_data, spcp->mylevel, spcp->val); 1146 } 1147 } 1148 slc_end_reply(); 1149 if (slc_update()) 1150 setconnmode(1); /* set the new character values */ 1151 } 1152 1153 slc(cp, len) 1154 register char *cp; 1155 int len; 1156 { 1157 register struct spc *spcp; 1158 register int func,level; 1159 1160 slc_start_reply(); 1161 1162 for (; len >= 3; len -=3, cp +=3) { 1163 1164 func = cp[SLC_FUNC]; 1165 1166 if (func == 0) { 1167 /* 1168 * Client side: always ignore 0 function. 1169 */ 1170 continue; 1171 } 1172 if (func > NSLC) { 1173 if (cp[SLC_FLAGS] & SLC_LEVELBITS != SLC_NOSUPPORT) 1174 slc_add_reply(func, SLC_NOSUPPORT, 0); 1175 continue; 1176 } 1177 1178 spcp = &spc_data[func]; 1179 1180 level = cp[SLC_FLAGS]&(SLC_LEVELBITS|SLC_ACK); 1181 1182 if ((cp[SLC_VALUE] == (unsigned char)spcp->val) && 1183 ((level&SLC_LEVELBITS) == (spcp->flags&SLC_LEVELBITS))) { 1184 continue; 1185 } 1186 1187 if (level == (SLC_DEFAULT|SLC_ACK)) { 1188 /* 1189 * This is an error condition, the SLC_ACK 1190 * bit should never be set for the SLC_DEFAULT 1191 * level. Our best guess to recover is to 1192 * ignore the SLC_ACK bit. 1193 */ 1194 cp[SLC_FLAGS] &= ~SLC_ACK; 1195 } 1196 1197 if (level == ((spcp->flags&SLC_LEVELBITS)|SLC_ACK)) { 1198 spcp->val = (cc_t)cp[SLC_VALUE]; 1199 spcp->flags = cp[SLC_FLAGS]; /* include SLC_ACK */ 1200 continue; 1201 } 1202 1203 level &= ~SLC_ACK; 1204 1205 if (level <= (spcp->mylevel&SLC_LEVELBITS)) { 1206 spcp->flags = cp[SLC_FLAGS]|SLC_ACK; 1207 spcp->val = (cc_t)cp[SLC_VALUE]; 1208 } 1209 if (level == SLC_DEFAULT) { 1210 if ((spcp->mylevel&SLC_LEVELBITS) != SLC_DEFAULT) 1211 spcp->flags = spcp->mylevel; 1212 else 1213 spcp->flags = SLC_NOSUPPORT; 1214 } 1215 slc_add_reply(func, spcp->flags, spcp->val); 1216 } 1217 slc_end_reply(); 1218 if (slc_update()) 1219 setconnmode(1); /* set the new character values */ 1220 } 1221 1222 slc_check() 1223 { 1224 register struct spc *spcp; 1225 1226 slc_start_reply(); 1227 for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) { 1228 if (spcp->valp && spcp->val != *spcp->valp) { 1229 spcp->val = *spcp->valp; 1230 slc_add_reply(spcp - spc_data, spcp->mylevel, spcp->val); 1231 } 1232 } 1233 slc_end_reply(); 1234 setconnmode(1); 1235 } 1236 1237 1238 unsigned char slc_reply[128]; 1239 unsigned char *slc_replyp; 1240 slc_start_reply() 1241 { 1242 slc_replyp = slc_reply; 1243 *slc_replyp++ = IAC; 1244 *slc_replyp++ = SB; 1245 *slc_replyp++ = TELOPT_LINEMODE; 1246 *slc_replyp++ = LM_SLC; 1247 } 1248 1249 slc_add_reply(func, flags, value) 1250 char func; 1251 char flags; 1252 cc_t value; 1253 { 1254 if ((*slc_replyp++ = func) == IAC) 1255 *slc_replyp++ = IAC; 1256 if ((*slc_replyp++ = flags) == IAC) 1257 *slc_replyp++ = IAC; 1258 if ((*slc_replyp++ = (unsigned char)value) == IAC) 1259 *slc_replyp++ = IAC; 1260 } 1261 1262 slc_end_reply() 1263 { 1264 register char *cp; 1265 register int len; 1266 1267 *slc_replyp++ = IAC; 1268 *slc_replyp++ = SE; 1269 len = slc_replyp - slc_reply; 1270 if (len <= 6) 1271 return; 1272 if (NETROOM() > len) { 1273 ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply); 1274 printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2); 1275 } 1276 /*@*/else printf("slc_end_reply: not enough room\n"); 1277 } 1278 1279 slc_update() 1280 { 1281 register struct spc *spcp; 1282 int need_update = 0; 1283 1284 for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) { 1285 if (!(spcp->flags&SLC_ACK)) 1286 continue; 1287 spcp->flags &= ~SLC_ACK; 1288 if (spcp->valp && (*spcp->valp != spcp->val)) { 1289 *spcp->valp = spcp->val; 1290 need_update = 1; 1291 } 1292 } 1293 return(need_update); 1294 } 1295 1296 1297 1298 int 1299 telrcv() 1300 { 1301 register int c; 1302 register int scc; 1303 register char *sbp; 1304 int count; 1305 int returnValue = 0; 1306 1307 scc = 0; 1308 count = 0; 1309 while (TTYROOM() > 2) { 1310 if (scc == 0) { 1311 if (count) { 1312 ring_consumed(&netiring, count); 1313 returnValue = 1; 1314 count = 0; 1315 } 1316 sbp = netiring.consume; 1317 scc = ring_full_consecutive(&netiring); 1318 if (scc == 0) { 1319 /* No more data coming in */ 1320 break; 1321 } 1322 } 1323 1324 c = *sbp++ & 0xff, scc--; count++; 1325 1326 switch (telrcv_state) { 1327 1328 case TS_CR: 1329 telrcv_state = TS_DATA; 1330 if (c == '\0') { 1331 break; /* Ignore \0 after CR */ 1332 } 1333 else if ((c == '\n') && my_want_state_is_dont(TELOPT_ECHO) && !crmod) { 1334 TTYADD(c); 1335 break; 1336 } 1337 /* Else, fall through */ 1338 1339 case TS_DATA: 1340 if (c == IAC) { 1341 telrcv_state = TS_IAC; 1342 break; 1343 } 1344 # if defined(TN3270) 1345 if (In3270) { 1346 *Ifrontp++ = c; 1347 while (scc > 0) { 1348 c = *sbp++ & 0377, scc--; count++; 1349 if (c == IAC) { 1350 telrcv_state = TS_IAC; 1351 break; 1352 } 1353 *Ifrontp++ = c; 1354 } 1355 } else 1356 # endif /* defined(TN3270) */ 1357 /* 1358 * The 'crmod' hack (see following) is needed 1359 * since we can't * set CRMOD on output only. 1360 * Machines like MULTICS like to send \r without 1361 * \n; since we must turn off CRMOD to get proper 1362 * input, the mapping is done here (sigh). 1363 */ 1364 if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) { 1365 if (scc > 0) { 1366 c = *sbp&0xff; 1367 if (c == 0) { 1368 sbp++, scc--; count++; 1369 /* a "true" CR */ 1370 TTYADD('\r'); 1371 } else if (my_want_state_is_dont(TELOPT_ECHO) && 1372 (c == '\n')) { 1373 sbp++, scc--; count++; 1374 TTYADD('\n'); 1375 } else { 1376 TTYADD('\r'); 1377 if (crmod) { 1378 TTYADD('\n'); 1379 } 1380 } 1381 } else { 1382 telrcv_state = TS_CR; 1383 TTYADD('\r'); 1384 if (crmod) { 1385 TTYADD('\n'); 1386 } 1387 } 1388 } else { 1389 TTYADD(c); 1390 } 1391 continue; 1392 1393 case TS_IAC: 1394 process_iac: 1395 switch (c) { 1396 1397 case WILL: 1398 telrcv_state = TS_WILL; 1399 continue; 1400 1401 case WONT: 1402 telrcv_state = TS_WONT; 1403 continue; 1404 1405 case DO: 1406 telrcv_state = TS_DO; 1407 continue; 1408 1409 case DONT: 1410 telrcv_state = TS_DONT; 1411 continue; 1412 1413 case DM: 1414 /* 1415 * We may have missed an urgent notification, 1416 * so make sure we flush whatever is in the 1417 * buffer currently. 1418 */ 1419 SYNCHing = 1; 1420 ttyflush(1); 1421 SYNCHing = stilloob(); 1422 settimer(gotDM); 1423 break; 1424 1425 case NOP: 1426 case GA: 1427 break; 1428 1429 case SB: 1430 SB_CLEAR(); 1431 telrcv_state = TS_SB; 1432 printoption("RCVD", "IAC", SB); 1433 continue; 1434 1435 # if defined(TN3270) 1436 case EOR: 1437 if (In3270) { 1438 Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, 1); 1439 if (Ibackp == Ifrontp) { 1440 Ibackp = Ifrontp = Ibuf; 1441 ISend = 0; /* should have been! */ 1442 } else { 1443 ISend = 1; 1444 } 1445 } 1446 break; 1447 # endif /* defined(TN3270) */ 1448 1449 case IAC: 1450 # if !defined(TN3270) 1451 TTYADD(IAC); 1452 # else /* !defined(TN3270) */ 1453 if (In3270) { 1454 *Ifrontp++ = IAC; 1455 } else { 1456 TTYADD(IAC); 1457 } 1458 # endif /* !defined(TN3270) */ 1459 break; 1460 1461 default: 1462 break; 1463 } 1464 telrcv_state = TS_DATA; 1465 continue; 1466 1467 case TS_WILL: 1468 printoption("RCVD", "will", c); 1469 willoption(c); 1470 SetIn3270(); 1471 telrcv_state = TS_DATA; 1472 continue; 1473 1474 case TS_WONT: 1475 printoption("RCVD", "wont", c); 1476 wontoption(c); 1477 SetIn3270(); 1478 telrcv_state = TS_DATA; 1479 continue; 1480 1481 case TS_DO: 1482 printoption("RCVD", "do", c); 1483 dooption(c); 1484 SetIn3270(); 1485 if (c == TELOPT_NAWS) { 1486 sendnaws(); 1487 } else if (c == TELOPT_LFLOW) { 1488 localflow = 1; 1489 setcommandmode(); 1490 setconnmode(0); 1491 } 1492 telrcv_state = TS_DATA; 1493 continue; 1494 1495 case TS_DONT: 1496 printoption("RCVD", "dont", c); 1497 dontoption(c); 1498 flushline = 1; 1499 setconnmode(0); /* set new tty mode (maybe) */ 1500 SetIn3270(); 1501 telrcv_state = TS_DATA; 1502 continue; 1503 1504 case TS_SB: 1505 if (c == IAC) { 1506 telrcv_state = TS_SE; 1507 } else { 1508 SB_ACCUM(c); 1509 } 1510 continue; 1511 1512 case TS_SE: 1513 if (c != SE) { 1514 if (c != IAC) { 1515 /* 1516 * This is an error. We only expect to get 1517 * "IAC IAC" or "IAC SE". Several things may 1518 * have happend. An IAC was not doubled, the 1519 * IAC SE was left off, or another option got 1520 * inserted into the suboption are all possibilities. 1521 * If we assume that the IAC was not doubled, 1522 * and really the IAC SE was left off, we could 1523 * get into an infinate loop here. So, instead, 1524 * we terminate the suboption, and process the 1525 * partial suboption if we can. 1526 */ 1527 SB_TERM(); 1528 SB_ACCUM(IAC); 1529 SB_ACCUM(c); 1530 printoption("In SUBOPTION processing, RCVD", "IAC", c); 1531 suboption(); /* handle sub-option */ 1532 SetIn3270(); 1533 telrcv_state = TS_IAC; 1534 goto process_iac; 1535 } 1536 SB_ACCUM(c); 1537 telrcv_state = TS_SB; 1538 } else { 1539 SB_TERM(); 1540 SB_ACCUM(IAC); 1541 SB_ACCUM(SE); 1542 suboption(); /* handle sub-option */ 1543 SetIn3270(); 1544 telrcv_state = TS_DATA; 1545 } 1546 } 1547 } 1548 if (count) 1549 ring_consumed(&netiring, count); 1550 return returnValue||count; 1551 } 1552 1553 static int 1554 telsnd() 1555 { 1556 int tcc; 1557 int count; 1558 int returnValue = 0; 1559 char *tbp; 1560 1561 tcc = 0; 1562 count = 0; 1563 while (NETROOM() > 2) { 1564 register int sc; 1565 register int c; 1566 1567 if (tcc == 0) { 1568 if (count) { 1569 ring_consumed(&ttyiring, count); 1570 returnValue = 1; 1571 count = 0; 1572 } 1573 tbp = ttyiring.consume; 1574 tcc = ring_full_consecutive(&ttyiring); 1575 if (tcc == 0) { 1576 break; 1577 } 1578 } 1579 c = *tbp++ & 0xff, sc = strip(c), tcc--; count++; 1580 if (sc == escape) { 1581 /* 1582 * Double escape is a pass through of a single escape character. 1583 */ 1584 if (tcc && strip(*tbp) == escape) { 1585 tbp++; 1586 tcc--; 1587 count++; 1588 } else { 1589 command(0, tbp, tcc); 1590 count += tcc; 1591 tcc = 0; 1592 flushline = 1; 1593 break; 1594 } 1595 } 1596 #ifdef KLUDGELINEMODE 1597 if (kludgelinemode && (globalmode&MODE_EDIT) && (sc == echoc)) { 1598 if (tcc > 0 && strip(*tbp) == echoc) { 1599 tcc--; tbp++; count++; 1600 } else { 1601 dontlecho = !dontlecho; 1602 settimer(echotoggle); 1603 setconnmode(0); 1604 flushline = 1; 1605 break; 1606 } 1607 } 1608 #endif 1609 if (MODE_LOCAL_CHARS(globalmode)) { 1610 if (TerminalSpecialChars(sc) == 0) { 1611 break; 1612 } 1613 } 1614 if (my_want_state_is_wont(TELOPT_BINARY)) { 1615 switch (c) { 1616 case '\n': 1617 /* 1618 * If we are in CRMOD mode (\r ==> \n) 1619 * on our local machine, then probably 1620 * a newline (unix) is CRLF (TELNET). 1621 */ 1622 if (MODE_LOCAL_CHARS(globalmode)) { 1623 NETADD('\r'); 1624 } 1625 NETADD('\n'); 1626 flushline = 1; 1627 break; 1628 case '\r': 1629 if (!crlf) { 1630 NET2ADD('\r', '\0'); 1631 } else { 1632 NET2ADD('\r', '\n'); 1633 } 1634 flushline = 1; 1635 break; 1636 case IAC: 1637 NET2ADD(IAC, IAC); 1638 break; 1639 default: 1640 NETADD(c); 1641 break; 1642 } 1643 } else if (c == IAC) { 1644 NET2ADD(IAC, IAC); 1645 } else { 1646 NETADD(c); 1647 } 1648 } 1649 if (count) 1650 ring_consumed(&ttyiring, count); 1651 return returnValue||count; /* Non-zero if we did anything */ 1652 } 1653 1654 /* 1655 * Scheduler() 1656 * 1657 * Try to do something. 1658 * 1659 * If we do something useful, return 1; else return 0. 1660 * 1661 */ 1662 1663 1664 int 1665 Scheduler(block) 1666 int block; /* should we block in the select ? */ 1667 { 1668 /* One wants to be a bit careful about setting returnValue 1669 * to one, since a one implies we did some useful work, 1670 * and therefore probably won't be called to block next 1671 * time (TN3270 mode only). 1672 */ 1673 int returnValue; 1674 int netin, netout, netex, ttyin, ttyout; 1675 1676 /* Decide which rings should be processed */ 1677 1678 netout = ring_full_count(&netoring) && 1679 (flushline || 1680 (my_want_state_is_wont(TELOPT_LINEMODE) 1681 #ifdef KLUDGELINEMODE 1682 && (!kludgelinemode || my_want_state_is_do(TELOPT_SGA)) 1683 #endif 1684 ) || 1685 my_want_state_is_will(TELOPT_BINARY)); 1686 ttyout = ring_full_count(&ttyoring); 1687 1688 #if defined(TN3270) 1689 ttyin = ring_empty_count(&ttyiring) && (shell_active == 0); 1690 #else /* defined(TN3270) */ 1691 ttyin = ring_empty_count(&ttyiring); 1692 #endif /* defined(TN3270) */ 1693 1694 #if defined(TN3270) 1695 netin = ring_empty_count(&netiring); 1696 # else /* !defined(TN3270) */ 1697 netin = !ISend && ring_empty_count(&netiring); 1698 # endif /* !defined(TN3270) */ 1699 1700 netex = !SYNCHing; 1701 1702 /* If we have seen a signal recently, reset things */ 1703 # if defined(TN3270) && defined(unix) 1704 if (HaveInput) { 1705 HaveInput = 0; 1706 signal(SIGIO, inputAvailable); 1707 } 1708 #endif /* defined(TN3270) && defined(unix) */ 1709 1710 /* Call to system code to process rings */ 1711 1712 returnValue = process_rings(netin, netout, netex, ttyin, ttyout, !block); 1713 1714 /* Now, look at the input rings, looking for work to do. */ 1715 1716 if (ring_full_count(&ttyiring)) { 1717 # if defined(TN3270) 1718 if (In3270) { 1719 int c; 1720 1721 c = DataFromTerminal(ttyiring.consume, 1722 ring_full_consecutive(&ttyiring)); 1723 if (c) { 1724 returnValue = 1; 1725 ring_consumed(&ttyiring, c); 1726 } 1727 } else { 1728 # endif /* defined(TN3270) */ 1729 returnValue |= telsnd(); 1730 # if defined(TN3270) 1731 } 1732 # endif /* defined(TN3270) */ 1733 } 1734 1735 if (ring_full_count(&netiring)) { 1736 # if !defined(TN3270) 1737 returnValue |= telrcv(); 1738 # else /* !defined(TN3270) */ 1739 returnValue = Push3270(); 1740 # endif /* !defined(TN3270) */ 1741 } 1742 return returnValue; 1743 } 1744 1745 /* 1746 * Select from tty and network... 1747 */ 1748 void 1749 telnet() 1750 { 1751 sys_telnet_init(); 1752 1753 # if !defined(TN3270) 1754 if (telnetport) { 1755 send_do(TELOPT_SGA, 1); 1756 send_will(TELOPT_TTYPE, 1); 1757 send_will(TELOPT_NAWS, 1); 1758 send_will(TELOPT_TSPEED, 1); 1759 send_will(TELOPT_LFLOW, 1); 1760 send_will(TELOPT_LINEMODE, 1); 1761 #ifdef KERBEROS 1762 if (kerberized) 1763 send_will(TELOPT_AUTHENTICATION, 1); 1764 #endif 1765 send_do(TELOPT_STATUS, 1); 1766 } 1767 # endif /* !defined(TN3270) */ 1768 1769 # if !defined(TN3270) 1770 for (;;) { 1771 int schedValue; 1772 1773 while ((schedValue = Scheduler(0)) != 0) { 1774 if (schedValue == -1) { 1775 setcommandmode(); 1776 return; 1777 } 1778 } 1779 1780 if (Scheduler(1) == -1) { 1781 setcommandmode(); 1782 return; 1783 } 1784 } 1785 # else /* !defined(TN3270) */ 1786 for (;;) { 1787 int schedValue; 1788 1789 while (!In3270 && !shell_active) { 1790 if (Scheduler(1) == -1) { 1791 setcommandmode(); 1792 return; 1793 } 1794 } 1795 1796 while ((schedValue = Scheduler(0)) != 0) { 1797 if (schedValue == -1) { 1798 setcommandmode(); 1799 return; 1800 } 1801 } 1802 /* If there is data waiting to go out to terminal, don't 1803 * schedule any more data for the terminal. 1804 */ 1805 if (ring_full_count(&ttyoring)) { 1806 schedValue = 1; 1807 } else { 1808 if (shell_active) { 1809 if (shell_continue() == 0) { 1810 ConnectScreen(); 1811 } 1812 } else if (In3270) { 1813 schedValue = DoTerminalOutput(); 1814 } 1815 } 1816 if (schedValue && (shell_active == 0)) { 1817 if (Scheduler(1) == -1) { 1818 setcommandmode(); 1819 return; 1820 } 1821 } 1822 } 1823 # endif /* !defined(TN3270) */ 1824 } 1825 1826 #if 0 /* XXX - this not being in is a bug */ 1827 /* 1828 * nextitem() 1829 * 1830 * Return the address of the next "item" in the TELNET data 1831 * stream. This will be the address of the next character if 1832 * the current address is a user data character, or it will 1833 * be the address of the character following the TELNET command 1834 * if the current address is a TELNET IAC ("I Am a Command") 1835 * character. 1836 */ 1837 1838 static char * 1839 nextitem(current) 1840 char *current; 1841 { 1842 if ((*current&0xff) != IAC) { 1843 return current+1; 1844 } 1845 switch (*(current+1)&0xff) { 1846 case DO: 1847 case DONT: 1848 case WILL: 1849 case WONT: 1850 return current+3; 1851 case SB: /* loop forever looking for the SE */ 1852 { 1853 register char *look = current+2; 1854 1855 for (;;) { 1856 if ((*look++&0xff) == IAC) { 1857 if ((*look++&0xff) == SE) { 1858 return look; 1859 } 1860 } 1861 } 1862 } 1863 default: 1864 return current+2; 1865 } 1866 } 1867 #endif /* 0 */ 1868 1869 /* 1870 * netclear() 1871 * 1872 * We are about to do a TELNET SYNCH operation. Clear 1873 * the path to the network. 1874 * 1875 * Things are a bit tricky since we may have sent the first 1876 * byte or so of a previous TELNET command into the network. 1877 * So, we have to scan the network buffer from the beginning 1878 * until we are up to where we want to be. 1879 * 1880 * A side effect of what we do, just to keep things 1881 * simple, is to clear the urgent data pointer. The principal 1882 * caller should be setting the urgent data pointer AFTER calling 1883 * us in any case. 1884 */ 1885 1886 static void 1887 netclear() 1888 { 1889 #if 0 /* XXX */ 1890 register char *thisitem, *next; 1891 char *good; 1892 #define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \ 1893 ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) 1894 1895 thisitem = netobuf; 1896 1897 while ((next = nextitem(thisitem)) <= netobuf.send) { 1898 thisitem = next; 1899 } 1900 1901 /* Now, thisitem is first before/at boundary. */ 1902 1903 good = netobuf; /* where the good bytes go */ 1904 1905 while (netoring.add > thisitem) { 1906 if (wewant(thisitem)) { 1907 int length; 1908 1909 next = thisitem; 1910 do { 1911 next = nextitem(next); 1912 } while (wewant(next) && (nfrontp > next)); 1913 length = next-thisitem; 1914 memcpy(good, thisitem, length); 1915 good += length; 1916 thisitem = next; 1917 } else { 1918 thisitem = nextitem(thisitem); 1919 } 1920 } 1921 1922 #endif /* 0 */ 1923 } 1924 1925 /* 1926 * These routines add various telnet commands to the data stream. 1927 */ 1928 1929 static void 1930 doflush() 1931 { 1932 NET2ADD(IAC, DO); 1933 NETADD(TELOPT_TM); 1934 flushline = 1; 1935 flushout = 1; 1936 ttyflush(1); /* Flush/drop output */ 1937 /* do printoption AFTER flush, otherwise the output gets tossed... */ 1938 printoption("SENT", "do", TELOPT_TM); 1939 } 1940 1941 void 1942 xmitAO() 1943 { 1944 NET2ADD(IAC, AO); 1945 printoption("SENT", "IAC", AO); 1946 if (autoflush) { 1947 doflush(); 1948 } 1949 } 1950 1951 1952 void 1953 xmitEL() 1954 { 1955 NET2ADD(IAC, EL); 1956 printoption("SENT", "IAC", EL); 1957 } 1958 1959 void 1960 xmitEC() 1961 { 1962 NET2ADD(IAC, EC); 1963 printoption("SENT", "IAC", EC); 1964 } 1965 1966 1967 #if defined(NOT43) 1968 int 1969 #else /* defined(NOT43) */ 1970 void 1971 #endif /* defined(NOT43) */ 1972 dosynch() 1973 { 1974 netclear(); /* clear the path to the network */ 1975 NETADD(IAC); 1976 setneturg(); 1977 NETADD(DM); 1978 printoption("SENT", "IAC", DM); 1979 1980 #if defined(NOT43) 1981 return 0; 1982 #endif /* defined(NOT43) */ 1983 } 1984 1985 void 1986 get_status() 1987 { 1988 char tmp[16]; 1989 register char *cp; 1990 1991 if (my_want_state_is_dont(TELOPT_STATUS)) { 1992 printf("Remote side does not support STATUS option\n"); 1993 return; 1994 } 1995 if (!showoptions) 1996 printf("You will not see the response unless you set \"options\"\n"); 1997 1998 cp = tmp; 1999 2000 *cp++ = IAC; 2001 *cp++ = SB; 2002 *cp++ = TELOPT_STATUS; 2003 *cp++ = TELQUAL_SEND; 2004 *cp++ = IAC; 2005 *cp++ = SE; 2006 if (NETROOM() >= cp - tmp) { 2007 ring_supply_data(&netoring, tmp, cp-tmp); 2008 printsub('>', tmp+2, cp - tmp - 2); 2009 } 2010 } 2011 2012 void 2013 intp() 2014 { 2015 NET2ADD(IAC, IP); 2016 printoption("SENT", "IAC", IP); 2017 flushline = 1; 2018 if (autoflush) { 2019 doflush(); 2020 } 2021 if (autosynch) { 2022 dosynch(); 2023 } 2024 } 2025 2026 void 2027 sendbrk() 2028 { 2029 NET2ADD(IAC, BREAK); 2030 printoption("SENT", "IAC", BREAK); 2031 flushline = 1; 2032 if (autoflush) { 2033 doflush(); 2034 } 2035 if (autosynch) { 2036 dosynch(); 2037 } 2038 } 2039 2040 void 2041 sendabort() 2042 { 2043 NET2ADD(IAC, ABORT); 2044 printoption("SENT", "IAC", ABORT); 2045 flushline = 1; 2046 if (autoflush) { 2047 doflush(); 2048 } 2049 if (autosynch) { 2050 dosynch(); 2051 } 2052 } 2053 2054 void 2055 sendsusp() 2056 { 2057 NET2ADD(IAC, SUSP); 2058 printoption("SENT", "IAC", SUSP); 2059 flushline = 1; 2060 if (autoflush) { 2061 doflush(); 2062 } 2063 if (autosynch) { 2064 dosynch(); 2065 } 2066 } 2067 2068 void 2069 sendeof() 2070 { 2071 NET2ADD(IAC, xEOF); 2072 printoption("SENT", "IAC", xEOF); 2073 } 2074 2075 /* 2076 * Send a window size update to the remote system. 2077 */ 2078 2079 void 2080 sendnaws() 2081 { 2082 long rows, cols; 2083 unsigned char tmp[16]; 2084 register unsigned char *cp; 2085 2086 if (my_state_is_wont(TELOPT_NAWS)) 2087 return; 2088 2089 #define PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \ 2090 if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; } 2091 2092 if (TerminalWindowSize(&rows, &cols) == 0) { /* Failed */ 2093 return; 2094 } 2095 2096 cp = tmp; 2097 2098 *cp++ = IAC; 2099 *cp++ = SB; 2100 *cp++ = TELOPT_NAWS; 2101 PUTSHORT(cp, cols); 2102 PUTSHORT(cp, rows); 2103 *cp++ = IAC; 2104 *cp++ = SE; 2105 if (NETROOM() >= cp - tmp) { 2106 ring_supply_data(&netoring, tmp, cp-tmp); 2107 printsub('>', tmp+2, cp - tmp - 2); 2108 } 2109 } 2110 2111 tel_enter_binary(rw) 2112 int rw; 2113 { 2114 if (rw&1) 2115 send_do(TELOPT_BINARY, 1); 2116 if (rw&2) 2117 send_will(TELOPT_BINARY, 1); 2118 } 2119 2120 tel_leave_binary(rw) 2121 int rw; 2122 { 2123 if (rw&1) 2124 send_dont(TELOPT_BINARY, 1); 2125 if (rw&2) 2126 send_wont(TELOPT_BINARY, 1); 2127 } 2128