xref: /original-bsd/usr.bin/telnet/utilities.c (revision 29d43723)
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.12 (Berkeley) 03/21/89";
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 	if (NetTrace == stdout) {
115 	    fprintf(NetTrace, "\n");
116 	} else {
117 	    fprintf(NetTrace, "\r\n");
118 	}
119 	length -= BYTES_PER_LINE;
120 	offset += BYTES_PER_LINE;
121 	if (length < 0) {
122 	    fflush(NetTrace);
123 	    return;
124 	}
125 	/* find next unique line */
126     }
127     fflush(NetTrace);
128 }
129 
130 
131 void
132 printoption(direction, fmt, option)
133 	char *direction, *fmt;
134 	int option;
135 {
136 	if (!showoptions)
137 		return;
138 	fprintf(NetTrace, "%s ", direction);
139 	if (option < (sizeof telopts/sizeof telopts[0]))
140 		fprintf(NetTrace, "%s %s", fmt, telopts[option]);
141 	else
142 		fprintf(NetTrace, "%s %d", fmt, option);
143 	if (NetTrace == stdout) {
144 	    fprintf(NetTrace, "\r\n");
145 	} else {
146 	    fprintf(NetTrace, "\n");
147 	}
148 	return;
149 }
150 
151 void
152 printsub(direction, pointer, length)
153 char	*direction,		/* "<" or ">" */
154 	*pointer;		/* where suboption data sits */
155 int	length;			/* length of suboption data */
156 {
157     if (showoptions) {
158 	fprintf(NetTrace, "%s suboption ",
159 				(direction[0] == '<')? "Received":"Sent");
160 	switch (pointer[0]) {
161 	case TELOPT_TTYPE:
162 	    fprintf(NetTrace, "Terminal type ");
163 	    switch (pointer[1]) {
164 	    case TELQUAL_IS:
165 		{
166 		    char tmpbuf[SUBBUFSIZE];
167 		    int minlen = min(length, sizeof tmpbuf);
168 
169 		    memcpy(tmpbuf, pointer+2, minlen);
170 		    tmpbuf[minlen-1] = 0;
171 		    fprintf(NetTrace, "is %s.\n", tmpbuf);
172 		}
173 		break;
174 	    case TELQUAL_SEND:
175 		fprintf(NetTrace, "- request to send.\n");
176 		break;
177 	    default:
178 		fprintf(NetTrace,
179 				"- unknown qualifier %d (0x%x).\n",
180 				pointer[1], pointer[1]);
181 	    }
182 	    break;
183 	default:
184 	    fprintf(NetTrace, "Unknown option %d (0x%x)\n",
185 					pointer[0], pointer[0]);
186 	}
187     }
188 }
189 
190 /* EmptyTerminal - called to make sure that the terminal buffer is empty.
191  *			Note that we consider the buffer to run all the
192  *			way to the kernel (thus the select).
193  */
194 
195 void
196 EmptyTerminal()
197 {
198 #if	defined(unix)
199     fd_set	o;
200 
201     FD_ZERO(&o);
202 #endif	/* defined(unix) */
203 
204     if (TTYBYTES() == 0) {
205 #if	defined(unix)
206 	FD_SET(tout, &o);
207 	(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
208 			(struct timeval *) 0);	/* wait for TTLOWAT */
209 #endif	/* defined(unix) */
210     } else {
211 	while (TTYBYTES()) {
212 	    ttyflush(0);
213 #if	defined(unix)
214 	    FD_SET(tout, &o);
215 	    (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
216 				(struct timeval *) 0);	/* wait for TTLOWAT */
217 #endif	/* defined(unix) */
218 	}
219     }
220 }
221 
222 void
223 SetForExit()
224 {
225     setconnmode();
226 #if	defined(TN3270)
227     if (In3270) {
228 	Finish3270();
229     }
230 #else	/* defined(TN3270) */
231     do {
232 	telrcv();			/* Process any incoming data */
233 	EmptyTerminal();
234     } while (ring_full_count(&netiring));	/* While there is any */
235 #endif	/* defined(TN3270) */
236     setcommandmode();
237     fflush(stdout);
238     fflush(stderr);
239 #if	defined(TN3270)
240     if (In3270) {
241 	StopScreen(1);
242     }
243 #endif	/* defined(TN3270) */
244     setconnmode();
245     EmptyTerminal();			/* Flush the path to the tty */
246     setcommandmode();
247 }
248 
249 void
250 Exit(returnCode)
251 int returnCode;
252 {
253     SetForExit();
254     exit(returnCode);
255 }
256 
257 void
258 ExitString(string, returnCode)
259 char *string;
260 int returnCode;
261 {
262     SetForExit();
263     fwrite(string, 1, strlen(string), stderr);
264     exit(returnCode);
265 }
266 
267 #if defined(MSDOS)
268 void
269 ExitPerror(string, returnCode)
270 char *string;
271 int returnCode;
272 {
273     SetForExit();
274     perror(string);
275     exit(returnCode);
276 }
277 #endif /* defined(MSDOS) */
278