1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate */
5*7c478bd9Sstevel@tonic-gate
6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
7*7c478bd9Sstevel@tonic-gate
8*7c478bd9Sstevel@tonic-gate /*
9*7c478bd9Sstevel@tonic-gate * usr/src/cmd/cmd-inet/usr.bin/telnet/utilities.c
10*7c478bd9Sstevel@tonic-gate */
11*7c478bd9Sstevel@tonic-gate
12*7c478bd9Sstevel@tonic-gate /*
13*7c478bd9Sstevel@tonic-gate * Copyright (c) 1988, 1993
14*7c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved.
15*7c478bd9Sstevel@tonic-gate *
16*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
17*7c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions
18*7c478bd9Sstevel@tonic-gate * are met:
19*7c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
20*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
21*7c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
22*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
23*7c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
24*7c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
25*7c478bd9Sstevel@tonic-gate * must display the following acknowledgement:
26*7c478bd9Sstevel@tonic-gate * This product includes software developed by the University of
27*7c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors.
28*7c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors
29*7c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software
30*7c478bd9Sstevel@tonic-gate * without specific prior written permission.
31*7c478bd9Sstevel@tonic-gate *
32*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33*7c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34*7c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35*7c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36*7c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*7c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*7c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*7c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40*7c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41*7c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42*7c478bd9Sstevel@tonic-gate * SUCH DAMAGE.
43*7c478bd9Sstevel@tonic-gate */
44*7c478bd9Sstevel@tonic-gate
45*7c478bd9Sstevel@tonic-gate #ifndef lint
46*7c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/6/93";
47*7c478bd9Sstevel@tonic-gate #endif /* not lint */
48*7c478bd9Sstevel@tonic-gate
49*7c478bd9Sstevel@tonic-gate #define TELOPTS
50*7c478bd9Sstevel@tonic-gate #ifdef lint
51*7c478bd9Sstevel@tonic-gate static char *telcmds[] = {0};
52*7c478bd9Sstevel@tonic-gate static char *slc_names[] = {0};
53*7c478bd9Sstevel@tonic-gate static char *encrypt_names[] = {0};
54*7c478bd9Sstevel@tonic-gate static char *enctype_names[] = {0};
55*7c478bd9Sstevel@tonic-gate #else /* lint */
56*7c478bd9Sstevel@tonic-gate #define TELCMDS
57*7c478bd9Sstevel@tonic-gate #define SLC_NAMES
58*7c478bd9Sstevel@tonic-gate #endif /* lint */
59*7c478bd9Sstevel@tonic-gate #include <arpa/telnet.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
61*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
62*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
63*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
64*7c478bd9Sstevel@tonic-gate #include <errno.h>
65*7c478bd9Sstevel@tonic-gate
66*7c478bd9Sstevel@tonic-gate #include <ctype.h>
67*7c478bd9Sstevel@tonic-gate
68*7c478bd9Sstevel@tonic-gate #include "general.h"
69*7c478bd9Sstevel@tonic-gate
70*7c478bd9Sstevel@tonic-gate #include "ring.h"
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate #include "defines.h"
73*7c478bd9Sstevel@tonic-gate
74*7c478bd9Sstevel@tonic-gate #include "externs.h"
75*7c478bd9Sstevel@tonic-gate
76*7c478bd9Sstevel@tonic-gate FILE *NetTrace = 0; /* Not in bss, since needs to stay */
77*7c478bd9Sstevel@tonic-gate int prettydump;
78*7c478bd9Sstevel@tonic-gate
79*7c478bd9Sstevel@tonic-gate /*
80*7c478bd9Sstevel@tonic-gate * upcase()
81*7c478bd9Sstevel@tonic-gate *
82*7c478bd9Sstevel@tonic-gate * Upcase (in place) the argument.
83*7c478bd9Sstevel@tonic-gate */
84*7c478bd9Sstevel@tonic-gate
85*7c478bd9Sstevel@tonic-gate void
upcase(argument)86*7c478bd9Sstevel@tonic-gate upcase(argument)
87*7c478bd9Sstevel@tonic-gate register char *argument;
88*7c478bd9Sstevel@tonic-gate {
89*7c478bd9Sstevel@tonic-gate register int c;
90*7c478bd9Sstevel@tonic-gate
91*7c478bd9Sstevel@tonic-gate while ((c = *argument) != 0) {
92*7c478bd9Sstevel@tonic-gate if (islower(c)) {
93*7c478bd9Sstevel@tonic-gate *argument = toupper(c);
94*7c478bd9Sstevel@tonic-gate }
95*7c478bd9Sstevel@tonic-gate argument++;
96*7c478bd9Sstevel@tonic-gate }
97*7c478bd9Sstevel@tonic-gate }
98*7c478bd9Sstevel@tonic-gate
99*7c478bd9Sstevel@tonic-gate /*
100*7c478bd9Sstevel@tonic-gate * SetSockOpt()
101*7c478bd9Sstevel@tonic-gate *
102*7c478bd9Sstevel@tonic-gate * Compensate for differences in 4.2 and 4.3 systems.
103*7c478bd9Sstevel@tonic-gate */
104*7c478bd9Sstevel@tonic-gate
105*7c478bd9Sstevel@tonic-gate int
SetSockOpt(fd,level,option,yesno)106*7c478bd9Sstevel@tonic-gate SetSockOpt(fd, level, option, yesno)
107*7c478bd9Sstevel@tonic-gate int fd, level, option, yesno;
108*7c478bd9Sstevel@tonic-gate {
109*7c478bd9Sstevel@tonic-gate return (setsockopt(fd, level, option, &yesno, sizeof (yesno)));
110*7c478bd9Sstevel@tonic-gate }
111*7c478bd9Sstevel@tonic-gate
112*7c478bd9Sstevel@tonic-gate /*
113*7c478bd9Sstevel@tonic-gate * The following are routines used to print out debugging information.
114*7c478bd9Sstevel@tonic-gate */
115*7c478bd9Sstevel@tonic-gate
116*7c478bd9Sstevel@tonic-gate unsigned char NetTraceFile[MAXPATHLEN] = "(standard output)";
117*7c478bd9Sstevel@tonic-gate
118*7c478bd9Sstevel@tonic-gate void
SetNetTrace(file)119*7c478bd9Sstevel@tonic-gate SetNetTrace(file)
120*7c478bd9Sstevel@tonic-gate register char *file;
121*7c478bd9Sstevel@tonic-gate {
122*7c478bd9Sstevel@tonic-gate if (NetTrace && NetTrace != stdout)
123*7c478bd9Sstevel@tonic-gate (void) fclose(NetTrace);
124*7c478bd9Sstevel@tonic-gate if (file && (strcmp(file, "-") != 0)) {
125*7c478bd9Sstevel@tonic-gate NetTrace = fopen(file, "w");
126*7c478bd9Sstevel@tonic-gate if (NetTrace) {
127*7c478bd9Sstevel@tonic-gate (void) strcpy((char *)NetTraceFile, file);
128*7c478bd9Sstevel@tonic-gate return;
129*7c478bd9Sstevel@tonic-gate }
130*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Cannot open %s.\n", file);
131*7c478bd9Sstevel@tonic-gate }
132*7c478bd9Sstevel@tonic-gate NetTrace = stdout;
133*7c478bd9Sstevel@tonic-gate (void) strcpy((char *)NetTraceFile, "(standard output)");
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate
136*7c478bd9Sstevel@tonic-gate void
Dump(direction,buffer,length)137*7c478bd9Sstevel@tonic-gate Dump(direction, buffer, length)
138*7c478bd9Sstevel@tonic-gate char direction;
139*7c478bd9Sstevel@tonic-gate unsigned char *buffer;
140*7c478bd9Sstevel@tonic-gate int length;
141*7c478bd9Sstevel@tonic-gate {
142*7c478bd9Sstevel@tonic-gate #define BYTES_PER_LINE 32
143*7c478bd9Sstevel@tonic-gate #define min(x, y) ((x < y) ? x:y)
144*7c478bd9Sstevel@tonic-gate unsigned char *pThis;
145*7c478bd9Sstevel@tonic-gate int offset;
146*7c478bd9Sstevel@tonic-gate
147*7c478bd9Sstevel@tonic-gate offset = 0;
148*7c478bd9Sstevel@tonic-gate
149*7c478bd9Sstevel@tonic-gate while (length) {
150*7c478bd9Sstevel@tonic-gate /* print one line */
151*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%c 0x%x\t", direction, offset);
152*7c478bd9Sstevel@tonic-gate pThis = buffer;
153*7c478bd9Sstevel@tonic-gate if (prettydump) {
154*7c478bd9Sstevel@tonic-gate buffer = buffer + min(length, BYTES_PER_LINE/2);
155*7c478bd9Sstevel@tonic-gate while (pThis < buffer) {
156*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%c%.2x",
157*7c478bd9Sstevel@tonic-gate (((*pThis)&0xff) == 0xff) ? '*' : ' ',
158*7c478bd9Sstevel@tonic-gate (*pThis)&0xff);
159*7c478bd9Sstevel@tonic-gate pThis++;
160*7c478bd9Sstevel@tonic-gate }
161*7c478bd9Sstevel@tonic-gate length -= BYTES_PER_LINE/2;
162*7c478bd9Sstevel@tonic-gate offset += BYTES_PER_LINE/2;
163*7c478bd9Sstevel@tonic-gate } else {
164*7c478bd9Sstevel@tonic-gate buffer = buffer + min(length, BYTES_PER_LINE);
165*7c478bd9Sstevel@tonic-gate while (pThis < buffer) {
166*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%.2x", (*pThis)&0xff);
167*7c478bd9Sstevel@tonic-gate pThis++;
168*7c478bd9Sstevel@tonic-gate }
169*7c478bd9Sstevel@tonic-gate length -= BYTES_PER_LINE;
170*7c478bd9Sstevel@tonic-gate offset += BYTES_PER_LINE;
171*7c478bd9Sstevel@tonic-gate }
172*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout) {
173*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
174*7c478bd9Sstevel@tonic-gate } else {
175*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
176*7c478bd9Sstevel@tonic-gate }
177*7c478bd9Sstevel@tonic-gate if (length < 0) {
178*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
179*7c478bd9Sstevel@tonic-gate return;
180*7c478bd9Sstevel@tonic-gate }
181*7c478bd9Sstevel@tonic-gate /* find next unique line */
182*7c478bd9Sstevel@tonic-gate }
183*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
184*7c478bd9Sstevel@tonic-gate }
185*7c478bd9Sstevel@tonic-gate
186*7c478bd9Sstevel@tonic-gate
187*7c478bd9Sstevel@tonic-gate void
printoption(direction,cmd,option)188*7c478bd9Sstevel@tonic-gate printoption(direction, cmd, option)
189*7c478bd9Sstevel@tonic-gate char *direction;
190*7c478bd9Sstevel@tonic-gate int cmd, option;
191*7c478bd9Sstevel@tonic-gate {
192*7c478bd9Sstevel@tonic-gate if (!showoptions)
193*7c478bd9Sstevel@tonic-gate return;
194*7c478bd9Sstevel@tonic-gate if (cmd == IAC) {
195*7c478bd9Sstevel@tonic-gate if (TELCMD_OK(option))
196*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s IAC %s", direction,
197*7c478bd9Sstevel@tonic-gate TELCMD(option));
198*7c478bd9Sstevel@tonic-gate else
199*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s IAC %d", direction,
200*7c478bd9Sstevel@tonic-gate option);
201*7c478bd9Sstevel@tonic-gate } else {
202*7c478bd9Sstevel@tonic-gate register char *fmt;
203*7c478bd9Sstevel@tonic-gate fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
204*7c478bd9Sstevel@tonic-gate (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
205*7c478bd9Sstevel@tonic-gate if (fmt) {
206*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s %s ", direction, fmt);
207*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(option))
208*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", TELOPT(option));
209*7c478bd9Sstevel@tonic-gate else if (option == TELOPT_EXOPL)
210*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "EXOPL");
211*7c478bd9Sstevel@tonic-gate else
212*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d", option);
213*7c478bd9Sstevel@tonic-gate } else
214*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s %d %d", direction, cmd,
215*7c478bd9Sstevel@tonic-gate option);
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout) {
218*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
219*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
220*7c478bd9Sstevel@tonic-gate } else {
221*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
222*7c478bd9Sstevel@tonic-gate }
223*7c478bd9Sstevel@tonic-gate }
224*7c478bd9Sstevel@tonic-gate
225*7c478bd9Sstevel@tonic-gate void
optionstatus()226*7c478bd9Sstevel@tonic-gate optionstatus()
227*7c478bd9Sstevel@tonic-gate {
228*7c478bd9Sstevel@tonic-gate register int i;
229*7c478bd9Sstevel@tonic-gate extern char will_wont_resp[], do_dont_resp[];
230*7c478bd9Sstevel@tonic-gate
231*7c478bd9Sstevel@tonic-gate for (i = 0; i < SUBBUFSIZE; i++) {
232*7c478bd9Sstevel@tonic-gate if (do_dont_resp[i]) {
233*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
234*7c478bd9Sstevel@tonic-gate (void) printf("resp DO_DONT %s: %d\n",
235*7c478bd9Sstevel@tonic-gate TELOPT(i), do_dont_resp[i]);
236*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
237*7c478bd9Sstevel@tonic-gate (void) printf("resp DO_DONT %s: %d\n",
238*7c478bd9Sstevel@tonic-gate TELCMD(i), do_dont_resp[i]);
239*7c478bd9Sstevel@tonic-gate else
240*7c478bd9Sstevel@tonic-gate (void) printf("resp DO_DONT %d: %d\n", i,
241*7c478bd9Sstevel@tonic-gate do_dont_resp[i]);
242*7c478bd9Sstevel@tonic-gate if (my_want_state_is_do(i)) {
243*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
244*7c478bd9Sstevel@tonic-gate (void) printf("want DO %s\n",
245*7c478bd9Sstevel@tonic-gate TELOPT(i));
246*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
247*7c478bd9Sstevel@tonic-gate (void) printf("want DO %s\n",
248*7c478bd9Sstevel@tonic-gate TELCMD(i));
249*7c478bd9Sstevel@tonic-gate else
250*7c478bd9Sstevel@tonic-gate (void) printf("want DO %d\n", i);
251*7c478bd9Sstevel@tonic-gate } else {
252*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
253*7c478bd9Sstevel@tonic-gate (void) printf("want DONT %s\n",
254*7c478bd9Sstevel@tonic-gate TELOPT(i));
255*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
256*7c478bd9Sstevel@tonic-gate (void) printf("want DONT %s\n",
257*7c478bd9Sstevel@tonic-gate TELCMD(i));
258*7c478bd9Sstevel@tonic-gate else
259*7c478bd9Sstevel@tonic-gate (void) printf("want DONT %d\n", i);
260*7c478bd9Sstevel@tonic-gate }
261*7c478bd9Sstevel@tonic-gate } else {
262*7c478bd9Sstevel@tonic-gate if (my_state_is_do(i)) {
263*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
264*7c478bd9Sstevel@tonic-gate (void) printf(" DO %s\n",
265*7c478bd9Sstevel@tonic-gate TELOPT(i));
266*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
267*7c478bd9Sstevel@tonic-gate (void) printf(" DO %s\n",
268*7c478bd9Sstevel@tonic-gate TELCMD(i));
269*7c478bd9Sstevel@tonic-gate else
270*7c478bd9Sstevel@tonic-gate (void) printf(" DO %d\n", i);
271*7c478bd9Sstevel@tonic-gate }
272*7c478bd9Sstevel@tonic-gate }
273*7c478bd9Sstevel@tonic-gate if (will_wont_resp[i]) {
274*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
275*7c478bd9Sstevel@tonic-gate (void) printf("resp WILL_WONT %s: %d\n",
276*7c478bd9Sstevel@tonic-gate TELOPT(i), will_wont_resp[i]);
277*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
278*7c478bd9Sstevel@tonic-gate (void) printf("resp WILL_WONT %s: %d\n",
279*7c478bd9Sstevel@tonic-gate TELCMD(i), will_wont_resp[i]);
280*7c478bd9Sstevel@tonic-gate else
281*7c478bd9Sstevel@tonic-gate (void) printf("resp WILL_WONT %d: %d\n",
282*7c478bd9Sstevel@tonic-gate i, will_wont_resp[i]);
283*7c478bd9Sstevel@tonic-gate if (my_want_state_is_will(i)) {
284*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
285*7c478bd9Sstevel@tonic-gate (void) printf("want WILL %s\n",
286*7c478bd9Sstevel@tonic-gate TELOPT(i));
287*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
288*7c478bd9Sstevel@tonic-gate (void) printf("want WILL %s\n",
289*7c478bd9Sstevel@tonic-gate TELCMD(i));
290*7c478bd9Sstevel@tonic-gate else
291*7c478bd9Sstevel@tonic-gate (void) printf("want WILL %d\n", i);
292*7c478bd9Sstevel@tonic-gate } else {
293*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
294*7c478bd9Sstevel@tonic-gate (void) printf("want WONT %s\n",
295*7c478bd9Sstevel@tonic-gate TELOPT(i));
296*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
297*7c478bd9Sstevel@tonic-gate (void) printf("want WONT %s\n",
298*7c478bd9Sstevel@tonic-gate TELCMD(i));
299*7c478bd9Sstevel@tonic-gate else
300*7c478bd9Sstevel@tonic-gate (void) printf("want WONT %d\n", i);
301*7c478bd9Sstevel@tonic-gate }
302*7c478bd9Sstevel@tonic-gate } else {
303*7c478bd9Sstevel@tonic-gate if (my_state_is_will(i)) {
304*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
305*7c478bd9Sstevel@tonic-gate (void) printf(" WILL %s\n",
306*7c478bd9Sstevel@tonic-gate TELOPT(i));
307*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
308*7c478bd9Sstevel@tonic-gate (void) printf(" WILL %s\n",
309*7c478bd9Sstevel@tonic-gate TELCMD(i));
310*7c478bd9Sstevel@tonic-gate else
311*7c478bd9Sstevel@tonic-gate (void) printf(" WILL %d\n", i);
312*7c478bd9Sstevel@tonic-gate }
313*7c478bd9Sstevel@tonic-gate }
314*7c478bd9Sstevel@tonic-gate }
315*7c478bd9Sstevel@tonic-gate
316*7c478bd9Sstevel@tonic-gate }
317*7c478bd9Sstevel@tonic-gate
318*7c478bd9Sstevel@tonic-gate void
printsub(direction,pointer,length)319*7c478bd9Sstevel@tonic-gate printsub(direction, pointer, length)
320*7c478bd9Sstevel@tonic-gate char direction; /* '<' or '>' */
321*7c478bd9Sstevel@tonic-gate unsigned char *pointer; /* where suboption data sits */
322*7c478bd9Sstevel@tonic-gate int length; /* length of suboption data */
323*7c478bd9Sstevel@tonic-gate {
324*7c478bd9Sstevel@tonic-gate register int i;
325*7c478bd9Sstevel@tonic-gate char buf[512];
326*7c478bd9Sstevel@tonic-gate extern int want_status_response;
327*7c478bd9Sstevel@tonic-gate
328*7c478bd9Sstevel@tonic-gate if (showoptions || direction == 0 ||
329*7c478bd9Sstevel@tonic-gate (want_status_response && (pointer[0] == TELOPT_STATUS))) {
330*7c478bd9Sstevel@tonic-gate if (direction) {
331*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s IAC SB ",
332*7c478bd9Sstevel@tonic-gate (direction == '<')? "RCVD":"SENT");
333*7c478bd9Sstevel@tonic-gate if (length >= 3) {
334*7c478bd9Sstevel@tonic-gate register int j;
335*7c478bd9Sstevel@tonic-gate
336*7c478bd9Sstevel@tonic-gate i = pointer[length-2];
337*7c478bd9Sstevel@tonic-gate j = pointer[length-1];
338*7c478bd9Sstevel@tonic-gate
339*7c478bd9Sstevel@tonic-gate if (i != IAC || j != SE) {
340*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
341*7c478bd9Sstevel@tonic-gate "(terminated by ");
342*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(i))
343*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
344*7c478bd9Sstevel@tonic-gate TELOPT(i));
345*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(i))
346*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
347*7c478bd9Sstevel@tonic-gate TELCMD(i));
348*7c478bd9Sstevel@tonic-gate else
349*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
350*7c478bd9Sstevel@tonic-gate i);
351*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(j))
352*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s",
353*7c478bd9Sstevel@tonic-gate TELOPT(j));
354*7c478bd9Sstevel@tonic-gate else if (TELCMD_OK(j))
355*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s",
356*7c478bd9Sstevel@tonic-gate TELCMD(j));
357*7c478bd9Sstevel@tonic-gate else
358*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d",
359*7c478bd9Sstevel@tonic-gate j);
360*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
361*7c478bd9Sstevel@tonic-gate ", not IAC SE!) ");
362*7c478bd9Sstevel@tonic-gate }
363*7c478bd9Sstevel@tonic-gate }
364*7c478bd9Sstevel@tonic-gate length -= 2;
365*7c478bd9Sstevel@tonic-gate }
366*7c478bd9Sstevel@tonic-gate if (length < 1) {
367*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "(Empty suboption??\?)");
368*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
369*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
370*7c478bd9Sstevel@tonic-gate return;
371*7c478bd9Sstevel@tonic-gate }
372*7c478bd9Sstevel@tonic-gate switch (pointer[0]) {
373*7c478bd9Sstevel@tonic-gate case TELOPT_TTYPE:
374*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "TERMINAL-TYPE ");
375*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
376*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
377*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "IS \"%.*s\"",
378*7c478bd9Sstevel@tonic-gate length-2,
379*7c478bd9Sstevel@tonic-gate (char *)pointer+2);
380*7c478bd9Sstevel@tonic-gate break;
381*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
382*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SEND");
383*7c478bd9Sstevel@tonic-gate break;
384*7c478bd9Sstevel@tonic-gate default:
385*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
386*7c478bd9Sstevel@tonic-gate "- unknown qualifier %d (0x%x).",
387*7c478bd9Sstevel@tonic-gate pointer[1], pointer[1]);
388*7c478bd9Sstevel@tonic-gate }
389*7c478bd9Sstevel@tonic-gate break;
390*7c478bd9Sstevel@tonic-gate case TELOPT_TSPEED:
391*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "TERMINAL-SPEED");
392*7c478bd9Sstevel@tonic-gate if (length < 2) {
393*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
394*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
395*7c478bd9Sstevel@tonic-gate break;
396*7c478bd9Sstevel@tonic-gate }
397*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
398*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
399*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " IS ");
400*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%.*s", length-2,
401*7c478bd9Sstevel@tonic-gate (char *)pointer+2);
402*7c478bd9Sstevel@tonic-gate break;
403*7c478bd9Sstevel@tonic-gate default:
404*7c478bd9Sstevel@tonic-gate if (pointer[1] == 1)
405*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SEND");
406*7c478bd9Sstevel@tonic-gate else
407*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
408*7c478bd9Sstevel@tonic-gate " %d (unknown)", pointer[1]);
409*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
410*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
411*7c478bd9Sstevel@tonic-gate pointer[i]);
412*7c478bd9Sstevel@tonic-gate break;
413*7c478bd9Sstevel@tonic-gate }
414*7c478bd9Sstevel@tonic-gate break;
415*7c478bd9Sstevel@tonic-gate
416*7c478bd9Sstevel@tonic-gate case TELOPT_LFLOW:
417*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
418*7c478bd9Sstevel@tonic-gate if (length < 2) {
419*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
420*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
421*7c478bd9Sstevel@tonic-gate break;
422*7c478bd9Sstevel@tonic-gate }
423*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
424*7c478bd9Sstevel@tonic-gate case LFLOW_OFF:
425*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " OFF");
426*7c478bd9Sstevel@tonic-gate break;
427*7c478bd9Sstevel@tonic-gate case LFLOW_ON:
428*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ON");
429*7c478bd9Sstevel@tonic-gate break;
430*7c478bd9Sstevel@tonic-gate case LFLOW_RESTART_ANY:
431*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " RESTART-ANY");
432*7c478bd9Sstevel@tonic-gate break;
433*7c478bd9Sstevel@tonic-gate case LFLOW_RESTART_XON:
434*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " RESTART-XON");
435*7c478bd9Sstevel@tonic-gate break;
436*7c478bd9Sstevel@tonic-gate default:
437*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d (unknown)",
438*7c478bd9Sstevel@tonic-gate pointer[1]);
439*7c478bd9Sstevel@tonic-gate }
440*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
441*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
442*7c478bd9Sstevel@tonic-gate pointer[i]);
443*7c478bd9Sstevel@tonic-gate break;
444*7c478bd9Sstevel@tonic-gate
445*7c478bd9Sstevel@tonic-gate case TELOPT_NAWS:
446*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "NAWS");
447*7c478bd9Sstevel@tonic-gate if (length < 2) {
448*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
449*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
450*7c478bd9Sstevel@tonic-gate break;
451*7c478bd9Sstevel@tonic-gate }
452*7c478bd9Sstevel@tonic-gate if (length == 2) {
453*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[1]);
454*7c478bd9Sstevel@tonic-gate break;
455*7c478bd9Sstevel@tonic-gate }
456*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d %d (%d)",
457*7c478bd9Sstevel@tonic-gate pointer[1], pointer[2],
458*7c478bd9Sstevel@tonic-gate (int)((((unsigned int)pointer[1])<<8)|
459*7c478bd9Sstevel@tonic-gate ((unsigned int)pointer[2])));
460*7c478bd9Sstevel@tonic-gate if (length == 4) {
461*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[3]);
462*7c478bd9Sstevel@tonic-gate break;
463*7c478bd9Sstevel@tonic-gate }
464*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d %d (%d)",
465*7c478bd9Sstevel@tonic-gate pointer[3], pointer[4],
466*7c478bd9Sstevel@tonic-gate (int)((((unsigned int)pointer[3])<<8)|
467*7c478bd9Sstevel@tonic-gate ((unsigned int)pointer[4])));
468*7c478bd9Sstevel@tonic-gate for (i = 5; i < length; i++)
469*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[i]);
470*7c478bd9Sstevel@tonic-gate break;
471*7c478bd9Sstevel@tonic-gate
472*7c478bd9Sstevel@tonic-gate case TELOPT_AUTHENTICATION:
473*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "AUTHENTICATION");
474*7c478bd9Sstevel@tonic-gate if (length < 2) {
475*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
476*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
477*7c478bd9Sstevel@tonic-gate break;
478*7c478bd9Sstevel@tonic-gate }
479*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
480*7c478bd9Sstevel@tonic-gate case TELQUAL_REPLY:
481*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
482*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %s ",
483*7c478bd9Sstevel@tonic-gate (pointer[1] == TELQUAL_IS) ?
484*7c478bd9Sstevel@tonic-gate "IS" : "REPLY");
485*7c478bd9Sstevel@tonic-gate if (AUTHTYPE_NAME_OK(pointer[2]))
486*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
487*7c478bd9Sstevel@tonic-gate AUTHTYPE_NAME(pointer[2]));
488*7c478bd9Sstevel@tonic-gate else
489*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
490*7c478bd9Sstevel@tonic-gate pointer[2]);
491*7c478bd9Sstevel@tonic-gate if (length < 3) {
492*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
493*7c478bd9Sstevel@tonic-gate "(partial suboption??\?)");
494*7c478bd9Sstevel@tonic-gate break;
495*7c478bd9Sstevel@tonic-gate }
496*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s|%s",
497*7c478bd9Sstevel@tonic-gate ((pointer[3] & AUTH_WHO_MASK) ==
498*7c478bd9Sstevel@tonic-gate AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER",
499*7c478bd9Sstevel@tonic-gate ((pointer[3] & AUTH_HOW_MASK) ==
500*7c478bd9Sstevel@tonic-gate AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY");
501*7c478bd9Sstevel@tonic-gate
502*7c478bd9Sstevel@tonic-gate auth_printsub(&pointer[1], length - 1,
503*7c478bd9Sstevel@tonic-gate (uchar_t *)buf, sizeof (buf));
504*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", buf);
505*7c478bd9Sstevel@tonic-gate break;
506*7c478bd9Sstevel@tonic-gate
507*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
508*7c478bd9Sstevel@tonic-gate i = 2;
509*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SEND ");
510*7c478bd9Sstevel@tonic-gate while (i < length) {
511*7c478bd9Sstevel@tonic-gate if (AUTHTYPE_NAME_OK(pointer[i]))
512*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
513*7c478bd9Sstevel@tonic-gate AUTHTYPE_NAME(pointer[i]));
514*7c478bd9Sstevel@tonic-gate else
515*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
516*7c478bd9Sstevel@tonic-gate pointer[i]);
517*7c478bd9Sstevel@tonic-gate if (++i >= length) {
518*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
519*7c478bd9Sstevel@tonic-gate "(partial "
520*7c478bd9Sstevel@tonic-gate "suboption??\?)");
521*7c478bd9Sstevel@tonic-gate break;
522*7c478bd9Sstevel@tonic-gate }
523*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s|%s ",
524*7c478bd9Sstevel@tonic-gate ((pointer[i] & AUTH_WHO_MASK) ==
525*7c478bd9Sstevel@tonic-gate AUTH_WHO_CLIENT) ?
526*7c478bd9Sstevel@tonic-gate "CLIENT" : "SERVER",
527*7c478bd9Sstevel@tonic-gate ((pointer[i] & AUTH_HOW_MASK) ==
528*7c478bd9Sstevel@tonic-gate AUTH_HOW_MUTUAL) ?
529*7c478bd9Sstevel@tonic-gate "MUTUAL" : "ONE-WAY");
530*7c478bd9Sstevel@tonic-gate ++i;
531*7c478bd9Sstevel@tonic-gate }
532*7c478bd9Sstevel@tonic-gate break;
533*7c478bd9Sstevel@tonic-gate
534*7c478bd9Sstevel@tonic-gate case TELQUAL_NAME:
535*7c478bd9Sstevel@tonic-gate i = 2;
536*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " NAME \"");
537*7c478bd9Sstevel@tonic-gate while (i < length)
538*7c478bd9Sstevel@tonic-gate (void) putc(pointer[i++], NetTrace);
539*7c478bd9Sstevel@tonic-gate (void) putc('"', NetTrace);
540*7c478bd9Sstevel@tonic-gate break;
541*7c478bd9Sstevel@tonic-gate
542*7c478bd9Sstevel@tonic-gate default:
543*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
544*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?", pointer[i]);
545*7c478bd9Sstevel@tonic-gate break;
546*7c478bd9Sstevel@tonic-gate }
547*7c478bd9Sstevel@tonic-gate break;
548*7c478bd9Sstevel@tonic-gate
549*7c478bd9Sstevel@tonic-gate case TELOPT_ENCRYPT:
550*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "ENCRYPT");
551*7c478bd9Sstevel@tonic-gate if (length < 2) {
552*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
553*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
554*7c478bd9Sstevel@tonic-gate break;
555*7c478bd9Sstevel@tonic-gate }
556*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
557*7c478bd9Sstevel@tonic-gate case ENCRYPT_START:
558*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " START");
559*7c478bd9Sstevel@tonic-gate break;
560*7c478bd9Sstevel@tonic-gate
561*7c478bd9Sstevel@tonic-gate case ENCRYPT_END:
562*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " END");
563*7c478bd9Sstevel@tonic-gate break;
564*7c478bd9Sstevel@tonic-gate
565*7c478bd9Sstevel@tonic-gate case ENCRYPT_REQSTART:
566*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " REQUEST-START");
567*7c478bd9Sstevel@tonic-gate break;
568*7c478bd9Sstevel@tonic-gate
569*7c478bd9Sstevel@tonic-gate case ENCRYPT_REQEND:
570*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " REQUEST-END");
571*7c478bd9Sstevel@tonic-gate break;
572*7c478bd9Sstevel@tonic-gate
573*7c478bd9Sstevel@tonic-gate case ENCRYPT_IS:
574*7c478bd9Sstevel@tonic-gate case ENCRYPT_REPLY:
575*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %s ",
576*7c478bd9Sstevel@tonic-gate (pointer[1] == ENCRYPT_IS) ?
577*7c478bd9Sstevel@tonic-gate "IS" : "REPLY");
578*7c478bd9Sstevel@tonic-gate if (length < 3) {
579*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " (partial "
580*7c478bd9Sstevel@tonic-gate "suboption??\?)");
581*7c478bd9Sstevel@tonic-gate break;
582*7c478bd9Sstevel@tonic-gate }
583*7c478bd9Sstevel@tonic-gate if (ENCTYPE_NAME_OK(pointer[2]))
584*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
585*7c478bd9Sstevel@tonic-gate ENCTYPE_NAME(pointer[2]));
586*7c478bd9Sstevel@tonic-gate else
587*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
588*7c478bd9Sstevel@tonic-gate " %d (unknown)", pointer[2]);
589*7c478bd9Sstevel@tonic-gate
590*7c478bd9Sstevel@tonic-gate encrypt_printsub(&pointer[1], length - 1,
591*7c478bd9Sstevel@tonic-gate (uchar_t *)buf, sizeof (buf));
592*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", buf);
593*7c478bd9Sstevel@tonic-gate break;
594*7c478bd9Sstevel@tonic-gate
595*7c478bd9Sstevel@tonic-gate case ENCRYPT_SUPPORT:
596*7c478bd9Sstevel@tonic-gate i = 2;
597*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SUPPORT ");
598*7c478bd9Sstevel@tonic-gate while (i < length) {
599*7c478bd9Sstevel@tonic-gate if (ENCTYPE_NAME_OK(pointer[i]))
600*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s ",
601*7c478bd9Sstevel@tonic-gate ENCTYPE_NAME(pointer[i]));
602*7c478bd9Sstevel@tonic-gate else
603*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d ",
604*7c478bd9Sstevel@tonic-gate pointer[i]);
605*7c478bd9Sstevel@tonic-gate i++;
606*7c478bd9Sstevel@tonic-gate }
607*7c478bd9Sstevel@tonic-gate break;
608*7c478bd9Sstevel@tonic-gate
609*7c478bd9Sstevel@tonic-gate case ENCRYPT_ENC_KEYID:
610*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ENC_KEYID ");
611*7c478bd9Sstevel@tonic-gate goto encommon;
612*7c478bd9Sstevel@tonic-gate
613*7c478bd9Sstevel@tonic-gate case ENCRYPT_DEC_KEYID:
614*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " DEC_KEYID ");
615*7c478bd9Sstevel@tonic-gate goto encommon;
616*7c478bd9Sstevel@tonic-gate
617*7c478bd9Sstevel@tonic-gate default:
618*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d (unknown)",
619*7c478bd9Sstevel@tonic-gate pointer[1]);
620*7c478bd9Sstevel@tonic-gate encommon:
621*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
622*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d",
623*7c478bd9Sstevel@tonic-gate pointer[i]);
624*7c478bd9Sstevel@tonic-gate break;
625*7c478bd9Sstevel@tonic-gate }
626*7c478bd9Sstevel@tonic-gate break;
627*7c478bd9Sstevel@tonic-gate
628*7c478bd9Sstevel@tonic-gate case TELOPT_LINEMODE:
629*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "LINEMODE ");
630*7c478bd9Sstevel@tonic-gate if (length < 2) {
631*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
632*7c478bd9Sstevel@tonic-gate " (empty suboption??\?)");
633*7c478bd9Sstevel@tonic-gate break;
634*7c478bd9Sstevel@tonic-gate }
635*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
636*7c478bd9Sstevel@tonic-gate case WILL:
637*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "WILL ");
638*7c478bd9Sstevel@tonic-gate goto common;
639*7c478bd9Sstevel@tonic-gate case WONT:
640*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "WONT ");
641*7c478bd9Sstevel@tonic-gate goto common;
642*7c478bd9Sstevel@tonic-gate case DO:
643*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "DO ");
644*7c478bd9Sstevel@tonic-gate goto common;
645*7c478bd9Sstevel@tonic-gate case DONT:
646*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "DONT ");
647*7c478bd9Sstevel@tonic-gate common:
648*7c478bd9Sstevel@tonic-gate if (length < 3) {
649*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
650*7c478bd9Sstevel@tonic-gate "(no option??\?)");
651*7c478bd9Sstevel@tonic-gate break;
652*7c478bd9Sstevel@tonic-gate }
653*7c478bd9Sstevel@tonic-gate switch (pointer[2]) {
654*7c478bd9Sstevel@tonic-gate case LM_FORWARDMASK:
655*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
656*7c478bd9Sstevel@tonic-gate "Forward Mask");
657*7c478bd9Sstevel@tonic-gate for (i = 3; i < length; i++)
658*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %x",
659*7c478bd9Sstevel@tonic-gate pointer[i]);
660*7c478bd9Sstevel@tonic-gate break;
661*7c478bd9Sstevel@tonic-gate default:
662*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d (unknown)",
663*7c478bd9Sstevel@tonic-gate pointer[2]);
664*7c478bd9Sstevel@tonic-gate for (i = 3; i < length; i++)
665*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
666*7c478bd9Sstevel@tonic-gate " %d", pointer[i]);
667*7c478bd9Sstevel@tonic-gate break;
668*7c478bd9Sstevel@tonic-gate }
669*7c478bd9Sstevel@tonic-gate break;
670*7c478bd9Sstevel@tonic-gate
671*7c478bd9Sstevel@tonic-gate case LM_SLC:
672*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SLC");
673*7c478bd9Sstevel@tonic-gate for (i = 2; i < length - 2; i += 3) {
674*7c478bd9Sstevel@tonic-gate if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
675*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %s",
676*7c478bd9Sstevel@tonic-gate SLC_NAME(pointer[
677*7c478bd9Sstevel@tonic-gate i+SLC_FUNC]));
678*7c478bd9Sstevel@tonic-gate else
679*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d",
680*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FUNC]);
681*7c478bd9Sstevel@tonic-gate switch (pointer[i+SLC_FLAGS] &
682*7c478bd9Sstevel@tonic-gate SLC_LEVELBITS) {
683*7c478bd9Sstevel@tonic-gate case SLC_NOSUPPORT:
684*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
685*7c478bd9Sstevel@tonic-gate " NOSUPPORT");
686*7c478bd9Sstevel@tonic-gate break;
687*7c478bd9Sstevel@tonic-gate case SLC_CANTCHANGE:
688*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
689*7c478bd9Sstevel@tonic-gate " CANTCHANGE");
690*7c478bd9Sstevel@tonic-gate break;
691*7c478bd9Sstevel@tonic-gate case SLC_VARIABLE:
692*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
693*7c478bd9Sstevel@tonic-gate " VARIABLE");
694*7c478bd9Sstevel@tonic-gate break;
695*7c478bd9Sstevel@tonic-gate case SLC_DEFAULT:
696*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
697*7c478bd9Sstevel@tonic-gate " DEFAULT");
698*7c478bd9Sstevel@tonic-gate break;
699*7c478bd9Sstevel@tonic-gate }
700*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s%s%s",
701*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]&SLC_ACK ?
702*7c478bd9Sstevel@tonic-gate "|ACK" : "",
703*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]&SLC_FLUSHIN ?
704*7c478bd9Sstevel@tonic-gate "|FLUSHIN" : "",
705*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ?
706*7c478bd9Sstevel@tonic-gate "|FLUSHOUT" : "");
707*7c478bd9Sstevel@tonic-gate if (pointer[i+SLC_FLAGS] &
708*7c478bd9Sstevel@tonic-gate ~(SLC_ACK|SLC_FLUSHIN|
709*7c478bd9Sstevel@tonic-gate SLC_FLUSHOUT| SLC_LEVELBITS))
710*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "(0x%x)",
711*7c478bd9Sstevel@tonic-gate pointer[i+SLC_FLAGS]);
712*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d;",
713*7c478bd9Sstevel@tonic-gate pointer[i+SLC_VALUE]);
714*7c478bd9Sstevel@tonic-gate if ((pointer[i+SLC_VALUE] == IAC) &&
715*7c478bd9Sstevel@tonic-gate (pointer[i+SLC_VALUE+1] == IAC))
716*7c478bd9Sstevel@tonic-gate i++;
717*7c478bd9Sstevel@tonic-gate }
718*7c478bd9Sstevel@tonic-gate for (; i < length; i++)
719*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
720*7c478bd9Sstevel@tonic-gate pointer[i]);
721*7c478bd9Sstevel@tonic-gate break;
722*7c478bd9Sstevel@tonic-gate
723*7c478bd9Sstevel@tonic-gate case LM_MODE:
724*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "MODE ");
725*7c478bd9Sstevel@tonic-gate if (length < 3) {
726*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
727*7c478bd9Sstevel@tonic-gate "(no mode??\?)");
728*7c478bd9Sstevel@tonic-gate break;
729*7c478bd9Sstevel@tonic-gate }
730*7c478bd9Sstevel@tonic-gate {
731*7c478bd9Sstevel@tonic-gate char tbuf[64];
732*7c478bd9Sstevel@tonic-gate (void) sprintf(tbuf, "%s%s%s%s%s",
733*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_EDIT ? "|EDIT" : "",
734*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_TRAPSIG ?
735*7c478bd9Sstevel@tonic-gate "|TRAPSIG" : "",
736*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_SOFT_TAB ?
737*7c478bd9Sstevel@tonic-gate "|SOFT_TAB" : "",
738*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_LIT_ECHO ?
739*7c478bd9Sstevel@tonic-gate "|LIT_ECHO" : "",
740*7c478bd9Sstevel@tonic-gate pointer[2]&MODE_ACK ? "|ACK" : "");
741*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s", tbuf[1] ?
742*7c478bd9Sstevel@tonic-gate &tbuf[1] : "0");
743*7c478bd9Sstevel@tonic-gate }
744*7c478bd9Sstevel@tonic-gate if (pointer[2]&~(MODE_MASK))
745*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " (0x%x)",
746*7c478bd9Sstevel@tonic-gate pointer[2]);
747*7c478bd9Sstevel@tonic-gate for (i = 3; i < length; i++)
748*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?0x%x?",
749*7c478bd9Sstevel@tonic-gate pointer[i]);
750*7c478bd9Sstevel@tonic-gate break;
751*7c478bd9Sstevel@tonic-gate default:
752*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d (unknown)",
753*7c478bd9Sstevel@tonic-gate pointer[1]);
754*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
755*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d",
756*7c478bd9Sstevel@tonic-gate pointer[i]);
757*7c478bd9Sstevel@tonic-gate }
758*7c478bd9Sstevel@tonic-gate break;
759*7c478bd9Sstevel@tonic-gate
760*7c478bd9Sstevel@tonic-gate case TELOPT_STATUS: {
761*7c478bd9Sstevel@tonic-gate register char *cp;
762*7c478bd9Sstevel@tonic-gate register int j, k;
763*7c478bd9Sstevel@tonic-gate
764*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "STATUS");
765*7c478bd9Sstevel@tonic-gate
766*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
767*7c478bd9Sstevel@tonic-gate default:
768*7c478bd9Sstevel@tonic-gate if (pointer[1] == TELQUAL_SEND)
769*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
770*7c478bd9Sstevel@tonic-gate " SEND");
771*7c478bd9Sstevel@tonic-gate else
772*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
773*7c478bd9Sstevel@tonic-gate " %d (unknown)",
774*7c478bd9Sstevel@tonic-gate pointer[1]);
775*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++)
776*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " ?%d?",
777*7c478bd9Sstevel@tonic-gate pointer[i]);
778*7c478bd9Sstevel@tonic-gate break;
779*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
780*7c478bd9Sstevel@tonic-gate if (--want_status_response < 0)
781*7c478bd9Sstevel@tonic-gate want_status_response = 0;
782*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
783*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
784*7c478bd9Sstevel@tonic-gate " IS\r\n");
785*7c478bd9Sstevel@tonic-gate else
786*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
787*7c478bd9Sstevel@tonic-gate " IS\n");
788*7c478bd9Sstevel@tonic-gate
789*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++) {
790*7c478bd9Sstevel@tonic-gate switch (pointer[i]) {
791*7c478bd9Sstevel@tonic-gate case DO:
792*7c478bd9Sstevel@tonic-gate cp = "DO";
793*7c478bd9Sstevel@tonic-gate goto common2;
794*7c478bd9Sstevel@tonic-gate case DONT:
795*7c478bd9Sstevel@tonic-gate cp = "DONT";
796*7c478bd9Sstevel@tonic-gate goto common2;
797*7c478bd9Sstevel@tonic-gate case WILL:
798*7c478bd9Sstevel@tonic-gate cp = "WILL";
799*7c478bd9Sstevel@tonic-gate goto common2;
800*7c478bd9Sstevel@tonic-gate case WONT:
801*7c478bd9Sstevel@tonic-gate cp = "WONT";
802*7c478bd9Sstevel@tonic-gate goto common2;
803*7c478bd9Sstevel@tonic-gate common2:
804*7c478bd9Sstevel@tonic-gate i++;
805*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(
806*7c478bd9Sstevel@tonic-gate (int)pointer[i]))
807*7c478bd9Sstevel@tonic-gate (void) fprintf(
808*7c478bd9Sstevel@tonic-gate NetTrace,
809*7c478bd9Sstevel@tonic-gate " %s %s",
810*7c478bd9Sstevel@tonic-gate cp,
811*7c478bd9Sstevel@tonic-gate TELOPT(
812*7c478bd9Sstevel@tonic-gate pointer[
813*7c478bd9Sstevel@tonic-gate i]));
814*7c478bd9Sstevel@tonic-gate else
815*7c478bd9Sstevel@tonic-gate (void) fprintf(
816*7c478bd9Sstevel@tonic-gate NetTrace,
817*7c478bd9Sstevel@tonic-gate " %s %d",
818*7c478bd9Sstevel@tonic-gate cp,
819*7c478bd9Sstevel@tonic-gate pointer[i]);
820*7c478bd9Sstevel@tonic-gate
821*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
822*7c478bd9Sstevel@tonic-gate (void) fprintf(
823*7c478bd9Sstevel@tonic-gate NetTrace,
824*7c478bd9Sstevel@tonic-gate "\r\n");
825*7c478bd9Sstevel@tonic-gate else
826*7c478bd9Sstevel@tonic-gate (void) fprintf(
827*7c478bd9Sstevel@tonic-gate NetTrace,
828*7c478bd9Sstevel@tonic-gate "\n");
829*7c478bd9Sstevel@tonic-gate break;
830*7c478bd9Sstevel@tonic-gate
831*7c478bd9Sstevel@tonic-gate case SB:
832*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
833*7c478bd9Sstevel@tonic-gate " SB ");
834*7c478bd9Sstevel@tonic-gate i++;
835*7c478bd9Sstevel@tonic-gate j = k = i;
836*7c478bd9Sstevel@tonic-gate while (j < length) {
837*7c478bd9Sstevel@tonic-gate if (pointer[j] == SE) {
838*7c478bd9Sstevel@tonic-gate if (j+1 == length)
839*7c478bd9Sstevel@tonic-gate break;
840*7c478bd9Sstevel@tonic-gate if (pointer[j+1] == SE)
841*7c478bd9Sstevel@tonic-gate j++;
842*7c478bd9Sstevel@tonic-gate else
843*7c478bd9Sstevel@tonic-gate break;
844*7c478bd9Sstevel@tonic-gate }
845*7c478bd9Sstevel@tonic-gate pointer[k++] = pointer[j++];
846*7c478bd9Sstevel@tonic-gate }
847*7c478bd9Sstevel@tonic-gate printsub(0,
848*7c478bd9Sstevel@tonic-gate &pointer[i], k - i);
849*7c478bd9Sstevel@tonic-gate if (i < length) {
850*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " SE");
851*7c478bd9Sstevel@tonic-gate i = j;
852*7c478bd9Sstevel@tonic-gate } else
853*7c478bd9Sstevel@tonic-gate i = j - 1;
854*7c478bd9Sstevel@tonic-gate
855*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
856*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
857*7c478bd9Sstevel@tonic-gate else
858*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
859*7c478bd9Sstevel@tonic-gate
860*7c478bd9Sstevel@tonic-gate break;
861*7c478bd9Sstevel@tonic-gate
862*7c478bd9Sstevel@tonic-gate default:
863*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
864*7c478bd9Sstevel@tonic-gate " %d", pointer[i]);
865*7c478bd9Sstevel@tonic-gate break;
866*7c478bd9Sstevel@tonic-gate }
867*7c478bd9Sstevel@tonic-gate }
868*7c478bd9Sstevel@tonic-gate break;
869*7c478bd9Sstevel@tonic-gate }
870*7c478bd9Sstevel@tonic-gate break;
871*7c478bd9Sstevel@tonic-gate }
872*7c478bd9Sstevel@tonic-gate
873*7c478bd9Sstevel@tonic-gate case TELOPT_XDISPLOC:
874*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "X-DISPLAY-LOCATION ");
875*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
876*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
877*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "IS \"%.*s\"",
878*7c478bd9Sstevel@tonic-gate length-2, (char *)pointer+2);
879*7c478bd9Sstevel@tonic-gate break;
880*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
881*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SEND");
882*7c478bd9Sstevel@tonic-gate break;
883*7c478bd9Sstevel@tonic-gate default:
884*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
885*7c478bd9Sstevel@tonic-gate "- unknown qualifier %d (0x%x).",
886*7c478bd9Sstevel@tonic-gate pointer[1], pointer[1]);
887*7c478bd9Sstevel@tonic-gate }
888*7c478bd9Sstevel@tonic-gate break;
889*7c478bd9Sstevel@tonic-gate
890*7c478bd9Sstevel@tonic-gate case TELOPT_NEW_ENVIRON:
891*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "NEW-ENVIRON ");
892*7c478bd9Sstevel@tonic-gate #ifdef OLD_ENVIRON
893*7c478bd9Sstevel@tonic-gate goto env_common1;
894*7c478bd9Sstevel@tonic-gate case TELOPT_OLD_ENVIRON:
895*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "OLD-ENVIRON ");
896*7c478bd9Sstevel@tonic-gate env_common1:
897*7c478bd9Sstevel@tonic-gate #endif
898*7c478bd9Sstevel@tonic-gate switch (pointer[1]) {
899*7c478bd9Sstevel@tonic-gate case TELQUAL_IS:
900*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "IS ");
901*7c478bd9Sstevel@tonic-gate goto env_common;
902*7c478bd9Sstevel@tonic-gate case TELQUAL_SEND:
903*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "SEND ");
904*7c478bd9Sstevel@tonic-gate goto env_common;
905*7c478bd9Sstevel@tonic-gate case TELQUAL_INFO:
906*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "INFO ");
907*7c478bd9Sstevel@tonic-gate env_common:
908*7c478bd9Sstevel@tonic-gate {
909*7c478bd9Sstevel@tonic-gate register int noquote = 2;
910*7c478bd9Sstevel@tonic-gate #if defined(ENV_HACK) && defined(OLD_ENVIRON)
911*7c478bd9Sstevel@tonic-gate extern int old_env_var, old_env_value;
912*7c478bd9Sstevel@tonic-gate #endif
913*7c478bd9Sstevel@tonic-gate for (i = 2; i < length; i++) {
914*7c478bd9Sstevel@tonic-gate switch (pointer[i]) {
915*7c478bd9Sstevel@tonic-gate case NEW_ENV_VALUE:
916*7c478bd9Sstevel@tonic-gate #ifdef OLD_ENVIRON
917*7c478bd9Sstevel@tonic-gate /* case NEW_ENV_OVAR: */
918*7c478bd9Sstevel@tonic-gate if (pointer[0] == TELOPT_OLD_ENVIRON) {
919*7c478bd9Sstevel@tonic-gate #ifdef ENV_HACK
920*7c478bd9Sstevel@tonic-gate if (old_env_var == OLD_ENV_VALUE)
921*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
922*7c478bd9Sstevel@tonic-gate "\" (VALUE) " + noquote);
923*7c478bd9Sstevel@tonic-gate else
924*7c478bd9Sstevel@tonic-gate #endif
925*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
926*7c478bd9Sstevel@tonic-gate "\" VAR " + noquote);
927*7c478bd9Sstevel@tonic-gate } else
928*7c478bd9Sstevel@tonic-gate #endif /* OLD_ENVIRON */
929*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" VALUE " + noquote);
930*7c478bd9Sstevel@tonic-gate noquote = 2;
931*7c478bd9Sstevel@tonic-gate break;
932*7c478bd9Sstevel@tonic-gate
933*7c478bd9Sstevel@tonic-gate case NEW_ENV_VAR:
934*7c478bd9Sstevel@tonic-gate #ifdef OLD_ENVIRON
935*7c478bd9Sstevel@tonic-gate /* case OLD_ENV_VALUE: */
936*7c478bd9Sstevel@tonic-gate if (pointer[0] == TELOPT_OLD_ENVIRON) {
937*7c478bd9Sstevel@tonic-gate #ifdef ENV_HACK
938*7c478bd9Sstevel@tonic-gate if (old_env_value == OLD_ENV_VAR)
939*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
940*7c478bd9Sstevel@tonic-gate "\" (VAR) " + noquote);
941*7c478bd9Sstevel@tonic-gate else
942*7c478bd9Sstevel@tonic-gate #endif
943*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace,
944*7c478bd9Sstevel@tonic-gate "\" VALUE " + noquote);
945*7c478bd9Sstevel@tonic-gate } else
946*7c478bd9Sstevel@tonic-gate #endif /* OLD_ENVIRON */
947*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" VAR " + noquote);
948*7c478bd9Sstevel@tonic-gate noquote = 2;
949*7c478bd9Sstevel@tonic-gate break;
950*7c478bd9Sstevel@tonic-gate
951*7c478bd9Sstevel@tonic-gate case ENV_ESC:
952*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" ESC " + noquote);
953*7c478bd9Sstevel@tonic-gate noquote = 2;
954*7c478bd9Sstevel@tonic-gate break;
955*7c478bd9Sstevel@tonic-gate
956*7c478bd9Sstevel@tonic-gate case ENV_USERVAR:
957*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" USERVAR " + noquote);
958*7c478bd9Sstevel@tonic-gate noquote = 2;
959*7c478bd9Sstevel@tonic-gate break;
960*7c478bd9Sstevel@tonic-gate
961*7c478bd9Sstevel@tonic-gate default:
962*7c478bd9Sstevel@tonic-gate def_case:
963*7c478bd9Sstevel@tonic-gate if (isprint(pointer[i]) && pointer[i] != '"') {
964*7c478bd9Sstevel@tonic-gate if (noquote) {
965*7c478bd9Sstevel@tonic-gate (void) putc('"', NetTrace);
966*7c478bd9Sstevel@tonic-gate noquote = 0;
967*7c478bd9Sstevel@tonic-gate }
968*7c478bd9Sstevel@tonic-gate (void) putc(pointer[i], NetTrace);
969*7c478bd9Sstevel@tonic-gate } else {
970*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\" %03o " + noquote,
971*7c478bd9Sstevel@tonic-gate pointer[i]);
972*7c478bd9Sstevel@tonic-gate noquote = 2;
973*7c478bd9Sstevel@tonic-gate }
974*7c478bd9Sstevel@tonic-gate break;
975*7c478bd9Sstevel@tonic-gate }
976*7c478bd9Sstevel@tonic-gate }
977*7c478bd9Sstevel@tonic-gate if (!noquote)
978*7c478bd9Sstevel@tonic-gate (void) putc('"', NetTrace);
979*7c478bd9Sstevel@tonic-gate break;
980*7c478bd9Sstevel@tonic-gate }
981*7c478bd9Sstevel@tonic-gate }
982*7c478bd9Sstevel@tonic-gate break;
983*7c478bd9Sstevel@tonic-gate
984*7c478bd9Sstevel@tonic-gate default:
985*7c478bd9Sstevel@tonic-gate if (TELOPT_OK(pointer[0]))
986*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
987*7c478bd9Sstevel@tonic-gate else
988*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "%d (unknown)", pointer[0]);
989*7c478bd9Sstevel@tonic-gate for (i = 1; i < length; i++)
990*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, " %d", pointer[i]);
991*7c478bd9Sstevel@tonic-gate break;
992*7c478bd9Sstevel@tonic-gate }
993*7c478bd9Sstevel@tonic-gate if (direction) {
994*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
995*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\r\n");
996*7c478bd9Sstevel@tonic-gate else
997*7c478bd9Sstevel@tonic-gate (void) fprintf(NetTrace, "\n");
998*7c478bd9Sstevel@tonic-gate }
999*7c478bd9Sstevel@tonic-gate if (NetTrace == stdout)
1000*7c478bd9Sstevel@tonic-gate (void) fflush(NetTrace);
1001*7c478bd9Sstevel@tonic-gate }
1002*7c478bd9Sstevel@tonic-gate }
1003*7c478bd9Sstevel@tonic-gate
1004*7c478bd9Sstevel@tonic-gate /*
1005*7c478bd9Sstevel@tonic-gate * EmptyTerminal - called to make sure that the terminal buffer is empty.
1006*7c478bd9Sstevel@tonic-gate * Note that we consider the buffer to run all the
1007*7c478bd9Sstevel@tonic-gate * way to the kernel (thus the select).
1008*7c478bd9Sstevel@tonic-gate */
1009*7c478bd9Sstevel@tonic-gate
1010*7c478bd9Sstevel@tonic-gate static void
EmptyTerminal()1011*7c478bd9Sstevel@tonic-gate EmptyTerminal()
1012*7c478bd9Sstevel@tonic-gate {
1013*7c478bd9Sstevel@tonic-gate fd_set o;
1014*7c478bd9Sstevel@tonic-gate
1015*7c478bd9Sstevel@tonic-gate FD_ZERO(&o);
1016*7c478bd9Sstevel@tonic-gate
1017*7c478bd9Sstevel@tonic-gate if (TTYBYTES() == 0) {
1018*7c478bd9Sstevel@tonic-gate FD_SET(tout, &o);
1019*7c478bd9Sstevel@tonic-gate /* wait for TTLOWAT */
1020*7c478bd9Sstevel@tonic-gate (void) select(tout+1, NULL, &o, NULL, NULL);
1021*7c478bd9Sstevel@tonic-gate } else {
1022*7c478bd9Sstevel@tonic-gate while (TTYBYTES()) {
1023*7c478bd9Sstevel@tonic-gate if (ttyflush(0) == -2) {
1024*7c478bd9Sstevel@tonic-gate /* This will not return. */
1025*7c478bd9Sstevel@tonic-gate fatal_tty_error("write");
1026*7c478bd9Sstevel@tonic-gate }
1027*7c478bd9Sstevel@tonic-gate FD_SET(tout, &o);
1028*7c478bd9Sstevel@tonic-gate /* wait for TTLOWAT */
1029*7c478bd9Sstevel@tonic-gate (void) select(tout+1, NULL, &o, NULL, NULL);
1030*7c478bd9Sstevel@tonic-gate }
1031*7c478bd9Sstevel@tonic-gate }
1032*7c478bd9Sstevel@tonic-gate }
1033*7c478bd9Sstevel@tonic-gate
1034*7c478bd9Sstevel@tonic-gate static void
SetForExit()1035*7c478bd9Sstevel@tonic-gate SetForExit()
1036*7c478bd9Sstevel@tonic-gate {
1037*7c478bd9Sstevel@tonic-gate setconnmode(0);
1038*7c478bd9Sstevel@tonic-gate do {
1039*7c478bd9Sstevel@tonic-gate (void) telrcv(); /* Process any incoming data */
1040*7c478bd9Sstevel@tonic-gate EmptyTerminal();
1041*7c478bd9Sstevel@tonic-gate } while (ring_full_count(&netiring)); /* While there is any */
1042*7c478bd9Sstevel@tonic-gate setcommandmode();
1043*7c478bd9Sstevel@tonic-gate (void) fflush(stdout);
1044*7c478bd9Sstevel@tonic-gate (void) fflush(stderr);
1045*7c478bd9Sstevel@tonic-gate setconnmode(0);
1046*7c478bd9Sstevel@tonic-gate EmptyTerminal(); /* Flush the path to the tty */
1047*7c478bd9Sstevel@tonic-gate setcommandmode();
1048*7c478bd9Sstevel@tonic-gate }
1049*7c478bd9Sstevel@tonic-gate
1050*7c478bd9Sstevel@tonic-gate void
Exit(returnCode)1051*7c478bd9Sstevel@tonic-gate Exit(returnCode)
1052*7c478bd9Sstevel@tonic-gate int returnCode;
1053*7c478bd9Sstevel@tonic-gate {
1054*7c478bd9Sstevel@tonic-gate SetForExit();
1055*7c478bd9Sstevel@tonic-gate exit(returnCode);
1056*7c478bd9Sstevel@tonic-gate }
1057*7c478bd9Sstevel@tonic-gate
1058*7c478bd9Sstevel@tonic-gate void
ExitString(string,returnCode)1059*7c478bd9Sstevel@tonic-gate ExitString(string, returnCode)
1060*7c478bd9Sstevel@tonic-gate char *string;
1061*7c478bd9Sstevel@tonic-gate int returnCode;
1062*7c478bd9Sstevel@tonic-gate {
1063*7c478bd9Sstevel@tonic-gate SetForExit();
1064*7c478bd9Sstevel@tonic-gate (void) fwrite(string, 1, strlen(string), stderr);
1065*7c478bd9Sstevel@tonic-gate exit(returnCode);
1066*7c478bd9Sstevel@tonic-gate }
1067*7c478bd9Sstevel@tonic-gate
1068*7c478bd9Sstevel@tonic-gate #define BUFFER_CHUNK_SIZE 64
1069*7c478bd9Sstevel@tonic-gate
1070*7c478bd9Sstevel@tonic-gate /* Round up to a multiple of BUFFER_CHUNK_SIZE */
1071*7c478bd9Sstevel@tonic-gate #define ROUND_CHUNK_SIZE(s) ((((s) + BUFFER_CHUNK_SIZE - 1) / \
1072*7c478bd9Sstevel@tonic-gate BUFFER_CHUNK_SIZE) * BUFFER_CHUNK_SIZE)
1073*7c478bd9Sstevel@tonic-gate
1074*7c478bd9Sstevel@tonic-gate /*
1075*7c478bd9Sstevel@tonic-gate * Optionally allocate a buffer, and optionally read a string from a stream
1076*7c478bd9Sstevel@tonic-gate * into the buffer, starting at the given offset. If the buffer isn't
1077*7c478bd9Sstevel@tonic-gate * large enough for the given offset, or if buffer space is exhausted
1078*7c478bd9Sstevel@tonic-gate * when reading the string, the size of the buffer is increased.
1079*7c478bd9Sstevel@tonic-gate *
1080*7c478bd9Sstevel@tonic-gate * A buffer can be supplied when the function is called, passing the
1081*7c478bd9Sstevel@tonic-gate * buffer address via the first argument. The buffer size can be
1082*7c478bd9Sstevel@tonic-gate * passed as well, in the second argument. If the second argument is
1083*7c478bd9Sstevel@tonic-gate * NULL, the function makes no assumptions about the buffer size.
1084*7c478bd9Sstevel@tonic-gate * The address of the buffer is returned via the first argument, and the
1085*7c478bd9Sstevel@tonic-gate * buffer size via the second argument if this is not NULL.
1086*7c478bd9Sstevel@tonic-gate * These returned values may differ from the supplied values if the buffer
1087*7c478bd9Sstevel@tonic-gate * was reallocated.
1088*7c478bd9Sstevel@tonic-gate *
1089*7c478bd9Sstevel@tonic-gate * If no buffer is to be supplied, specify a buffer address of NULL, via
1090*7c478bd9Sstevel@tonic-gate * the first argument.
1091*7c478bd9Sstevel@tonic-gate *
1092*7c478bd9Sstevel@tonic-gate * If the pointer to the buffer address is NULL, the function just returns
1093*7c478bd9Sstevel@tonic-gate * NULL, and performs no other processing.
1094*7c478bd9Sstevel@tonic-gate *
1095*7c478bd9Sstevel@tonic-gate * If a NULL stream is passed, the function will just make sure the
1096*7c478bd9Sstevel@tonic-gate * supplied buffer is large enough to hold the supplied offset,
1097*7c478bd9Sstevel@tonic-gate * reallocating it if is too small or too large.
1098*7c478bd9Sstevel@tonic-gate *
1099*7c478bd9Sstevel@tonic-gate * The returned buffer will be a multiple of BUFFER_CHUNK_SIZE in size.
1100*7c478bd9Sstevel@tonic-gate *
1101*7c478bd9Sstevel@tonic-gate * The function stops reading from the stream when a newline is read,
1102*7c478bd9Sstevel@tonic-gate * end of file is reached, or an error occurs. The newline is not
1103*7c478bd9Sstevel@tonic-gate * returned in the buffer. The returned string will be NULL terminated.
1104*7c478bd9Sstevel@tonic-gate *
1105*7c478bd9Sstevel@tonic-gate * The function returns the address of the buffer if any characters
1106*7c478bd9Sstevel@tonic-gate * are read and no error occurred, otherwise it returns NULL.
1107*7c478bd9Sstevel@tonic-gate *
1108*7c478bd9Sstevel@tonic-gate * If the function returns NULL, a buffer may have been allocated. The
1109*7c478bd9Sstevel@tonic-gate * buffer address will be returned via the first argument, together with
1110*7c478bd9Sstevel@tonic-gate * the buffer size if the second argument is not NULL.
1111*7c478bd9Sstevel@tonic-gate *
1112*7c478bd9Sstevel@tonic-gate */
1113*7c478bd9Sstevel@tonic-gate static char *
GetStringAtOffset(bufp,cbufsiz,off,st)1114*7c478bd9Sstevel@tonic-gate GetStringAtOffset(bufp, cbufsiz, off, st)
1115*7c478bd9Sstevel@tonic-gate char **bufp;
1116*7c478bd9Sstevel@tonic-gate unsigned int *cbufsiz;
1117*7c478bd9Sstevel@tonic-gate unsigned int off;
1118*7c478bd9Sstevel@tonic-gate FILE *st;
1119*7c478bd9Sstevel@tonic-gate {
1120*7c478bd9Sstevel@tonic-gate unsigned int bufsiz;
1121*7c478bd9Sstevel@tonic-gate char *buf;
1122*7c478bd9Sstevel@tonic-gate char *nbuf;
1123*7c478bd9Sstevel@tonic-gate unsigned int idx = off;
1124*7c478bd9Sstevel@tonic-gate
1125*7c478bd9Sstevel@tonic-gate if (bufp == NULL)
1126*7c478bd9Sstevel@tonic-gate return (NULL);
1127*7c478bd9Sstevel@tonic-gate
1128*7c478bd9Sstevel@tonic-gate buf = *bufp;
1129*7c478bd9Sstevel@tonic-gate
1130*7c478bd9Sstevel@tonic-gate bufsiz = ROUND_CHUNK_SIZE(off + 1);
1131*7c478bd9Sstevel@tonic-gate
1132*7c478bd9Sstevel@tonic-gate if (buf == NULL || cbufsiz == NULL || *cbufsiz != bufsiz) {
1133*7c478bd9Sstevel@tonic-gate if ((nbuf = realloc(buf, bufsiz)) == NULL)
1134*7c478bd9Sstevel@tonic-gate return (NULL);
1135*7c478bd9Sstevel@tonic-gate
1136*7c478bd9Sstevel@tonic-gate buf = nbuf;
1137*7c478bd9Sstevel@tonic-gate *bufp = buf;
1138*7c478bd9Sstevel@tonic-gate if (cbufsiz != NULL)
1139*7c478bd9Sstevel@tonic-gate *cbufsiz = bufsiz;
1140*7c478bd9Sstevel@tonic-gate }
1141*7c478bd9Sstevel@tonic-gate
1142*7c478bd9Sstevel@tonic-gate
1143*7c478bd9Sstevel@tonic-gate if (st == NULL)
1144*7c478bd9Sstevel@tonic-gate return (buf);
1145*7c478bd9Sstevel@tonic-gate
1146*7c478bd9Sstevel@tonic-gate clearerr(st);
1147*7c478bd9Sstevel@tonic-gate for (;;) {
1148*7c478bd9Sstevel@tonic-gate int c = getc(st);
1149*7c478bd9Sstevel@tonic-gate
1150*7c478bd9Sstevel@tonic-gate /* Expand the buffer as needed. */
1151*7c478bd9Sstevel@tonic-gate if (idx == bufsiz) {
1152*7c478bd9Sstevel@tonic-gate bufsiz += BUFFER_CHUNK_SIZE;
1153*7c478bd9Sstevel@tonic-gate if ((nbuf = realloc(buf, bufsiz)) == NULL) {
1154*7c478bd9Sstevel@tonic-gate /* Discard everything we read. */
1155*7c478bd9Sstevel@tonic-gate buf[off] = 0;
1156*7c478bd9Sstevel@tonic-gate buf = NULL;
1157*7c478bd9Sstevel@tonic-gate break;
1158*7c478bd9Sstevel@tonic-gate }
1159*7c478bd9Sstevel@tonic-gate buf = nbuf;
1160*7c478bd9Sstevel@tonic-gate *bufp = buf;
1161*7c478bd9Sstevel@tonic-gate if (cbufsiz != NULL)
1162*7c478bd9Sstevel@tonic-gate *cbufsiz = bufsiz;
1163*7c478bd9Sstevel@tonic-gate }
1164*7c478bd9Sstevel@tonic-gate
1165*7c478bd9Sstevel@tonic-gate if (c == EOF || c == '\n') {
1166*7c478bd9Sstevel@tonic-gate buf[idx] = 0;
1167*7c478bd9Sstevel@tonic-gate if (ferror(st) != 0) {
1168*7c478bd9Sstevel@tonic-gate /* Retry if interrupted by a signal. */
1169*7c478bd9Sstevel@tonic-gate if (errno == EINTR) {
1170*7c478bd9Sstevel@tonic-gate clearerr(st);
1171*7c478bd9Sstevel@tonic-gate continue;
1172*7c478bd9Sstevel@tonic-gate }
1173*7c478bd9Sstevel@tonic-gate buf = NULL;
1174*7c478bd9Sstevel@tonic-gate } else if (feof(st) != 0) {
1175*7c478bd9Sstevel@tonic-gate /* No characters transferred? */
1176*7c478bd9Sstevel@tonic-gate if (off == idx)
1177*7c478bd9Sstevel@tonic-gate buf = NULL;
1178*7c478bd9Sstevel@tonic-gate }
1179*7c478bd9Sstevel@tonic-gate break;
1180*7c478bd9Sstevel@tonic-gate }
1181*7c478bd9Sstevel@tonic-gate buf[idx++] = c;
1182*7c478bd9Sstevel@tonic-gate }
1183*7c478bd9Sstevel@tonic-gate return (buf);
1184*7c478bd9Sstevel@tonic-gate }
1185*7c478bd9Sstevel@tonic-gate
1186*7c478bd9Sstevel@tonic-gate /*
1187*7c478bd9Sstevel@tonic-gate * Read a string from the supplied stream. Stop reading when a newline
1188*7c478bd9Sstevel@tonic-gate * is read, end of file reached, or an error occurs.
1189*7c478bd9Sstevel@tonic-gate *
1190*7c478bd9Sstevel@tonic-gate * A buffer can be supplied by specifying the buffer address via the
1191*7c478bd9Sstevel@tonic-gate * first argument. The buffer size can be passed via the second argument.
1192*7c478bd9Sstevel@tonic-gate * If the second argument is NULL, the function makes no assumptions
1193*7c478bd9Sstevel@tonic-gate * about the buffer size. The buffer will be reallocated if it is too
1194*7c478bd9Sstevel@tonic-gate * small or too large for the returned string.
1195*7c478bd9Sstevel@tonic-gate *
1196*7c478bd9Sstevel@tonic-gate * If no buffer is to be supplied, specify a buffer address of NULL,
1197*7c478bd9Sstevel@tonic-gate * via the first argument.
1198*7c478bd9Sstevel@tonic-gate *
1199*7c478bd9Sstevel@tonic-gate * If the first argument is NULL, the function just returns NULL, and
1200*7c478bd9Sstevel@tonic-gate * performs no other processing.
1201*7c478bd9Sstevel@tonic-gate *
1202*7c478bd9Sstevel@tonic-gate * The function returns the address of the buffer if any characters are
1203*7c478bd9Sstevel@tonic-gate * read and no error occurred.
1204*7c478bd9Sstevel@tonic-gate *
1205*7c478bd9Sstevel@tonic-gate * If the function returns NULL, a buffer may have been allocated. The
1206*7c478bd9Sstevel@tonic-gate * buffer address and buffer size will be returned via the first argument,
1207*7c478bd9Sstevel@tonic-gate * and the buffer size via the second argument, if this isn't NULL.
1208*7c478bd9Sstevel@tonic-gate */
1209*7c478bd9Sstevel@tonic-gate char *
GetString(bufp,bufsiz,st)1210*7c478bd9Sstevel@tonic-gate GetString(bufp, bufsiz, st)
1211*7c478bd9Sstevel@tonic-gate char **bufp;
1212*7c478bd9Sstevel@tonic-gate unsigned int *bufsiz;
1213*7c478bd9Sstevel@tonic-gate FILE *st;
1214*7c478bd9Sstevel@tonic-gate {
1215*7c478bd9Sstevel@tonic-gate return (GetStringAtOffset(bufp, bufsiz, 0, st));
1216*7c478bd9Sstevel@tonic-gate }
1217*7c478bd9Sstevel@tonic-gate
1218*7c478bd9Sstevel@tonic-gate /*
1219*7c478bd9Sstevel@tonic-gate * Allocate a buffer to hold a string of given length.
1220*7c478bd9Sstevel@tonic-gate *
1221*7c478bd9Sstevel@tonic-gate * An existing buffer can be reallocated by passing its address and via
1222*7c478bd9Sstevel@tonic-gate * the first argument. The buffer size can be passed via the second
1223*7c478bd9Sstevel@tonic-gate * argument. If the second argument is NULL, the function makes no
1224*7c478bd9Sstevel@tonic-gate * assumptions about the buffer size.
1225*7c478bd9Sstevel@tonic-gate *
1226*7c478bd9Sstevel@tonic-gate * If no existing buffer is to be supplied, pass a NULL buffer address via
1227*7c478bd9Sstevel@tonic-gate * the first argument.
1228*7c478bd9Sstevel@tonic-gate *
1229*7c478bd9Sstevel@tonic-gate * If the first argument is NULL, the function just returns NULL,
1230*7c478bd9Sstevel@tonic-gate * and performs no other processing.
1231*7c478bd9Sstevel@tonic-gate */
1232*7c478bd9Sstevel@tonic-gate char *
AllocStringBuffer(bufp,bufsiz,size)1233*7c478bd9Sstevel@tonic-gate AllocStringBuffer(bufp, bufsiz, size)
1234*7c478bd9Sstevel@tonic-gate char **bufp;
1235*7c478bd9Sstevel@tonic-gate unsigned int *bufsiz;
1236*7c478bd9Sstevel@tonic-gate unsigned int size;
1237*7c478bd9Sstevel@tonic-gate {
1238*7c478bd9Sstevel@tonic-gate return (GetStringAtOffset(bufp, bufsiz, size, (FILE *)NULL));
1239*7c478bd9Sstevel@tonic-gate }
1240*7c478bd9Sstevel@tonic-gate
1241*7c478bd9Sstevel@tonic-gate /*
1242*7c478bd9Sstevel@tonic-gate * This function is similar to GetString(), except that the string read
1243*7c478bd9Sstevel@tonic-gate * from the stream is appended to the supplied string.
1244*7c478bd9Sstevel@tonic-gate */
1245*7c478bd9Sstevel@tonic-gate char *
GetAndAppendString(bufp,bufsiz,str,st)1246*7c478bd9Sstevel@tonic-gate GetAndAppendString(bufp, bufsiz, str, st)
1247*7c478bd9Sstevel@tonic-gate char **bufp;
1248*7c478bd9Sstevel@tonic-gate unsigned int *bufsiz;
1249*7c478bd9Sstevel@tonic-gate char *str;
1250*7c478bd9Sstevel@tonic-gate FILE *st;
1251*7c478bd9Sstevel@tonic-gate {
1252*7c478bd9Sstevel@tonic-gate unsigned int off = strlen(str);
1253*7c478bd9Sstevel@tonic-gate
1254*7c478bd9Sstevel@tonic-gate if (GetStringAtOffset(bufp, bufsiz, off, st) == NULL)
1255*7c478bd9Sstevel@tonic-gate return (NULL);
1256*7c478bd9Sstevel@tonic-gate
1257*7c478bd9Sstevel@tonic-gate return (memcpy(*bufp, str, off));
1258*7c478bd9Sstevel@tonic-gate }
1259