133686Sbostic /* 2*62313Sbostic * Copyright (c) 1988, 1993 3*62313Sbostic * The Regents of the University of California. All rights reserved. 433686Sbostic * 544361Sborman * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*62313Sbostic static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 06/06/93"; 1033686Sbostic #endif /* not lint */ 1133686Sbostic 1232149Sminshall #define TELOPTS 1338690Sborman #define TELCMDS 1446808Sdab #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 4046808Sdab void 4132149Sminshall upcase(argument) 4246808Sdab 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 6046808Sdab int 6132149Sminshall SetSockOpt(fd, level, option, yesno) 6246808Sdab 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 8346808Sdab void 8438690Sborman SetNetTrace(file) 8546808Sdab 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) { 9246808Sdab strcpy((char *)NetTraceFile, file); 9338690Sborman return; 9438690Sborman } 9538690Sborman fprintf(stderr, "Cannot open %s.\n", file); 9638690Sborman } 9738690Sborman NetTrace = stdout; 9846808Sdab strcpy((char *)NetTraceFile, "(standard output)"); 9938690Sborman } 10038690Sborman 10146808Sdab void 10232149Sminshall Dump(direction, buffer, length) 10346808Sdab char direction; 10446808Sdab unsigned char *buffer; 10546808Sdab int length; 10632149Sminshall { 10732149Sminshall # define BYTES_PER_LINE 32 10832149Sminshall # define min(x,y) ((x<y)? x:y) 10946808Sdab 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 15346808Sdab void 15446808Sdab printoption(direction, cmd, option) 15546808Sdab char *direction; 15646808Sdab int cmd, option; 15732149Sminshall { 15832149Sminshall if (!showoptions) 15932149Sminshall return; 16046808Sdab if (cmd == IAC) { 16146808Sdab if (TELCMD_OK(option)) 16246808Sdab fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option)); 16346808Sdab else 16446808Sdab fprintf(NetTrace, "%s IAC %d", direction, option); 16546808Sdab } else { 16646808Sdab register char *fmt; 16746808Sdab fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" : 16846808Sdab (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0; 16946808Sdab if (fmt) { 17046808Sdab fprintf(NetTrace, "%s %s ", direction, fmt); 17146808Sdab if (TELOPT_OK(option)) 17246808Sdab fprintf(NetTrace, "%s", TELOPT(option)); 17346808Sdab else if (option == TELOPT_EXOPL) 17446808Sdab fprintf(NetTrace, "EXOPL"); 17546808Sdab else 17646808Sdab fprintf(NetTrace, "%d", option); 17746808Sdab } else 17846808Sdab fprintf(NetTrace, "%s %d %d", direction, cmd, option); 17946808Sdab } 18038690Sborman if (NetTrace == stdout) 18137226Sminshall fprintf(NetTrace, "\r\n"); 18238690Sborman else 18337226Sminshall fprintf(NetTrace, "\n"); 18437226Sminshall return; 18532149Sminshall } 18632149Sminshall 18746808Sdab 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 26446808Sdab void 26532149Sminshall printsub(direction, pointer, length) 26646808Sdab char direction; /* '<' or '>' */ 26746808Sdab unsigned char *pointer; /* where suboption data sits */ 26846808Sdab int length; /* length of suboption data */ 26932149Sminshall { 27038690Sborman register int i; 27147608Sdab char buf[512]; 27246808Sdab extern int want_status_response; 27338690Sborman 27446808Sdab if (showoptions || direction == 0 || 27546808Sdab (want_status_response && (pointer[0] == TELOPT_STATUS))) { 27638909Sborman if (direction) { 27746808Sdab fprintf(NetTrace, "%s IAC SB ", 27846808Sdab (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]) { 35357598Sdab case LFLOW_OFF: 35438690Sborman fprintf(NetTrace, " OFF"); break; 35557598Sdab case LFLOW_ON: 35638690Sborman fprintf(NetTrace, " ON"); break; 35757598Sdab case LFLOW_RESTART_ANY: 35857598Sdab fprintf(NetTrace, " RESTART-ANY"); break; 35957598Sdab case LFLOW_RESTART_XON: 36057598Sdab fprintf(NetTrace, " RESTART-XON"); break; 36138690Sborman default: 36244361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 36338690Sborman } 36438690Sborman for (i = 2; i < length; i++) 36538690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 36638690Sborman break; 36738690Sborman 36838690Sborman case TELOPT_NAWS: 36938690Sborman fprintf(NetTrace, "NAWS"); 37038690Sborman if (length < 2) { 37138690Sborman fprintf(NetTrace, " (empty suboption???)"); 37238690Sborman break; 37338690Sborman } 37438690Sborman if (length == 2) { 37538690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 37638690Sborman break; 37738690Sborman } 37838690Sborman fprintf(NetTrace, " %d %d (%d)", 37938690Sborman pointer[1], pointer[2], 38044361Sborman (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 38138690Sborman if (length == 4) { 38238690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 38338690Sborman break; 38438690Sborman } 38538690Sborman fprintf(NetTrace, " %d %d (%d)", 38638690Sborman pointer[3], pointer[4], 38744361Sborman (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 38838690Sborman for (i = 5; i < length; i++) 38938690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 39038690Sborman break; 39138690Sborman 39257213Sdab #if defined(AUTHENTICATION) 39343320Skfall case TELOPT_AUTHENTICATION: 39446808Sdab fprintf(NetTrace, "AUTHENTICATION"); 39546808Sdab if (length < 2) { 39646808Sdab fprintf(NetTrace, " (empty suboption???)"); 39746808Sdab break; 39846808Sdab } 39943320Skfall switch (pointer[1]) { 40046808Sdab case TELQUAL_REPLY: 40143320Skfall case TELQUAL_IS: 40246808Sdab fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? 40346808Sdab "IS" : "REPLY"); 40446808Sdab if (AUTHTYPE_NAME_OK(pointer[2])) 40546808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2])); 40646808Sdab else 40746808Sdab fprintf(NetTrace, "%d ", pointer[2]); 40846808Sdab if (length < 3) { 40946808Sdab fprintf(NetTrace, "(partial suboption???)"); 41046808Sdab break; 41146808Sdab } 41246808Sdab fprintf(NetTrace, "%s|%s", 41347608Sdab ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 41446808Sdab "CLIENT" : "SERVER", 41547608Sdab ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 41646808Sdab "MUTUAL" : "ONE-WAY"); 41743320Skfall 41846808Sdab auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 41946808Sdab fprintf(NetTrace, "%s", buf); 42046808Sdab break; 42146808Sdab 42246808Sdab case TELQUAL_SEND: 42346808Sdab i = 2; 42446808Sdab fprintf(NetTrace, " SEND "); 42546808Sdab while (i < length) { 42646808Sdab if (AUTHTYPE_NAME_OK(pointer[i])) 42746808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i])); 42846808Sdab else 42946808Sdab fprintf(NetTrace, "%d ", pointer[i]); 43046808Sdab if (++i >= length) { 43146808Sdab fprintf(NetTrace, "(partial suboption???)"); 43243320Skfall break; 43346808Sdab } 43446808Sdab fprintf(NetTrace, "%s|%s ", 43547608Sdab ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 43646808Sdab "CLIENT" : "SERVER", 43747608Sdab ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 43846808Sdab "MUTUAL" : "ONE-WAY"); 43946808Sdab ++i; 44043320Skfall } 44146808Sdab break; 44243320Skfall 44347608Sdab case TELQUAL_NAME: 44447608Sdab i = 2; 44547608Sdab fprintf(NetTrace, " NAME \""); 44647608Sdab while (i < length) 44747608Sdab putc(pointer[i++], NetTrace); 44847608Sdab putc('"', NetTrace); 44947608Sdab break; 45047608Sdab 45146808Sdab default: 45246808Sdab for (i = 2; i < length; i++) 45346808Sdab fprintf(NetTrace, " ?%d?", pointer[i]); 45446808Sdab break; 45543320Skfall } 45646808Sdab break; 45746808Sdab #endif 45846808Sdab 45960149Sdab #ifdef ENCRYPTION 46046808Sdab case TELOPT_ENCRYPT: 46146808Sdab fprintf(NetTrace, "ENCRYPT"); 46246808Sdab if (length < 2) { 46346808Sdab fprintf(NetTrace, " (empty suboption???)"); 46443320Skfall break; 46546808Sdab } 46646808Sdab switch (pointer[1]) { 46746808Sdab case ENCRYPT_START: 46846808Sdab fprintf(NetTrace, " START"); 46946808Sdab break; 47043320Skfall 47146808Sdab case ENCRYPT_END: 47246808Sdab fprintf(NetTrace, " END"); 47346808Sdab break; 47446808Sdab 47546808Sdab case ENCRYPT_REQSTART: 47646808Sdab fprintf(NetTrace, " REQUEST-START"); 47746808Sdab break; 47846808Sdab 47946808Sdab case ENCRYPT_REQEND: 48046808Sdab fprintf(NetTrace, " REQUEST-END"); 48146808Sdab break; 48246808Sdab 48346808Sdab case ENCRYPT_IS: 48446808Sdab case ENCRYPT_REPLY: 48546808Sdab fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? 48646808Sdab "IS" : "REPLY"); 48746808Sdab if (length < 3) { 48846808Sdab fprintf(NetTrace, " (partial suboption???)"); 48946808Sdab break; 49046808Sdab } 49146808Sdab if (ENCTYPE_NAME_OK(pointer[2])) 49246808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2])); 49346808Sdab else 49446808Sdab fprintf(NetTrace, " %d (unknown)", pointer[2]); 49546808Sdab 49646808Sdab encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 49746808Sdab fprintf(NetTrace, "%s", buf); 49846808Sdab break; 49946808Sdab 50046808Sdab case ENCRYPT_SUPPORT: 50146808Sdab i = 2; 50246808Sdab fprintf(NetTrace, " SUPPORT "); 50346808Sdab while (i < length) { 50446808Sdab if (ENCTYPE_NAME_OK(pointer[i])) 50546808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i])); 50646808Sdab else 50746808Sdab fprintf(NetTrace, "%d ", pointer[i]); 50846808Sdab i++; 50946808Sdab } 51046808Sdab break; 51146808Sdab 51247608Sdab case ENCRYPT_ENC_KEYID: 51347608Sdab fprintf(NetTrace, " ENC_KEYID "); 51447608Sdab goto encommon; 51547608Sdab 51647608Sdab case ENCRYPT_DEC_KEYID: 51747608Sdab fprintf(NetTrace, " DEC_KEYID "); 51847608Sdab goto encommon; 51947608Sdab 52043320Skfall default: 52147608Sdab fprintf(NetTrace, " %d (unknown)", pointer[1]); 52247608Sdab encommon: 52346808Sdab for (i = 2; i < length; i++) 52446808Sdab fprintf(NetTrace, " %d", pointer[i]); 52546808Sdab break; 52643320Skfall } 52743320Skfall break; 52860149Sdab #endif /* ENCRYPTION */ 52943320Skfall 53038690Sborman case TELOPT_LINEMODE: 53138690Sborman fprintf(NetTrace, "LINEMODE "); 53238690Sborman if (length < 2) { 53338690Sborman fprintf(NetTrace, " (empty suboption???)"); 53438690Sborman break; 53538690Sborman } 53638690Sborman switch (pointer[1]) { 53738690Sborman case WILL: 53838690Sborman fprintf(NetTrace, "WILL "); 53938690Sborman goto common; 54038690Sborman case WONT: 54138690Sborman fprintf(NetTrace, "WONT "); 54238690Sborman goto common; 54338690Sborman case DO: 54438690Sborman fprintf(NetTrace, "DO "); 54538690Sborman goto common; 54638690Sborman case DONT: 54738690Sborman fprintf(NetTrace, "DONT "); 54838690Sborman common: 54938690Sborman if (length < 3) { 55038690Sborman fprintf(NetTrace, "(no option???)"); 55138690Sborman break; 55238690Sborman } 55338690Sborman switch (pointer[2]) { 55438690Sborman case LM_FORWARDMASK: 55538690Sborman fprintf(NetTrace, "Forward Mask"); 55638690Sborman for (i = 3; i < length; i++) 55738690Sborman fprintf(NetTrace, " %x", pointer[i]); 55838690Sborman break; 55938690Sborman default: 56038690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 56138690Sborman for (i = 3; i < length; i++) 56238690Sborman fprintf(NetTrace, " %d", pointer[i]); 56338690Sborman break; 56438690Sborman } 56538690Sborman break; 56638690Sborman 56738690Sborman case LM_SLC: 56838690Sborman fprintf(NetTrace, "SLC"); 56938690Sborman for (i = 2; i < length - 2; i += 3) { 57046808Sdab if (SLC_NAME_OK(pointer[i+SLC_FUNC])) 57146808Sdab fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC])); 57238690Sborman else 57338690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 57438690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 57538690Sborman case SLC_NOSUPPORT: 57638690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 57738690Sborman case SLC_CANTCHANGE: 57838690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 57938690Sborman case SLC_VARIABLE: 58038690Sborman fprintf(NetTrace, " VARIABLE"); break; 58138690Sborman case SLC_DEFAULT: 58238690Sborman fprintf(NetTrace, " DEFAULT"); break; 58338690Sborman } 58438690Sborman fprintf(NetTrace, "%s%s%s", 58538690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 58638690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 58738690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 58838690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 58938690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 59038690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 59138690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 59244361Sborman if ((pointer[i+SLC_VALUE] == IAC) && 59344361Sborman (pointer[i+SLC_VALUE+1] == IAC)) 59444361Sborman i++; 59538690Sborman } 59638690Sborman for (; i < length; i++) 59738690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 59838690Sborman break; 59938690Sborman 60038690Sborman case LM_MODE: 60138690Sborman fprintf(NetTrace, "MODE "); 60238690Sborman if (length < 3) { 60338690Sborman fprintf(NetTrace, "(no mode???)"); 60438690Sborman break; 60538690Sborman } 60638690Sborman { 60744361Sborman char tbuf[64]; 60844361Sborman sprintf(tbuf, "%s%s%s%s%s", 60938690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 61038690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 61144361Sborman pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 61244361Sborman pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 61338690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 61438690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 61538690Sborman } 61646808Sdab if (pointer[2]&~(MODE_MASK)) 61738690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 61838690Sborman for (i = 3; i < length; i++) 61938690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 62038690Sborman break; 62138690Sborman default: 62238690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 62338690Sborman for (i = 2; i < length; i++) 62438690Sborman fprintf(NetTrace, " %d", pointer[i]); 62538690Sborman } 62638690Sborman break; 62738690Sborman 62838909Sborman case TELOPT_STATUS: { 62938909Sborman register char *cp; 63038909Sborman register int j, k; 63138909Sborman 63238909Sborman fprintf(NetTrace, "STATUS"); 63338909Sborman 63438909Sborman switch (pointer[1]) { 63538909Sborman default: 63638909Sborman if (pointer[1] == TELQUAL_SEND) 63738909Sborman fprintf(NetTrace, " SEND"); 63838909Sborman else 63944361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 64038909Sborman for (i = 2; i < length; i++) 64138909Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 64238909Sborman break; 64338909Sborman case TELQUAL_IS: 64446808Sdab if (--want_status_response < 0) 64546808Sdab want_status_response = 0; 64638909Sborman if (NetTrace == stdout) 64738909Sborman fprintf(NetTrace, " IS\r\n"); 64838909Sborman else 64938909Sborman fprintf(NetTrace, " IS\n"); 65038909Sborman 65138909Sborman for (i = 2; i < length; i++) { 65238909Sborman switch(pointer[i]) { 65338909Sborman case DO: cp = "DO"; goto common2; 65438909Sborman case DONT: cp = "DONT"; goto common2; 65538909Sborman case WILL: cp = "WILL"; goto common2; 65638909Sborman case WONT: cp = "WONT"; goto common2; 65738909Sborman common2: 65838909Sborman i++; 65944361Sborman if (TELOPT_OK((int)pointer[i])) 66038909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 66138909Sborman else 66238909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]); 66338909Sborman 66438909Sborman if (NetTrace == stdout) 66538909Sborman fprintf(NetTrace, "\r\n"); 66638909Sborman else 66738909Sborman fprintf(NetTrace, "\n"); 66838909Sborman break; 66938909Sborman 67038909Sborman case SB: 67138909Sborman fprintf(NetTrace, " SB "); 67238909Sborman i++; 67338909Sborman j = k = i; 67438909Sborman while (j < length) { 67538909Sborman if (pointer[j] == SE) { 67638909Sborman if (j+1 == length) 67738909Sborman break; 67838909Sborman if (pointer[j+1] == SE) 67938909Sborman j++; 68038909Sborman else 68138909Sborman break; 68238909Sborman } 68338909Sborman pointer[k++] = pointer[j++]; 68438909Sborman } 68538909Sborman printsub(0, &pointer[i], k - i); 68638909Sborman if (i < length) { 68738909Sborman fprintf(NetTrace, " SE"); 68838909Sborman i = j; 68938909Sborman } else 69038909Sborman i = j - 1; 69138909Sborman 69238909Sborman if (NetTrace == stdout) 69338909Sborman fprintf(NetTrace, "\r\n"); 69438909Sborman else 69538909Sborman fprintf(NetTrace, "\n"); 69638909Sborman 69738909Sborman break; 69838909Sborman 69938909Sborman default: 70038909Sborman fprintf(NetTrace, " %d", pointer[i]); 70138909Sborman break; 70238909Sborman } 70338909Sborman } 70438909Sborman break; 70538909Sborman } 70638909Sborman break; 70738909Sborman } 70838909Sborman 70944361Sborman case TELOPT_XDISPLOC: 71044361Sborman fprintf(NetTrace, "X-DISPLAY-LOCATION "); 71144361Sborman switch (pointer[1]) { 71244361Sborman case TELQUAL_IS: 71344361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 71444361Sborman break; 71544361Sborman case TELQUAL_SEND: 71644361Sborman fprintf(NetTrace, "SEND"); 71744361Sborman break; 71844361Sborman default: 71944361Sborman fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 72044361Sborman pointer[1], pointer[1]); 72144361Sborman } 72244361Sborman break; 72344361Sborman 72444361Sborman case TELOPT_ENVIRON: 72544361Sborman fprintf(NetTrace, "ENVIRON "); 72644361Sborman switch (pointer[1]) { 72744361Sborman case TELQUAL_IS: 72844361Sborman fprintf(NetTrace, "IS "); 72944361Sborman goto env_common; 73044361Sborman case TELQUAL_SEND: 73144361Sborman fprintf(NetTrace, "SEND "); 73244361Sborman goto env_common; 73344361Sborman case TELQUAL_INFO: 73444361Sborman fprintf(NetTrace, "INFO "); 73544361Sborman env_common: 73644361Sborman { 73744361Sborman register int noquote = 2; 73858972Sdab #ifdef ENV_HACK 73958972Sdab extern int env_var, env_value; 74058972Sdab #endif 74144361Sborman for (i = 2; i < length; i++ ) { 74244361Sborman switch (pointer[i]) { 74344361Sborman case ENV_VAR: 74458972Sdab #ifdef ENV_HACK 74558972Sdab if (env_var == ENV_VALUE) 74658972Sdab fprintf(NetTrace, "\" (VALUE) " + noquote); 74758972Sdab else 74858972Sdab #endif 74944361Sborman fprintf(NetTrace, "\" VAR " + noquote); 75044361Sborman noquote = 2; 75144361Sborman break; 75244361Sborman 75344361Sborman case ENV_VALUE: 75458972Sdab #ifdef ENV_HACK 75558972Sdab if (env_value == ENV_VAR) 75658972Sdab fprintf(NetTrace, "\" (VAR) " + noquote); 75758972Sdab else 75858972Sdab #endif 75944361Sborman fprintf(NetTrace, "\" VALUE " + noquote); 76044361Sborman noquote = 2; 76144361Sborman break; 76244361Sborman 76344361Sborman case ENV_ESC: 76444361Sborman fprintf(NetTrace, "\" ESC " + noquote); 76544361Sborman noquote = 2; 76644361Sborman break; 76744361Sborman 76857213Sdab case ENV_USERVAR: 76957213Sdab fprintf(NetTrace, "\" USERVAR " + noquote); 77057213Sdab noquote = 2; 77157213Sdab break; 77257213Sdab 77344361Sborman default: 77444361Sborman def_case: 77544361Sborman if (isprint(pointer[i]) && pointer[i] != '"') { 77644361Sborman if (noquote) { 77744361Sborman putc('"', NetTrace); 77844361Sborman noquote = 0; 77944361Sborman } 78044361Sborman putc(pointer[i], NetTrace); 78144361Sborman } else { 78244361Sborman fprintf(NetTrace, "\" %03o " + noquote, 78344361Sborman pointer[i]); 78444361Sborman noquote = 2; 78544361Sborman } 78644361Sborman break; 78744361Sborman } 78844361Sborman } 78944361Sborman if (!noquote) 79044361Sborman putc('"', NetTrace); 79144361Sborman break; 79244361Sborman } 79344361Sborman } 79444361Sborman break; 79544361Sborman 79632149Sminshall default: 79746808Sdab if (TELOPT_OK(pointer[0])) 79846808Sdab fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0])); 79946808Sdab else 80056860Storek fprintf(NetTrace, "%d (unknown)", pointer[0]); 80146808Sdab for (i = 1; i < length; i++) 80238690Sborman fprintf(NetTrace, " %d", pointer[i]); 80338690Sborman break; 80432149Sminshall } 80538909Sborman if (direction) { 80638909Sborman if (NetTrace == stdout) 80738909Sborman fprintf(NetTrace, "\r\n"); 80838909Sborman else 80938909Sborman fprintf(NetTrace, "\n"); 81038909Sborman } 81132149Sminshall } 81232149Sminshall } 81336278Sminshall 81436278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 81536278Sminshall * Note that we consider the buffer to run all the 81636278Sminshall * way to the kernel (thus the select). 81736278Sminshall */ 81836278Sminshall 81946808Sdab void 82036278Sminshall EmptyTerminal() 82136278Sminshall { 82236278Sminshall #if defined(unix) 82336278Sminshall fd_set o; 82436278Sminshall 82536278Sminshall FD_ZERO(&o); 82636278Sminshall #endif /* defined(unix) */ 82736278Sminshall 82836278Sminshall if (TTYBYTES() == 0) { 82936278Sminshall #if defined(unix) 83036278Sminshall FD_SET(tout, &o); 83136278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 83236278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 83336278Sminshall #endif /* defined(unix) */ 83436278Sminshall } else { 83536278Sminshall while (TTYBYTES()) { 83644361Sborman (void) ttyflush(0); 83736278Sminshall #if defined(unix) 83836278Sminshall FD_SET(tout, &o); 83936278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 84036278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 84136278Sminshall #endif /* defined(unix) */ 84236278Sminshall } 84336278Sminshall } 84436278Sminshall } 84536278Sminshall 84646808Sdab void 84736278Sminshall SetForExit() 84836278Sminshall { 84938690Sborman setconnmode(0); 85036278Sminshall #if defined(TN3270) 85136278Sminshall if (In3270) { 85236278Sminshall Finish3270(); 85336278Sminshall } 85436279Sminshall #else /* defined(TN3270) */ 85536279Sminshall do { 85644361Sborman (void)telrcv(); /* Process any incoming data */ 85736279Sminshall EmptyTerminal(); 85836279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 85936278Sminshall #endif /* defined(TN3270) */ 86036278Sminshall setcommandmode(); 86136278Sminshall fflush(stdout); 86236278Sminshall fflush(stderr); 86336278Sminshall #if defined(TN3270) 86436278Sminshall if (In3270) { 86536278Sminshall StopScreen(1); 86636278Sminshall } 86736278Sminshall #endif /* defined(TN3270) */ 86838690Sborman setconnmode(0); 86936278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 87036278Sminshall setcommandmode(); 87136278Sminshall } 87236278Sminshall 87346808Sdab void 87436278Sminshall Exit(returnCode) 87546808Sdab int returnCode; 87636278Sminshall { 87736278Sminshall SetForExit(); 87836278Sminshall exit(returnCode); 87936278Sminshall } 88036278Sminshall 88146808Sdab void 88236278Sminshall ExitString(string, returnCode) 88346808Sdab char *string; 88446808Sdab int returnCode; 88536278Sminshall { 88636278Sminshall SetForExit(); 88736278Sminshall fwrite(string, 1, strlen(string), stderr); 88836278Sminshall exit(returnCode); 88936278Sminshall } 890