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