xref: /original-bsd/usr.bin/telnet/utilities.c (revision ed20bae8)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)utilities.c	1.10 (Berkeley) 12/01/88";
20 #endif /* not lint */
21 
22 #define	TELOPTS
23 #include <arpa/telnet.h>
24 #include <sys/types.h>
25 
26 #include <ctype.h>
27 
28 #include "general.h"
29 
30 #include "fdset.h"
31 
32 #include "ring.h"
33 
34 #include "defines.h"
35 
36 #include "externs.h"
37 
38 FILE	*NetTrace = 0;		/* Not in bss, since needs to stay */
39 
40 /*
41  * upcase()
42  *
43  *	Upcase (in place) the argument.
44  */
45 
46 void
47 upcase(argument)
48 register char *argument;
49 {
50     register int c;
51 
52     while ((c = *argument) != 0) {
53 	if (islower(c)) {
54 	    *argument = toupper(c);
55 	}
56 	argument++;
57     }
58 }
59 
60 /*
61  * SetSockOpt()
62  *
63  * Compensate for differences in 4.2 and 4.3 systems.
64  */
65 
66 int
67 SetSockOpt(fd, level, option, yesno)
68 int
69 	fd,
70 	level,
71 	option,
72 	yesno;
73 {
74 #ifndef	NOT43
75     return setsockopt(fd, level, option,
76 				(char *)&yesno, sizeof yesno);
77 #else	/* NOT43 */
78     if (yesno == 0) {		/* Can't do that in 4.2! */
79 	fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
80 				option);
81 	return -1;
82     }
83     return setsockopt(fd, level, option, 0, 0);
84 #endif	/* NOT43 */
85 }
86 
87 /*
88  * The following are routines used to print out debugging information.
89  */
90 
91 
92 void
93 Dump(direction, buffer, length)
94 char	direction;
95 char	*buffer;
96 int	length;
97 {
98 #   define BYTES_PER_LINE	32
99 #   define min(x,y)	((x<y)? x:y)
100     char *pThis;
101     int offset;
102 
103     offset = 0;
104 
105     while (length) {
106 	/* print one line */
107 	fprintf(NetTrace, "%c 0x%x\t", direction, offset);
108 	pThis = buffer;
109 	buffer = buffer+min(length, BYTES_PER_LINE);
110 	while (pThis < buffer) {
111 	    fprintf(NetTrace, "%.2x", (*pThis)&0xff);
112 	    pThis++;
113 	}
114 	fprintf(NetTrace, "\n");
115 	length -= BYTES_PER_LINE;
116 	offset += BYTES_PER_LINE;
117 	if (length < 0) {
118 	    return;
119 	}
120 	/* find next unique line */
121     }
122 }
123 
124 
125 /*VARARGS*/
126 void
127 printoption(direction, fmt, option, what)
128 	char *direction, *fmt;
129 	int option, what;
130 {
131 	if (!showoptions)
132 		return;
133 	fprintf(NetTrace, "%s ", direction+1);
134 	if (fmt == doopt)
135 		fmt = "do";
136 	else if (fmt == dont)
137 		fmt = "dont";
138 	else if (fmt == will)
139 		fmt = "will";
140 	else if (fmt == wont)
141 		fmt = "wont";
142 	else
143 		fmt = "???";
144 	if (option < (sizeof telopts/sizeof telopts[0]))
145 		fprintf(NetTrace, "%s %s", fmt, telopts[option]);
146 	else
147 		fprintf(NetTrace, "%s %d", fmt, option);
148 	if (*direction == '<') {
149 		fprintf(NetTrace, "\r\n");
150 		return;
151 	}
152 	fprintf(NetTrace, " (%s)\r\n", what ? "reply" : "don't reply");
153 }
154 
155 void
156 printsub(direction, pointer, length)
157 char	*direction,		/* "<" or ">" */
158 	*pointer;		/* where suboption data sits */
159 int	length;			/* length of suboption data */
160 {
161     if (showoptions) {
162 	fprintf(NetTrace, "%s suboption ",
163 				(direction[0] == '<')? "Received":"Sent");
164 	switch (pointer[0]) {
165 	case TELOPT_TTYPE:
166 	    fprintf(NetTrace, "Terminal type ");
167 	    switch (pointer[1]) {
168 	    case TELQUAL_IS:
169 		{
170 		    char tmpbuf[SUBBUFSIZE];
171 		    int minlen = min(length, sizeof tmpbuf);
172 
173 		    memcpy(tmpbuf, pointer+2, minlen);
174 		    tmpbuf[minlen-1] = 0;
175 		    fprintf(NetTrace, "is %s.\n", tmpbuf);
176 		}
177 		break;
178 	    case TELQUAL_SEND:
179 		fprintf(NetTrace, "- request to send.\n");
180 		break;
181 	    default:
182 		fprintf(NetTrace,
183 				"- unknown qualifier %d (0x%x).\n",
184 				pointer[1], pointer[1]);
185 	    }
186 	    break;
187 	default:
188 	    fprintf(NetTrace, "Unknown option %d (0x%x)\n",
189 					pointer[0], pointer[0]);
190 	}
191     }
192 }
193 
194 /* EmptyTerminal - called to make sure that the terminal buffer is empty.
195  *			Note that we consider the buffer to run all the
196  *			way to the kernel (thus the select).
197  */
198 
199 void
200 EmptyTerminal()
201 {
202 #if	defined(unix)
203     fd_set	o;
204 
205     FD_ZERO(&o);
206 #endif	/* defined(unix) */
207 
208     if (TTYBYTES() == 0) {
209 #if	defined(unix)
210 	FD_SET(tout, &o);
211 	(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
212 			(struct timeval *) 0);	/* wait for TTLOWAT */
213 #endif	/* defined(unix) */
214     } else {
215 	while (TTYBYTES()) {
216 	    ttyflush(0);
217 #if	defined(unix)
218 	    FD_SET(tout, &o);
219 	    (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
220 				(struct timeval *) 0);	/* wait for TTLOWAT */
221 #endif	/* defined(unix) */
222 	}
223     }
224 }
225 
226 void
227 SetForExit()
228 {
229     setconnmode();
230 #if	defined(TN3270)
231     if (In3270) {
232 	Finish3270();
233     }
234 #else	/* defined(TN3270) */
235     do {
236 	telrcv();			/* Process any incoming data */
237 	EmptyTerminal();
238     } while (ring_full_count(&netiring));	/* While there is any */
239 #endif	/* defined(TN3270) */
240     setcommandmode();
241     fflush(stdout);
242     fflush(stderr);
243 #if	defined(TN3270)
244     if (In3270) {
245 	StopScreen(1);
246     }
247 #endif	/* defined(TN3270) */
248     setconnmode();
249     EmptyTerminal();			/* Flush the path to the tty */
250     setcommandmode();
251 }
252 
253 void
254 Exit(returnCode)
255 int returnCode;
256 {
257     SetForExit();
258     exit(returnCode);
259 }
260 
261 void
262 ExitString(string, returnCode)
263 char *string;
264 int returnCode;
265 {
266     SetForExit();
267     fwrite(string, 1, strlen(string), stderr);
268     exit(returnCode);
269 }
270 
271 #if defined(MSDOS)
272 void
273 ExitPerror(string, returnCode)
274 char *string;
275 int returnCode;
276 {
277     SetForExit();
278     perror(string);
279     exit(returnCode);
280 }
281 #endif /* defined(MSDOS) */
282