133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 5*44361Sborman * %sccs.include.redist.c% 633686Sbostic */ 733686Sbostic 833686Sbostic #ifndef lint 9*44361Sborman static char sccsid[] = "@(#)utilities.c 1.19 (Berkeley) 06/28/90"; 1033686Sbostic #endif /* not lint */ 1133686Sbostic 1232149Sminshall #define TELOPTS 1338690Sborman #define TELCMDS 1432149Sminshall #include <arpa/telnet.h> 1532381Sminshall #include <sys/types.h> 16*44361Sborman #include <sys/time.h> 1732149Sminshall 1832149Sminshall #include <ctype.h> 1932149Sminshall 2034305Sminshall #include "general.h" 2134305Sminshall 2236280Sminshall #include "fdset.h" 2336280Sminshall 2432381Sminshall #include "ring.h" 2532381Sminshall 2636278Sminshall #include "defines.h" 2736278Sminshall 2832149Sminshall #include "externs.h" 2932149Sminshall 3032149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 3138690Sborman int prettydump; 3232149Sminshall 3332149Sminshall /* 3432149Sminshall * upcase() 3532149Sminshall * 3632149Sminshall * Upcase (in place) the argument. 3732149Sminshall */ 3832149Sminshall 3932149Sminshall void 4032149Sminshall upcase(argument) 4132149Sminshall register char *argument; 4232149Sminshall { 4332149Sminshall register int c; 4432149Sminshall 4532149Sminshall while ((c = *argument) != 0) { 4632149Sminshall if (islower(c)) { 4732149Sminshall *argument = toupper(c); 4832149Sminshall } 4932149Sminshall argument++; 5032149Sminshall } 5132149Sminshall } 5232149Sminshall 5332149Sminshall /* 5432149Sminshall * SetSockOpt() 5532149Sminshall * 5632149Sminshall * Compensate for differences in 4.2 and 4.3 systems. 5732149Sminshall */ 5832149Sminshall 5932149Sminshall int 6032149Sminshall SetSockOpt(fd, level, option, yesno) 6132149Sminshall int 6232149Sminshall fd, 6332149Sminshall level, 6432149Sminshall option, 6532149Sminshall yesno; 6632149Sminshall { 6732149Sminshall #ifndef NOT43 6832149Sminshall return setsockopt(fd, level, option, 6932149Sminshall (char *)&yesno, sizeof yesno); 7032149Sminshall #else /* NOT43 */ 7132149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */ 7232149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 7332149Sminshall option); 7432149Sminshall return -1; 7532149Sminshall } 7632149Sminshall return setsockopt(fd, level, option, 0, 0); 7732149Sminshall #endif /* NOT43 */ 7832149Sminshall } 7932149Sminshall 8032149Sminshall /* 8132149Sminshall * The following are routines used to print out debugging information. 8232149Sminshall */ 8332149Sminshall 8439529Sborman unsigned char NetTraceFile[256] = "(standard output)"; 8532149Sminshall 8632149Sminshall void 8738690Sborman SetNetTrace(file) 8838690Sborman register char *file; 8938690Sborman { 9038690Sborman if (NetTrace && NetTrace != stdout) 9138690Sborman fclose(NetTrace); 9238690Sborman if (file && (strcmp(file, "-") != 0)) { 9338690Sborman NetTrace = fopen(file, "w"); 9438690Sborman if (NetTrace) { 9538690Sborman strcpy(NetTraceFile, file); 9638690Sborman return; 9738690Sborman } 9838690Sborman fprintf(stderr, "Cannot open %s.\n", file); 9938690Sborman } 10038690Sborman NetTrace = stdout; 10138690Sborman strcpy(NetTraceFile, "(standard output)"); 10238690Sborman } 10338690Sborman 10438690Sborman void 10532149Sminshall Dump(direction, buffer, length) 10632149Sminshall char direction; 10732149Sminshall char *buffer; 10832149Sminshall int length; 10932149Sminshall { 11032149Sminshall # define BYTES_PER_LINE 32 11132149Sminshall # define min(x,y) ((x<y)? x:y) 11232149Sminshall char *pThis; 11332149Sminshall int offset; 11438690Sborman extern pettydump; 11532149Sminshall 11632149Sminshall offset = 0; 11732149Sminshall 11832149Sminshall while (length) { 11932149Sminshall /* print one line */ 12032149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset); 12132149Sminshall pThis = buffer; 12238690Sborman if (prettydump) { 12338909Sborman buffer = buffer + min(length, BYTES_PER_LINE/2); 12438690Sborman while (pThis < buffer) { 12538690Sborman fprintf(NetTrace, "%c%.2x", 12638690Sborman (((*pThis)&0xff) == 0xff) ? '*' : ' ', 12738690Sborman (*pThis)&0xff); 12838690Sborman pThis++; 12938690Sborman } 13038909Sborman length -= BYTES_PER_LINE/2; 13138909Sborman offset += BYTES_PER_LINE/2; 13238690Sborman } else { 13338909Sborman buffer = buffer + min(length, BYTES_PER_LINE); 13438690Sborman while (pThis < buffer) { 13538690Sborman fprintf(NetTrace, "%.2x", (*pThis)&0xff); 13638690Sborman pThis++; 13738690Sborman } 13838909Sborman length -= BYTES_PER_LINE; 13938909Sborman offset += BYTES_PER_LINE; 14032149Sminshall } 14137226Sminshall if (NetTrace == stdout) { 14238207Sminshall fprintf(NetTrace, "\r\n"); 14338207Sminshall } else { 14437226Sminshall fprintf(NetTrace, "\n"); 14537226Sminshall } 14632149Sminshall if (length < 0) { 14736693Sminshall fflush(NetTrace); 14832149Sminshall return; 14932149Sminshall } 15032149Sminshall /* find next unique line */ 15132149Sminshall } 15236693Sminshall fflush(NetTrace); 15332149Sminshall } 15432149Sminshall 15532149Sminshall 15632149Sminshall void 15737226Sminshall printoption(direction, fmt, option) 15832149Sminshall char *direction, *fmt; 15937226Sminshall int option; 16032149Sminshall { 16132149Sminshall if (!showoptions) 16232149Sminshall return; 16337226Sminshall fprintf(NetTrace, "%s ", direction); 16438690Sborman if (TELOPT_OK(option)) 16538690Sborman fprintf(NetTrace, "%s %s", fmt, TELOPT(option)); 16638690Sborman else if (TELCMD_OK(option)) 16738690Sborman fprintf(NetTrace, "%s %s", fmt, TELCMD(option)); 16832149Sminshall else 16932149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 17038690Sborman if (NetTrace == stdout) 17137226Sminshall fprintf(NetTrace, "\r\n"); 17238690Sborman else 17337226Sminshall fprintf(NetTrace, "\n"); 17437226Sminshall return; 17532149Sminshall } 17632149Sminshall 17738690Sborman optionstatus() 17838690Sborman { 17938690Sborman register int i; 18038690Sborman extern char will_wont_resp[], do_dont_resp[]; 18138690Sborman 18238690Sborman for (i = 0; i < 256; i++) { 18338690Sborman if (do_dont_resp[i]) { 18438690Sborman if (TELOPT_OK(i)) 18538690Sborman printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 18638690Sborman else if (TELCMD_OK(i)) 18738690Sborman printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 18838690Sborman else 18938690Sborman printf("resp DO_DONT %d: %d\n", i, 19038690Sborman do_dont_resp[i]); 19138690Sborman if (my_want_state_is_do(i)) { 19238690Sborman if (TELOPT_OK(i)) 19338690Sborman printf("want DO %s\n", TELOPT(i)); 19438690Sborman else if (TELCMD_OK(i)) 19538690Sborman printf("want DO %s\n", TELCMD(i)); 19638690Sborman else 19738690Sborman printf("want DO %d\n", i); 19838690Sborman } else { 19938690Sborman if (TELOPT_OK(i)) 20038690Sborman printf("want DONT %s\n", TELOPT(i)); 20138690Sborman else if (TELCMD_OK(i)) 20238690Sborman printf("want DONT %s\n", TELCMD(i)); 20338690Sborman else 20438690Sborman printf("want DONT %d\n", i); 20538690Sborman } 20638690Sborman } else { 20738690Sborman if (my_state_is_do(i)) { 20838690Sborman if (TELOPT_OK(i)) 20938690Sborman printf(" DO %s\n", TELOPT(i)); 21038690Sborman else if (TELCMD_OK(i)) 21138690Sborman printf(" DO %s\n", TELCMD(i)); 21238690Sborman else 21338690Sborman printf(" DO %d\n", i); 21438690Sborman } 21538690Sborman } 21638690Sborman if (will_wont_resp[i]) { 21738690Sborman if (TELOPT_OK(i)) 21838690Sborman printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 21938690Sborman else if (TELCMD_OK(i)) 22038690Sborman printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 22138690Sborman else 22238690Sborman printf("resp WILL_WONT %d: %d\n", 22338690Sborman i, will_wont_resp[i]); 22438690Sborman if (my_want_state_is_will(i)) { 22538690Sborman if (TELOPT_OK(i)) 22638690Sborman printf("want WILL %s\n", TELOPT(i)); 22738690Sborman else if (TELCMD_OK(i)) 22838690Sborman printf("want WILL %s\n", TELCMD(i)); 22938690Sborman else 23038690Sborman printf("want WILL %d\n", i); 23138690Sborman } else { 23238690Sborman if (TELOPT_OK(i)) 23338690Sborman printf("want WONT %s\n", TELOPT(i)); 23438690Sborman else if (TELCMD_OK(i)) 23538690Sborman printf("want WONT %s\n", TELCMD(i)); 23638690Sborman else 23738690Sborman printf("want WONT %d\n", i); 23838690Sborman } 23938690Sborman } else { 24038690Sborman if (my_state_is_will(i)) { 24138690Sborman if (TELOPT_OK(i)) 24238690Sborman printf(" WILL %s\n", TELOPT(i)); 24338690Sborman else if (TELCMD_OK(i)) 24438690Sborman printf(" WILL %s\n", TELCMD(i)); 24538690Sborman else 24638690Sborman printf(" WILL %d\n", i); 24738690Sborman } 24838690Sborman } 24938690Sborman } 25038690Sborman 25138690Sborman } 25238690Sborman 25338690Sborman char *slcnames[] = { SLC_NAMES }; 25438690Sborman 25543320Skfall #ifdef KERBEROS 25643320Skfall static char *authtypes[3] = { "NONE", "PRIVATE", "KERBEROS" }; 25743320Skfall #endif 25843320Skfall 25932149Sminshall void 26032149Sminshall printsub(direction, pointer, length) 26138690Sborman char direction; /* '<' or '>' */ 26238690Sborman unsigned char *pointer; /* where suboption data sits */ 26332149Sminshall int length; /* length of suboption data */ 26432149Sminshall { 26538690Sborman register int i; 26638690Sborman 26732149Sminshall if (showoptions) { 26838909Sborman if (direction) { 26938909Sborman fprintf(NetTrace, "%s suboption ", 27038690Sborman (direction == '<')? "Received":"Sent"); 27138909Sborman if (length >= 3) { 27238909Sborman register int j; 27338690Sborman 27438909Sborman i = pointer[length-2]; 27538909Sborman j = pointer[length-1]; 27638690Sborman 27738909Sborman if (i != IAC || j != SE) { 27838909Sborman fprintf(NetTrace, "(terminated by "); 27938909Sborman if (TELOPT_OK(i)) 28038909Sborman fprintf(NetTrace, "%s ", TELOPT(i)); 28138909Sborman else if (TELCMD_OK(i)) 28238909Sborman fprintf(NetTrace, "%s ", TELCMD(i)); 28338909Sborman else 28438909Sborman fprintf(NetTrace, "%d ", i); 28538909Sborman if (TELOPT_OK(j)) 28638909Sborman fprintf(NetTrace, "%s", TELOPT(j)); 28738909Sborman else if (TELCMD_OK(j)) 28838909Sborman fprintf(NetTrace, "%s", TELCMD(j)); 28938909Sborman else 29038909Sborman fprintf(NetTrace, "%d", j); 29138909Sborman fprintf(NetTrace, ", not IAC SE!) "); 29238909Sborman } 29338690Sborman } 29438909Sborman length -= 2; 29538690Sborman } 29638690Sborman if (length < 1) { 29738690Sborman fprintf(NetTrace, "(Empty suboption???)"); 29838690Sborman return; 29938690Sborman } 30032149Sminshall switch (pointer[0]) { 30132149Sminshall case TELOPT_TTYPE: 30238690Sborman fprintf(NetTrace, "TERMINAL-TYPE "); 30332149Sminshall switch (pointer[1]) { 30432149Sminshall case TELQUAL_IS: 305*44361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 30632149Sminshall break; 30732149Sminshall case TELQUAL_SEND: 30838690Sborman fprintf(NetTrace, "SEND"); 30932149Sminshall break; 31032149Sminshall default: 31132149Sminshall fprintf(NetTrace, 31238690Sborman "- unknown qualifier %d (0x%x).", 31334849Sminshall pointer[1], pointer[1]); 31432149Sminshall } 31532149Sminshall break; 31638690Sborman case TELOPT_TSPEED: 31738690Sborman fprintf(NetTrace, "TERMINAL-SPEED"); 31838690Sborman if (length < 2) { 31938690Sborman fprintf(NetTrace, " (empty suboption???)"); 32038690Sborman break; 32138690Sborman } 32238690Sborman switch (pointer[1]) { 32338909Sborman case TELQUAL_IS: 32438690Sborman fprintf(NetTrace, " IS "); 325*44361Sborman fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2); 32638690Sborman break; 32738690Sborman default: 32838690Sborman if (pointer[1] == 1) 32938690Sborman fprintf(NetTrace, " SEND"); 33038690Sborman else 331*44361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 33238690Sborman for (i = 2; i < length; i++) 33338690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 33438690Sborman break; 33538690Sborman } 33638690Sborman break; 33738690Sborman 33838690Sborman case TELOPT_LFLOW: 33938690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 34038690Sborman if (length < 2) { 34138690Sborman fprintf(NetTrace, " (empty suboption???)"); 34238690Sborman break; 34338690Sborman } 34438690Sborman switch (pointer[1]) { 34538690Sborman case 0: 34638690Sborman fprintf(NetTrace, " OFF"); break; 34738690Sborman case 1: 34838690Sborman fprintf(NetTrace, " ON"); break; 34938690Sborman default: 350*44361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 35138690Sborman } 35238690Sborman for (i = 2; i < length; i++) 35338690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 35438690Sborman break; 35538690Sborman 35638690Sborman case TELOPT_NAWS: 35738690Sborman fprintf(NetTrace, "NAWS"); 35838690Sborman if (length < 2) { 35938690Sborman fprintf(NetTrace, " (empty suboption???)"); 36038690Sborman break; 36138690Sborman } 36238690Sborman if (length == 2) { 36338690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 36438690Sborman break; 36538690Sborman } 36638690Sborman fprintf(NetTrace, " %d %d (%d)", 36738690Sborman pointer[1], pointer[2], 368*44361Sborman (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 36938690Sborman if (length == 4) { 37038690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 37138690Sborman break; 37238690Sborman } 37338690Sborman fprintf(NetTrace, " %d %d (%d)", 37438690Sborman pointer[3], pointer[4], 375*44361Sborman (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 37638690Sborman for (i = 5; i < length; i++) 37738690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 37838690Sborman break; 37938690Sborman 38043320Skfall #ifdef KERBEROS 38143320Skfall case TELOPT_AUTHENTICATION: 38243320Skfall fprintf(NetTrace, "Authentication information "); 38343320Skfall switch (pointer[1]) { 38443320Skfall case TELQUAL_IS: 38543320Skfall switch (pointer[2]) { 38643320Skfall case TELQUAL_AUTHTYPE_NONE: 38743320Skfall case TELQUAL_AUTHTYPE_PRIVATE: 38843320Skfall case TELQUAL_AUTHTYPE_KERBEROS: 38943320Skfall 39043320Skfall fprintf(NetTrace, "is type %s\r\n", authtypes[pointer[2]]); 39143320Skfall break; 39243320Skfall default: 39343320Skfall fprintf(NetTrace, "is type unknown\r\n"); 39443320Skfall break; 39543320Skfall } 39643320Skfall 39743320Skfall case TELQUAL_SEND: 39843320Skfall { 39943320Skfall int idx = 2; 40043320Skfall fprintf(NetTrace, "- request to send, types"); 40143320Skfall for (idx = 2; idx < length - 1; idx++) 40243320Skfall switch (pointer[idx]) { 40343320Skfall case TELQUAL_AUTHTYPE_NONE: 40443320Skfall case TELQUAL_AUTHTYPE_PRIVATE: 40543320Skfall case TELQUAL_AUTHTYPE_KERBEROS: 40643320Skfall fprintf(NetTrace, " %s", 40743320Skfall authtypes[pointer[idx]]); 40843320Skfall break; 40943320Skfall default: 41043320Skfall fprintf(NetTrace, " <unknown %u>", 41143320Skfall pointer[idx]); 41243320Skfall break; 41343320Skfall } 41443320Skfall fprintf(NetTrace, "\r\n"); 41543320Skfall } 41643320Skfall break; 41743320Skfall 41843320Skfall default: 41943320Skfall fprintf(NetTrace, " - unknown qualifier %d (0x%x).\r\n", 42043320Skfall pointer[1], pointer[1]); 42143320Skfall } 42243320Skfall break; 42343320Skfall #endif /* KERBEROS */ 42443320Skfall 42538690Sborman case TELOPT_LINEMODE: 42638690Sborman fprintf(NetTrace, "LINEMODE "); 42738690Sborman if (length < 2) { 42838690Sborman fprintf(NetTrace, " (empty suboption???)"); 42938690Sborman break; 43038690Sborman } 43138690Sborman switch (pointer[1]) { 43238690Sborman case WILL: 43338690Sborman fprintf(NetTrace, "WILL "); 43438690Sborman goto common; 43538690Sborman case WONT: 43638690Sborman fprintf(NetTrace, "WONT "); 43738690Sborman goto common; 43838690Sborman case DO: 43938690Sborman fprintf(NetTrace, "DO "); 44038690Sborman goto common; 44138690Sborman case DONT: 44238690Sborman fprintf(NetTrace, "DONT "); 44338690Sborman common: 44438690Sborman if (length < 3) { 44538690Sborman fprintf(NetTrace, "(no option???)"); 44638690Sborman break; 44738690Sborman } 44838690Sborman switch (pointer[2]) { 44938690Sborman case LM_FORWARDMASK: 45038690Sborman fprintf(NetTrace, "Forward Mask"); 45138690Sborman for (i = 3; i < length; i++) 45238690Sborman fprintf(NetTrace, " %x", pointer[i]); 45338690Sborman break; 45438690Sborman default: 45538690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 45638690Sborman for (i = 3; i < length; i++) 45738690Sborman fprintf(NetTrace, " %d", pointer[i]); 45838690Sborman break; 45938690Sborman } 46038690Sborman break; 46138690Sborman 46238690Sborman case LM_SLC: 46338690Sborman fprintf(NetTrace, "SLC"); 46438690Sborman for (i = 2; i < length - 2; i += 3) { 46538690Sborman if (pointer[i+SLC_FUNC] <= NSLC) 46638690Sborman fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]); 46738690Sborman else 46838690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 46938690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 47038690Sborman case SLC_NOSUPPORT: 47138690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 47238690Sborman case SLC_CANTCHANGE: 47338690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 47438690Sborman case SLC_VARIABLE: 47538690Sborman fprintf(NetTrace, " VARIABLE"); break; 47638690Sborman case SLC_DEFAULT: 47738690Sborman fprintf(NetTrace, " DEFAULT"); break; 47838690Sborman } 47938690Sborman fprintf(NetTrace, "%s%s%s", 48038690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 48138690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 48238690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 48338690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 48438690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 48538690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 48638690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 487*44361Sborman if ((pointer[i+SLC_VALUE] == IAC) && 488*44361Sborman (pointer[i+SLC_VALUE+1] == IAC)) 489*44361Sborman i++; 49038690Sborman } 49138690Sborman for (; i < length; i++) 49238690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 49338690Sborman break; 49438690Sborman 49538690Sborman case LM_MODE: 49638690Sborman fprintf(NetTrace, "MODE "); 49738690Sborman if (length < 3) { 49838690Sborman fprintf(NetTrace, "(no mode???)"); 49938690Sborman break; 50038690Sborman } 50138690Sborman { 502*44361Sborman char tbuf[64]; 503*44361Sborman sprintf(tbuf, "%s%s%s%s%s", 50438690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 50538690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 506*44361Sborman pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 507*44361Sborman pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 50838690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 50938690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 51038690Sborman } 51138690Sborman if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) 51238690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 51338690Sborman for (i = 3; i < length; i++) 51438690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 51538690Sborman break; 51638690Sborman default: 51738690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 51838690Sborman for (i = 2; i < length; i++) 51938690Sborman fprintf(NetTrace, " %d", pointer[i]); 52038690Sborman } 52138690Sborman break; 52238690Sborman 52338909Sborman case TELOPT_STATUS: { 52438909Sborman register char *cp; 52538909Sborman register int j, k; 52638909Sborman 52738909Sborman fprintf(NetTrace, "STATUS"); 52838909Sborman 52938909Sborman switch (pointer[1]) { 53038909Sborman default: 53138909Sborman if (pointer[1] == TELQUAL_SEND) 53238909Sborman fprintf(NetTrace, " SEND"); 53338909Sborman else 534*44361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]); 53538909Sborman for (i = 2; i < length; i++) 53638909Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 53738909Sborman break; 53838909Sborman case TELQUAL_IS: 53938909Sborman if (NetTrace == stdout) 54038909Sborman fprintf(NetTrace, " IS\r\n"); 54138909Sborman else 54238909Sborman fprintf(NetTrace, " IS\n"); 54338909Sborman 54438909Sborman for (i = 2; i < length; i++) { 54538909Sborman switch(pointer[i]) { 54638909Sborman case DO: cp = "DO"; goto common2; 54738909Sborman case DONT: cp = "DONT"; goto common2; 54838909Sborman case WILL: cp = "WILL"; goto common2; 54938909Sborman case WONT: cp = "WONT"; goto common2; 55038909Sborman common2: 55138909Sborman i++; 552*44361Sborman if (TELOPT_OK((int)pointer[i])) 55338909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 55438909Sborman else 55538909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]); 55638909Sborman 55738909Sborman if (NetTrace == stdout) 55838909Sborman fprintf(NetTrace, "\r\n"); 55938909Sborman else 56038909Sborman fprintf(NetTrace, "\n"); 56138909Sborman break; 56238909Sborman 56338909Sborman case SB: 56438909Sborman fprintf(NetTrace, " SB "); 56538909Sborman i++; 56638909Sborman j = k = i; 56738909Sborman while (j < length) { 56838909Sborman if (pointer[j] == SE) { 56938909Sborman if (j+1 == length) 57038909Sborman break; 57138909Sborman if (pointer[j+1] == SE) 57238909Sborman j++; 57338909Sborman else 57438909Sborman break; 57538909Sborman } 57638909Sborman pointer[k++] = pointer[j++]; 57738909Sborman } 57838909Sborman printsub(0, &pointer[i], k - i); 57938909Sborman if (i < length) { 58038909Sborman fprintf(NetTrace, " SE"); 58138909Sborman i = j; 58238909Sborman } else 58338909Sborman i = j - 1; 58438909Sborman 58538909Sborman if (NetTrace == stdout) 58638909Sborman fprintf(NetTrace, "\r\n"); 58738909Sborman else 58838909Sborman fprintf(NetTrace, "\n"); 58938909Sborman 59038909Sborman break; 59138909Sborman 59238909Sborman default: 59338909Sborman fprintf(NetTrace, " %d", pointer[i]); 59438909Sborman break; 59538909Sborman } 59638909Sborman } 59738909Sborman break; 59838909Sborman } 59938909Sborman break; 60038909Sborman } 60138909Sborman 602*44361Sborman case TELOPT_XDISPLOC: 603*44361Sborman fprintf(NetTrace, "X-DISPLAY-LOCATION "); 604*44361Sborman switch (pointer[1]) { 605*44361Sborman case TELQUAL_IS: 606*44361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 607*44361Sborman break; 608*44361Sborman case TELQUAL_SEND: 609*44361Sborman fprintf(NetTrace, "SEND"); 610*44361Sborman break; 611*44361Sborman default: 612*44361Sborman fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 613*44361Sborman pointer[1], pointer[1]); 614*44361Sborman } 615*44361Sborman break; 616*44361Sborman 617*44361Sborman case TELOPT_ENVIRON: 618*44361Sborman fprintf(NetTrace, "ENVIRON "); 619*44361Sborman switch (pointer[1]) { 620*44361Sborman case TELQUAL_IS: 621*44361Sborman fprintf(NetTrace, "IS "); 622*44361Sborman goto env_common; 623*44361Sborman case TELQUAL_SEND: 624*44361Sborman fprintf(NetTrace, "SEND "); 625*44361Sborman goto env_common; 626*44361Sborman case TELQUAL_INFO: 627*44361Sborman fprintf(NetTrace, "INFO "); 628*44361Sborman env_common: 629*44361Sborman { 630*44361Sborman register int noquote = 2; 631*44361Sborman for (i = 2; i < length; i++ ) { 632*44361Sborman switch (pointer[i]) { 633*44361Sborman case ENV_VAR: 634*44361Sborman if (pointer[1] == TELQUAL_SEND) 635*44361Sborman goto def_case; 636*44361Sborman fprintf(NetTrace, "\" VAR " + noquote); 637*44361Sborman noquote = 2; 638*44361Sborman break; 639*44361Sborman 640*44361Sborman case ENV_VALUE: 641*44361Sborman fprintf(NetTrace, "\" VALUE " + noquote); 642*44361Sborman noquote = 2; 643*44361Sborman break; 644*44361Sborman 645*44361Sborman case ENV_ESC: 646*44361Sborman fprintf(NetTrace, "\" ESC " + noquote); 647*44361Sborman noquote = 2; 648*44361Sborman break; 649*44361Sborman 650*44361Sborman default: 651*44361Sborman def_case: 652*44361Sborman if (isprint(pointer[i]) && pointer[i] != '"') { 653*44361Sborman if (noquote) { 654*44361Sborman putc('"', NetTrace); 655*44361Sborman noquote = 0; 656*44361Sborman } 657*44361Sborman putc(pointer[i], NetTrace); 658*44361Sborman } else { 659*44361Sborman fprintf(NetTrace, "\" %03o " + noquote, 660*44361Sborman pointer[i]); 661*44361Sborman noquote = 2; 662*44361Sborman } 663*44361Sborman break; 664*44361Sborman } 665*44361Sborman } 666*44361Sborman if (!noquote) 667*44361Sborman putc('"', NetTrace); 668*44361Sborman break; 669*44361Sborman } 670*44361Sborman } 671*44361Sborman break; 672*44361Sborman 67332149Sminshall default: 67438690Sborman fprintf(NetTrace, "Unknown option "); 67538690Sborman for (i = 0; i < length; i++) 67638690Sborman fprintf(NetTrace, " %d", pointer[i]); 67738690Sborman break; 67832149Sminshall } 67938909Sborman if (direction) { 68038909Sborman if (NetTrace == stdout) 68138909Sborman fprintf(NetTrace, "\r\n"); 68238909Sborman else 68338909Sborman fprintf(NetTrace, "\n"); 68438909Sborman } 68532149Sminshall } 68632149Sminshall } 68736278Sminshall 68836278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 68936278Sminshall * Note that we consider the buffer to run all the 69036278Sminshall * way to the kernel (thus the select). 69136278Sminshall */ 69236278Sminshall 69336278Sminshall void 69436278Sminshall EmptyTerminal() 69536278Sminshall { 69636278Sminshall #if defined(unix) 69736278Sminshall fd_set o; 69836278Sminshall 69936278Sminshall FD_ZERO(&o); 70036278Sminshall #endif /* defined(unix) */ 70136278Sminshall 70236278Sminshall if (TTYBYTES() == 0) { 70336278Sminshall #if defined(unix) 70436278Sminshall FD_SET(tout, &o); 70536278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 70636278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 70736278Sminshall #endif /* defined(unix) */ 70836278Sminshall } else { 70936278Sminshall while (TTYBYTES()) { 710*44361Sborman (void) ttyflush(0); 71136278Sminshall #if defined(unix) 71236278Sminshall FD_SET(tout, &o); 71336278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 71436278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 71536278Sminshall #endif /* defined(unix) */ 71636278Sminshall } 71736278Sminshall } 71836278Sminshall } 71936278Sminshall 72036278Sminshall void 72136278Sminshall SetForExit() 72236278Sminshall { 72338690Sborman setconnmode(0); 72436278Sminshall #if defined(TN3270) 72536278Sminshall if (In3270) { 72636278Sminshall Finish3270(); 72736278Sminshall } 72836279Sminshall #else /* defined(TN3270) */ 72936279Sminshall do { 730*44361Sborman (void)telrcv(); /* Process any incoming data */ 73136279Sminshall EmptyTerminal(); 73236279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 73336278Sminshall #endif /* defined(TN3270) */ 73436278Sminshall setcommandmode(); 73536278Sminshall fflush(stdout); 73636278Sminshall fflush(stderr); 73736278Sminshall #if defined(TN3270) 73836278Sminshall if (In3270) { 73936278Sminshall StopScreen(1); 74036278Sminshall } 74136278Sminshall #endif /* defined(TN3270) */ 74238690Sborman setconnmode(0); 74336278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 74436278Sminshall setcommandmode(); 74536278Sminshall } 74636278Sminshall 74736278Sminshall void 74836278Sminshall Exit(returnCode) 74936278Sminshall int returnCode; 75036278Sminshall { 75136278Sminshall SetForExit(); 75236278Sminshall exit(returnCode); 75336278Sminshall } 75436278Sminshall 75536278Sminshall void 75636278Sminshall ExitString(string, returnCode) 75736278Sminshall char *string; 75836278Sminshall int returnCode; 75936278Sminshall { 76036278Sminshall SetForExit(); 76136278Sminshall fwrite(string, 1, strlen(string), stderr); 76236278Sminshall exit(returnCode); 76336278Sminshall } 764