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