133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 544361Sborman * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*46808Sdab static char sccsid[] = "@(#)utilities.c 5.2 (Berkeley) 03/01/91"; 1033686Sbostic #endif /* not lint */ 1133686Sbostic 1232149Sminshall #define TELOPTS 1338690Sborman #define TELCMDS 14*46808Sdab #define SLC_NAMES 1532149Sminshall #include <arpa/telnet.h> 1632381Sminshall #include <sys/types.h> 1744361Sborman #include <sys/time.h> 1832149Sminshall 1932149Sminshall #include <ctype.h> 2032149Sminshall 2134305Sminshall #include "general.h" 2234305Sminshall 2336280Sminshall #include "fdset.h" 2436280Sminshall 2532381Sminshall #include "ring.h" 2632381Sminshall 2736278Sminshall #include "defines.h" 2836278Sminshall 2932149Sminshall #include "externs.h" 3032149Sminshall 3132149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 3238690Sborman int prettydump; 3332149Sminshall 3432149Sminshall /* 3532149Sminshall * upcase() 3632149Sminshall * 3732149Sminshall * Upcase (in place) the argument. 3832149Sminshall */ 3932149Sminshall 40*46808Sdab void 4132149Sminshall upcase(argument) 42*46808Sdab register char *argument; 4332149Sminshall { 4432149Sminshall register int c; 4532149Sminshall 4632149Sminshall while ((c = *argument) != 0) { 4732149Sminshall if (islower(c)) { 4832149Sminshall *argument = toupper(c); 4932149Sminshall } 5032149Sminshall argument++; 5132149Sminshall } 5232149Sminshall } 5332149Sminshall 5432149Sminshall /* 5532149Sminshall * SetSockOpt() 5632149Sminshall * 5732149Sminshall * Compensate for differences in 4.2 and 4.3 systems. 5832149Sminshall */ 5932149Sminshall 60*46808Sdab int 6132149Sminshall SetSockOpt(fd, level, option, yesno) 62*46808Sdab int fd, level, option, yesno; 6332149Sminshall { 6432149Sminshall #ifndef NOT43 6532149Sminshall return setsockopt(fd, level, option, 6632149Sminshall (char *)&yesno, sizeof yesno); 6732149Sminshall #else /* NOT43 */ 6832149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */ 6932149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 7032149Sminshall option); 7132149Sminshall return -1; 7232149Sminshall } 7332149Sminshall return setsockopt(fd, level, option, 0, 0); 7432149Sminshall #endif /* NOT43 */ 7532149Sminshall } 7632149Sminshall 7732149Sminshall /* 7832149Sminshall * The following are routines used to print out debugging information. 7932149Sminshall */ 8032149Sminshall 8139529Sborman unsigned char NetTraceFile[256] = "(standard output)"; 8232149Sminshall 83*46808Sdab void 8438690Sborman SetNetTrace(file) 85*46808Sdab register char *file; 8638690Sborman { 8738690Sborman if (NetTrace && NetTrace != stdout) 8838690Sborman fclose(NetTrace); 8938690Sborman if (file && (strcmp(file, "-") != 0)) { 9038690Sborman NetTrace = fopen(file, "w"); 9138690Sborman if (NetTrace) { 92*46808Sdab strcpy((char *)NetTraceFile, file); 9338690Sborman return; 9438690Sborman } 9538690Sborman fprintf(stderr, "Cannot open %s.\n", file); 9638690Sborman } 9738690Sborman NetTrace = stdout; 98*46808Sdab strcpy((char *)NetTraceFile, "(standard output)"); 9938690Sborman } 10038690Sborman 101*46808Sdab void 10232149Sminshall Dump(direction, buffer, length) 103*46808Sdab char direction; 104*46808Sdab unsigned char *buffer; 105*46808Sdab int length; 10632149Sminshall { 10732149Sminshall # define BYTES_PER_LINE 32 10832149Sminshall # define min(x,y) ((x<y)? x:y) 109*46808Sdab unsigned char *pThis; 11032149Sminshall int offset; 11138690Sborman extern pettydump; 11232149Sminshall 11332149Sminshall offset = 0; 11432149Sminshall 11532149Sminshall while (length) { 11632149Sminshall /* print one line */ 11732149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset); 11832149Sminshall pThis = buffer; 11938690Sborman if (prettydump) { 12038909Sborman buffer = buffer + min(length, BYTES_PER_LINE/2); 12138690Sborman while (pThis < buffer) { 12238690Sborman fprintf(NetTrace, "%c%.2x", 12338690Sborman (((*pThis)&0xff) == 0xff) ? '*' : ' ', 12438690Sborman (*pThis)&0xff); 12538690Sborman pThis++; 12638690Sborman } 12738909Sborman length -= BYTES_PER_LINE/2; 12838909Sborman offset += BYTES_PER_LINE/2; 12938690Sborman } else { 13038909Sborman buffer = buffer + min(length, BYTES_PER_LINE); 13138690Sborman while (pThis < buffer) { 13238690Sborman fprintf(NetTrace, "%.2x", (*pThis)&0xff); 13338690Sborman pThis++; 13438690Sborman } 13538909Sborman length -= BYTES_PER_LINE; 13638909Sborman offset += BYTES_PER_LINE; 13732149Sminshall } 13837226Sminshall if (NetTrace == stdout) { 13938207Sminshall fprintf(NetTrace, "\r\n"); 14038207Sminshall } else { 14137226Sminshall fprintf(NetTrace, "\n"); 14237226Sminshall } 14332149Sminshall if (length < 0) { 14436693Sminshall fflush(NetTrace); 14532149Sminshall return; 14632149Sminshall } 14732149Sminshall /* find next unique line */ 14832149Sminshall } 14936693Sminshall fflush(NetTrace); 15032149Sminshall } 15132149Sminshall 15232149Sminshall 153*46808Sdab void 154*46808Sdab printoption(direction, cmd, option) 155*46808Sdab char *direction; 156*46808Sdab int cmd, option; 15732149Sminshall { 15832149Sminshall if (!showoptions) 15932149Sminshall return; 160*46808Sdab if (cmd == IAC) { 161*46808Sdab if (TELCMD_OK(option)) 162*46808Sdab fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option)); 163*46808Sdab else 164*46808Sdab fprintf(NetTrace, "%s IAC %d", direction, option); 165*46808Sdab } else { 166*46808Sdab register char *fmt; 167*46808Sdab fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" : 168*46808Sdab (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0; 169*46808Sdab if (fmt) { 170*46808Sdab fprintf(NetTrace, "%s %s ", direction, fmt); 171*46808Sdab if (TELOPT_OK(option)) 172*46808Sdab fprintf(NetTrace, "%s", TELOPT(option)); 173*46808Sdab else if (option == TELOPT_EXOPL) 174*46808Sdab fprintf(NetTrace, "EXOPL"); 175*46808Sdab else 176*46808Sdab fprintf(NetTrace, "%d", option); 177*46808Sdab } else 178*46808Sdab fprintf(NetTrace, "%s %d %d", direction, cmd, option); 179*46808Sdab } 18038690Sborman if (NetTrace == stdout) 18137226Sminshall fprintf(NetTrace, "\r\n"); 18238690Sborman else 18337226Sminshall fprintf(NetTrace, "\n"); 18437226Sminshall return; 18532149Sminshall } 18632149Sminshall 187*46808Sdab void 18838690Sborman optionstatus() 18938690Sborman { 19038690Sborman register int i; 19138690Sborman extern char will_wont_resp[], do_dont_resp[]; 19238690Sborman 19338690Sborman for (i = 0; i < 256; i++) { 19438690Sborman if (do_dont_resp[i]) { 19538690Sborman if (TELOPT_OK(i)) 19638690Sborman printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 19738690Sborman else if (TELCMD_OK(i)) 19838690Sborman printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 19938690Sborman else 20038690Sborman printf("resp DO_DONT %d: %d\n", i, 20138690Sborman do_dont_resp[i]); 20238690Sborman if (my_want_state_is_do(i)) { 20338690Sborman if (TELOPT_OK(i)) 20438690Sborman printf("want DO %s\n", TELOPT(i)); 20538690Sborman else if (TELCMD_OK(i)) 20638690Sborman printf("want DO %s\n", TELCMD(i)); 20738690Sborman else 20838690Sborman printf("want DO %d\n", i); 20938690Sborman } else { 21038690Sborman if (TELOPT_OK(i)) 21138690Sborman printf("want DONT %s\n", TELOPT(i)); 21238690Sborman else if (TELCMD_OK(i)) 21338690Sborman printf("want DONT %s\n", TELCMD(i)); 21438690Sborman else 21538690Sborman printf("want DONT %d\n", i); 21638690Sborman } 21738690Sborman } else { 21838690Sborman if (my_state_is_do(i)) { 21938690Sborman if (TELOPT_OK(i)) 22038690Sborman printf(" DO %s\n", TELOPT(i)); 22138690Sborman else if (TELCMD_OK(i)) 22238690Sborman printf(" DO %s\n", TELCMD(i)); 22338690Sborman else 22438690Sborman printf(" DO %d\n", i); 22538690Sborman } 22638690Sborman } 22738690Sborman if (will_wont_resp[i]) { 22838690Sborman if (TELOPT_OK(i)) 22938690Sborman printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 23038690Sborman else if (TELCMD_OK(i)) 23138690Sborman printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 23238690Sborman else 23338690Sborman printf("resp WILL_WONT %d: %d\n", 23438690Sborman i, will_wont_resp[i]); 23538690Sborman if (my_want_state_is_will(i)) { 23638690Sborman if (TELOPT_OK(i)) 23738690Sborman printf("want WILL %s\n", TELOPT(i)); 23838690Sborman else if (TELCMD_OK(i)) 23938690Sborman printf("want WILL %s\n", TELCMD(i)); 24038690Sborman else 24138690Sborman printf("want WILL %d\n", i); 24238690Sborman } else { 24338690Sborman if (TELOPT_OK(i)) 24438690Sborman printf("want WONT %s\n", TELOPT(i)); 24538690Sborman else if (TELCMD_OK(i)) 24638690Sborman printf("want WONT %s\n", TELCMD(i)); 24738690Sborman else 24838690Sborman printf("want WONT %d\n", i); 24938690Sborman } 25038690Sborman } else { 25138690Sborman if (my_state_is_will(i)) { 25238690Sborman if (TELOPT_OK(i)) 25338690Sborman printf(" WILL %s\n", TELOPT(i)); 25438690Sborman else if (TELCMD_OK(i)) 25538690Sborman printf(" WILL %s\n", TELCMD(i)); 25638690Sborman else 25738690Sborman printf(" WILL %d\n", i); 25838690Sborman } 25938690Sborman } 26038690Sborman } 26138690Sborman 26238690Sborman } 26338690Sborman 264*46808Sdab void 26532149Sminshall printsub(direction, pointer, length) 266*46808Sdab char direction; /* '<' or '>' */ 267*46808Sdab unsigned char *pointer; /* where suboption data sits */ 268*46808Sdab int length; /* length of suboption data */ 26932149Sminshall { 27038690Sborman register int i; 271*46808Sdab char buf[256]; 272*46808Sdab extern int want_status_response; 27338690Sborman 274*46808Sdab if (showoptions || direction == 0 || 275*46808Sdab (want_status_response && (pointer[0] == TELOPT_STATUS))) { 27638909Sborman if (direction) { 277*46808Sdab fprintf(NetTrace, "%s IAC SB ", 278*46808Sdab (direction == '<')? "RCVD":"SENT"); 27938909Sborman if (length >= 3) { 28038909Sborman register int j; 28138690Sborman 28238909Sborman i = pointer[length-2]; 28338909Sborman j = pointer[length-1]; 28438690Sborman 28538909Sborman if (i != IAC || j != SE) { 28638909Sborman fprintf(NetTrace, "(terminated by "); 28738909Sborman if (TELOPT_OK(i)) 28838909Sborman fprintf(NetTrace, "%s ", TELOPT(i)); 28938909Sborman else if (TELCMD_OK(i)) 29038909Sborman fprintf(NetTrace, "%s ", TELCMD(i)); 29138909Sborman else 29238909Sborman fprintf(NetTrace, "%d ", i); 29338909Sborman if (TELOPT_OK(j)) 29438909Sborman fprintf(NetTrace, "%s", TELOPT(j)); 29538909Sborman else if (TELCMD_OK(j)) 29638909Sborman fprintf(NetTrace, "%s", TELCMD(j)); 29738909Sborman else 29838909Sborman fprintf(NetTrace, "%d", j); 29938909Sborman fprintf(NetTrace, ", not IAC SE!) "); 30038909Sborman } 30138690Sborman } 30238909Sborman length -= 2; 30338690Sborman } 30438690Sborman if (length < 1) { 30538690Sborman fprintf(NetTrace, "(Empty suboption???)"); 30638690Sborman return; 30738690Sborman } 30832149Sminshall switch (pointer[0]) { 30932149Sminshall case TELOPT_TTYPE: 31038690Sborman fprintf(NetTrace, "TERMINAL-TYPE "); 31132149Sminshall switch (pointer[1]) { 31232149Sminshall case TELQUAL_IS: 31344361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 31432149Sminshall break; 31532149Sminshall case TELQUAL_SEND: 31638690Sborman fprintf(NetTrace, "SEND"); 31732149Sminshall break; 31832149Sminshall default: 31932149Sminshall fprintf(NetTrace, 32038690Sborman "- unknown qualifier %d (0x%x).", 32134849Sminshall pointer[1], pointer[1]); 32232149Sminshall } 32332149Sminshall break; 32438690Sborman case TELOPT_TSPEED: 32538690Sborman fprintf(NetTrace, "TERMINAL-SPEED"); 32638690Sborman if (length < 2) { 32738690Sborman fprintf(NetTrace, " (empty suboption???)"); 32838690Sborman break; 32938690Sborman } 33038690Sborman switch (pointer[1]) { 33138909Sborman case TELQUAL_IS: 33238690Sborman fprintf(NetTrace, " IS "); 33344361Sborman fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2); 33438690Sborman break; 33538690Sborman default: 33638690Sborman if (pointer[1] == 1) 33738690Sborman fprintf(NetTrace, " SEND"); 33838690Sborman else 33944361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 34038690Sborman for (i = 2; i < length; i++) 34138690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 34238690Sborman break; 34338690Sborman } 34438690Sborman break; 34538690Sborman 34638690Sborman case TELOPT_LFLOW: 34738690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 34838690Sborman if (length < 2) { 34938690Sborman fprintf(NetTrace, " (empty suboption???)"); 35038690Sborman break; 35138690Sborman } 35238690Sborman switch (pointer[1]) { 35338690Sborman case 0: 35438690Sborman fprintf(NetTrace, " OFF"); break; 35538690Sborman case 1: 35638690Sborman fprintf(NetTrace, " ON"); break; 35738690Sborman default: 35844361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 35938690Sborman } 36038690Sborman for (i = 2; i < length; i++) 36138690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 36238690Sborman break; 36338690Sborman 36438690Sborman case TELOPT_NAWS: 36538690Sborman fprintf(NetTrace, "NAWS"); 36638690Sborman if (length < 2) { 36738690Sborman fprintf(NetTrace, " (empty suboption???)"); 36838690Sborman break; 36938690Sborman } 37038690Sborman if (length == 2) { 37138690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 37238690Sborman break; 37338690Sborman } 37438690Sborman fprintf(NetTrace, " %d %d (%d)", 37538690Sborman pointer[1], pointer[2], 37644361Sborman (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 37738690Sborman if (length == 4) { 37838690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 37938690Sborman break; 38038690Sborman } 38138690Sborman fprintf(NetTrace, " %d %d (%d)", 38238690Sborman pointer[3], pointer[4], 38344361Sborman (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 38438690Sborman for (i = 5; i < length; i++) 38538690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 38638690Sborman break; 38738690Sborman 388*46808Sdab #if defined(AUTHENTICATE) 38943320Skfall case TELOPT_AUTHENTICATION: 390*46808Sdab fprintf(NetTrace, "AUTHENTICATION"); 391*46808Sdab if (length < 2) { 392*46808Sdab fprintf(NetTrace, " (empty suboption???)"); 393*46808Sdab break; 394*46808Sdab } 39543320Skfall switch (pointer[1]) { 396*46808Sdab case TELQUAL_REPLY: 39743320Skfall case TELQUAL_IS: 398*46808Sdab fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? 399*46808Sdab "IS" : "REPLY"); 400*46808Sdab if (AUTHTYPE_NAME_OK(pointer[2])) 401*46808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2])); 402*46808Sdab else 403*46808Sdab fprintf(NetTrace, "%d ", pointer[2]); 404*46808Sdab if (length < 3) { 405*46808Sdab fprintf(NetTrace, "(partial suboption???)"); 406*46808Sdab break; 407*46808Sdab } 408*46808Sdab fprintf(NetTrace, "%s|%s", 409*46808Sdab (pointer[3] & AUTH_WHO_MASK == AUTH_WHO_CLIENT) ? 410*46808Sdab "CLIENT" : "SERVER", 411*46808Sdab (pointer[3] & AUTH_HOW_MASK == AUTH_HOW_MUTUAL) ? 412*46808Sdab "MUTUAL" : "ONE-WAY"); 41343320Skfall 414*46808Sdab auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 415*46808Sdab fprintf(NetTrace, "%s", buf); 416*46808Sdab break; 417*46808Sdab 418*46808Sdab case TELQUAL_SEND: 419*46808Sdab i = 2; 420*46808Sdab fprintf(NetTrace, " SEND "); 421*46808Sdab while (i < length) { 422*46808Sdab if (AUTHTYPE_NAME_OK(pointer[i])) 423*46808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i])); 424*46808Sdab else 425*46808Sdab fprintf(NetTrace, "%d ", pointer[i]); 426*46808Sdab if (++i >= length) { 427*46808Sdab fprintf(NetTrace, "(partial suboption???)"); 42843320Skfall break; 429*46808Sdab } 430*46808Sdab fprintf(NetTrace, "%s|%s ", 431*46808Sdab (pointer[i] & AUTH_WHO_MASK == AUTH_WHO_CLIENT) ? 432*46808Sdab "CLIENT" : "SERVER", 433*46808Sdab (pointer[i] & AUTH_HOW_MASK == AUTH_HOW_MUTUAL) ? 434*46808Sdab "MUTUAL" : "ONE-WAY"); 435*46808Sdab ++i; 43643320Skfall } 437*46808Sdab break; 43843320Skfall 439*46808Sdab default: 440*46808Sdab for (i = 2; i < length; i++) 441*46808Sdab fprintf(NetTrace, " ?%d?", pointer[i]); 442*46808Sdab break; 44343320Skfall } 444*46808Sdab break; 445*46808Sdab #endif 446*46808Sdab 447*46808Sdab #if defined(ENCRYPT) 448*46808Sdab case TELOPT_ENCRYPT: 449*46808Sdab fprintf(NetTrace, "ENCRYPT"); 450*46808Sdab if (length < 2) { 451*46808Sdab fprintf(NetTrace, " (empty suboption???)"); 45243320Skfall break; 453*46808Sdab } 454*46808Sdab switch (pointer[1]) { 455*46808Sdab case ENCRYPT_START: 456*46808Sdab fprintf(NetTrace, " START"); 457*46808Sdab break; 45843320Skfall 459*46808Sdab case ENCRYPT_END: 460*46808Sdab fprintf(NetTrace, " END"); 461*46808Sdab break; 462*46808Sdab 463*46808Sdab case ENCRYPT_REQSTART: 464*46808Sdab fprintf(NetTrace, " REQUEST-START"); 465*46808Sdab break; 466*46808Sdab 467*46808Sdab case ENCRYPT_REQEND: 468*46808Sdab fprintf(NetTrace, " REQUEST-END"); 469*46808Sdab break; 470*46808Sdab 471*46808Sdab case ENCRYPT_IS: 472*46808Sdab case ENCRYPT_REPLY: 473*46808Sdab fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? 474*46808Sdab "IS" : "REPLY"); 475*46808Sdab if (length < 3) { 476*46808Sdab fprintf(NetTrace, " (partial suboption???)"); 477*46808Sdab break; 478*46808Sdab } 479*46808Sdab if (ENCTYPE_NAME_OK(pointer[2])) 480*46808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2])); 481*46808Sdab else 482*46808Sdab fprintf(NetTrace, " %d (unknown)", pointer[2]); 483*46808Sdab 484*46808Sdab encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 485*46808Sdab fprintf(NetTrace, "%s", buf); 486*46808Sdab break; 487*46808Sdab 488*46808Sdab case ENCRYPT_SUPPORT: 489*46808Sdab i = 2; 490*46808Sdab fprintf(NetTrace, " SUPPORT "); 491*46808Sdab while (i < length) { 492*46808Sdab if (ENCTYPE_NAME_OK(pointer[i])) 493*46808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i])); 494*46808Sdab else 495*46808Sdab fprintf(NetTrace, "%d ", pointer[i]); 496*46808Sdab i++; 497*46808Sdab } 498*46808Sdab break; 499*46808Sdab 50043320Skfall default: 501*46808Sdab fprintf(NetTrace, "%d (unknown)", pointer[1]); 502*46808Sdab for (i = 2; i < length; i++) 503*46808Sdab fprintf(NetTrace, " %d", pointer[i]); 504*46808Sdab break; 50543320Skfall } 50643320Skfall break; 507*46808Sdab #endif 50843320Skfall 50938690Sborman case TELOPT_LINEMODE: 51038690Sborman fprintf(NetTrace, "LINEMODE "); 51138690Sborman if (length < 2) { 51238690Sborman fprintf(NetTrace, " (empty suboption???)"); 51338690Sborman break; 51438690Sborman } 51538690Sborman switch (pointer[1]) { 51638690Sborman case WILL: 51738690Sborman fprintf(NetTrace, "WILL "); 51838690Sborman goto common; 51938690Sborman case WONT: 52038690Sborman fprintf(NetTrace, "WONT "); 52138690Sborman goto common; 52238690Sborman case DO: 52338690Sborman fprintf(NetTrace, "DO "); 52438690Sborman goto common; 52538690Sborman case DONT: 52638690Sborman fprintf(NetTrace, "DONT "); 52738690Sborman common: 52838690Sborman if (length < 3) { 52938690Sborman fprintf(NetTrace, "(no option???)"); 53038690Sborman break; 53138690Sborman } 53238690Sborman switch (pointer[2]) { 53338690Sborman case LM_FORWARDMASK: 53438690Sborman fprintf(NetTrace, "Forward Mask"); 53538690Sborman for (i = 3; i < length; i++) 53638690Sborman fprintf(NetTrace, " %x", pointer[i]); 53738690Sborman break; 53838690Sborman default: 53938690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 54038690Sborman for (i = 3; i < length; i++) 54138690Sborman fprintf(NetTrace, " %d", pointer[i]); 54238690Sborman break; 54338690Sborman } 54438690Sborman break; 54538690Sborman 54638690Sborman case LM_SLC: 54738690Sborman fprintf(NetTrace, "SLC"); 54838690Sborman for (i = 2; i < length - 2; i += 3) { 549*46808Sdab if (SLC_NAME_OK(pointer[i+SLC_FUNC])) 550*46808Sdab fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC])); 55138690Sborman else 55238690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 55338690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 55438690Sborman case SLC_NOSUPPORT: 55538690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 55638690Sborman case SLC_CANTCHANGE: 55738690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 55838690Sborman case SLC_VARIABLE: 55938690Sborman fprintf(NetTrace, " VARIABLE"); break; 56038690Sborman case SLC_DEFAULT: 56138690Sborman fprintf(NetTrace, " DEFAULT"); break; 56238690Sborman } 56338690Sborman fprintf(NetTrace, "%s%s%s", 56438690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 56538690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 56638690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 56738690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 56838690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 56938690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 57038690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 57144361Sborman if ((pointer[i+SLC_VALUE] == IAC) && 57244361Sborman (pointer[i+SLC_VALUE+1] == IAC)) 57344361Sborman i++; 57438690Sborman } 57538690Sborman for (; i < length; i++) 57638690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 57738690Sborman break; 57838690Sborman 57938690Sborman case LM_MODE: 58038690Sborman fprintf(NetTrace, "MODE "); 58138690Sborman if (length < 3) { 58238690Sborman fprintf(NetTrace, "(no mode???)"); 58338690Sborman break; 58438690Sborman } 58538690Sborman { 58644361Sborman char tbuf[64]; 58744361Sborman sprintf(tbuf, "%s%s%s%s%s", 58838690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 58938690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 59044361Sborman pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 59144361Sborman pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 59238690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 59338690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 59438690Sborman } 595*46808Sdab if (pointer[2]&~(MODE_MASK)) 59638690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 59738690Sborman for (i = 3; i < length; i++) 59838690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 59938690Sborman break; 60038690Sborman default: 60138690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 60238690Sborman for (i = 2; i < length; i++) 60338690Sborman fprintf(NetTrace, " %d", pointer[i]); 60438690Sborman } 60538690Sborman break; 60638690Sborman 60738909Sborman case TELOPT_STATUS: { 60838909Sborman register char *cp; 60938909Sborman register int j, k; 61038909Sborman 61138909Sborman fprintf(NetTrace, "STATUS"); 61238909Sborman 61338909Sborman switch (pointer[1]) { 61438909Sborman default: 61538909Sborman if (pointer[1] == TELQUAL_SEND) 61638909Sborman fprintf(NetTrace, " SEND"); 61738909Sborman else 61844361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 61938909Sborman for (i = 2; i < length; i++) 62038909Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 62138909Sborman break; 62238909Sborman case TELQUAL_IS: 623*46808Sdab if (--want_status_response < 0) 624*46808Sdab want_status_response = 0; 62538909Sborman if (NetTrace == stdout) 62638909Sborman fprintf(NetTrace, " IS\r\n"); 62738909Sborman else 62838909Sborman fprintf(NetTrace, " IS\n"); 62938909Sborman 63038909Sborman for (i = 2; i < length; i++) { 63138909Sborman switch(pointer[i]) { 63238909Sborman case DO: cp = "DO"; goto common2; 63338909Sborman case DONT: cp = "DONT"; goto common2; 63438909Sborman case WILL: cp = "WILL"; goto common2; 63538909Sborman case WONT: cp = "WONT"; goto common2; 63638909Sborman common2: 63738909Sborman i++; 63844361Sborman if (TELOPT_OK((int)pointer[i])) 63938909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 64038909Sborman else 64138909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]); 64238909Sborman 64338909Sborman if (NetTrace == stdout) 64438909Sborman fprintf(NetTrace, "\r\n"); 64538909Sborman else 64638909Sborman fprintf(NetTrace, "\n"); 64738909Sborman break; 64838909Sborman 64938909Sborman case SB: 65038909Sborman fprintf(NetTrace, " SB "); 65138909Sborman i++; 65238909Sborman j = k = i; 65338909Sborman while (j < length) { 65438909Sborman if (pointer[j] == SE) { 65538909Sborman if (j+1 == length) 65638909Sborman break; 65738909Sborman if (pointer[j+1] == SE) 65838909Sborman j++; 65938909Sborman else 66038909Sborman break; 66138909Sborman } 66238909Sborman pointer[k++] = pointer[j++]; 66338909Sborman } 66438909Sborman printsub(0, &pointer[i], k - i); 66538909Sborman if (i < length) { 66638909Sborman fprintf(NetTrace, " SE"); 66738909Sborman i = j; 66838909Sborman } else 66938909Sborman i = j - 1; 67038909Sborman 67138909Sborman if (NetTrace == stdout) 67238909Sborman fprintf(NetTrace, "\r\n"); 67338909Sborman else 67438909Sborman fprintf(NetTrace, "\n"); 67538909Sborman 67638909Sborman break; 67738909Sborman 67838909Sborman default: 67938909Sborman fprintf(NetTrace, " %d", pointer[i]); 68038909Sborman break; 68138909Sborman } 68238909Sborman } 68338909Sborman break; 68438909Sborman } 68538909Sborman break; 68638909Sborman } 68738909Sborman 68844361Sborman case TELOPT_XDISPLOC: 68944361Sborman fprintf(NetTrace, "X-DISPLAY-LOCATION "); 69044361Sborman switch (pointer[1]) { 69144361Sborman case TELQUAL_IS: 69244361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 69344361Sborman break; 69444361Sborman case TELQUAL_SEND: 69544361Sborman fprintf(NetTrace, "SEND"); 69644361Sborman break; 69744361Sborman default: 69844361Sborman fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 69944361Sborman pointer[1], pointer[1]); 70044361Sborman } 70144361Sborman break; 70244361Sborman 70344361Sborman case TELOPT_ENVIRON: 70444361Sborman fprintf(NetTrace, "ENVIRON "); 70544361Sborman switch (pointer[1]) { 70644361Sborman case TELQUAL_IS: 70744361Sborman fprintf(NetTrace, "IS "); 70844361Sborman goto env_common; 70944361Sborman case TELQUAL_SEND: 71044361Sborman fprintf(NetTrace, "SEND "); 71144361Sborman goto env_common; 71244361Sborman case TELQUAL_INFO: 71344361Sborman fprintf(NetTrace, "INFO "); 71444361Sborman env_common: 71544361Sborman { 71644361Sborman register int noquote = 2; 71744361Sborman for (i = 2; i < length; i++ ) { 71844361Sborman switch (pointer[i]) { 71944361Sborman case ENV_VAR: 72044361Sborman if (pointer[1] == TELQUAL_SEND) 72144361Sborman goto def_case; 72244361Sborman fprintf(NetTrace, "\" VAR " + noquote); 72344361Sborman noquote = 2; 72444361Sborman break; 72544361Sborman 72644361Sborman case ENV_VALUE: 72744361Sborman fprintf(NetTrace, "\" VALUE " + noquote); 72844361Sborman noquote = 2; 72944361Sborman break; 73044361Sborman 73144361Sborman case ENV_ESC: 73244361Sborman fprintf(NetTrace, "\" ESC " + noquote); 73344361Sborman noquote = 2; 73444361Sborman break; 73544361Sborman 73644361Sborman default: 73744361Sborman def_case: 73844361Sborman if (isprint(pointer[i]) && pointer[i] != '"') { 73944361Sborman if (noquote) { 74044361Sborman putc('"', NetTrace); 74144361Sborman noquote = 0; 74244361Sborman } 74344361Sborman putc(pointer[i], NetTrace); 74444361Sborman } else { 74544361Sborman fprintf(NetTrace, "\" %03o " + noquote, 74644361Sborman pointer[i]); 74744361Sborman noquote = 2; 74844361Sborman } 74944361Sborman break; 75044361Sborman } 75144361Sborman } 75244361Sborman if (!noquote) 75344361Sborman putc('"', NetTrace); 75444361Sborman break; 75544361Sborman } 75644361Sborman } 75744361Sborman break; 75844361Sborman 75932149Sminshall default: 760*46808Sdab if (TELOPT_OK(pointer[0])) 761*46808Sdab fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0])); 762*46808Sdab else 763*46808Sdab fprintf(NetTrace, "%d (unknown)", pointer[i]); 764*46808Sdab for (i = 1; i < length; i++) 76538690Sborman fprintf(NetTrace, " %d", pointer[i]); 76638690Sborman break; 76732149Sminshall } 76838909Sborman if (direction) { 76938909Sborman if (NetTrace == stdout) 77038909Sborman fprintf(NetTrace, "\r\n"); 77138909Sborman else 77238909Sborman fprintf(NetTrace, "\n"); 77338909Sborman } 77432149Sminshall } 77532149Sminshall } 77636278Sminshall 77736278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 77836278Sminshall * Note that we consider the buffer to run all the 77936278Sminshall * way to the kernel (thus the select). 78036278Sminshall */ 78136278Sminshall 782*46808Sdab void 78336278Sminshall EmptyTerminal() 78436278Sminshall { 78536278Sminshall #if defined(unix) 78636278Sminshall fd_set o; 78736278Sminshall 78836278Sminshall FD_ZERO(&o); 78936278Sminshall #endif /* defined(unix) */ 79036278Sminshall 79136278Sminshall if (TTYBYTES() == 0) { 79236278Sminshall #if defined(unix) 79336278Sminshall FD_SET(tout, &o); 79436278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 79536278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 79636278Sminshall #endif /* defined(unix) */ 79736278Sminshall } else { 79836278Sminshall while (TTYBYTES()) { 79944361Sborman (void) ttyflush(0); 80036278Sminshall #if defined(unix) 80136278Sminshall FD_SET(tout, &o); 80236278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 80336278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 80436278Sminshall #endif /* defined(unix) */ 80536278Sminshall } 80636278Sminshall } 80736278Sminshall } 80836278Sminshall 809*46808Sdab void 81036278Sminshall SetForExit() 81136278Sminshall { 81238690Sborman setconnmode(0); 81336278Sminshall #if defined(TN3270) 81436278Sminshall if (In3270) { 81536278Sminshall Finish3270(); 81636278Sminshall } 81736279Sminshall #else /* defined(TN3270) */ 81836279Sminshall do { 81944361Sborman (void)telrcv(); /* Process any incoming data */ 82036279Sminshall EmptyTerminal(); 82136279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 82236278Sminshall #endif /* defined(TN3270) */ 82336278Sminshall setcommandmode(); 82436278Sminshall fflush(stdout); 82536278Sminshall fflush(stderr); 82636278Sminshall #if defined(TN3270) 82736278Sminshall if (In3270) { 82836278Sminshall StopScreen(1); 82936278Sminshall } 83036278Sminshall #endif /* defined(TN3270) */ 83138690Sborman setconnmode(0); 83236278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 83336278Sminshall setcommandmode(); 83436278Sminshall } 83536278Sminshall 836*46808Sdab void 83736278Sminshall Exit(returnCode) 838*46808Sdab int returnCode; 83936278Sminshall { 84036278Sminshall SetForExit(); 84136278Sminshall exit(returnCode); 84236278Sminshall } 84336278Sminshall 844*46808Sdab void 84536278Sminshall ExitString(string, returnCode) 846*46808Sdab char *string; 847*46808Sdab int returnCode; 84836278Sminshall { 84936278Sminshall SetForExit(); 85036278Sminshall fwrite(string, 1, strlen(string), stderr); 85136278Sminshall exit(returnCode); 85236278Sminshall } 853