1 /* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 05/30/95"; 10 #endif /* not lint */ 11 12 #define TELOPTS 13 #define TELCMDS 14 #define SLC_NAMES 15 #include <arpa/telnet.h> 16 #include <sys/types.h> 17 #include <sys/time.h> 18 19 #include <ctype.h> 20 21 #include "general.h" 22 23 #include "fdset.h" 24 25 #include "ring.h" 26 27 #include "defines.h" 28 29 #include "externs.h" 30 31 FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 32 int prettydump; 33 34 /* 35 * upcase() 36 * 37 * Upcase (in place) the argument. 38 */ 39 40 void 41 upcase(argument) 42 register char *argument; 43 { 44 register int c; 45 46 while ((c = *argument) != 0) { 47 if (islower(c)) { 48 *argument = toupper(c); 49 } 50 argument++; 51 } 52 } 53 54 /* 55 * SetSockOpt() 56 * 57 * Compensate for differences in 4.2 and 4.3 systems. 58 */ 59 60 int 61 SetSockOpt(fd, level, option, yesno) 62 int fd, level, option, yesno; 63 { 64 #ifndef NOT43 65 return setsockopt(fd, level, option, 66 (char *)&yesno, sizeof yesno); 67 #else /* NOT43 */ 68 if (yesno == 0) { /* Can't do that in 4.2! */ 69 fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 70 option); 71 return -1; 72 } 73 return setsockopt(fd, level, option, 0, 0); 74 #endif /* NOT43 */ 75 } 76 77 /* 78 * The following are routines used to print out debugging information. 79 */ 80 81 unsigned char NetTraceFile[256] = "(standard output)"; 82 83 void 84 SetNetTrace(file) 85 register char *file; 86 { 87 if (NetTrace && NetTrace != stdout) 88 fclose(NetTrace); 89 if (file && (strcmp(file, "-") != 0)) { 90 NetTrace = fopen(file, "w"); 91 if (NetTrace) { 92 strcpy((char *)NetTraceFile, file); 93 return; 94 } 95 fprintf(stderr, "Cannot open %s.\n", file); 96 } 97 NetTrace = stdout; 98 strcpy((char *)NetTraceFile, "(standard output)"); 99 } 100 101 void 102 Dump(direction, buffer, length) 103 char direction; 104 unsigned char *buffer; 105 int length; 106 { 107 # define BYTES_PER_LINE 32 108 # define min(x,y) ((x<y)? x:y) 109 unsigned char *pThis; 110 int offset; 111 extern pettydump; 112 113 offset = 0; 114 115 while (length) { 116 /* print one line */ 117 fprintf(NetTrace, "%c 0x%x\t", direction, offset); 118 pThis = buffer; 119 if (prettydump) { 120 buffer = buffer + min(length, BYTES_PER_LINE/2); 121 while (pThis < buffer) { 122 fprintf(NetTrace, "%c%.2x", 123 (((*pThis)&0xff) == 0xff) ? '*' : ' ', 124 (*pThis)&0xff); 125 pThis++; 126 } 127 length -= BYTES_PER_LINE/2; 128 offset += BYTES_PER_LINE/2; 129 } else { 130 buffer = buffer + min(length, BYTES_PER_LINE); 131 while (pThis < buffer) { 132 fprintf(NetTrace, "%.2x", (*pThis)&0xff); 133 pThis++; 134 } 135 length -= BYTES_PER_LINE; 136 offset += BYTES_PER_LINE; 137 } 138 if (NetTrace == stdout) { 139 fprintf(NetTrace, "\r\n"); 140 } else { 141 fprintf(NetTrace, "\n"); 142 } 143 if (length < 0) { 144 fflush(NetTrace); 145 return; 146 } 147 /* find next unique line */ 148 } 149 fflush(NetTrace); 150 } 151 152 153 void 154 printoption(direction, cmd, option) 155 char *direction; 156 int cmd, option; 157 { 158 if (!showoptions) 159 return; 160 if (cmd == IAC) { 161 if (TELCMD_OK(option)) 162 fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option)); 163 else 164 fprintf(NetTrace, "%s IAC %d", direction, option); 165 } else { 166 register char *fmt; 167 fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" : 168 (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0; 169 if (fmt) { 170 fprintf(NetTrace, "%s %s ", direction, fmt); 171 if (TELOPT_OK(option)) 172 fprintf(NetTrace, "%s", TELOPT(option)); 173 else if (option == TELOPT_EXOPL) 174 fprintf(NetTrace, "EXOPL"); 175 else 176 fprintf(NetTrace, "%d", option); 177 } else 178 fprintf(NetTrace, "%s %d %d", direction, cmd, option); 179 } 180 if (NetTrace == stdout) { 181 fprintf(NetTrace, "\r\n"); 182 fflush(NetTrace); 183 } else { 184 fprintf(NetTrace, "\n"); 185 } 186 return; 187 } 188 189 void 190 optionstatus() 191 { 192 register int i; 193 extern char will_wont_resp[], do_dont_resp[]; 194 195 for (i = 0; i < 256; i++) { 196 if (do_dont_resp[i]) { 197 if (TELOPT_OK(i)) 198 printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 199 else if (TELCMD_OK(i)) 200 printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 201 else 202 printf("resp DO_DONT %d: %d\n", i, 203 do_dont_resp[i]); 204 if (my_want_state_is_do(i)) { 205 if (TELOPT_OK(i)) 206 printf("want DO %s\n", TELOPT(i)); 207 else if (TELCMD_OK(i)) 208 printf("want DO %s\n", TELCMD(i)); 209 else 210 printf("want DO %d\n", i); 211 } else { 212 if (TELOPT_OK(i)) 213 printf("want DONT %s\n", TELOPT(i)); 214 else if (TELCMD_OK(i)) 215 printf("want DONT %s\n", TELCMD(i)); 216 else 217 printf("want DONT %d\n", i); 218 } 219 } else { 220 if (my_state_is_do(i)) { 221 if (TELOPT_OK(i)) 222 printf(" DO %s\n", TELOPT(i)); 223 else if (TELCMD_OK(i)) 224 printf(" DO %s\n", TELCMD(i)); 225 else 226 printf(" DO %d\n", i); 227 } 228 } 229 if (will_wont_resp[i]) { 230 if (TELOPT_OK(i)) 231 printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 232 else if (TELCMD_OK(i)) 233 printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 234 else 235 printf("resp WILL_WONT %d: %d\n", 236 i, will_wont_resp[i]); 237 if (my_want_state_is_will(i)) { 238 if (TELOPT_OK(i)) 239 printf("want WILL %s\n", TELOPT(i)); 240 else if (TELCMD_OK(i)) 241 printf("want WILL %s\n", TELCMD(i)); 242 else 243 printf("want WILL %d\n", i); 244 } else { 245 if (TELOPT_OK(i)) 246 printf("want WONT %s\n", TELOPT(i)); 247 else if (TELCMD_OK(i)) 248 printf("want WONT %s\n", TELCMD(i)); 249 else 250 printf("want WONT %d\n", i); 251 } 252 } else { 253 if (my_state_is_will(i)) { 254 if (TELOPT_OK(i)) 255 printf(" WILL %s\n", TELOPT(i)); 256 else if (TELCMD_OK(i)) 257 printf(" WILL %s\n", TELCMD(i)); 258 else 259 printf(" WILL %d\n", i); 260 } 261 } 262 } 263 264 } 265 266 void 267 printsub(direction, pointer, length) 268 char direction; /* '<' or '>' */ 269 unsigned char *pointer; /* where suboption data sits */ 270 int length; /* length of suboption data */ 271 { 272 register int i; 273 char buf[512]; 274 extern int want_status_response; 275 276 if (showoptions || direction == 0 || 277 (want_status_response && (pointer[0] == TELOPT_STATUS))) { 278 if (direction) { 279 fprintf(NetTrace, "%s IAC SB ", 280 (direction == '<')? "RCVD":"SENT"); 281 if (length >= 3) { 282 register int j; 283 284 i = pointer[length-2]; 285 j = pointer[length-1]; 286 287 if (i != IAC || j != SE) { 288 fprintf(NetTrace, "(terminated by "); 289 if (TELOPT_OK(i)) 290 fprintf(NetTrace, "%s ", TELOPT(i)); 291 else if (TELCMD_OK(i)) 292 fprintf(NetTrace, "%s ", TELCMD(i)); 293 else 294 fprintf(NetTrace, "%d ", i); 295 if (TELOPT_OK(j)) 296 fprintf(NetTrace, "%s", TELOPT(j)); 297 else if (TELCMD_OK(j)) 298 fprintf(NetTrace, "%s", TELCMD(j)); 299 else 300 fprintf(NetTrace, "%d", j); 301 fprintf(NetTrace, ", not IAC SE!) "); 302 } 303 } 304 length -= 2; 305 } 306 if (length < 1) { 307 fprintf(NetTrace, "(Empty suboption??\?)"); 308 if (NetTrace == stdout) 309 fflush(NetTrace); 310 return; 311 } 312 switch (pointer[0]) { 313 case TELOPT_TTYPE: 314 fprintf(NetTrace, "TERMINAL-TYPE "); 315 switch (pointer[1]) { 316 case TELQUAL_IS: 317 fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 318 break; 319 case TELQUAL_SEND: 320 fprintf(NetTrace, "SEND"); 321 break; 322 default: 323 fprintf(NetTrace, 324 "- unknown qualifier %d (0x%x).", 325 pointer[1], pointer[1]); 326 } 327 break; 328 case TELOPT_TSPEED: 329 fprintf(NetTrace, "TERMINAL-SPEED"); 330 if (length < 2) { 331 fprintf(NetTrace, " (empty suboption??\?)"); 332 break; 333 } 334 switch (pointer[1]) { 335 case TELQUAL_IS: 336 fprintf(NetTrace, " IS "); 337 fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2); 338 break; 339 default: 340 if (pointer[1] == 1) 341 fprintf(NetTrace, " SEND"); 342 else 343 fprintf(NetTrace, " %d (unknown)", pointer[1]); 344 for (i = 2; i < length; i++) 345 fprintf(NetTrace, " ?%d?", pointer[i]); 346 break; 347 } 348 break; 349 350 case TELOPT_LFLOW: 351 fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 352 if (length < 2) { 353 fprintf(NetTrace, " (empty suboption??\?)"); 354 break; 355 } 356 switch (pointer[1]) { 357 case LFLOW_OFF: 358 fprintf(NetTrace, " OFF"); break; 359 case LFLOW_ON: 360 fprintf(NetTrace, " ON"); break; 361 case LFLOW_RESTART_ANY: 362 fprintf(NetTrace, " RESTART-ANY"); break; 363 case LFLOW_RESTART_XON: 364 fprintf(NetTrace, " RESTART-XON"); break; 365 default: 366 fprintf(NetTrace, " %d (unknown)", pointer[1]); 367 } 368 for (i = 2; i < length; i++) 369 fprintf(NetTrace, " ?%d?", pointer[i]); 370 break; 371 372 case TELOPT_NAWS: 373 fprintf(NetTrace, "NAWS"); 374 if (length < 2) { 375 fprintf(NetTrace, " (empty suboption??\?)"); 376 break; 377 } 378 if (length == 2) { 379 fprintf(NetTrace, " ?%d?", pointer[1]); 380 break; 381 } 382 fprintf(NetTrace, " %d %d (%d)", 383 pointer[1], pointer[2], 384 (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 385 if (length == 4) { 386 fprintf(NetTrace, " ?%d?", pointer[3]); 387 break; 388 } 389 fprintf(NetTrace, " %d %d (%d)", 390 pointer[3], pointer[4], 391 (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 392 for (i = 5; i < length; i++) 393 fprintf(NetTrace, " ?%d?", pointer[i]); 394 break; 395 396 #if defined(AUTHENTICATION) 397 case TELOPT_AUTHENTICATION: 398 fprintf(NetTrace, "AUTHENTICATION"); 399 if (length < 2) { 400 fprintf(NetTrace, " (empty suboption??\?)"); 401 break; 402 } 403 switch (pointer[1]) { 404 case TELQUAL_REPLY: 405 case TELQUAL_IS: 406 fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? 407 "IS" : "REPLY"); 408 if (AUTHTYPE_NAME_OK(pointer[2])) 409 fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2])); 410 else 411 fprintf(NetTrace, "%d ", pointer[2]); 412 if (length < 3) { 413 fprintf(NetTrace, "(partial suboption??\?)"); 414 break; 415 } 416 fprintf(NetTrace, "%s|%s", 417 ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 418 "CLIENT" : "SERVER", 419 ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 420 "MUTUAL" : "ONE-WAY"); 421 422 auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 423 fprintf(NetTrace, "%s", buf); 424 break; 425 426 case TELQUAL_SEND: 427 i = 2; 428 fprintf(NetTrace, " SEND "); 429 while (i < length) { 430 if (AUTHTYPE_NAME_OK(pointer[i])) 431 fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i])); 432 else 433 fprintf(NetTrace, "%d ", pointer[i]); 434 if (++i >= length) { 435 fprintf(NetTrace, "(partial suboption??\?)"); 436 break; 437 } 438 fprintf(NetTrace, "%s|%s ", 439 ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 440 "CLIENT" : "SERVER", 441 ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 442 "MUTUAL" : "ONE-WAY"); 443 ++i; 444 } 445 break; 446 447 case TELQUAL_NAME: 448 i = 2; 449 fprintf(NetTrace, " NAME \""); 450 while (i < length) 451 putc(pointer[i++], NetTrace); 452 putc('"', NetTrace); 453 break; 454 455 default: 456 for (i = 2; i < length; i++) 457 fprintf(NetTrace, " ?%d?", pointer[i]); 458 break; 459 } 460 break; 461 #endif 462 463 #ifdef ENCRYPTION 464 case TELOPT_ENCRYPT: 465 fprintf(NetTrace, "ENCRYPT"); 466 if (length < 2) { 467 fprintf(NetTrace, " (empty suboption??\?)"); 468 break; 469 } 470 switch (pointer[1]) { 471 case ENCRYPT_START: 472 fprintf(NetTrace, " START"); 473 break; 474 475 case ENCRYPT_END: 476 fprintf(NetTrace, " END"); 477 break; 478 479 case ENCRYPT_REQSTART: 480 fprintf(NetTrace, " REQUEST-START"); 481 break; 482 483 case ENCRYPT_REQEND: 484 fprintf(NetTrace, " REQUEST-END"); 485 break; 486 487 case ENCRYPT_IS: 488 case ENCRYPT_REPLY: 489 fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? 490 "IS" : "REPLY"); 491 if (length < 3) { 492 fprintf(NetTrace, " (partial suboption??\?)"); 493 break; 494 } 495 if (ENCTYPE_NAME_OK(pointer[2])) 496 fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2])); 497 else 498 fprintf(NetTrace, " %d (unknown)", pointer[2]); 499 500 encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 501 fprintf(NetTrace, "%s", buf); 502 break; 503 504 case ENCRYPT_SUPPORT: 505 i = 2; 506 fprintf(NetTrace, " SUPPORT "); 507 while (i < length) { 508 if (ENCTYPE_NAME_OK(pointer[i])) 509 fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i])); 510 else 511 fprintf(NetTrace, "%d ", pointer[i]); 512 i++; 513 } 514 break; 515 516 case ENCRYPT_ENC_KEYID: 517 fprintf(NetTrace, " ENC_KEYID "); 518 goto encommon; 519 520 case ENCRYPT_DEC_KEYID: 521 fprintf(NetTrace, " DEC_KEYID "); 522 goto encommon; 523 524 default: 525 fprintf(NetTrace, " %d (unknown)", pointer[1]); 526 encommon: 527 for (i = 2; i < length; i++) 528 fprintf(NetTrace, " %d", pointer[i]); 529 break; 530 } 531 break; 532 #endif /* ENCRYPTION */ 533 534 case TELOPT_LINEMODE: 535 fprintf(NetTrace, "LINEMODE "); 536 if (length < 2) { 537 fprintf(NetTrace, " (empty suboption??\?)"); 538 break; 539 } 540 switch (pointer[1]) { 541 case WILL: 542 fprintf(NetTrace, "WILL "); 543 goto common; 544 case WONT: 545 fprintf(NetTrace, "WONT "); 546 goto common; 547 case DO: 548 fprintf(NetTrace, "DO "); 549 goto common; 550 case DONT: 551 fprintf(NetTrace, "DONT "); 552 common: 553 if (length < 3) { 554 fprintf(NetTrace, "(no option??\?)"); 555 break; 556 } 557 switch (pointer[2]) { 558 case LM_FORWARDMASK: 559 fprintf(NetTrace, "Forward Mask"); 560 for (i = 3; i < length; i++) 561 fprintf(NetTrace, " %x", pointer[i]); 562 break; 563 default: 564 fprintf(NetTrace, "%d (unknown)", pointer[2]); 565 for (i = 3; i < length; i++) 566 fprintf(NetTrace, " %d", pointer[i]); 567 break; 568 } 569 break; 570 571 case LM_SLC: 572 fprintf(NetTrace, "SLC"); 573 for (i = 2; i < length - 2; i += 3) { 574 if (SLC_NAME_OK(pointer[i+SLC_FUNC])) 575 fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC])); 576 else 577 fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 578 switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 579 case SLC_NOSUPPORT: 580 fprintf(NetTrace, " NOSUPPORT"); break; 581 case SLC_CANTCHANGE: 582 fprintf(NetTrace, " CANTCHANGE"); break; 583 case SLC_VARIABLE: 584 fprintf(NetTrace, " VARIABLE"); break; 585 case SLC_DEFAULT: 586 fprintf(NetTrace, " DEFAULT"); break; 587 } 588 fprintf(NetTrace, "%s%s%s", 589 pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 590 pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 591 pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 592 if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 593 SLC_FLUSHOUT| SLC_LEVELBITS)) 594 fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 595 fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 596 if ((pointer[i+SLC_VALUE] == IAC) && 597 (pointer[i+SLC_VALUE+1] == IAC)) 598 i++; 599 } 600 for (; i < length; i++) 601 fprintf(NetTrace, " ?%d?", pointer[i]); 602 break; 603 604 case LM_MODE: 605 fprintf(NetTrace, "MODE "); 606 if (length < 3) { 607 fprintf(NetTrace, "(no mode??\?)"); 608 break; 609 } 610 { 611 char tbuf[64]; 612 sprintf(tbuf, "%s%s%s%s%s", 613 pointer[2]&MODE_EDIT ? "|EDIT" : "", 614 pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 615 pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 616 pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 617 pointer[2]&MODE_ACK ? "|ACK" : ""); 618 fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 619 } 620 if (pointer[2]&~(MODE_MASK)) 621 fprintf(NetTrace, " (0x%x)", pointer[2]); 622 for (i = 3; i < length; i++) 623 fprintf(NetTrace, " ?0x%x?", pointer[i]); 624 break; 625 default: 626 fprintf(NetTrace, "%d (unknown)", pointer[1]); 627 for (i = 2; i < length; i++) 628 fprintf(NetTrace, " %d", pointer[i]); 629 } 630 break; 631 632 case TELOPT_STATUS: { 633 register char *cp; 634 register int j, k; 635 636 fprintf(NetTrace, "STATUS"); 637 638 switch (pointer[1]) { 639 default: 640 if (pointer[1] == TELQUAL_SEND) 641 fprintf(NetTrace, " SEND"); 642 else 643 fprintf(NetTrace, " %d (unknown)", pointer[1]); 644 for (i = 2; i < length; i++) 645 fprintf(NetTrace, " ?%d?", pointer[i]); 646 break; 647 case TELQUAL_IS: 648 if (--want_status_response < 0) 649 want_status_response = 0; 650 if (NetTrace == stdout) 651 fprintf(NetTrace, " IS\r\n"); 652 else 653 fprintf(NetTrace, " IS\n"); 654 655 for (i = 2; i < length; i++) { 656 switch(pointer[i]) { 657 case DO: cp = "DO"; goto common2; 658 case DONT: cp = "DONT"; goto common2; 659 case WILL: cp = "WILL"; goto common2; 660 case WONT: cp = "WONT"; goto common2; 661 common2: 662 i++; 663 if (TELOPT_OK((int)pointer[i])) 664 fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 665 else 666 fprintf(NetTrace, " %s %d", cp, pointer[i]); 667 668 if (NetTrace == stdout) 669 fprintf(NetTrace, "\r\n"); 670 else 671 fprintf(NetTrace, "\n"); 672 break; 673 674 case SB: 675 fprintf(NetTrace, " SB "); 676 i++; 677 j = k = i; 678 while (j < length) { 679 if (pointer[j] == SE) { 680 if (j+1 == length) 681 break; 682 if (pointer[j+1] == SE) 683 j++; 684 else 685 break; 686 } 687 pointer[k++] = pointer[j++]; 688 } 689 printsub(0, &pointer[i], k - i); 690 if (i < length) { 691 fprintf(NetTrace, " SE"); 692 i = j; 693 } else 694 i = j - 1; 695 696 if (NetTrace == stdout) 697 fprintf(NetTrace, "\r\n"); 698 else 699 fprintf(NetTrace, "\n"); 700 701 break; 702 703 default: 704 fprintf(NetTrace, " %d", pointer[i]); 705 break; 706 } 707 } 708 break; 709 } 710 break; 711 } 712 713 case TELOPT_XDISPLOC: 714 fprintf(NetTrace, "X-DISPLAY-LOCATION "); 715 switch (pointer[1]) { 716 case TELQUAL_IS: 717 fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 718 break; 719 case TELQUAL_SEND: 720 fprintf(NetTrace, "SEND"); 721 break; 722 default: 723 fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 724 pointer[1], pointer[1]); 725 } 726 break; 727 728 case TELOPT_NEW_ENVIRON: 729 fprintf(NetTrace, "NEW-ENVIRON "); 730 #ifdef OLD_ENVIRON 731 goto env_common1; 732 case TELOPT_OLD_ENVIRON: 733 fprintf(NetTrace, "OLD-ENVIRON"); 734 env_common1: 735 #endif 736 switch (pointer[1]) { 737 case TELQUAL_IS: 738 fprintf(NetTrace, "IS "); 739 goto env_common; 740 case TELQUAL_SEND: 741 fprintf(NetTrace, "SEND "); 742 goto env_common; 743 case TELQUAL_INFO: 744 fprintf(NetTrace, "INFO "); 745 env_common: 746 { 747 register int noquote = 2; 748 #if defined(ENV_HACK) && defined(OLD_ENVIRON) 749 extern int old_env_var, old_env_value; 750 #endif 751 for (i = 2; i < length; i++ ) { 752 switch (pointer[i]) { 753 case NEW_ENV_VALUE: 754 #ifdef OLD_ENVIRON 755 /* case NEW_ENV_OVAR: */ 756 if (pointer[0] == TELOPT_OLD_ENVIRON) { 757 # ifdef ENV_HACK 758 if (old_env_var == OLD_ENV_VALUE) 759 fprintf(NetTrace, "\" (VALUE) " + noquote); 760 else 761 # endif 762 fprintf(NetTrace, "\" VAR " + noquote); 763 } else 764 #endif /* OLD_ENVIRON */ 765 fprintf(NetTrace, "\" VALUE " + noquote); 766 noquote = 2; 767 break; 768 769 case NEW_ENV_VAR: 770 #ifdef OLD_ENVIRON 771 /* case OLD_ENV_VALUE: */ 772 if (pointer[0] == TELOPT_OLD_ENVIRON) { 773 # ifdef ENV_HACK 774 if (old_env_value == OLD_ENV_VAR) 775 fprintf(NetTrace, "\" (VAR) " + noquote); 776 else 777 # endif 778 fprintf(NetTrace, "\" VALUE " + noquote); 779 } else 780 #endif /* OLD_ENVIRON */ 781 fprintf(NetTrace, "\" VAR " + noquote); 782 noquote = 2; 783 break; 784 785 case ENV_ESC: 786 fprintf(NetTrace, "\" ESC " + noquote); 787 noquote = 2; 788 break; 789 790 case ENV_USERVAR: 791 fprintf(NetTrace, "\" USERVAR " + noquote); 792 noquote = 2; 793 break; 794 795 default: 796 def_case: 797 if (isprint(pointer[i]) && pointer[i] != '"') { 798 if (noquote) { 799 putc('"', NetTrace); 800 noquote = 0; 801 } 802 putc(pointer[i], NetTrace); 803 } else { 804 fprintf(NetTrace, "\" %03o " + noquote, 805 pointer[i]); 806 noquote = 2; 807 } 808 break; 809 } 810 } 811 if (!noquote) 812 putc('"', NetTrace); 813 break; 814 } 815 } 816 break; 817 818 default: 819 if (TELOPT_OK(pointer[0])) 820 fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0])); 821 else 822 fprintf(NetTrace, "%d (unknown)", pointer[0]); 823 for (i = 1; i < length; i++) 824 fprintf(NetTrace, " %d", pointer[i]); 825 break; 826 } 827 if (direction) { 828 if (NetTrace == stdout) 829 fprintf(NetTrace, "\r\n"); 830 else 831 fprintf(NetTrace, "\n"); 832 } 833 if (NetTrace == stdout) 834 fflush(NetTrace); 835 } 836 } 837 838 /* EmptyTerminal - called to make sure that the terminal buffer is empty. 839 * Note that we consider the buffer to run all the 840 * way to the kernel (thus the select). 841 */ 842 843 void 844 EmptyTerminal() 845 { 846 #if defined(unix) 847 fd_set o; 848 849 FD_ZERO(&o); 850 #endif /* defined(unix) */ 851 852 if (TTYBYTES() == 0) { 853 #if defined(unix) 854 FD_SET(tout, &o); 855 (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 856 (struct timeval *) 0); /* wait for TTLOWAT */ 857 #endif /* defined(unix) */ 858 } else { 859 while (TTYBYTES()) { 860 (void) ttyflush(0); 861 #if defined(unix) 862 FD_SET(tout, &o); 863 (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 864 (struct timeval *) 0); /* wait for TTLOWAT */ 865 #endif /* defined(unix) */ 866 } 867 } 868 } 869 870 void 871 SetForExit() 872 { 873 setconnmode(0); 874 #if defined(TN3270) 875 if (In3270) { 876 Finish3270(); 877 } 878 #else /* defined(TN3270) */ 879 do { 880 (void)telrcv(); /* Process any incoming data */ 881 EmptyTerminal(); 882 } while (ring_full_count(&netiring)); /* While there is any */ 883 #endif /* defined(TN3270) */ 884 setcommandmode(); 885 fflush(stdout); 886 fflush(stderr); 887 #if defined(TN3270) 888 if (In3270) { 889 StopScreen(1); 890 } 891 #endif /* defined(TN3270) */ 892 setconnmode(0); 893 EmptyTerminal(); /* Flush the path to the tty */ 894 setcommandmode(); 895 } 896 897 void 898 Exit(returnCode) 899 int returnCode; 900 { 901 SetForExit(); 902 exit(returnCode); 903 } 904 905 void 906 ExitString(string, returnCode) 907 char *string; 908 int returnCode; 909 { 910 SetForExit(); 911 fwrite(string, 1, strlen(string), stderr); 912 exit(returnCode); 913 } 914