133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 5*43320Skfall * Redistribution and use in source and binary forms are permitted 6*43320Skfall * provided that: (1) source distributions retain this entire copyright 7*43320Skfall * notice and comment, and (2) distributions including binaries display 8*43320Skfall * the following acknowledgement: ``This product includes software 9*43320Skfall * developed by the University of California, Berkeley and its contributors'' 10*43320Skfall * in the documentation or other materials provided with the distribution 11*43320Skfall * and in all advertising materials mentioning features or use of this 12*43320Skfall * software. Neither the name of the University nor the names of its 13*43320Skfall * contributors may be used to endorse or promote products derived 14*43320Skfall * from this software without specific prior written permission. 15*43320Skfall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 16*43320Skfall * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 17*43320Skfall * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1833686Sbostic */ 1933686Sbostic 2033686Sbostic #ifndef lint 21*43320Skfall static char sccsid[] = "@(#)utilities.c 1.17 (Berkeley) 6/1/90"; 2233686Sbostic #endif /* not lint */ 2333686Sbostic 2432149Sminshall #define TELOPTS 2538690Sborman #define TELCMDS 2632149Sminshall #include <arpa/telnet.h> 2732381Sminshall #include <sys/types.h> 2832149Sminshall 2932149Sminshall #include <ctype.h> 3032149Sminshall 3134305Sminshall #include "general.h" 3234305Sminshall 3336280Sminshall #include "fdset.h" 3436280Sminshall 3532381Sminshall #include "ring.h" 3632381Sminshall 3736278Sminshall #include "defines.h" 3836278Sminshall 3932149Sminshall #include "externs.h" 4032149Sminshall 4132149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 4238690Sborman int prettydump; 4332149Sminshall 4432149Sminshall /* 4532149Sminshall * upcase() 4632149Sminshall * 4732149Sminshall * Upcase (in place) the argument. 4832149Sminshall */ 4932149Sminshall 5032149Sminshall void 5132149Sminshall upcase(argument) 5232149Sminshall register char *argument; 5332149Sminshall { 5432149Sminshall register int c; 5532149Sminshall 5632149Sminshall while ((c = *argument) != 0) { 5732149Sminshall if (islower(c)) { 5832149Sminshall *argument = toupper(c); 5932149Sminshall } 6032149Sminshall argument++; 6132149Sminshall } 6232149Sminshall } 6332149Sminshall 6432149Sminshall /* 6532149Sminshall * SetSockOpt() 6632149Sminshall * 6732149Sminshall * Compensate for differences in 4.2 and 4.3 systems. 6832149Sminshall */ 6932149Sminshall 7032149Sminshall int 7132149Sminshall SetSockOpt(fd, level, option, yesno) 7232149Sminshall int 7332149Sminshall fd, 7432149Sminshall level, 7532149Sminshall option, 7632149Sminshall yesno; 7732149Sminshall { 7832149Sminshall #ifndef NOT43 7932149Sminshall return setsockopt(fd, level, option, 8032149Sminshall (char *)&yesno, sizeof yesno); 8132149Sminshall #else /* NOT43 */ 8232149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */ 8332149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 8432149Sminshall option); 8532149Sminshall return -1; 8632149Sminshall } 8732149Sminshall return setsockopt(fd, level, option, 0, 0); 8832149Sminshall #endif /* NOT43 */ 8932149Sminshall } 9032149Sminshall 9132149Sminshall /* 9232149Sminshall * The following are routines used to print out debugging information. 9332149Sminshall */ 9432149Sminshall 9539529Sborman unsigned char NetTraceFile[256] = "(standard output)"; 9632149Sminshall 9732149Sminshall void 9838690Sborman SetNetTrace(file) 9938690Sborman register char *file; 10038690Sborman { 10138690Sborman if (NetTrace && NetTrace != stdout) 10238690Sborman fclose(NetTrace); 10338690Sborman if (file && (strcmp(file, "-") != 0)) { 10438690Sborman NetTrace = fopen(file, "w"); 10538690Sborman if (NetTrace) { 10638690Sborman strcpy(NetTraceFile, file); 10738690Sborman return; 10838690Sborman } 10938690Sborman fprintf(stderr, "Cannot open %s.\n", file); 11038690Sborman } 11138690Sborman NetTrace = stdout; 11238690Sborman strcpy(NetTraceFile, "(standard output)"); 11338690Sborman } 11438690Sborman 11538690Sborman void 11632149Sminshall Dump(direction, buffer, length) 11732149Sminshall char direction; 11832149Sminshall char *buffer; 11932149Sminshall int length; 12032149Sminshall { 12132149Sminshall # define BYTES_PER_LINE 32 12232149Sminshall # define min(x,y) ((x<y)? x:y) 12332149Sminshall char *pThis; 12432149Sminshall int offset; 12538690Sborman extern pettydump; 12632149Sminshall 12732149Sminshall offset = 0; 12832149Sminshall 12932149Sminshall while (length) { 13032149Sminshall /* print one line */ 13132149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset); 13232149Sminshall pThis = buffer; 13338690Sborman if (prettydump) { 13438909Sborman buffer = buffer + min(length, BYTES_PER_LINE/2); 13538690Sborman while (pThis < buffer) { 13638690Sborman fprintf(NetTrace, "%c%.2x", 13738690Sborman (((*pThis)&0xff) == 0xff) ? '*' : ' ', 13838690Sborman (*pThis)&0xff); 13938690Sborman pThis++; 14038690Sborman } 14138909Sborman length -= BYTES_PER_LINE/2; 14238909Sborman offset += BYTES_PER_LINE/2; 14338690Sborman } else { 14438909Sborman buffer = buffer + min(length, BYTES_PER_LINE); 14538690Sborman while (pThis < buffer) { 14638690Sborman fprintf(NetTrace, "%.2x", (*pThis)&0xff); 14738690Sborman pThis++; 14838690Sborman } 14938909Sborman length -= BYTES_PER_LINE; 15038909Sborman offset += BYTES_PER_LINE; 15132149Sminshall } 15237226Sminshall if (NetTrace == stdout) { 15338207Sminshall fprintf(NetTrace, "\r\n"); 15438207Sminshall } else { 15537226Sminshall fprintf(NetTrace, "\n"); 15637226Sminshall } 15732149Sminshall if (length < 0) { 15836693Sminshall fflush(NetTrace); 15932149Sminshall return; 16032149Sminshall } 16132149Sminshall /* find next unique line */ 16232149Sminshall } 16336693Sminshall fflush(NetTrace); 16432149Sminshall } 16532149Sminshall 16632149Sminshall 16732149Sminshall void 16837226Sminshall printoption(direction, fmt, option) 16932149Sminshall char *direction, *fmt; 17037226Sminshall int option; 17132149Sminshall { 17232149Sminshall if (!showoptions) 17332149Sminshall return; 17437226Sminshall fprintf(NetTrace, "%s ", direction); 17538690Sborman if (TELOPT_OK(option)) 17638690Sborman fprintf(NetTrace, "%s %s", fmt, TELOPT(option)); 17738690Sborman else if (TELCMD_OK(option)) 17838690Sborman fprintf(NetTrace, "%s %s", fmt, TELCMD(option)); 17932149Sminshall else 18032149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 18138690Sborman if (NetTrace == stdout) 18237226Sminshall fprintf(NetTrace, "\r\n"); 18338690Sborman else 18437226Sminshall fprintf(NetTrace, "\n"); 18537226Sminshall return; 18632149Sminshall } 18732149Sminshall 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 26438690Sborman char *slcnames[] = { SLC_NAMES }; 26538690Sborman 266*43320Skfall #ifdef KERBEROS 267*43320Skfall static char *authtypes[3] = { "NONE", "PRIVATE", "KERBEROS" }; 268*43320Skfall #else 269*43320Skfall static char *authtypes[2] = { "NONE", "PRIVATE" }; 270*43320Skfall #endif 271*43320Skfall 27232149Sminshall void 27332149Sminshall printsub(direction, pointer, length) 27438690Sborman char direction; /* '<' or '>' */ 27538690Sborman unsigned char *pointer; /* where suboption data sits */ 27632149Sminshall int length; /* length of suboption data */ 27732149Sminshall { 27838690Sborman register int i; 27938690Sborman 28032149Sminshall if (showoptions) { 28138909Sborman if (direction) { 28238909Sborman fprintf(NetTrace, "%s suboption ", 28338690Sborman (direction == '<')? "Received":"Sent"); 28438909Sborman if (length >= 3) { 28538909Sborman register int j; 28638690Sborman 28738909Sborman i = pointer[length-2]; 28838909Sborman j = pointer[length-1]; 28938690Sborman 29038909Sborman if (i != IAC || j != SE) { 29138909Sborman fprintf(NetTrace, "(terminated by "); 29238909Sborman if (TELOPT_OK(i)) 29338909Sborman fprintf(NetTrace, "%s ", TELOPT(i)); 29438909Sborman else if (TELCMD_OK(i)) 29538909Sborman fprintf(NetTrace, "%s ", TELCMD(i)); 29638909Sborman else 29738909Sborman fprintf(NetTrace, "%d ", i); 29838909Sborman if (TELOPT_OK(j)) 29938909Sborman fprintf(NetTrace, "%s", TELOPT(j)); 30038909Sborman else if (TELCMD_OK(j)) 30138909Sborman fprintf(NetTrace, "%s", TELCMD(j)); 30238909Sborman else 30338909Sborman fprintf(NetTrace, "%d", j); 30438909Sborman fprintf(NetTrace, ", not IAC SE!) "); 30538909Sborman } 30638690Sborman } 30738909Sborman length -= 2; 30838690Sborman } 30938690Sborman if (length < 1) { 31038690Sborman fprintf(NetTrace, "(Empty suboption???)"); 31138690Sborman return; 31238690Sborman } 31332149Sminshall switch (pointer[0]) { 31432149Sminshall case TELOPT_TTYPE: 31538690Sborman fprintf(NetTrace, "TERMINAL-TYPE "); 31632149Sminshall switch (pointer[1]) { 31732149Sminshall case TELQUAL_IS: 31838690Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, pointer+2); 31932149Sminshall break; 32032149Sminshall case TELQUAL_SEND: 32138690Sborman fprintf(NetTrace, "SEND"); 32232149Sminshall break; 32332149Sminshall default: 32432149Sminshall fprintf(NetTrace, 32538690Sborman "- unknown qualifier %d (0x%x).", 32634849Sminshall pointer[1], pointer[1]); 32732149Sminshall } 32832149Sminshall break; 32938690Sborman case TELOPT_TSPEED: 33038690Sborman fprintf(NetTrace, "TERMINAL-SPEED"); 33138690Sborman if (length < 2) { 33238690Sborman fprintf(NetTrace, " (empty suboption???)"); 33338690Sborman break; 33438690Sborman } 33538690Sborman switch (pointer[1]) { 33638909Sborman case TELQUAL_IS: 33738690Sborman fprintf(NetTrace, " IS "); 33838690Sborman fprintf(NetTrace, "%.*s", length-2, pointer+2); 33938690Sborman break; 34038690Sborman default: 34138690Sborman if (pointer[1] == 1) 34238690Sborman fprintf(NetTrace, " SEND"); 34338690Sborman else 34438690Sborman fprintf(NetTrace, " %d (unknown)"); 34538690Sborman for (i = 2; i < length; i++) 34638690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 34738690Sborman break; 34838690Sborman } 34938690Sborman break; 35038690Sborman 35138690Sborman case TELOPT_LFLOW: 35238690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 35338690Sborman if (length < 2) { 35438690Sborman fprintf(NetTrace, " (empty suboption???)"); 35538690Sborman break; 35638690Sborman } 35738690Sborman switch (pointer[1]) { 35838690Sborman case 0: 35938690Sborman fprintf(NetTrace, " OFF"); break; 36038690Sborman case 1: 36138690Sborman fprintf(NetTrace, " ON"); break; 36238690Sborman default: 36338690Sborman fprintf(NetTrace, " %d (unknown)"); 36438690Sborman } 36538690Sborman for (i = 2; i < length; i++) 36638690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 36738690Sborman break; 36838690Sborman 36938690Sborman case TELOPT_NAWS: 37038690Sborman fprintf(NetTrace, "NAWS"); 37138690Sborman if (length < 2) { 37238690Sborman fprintf(NetTrace, " (empty suboption???)"); 37338690Sborman break; 37438690Sborman } 37538690Sborman if (length == 2) { 37638690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 37738690Sborman break; 37838690Sborman } 37938690Sborman fprintf(NetTrace, " %d %d (%d)", 38038690Sborman pointer[1], pointer[2], 38138690Sborman (((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])); 38238690Sborman if (length == 4) { 38338690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 38438690Sborman break; 38538690Sborman } 38638690Sborman fprintf(NetTrace, " %d %d (%d)", 38738690Sborman pointer[3], pointer[4], 38838690Sborman (((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])); 38938690Sborman for (i = 5; i < length; i++) 39038690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 39138690Sborman break; 39238690Sborman 393*43320Skfall #ifdef KERBEROS 394*43320Skfall case TELOPT_AUTHENTICATION: 395*43320Skfall fprintf(NetTrace, "Authentication information "); 396*43320Skfall switch (pointer[1]) { 397*43320Skfall case TELQUAL_IS: 398*43320Skfall switch (pointer[2]) { 399*43320Skfall case TELQUAL_AUTHTYPE_NONE: 400*43320Skfall case TELQUAL_AUTHTYPE_PRIVATE: 401*43320Skfall case TELQUAL_AUTHTYPE_KERBEROS: 402*43320Skfall 403*43320Skfall fprintf(NetTrace, "is type %s\r\n", authtypes[pointer[2]]); 404*43320Skfall break; 405*43320Skfall default: 406*43320Skfall fprintf(NetTrace, "is type unknown\r\n"); 407*43320Skfall break; 408*43320Skfall } 409*43320Skfall 410*43320Skfall case TELQUAL_SEND: 411*43320Skfall { 412*43320Skfall int idx = 2; 413*43320Skfall fprintf(NetTrace, "- request to send, types"); 414*43320Skfall for (idx = 2; idx < length - 1; idx++) 415*43320Skfall switch (pointer[idx]) { 416*43320Skfall case TELQUAL_AUTHTYPE_NONE: 417*43320Skfall case TELQUAL_AUTHTYPE_PRIVATE: 418*43320Skfall case TELQUAL_AUTHTYPE_KERBEROS: 419*43320Skfall fprintf(NetTrace, " %s", 420*43320Skfall authtypes[pointer[idx]]); 421*43320Skfall break; 422*43320Skfall default: 423*43320Skfall fprintf(NetTrace, " <unknown %u>", 424*43320Skfall pointer[idx]); 425*43320Skfall break; 426*43320Skfall } 427*43320Skfall fprintf(NetTrace, "\r\n"); 428*43320Skfall } 429*43320Skfall break; 430*43320Skfall 431*43320Skfall default: 432*43320Skfall fprintf(NetTrace, " - unknown qualifier %d (0x%x).\r\n", 433*43320Skfall pointer[1], pointer[1]); 434*43320Skfall } 435*43320Skfall break; 436*43320Skfall #endif /* KERBEROS */ 437*43320Skfall 43838690Sborman case TELOPT_LINEMODE: 43938690Sborman fprintf(NetTrace, "LINEMODE "); 44038690Sborman if (length < 2) { 44138690Sborman fprintf(NetTrace, " (empty suboption???)"); 44238690Sborman break; 44338690Sborman } 44438690Sborman switch (pointer[1]) { 44538690Sborman case WILL: 44638690Sborman fprintf(NetTrace, "WILL "); 44738690Sborman goto common; 44838690Sborman case WONT: 44938690Sborman fprintf(NetTrace, "WONT "); 45038690Sborman goto common; 45138690Sborman case DO: 45238690Sborman fprintf(NetTrace, "DO "); 45338690Sborman goto common; 45438690Sborman case DONT: 45538690Sborman fprintf(NetTrace, "DONT "); 45638690Sborman common: 45738690Sborman if (length < 3) { 45838690Sborman fprintf(NetTrace, "(no option???)"); 45938690Sborman break; 46038690Sborman } 46138690Sborman switch (pointer[2]) { 46238690Sborman case LM_FORWARDMASK: 46338690Sborman fprintf(NetTrace, "Forward Mask"); 46438690Sborman for (i = 3; i < length; i++) 46538690Sborman fprintf(NetTrace, " %x", pointer[i]); 46638690Sborman break; 46738690Sborman default: 46838690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 46938690Sborman for (i = 3; i < length; i++) 47038690Sborman fprintf(NetTrace, " %d", pointer[i]); 47138690Sborman break; 47238690Sborman } 47338690Sborman break; 47438690Sborman 47538690Sborman case LM_SLC: 47638690Sborman fprintf(NetTrace, "SLC"); 47738690Sborman for (i = 2; i < length - 2; i += 3) { 47838690Sborman if (pointer[i+SLC_FUNC] <= NSLC) 47938690Sborman fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]); 48038690Sborman else 48138690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 48238690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 48338690Sborman case SLC_NOSUPPORT: 48438690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 48538690Sborman case SLC_CANTCHANGE: 48638690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 48738690Sborman case SLC_VARIABLE: 48838690Sborman fprintf(NetTrace, " VARIABLE"); break; 48938690Sborman case SLC_DEFAULT: 49038690Sborman fprintf(NetTrace, " DEFAULT"); break; 49138690Sborman } 49238690Sborman fprintf(NetTrace, "%s%s%s", 49338690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 49438690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 49538690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 49638690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 49738690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 49838690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 49938690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 50038690Sborman } 50138690Sborman for (; i < length; i++) 50238690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 50338690Sborman break; 50438690Sborman 50538690Sborman case LM_MODE: 50638690Sborman fprintf(NetTrace, "MODE "); 50738690Sborman if (length < 3) { 50838690Sborman fprintf(NetTrace, "(no mode???)"); 50938690Sborman break; 51038690Sborman } 51138690Sborman { 51238690Sborman char tbuf[32]; 51338690Sborman sprintf(tbuf, "%s%s%s", 51438690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 51538690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 51638690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 51738690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 51838690Sborman } 51938690Sborman if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) 52038690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 52138690Sborman for (i = 3; i < length; i++) 52238690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 52338690Sborman break; 52438690Sborman default: 52538690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 52638690Sborman for (i = 2; i < length; i++) 52738690Sborman fprintf(NetTrace, " %d", pointer[i]); 52838690Sborman } 52938690Sborman break; 53038690Sborman 53138909Sborman case TELOPT_STATUS: { 53238909Sborman register char *cp; 53338909Sborman register int j, k; 53438909Sborman 53538909Sborman fprintf(NetTrace, "STATUS"); 53638909Sborman 53738909Sborman switch (pointer[1]) { 53838909Sborman default: 53938909Sborman if (pointer[1] == TELQUAL_SEND) 54038909Sborman fprintf(NetTrace, " SEND"); 54138909Sborman else 54238909Sborman fprintf(NetTrace, " %d (unknown)"); 54338909Sborman for (i = 2; i < length; i++) 54438909Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 54538909Sborman break; 54638909Sborman case TELQUAL_IS: 54738909Sborman if (NetTrace == stdout) 54838909Sborman fprintf(NetTrace, " IS\r\n"); 54938909Sborman else 55038909Sborman fprintf(NetTrace, " IS\n"); 55138909Sborman 55238909Sborman for (i = 2; i < length; i++) { 55338909Sborman switch(pointer[i]) { 55438909Sborman case DO: cp = "DO"; goto common2; 55538909Sborman case DONT: cp = "DONT"; goto common2; 55638909Sborman case WILL: cp = "WILL"; goto common2; 55738909Sborman case WONT: cp = "WONT"; goto common2; 55838909Sborman common2: 55938909Sborman i++; 56038909Sborman if (TELOPT_OK(pointer[i])) 56138909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 56238909Sborman else 56338909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]); 56438909Sborman 56538909Sborman if (NetTrace == stdout) 56638909Sborman fprintf(NetTrace, "\r\n"); 56738909Sborman else 56838909Sborman fprintf(NetTrace, "\n"); 56938909Sborman break; 57038909Sborman 57138909Sborman case SB: 57238909Sborman fprintf(NetTrace, " SB "); 57338909Sborman i++; 57438909Sborman j = k = i; 57538909Sborman while (j < length) { 57638909Sborman if (pointer[j] == SE) { 57738909Sborman if (j+1 == length) 57838909Sborman break; 57938909Sborman if (pointer[j+1] == SE) 58038909Sborman j++; 58138909Sborman else 58238909Sborman break; 58338909Sborman } 58438909Sborman pointer[k++] = pointer[j++]; 58538909Sborman } 58638909Sborman printsub(0, &pointer[i], k - i); 58738909Sborman if (i < length) { 58838909Sborman fprintf(NetTrace, " SE"); 58938909Sborman i = j; 59038909Sborman } else 59138909Sborman i = j - 1; 59238909Sborman 59338909Sborman if (NetTrace == stdout) 59438909Sborman fprintf(NetTrace, "\r\n"); 59538909Sborman else 59638909Sborman fprintf(NetTrace, "\n"); 59738909Sborman 59838909Sborman break; 59938909Sborman 60038909Sborman default: 60138909Sborman fprintf(NetTrace, " %d", pointer[i]); 60238909Sborman break; 60338909Sborman } 60438909Sborman } 60538909Sborman break; 60638909Sborman } 60738909Sborman break; 60838909Sborman } 60938909Sborman 61032149Sminshall default: 61138690Sborman fprintf(NetTrace, "Unknown option "); 61238690Sborman for (i = 0; i < length; i++) 61338690Sborman fprintf(NetTrace, " %d", pointer[i]); 61438690Sborman break; 61532149Sminshall } 61638909Sborman if (direction) { 61738909Sborman if (NetTrace == stdout) 61838909Sborman fprintf(NetTrace, "\r\n"); 61938909Sborman else 62038909Sborman fprintf(NetTrace, "\n"); 62138909Sborman } 62232149Sminshall } 62332149Sminshall } 62436278Sminshall 62536278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 62636278Sminshall * Note that we consider the buffer to run all the 62736278Sminshall * way to the kernel (thus the select). 62836278Sminshall */ 62936278Sminshall 63036278Sminshall void 63136278Sminshall EmptyTerminal() 63236278Sminshall { 63336278Sminshall #if defined(unix) 63436278Sminshall fd_set o; 63536278Sminshall 63636278Sminshall FD_ZERO(&o); 63736278Sminshall #endif /* defined(unix) */ 63836278Sminshall 63936278Sminshall if (TTYBYTES() == 0) { 64036278Sminshall #if defined(unix) 64136278Sminshall FD_SET(tout, &o); 64236278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 64336278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 64436278Sminshall #endif /* defined(unix) */ 64536278Sminshall } else { 64636278Sminshall while (TTYBYTES()) { 64736278Sminshall ttyflush(0); 64836278Sminshall #if defined(unix) 64936278Sminshall FD_SET(tout, &o); 65036278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 65136278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 65236278Sminshall #endif /* defined(unix) */ 65336278Sminshall } 65436278Sminshall } 65536278Sminshall } 65636278Sminshall 65736278Sminshall void 65836278Sminshall SetForExit() 65936278Sminshall { 66038690Sborman setconnmode(0); 66136278Sminshall #if defined(TN3270) 66236278Sminshall if (In3270) { 66336278Sminshall Finish3270(); 66436278Sminshall } 66536279Sminshall #else /* defined(TN3270) */ 66636279Sminshall do { 66736279Sminshall telrcv(); /* Process any incoming data */ 66836279Sminshall EmptyTerminal(); 66936279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 67036278Sminshall #endif /* defined(TN3270) */ 67136278Sminshall setcommandmode(); 67236278Sminshall fflush(stdout); 67336278Sminshall fflush(stderr); 67436278Sminshall #if defined(TN3270) 67536278Sminshall if (In3270) { 67636278Sminshall StopScreen(1); 67736278Sminshall } 67836278Sminshall #endif /* defined(TN3270) */ 67938690Sborman setconnmode(0); 68036278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 68136278Sminshall setcommandmode(); 68236278Sminshall } 68336278Sminshall 68436278Sminshall void 68536278Sminshall Exit(returnCode) 68636278Sminshall int returnCode; 68736278Sminshall { 68836278Sminshall SetForExit(); 68936278Sminshall exit(returnCode); 69036278Sminshall } 69136278Sminshall 69236278Sminshall void 69336278Sminshall ExitString(string, returnCode) 69436278Sminshall char *string; 69536278Sminshall int returnCode; 69636278Sminshall { 69736278Sminshall SetForExit(); 69836278Sminshall fwrite(string, 1, strlen(string), stderr); 69936278Sminshall exit(returnCode); 70036278Sminshall } 701