add need to include <sys/time.h> (4.3BSD-tahoe/man/2)
[unix-history] / usr / src / usr.bin / telnet / utilities.c
CommitLineData
897ce52e
KB
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
b36fc510
KB
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.
897ce52e
KB
16 */
17
18#ifndef lint
6d0564c5 19static char sccsid[] = "@(#)utilities.c 1.10 (Berkeley) %G%";
897ce52e
KB
20#endif /* not lint */
21
788caa15
GM
22#define TELOPTS
23#include <arpa/telnet.h>
115a5494 24#include <sys/types.h>
788caa15
GM
25
26#include <ctype.h>
27
2dde2af0
GM
28#include "general.h"
29
6d0564c5
GM
30#include "fdset.h"
31
115a5494
GM
32#include "ring.h"
33
cf9305fa
GM
34#include "defines.h"
35
788caa15
GM
36#include "externs.h"
37
38FILE *NetTrace = 0; /* Not in bss, since needs to stay */
39
40/*
41 * upcase()
42 *
43 * Upcase (in place) the argument.
44 */
45
46void
47upcase(argument)
48register 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
66int
67SetSockOpt(fd, level, option, yesno)
68int
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\f
87/*
88 * The following are routines used to print out debugging information.
89 */
90
91
92void
93Dump(direction, buffer, length)
94char direction;
95char *buffer;
96int 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*/
126void
127printoption(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
155void
156printsub(direction, pointer, length)
157char *direction, /* "<" or ">" */
158 *pointer; /* where suboption data sits */
159int 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 {
448f9c06 170 char tmpbuf[SUBBUFSIZE];
788caa15
GM
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,
80a47e22
GM
183 "- unknown qualifier %d (0x%x).\n",
184 pointer[1], pointer[1]);
788caa15
GM
185 }
186 break;
187 default:
188 fprintf(NetTrace, "Unknown option %d (0x%x)\n",
189 pointer[0], pointer[0]);
190 }
191 }
192}
cf9305fa
GM
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
199void
200EmptyTerminal()
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
226void
227SetForExit()
228{
229 setconnmode();
230#if defined(TN3270)
231 if (In3270) {
232 Finish3270();
233 }
6da40c06
GM
234#else /* defined(TN3270) */
235 do {
236 telrcv(); /* Process any incoming data */
237 EmptyTerminal();
238 } while (ring_full_count(&netiring)); /* While there is any */
cf9305fa
GM
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
253void
254Exit(returnCode)
255int returnCode;
256{
257 SetForExit();
258 exit(returnCode);
259}
260
261void
262ExitString(string, returnCode)
263char *string;
264int returnCode;
265{
266 SetForExit();
267 fwrite(string, 1, strlen(string), stderr);
268 exit(returnCode);
269}
270
271#if defined(MSDOS)
272void
273ExitPerror(string, returnCode)
274char *string;
275int returnCode;
276{
277 SetForExit();
278 perror(string);
279 exit(returnCode);
280}
281#endif /* defined(MSDOS) */