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