133686Sbostic /* 262313Sbostic * Copyright (c) 1988, 1993 362313Sbostic * The Regents of the University of California. All rights reserved. 433686Sbostic * 544361Sborman * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*65157Sdab static char sccsid[] = "@(#)utilities.c 8.2 (Berkeley) 12/15/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 } 180*65157Sdab if (NetTrace == stdout) { 18137226Sminshall fprintf(NetTrace, "\r\n"); 182*65157Sdab fflush(NetTrace); 183*65157Sdab } else { 18437226Sminshall fprintf(NetTrace, "\n"); 185*65157Sdab } 18637226Sminshall return; 18732149Sminshall } 18832149Sminshall 18946808Sdab void 19038690Sborman optionstatus() 19138690Sborman { 19238690Sborman register int i; 19338690Sborman extern char will_wont_resp[], do_dont_resp[]; 19438690Sborman 19538690Sborman for (i = 0; i < 256; i++) { 19638690Sborman if (do_dont_resp[i]) { 19738690Sborman if (TELOPT_OK(i)) 19838690Sborman printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 19938690Sborman else if (TELCMD_OK(i)) 20038690Sborman printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 20138690Sborman else 20238690Sborman printf("resp DO_DONT %d: %d\n", i, 20338690Sborman do_dont_resp[i]); 20438690Sborman if (my_want_state_is_do(i)) { 20538690Sborman if (TELOPT_OK(i)) 20638690Sborman printf("want DO %s\n", TELOPT(i)); 20738690Sborman else if (TELCMD_OK(i)) 20838690Sborman printf("want DO %s\n", TELCMD(i)); 20938690Sborman else 21038690Sborman printf("want DO %d\n", i); 21138690Sborman } else { 21238690Sborman if (TELOPT_OK(i)) 21338690Sborman printf("want DONT %s\n", TELOPT(i)); 21438690Sborman else if (TELCMD_OK(i)) 21538690Sborman printf("want DONT %s\n", TELCMD(i)); 21638690Sborman else 21738690Sborman printf("want DONT %d\n", i); 21838690Sborman } 21938690Sborman } else { 22038690Sborman if (my_state_is_do(i)) { 22138690Sborman if (TELOPT_OK(i)) 22238690Sborman printf(" DO %s\n", TELOPT(i)); 22338690Sborman else if (TELCMD_OK(i)) 22438690Sborman printf(" DO %s\n", TELCMD(i)); 22538690Sborman else 22638690Sborman printf(" DO %d\n", i); 22738690Sborman } 22838690Sborman } 22938690Sborman if (will_wont_resp[i]) { 23038690Sborman if (TELOPT_OK(i)) 23138690Sborman printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 23238690Sborman else if (TELCMD_OK(i)) 23338690Sborman printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 23438690Sborman else 23538690Sborman printf("resp WILL_WONT %d: %d\n", 23638690Sborman i, will_wont_resp[i]); 23738690Sborman if (my_want_state_is_will(i)) { 23838690Sborman if (TELOPT_OK(i)) 23938690Sborman printf("want WILL %s\n", TELOPT(i)); 24038690Sborman else if (TELCMD_OK(i)) 24138690Sborman printf("want WILL %s\n", TELCMD(i)); 24238690Sborman else 24338690Sborman printf("want WILL %d\n", i); 24438690Sborman } else { 24538690Sborman if (TELOPT_OK(i)) 24638690Sborman printf("want WONT %s\n", TELOPT(i)); 24738690Sborman else if (TELCMD_OK(i)) 24838690Sborman printf("want WONT %s\n", TELCMD(i)); 24938690Sborman else 25038690Sborman printf("want WONT %d\n", i); 25138690Sborman } 25238690Sborman } else { 25338690Sborman if (my_state_is_will(i)) { 25438690Sborman if (TELOPT_OK(i)) 25538690Sborman printf(" WILL %s\n", TELOPT(i)); 25638690Sborman else if (TELCMD_OK(i)) 25738690Sborman printf(" WILL %s\n", TELCMD(i)); 25838690Sborman else 25938690Sborman printf(" WILL %d\n", i); 26038690Sborman } 26138690Sborman } 26238690Sborman } 26338690Sborman 26438690Sborman } 26538690Sborman 26646808Sdab void 26732149Sminshall printsub(direction, pointer, length) 26846808Sdab char direction; /* '<' or '>' */ 26946808Sdab unsigned char *pointer; /* where suboption data sits */ 27046808Sdab int length; /* length of suboption data */ 27132149Sminshall { 27238690Sborman register int i; 27347608Sdab char buf[512]; 27446808Sdab extern int want_status_response; 27538690Sborman 27646808Sdab if (showoptions || direction == 0 || 27746808Sdab (want_status_response && (pointer[0] == TELOPT_STATUS))) { 27838909Sborman if (direction) { 27946808Sdab fprintf(NetTrace, "%s IAC SB ", 28046808Sdab (direction == '<')? "RCVD":"SENT"); 28138909Sborman if (length >= 3) { 28238909Sborman register int j; 28338690Sborman 28438909Sborman i = pointer[length-2]; 28538909Sborman j = pointer[length-1]; 28638690Sborman 28738909Sborman if (i != IAC || j != SE) { 28838909Sborman fprintf(NetTrace, "(terminated by "); 28938909Sborman if (TELOPT_OK(i)) 29038909Sborman fprintf(NetTrace, "%s ", TELOPT(i)); 29138909Sborman else if (TELCMD_OK(i)) 29238909Sborman fprintf(NetTrace, "%s ", TELCMD(i)); 29338909Sborman else 29438909Sborman fprintf(NetTrace, "%d ", i); 29538909Sborman if (TELOPT_OK(j)) 29638909Sborman fprintf(NetTrace, "%s", TELOPT(j)); 29738909Sborman else if (TELCMD_OK(j)) 29838909Sborman fprintf(NetTrace, "%s", TELCMD(j)); 29938909Sborman else 30038909Sborman fprintf(NetTrace, "%d", j); 30138909Sborman fprintf(NetTrace, ", not IAC SE!) "); 30238909Sborman } 30338690Sborman } 30438909Sborman length -= 2; 30538690Sborman } 30638690Sborman if (length < 1) { 307*65157Sdab fprintf(NetTrace, "(Empty suboption??\?)"); 308*65157Sdab if (NetTrace == stdout) 309*65157Sdab fflush(NetTrace); 31038690Sborman return; 31138690Sborman } 31232149Sminshall switch (pointer[0]) { 31332149Sminshall case TELOPT_TTYPE: 31438690Sborman fprintf(NetTrace, "TERMINAL-TYPE "); 31532149Sminshall switch (pointer[1]) { 31632149Sminshall case TELQUAL_IS: 31744361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 31832149Sminshall break; 31932149Sminshall case TELQUAL_SEND: 32038690Sborman fprintf(NetTrace, "SEND"); 32132149Sminshall break; 32232149Sminshall default: 32332149Sminshall fprintf(NetTrace, 32438690Sborman "- unknown qualifier %d (0x%x).", 32534849Sminshall pointer[1], pointer[1]); 32632149Sminshall } 32732149Sminshall break; 32838690Sborman case TELOPT_TSPEED: 32938690Sborman fprintf(NetTrace, "TERMINAL-SPEED"); 33038690Sborman if (length < 2) { 331*65157Sdab fprintf(NetTrace, " (empty suboption??\?)"); 33238690Sborman break; 33338690Sborman } 33438690Sborman switch (pointer[1]) { 33538909Sborman case TELQUAL_IS: 33638690Sborman fprintf(NetTrace, " IS "); 33744361Sborman fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2); 33838690Sborman break; 33938690Sborman default: 34038690Sborman if (pointer[1] == 1) 34138690Sborman fprintf(NetTrace, " SEND"); 34238690Sborman else 34344361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 34438690Sborman for (i = 2; i < length; i++) 34538690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 34638690Sborman break; 34738690Sborman } 34838690Sborman break; 34938690Sborman 35038690Sborman case TELOPT_LFLOW: 35138690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 35238690Sborman if (length < 2) { 353*65157Sdab fprintf(NetTrace, " (empty suboption??\?)"); 35438690Sborman break; 35538690Sborman } 35638690Sborman switch (pointer[1]) { 35757598Sdab case LFLOW_OFF: 35838690Sborman fprintf(NetTrace, " OFF"); break; 35957598Sdab case LFLOW_ON: 36038690Sborman fprintf(NetTrace, " ON"); break; 36157598Sdab case LFLOW_RESTART_ANY: 36257598Sdab fprintf(NetTrace, " RESTART-ANY"); break; 36357598Sdab case LFLOW_RESTART_XON: 36457598Sdab fprintf(NetTrace, " RESTART-XON"); break; 36538690Sborman default: 36644361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 36738690Sborman } 36838690Sborman for (i = 2; i < length; i++) 36938690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 37038690Sborman break; 37138690Sborman 37238690Sborman case TELOPT_NAWS: 37338690Sborman fprintf(NetTrace, "NAWS"); 37438690Sborman if (length < 2) { 375*65157Sdab fprintf(NetTrace, " (empty suboption??\?)"); 37638690Sborman break; 37738690Sborman } 37838690Sborman if (length == 2) { 37938690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 38038690Sborman break; 38138690Sborman } 38238690Sborman fprintf(NetTrace, " %d %d (%d)", 38338690Sborman pointer[1], pointer[2], 38444361Sborman (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 38538690Sborman if (length == 4) { 38638690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 38738690Sborman break; 38838690Sborman } 38938690Sborman fprintf(NetTrace, " %d %d (%d)", 39038690Sborman pointer[3], pointer[4], 39144361Sborman (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 39238690Sborman for (i = 5; i < length; i++) 39338690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 39438690Sborman break; 39538690Sborman 39657213Sdab #if defined(AUTHENTICATION) 39743320Skfall case TELOPT_AUTHENTICATION: 39846808Sdab fprintf(NetTrace, "AUTHENTICATION"); 39946808Sdab if (length < 2) { 400*65157Sdab fprintf(NetTrace, " (empty suboption??\?)"); 40146808Sdab break; 40246808Sdab } 40343320Skfall switch (pointer[1]) { 40446808Sdab case TELQUAL_REPLY: 40543320Skfall case TELQUAL_IS: 40646808Sdab fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? 40746808Sdab "IS" : "REPLY"); 40846808Sdab if (AUTHTYPE_NAME_OK(pointer[2])) 40946808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2])); 41046808Sdab else 41146808Sdab fprintf(NetTrace, "%d ", pointer[2]); 41246808Sdab if (length < 3) { 413*65157Sdab fprintf(NetTrace, "(partial suboption??\?)"); 41446808Sdab break; 41546808Sdab } 41646808Sdab fprintf(NetTrace, "%s|%s", 41747608Sdab ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 41846808Sdab "CLIENT" : "SERVER", 41947608Sdab ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 42046808Sdab "MUTUAL" : "ONE-WAY"); 42143320Skfall 42246808Sdab auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 42346808Sdab fprintf(NetTrace, "%s", buf); 42446808Sdab break; 42546808Sdab 42646808Sdab case TELQUAL_SEND: 42746808Sdab i = 2; 42846808Sdab fprintf(NetTrace, " SEND "); 42946808Sdab while (i < length) { 43046808Sdab if (AUTHTYPE_NAME_OK(pointer[i])) 43146808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i])); 43246808Sdab else 43346808Sdab fprintf(NetTrace, "%d ", pointer[i]); 43446808Sdab if (++i >= length) { 435*65157Sdab fprintf(NetTrace, "(partial suboption??\?)"); 43643320Skfall break; 43746808Sdab } 43846808Sdab fprintf(NetTrace, "%s|%s ", 43947608Sdab ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 44046808Sdab "CLIENT" : "SERVER", 44147608Sdab ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 44246808Sdab "MUTUAL" : "ONE-WAY"); 44346808Sdab ++i; 44443320Skfall } 44546808Sdab break; 44643320Skfall 44747608Sdab case TELQUAL_NAME: 44847608Sdab i = 2; 44947608Sdab fprintf(NetTrace, " NAME \""); 45047608Sdab while (i < length) 45147608Sdab putc(pointer[i++], NetTrace); 45247608Sdab putc('"', NetTrace); 45347608Sdab break; 45447608Sdab 45546808Sdab default: 45646808Sdab for (i = 2; i < length; i++) 45746808Sdab fprintf(NetTrace, " ?%d?", pointer[i]); 45846808Sdab break; 45943320Skfall } 46046808Sdab break; 46146808Sdab #endif 46246808Sdab 46360149Sdab #ifdef ENCRYPTION 46446808Sdab case TELOPT_ENCRYPT: 46546808Sdab fprintf(NetTrace, "ENCRYPT"); 46646808Sdab if (length < 2) { 467*65157Sdab fprintf(NetTrace, " (empty suboption??\?)"); 46843320Skfall break; 46946808Sdab } 47046808Sdab switch (pointer[1]) { 47146808Sdab case ENCRYPT_START: 47246808Sdab fprintf(NetTrace, " START"); 47346808Sdab break; 47443320Skfall 47546808Sdab case ENCRYPT_END: 47646808Sdab fprintf(NetTrace, " END"); 47746808Sdab break; 47846808Sdab 47946808Sdab case ENCRYPT_REQSTART: 48046808Sdab fprintf(NetTrace, " REQUEST-START"); 48146808Sdab break; 48246808Sdab 48346808Sdab case ENCRYPT_REQEND: 48446808Sdab fprintf(NetTrace, " REQUEST-END"); 48546808Sdab break; 48646808Sdab 48746808Sdab case ENCRYPT_IS: 48846808Sdab case ENCRYPT_REPLY: 48946808Sdab fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? 49046808Sdab "IS" : "REPLY"); 49146808Sdab if (length < 3) { 492*65157Sdab fprintf(NetTrace, " (partial suboption??\?)"); 49346808Sdab break; 49446808Sdab } 49546808Sdab if (ENCTYPE_NAME_OK(pointer[2])) 49646808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2])); 49746808Sdab else 49846808Sdab fprintf(NetTrace, " %d (unknown)", pointer[2]); 49946808Sdab 50046808Sdab encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 50146808Sdab fprintf(NetTrace, "%s", buf); 50246808Sdab break; 50346808Sdab 50446808Sdab case ENCRYPT_SUPPORT: 50546808Sdab i = 2; 50646808Sdab fprintf(NetTrace, " SUPPORT "); 50746808Sdab while (i < length) { 50846808Sdab if (ENCTYPE_NAME_OK(pointer[i])) 50946808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i])); 51046808Sdab else 51146808Sdab fprintf(NetTrace, "%d ", pointer[i]); 51246808Sdab i++; 51346808Sdab } 51446808Sdab break; 51546808Sdab 51647608Sdab case ENCRYPT_ENC_KEYID: 51747608Sdab fprintf(NetTrace, " ENC_KEYID "); 51847608Sdab goto encommon; 51947608Sdab 52047608Sdab case ENCRYPT_DEC_KEYID: 52147608Sdab fprintf(NetTrace, " DEC_KEYID "); 52247608Sdab goto encommon; 52347608Sdab 52443320Skfall default: 52547608Sdab fprintf(NetTrace, " %d (unknown)", pointer[1]); 52647608Sdab encommon: 52746808Sdab for (i = 2; i < length; i++) 52846808Sdab fprintf(NetTrace, " %d", pointer[i]); 52946808Sdab break; 53043320Skfall } 53143320Skfall break; 53260149Sdab #endif /* ENCRYPTION */ 53343320Skfall 53438690Sborman case TELOPT_LINEMODE: 53538690Sborman fprintf(NetTrace, "LINEMODE "); 53638690Sborman if (length < 2) { 537*65157Sdab fprintf(NetTrace, " (empty suboption??\?)"); 53838690Sborman break; 53938690Sborman } 54038690Sborman switch (pointer[1]) { 54138690Sborman case WILL: 54238690Sborman fprintf(NetTrace, "WILL "); 54338690Sborman goto common; 54438690Sborman case WONT: 54538690Sborman fprintf(NetTrace, "WONT "); 54638690Sborman goto common; 54738690Sborman case DO: 54838690Sborman fprintf(NetTrace, "DO "); 54938690Sborman goto common; 55038690Sborman case DONT: 55138690Sborman fprintf(NetTrace, "DONT "); 55238690Sborman common: 55338690Sborman if (length < 3) { 554*65157Sdab fprintf(NetTrace, "(no option??\?)"); 55538690Sborman break; 55638690Sborman } 55738690Sborman switch (pointer[2]) { 55838690Sborman case LM_FORWARDMASK: 55938690Sborman fprintf(NetTrace, "Forward Mask"); 56038690Sborman for (i = 3; i < length; i++) 56138690Sborman fprintf(NetTrace, " %x", pointer[i]); 56238690Sborman break; 56338690Sborman default: 56438690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 56538690Sborman for (i = 3; i < length; i++) 56638690Sborman fprintf(NetTrace, " %d", pointer[i]); 56738690Sborman break; 56838690Sborman } 56938690Sborman break; 57038690Sborman 57138690Sborman case LM_SLC: 57238690Sborman fprintf(NetTrace, "SLC"); 57338690Sborman for (i = 2; i < length - 2; i += 3) { 57446808Sdab if (SLC_NAME_OK(pointer[i+SLC_FUNC])) 57546808Sdab fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC])); 57638690Sborman else 57738690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 57838690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 57938690Sborman case SLC_NOSUPPORT: 58038690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 58138690Sborman case SLC_CANTCHANGE: 58238690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 58338690Sborman case SLC_VARIABLE: 58438690Sborman fprintf(NetTrace, " VARIABLE"); break; 58538690Sborman case SLC_DEFAULT: 58638690Sborman fprintf(NetTrace, " DEFAULT"); break; 58738690Sborman } 58838690Sborman fprintf(NetTrace, "%s%s%s", 58938690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 59038690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 59138690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 59238690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 59338690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 59438690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 59538690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 59644361Sborman if ((pointer[i+SLC_VALUE] == IAC) && 59744361Sborman (pointer[i+SLC_VALUE+1] == IAC)) 59844361Sborman i++; 59938690Sborman } 60038690Sborman for (; i < length; i++) 60138690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 60238690Sborman break; 60338690Sborman 60438690Sborman case LM_MODE: 60538690Sborman fprintf(NetTrace, "MODE "); 60638690Sborman if (length < 3) { 607*65157Sdab fprintf(NetTrace, "(no mode??\?)"); 60838690Sborman break; 60938690Sborman } 61038690Sborman { 61144361Sborman char tbuf[64]; 61244361Sborman sprintf(tbuf, "%s%s%s%s%s", 61338690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 61438690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 61544361Sborman pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 61644361Sborman pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 61738690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 61838690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 61938690Sborman } 62046808Sdab if (pointer[2]&~(MODE_MASK)) 62138690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 62238690Sborman for (i = 3; i < length; i++) 62338690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 62438690Sborman break; 62538690Sborman default: 62638690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 62738690Sborman for (i = 2; i < length; i++) 62838690Sborman fprintf(NetTrace, " %d", pointer[i]); 62938690Sborman } 63038690Sborman break; 63138690Sborman 63238909Sborman case TELOPT_STATUS: { 63338909Sborman register char *cp; 63438909Sborman register int j, k; 63538909Sborman 63638909Sborman fprintf(NetTrace, "STATUS"); 63738909Sborman 63838909Sborman switch (pointer[1]) { 63938909Sborman default: 64038909Sborman if (pointer[1] == TELQUAL_SEND) 64138909Sborman fprintf(NetTrace, " SEND"); 64238909Sborman else 64344361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 64438909Sborman for (i = 2; i < length; i++) 64538909Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 64638909Sborman break; 64738909Sborman case TELQUAL_IS: 64846808Sdab if (--want_status_response < 0) 64946808Sdab want_status_response = 0; 65038909Sborman if (NetTrace == stdout) 65138909Sborman fprintf(NetTrace, " IS\r\n"); 65238909Sborman else 65338909Sborman fprintf(NetTrace, " IS\n"); 65438909Sborman 65538909Sborman for (i = 2; i < length; i++) { 65638909Sborman switch(pointer[i]) { 65738909Sborman case DO: cp = "DO"; goto common2; 65838909Sborman case DONT: cp = "DONT"; goto common2; 65938909Sborman case WILL: cp = "WILL"; goto common2; 66038909Sborman case WONT: cp = "WONT"; goto common2; 66138909Sborman common2: 66238909Sborman i++; 66344361Sborman if (TELOPT_OK((int)pointer[i])) 66438909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 66538909Sborman else 66638909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]); 66738909Sborman 66838909Sborman if (NetTrace == stdout) 66938909Sborman fprintf(NetTrace, "\r\n"); 67038909Sborman else 67138909Sborman fprintf(NetTrace, "\n"); 67238909Sborman break; 67338909Sborman 67438909Sborman case SB: 67538909Sborman fprintf(NetTrace, " SB "); 67638909Sborman i++; 67738909Sborman j = k = i; 67838909Sborman while (j < length) { 67938909Sborman if (pointer[j] == SE) { 68038909Sborman if (j+1 == length) 68138909Sborman break; 68238909Sborman if (pointer[j+1] == SE) 68338909Sborman j++; 68438909Sborman else 68538909Sborman break; 68638909Sborman } 68738909Sborman pointer[k++] = pointer[j++]; 68838909Sborman } 68938909Sborman printsub(0, &pointer[i], k - i); 69038909Sborman if (i < length) { 69138909Sborman fprintf(NetTrace, " SE"); 69238909Sborman i = j; 69338909Sborman } else 69438909Sborman i = j - 1; 69538909Sborman 69638909Sborman if (NetTrace == stdout) 69738909Sborman fprintf(NetTrace, "\r\n"); 69838909Sborman else 69938909Sborman fprintf(NetTrace, "\n"); 70038909Sborman 70138909Sborman break; 70238909Sborman 70338909Sborman default: 70438909Sborman fprintf(NetTrace, " %d", pointer[i]); 70538909Sborman break; 70638909Sborman } 70738909Sborman } 70838909Sborman break; 70938909Sborman } 71038909Sborman break; 71138909Sborman } 71238909Sborman 71344361Sborman case TELOPT_XDISPLOC: 71444361Sborman fprintf(NetTrace, "X-DISPLAY-LOCATION "); 71544361Sborman switch (pointer[1]) { 71644361Sborman case TELQUAL_IS: 71744361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 71844361Sborman break; 71944361Sborman case TELQUAL_SEND: 72044361Sborman fprintf(NetTrace, "SEND"); 72144361Sborman break; 72244361Sborman default: 72344361Sborman fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 72444361Sborman pointer[1], pointer[1]); 72544361Sborman } 72644361Sborman break; 72744361Sborman 728*65157Sdab case TELOPT_NEW_ENVIRON: 729*65157Sdab fprintf(NetTrace, "NEW-ENVIRON "); 730*65157Sdab #ifdef OLD_ENVIRON 731*65157Sdab goto env_common1; 732*65157Sdab case TELOPT_OLD_ENVIRON: 733*65157Sdab fprintf(NetTrace, "OLD-ENVIRON"); 734*65157Sdab env_common1: 735*65157Sdab #endif 73644361Sborman switch (pointer[1]) { 73744361Sborman case TELQUAL_IS: 73844361Sborman fprintf(NetTrace, "IS "); 73944361Sborman goto env_common; 74044361Sborman case TELQUAL_SEND: 74144361Sborman fprintf(NetTrace, "SEND "); 74244361Sborman goto env_common; 74344361Sborman case TELQUAL_INFO: 74444361Sborman fprintf(NetTrace, "INFO "); 74544361Sborman env_common: 74644361Sborman { 74744361Sborman register int noquote = 2; 748*65157Sdab #if defined(ENV_HACK) && defined(OLD_ENVIRON) 749*65157Sdab extern int old_env_var, old_env_value; 75058972Sdab #endif 75144361Sborman for (i = 2; i < length; i++ ) { 75244361Sborman switch (pointer[i]) { 753*65157Sdab case NEW_ENV_VALUE: 754*65157Sdab #ifdef OLD_ENVIRON 755*65157Sdab /* case NEW_ENV_OVAR: */ 756*65157Sdab if (pointer[0] == TELOPT_OLD_ENVIRON) { 757*65157Sdab # ifdef ENV_HACK 758*65157Sdab if (old_env_var == OLD_ENV_VALUE) 759*65157Sdab fprintf(NetTrace, "\" (VALUE) " + noquote); 760*65157Sdab else 761*65157Sdab # endif 762*65157Sdab fprintf(NetTrace, "\" VAR " + noquote); 763*65157Sdab } else 764*65157Sdab #endif /* OLD_ENVIRON */ 765*65157Sdab fprintf(NetTrace, "\" VALUE " + noquote); 76644361Sborman noquote = 2; 76744361Sborman break; 76844361Sborman 769*65157Sdab case NEW_ENV_VAR: 770*65157Sdab #ifdef OLD_ENVIRON 771*65157Sdab /* case OLD_ENV_VALUE: */ 772*65157Sdab if (pointer[0] == TELOPT_OLD_ENVIRON) { 773*65157Sdab # ifdef ENV_HACK 774*65157Sdab if (old_env_value == OLD_ENV_VAR) 775*65157Sdab fprintf(NetTrace, "\" (VAR) " + noquote); 776*65157Sdab else 777*65157Sdab # endif 778*65157Sdab fprintf(NetTrace, "\" VALUE " + noquote); 779*65157Sdab } else 780*65157Sdab #endif /* OLD_ENVIRON */ 781*65157Sdab fprintf(NetTrace, "\" VAR " + noquote); 78244361Sborman noquote = 2; 78344361Sborman break; 78444361Sborman 78544361Sborman case ENV_ESC: 78644361Sborman fprintf(NetTrace, "\" ESC " + noquote); 78744361Sborman noquote = 2; 78844361Sborman break; 78944361Sborman 79057213Sdab case ENV_USERVAR: 79157213Sdab fprintf(NetTrace, "\" USERVAR " + noquote); 79257213Sdab noquote = 2; 79357213Sdab break; 79457213Sdab 79544361Sborman default: 79644361Sborman def_case: 79744361Sborman if (isprint(pointer[i]) && pointer[i] != '"') { 79844361Sborman if (noquote) { 79944361Sborman putc('"', NetTrace); 80044361Sborman noquote = 0; 80144361Sborman } 80244361Sborman putc(pointer[i], NetTrace); 80344361Sborman } else { 80444361Sborman fprintf(NetTrace, "\" %03o " + noquote, 80544361Sborman pointer[i]); 80644361Sborman noquote = 2; 80744361Sborman } 80844361Sborman break; 80944361Sborman } 81044361Sborman } 81144361Sborman if (!noquote) 81244361Sborman putc('"', NetTrace); 81344361Sborman break; 81444361Sborman } 81544361Sborman } 81644361Sborman break; 81744361Sborman 81832149Sminshall default: 81946808Sdab if (TELOPT_OK(pointer[0])) 82046808Sdab fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0])); 82146808Sdab else 82256860Storek fprintf(NetTrace, "%d (unknown)", pointer[0]); 82346808Sdab for (i = 1; i < length; i++) 82438690Sborman fprintf(NetTrace, " %d", pointer[i]); 82538690Sborman break; 82632149Sminshall } 82738909Sborman if (direction) { 82838909Sborman if (NetTrace == stdout) 82938909Sborman fprintf(NetTrace, "\r\n"); 83038909Sborman else 83138909Sborman fprintf(NetTrace, "\n"); 83238909Sborman } 833*65157Sdab if (NetTrace == stdout) 834*65157Sdab fflush(NetTrace); 83532149Sminshall } 83632149Sminshall } 83736278Sminshall 83836278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 83936278Sminshall * Note that we consider the buffer to run all the 84036278Sminshall * way to the kernel (thus the select). 84136278Sminshall */ 84236278Sminshall 84346808Sdab void 84436278Sminshall EmptyTerminal() 84536278Sminshall { 84636278Sminshall #if defined(unix) 84736278Sminshall fd_set o; 84836278Sminshall 84936278Sminshall FD_ZERO(&o); 85036278Sminshall #endif /* defined(unix) */ 85136278Sminshall 85236278Sminshall if (TTYBYTES() == 0) { 85336278Sminshall #if defined(unix) 85436278Sminshall FD_SET(tout, &o); 85536278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 85636278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 85736278Sminshall #endif /* defined(unix) */ 85836278Sminshall } else { 85936278Sminshall while (TTYBYTES()) { 86044361Sborman (void) ttyflush(0); 86136278Sminshall #if defined(unix) 86236278Sminshall FD_SET(tout, &o); 86336278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 86436278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 86536278Sminshall #endif /* defined(unix) */ 86636278Sminshall } 86736278Sminshall } 86836278Sminshall } 86936278Sminshall 87046808Sdab void 87136278Sminshall SetForExit() 87236278Sminshall { 87338690Sborman setconnmode(0); 87436278Sminshall #if defined(TN3270) 87536278Sminshall if (In3270) { 87636278Sminshall Finish3270(); 87736278Sminshall } 87836279Sminshall #else /* defined(TN3270) */ 87936279Sminshall do { 88044361Sborman (void)telrcv(); /* Process any incoming data */ 88136279Sminshall EmptyTerminal(); 88236279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 88336278Sminshall #endif /* defined(TN3270) */ 88436278Sminshall setcommandmode(); 88536278Sminshall fflush(stdout); 88636278Sminshall fflush(stderr); 88736278Sminshall #if defined(TN3270) 88836278Sminshall if (In3270) { 88936278Sminshall StopScreen(1); 89036278Sminshall } 89136278Sminshall #endif /* defined(TN3270) */ 89238690Sborman setconnmode(0); 89336278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 89436278Sminshall setcommandmode(); 89536278Sminshall } 89636278Sminshall 89746808Sdab void 89836278Sminshall Exit(returnCode) 89946808Sdab int returnCode; 90036278Sminshall { 90136278Sminshall SetForExit(); 90236278Sminshall exit(returnCode); 90336278Sminshall } 90436278Sminshall 90546808Sdab void 90636278Sminshall ExitString(string, returnCode) 90746808Sdab char *string; 90846808Sdab int returnCode; 90936278Sminshall { 91036278Sminshall SetForExit(); 91136278Sminshall fwrite(string, 1, strlen(string), stderr); 91236278Sminshall exit(returnCode); 91336278Sminshall } 914