2
* Copyright (c) 1988 Regents of the University of California.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. All advertising materials mentioning features or use of this software
14
* must display the following acknowledgement:
15
* This product includes software developed by the University of
16
* California, Berkeley and its contributors.
17
* 4. Neither the name of the University nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
21
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
* From: @(#)utilities.c 5.3 (Berkeley) 3/22/91
38
"$Id: utilities.cc,v 1.19 1999/12/12 15:33:40 dholland Exp $";
44
#include <arpa/telnet.h>
45
#include <sys/types.h>
47
#include <sys/socket.h>
57
FILE *NetTrace = 0; /* Not in bss, since needs to stay */ /* ? */
58
char NetTraceFile[256] = "(standard output)";
63
* Upcase (in place) the argument.
65
void upcase(char *str) {
66
for (int i=0; str[i]; i++) {
67
if (islower(str[i])) str[i] = toupper(str[i]);
72
* The following are routines used to print out debugging information.
75
void SetNetTrace(const char *file) {
76
if (NetTrace && NetTrace != stdout)
78
if (file && strcmp(file, "-")) {
79
NetTrace = fopen(file, "w");
81
strcpy((char *)NetTraceFile, file);
84
fprintf(stderr, "Cannot open %s.\n", file);
87
strcpy((char *)NetTraceFile, "(standard output)");
90
#define BYTES_PER_LINE 32
91
#define min(x,y) ((x<y)? x:y)
93
void Dump(int direction, char *buffer, int length) {
101
fprintf(NetTrace, "%c 0x%x\t", direction, offset);
103
if (0 /*prettydump*/) {
104
buffer = buffer + min(length, BYTES_PER_LINE/2);
105
while (pThis < buffer) {
106
fprintf(NetTrace, "%c%.2x",
107
(((*pThis)&0xff) == 0xff) ? '*' : ' ',
111
length -= BYTES_PER_LINE/2;
112
offset += BYTES_PER_LINE/2;
115
buffer = buffer + min(length, BYTES_PER_LINE);
116
while (pThis < buffer) {
117
fprintf(NetTrace, "%.2x", (*pThis)&0xff);
120
length -= BYTES_PER_LINE;
121
offset += BYTES_PER_LINE;
123
if (NetTrace == stdout) {
124
fprintf(NetTrace, "\r\n");
127
fprintf(NetTrace, "\n");
133
/* find next unique line */
139
void printoption(const char *direction, int cmd, int option) {
143
if (TELCMD_OK(option))
144
fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
146
fprintf(NetTrace, "%s IAC %d", direction, option);
150
fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
151
(cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
153
fprintf(NetTrace, "%s %s ", direction, fmt);
154
if (TELOPT_OK(option))
155
fprintf(NetTrace, "%s", TELOPT(option));
156
else if (option == TELOPT_EXOPL)
157
fprintf(NetTrace, "EXOPL");
159
fprintf(NetTrace, "%d", option);
162
fprintf(NetTrace, "%s %d %d", direction, cmd, option);
164
if (NetTrace == stdout)
165
fprintf(NetTrace, "\r\n");
167
fprintf(NetTrace, "\n");
171
void optionstatus(void) {
173
extern char will_wont_resp[], do_dont_resp[];
175
for (i = 0; i < 256; i++) {
176
if (do_dont_resp[i]) {
178
printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
179
else if (TELCMD_OK(i))
180
printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
182
printf("resp DO_DONT %d: %d\n", i, do_dont_resp[i]);
183
if (my_want_state_is_do(i)) {
185
printf("want DO %s\n", TELOPT(i));
186
else if (TELCMD_OK(i))
187
printf("want DO %s\n", TELCMD(i));
189
printf("want DO %d\n", i);
193
printf("want DONT %s\n", TELOPT(i));
194
else if (TELCMD_OK(i))
195
printf("want DONT %s\n", TELCMD(i));
197
printf("want DONT %d\n", i);
201
if (my_state_is_do(i)) {
203
printf(" DO %s\n", TELOPT(i));
204
else if (TELCMD_OK(i))
205
printf(" DO %s\n", TELCMD(i));
207
printf(" DO %d\n", i);
210
if (will_wont_resp[i]) {
212
printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
213
else if (TELCMD_OK(i))
214
printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
216
printf("resp WILL_WONT %d: %d\n",
217
i, will_wont_resp[i]);
218
if (my_want_state_is_will(i)) {
220
printf("want WILL %s\n", TELOPT(i));
221
else if (TELCMD_OK(i))
222
printf("want WILL %s\n", TELCMD(i));
224
printf("want WILL %d\n", i);
228
printf("want WONT %s\n", TELOPT(i));
229
else if (TELCMD_OK(i))
230
printf("want WONT %s\n", TELCMD(i));
232
printf("want WONT %d\n", i);
236
if (my_state_is_will(i)) {
238
printf(" WILL %s\n", TELOPT(i));
239
else if (TELCMD_OK(i))
240
printf(" WILL %s\n", TELCMD(i));
242
printf(" WILL %d\n", i);
249
/* direction: '<' or '>' */
250
/* pointer: where suboption data sits */
251
/* length: length of suboption data */
252
void printsub(int direction, unsigned char *pointer, int length) {
255
extern int want_status_response;
257
if (showoptions || direction == 0 ||
258
(want_status_response && (pointer[0] == TELOPT_STATUS))) {
260
fprintf(NetTrace, "%s IAC SB ",
261
(direction == '<')? "RCVD":"SENT");
265
i = pointer[length-2];
266
j = pointer[length-1];
268
if (i != IAC || j != SE) {
269
fprintf(NetTrace, "(terminated by ");
271
fprintf(NetTrace, "%s ", TELOPT(i));
272
else if (TELCMD_OK(i))
273
fprintf(NetTrace, "%s ", TELCMD(i));
275
fprintf(NetTrace, "%d ", i);
277
fprintf(NetTrace, "%s", TELOPT(j));
278
else if (TELCMD_OK(j))
279
fprintf(NetTrace, "%s", TELCMD(j));
281
fprintf(NetTrace, "%d", j);
282
fprintf(NetTrace, ", not IAC SE!) ");
288
fprintf(NetTrace, "(Empty suboption???)");
291
switch ((unsigned char)(pointer[0])) {
293
fprintf(NetTrace, "TERMINAL-TYPE ");
294
switch (pointer[1]) {
296
fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
299
fprintf(NetTrace, "SEND");
303
"- unknown qualifier %d (0x%x).",
304
pointer[1], pointer[1]);
308
fprintf(NetTrace, "TERMINAL-SPEED");
310
fprintf(NetTrace, " (empty suboption???)");
313
switch (pointer[1]) {
315
fprintf(NetTrace, " IS ");
316
fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
320
fprintf(NetTrace, " SEND");
322
fprintf(NetTrace, " %d (unknown)", pointer[1]);
323
for (i = 2; i < length; i++)
324
fprintf(NetTrace, " ?%d?", pointer[i]);
330
fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
332
fprintf(NetTrace, " (empty suboption???)");
335
switch (pointer[1]) {
337
fprintf(NetTrace, " OFF"); break;
339
fprintf(NetTrace, " ON"); break;
341
fprintf(NetTrace, " %d (unknown)", pointer[1]);
343
for (i = 2; i < length; i++)
344
fprintf(NetTrace, " ?%d?", pointer[i]);
348
fprintf(NetTrace, "NAWS");
350
fprintf(NetTrace, " (empty suboption???)");
354
fprintf(NetTrace, " ?%d?", pointer[1]);
357
fprintf(NetTrace, " %d %d (%d)",
358
pointer[1], pointer[2],
359
(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
361
fprintf(NetTrace, " ?%d?", pointer[3]);
364
fprintf(NetTrace, " %d %d (%d)",
365
pointer[3], pointer[4],
366
(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
367
for (i = 5; i < length; i++)
368
fprintf(NetTrace, " ?%d?", pointer[i]);
371
case TELOPT_LINEMODE:
372
fprintf(NetTrace, "LINEMODE ");
374
fprintf(NetTrace, " (empty suboption???)");
377
switch ((unsigned char)(pointer[1])) {
379
fprintf(NetTrace, "WILL ");
382
fprintf(NetTrace, "WONT ");
385
fprintf(NetTrace, "DO ");
388
fprintf(NetTrace, "DONT ");
391
fprintf(NetTrace, "(no option???)");
394
switch ((unsigned char)(pointer[2])) {
396
fprintf(NetTrace, "Forward Mask");
397
for (i = 3; i < length; i++)
398
fprintf(NetTrace, " %x", pointer[i]);
401
fprintf(NetTrace, "%d (unknown)", pointer[2]);
402
for (i = 3; i < length; i++)
403
fprintf(NetTrace, " %d", pointer[i]);
409
fprintf(NetTrace, "SLC");
410
for (i = 2; i < length - 2; i += 3) {
411
if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
412
fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
414
fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
415
switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
417
fprintf(NetTrace, " NOSUPPORT"); break;
419
fprintf(NetTrace, " CANTCHANGE"); break;
421
fprintf(NetTrace, " VARIABLE"); break;
423
fprintf(NetTrace, " DEFAULT"); break;
425
fprintf(NetTrace, "%s%s%s",
426
pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
427
pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
428
pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
429
if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
430
SLC_FLUSHOUT| SLC_LEVELBITS))
431
fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
432
fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
433
if ((pointer[i+SLC_VALUE] == IAC) &&
434
(pointer[i+SLC_VALUE+1] == IAC))
437
for (; i < length; i++)
438
fprintf(NetTrace, " ?%d?", pointer[i]);
442
fprintf(NetTrace, "MODE ");
444
fprintf(NetTrace, "(no mode???)");
449
snprintf(tbuf, sizeof(tbuf), "%s%s%s%s%s",
450
pointer[2]&MODE_EDIT ? "|EDIT" : "",
451
pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
452
pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
453
pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
454
pointer[2]&MODE_ACK ? "|ACK" : "");
455
fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
457
if (pointer[2]&~(MODE_MASK))
458
fprintf(NetTrace, " (0x%x)", pointer[2]);
459
for (i = 3; i < length; i++)
460
fprintf(NetTrace, " ?0x%x?", pointer[i]);
463
fprintf(NetTrace, "%d (unknown)", pointer[1]);
464
for (i = 2; i < length; i++)
465
fprintf(NetTrace, " %d", pointer[i]);
469
case TELOPT_STATUS: {
473
fprintf(NetTrace, "STATUS");
475
switch (pointer[1]) {
477
if (pointer[1] == TELQUAL_SEND)
478
fprintf(NetTrace, " SEND");
480
fprintf(NetTrace, " %d (unknown)", pointer[1]);
481
for (i = 2; i < length; i++)
482
fprintf(NetTrace, " ?%d?", pointer[i]);
485
if (--want_status_response < 0)
486
want_status_response = 0;
487
if (NetTrace == stdout)
488
fprintf(NetTrace, " IS\r\n");
490
fprintf(NetTrace, " IS\n");
492
for (i = 2; i < length; i++) {
493
switch((unsigned char)(pointer[i])) {
494
case DO: cp = "DO"; goto common2;
495
case DONT: cp = "DONT"; goto common2;
496
case WILL: cp = "WILL"; goto common2;
497
case WONT: cp = "WONT"; goto common2;
500
if (TELOPT_OK((int)pointer[i]))
501
fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
503
fprintf(NetTrace, " %s %d", cp, pointer[i]);
505
if (NetTrace == stdout)
506
fprintf(NetTrace, "\r\n");
508
fprintf(NetTrace, "\n");
512
fprintf(NetTrace, " SB ");
516
if (pointer[j] == SE) {
519
if (pointer[j+1] == SE)
524
pointer[k++] = pointer[j++];
526
printsub(0, &pointer[i], k - i);
528
fprintf(NetTrace, " SE");
533
if (NetTrace == stdout)
534
fprintf(NetTrace, "\r\n");
536
fprintf(NetTrace, "\n");
541
fprintf(NetTrace, " %d", pointer[i]);
550
case TELOPT_XDISPLOC:
551
fprintf(NetTrace, "X-DISPLAY-LOCATION ");
552
switch (pointer[1]) {
554
fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
557
fprintf(NetTrace, "SEND");
560
fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
561
pointer[1], pointer[1]);
566
fprintf(NetTrace, "ENVIRON ");
567
switch (pointer[1]) {
569
fprintf(NetTrace, "IS ");
572
fprintf(NetTrace, "SEND ");
575
fprintf(NetTrace, "INFO ");
578
register int noquote = 2;
579
for (i = 2; i < length; i++ ) {
580
switch (pointer[i]) {
582
if (pointer[1] == TELQUAL_SEND)
584
fprintf(NetTrace, "\" VAR " + noquote);
589
fprintf(NetTrace, "\" VALUE " + noquote);
594
fprintf(NetTrace, "\" ESC " + noquote);
600
if (isprint(pointer[i]) && pointer[i] != '"') {
605
putc(pointer[i], NetTrace);
607
fprintf(NetTrace, "\" %03o " + noquote,
622
if (TELOPT_OK(pointer[0]))
623
fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
625
fprintf(NetTrace, "%d (unknown)", pointer[i]);
626
for (i = 1; i < length; i++)
627
fprintf(NetTrace, " %d", pointer[i]);
631
if (NetTrace == stdout)
632
fprintf(NetTrace, "\r\n");
634
fprintf(NetTrace, "\n");
639
void SetForExit(void) {
645
#else /* defined(TN3270) */
647
telrcv(); /* Process any incoming data */
649
} while (netiring.full_count()); /* While there is any */
650
#endif /* defined(TN3270) */
658
#endif /* defined(TN3270) */
660
EmptyTerminal(); /* Flush the path to the tty */
664
void Exit(int returnCode) {
669
void ExitString(const char *string, int returnCode) {
671
fwrite(string, 1, strlen(string), stderr);