133686Sbostic /* 233686Sbostic * Copyright (c) 1988 Regents of the University of California. 333686Sbostic * All rights reserved. 433686Sbostic * 533686Sbostic * Redistribution and use in source and binary forms are permitted 634898Sbostic * provided that the above copyright notice and this paragraph are 734898Sbostic * duplicated in all such forms and that any documentation, 834898Sbostic * advertising materials, and other materials related to such 934898Sbostic * distribution and use acknowledge that the software was developed 1034898Sbostic * by the University of California, Berkeley. The name of the 1134898Sbostic * University may not be used to endorse or promote products derived 1234898Sbostic * from this software without specific prior written permission. 1334898Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434898Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534898Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633686Sbostic */ 1733686Sbostic 1833686Sbostic #ifndef lint 19*38909Sborman static char sccsid[] = "@(#)utilities.c 1.15 (Berkeley) 09/01/89"; 2033686Sbostic #endif /* not lint */ 2133686Sbostic 2232149Sminshall #define TELOPTS 2338690Sborman #define TELCMDS 2432149Sminshall #include <arpa/telnet.h> 2532381Sminshall #include <sys/types.h> 2632149Sminshall 2732149Sminshall #include <ctype.h> 2832149Sminshall 2934305Sminshall #include "general.h" 3034305Sminshall 3136280Sminshall #include "fdset.h" 3236280Sminshall 3332381Sminshall #include "ring.h" 3432381Sminshall 3536278Sminshall #include "defines.h" 3636278Sminshall 3732149Sminshall #include "externs.h" 3832149Sminshall 3932149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */ 4038690Sborman int prettydump; 4132149Sminshall 4232149Sminshall /* 4332149Sminshall * upcase() 4432149Sminshall * 4532149Sminshall * Upcase (in place) the argument. 4632149Sminshall */ 4732149Sminshall 4832149Sminshall void 4932149Sminshall upcase(argument) 5032149Sminshall register char *argument; 5132149Sminshall { 5232149Sminshall register int c; 5332149Sminshall 5432149Sminshall while ((c = *argument) != 0) { 5532149Sminshall if (islower(c)) { 5632149Sminshall *argument = toupper(c); 5732149Sminshall } 5832149Sminshall argument++; 5932149Sminshall } 6032149Sminshall } 6132149Sminshall 6232149Sminshall /* 6332149Sminshall * SetSockOpt() 6432149Sminshall * 6532149Sminshall * Compensate for differences in 4.2 and 4.3 systems. 6632149Sminshall */ 6732149Sminshall 6832149Sminshall int 6932149Sminshall SetSockOpt(fd, level, option, yesno) 7032149Sminshall int 7132149Sminshall fd, 7232149Sminshall level, 7332149Sminshall option, 7432149Sminshall yesno; 7532149Sminshall { 7632149Sminshall #ifndef NOT43 7732149Sminshall return setsockopt(fd, level, option, 7832149Sminshall (char *)&yesno, sizeof yesno); 7932149Sminshall #else /* NOT43 */ 8032149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */ 8132149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 8232149Sminshall option); 8332149Sminshall return -1; 8432149Sminshall } 8532149Sminshall return setsockopt(fd, level, option, 0, 0); 8632149Sminshall #endif /* NOT43 */ 8732149Sminshall } 8832149Sminshall 8932149Sminshall /* 9032149Sminshall * The following are routines used to print out debugging information. 9132149Sminshall */ 9232149Sminshall 9338690Sborman char NetTraceFile[256] = "(standard output)"; 9432149Sminshall 9532149Sminshall void 9638690Sborman SetNetTrace(file) 9738690Sborman register char *file; 9838690Sborman { 9938690Sborman if (NetTrace && NetTrace != stdout) 10038690Sborman fclose(NetTrace); 10138690Sborman if (file && (strcmp(file, "-") != 0)) { 10238690Sborman NetTrace = fopen(file, "w"); 10338690Sborman if (NetTrace) { 10438690Sborman strcpy(NetTraceFile, file); 10538690Sborman return; 10638690Sborman } 10738690Sborman fprintf(stderr, "Cannot open %s.\n", file); 10838690Sborman } 10938690Sborman NetTrace = stdout; 11038690Sborman strcpy(NetTraceFile, "(standard output)"); 11138690Sborman } 11238690Sborman 11338690Sborman void 11432149Sminshall Dump(direction, buffer, length) 11532149Sminshall char direction; 11632149Sminshall char *buffer; 11732149Sminshall int length; 11832149Sminshall { 11932149Sminshall # define BYTES_PER_LINE 32 12032149Sminshall # define min(x,y) ((x<y)? x:y) 12132149Sminshall char *pThis; 12232149Sminshall int offset; 12338690Sborman extern pettydump; 12432149Sminshall 12532149Sminshall offset = 0; 12632149Sminshall 12732149Sminshall while (length) { 12832149Sminshall /* print one line */ 12932149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset); 13032149Sminshall pThis = buffer; 13138690Sborman if (prettydump) { 132*38909Sborman buffer = buffer + min(length, BYTES_PER_LINE/2); 13338690Sborman while (pThis < buffer) { 13438690Sborman fprintf(NetTrace, "%c%.2x", 13538690Sborman (((*pThis)&0xff) == 0xff) ? '*' : ' ', 13638690Sborman (*pThis)&0xff); 13738690Sborman pThis++; 13838690Sborman } 139*38909Sborman length -= BYTES_PER_LINE/2; 140*38909Sborman offset += BYTES_PER_LINE/2; 14138690Sborman } else { 142*38909Sborman buffer = buffer + min(length, BYTES_PER_LINE); 14338690Sborman while (pThis < buffer) { 14438690Sborman fprintf(NetTrace, "%.2x", (*pThis)&0xff); 14538690Sborman pThis++; 14638690Sborman } 147*38909Sborman length -= BYTES_PER_LINE; 148*38909Sborman offset += BYTES_PER_LINE; 14932149Sminshall } 15037226Sminshall if (NetTrace == stdout) { 15138207Sminshall fprintf(NetTrace, "\r\n"); 15238207Sminshall } else { 15337226Sminshall fprintf(NetTrace, "\n"); 15437226Sminshall } 15532149Sminshall if (length < 0) { 15636693Sminshall fflush(NetTrace); 15732149Sminshall return; 15832149Sminshall } 15932149Sminshall /* find next unique line */ 16032149Sminshall } 16136693Sminshall fflush(NetTrace); 16232149Sminshall } 16332149Sminshall 16432149Sminshall 16532149Sminshall void 16637226Sminshall printoption(direction, fmt, option) 16732149Sminshall char *direction, *fmt; 16837226Sminshall int option; 16932149Sminshall { 17032149Sminshall if (!showoptions) 17132149Sminshall return; 17237226Sminshall fprintf(NetTrace, "%s ", direction); 17338690Sborman if (TELOPT_OK(option)) 17438690Sborman fprintf(NetTrace, "%s %s", fmt, TELOPT(option)); 17538690Sborman else if (TELCMD_OK(option)) 17638690Sborman fprintf(NetTrace, "%s %s", fmt, TELCMD(option)); 17732149Sminshall else 17832149Sminshall fprintf(NetTrace, "%s %d", fmt, option); 17938690Sborman if (NetTrace == stdout) 18037226Sminshall fprintf(NetTrace, "\r\n"); 18138690Sborman else 18237226Sminshall fprintf(NetTrace, "\n"); 18337226Sminshall return; 18432149Sminshall } 18532149Sminshall 18638690Sborman optionstatus() 18738690Sborman { 18838690Sborman register int i; 18938690Sborman extern char will_wont_resp[], do_dont_resp[]; 19038690Sborman 19138690Sborman for (i = 0; i < 256; i++) { 19238690Sborman if (do_dont_resp[i]) { 19338690Sborman if (TELOPT_OK(i)) 19438690Sborman printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 19538690Sborman else if (TELCMD_OK(i)) 19638690Sborman printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 19738690Sborman else 19838690Sborman printf("resp DO_DONT %d: %d\n", i, 19938690Sborman do_dont_resp[i]); 20038690Sborman if (my_want_state_is_do(i)) { 20138690Sborman if (TELOPT_OK(i)) 20238690Sborman printf("want DO %s\n", TELOPT(i)); 20338690Sborman else if (TELCMD_OK(i)) 20438690Sborman printf("want DO %s\n", TELCMD(i)); 20538690Sborman else 20638690Sborman printf("want DO %d\n", i); 20738690Sborman } else { 20838690Sborman if (TELOPT_OK(i)) 20938690Sborman printf("want DONT %s\n", TELOPT(i)); 21038690Sborman else if (TELCMD_OK(i)) 21138690Sborman printf("want DONT %s\n", TELCMD(i)); 21238690Sborman else 21338690Sborman printf("want DONT %d\n", i); 21438690Sborman } 21538690Sborman } else { 21638690Sborman if (my_state_is_do(i)) { 21738690Sborman if (TELOPT_OK(i)) 21838690Sborman printf(" DO %s\n", TELOPT(i)); 21938690Sborman else if (TELCMD_OK(i)) 22038690Sborman printf(" DO %s\n", TELCMD(i)); 22138690Sborman else 22238690Sborman printf(" DO %d\n", i); 22338690Sborman } 22438690Sborman } 22538690Sborman if (will_wont_resp[i]) { 22638690Sborman if (TELOPT_OK(i)) 22738690Sborman printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 22838690Sborman else if (TELCMD_OK(i)) 22938690Sborman printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 23038690Sborman else 23138690Sborman printf("resp WILL_WONT %d: %d\n", 23238690Sborman i, will_wont_resp[i]); 23338690Sborman if (my_want_state_is_will(i)) { 23438690Sborman if (TELOPT_OK(i)) 23538690Sborman printf("want WILL %s\n", TELOPT(i)); 23638690Sborman else if (TELCMD_OK(i)) 23738690Sborman printf("want WILL %s\n", TELCMD(i)); 23838690Sborman else 23938690Sborman printf("want WILL %d\n", i); 24038690Sborman } else { 24138690Sborman if (TELOPT_OK(i)) 24238690Sborman printf("want WONT %s\n", TELOPT(i)); 24338690Sborman else if (TELCMD_OK(i)) 24438690Sborman printf("want WONT %s\n", TELCMD(i)); 24538690Sborman else 24638690Sborman printf("want WONT %d\n", i); 24738690Sborman } 24838690Sborman } else { 24938690Sborman if (my_state_is_will(i)) { 25038690Sborman if (TELOPT_OK(i)) 25138690Sborman printf(" WILL %s\n", TELOPT(i)); 25238690Sborman else if (TELCMD_OK(i)) 25338690Sborman printf(" WILL %s\n", TELCMD(i)); 25438690Sborman else 25538690Sborman printf(" WILL %d\n", i); 25638690Sborman } 25738690Sborman } 25838690Sborman } 25938690Sborman 26038690Sborman } 26138690Sborman 26238690Sborman char *slcnames[] = { SLC_NAMES }; 26338690Sborman 26432149Sminshall void 26532149Sminshall printsub(direction, pointer, length) 26638690Sborman char direction; /* '<' or '>' */ 26738690Sborman unsigned char *pointer; /* where suboption data sits */ 26832149Sminshall int length; /* length of suboption data */ 26932149Sminshall { 27038690Sborman register int i; 27138690Sborman 27232149Sminshall if (showoptions) { 273*38909Sborman if (direction) { 274*38909Sborman fprintf(NetTrace, "%s suboption ", 27538690Sborman (direction == '<')? "Received":"Sent"); 276*38909Sborman if (length >= 3) { 277*38909Sborman register int j; 27838690Sborman 279*38909Sborman i = pointer[length-2]; 280*38909Sborman j = pointer[length-1]; 28138690Sborman 282*38909Sborman if (i != IAC || j != SE) { 283*38909Sborman fprintf(NetTrace, "(terminated by "); 284*38909Sborman if (TELOPT_OK(i)) 285*38909Sborman fprintf(NetTrace, "%s ", TELOPT(i)); 286*38909Sborman else if (TELCMD_OK(i)) 287*38909Sborman fprintf(NetTrace, "%s ", TELCMD(i)); 288*38909Sborman else 289*38909Sborman fprintf(NetTrace, "%d ", i); 290*38909Sborman if (TELOPT_OK(j)) 291*38909Sborman fprintf(NetTrace, "%s", TELOPT(j)); 292*38909Sborman else if (TELCMD_OK(j)) 293*38909Sborman fprintf(NetTrace, "%s", TELCMD(j)); 294*38909Sborman else 295*38909Sborman fprintf(NetTrace, "%d", j); 296*38909Sborman fprintf(NetTrace, ", not IAC SE!) "); 297*38909Sborman } 29838690Sborman } 299*38909Sborman length -= 2; 30038690Sborman } 30138690Sborman if (length < 1) { 30238690Sborman fprintf(NetTrace, "(Empty suboption???)"); 30338690Sborman return; 30438690Sborman } 30532149Sminshall switch (pointer[0]) { 30632149Sminshall case TELOPT_TTYPE: 30738690Sborman fprintf(NetTrace, "TERMINAL-TYPE "); 30832149Sminshall switch (pointer[1]) { 30932149Sminshall case TELQUAL_IS: 31038690Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, pointer+2); 31132149Sminshall break; 31232149Sminshall case TELQUAL_SEND: 31338690Sborman fprintf(NetTrace, "SEND"); 31432149Sminshall break; 31532149Sminshall default: 31632149Sminshall fprintf(NetTrace, 31738690Sborman "- unknown qualifier %d (0x%x).", 31834849Sminshall pointer[1], pointer[1]); 31932149Sminshall } 32032149Sminshall break; 32138690Sborman case TELOPT_TSPEED: 32238690Sborman fprintf(NetTrace, "TERMINAL-SPEED"); 32338690Sborman if (length < 2) { 32438690Sborman fprintf(NetTrace, " (empty suboption???)"); 32538690Sborman break; 32638690Sborman } 32738690Sborman switch (pointer[1]) { 328*38909Sborman case TELQUAL_IS: 32938690Sborman fprintf(NetTrace, " IS "); 33038690Sborman fprintf(NetTrace, "%.*s", length-2, pointer+2); 33138690Sborman break; 33238690Sborman default: 33338690Sborman if (pointer[1] == 1) 33438690Sborman fprintf(NetTrace, " SEND"); 33538690Sborman else 33638690Sborman fprintf(NetTrace, " %d (unknown)"); 33738690Sborman for (i = 2; i < length; i++) 33838690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 33938690Sborman break; 34038690Sborman } 34138690Sborman break; 34238690Sborman 34338690Sborman case TELOPT_LFLOW: 34438690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 34538690Sborman if (length < 2) { 34638690Sborman fprintf(NetTrace, " (empty suboption???)"); 34738690Sborman break; 34838690Sborman } 34938690Sborman switch (pointer[1]) { 35038690Sborman case 0: 35138690Sborman fprintf(NetTrace, " OFF"); break; 35238690Sborman case 1: 35338690Sborman fprintf(NetTrace, " ON"); break; 35438690Sborman default: 35538690Sborman fprintf(NetTrace, " %d (unknown)"); 35638690Sborman } 35738690Sborman for (i = 2; i < length; i++) 35838690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 35938690Sborman break; 36038690Sborman 36138690Sborman case TELOPT_NAWS: 36238690Sborman fprintf(NetTrace, "NAWS"); 36338690Sborman if (length < 2) { 36438690Sborman fprintf(NetTrace, " (empty suboption???)"); 36538690Sborman break; 36638690Sborman } 36738690Sborman if (length == 2) { 36838690Sborman fprintf(NetTrace, " ?%d?", pointer[1]); 36938690Sborman break; 37038690Sborman } 37138690Sborman fprintf(NetTrace, " %d %d (%d)", 37238690Sborman pointer[1], pointer[2], 37338690Sborman (((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])); 37438690Sborman if (length == 4) { 37538690Sborman fprintf(NetTrace, " ?%d?", pointer[3]); 37638690Sborman break; 37738690Sborman } 37838690Sborman fprintf(NetTrace, " %d %d (%d)", 37938690Sborman pointer[3], pointer[4], 38038690Sborman (((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])); 38138690Sborman for (i = 5; i < length; i++) 38238690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 38338690Sborman break; 38438690Sborman 38538690Sborman case TELOPT_LINEMODE: 38638690Sborman fprintf(NetTrace, "LINEMODE "); 38738690Sborman if (length < 2) { 38838690Sborman fprintf(NetTrace, " (empty suboption???)"); 38938690Sborman break; 39038690Sborman } 39138690Sborman switch (pointer[1]) { 39238690Sborman case WILL: 39338690Sborman fprintf(NetTrace, "WILL "); 39438690Sborman goto common; 39538690Sborman case WONT: 39638690Sborman fprintf(NetTrace, "WONT "); 39738690Sborman goto common; 39838690Sborman case DO: 39938690Sborman fprintf(NetTrace, "DO "); 40038690Sborman goto common; 40138690Sborman case DONT: 40238690Sborman fprintf(NetTrace, "DONT "); 40338690Sborman common: 40438690Sborman if (length < 3) { 40538690Sborman fprintf(NetTrace, "(no option???)"); 40638690Sborman break; 40738690Sborman } 40838690Sborman switch (pointer[2]) { 40938690Sborman case LM_FORWARDMASK: 41038690Sborman fprintf(NetTrace, "Forward Mask"); 41138690Sborman for (i = 3; i < length; i++) 41238690Sborman fprintf(NetTrace, " %x", pointer[i]); 41338690Sborman break; 41438690Sborman default: 41538690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]); 41638690Sborman for (i = 3; i < length; i++) 41738690Sborman fprintf(NetTrace, " %d", pointer[i]); 41838690Sborman break; 41938690Sborman } 42038690Sborman break; 42138690Sborman 42238690Sborman case LM_SLC: 42338690Sborman fprintf(NetTrace, "SLC"); 42438690Sborman for (i = 2; i < length - 2; i += 3) { 42538690Sborman if (pointer[i+SLC_FUNC] <= NSLC) 42638690Sborman fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]); 42738690Sborman else 42838690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 42938690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 43038690Sborman case SLC_NOSUPPORT: 43138690Sborman fprintf(NetTrace, " NOSUPPORT"); break; 43238690Sborman case SLC_CANTCHANGE: 43338690Sborman fprintf(NetTrace, " CANTCHANGE"); break; 43438690Sborman case SLC_VARIABLE: 43538690Sborman fprintf(NetTrace, " VARIABLE"); break; 43638690Sborman case SLC_DEFAULT: 43738690Sborman fprintf(NetTrace, " DEFAULT"); break; 43838690Sborman } 43938690Sborman fprintf(NetTrace, "%s%s%s", 44038690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 44138690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 44238690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 44338690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 44438690Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) 44538690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 44638690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 44738690Sborman } 44838690Sborman for (; i < length; i++) 44938690Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 45038690Sborman break; 45138690Sborman 45238690Sborman case LM_MODE: 45338690Sborman fprintf(NetTrace, "MODE "); 45438690Sborman if (length < 3) { 45538690Sborman fprintf(NetTrace, "(no mode???)"); 45638690Sborman break; 45738690Sborman } 45838690Sborman { 45938690Sborman char tbuf[32]; 46038690Sborman sprintf(tbuf, "%s%s%s", 46138690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "", 46238690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 46338690Sborman pointer[2]&MODE_ACK ? "|ACK" : ""); 46438690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 46538690Sborman } 46638690Sborman if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) 46738690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]); 46838690Sborman for (i = 3; i < length; i++) 46938690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]); 47038690Sborman break; 47138690Sborman default: 47238690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]); 47338690Sborman for (i = 2; i < length; i++) 47438690Sborman fprintf(NetTrace, " %d", pointer[i]); 47538690Sborman } 47638690Sborman break; 47738690Sborman 478*38909Sborman case TELOPT_STATUS: { 479*38909Sborman register char *cp; 480*38909Sborman register int j, k; 481*38909Sborman 482*38909Sborman fprintf(NetTrace, "STATUS"); 483*38909Sborman 484*38909Sborman switch (pointer[1]) { 485*38909Sborman default: 486*38909Sborman if (pointer[1] == TELQUAL_SEND) 487*38909Sborman fprintf(NetTrace, " SEND"); 488*38909Sborman else 489*38909Sborman fprintf(NetTrace, " %d (unknown)"); 490*38909Sborman for (i = 2; i < length; i++) 491*38909Sborman fprintf(NetTrace, " ?%d?", pointer[i]); 492*38909Sborman break; 493*38909Sborman case TELQUAL_IS: 494*38909Sborman if (NetTrace == stdout) 495*38909Sborman fprintf(NetTrace, " IS\r\n"); 496*38909Sborman else 497*38909Sborman fprintf(NetTrace, " IS\n"); 498*38909Sborman 499*38909Sborman for (i = 2; i < length; i++) { 500*38909Sborman switch(pointer[i]) { 501*38909Sborman case DO: cp = "DO"; goto common2; 502*38909Sborman case DONT: cp = "DONT"; goto common2; 503*38909Sborman case WILL: cp = "WILL"; goto common2; 504*38909Sborman case WONT: cp = "WONT"; goto common2; 505*38909Sborman common2: 506*38909Sborman i++; 507*38909Sborman if (TELOPT_OK(pointer[i])) 508*38909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 509*38909Sborman else 510*38909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]); 511*38909Sborman 512*38909Sborman if (NetTrace == stdout) 513*38909Sborman fprintf(NetTrace, "\r\n"); 514*38909Sborman else 515*38909Sborman fprintf(NetTrace, "\n"); 516*38909Sborman break; 517*38909Sborman 518*38909Sborman case SB: 519*38909Sborman fprintf(NetTrace, " SB "); 520*38909Sborman i++; 521*38909Sborman j = k = i; 522*38909Sborman while (j < length) { 523*38909Sborman if (pointer[j] == SE) { 524*38909Sborman if (j+1 == length) 525*38909Sborman break; 526*38909Sborman if (pointer[j+1] == SE) 527*38909Sborman j++; 528*38909Sborman else 529*38909Sborman break; 530*38909Sborman } 531*38909Sborman pointer[k++] = pointer[j++]; 532*38909Sborman } 533*38909Sborman printsub(0, &pointer[i], k - i); 534*38909Sborman if (i < length) { 535*38909Sborman fprintf(NetTrace, " SE"); 536*38909Sborman i = j; 537*38909Sborman } else 538*38909Sborman i = j - 1; 539*38909Sborman 540*38909Sborman if (NetTrace == stdout) 541*38909Sborman fprintf(NetTrace, "\r\n"); 542*38909Sborman else 543*38909Sborman fprintf(NetTrace, "\n"); 544*38909Sborman 545*38909Sborman break; 546*38909Sborman 547*38909Sborman default: 548*38909Sborman fprintf(NetTrace, " %d", pointer[i]); 549*38909Sborman break; 550*38909Sborman } 551*38909Sborman } 552*38909Sborman break; 553*38909Sborman } 554*38909Sborman break; 555*38909Sborman } 556*38909Sborman 55732149Sminshall default: 55838690Sborman fprintf(NetTrace, "Unknown option "); 55938690Sborman for (i = 0; i < length; i++) 56038690Sborman fprintf(NetTrace, " %d", pointer[i]); 56138690Sborman break; 56232149Sminshall } 563*38909Sborman if (direction) { 564*38909Sborman if (NetTrace == stdout) 565*38909Sborman fprintf(NetTrace, "\r\n"); 566*38909Sborman else 567*38909Sborman fprintf(NetTrace, "\n"); 568*38909Sborman } 56932149Sminshall } 57032149Sminshall } 57136278Sminshall 57236278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 57336278Sminshall * Note that we consider the buffer to run all the 57436278Sminshall * way to the kernel (thus the select). 57536278Sminshall */ 57636278Sminshall 57736278Sminshall void 57836278Sminshall EmptyTerminal() 57936278Sminshall { 58036278Sminshall #if defined(unix) 58136278Sminshall fd_set o; 58236278Sminshall 58336278Sminshall FD_ZERO(&o); 58436278Sminshall #endif /* defined(unix) */ 58536278Sminshall 58636278Sminshall if (TTYBYTES() == 0) { 58736278Sminshall #if defined(unix) 58836278Sminshall FD_SET(tout, &o); 58936278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 59036278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 59136278Sminshall #endif /* defined(unix) */ 59236278Sminshall } else { 59336278Sminshall while (TTYBYTES()) { 59436278Sminshall ttyflush(0); 59536278Sminshall #if defined(unix) 59636278Sminshall FD_SET(tout, &o); 59736278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 59836278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 59936278Sminshall #endif /* defined(unix) */ 60036278Sminshall } 60136278Sminshall } 60236278Sminshall } 60336278Sminshall 60436278Sminshall void 60536278Sminshall SetForExit() 60636278Sminshall { 60738690Sborman setconnmode(0); 60836278Sminshall #if defined(TN3270) 60936278Sminshall if (In3270) { 61036278Sminshall Finish3270(); 61136278Sminshall } 61236279Sminshall #else /* defined(TN3270) */ 61336279Sminshall do { 61436279Sminshall telrcv(); /* Process any incoming data */ 61536279Sminshall EmptyTerminal(); 61636279Sminshall } while (ring_full_count(&netiring)); /* While there is any */ 61736278Sminshall #endif /* defined(TN3270) */ 61836278Sminshall setcommandmode(); 61936278Sminshall fflush(stdout); 62036278Sminshall fflush(stderr); 62136278Sminshall #if defined(TN3270) 62236278Sminshall if (In3270) { 62336278Sminshall StopScreen(1); 62436278Sminshall } 62536278Sminshall #endif /* defined(TN3270) */ 62638690Sborman setconnmode(0); 62736278Sminshall EmptyTerminal(); /* Flush the path to the tty */ 62836278Sminshall setcommandmode(); 62936278Sminshall } 63036278Sminshall 63136278Sminshall void 63236278Sminshall Exit(returnCode) 63336278Sminshall int returnCode; 63436278Sminshall { 63536278Sminshall SetForExit(); 63636278Sminshall exit(returnCode); 63736278Sminshall } 63836278Sminshall 63936278Sminshall void 64036278Sminshall ExitString(string, returnCode) 64136278Sminshall char *string; 64236278Sminshall int returnCode; 64336278Sminshall { 64436278Sminshall SetForExit(); 64536278Sminshall fwrite(string, 1, strlen(string), stderr); 64636278Sminshall exit(returnCode); 64736278Sminshall } 64836278Sminshall 64936278Sminshall #if defined(MSDOS) 65036278Sminshall void 65136278Sminshall ExitPerror(string, returnCode) 65236278Sminshall char *string; 65336278Sminshall int returnCode; 65436278Sminshall { 65536278Sminshall SetForExit(); 65636278Sminshall perror(string); 65736278Sminshall exit(returnCode); 65836278Sminshall } 65936278Sminshall #endif /* defined(MSDOS) */ 660