utilities.c revision 29088
129088Smarkm/* 229088Smarkm * Copyright (c) 1988, 1993 329088Smarkm * The Regents of the University of California. All rights reserved. 429088Smarkm * 529088Smarkm * Redistribution and use in source and binary forms, with or without 629088Smarkm * modification, are permitted provided that the following conditions 729088Smarkm * are met: 829088Smarkm * 1. Redistributions of source code must retain the above copyright 929088Smarkm * notice, this list of conditions and the following disclaimer. 1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1129088Smarkm * notice, this list of conditions and the following disclaimer in the 1229088Smarkm * documentation and/or other materials provided with the distribution. 1329088Smarkm * 3. All advertising materials mentioning features or use of this software 1429088Smarkm * must display the following acknowledgement: 1529088Smarkm * This product includes software developed by the University of 1629088Smarkm * California, Berkeley and its contributors. 1729088Smarkm * 4. Neither the name of the University nor the names of its contributors 1829088Smarkm * may be used to endorse or promote products derived from this software 1929088Smarkm * without specific prior written permission. 2029088Smarkm * 2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2429088Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3129088Smarkm * SUCH DAMAGE. 3229088Smarkm */ 3329088Smarkm 3429088Smarkm#ifndef lint 3529088Smarkmstatic char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 5/30/95"; 3629088Smarkm#endif /* not lint */ 3729088Smarkm 3829088Smarkm#define TELOPTS 3929088Smarkm#define TELCMDS 4029088Smarkm#define SLC_NAMES 4129088Smarkm#include <arpa/telnet.h> 4229088Smarkm#include <sys/types.h> 4329088Smarkm#include <sys/time.h> 4429088Smarkm 4529088Smarkm#include <ctype.h> 4629088Smarkm 4729088Smarkm#include "general.h" 4829088Smarkm 4929088Smarkm#include "fdset.h" 5029088Smarkm 5129088Smarkm#include "ring.h" 5229088Smarkm 5329088Smarkm#include "defines.h" 5429088Smarkm 5529088Smarkm#include "externs.h" 5629088Smarkm 5729088SmarkmFILE *NetTrace = 0; /* Not in bss, since needs to stay */ 5829088Smarkmint prettydump; 5929088Smarkm 6029088Smarkm/* 6129088Smarkm * upcase() 6229088Smarkm * 6329088Smarkm * Upcase (in place) the argument. 6429088Smarkm */ 6529088Smarkm 6629088Smarkm void 6729088Smarkmupcase(argument) 6829088Smarkm register char *argument; 6929088Smarkm{ 7029088Smarkm register int c; 7129088Smarkm 7229088Smarkm while ((c = *argument) != 0) { 7329088Smarkm if (islower(c)) { 7429088Smarkm *argument = toupper(c); 7529088Smarkm } 7629088Smarkm argument++; 7729088Smarkm } 7829088Smarkm} 7929088Smarkm 8029088Smarkm/* 8129088Smarkm * SetSockOpt() 8229088Smarkm * 8329088Smarkm * Compensate for differences in 4.2 and 4.3 systems. 8429088Smarkm */ 8529088Smarkm 8629088Smarkm int 8729088SmarkmSetSockOpt(fd, level, option, yesno) 8829088Smarkm int fd, level, option, yesno; 8929088Smarkm{ 9029088Smarkm#ifndef NOT43 9129088Smarkm return setsockopt(fd, level, option, 9229088Smarkm (char *)&yesno, sizeof yesno); 9329088Smarkm#else /* NOT43 */ 9429088Smarkm if (yesno == 0) { /* Can't do that in 4.2! */ 9529088Smarkm fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n", 9629088Smarkm option); 9729088Smarkm return -1; 9829088Smarkm } 9929088Smarkm return setsockopt(fd, level, option, 0, 0); 10029088Smarkm#endif /* NOT43 */ 10129088Smarkm} 10229088Smarkm 10329088Smarkm/* 10429088Smarkm * The following are routines used to print out debugging information. 10529088Smarkm */ 10629088Smarkm 10729088Smarkmunsigned char NetTraceFile[256] = "(standard output)"; 10829088Smarkm 10929088Smarkm void 11029088SmarkmSetNetTrace(file) 11129088Smarkm register char *file; 11229088Smarkm{ 11329088Smarkm if (NetTrace && NetTrace != stdout) 11429088Smarkm fclose(NetTrace); 11529088Smarkm if (file && (strcmp(file, "-") != 0)) { 11629088Smarkm NetTrace = fopen(file, "w"); 11729088Smarkm if (NetTrace) { 11829088Smarkm strcpy((char *)NetTraceFile, file); 11929088Smarkm return; 12029088Smarkm } 12129088Smarkm fprintf(stderr, "Cannot open %s.\n", file); 12229088Smarkm } 12329088Smarkm NetTrace = stdout; 12429088Smarkm strcpy((char *)NetTraceFile, "(standard output)"); 12529088Smarkm} 12629088Smarkm 12729088Smarkm void 12829088SmarkmDump(direction, buffer, length) 12929088Smarkm char direction; 13029088Smarkm unsigned char *buffer; 13129088Smarkm int length; 13229088Smarkm{ 13329088Smarkm# define BYTES_PER_LINE 32 13429088Smarkm# define min(x,y) ((x<y)? x:y) 13529088Smarkm unsigned char *pThis; 13629088Smarkm int offset; 13729088Smarkm extern pettydump; 13829088Smarkm 13929088Smarkm offset = 0; 14029088Smarkm 14129088Smarkm while (length) { 14229088Smarkm /* print one line */ 14329088Smarkm fprintf(NetTrace, "%c 0x%x\t", direction, offset); 14429088Smarkm pThis = buffer; 14529088Smarkm if (prettydump) { 14629088Smarkm buffer = buffer + min(length, BYTES_PER_LINE/2); 14729088Smarkm while (pThis < buffer) { 14829088Smarkm fprintf(NetTrace, "%c%.2x", 14929088Smarkm (((*pThis)&0xff) == 0xff) ? '*' : ' ', 15029088Smarkm (*pThis)&0xff); 15129088Smarkm pThis++; 15229088Smarkm } 15329088Smarkm length -= BYTES_PER_LINE/2; 15429088Smarkm offset += BYTES_PER_LINE/2; 15529088Smarkm } else { 15629088Smarkm buffer = buffer + min(length, BYTES_PER_LINE); 15729088Smarkm while (pThis < buffer) { 15829088Smarkm fprintf(NetTrace, "%.2x", (*pThis)&0xff); 15929088Smarkm pThis++; 16029088Smarkm } 16129088Smarkm length -= BYTES_PER_LINE; 16229088Smarkm offset += BYTES_PER_LINE; 16329088Smarkm } 16429088Smarkm if (NetTrace == stdout) { 16529088Smarkm fprintf(NetTrace, "\r\n"); 16629088Smarkm } else { 16729088Smarkm fprintf(NetTrace, "\n"); 16829088Smarkm } 16929088Smarkm if (length < 0) { 17029088Smarkm fflush(NetTrace); 17129088Smarkm return; 17229088Smarkm } 17329088Smarkm /* find next unique line */ 17429088Smarkm } 17529088Smarkm fflush(NetTrace); 17629088Smarkm} 17729088Smarkm 17829088Smarkm 17929088Smarkm void 18029088Smarkmprintoption(direction, cmd, option) 18129088Smarkm char *direction; 18229088Smarkm int cmd, option; 18329088Smarkm{ 18429088Smarkm if (!showoptions) 18529088Smarkm return; 18629088Smarkm if (cmd == IAC) { 18729088Smarkm if (TELCMD_OK(option)) 18829088Smarkm fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option)); 18929088Smarkm else 19029088Smarkm fprintf(NetTrace, "%s IAC %d", direction, option); 19129088Smarkm } else { 19229088Smarkm register char *fmt; 19329088Smarkm fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" : 19429088Smarkm (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0; 19529088Smarkm if (fmt) { 19629088Smarkm fprintf(NetTrace, "%s %s ", direction, fmt); 19729088Smarkm if (TELOPT_OK(option)) 19829088Smarkm fprintf(NetTrace, "%s", TELOPT(option)); 19929088Smarkm else if (option == TELOPT_EXOPL) 20029088Smarkm fprintf(NetTrace, "EXOPL"); 20129088Smarkm else 20229088Smarkm fprintf(NetTrace, "%d", option); 20329088Smarkm } else 20429088Smarkm fprintf(NetTrace, "%s %d %d", direction, cmd, option); 20529088Smarkm } 20629088Smarkm if (NetTrace == stdout) { 20729088Smarkm fprintf(NetTrace, "\r\n"); 20829088Smarkm fflush(NetTrace); 20929088Smarkm } else { 21029088Smarkm fprintf(NetTrace, "\n"); 21129088Smarkm } 21229088Smarkm return; 21329088Smarkm} 21429088Smarkm 21529088Smarkm void 21629088Smarkmoptionstatus() 21729088Smarkm{ 21829088Smarkm register int i; 21929088Smarkm extern char will_wont_resp[], do_dont_resp[]; 22029088Smarkm 22129088Smarkm for (i = 0; i < 256; i++) { 22229088Smarkm if (do_dont_resp[i]) { 22329088Smarkm if (TELOPT_OK(i)) 22429088Smarkm printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]); 22529088Smarkm else if (TELCMD_OK(i)) 22629088Smarkm printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]); 22729088Smarkm else 22829088Smarkm printf("resp DO_DONT %d: %d\n", i, 22929088Smarkm do_dont_resp[i]); 23029088Smarkm if (my_want_state_is_do(i)) { 23129088Smarkm if (TELOPT_OK(i)) 23229088Smarkm printf("want DO %s\n", TELOPT(i)); 23329088Smarkm else if (TELCMD_OK(i)) 23429088Smarkm printf("want DO %s\n", TELCMD(i)); 23529088Smarkm else 23629088Smarkm printf("want DO %d\n", i); 23729088Smarkm } else { 23829088Smarkm if (TELOPT_OK(i)) 23929088Smarkm printf("want DONT %s\n", TELOPT(i)); 24029088Smarkm else if (TELCMD_OK(i)) 24129088Smarkm printf("want DONT %s\n", TELCMD(i)); 24229088Smarkm else 24329088Smarkm printf("want DONT %d\n", i); 24429088Smarkm } 24529088Smarkm } else { 24629088Smarkm if (my_state_is_do(i)) { 24729088Smarkm if (TELOPT_OK(i)) 24829088Smarkm printf(" DO %s\n", TELOPT(i)); 24929088Smarkm else if (TELCMD_OK(i)) 25029088Smarkm printf(" DO %s\n", TELCMD(i)); 25129088Smarkm else 25229088Smarkm printf(" DO %d\n", i); 25329088Smarkm } 25429088Smarkm } 25529088Smarkm if (will_wont_resp[i]) { 25629088Smarkm if (TELOPT_OK(i)) 25729088Smarkm printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]); 25829088Smarkm else if (TELCMD_OK(i)) 25929088Smarkm printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]); 26029088Smarkm else 26129088Smarkm printf("resp WILL_WONT %d: %d\n", 26229088Smarkm i, will_wont_resp[i]); 26329088Smarkm if (my_want_state_is_will(i)) { 26429088Smarkm if (TELOPT_OK(i)) 26529088Smarkm printf("want WILL %s\n", TELOPT(i)); 26629088Smarkm else if (TELCMD_OK(i)) 26729088Smarkm printf("want WILL %s\n", TELCMD(i)); 26829088Smarkm else 26929088Smarkm printf("want WILL %d\n", i); 27029088Smarkm } else { 27129088Smarkm if (TELOPT_OK(i)) 27229088Smarkm printf("want WONT %s\n", TELOPT(i)); 27329088Smarkm else if (TELCMD_OK(i)) 27429088Smarkm printf("want WONT %s\n", TELCMD(i)); 27529088Smarkm else 27629088Smarkm printf("want WONT %d\n", i); 27729088Smarkm } 27829088Smarkm } else { 27929088Smarkm if (my_state_is_will(i)) { 28029088Smarkm if (TELOPT_OK(i)) 28129088Smarkm printf(" WILL %s\n", TELOPT(i)); 28229088Smarkm else if (TELCMD_OK(i)) 28329088Smarkm printf(" WILL %s\n", TELCMD(i)); 28429088Smarkm else 28529088Smarkm printf(" WILL %d\n", i); 28629088Smarkm } 28729088Smarkm } 28829088Smarkm } 28929088Smarkm 29029088Smarkm} 29129088Smarkm 29229088Smarkm void 29329088Smarkmprintsub(direction, pointer, length) 29429088Smarkm char direction; /* '<' or '>' */ 29529088Smarkm unsigned char *pointer; /* where suboption data sits */ 29629088Smarkm int length; /* length of suboption data */ 29729088Smarkm{ 29829088Smarkm register int i; 29929088Smarkm char buf[512]; 30029088Smarkm extern int want_status_response; 30129088Smarkm 30229088Smarkm if (showoptions || direction == 0 || 30329088Smarkm (want_status_response && (pointer[0] == TELOPT_STATUS))) { 30429088Smarkm if (direction) { 30529088Smarkm fprintf(NetTrace, "%s IAC SB ", 30629088Smarkm (direction == '<')? "RCVD":"SENT"); 30729088Smarkm if (length >= 3) { 30829088Smarkm register int j; 30929088Smarkm 31029088Smarkm i = pointer[length-2]; 31129088Smarkm j = pointer[length-1]; 31229088Smarkm 31329088Smarkm if (i != IAC || j != SE) { 31429088Smarkm fprintf(NetTrace, "(terminated by "); 31529088Smarkm if (TELOPT_OK(i)) 31629088Smarkm fprintf(NetTrace, "%s ", TELOPT(i)); 31729088Smarkm else if (TELCMD_OK(i)) 31829088Smarkm fprintf(NetTrace, "%s ", TELCMD(i)); 31929088Smarkm else 32029088Smarkm fprintf(NetTrace, "%d ", i); 32129088Smarkm if (TELOPT_OK(j)) 32229088Smarkm fprintf(NetTrace, "%s", TELOPT(j)); 32329088Smarkm else if (TELCMD_OK(j)) 32429088Smarkm fprintf(NetTrace, "%s", TELCMD(j)); 32529088Smarkm else 32629088Smarkm fprintf(NetTrace, "%d", j); 32729088Smarkm fprintf(NetTrace, ", not IAC SE!) "); 32829088Smarkm } 32929088Smarkm } 33029088Smarkm length -= 2; 33129088Smarkm } 33229088Smarkm if (length < 1) { 33329088Smarkm fprintf(NetTrace, "(Empty suboption??\?)"); 33429088Smarkm if (NetTrace == stdout) 33529088Smarkm fflush(NetTrace); 33629088Smarkm return; 33729088Smarkm } 33829088Smarkm switch (pointer[0]) { 33929088Smarkm case TELOPT_TTYPE: 34029088Smarkm fprintf(NetTrace, "TERMINAL-TYPE "); 34129088Smarkm switch (pointer[1]) { 34229088Smarkm case TELQUAL_IS: 34329088Smarkm fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 34429088Smarkm break; 34529088Smarkm case TELQUAL_SEND: 34629088Smarkm fprintf(NetTrace, "SEND"); 34729088Smarkm break; 34829088Smarkm default: 34929088Smarkm fprintf(NetTrace, 35029088Smarkm "- unknown qualifier %d (0x%x).", 35129088Smarkm pointer[1], pointer[1]); 35229088Smarkm } 35329088Smarkm break; 35429088Smarkm case TELOPT_TSPEED: 35529088Smarkm fprintf(NetTrace, "TERMINAL-SPEED"); 35629088Smarkm if (length < 2) { 35729088Smarkm fprintf(NetTrace, " (empty suboption??\?)"); 35829088Smarkm break; 35929088Smarkm } 36029088Smarkm switch (pointer[1]) { 36129088Smarkm case TELQUAL_IS: 36229088Smarkm fprintf(NetTrace, " IS "); 36329088Smarkm fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2); 36429088Smarkm break; 36529088Smarkm default: 36629088Smarkm if (pointer[1] == 1) 36729088Smarkm fprintf(NetTrace, " SEND"); 36829088Smarkm else 36929088Smarkm fprintf(NetTrace, " %d (unknown)", pointer[1]); 37029088Smarkm for (i = 2; i < length; i++) 37129088Smarkm fprintf(NetTrace, " ?%d?", pointer[i]); 37229088Smarkm break; 37329088Smarkm } 37429088Smarkm break; 37529088Smarkm 37629088Smarkm case TELOPT_LFLOW: 37729088Smarkm fprintf(NetTrace, "TOGGLE-FLOW-CONTROL"); 37829088Smarkm if (length < 2) { 37929088Smarkm fprintf(NetTrace, " (empty suboption??\?)"); 38029088Smarkm break; 38129088Smarkm } 38229088Smarkm switch (pointer[1]) { 38329088Smarkm case LFLOW_OFF: 38429088Smarkm fprintf(NetTrace, " OFF"); break; 38529088Smarkm case LFLOW_ON: 38629088Smarkm fprintf(NetTrace, " ON"); break; 38729088Smarkm case LFLOW_RESTART_ANY: 38829088Smarkm fprintf(NetTrace, " RESTART-ANY"); break; 38929088Smarkm case LFLOW_RESTART_XON: 39029088Smarkm fprintf(NetTrace, " RESTART-XON"); break; 39129088Smarkm default: 39229088Smarkm fprintf(NetTrace, " %d (unknown)", pointer[1]); 39329088Smarkm } 39429088Smarkm for (i = 2; i < length; i++) 39529088Smarkm fprintf(NetTrace, " ?%d?", pointer[i]); 39629088Smarkm break; 39729088Smarkm 39829088Smarkm case TELOPT_NAWS: 39929088Smarkm fprintf(NetTrace, "NAWS"); 40029088Smarkm if (length < 2) { 40129088Smarkm fprintf(NetTrace, " (empty suboption??\?)"); 40229088Smarkm break; 40329088Smarkm } 40429088Smarkm if (length == 2) { 40529088Smarkm fprintf(NetTrace, " ?%d?", pointer[1]); 40629088Smarkm break; 40729088Smarkm } 40829088Smarkm fprintf(NetTrace, " %d %d (%d)", 40929088Smarkm pointer[1], pointer[2], 41029088Smarkm (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); 41129088Smarkm if (length == 4) { 41229088Smarkm fprintf(NetTrace, " ?%d?", pointer[3]); 41329088Smarkm break; 41429088Smarkm } 41529088Smarkm fprintf(NetTrace, " %d %d (%d)", 41629088Smarkm pointer[3], pointer[4], 41729088Smarkm (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); 41829088Smarkm for (i = 5; i < length; i++) 41929088Smarkm fprintf(NetTrace, " ?%d?", pointer[i]); 42029088Smarkm break; 42129088Smarkm 42229088Smarkm#if defined(AUTHENTICATION) 42329088Smarkm case TELOPT_AUTHENTICATION: 42429088Smarkm fprintf(NetTrace, "AUTHENTICATION"); 42529088Smarkm if (length < 2) { 42629088Smarkm fprintf(NetTrace, " (empty suboption??\?)"); 42729088Smarkm break; 42829088Smarkm } 42929088Smarkm switch (pointer[1]) { 43029088Smarkm case TELQUAL_REPLY: 43129088Smarkm case TELQUAL_IS: 43229088Smarkm fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? 43329088Smarkm "IS" : "REPLY"); 43429088Smarkm if (AUTHTYPE_NAME_OK(pointer[2])) 43529088Smarkm fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2])); 43629088Smarkm else 43729088Smarkm fprintf(NetTrace, "%d ", pointer[2]); 43829088Smarkm if (length < 3) { 43929088Smarkm fprintf(NetTrace, "(partial suboption??\?)"); 44029088Smarkm break; 44129088Smarkm } 44229088Smarkm fprintf(NetTrace, "%s|%s", 44329088Smarkm ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 44429088Smarkm "CLIENT" : "SERVER", 44529088Smarkm ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 44629088Smarkm "MUTUAL" : "ONE-WAY"); 44729088Smarkm 44829088Smarkm auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 44929088Smarkm fprintf(NetTrace, "%s", buf); 45029088Smarkm break; 45129088Smarkm 45229088Smarkm case TELQUAL_SEND: 45329088Smarkm i = 2; 45429088Smarkm fprintf(NetTrace, " SEND "); 45529088Smarkm while (i < length) { 45629088Smarkm if (AUTHTYPE_NAME_OK(pointer[i])) 45729088Smarkm fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i])); 45829088Smarkm else 45929088Smarkm fprintf(NetTrace, "%d ", pointer[i]); 46029088Smarkm if (++i >= length) { 46129088Smarkm fprintf(NetTrace, "(partial suboption??\?)"); 46229088Smarkm break; 46329088Smarkm } 46429088Smarkm fprintf(NetTrace, "%s|%s ", 46529088Smarkm ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? 46629088Smarkm "CLIENT" : "SERVER", 46729088Smarkm ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? 46829088Smarkm "MUTUAL" : "ONE-WAY"); 46929088Smarkm ++i; 47029088Smarkm } 47129088Smarkm break; 47229088Smarkm 47329088Smarkm case TELQUAL_NAME: 47429088Smarkm i = 2; 47529088Smarkm fprintf(NetTrace, " NAME \""); 47629088Smarkm while (i < length) 47729088Smarkm putc(pointer[i++], NetTrace); 47829088Smarkm putc('"', NetTrace); 47929088Smarkm break; 48029088Smarkm 48129088Smarkm default: 48229088Smarkm for (i = 2; i < length; i++) 48329088Smarkm fprintf(NetTrace, " ?%d?", pointer[i]); 48429088Smarkm break; 48529088Smarkm } 48629088Smarkm break; 48729088Smarkm#endif 48829088Smarkm 48929088Smarkm#ifdef ENCRYPTION 49029088Smarkm case TELOPT_ENCRYPT: 49129088Smarkm fprintf(NetTrace, "ENCRYPT"); 49229088Smarkm if (length < 2) { 49329088Smarkm fprintf(NetTrace, " (empty suboption??\?)"); 49429088Smarkm break; 49529088Smarkm } 49629088Smarkm switch (pointer[1]) { 49729088Smarkm case ENCRYPT_START: 49829088Smarkm fprintf(NetTrace, " START"); 49929088Smarkm break; 50029088Smarkm 50129088Smarkm case ENCRYPT_END: 50229088Smarkm fprintf(NetTrace, " END"); 50329088Smarkm break; 50429088Smarkm 50529088Smarkm case ENCRYPT_REQSTART: 50629088Smarkm fprintf(NetTrace, " REQUEST-START"); 50729088Smarkm break; 50829088Smarkm 50929088Smarkm case ENCRYPT_REQEND: 51029088Smarkm fprintf(NetTrace, " REQUEST-END"); 51129088Smarkm break; 51229088Smarkm 51329088Smarkm case ENCRYPT_IS: 51429088Smarkm case ENCRYPT_REPLY: 51529088Smarkm fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? 51629088Smarkm "IS" : "REPLY"); 51729088Smarkm if (length < 3) { 51829088Smarkm fprintf(NetTrace, " (partial suboption??\?)"); 51929088Smarkm break; 52029088Smarkm } 52129088Smarkm if (ENCTYPE_NAME_OK(pointer[2])) 52229088Smarkm fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2])); 52329088Smarkm else 52429088Smarkm fprintf(NetTrace, " %d (unknown)", pointer[2]); 52529088Smarkm 52629088Smarkm encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); 52729088Smarkm fprintf(NetTrace, "%s", buf); 52829088Smarkm break; 52929088Smarkm 53029088Smarkm case ENCRYPT_SUPPORT: 53129088Smarkm i = 2; 53229088Smarkm fprintf(NetTrace, " SUPPORT "); 53329088Smarkm while (i < length) { 53429088Smarkm if (ENCTYPE_NAME_OK(pointer[i])) 53529088Smarkm fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i])); 53629088Smarkm else 53729088Smarkm fprintf(NetTrace, "%d ", pointer[i]); 53829088Smarkm i++; 53929088Smarkm } 54029088Smarkm break; 54129088Smarkm 54229088Smarkm case ENCRYPT_ENC_KEYID: 54329088Smarkm fprintf(NetTrace, " ENC_KEYID "); 54429088Smarkm goto encommon; 54529088Smarkm 54629088Smarkm case ENCRYPT_DEC_KEYID: 54729088Smarkm fprintf(NetTrace, " DEC_KEYID "); 54829088Smarkm goto encommon; 54929088Smarkm 55029088Smarkm default: 55129088Smarkm fprintf(NetTrace, " %d (unknown)", pointer[1]); 55229088Smarkm encommon: 55329088Smarkm for (i = 2; i < length; i++) 55429088Smarkm fprintf(NetTrace, " %d", pointer[i]); 55529088Smarkm break; 55629088Smarkm } 55729088Smarkm break; 55829088Smarkm#endif /* ENCRYPTION */ 55929088Smarkm 56029088Smarkm case TELOPT_LINEMODE: 56129088Smarkm fprintf(NetTrace, "LINEMODE "); 56229088Smarkm if (length < 2) { 56329088Smarkm fprintf(NetTrace, " (empty suboption??\?)"); 56429088Smarkm break; 56529088Smarkm } 56629088Smarkm switch (pointer[1]) { 56729088Smarkm case WILL: 56829088Smarkm fprintf(NetTrace, "WILL "); 56929088Smarkm goto common; 57029088Smarkm case WONT: 57129088Smarkm fprintf(NetTrace, "WONT "); 57229088Smarkm goto common; 57329088Smarkm case DO: 57429088Smarkm fprintf(NetTrace, "DO "); 57529088Smarkm goto common; 57629088Smarkm case DONT: 57729088Smarkm fprintf(NetTrace, "DONT "); 57829088Smarkm common: 57929088Smarkm if (length < 3) { 58029088Smarkm fprintf(NetTrace, "(no option??\?)"); 58129088Smarkm break; 58229088Smarkm } 58329088Smarkm switch (pointer[2]) { 58429088Smarkm case LM_FORWARDMASK: 58529088Smarkm fprintf(NetTrace, "Forward Mask"); 58629088Smarkm for (i = 3; i < length; i++) 58729088Smarkm fprintf(NetTrace, " %x", pointer[i]); 58829088Smarkm break; 58929088Smarkm default: 59029088Smarkm fprintf(NetTrace, "%d (unknown)", pointer[2]); 59129088Smarkm for (i = 3; i < length; i++) 59229088Smarkm fprintf(NetTrace, " %d", pointer[i]); 59329088Smarkm break; 59429088Smarkm } 59529088Smarkm break; 59629088Smarkm 59729088Smarkm case LM_SLC: 59829088Smarkm fprintf(NetTrace, "SLC"); 59929088Smarkm for (i = 2; i < length - 2; i += 3) { 60029088Smarkm if (SLC_NAME_OK(pointer[i+SLC_FUNC])) 60129088Smarkm fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC])); 60229088Smarkm else 60329088Smarkm fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]); 60429088Smarkm switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { 60529088Smarkm case SLC_NOSUPPORT: 60629088Smarkm fprintf(NetTrace, " NOSUPPORT"); break; 60729088Smarkm case SLC_CANTCHANGE: 60829088Smarkm fprintf(NetTrace, " CANTCHANGE"); break; 60929088Smarkm case SLC_VARIABLE: 61029088Smarkm fprintf(NetTrace, " VARIABLE"); break; 61129088Smarkm case SLC_DEFAULT: 61229088Smarkm fprintf(NetTrace, " DEFAULT"); break; 61329088Smarkm } 61429088Smarkm fprintf(NetTrace, "%s%s%s", 61529088Smarkm pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", 61629088Smarkm pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", 61729088Smarkm pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); 61829088Smarkm if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| 61929088Smarkm SLC_FLUSHOUT| SLC_LEVELBITS)) 62029088Smarkm fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]); 62129088Smarkm fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]); 62229088Smarkm if ((pointer[i+SLC_VALUE] == IAC) && 62329088Smarkm (pointer[i+SLC_VALUE+1] == IAC)) 62429088Smarkm i++; 62529088Smarkm } 62629088Smarkm for (; i < length; i++) 62729088Smarkm fprintf(NetTrace, " ?%d?", pointer[i]); 62829088Smarkm break; 62929088Smarkm 63029088Smarkm case LM_MODE: 63129088Smarkm fprintf(NetTrace, "MODE "); 63229088Smarkm if (length < 3) { 63329088Smarkm fprintf(NetTrace, "(no mode??\?)"); 63429088Smarkm break; 63529088Smarkm } 63629088Smarkm { 63729088Smarkm char tbuf[64]; 63829088Smarkm sprintf(tbuf, "%s%s%s%s%s", 63929088Smarkm pointer[2]&MODE_EDIT ? "|EDIT" : "", 64029088Smarkm pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "", 64129088Smarkm pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", 64229088Smarkm pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", 64329088Smarkm pointer[2]&MODE_ACK ? "|ACK" : ""); 64429088Smarkm fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); 64529088Smarkm } 64629088Smarkm if (pointer[2]&~(MODE_MASK)) 64729088Smarkm fprintf(NetTrace, " (0x%x)", pointer[2]); 64829088Smarkm for (i = 3; i < length; i++) 64929088Smarkm fprintf(NetTrace, " ?0x%x?", pointer[i]); 65029088Smarkm break; 65129088Smarkm default: 65229088Smarkm fprintf(NetTrace, "%d (unknown)", pointer[1]); 65329088Smarkm for (i = 2; i < length; i++) 65429088Smarkm fprintf(NetTrace, " %d", pointer[i]); 65529088Smarkm } 65629088Smarkm break; 65729088Smarkm 65829088Smarkm case TELOPT_STATUS: { 65929088Smarkm register char *cp; 66029088Smarkm register int j, k; 66129088Smarkm 66229088Smarkm fprintf(NetTrace, "STATUS"); 66329088Smarkm 66429088Smarkm switch (pointer[1]) { 66529088Smarkm default: 66629088Smarkm if (pointer[1] == TELQUAL_SEND) 66729088Smarkm fprintf(NetTrace, " SEND"); 66829088Smarkm else 66929088Smarkm fprintf(NetTrace, " %d (unknown)", pointer[1]); 67029088Smarkm for (i = 2; i < length; i++) 67129088Smarkm fprintf(NetTrace, " ?%d?", pointer[i]); 67229088Smarkm break; 67329088Smarkm case TELQUAL_IS: 67429088Smarkm if (--want_status_response < 0) 67529088Smarkm want_status_response = 0; 67629088Smarkm if (NetTrace == stdout) 67729088Smarkm fprintf(NetTrace, " IS\r\n"); 67829088Smarkm else 67929088Smarkm fprintf(NetTrace, " IS\n"); 68029088Smarkm 68129088Smarkm for (i = 2; i < length; i++) { 68229088Smarkm switch(pointer[i]) { 68329088Smarkm case DO: cp = "DO"; goto common2; 68429088Smarkm case DONT: cp = "DONT"; goto common2; 68529088Smarkm case WILL: cp = "WILL"; goto common2; 68629088Smarkm case WONT: cp = "WONT"; goto common2; 68729088Smarkm common2: 68829088Smarkm i++; 68929088Smarkm if (TELOPT_OK((int)pointer[i])) 69029088Smarkm fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i])); 69129088Smarkm else 69229088Smarkm fprintf(NetTrace, " %s %d", cp, pointer[i]); 69329088Smarkm 69429088Smarkm if (NetTrace == stdout) 69529088Smarkm fprintf(NetTrace, "\r\n"); 69629088Smarkm else 69729088Smarkm fprintf(NetTrace, "\n"); 69829088Smarkm break; 69929088Smarkm 70029088Smarkm case SB: 70129088Smarkm fprintf(NetTrace, " SB "); 70229088Smarkm i++; 70329088Smarkm j = k = i; 70429088Smarkm while (j < length) { 70529088Smarkm if (pointer[j] == SE) { 70629088Smarkm if (j+1 == length) 70729088Smarkm break; 70829088Smarkm if (pointer[j+1] == SE) 70929088Smarkm j++; 71029088Smarkm else 71129088Smarkm break; 71229088Smarkm } 71329088Smarkm pointer[k++] = pointer[j++]; 71429088Smarkm } 71529088Smarkm printsub(0, &pointer[i], k - i); 71629088Smarkm if (i < length) { 71729088Smarkm fprintf(NetTrace, " SE"); 71829088Smarkm i = j; 71929088Smarkm } else 72029088Smarkm i = j - 1; 72129088Smarkm 72229088Smarkm if (NetTrace == stdout) 72329088Smarkm fprintf(NetTrace, "\r\n"); 72429088Smarkm else 72529088Smarkm fprintf(NetTrace, "\n"); 72629088Smarkm 72729088Smarkm break; 72829088Smarkm 72929088Smarkm default: 73029088Smarkm fprintf(NetTrace, " %d", pointer[i]); 73129088Smarkm break; 73229088Smarkm } 73329088Smarkm } 73429088Smarkm break; 73529088Smarkm } 73629088Smarkm break; 73729088Smarkm } 73829088Smarkm 73929088Smarkm case TELOPT_XDISPLOC: 74029088Smarkm fprintf(NetTrace, "X-DISPLAY-LOCATION "); 74129088Smarkm switch (pointer[1]) { 74229088Smarkm case TELQUAL_IS: 74329088Smarkm fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2); 74429088Smarkm break; 74529088Smarkm case TELQUAL_SEND: 74629088Smarkm fprintf(NetTrace, "SEND"); 74729088Smarkm break; 74829088Smarkm default: 74929088Smarkm fprintf(NetTrace, "- unknown qualifier %d (0x%x).", 75029088Smarkm pointer[1], pointer[1]); 75129088Smarkm } 75229088Smarkm break; 75329088Smarkm 75429088Smarkm case TELOPT_NEW_ENVIRON: 75529088Smarkm fprintf(NetTrace, "NEW-ENVIRON "); 75629088Smarkm#ifdef OLD_ENVIRON 75729088Smarkm goto env_common1; 75829088Smarkm case TELOPT_OLD_ENVIRON: 75929088Smarkm fprintf(NetTrace, "OLD-ENVIRON"); 76029088Smarkm env_common1: 76129088Smarkm#endif 76229088Smarkm switch (pointer[1]) { 76329088Smarkm case TELQUAL_IS: 76429088Smarkm fprintf(NetTrace, "IS "); 76529088Smarkm goto env_common; 76629088Smarkm case TELQUAL_SEND: 76729088Smarkm fprintf(NetTrace, "SEND "); 76829088Smarkm goto env_common; 76929088Smarkm case TELQUAL_INFO: 77029088Smarkm fprintf(NetTrace, "INFO "); 77129088Smarkm env_common: 77229088Smarkm { 77329088Smarkm register int noquote = 2; 77429088Smarkm#if defined(ENV_HACK) && defined(OLD_ENVIRON) 77529088Smarkm extern int old_env_var, old_env_value; 77629088Smarkm#endif 77729088Smarkm for (i = 2; i < length; i++ ) { 77829088Smarkm switch (pointer[i]) { 77929088Smarkm case NEW_ENV_VALUE: 78029088Smarkm#ifdef OLD_ENVIRON 78129088Smarkm /* case NEW_ENV_OVAR: */ 78229088Smarkm if (pointer[0] == TELOPT_OLD_ENVIRON) { 78329088Smarkm# ifdef ENV_HACK 78429088Smarkm if (old_env_var == OLD_ENV_VALUE) 78529088Smarkm fprintf(NetTrace, "\" (VALUE) " + noquote); 78629088Smarkm else 78729088Smarkm# endif 78829088Smarkm fprintf(NetTrace, "\" VAR " + noquote); 78929088Smarkm } else 79029088Smarkm#endif /* OLD_ENVIRON */ 79129088Smarkm fprintf(NetTrace, "\" VALUE " + noquote); 79229088Smarkm noquote = 2; 79329088Smarkm break; 79429088Smarkm 79529088Smarkm case NEW_ENV_VAR: 79629088Smarkm#ifdef OLD_ENVIRON 79729088Smarkm /* case OLD_ENV_VALUE: */ 79829088Smarkm if (pointer[0] == TELOPT_OLD_ENVIRON) { 79929088Smarkm# ifdef ENV_HACK 80029088Smarkm if (old_env_value == OLD_ENV_VAR) 80129088Smarkm fprintf(NetTrace, "\" (VAR) " + noquote); 80229088Smarkm else 80329088Smarkm# endif 80429088Smarkm fprintf(NetTrace, "\" VALUE " + noquote); 80529088Smarkm } else 80629088Smarkm#endif /* OLD_ENVIRON */ 80729088Smarkm fprintf(NetTrace, "\" VAR " + noquote); 80829088Smarkm noquote = 2; 80929088Smarkm break; 81029088Smarkm 81129088Smarkm case ENV_ESC: 81229088Smarkm fprintf(NetTrace, "\" ESC " + noquote); 81329088Smarkm noquote = 2; 81429088Smarkm break; 81529088Smarkm 81629088Smarkm case ENV_USERVAR: 81729088Smarkm fprintf(NetTrace, "\" USERVAR " + noquote); 81829088Smarkm noquote = 2; 81929088Smarkm break; 82029088Smarkm 82129088Smarkm default: 82229088Smarkm def_case: 82329088Smarkm if (isprint(pointer[i]) && pointer[i] != '"') { 82429088Smarkm if (noquote) { 82529088Smarkm putc('"', NetTrace); 82629088Smarkm noquote = 0; 82729088Smarkm } 82829088Smarkm putc(pointer[i], NetTrace); 82929088Smarkm } else { 83029088Smarkm fprintf(NetTrace, "\" %03o " + noquote, 83129088Smarkm pointer[i]); 83229088Smarkm noquote = 2; 83329088Smarkm } 83429088Smarkm break; 83529088Smarkm } 83629088Smarkm } 83729088Smarkm if (!noquote) 83829088Smarkm putc('"', NetTrace); 83929088Smarkm break; 84029088Smarkm } 84129088Smarkm } 84229088Smarkm break; 84329088Smarkm 84429088Smarkm default: 84529088Smarkm if (TELOPT_OK(pointer[0])) 84629088Smarkm fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0])); 84729088Smarkm else 84829088Smarkm fprintf(NetTrace, "%d (unknown)", pointer[0]); 84929088Smarkm for (i = 1; i < length; i++) 85029088Smarkm fprintf(NetTrace, " %d", pointer[i]); 85129088Smarkm break; 85229088Smarkm } 85329088Smarkm if (direction) { 85429088Smarkm if (NetTrace == stdout) 85529088Smarkm fprintf(NetTrace, "\r\n"); 85629088Smarkm else 85729088Smarkm fprintf(NetTrace, "\n"); 85829088Smarkm } 85929088Smarkm if (NetTrace == stdout) 86029088Smarkm fflush(NetTrace); 86129088Smarkm } 86229088Smarkm} 86329088Smarkm 86429088Smarkm/* EmptyTerminal - called to make sure that the terminal buffer is empty. 86529088Smarkm * Note that we consider the buffer to run all the 86629088Smarkm * way to the kernel (thus the select). 86729088Smarkm */ 86829088Smarkm 86929088Smarkm void 87029088SmarkmEmptyTerminal() 87129088Smarkm{ 87229088Smarkm#if defined(unix) 87329088Smarkm fd_set o; 87429088Smarkm 87529088Smarkm FD_ZERO(&o); 87629088Smarkm#endif /* defined(unix) */ 87729088Smarkm 87829088Smarkm if (TTYBYTES() == 0) { 87929088Smarkm#if defined(unix) 88029088Smarkm FD_SET(tout, &o); 88129088Smarkm (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 88229088Smarkm (struct timeval *) 0); /* wait for TTLOWAT */ 88329088Smarkm#endif /* defined(unix) */ 88429088Smarkm } else { 88529088Smarkm while (TTYBYTES()) { 88629088Smarkm (void) ttyflush(0); 88729088Smarkm#if defined(unix) 88829088Smarkm FD_SET(tout, &o); 88929088Smarkm (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 89029088Smarkm (struct timeval *) 0); /* wait for TTLOWAT */ 89129088Smarkm#endif /* defined(unix) */ 89229088Smarkm } 89329088Smarkm } 89429088Smarkm} 89529088Smarkm 89629088Smarkm void 89729088SmarkmSetForExit() 89829088Smarkm{ 89929088Smarkm setconnmode(0); 90029088Smarkm#if defined(TN3270) 90129088Smarkm if (In3270) { 90229088Smarkm Finish3270(); 90329088Smarkm } 90429088Smarkm#else /* defined(TN3270) */ 90529088Smarkm do { 90629088Smarkm (void)telrcv(); /* Process any incoming data */ 90729088Smarkm EmptyTerminal(); 90829088Smarkm } while (ring_full_count(&netiring)); /* While there is any */ 90929088Smarkm#endif /* defined(TN3270) */ 91029088Smarkm setcommandmode(); 91129088Smarkm fflush(stdout); 91229088Smarkm fflush(stderr); 91329088Smarkm#if defined(TN3270) 91429088Smarkm if (In3270) { 91529088Smarkm StopScreen(1); 91629088Smarkm } 91729088Smarkm#endif /* defined(TN3270) */ 91829088Smarkm setconnmode(0); 91929088Smarkm EmptyTerminal(); /* Flush the path to the tty */ 92029088Smarkm setcommandmode(); 92129088Smarkm} 92229088Smarkm 92329088Smarkm void 92429088SmarkmExit(returnCode) 92529088Smarkm int returnCode; 92629088Smarkm{ 92729088Smarkm SetForExit(); 92829088Smarkm exit(returnCode); 92929088Smarkm} 93029088Smarkm 93129088Smarkm void 93229088SmarkmExitString(string, returnCode) 93329088Smarkm char *string; 93429088Smarkm int returnCode; 93529088Smarkm{ 93629088Smarkm SetForExit(); 93729088Smarkm fwrite(string, 1, strlen(string), stderr); 93829088Smarkm exit(returnCode); 93929088Smarkm} 940