Annotation of src/usr.bin/telnet/utilities.c, Revision 1.4
1.4 ! jason 1: /* $OpenBSD: utilities.c,v 1.3 1996/12/12 11:24:08 robin Exp $ */
1.2 niklas 2: /* $NetBSD: utilities.c,v 1.5 1996/02/28 21:04:21 thorpej Exp $ */
3:
1.1 deraadt 4: /*
5: * Copyright (c) 1988, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
1.2 niklas 38: #if 0
39: static char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 5/30/95";
40: static char rcsid[] = "$NetBSD: utilities.c,v 1.5 1996/02/28 21:04:21 thorpej Exp $";
41: #else
1.4 ! jason 42: static char rcsid[] = "$OpenBSD: utilities.c,v 1.3 1996/12/12 11:24:08 robin Exp $";
1.2 niklas 43: #endif
1.1 deraadt 44: #endif /* not lint */
45:
46: #define TELOPTS
47: #define TELCMDS
48: #define SLC_NAMES
49: #include <arpa/telnet.h>
50: #include <sys/types.h>
51: #include <sys/time.h>
1.3 robin 52: #include <sys/socket.h>
53: #include <unistd.h>
1.1 deraadt 54: #include <ctype.h>
55:
56: #include "general.h"
57:
58: #include "fdset.h"
59:
60: #include "ring.h"
61:
62: #include "defines.h"
63:
64: #include "externs.h"
65:
66: FILE *NetTrace = 0; /* Not in bss, since needs to stay */
67: int prettydump;
68:
69: /*
70: * upcase()
71: *
72: * Upcase (in place) the argument.
73: */
74:
75: void
76: upcase(argument)
77: register char *argument;
78: {
79: register int c;
80:
81: while ((c = *argument) != 0) {
82: if (islower(c)) {
83: *argument = toupper(c);
84: }
85: argument++;
86: }
87: }
88:
89: /*
90: * SetSockOpt()
91: *
92: * Compensate for differences in 4.2 and 4.3 systems.
93: */
94:
95: int
96: SetSockOpt(fd, level, option, yesno)
97: int fd, level, option, yesno;
98: {
99: #ifndef NOT43
100: return setsockopt(fd, level, option,
101: (char *)&yesno, sizeof yesno);
102: #else /* NOT43 */
103: if (yesno == 0) { /* Can't do that in 4.2! */
104: fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
105: option);
106: return -1;
107: }
108: return setsockopt(fd, level, option, 0, 0);
109: #endif /* NOT43 */
110: }
111:
112: /*
113: * The following are routines used to print out debugging information.
114: */
115:
116: unsigned char NetTraceFile[256] = "(standard output)";
117:
118: void
119: SetNetTrace(file)
120: register char *file;
121: {
122: if (NetTrace && NetTrace != stdout)
123: fclose(NetTrace);
124: if (file && (strcmp(file, "-") != 0)) {
125: NetTrace = fopen(file, "w");
126: if (NetTrace) {
127: strcpy((char *)NetTraceFile, file);
128: return;
129: }
130: fprintf(stderr, "Cannot open %s.\n", file);
131: }
132: NetTrace = stdout;
133: strcpy((char *)NetTraceFile, "(standard output)");
134: }
135:
136: void
137: Dump(direction, buffer, length)
138: char direction;
139: unsigned char *buffer;
140: int length;
141: {
142: # define BYTES_PER_LINE 32
143: # define min(x,y) ((x<y)? x:y)
144: unsigned char *pThis;
145: int offset;
146:
147: offset = 0;
148:
149: while (length) {
150: /* print one line */
151: fprintf(NetTrace, "%c 0x%x\t", direction, offset);
152: pThis = buffer;
153: if (prettydump) {
154: buffer = buffer + min(length, BYTES_PER_LINE/2);
155: while (pThis < buffer) {
156: fprintf(NetTrace, "%c%.2x",
157: (((*pThis)&0xff) == 0xff) ? '*' : ' ',
158: (*pThis)&0xff);
159: pThis++;
160: }
161: length -= BYTES_PER_LINE/2;
162: offset += BYTES_PER_LINE/2;
163: } else {
164: buffer = buffer + min(length, BYTES_PER_LINE);
165: while (pThis < buffer) {
166: fprintf(NetTrace, "%.2x", (*pThis)&0xff);
167: pThis++;
168: }
169: length -= BYTES_PER_LINE;
170: offset += BYTES_PER_LINE;
171: }
172: if (NetTrace == stdout) {
173: fprintf(NetTrace, "\r\n");
174: } else {
175: fprintf(NetTrace, "\n");
176: }
177: if (length < 0) {
178: fflush(NetTrace);
179: return;
180: }
181: /* find next unique line */
182: }
183: fflush(NetTrace);
184: }
185:
186:
187: void
188: printoption(direction, cmd, option)
189: char *direction;
190: int cmd, option;
191: {
192: if (!showoptions)
193: return;
194: if (cmd == IAC) {
195: if (TELCMD_OK(option))
196: fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
197: else
198: fprintf(NetTrace, "%s IAC %d", direction, option);
199: } else {
200: register char *fmt;
201: fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
202: (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
203: if (fmt) {
204: fprintf(NetTrace, "%s %s ", direction, fmt);
205: if (TELOPT_OK(option))
206: fprintf(NetTrace, "%s", TELOPT(option));
207: else if (option == TELOPT_EXOPL)
208: fprintf(NetTrace, "EXOPL");
209: else
210: fprintf(NetTrace, "%d", option);
211: } else
212: fprintf(NetTrace, "%s %d %d", direction, cmd, option);
213: }
214: if (NetTrace == stdout) {
215: fprintf(NetTrace, "\r\n");
216: fflush(NetTrace);
217: } else {
218: fprintf(NetTrace, "\n");
219: }
220: return;
221: }
222:
223: void
224: optionstatus()
225: {
226: register int i;
227: extern char will_wont_resp[], do_dont_resp[];
228:
229: for (i = 0; i < 256; i++) {
230: if (do_dont_resp[i]) {
231: if (TELOPT_OK(i))
232: printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
233: else if (TELCMD_OK(i))
234: printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
235: else
236: printf("resp DO_DONT %d: %d\n", i,
237: do_dont_resp[i]);
238: if (my_want_state_is_do(i)) {
239: if (TELOPT_OK(i))
240: printf("want DO %s\n", TELOPT(i));
241: else if (TELCMD_OK(i))
242: printf("want DO %s\n", TELCMD(i));
243: else
244: printf("want DO %d\n", i);
245: } else {
246: if (TELOPT_OK(i))
247: printf("want DONT %s\n", TELOPT(i));
248: else if (TELCMD_OK(i))
249: printf("want DONT %s\n", TELCMD(i));
250: else
251: printf("want DONT %d\n", i);
252: }
253: } else {
254: if (my_state_is_do(i)) {
255: if (TELOPT_OK(i))
256: printf(" DO %s\n", TELOPT(i));
257: else if (TELCMD_OK(i))
258: printf(" DO %s\n", TELCMD(i));
259: else
260: printf(" DO %d\n", i);
261: }
262: }
263: if (will_wont_resp[i]) {
264: if (TELOPT_OK(i))
265: printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
266: else if (TELCMD_OK(i))
267: printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
268: else
269: printf("resp WILL_WONT %d: %d\n",
270: i, will_wont_resp[i]);
271: if (my_want_state_is_will(i)) {
272: if (TELOPT_OK(i))
273: printf("want WILL %s\n", TELOPT(i));
274: else if (TELCMD_OK(i))
275: printf("want WILL %s\n", TELCMD(i));
276: else
277: printf("want WILL %d\n", i);
278: } else {
279: if (TELOPT_OK(i))
280: printf("want WONT %s\n", TELOPT(i));
281: else if (TELCMD_OK(i))
282: printf("want WONT %s\n", TELCMD(i));
283: else
284: printf("want WONT %d\n", i);
285: }
286: } else {
287: if (my_state_is_will(i)) {
288: if (TELOPT_OK(i))
289: printf(" WILL %s\n", TELOPT(i));
290: else if (TELCMD_OK(i))
291: printf(" WILL %s\n", TELCMD(i));
292: else
293: printf(" WILL %d\n", i);
294: }
295: }
296: }
297:
298: }
299:
300: void
301: printsub(direction, pointer, length)
302: char direction; /* '<' or '>' */
303: unsigned char *pointer; /* where suboption data sits */
304: int length; /* length of suboption data */
305: {
306: register int i;
1.4 ! jason 307: char buf[512];
1.1 deraadt 308: extern int want_status_response;
309:
310: if (showoptions || direction == 0 ||
311: (want_status_response && (pointer[0] == TELOPT_STATUS))) {
312: if (direction) {
313: fprintf(NetTrace, "%s IAC SB ",
314: (direction == '<')? "RCVD":"SENT");
315: if (length >= 3) {
316: register int j;
317:
318: i = pointer[length-2];
319: j = pointer[length-1];
320:
321: if (i != IAC || j != SE) {
322: fprintf(NetTrace, "(terminated by ");
323: if (TELOPT_OK(i))
324: fprintf(NetTrace, "%s ", TELOPT(i));
325: else if (TELCMD_OK(i))
326: fprintf(NetTrace, "%s ", TELCMD(i));
327: else
328: fprintf(NetTrace, "%d ", i);
329: if (TELOPT_OK(j))
330: fprintf(NetTrace, "%s", TELOPT(j));
331: else if (TELCMD_OK(j))
332: fprintf(NetTrace, "%s", TELCMD(j));
333: else
334: fprintf(NetTrace, "%d", j);
335: fprintf(NetTrace, ", not IAC SE!) ");
336: }
337: }
338: length -= 2;
339: }
340: if (length < 1) {
341: fprintf(NetTrace, "(Empty suboption??\?)");
342: if (NetTrace == stdout)
343: fflush(NetTrace);
344: return;
345: }
346: switch (pointer[0]) {
347: case TELOPT_TTYPE:
348: fprintf(NetTrace, "TERMINAL-TYPE ");
349: switch (pointer[1]) {
350: case TELQUAL_IS:
351: fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
352: break;
353: case TELQUAL_SEND:
354: fprintf(NetTrace, "SEND");
355: break;
356: default:
357: fprintf(NetTrace,
358: "- unknown qualifier %d (0x%x).",
359: pointer[1], pointer[1]);
360: }
361: break;
362: case TELOPT_TSPEED:
363: fprintf(NetTrace, "TERMINAL-SPEED");
364: if (length < 2) {
365: fprintf(NetTrace, " (empty suboption??\?)");
366: break;
367: }
368: switch (pointer[1]) {
369: case TELQUAL_IS:
370: fprintf(NetTrace, " IS ");
371: fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
372: break;
373: default:
374: if (pointer[1] == 1)
375: fprintf(NetTrace, " SEND");
376: else
377: fprintf(NetTrace, " %d (unknown)", pointer[1]);
378: for (i = 2; i < length; i++)
379: fprintf(NetTrace, " ?%d?", pointer[i]);
380: break;
381: }
382: break;
383:
384: case TELOPT_LFLOW:
385: fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
386: if (length < 2) {
387: fprintf(NetTrace, " (empty suboption??\?)");
388: break;
389: }
390: switch (pointer[1]) {
391: case LFLOW_OFF:
392: fprintf(NetTrace, " OFF"); break;
393: case LFLOW_ON:
394: fprintf(NetTrace, " ON"); break;
395: case LFLOW_RESTART_ANY:
396: fprintf(NetTrace, " RESTART-ANY"); break;
397: case LFLOW_RESTART_XON:
398: fprintf(NetTrace, " RESTART-XON"); break;
399: default:
400: fprintf(NetTrace, " %d (unknown)", pointer[1]);
401: }
402: for (i = 2; i < length; i++)
403: fprintf(NetTrace, " ?%d?", pointer[i]);
404: break;
405:
406: case TELOPT_NAWS:
407: fprintf(NetTrace, "NAWS");
408: if (length < 2) {
409: fprintf(NetTrace, " (empty suboption??\?)");
410: break;
411: }
412: if (length == 2) {
413: fprintf(NetTrace, " ?%d?", pointer[1]);
414: break;
415: }
416: fprintf(NetTrace, " %d %d (%d)",
417: pointer[1], pointer[2],
418: (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
419: if (length == 4) {
420: fprintf(NetTrace, " ?%d?", pointer[3]);
421: break;
422: }
423: fprintf(NetTrace, " %d %d (%d)",
424: pointer[3], pointer[4],
425: (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
426: for (i = 5; i < length; i++)
427: fprintf(NetTrace, " ?%d?", pointer[i]);
428: break;
429:
430: #if defined(AUTHENTICATION)
431: case TELOPT_AUTHENTICATION:
432: fprintf(NetTrace, "AUTHENTICATION");
433: if (length < 2) {
434: fprintf(NetTrace, " (empty suboption??\?)");
435: break;
436: }
437: switch (pointer[1]) {
438: case TELQUAL_REPLY:
439: case TELQUAL_IS:
440: fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
441: "IS" : "REPLY");
442: if (AUTHTYPE_NAME_OK(pointer[2]))
443: fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
444: else
445: fprintf(NetTrace, "%d ", pointer[2]);
446: if (length < 3) {
447: fprintf(NetTrace, "(partial suboption??\?)");
448: break;
449: }
450: fprintf(NetTrace, "%s|%s",
451: ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
452: "CLIENT" : "SERVER",
453: ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
454: "MUTUAL" : "ONE-WAY");
455:
456: auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
457: fprintf(NetTrace, "%s", buf);
458: break;
459:
460: case TELQUAL_SEND:
461: i = 2;
462: fprintf(NetTrace, " SEND ");
463: while (i < length) {
464: if (AUTHTYPE_NAME_OK(pointer[i]))
465: fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
466: else
467: fprintf(NetTrace, "%d ", pointer[i]);
468: if (++i >= length) {
469: fprintf(NetTrace, "(partial suboption??\?)");
470: break;
471: }
472: fprintf(NetTrace, "%s|%s ",
473: ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
474: "CLIENT" : "SERVER",
475: ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
476: "MUTUAL" : "ONE-WAY");
477: ++i;
478: }
479: break;
480:
481: case TELQUAL_NAME:
482: i = 2;
483: fprintf(NetTrace, " NAME \"");
484: while (i < length)
485: putc(pointer[i++], NetTrace);
486: putc('"', NetTrace);
487: break;
488:
489: default:
490: for (i = 2; i < length; i++)
491: fprintf(NetTrace, " ?%d?", pointer[i]);
492: break;
493: }
494: break;
495: #endif
496:
497:
498: case TELOPT_LINEMODE:
499: fprintf(NetTrace, "LINEMODE ");
500: if (length < 2) {
501: fprintf(NetTrace, " (empty suboption??\?)");
502: break;
503: }
504: switch (pointer[1]) {
505: case WILL:
506: fprintf(NetTrace, "WILL ");
507: goto common;
508: case WONT:
509: fprintf(NetTrace, "WONT ");
510: goto common;
511: case DO:
512: fprintf(NetTrace, "DO ");
513: goto common;
514: case DONT:
515: fprintf(NetTrace, "DONT ");
516: common:
517: if (length < 3) {
518: fprintf(NetTrace, "(no option??\?)");
519: break;
520: }
521: switch (pointer[2]) {
522: case LM_FORWARDMASK:
523: fprintf(NetTrace, "Forward Mask");
524: for (i = 3; i < length; i++)
525: fprintf(NetTrace, " %x", pointer[i]);
526: break;
527: default:
528: fprintf(NetTrace, "%d (unknown)", pointer[2]);
529: for (i = 3; i < length; i++)
530: fprintf(NetTrace, " %d", pointer[i]);
531: break;
532: }
533: break;
1.2 niklas 534:
1.1 deraadt 535: case LM_SLC:
536: fprintf(NetTrace, "SLC");
537: for (i = 2; i < length - 2; i += 3) {
538: if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
539: fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
540: else
541: fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
542: switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
543: case SLC_NOSUPPORT:
544: fprintf(NetTrace, " NOSUPPORT"); break;
545: case SLC_CANTCHANGE:
546: fprintf(NetTrace, " CANTCHANGE"); break;
547: case SLC_VARIABLE:
548: fprintf(NetTrace, " VARIABLE"); break;
549: case SLC_DEFAULT:
550: fprintf(NetTrace, " DEFAULT"); break;
551: }
552: fprintf(NetTrace, "%s%s%s",
553: pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
554: pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
555: pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
556: if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
557: SLC_FLUSHOUT| SLC_LEVELBITS))
558: fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
559: fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
560: if ((pointer[i+SLC_VALUE] == IAC) &&
561: (pointer[i+SLC_VALUE+1] == IAC))
562: i++;
563: }
564: for (; i < length; i++)
565: fprintf(NetTrace, " ?%d?", pointer[i]);
566: break;
567:
568: case LM_MODE:
569: fprintf(NetTrace, "MODE ");
570: if (length < 3) {
571: fprintf(NetTrace, "(no mode??\?)");
572: break;
573: }
574: {
575: char tbuf[64];
576: sprintf(tbuf, "%s%s%s%s%s",
577: pointer[2]&MODE_EDIT ? "|EDIT" : "",
578: pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
579: pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
580: pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
581: pointer[2]&MODE_ACK ? "|ACK" : "");
582: fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
583: }
584: if (pointer[2]&~(MODE_MASK))
585: fprintf(NetTrace, " (0x%x)", pointer[2]);
586: for (i = 3; i < length; i++)
587: fprintf(NetTrace, " ?0x%x?", pointer[i]);
588: break;
589: default:
590: fprintf(NetTrace, "%d (unknown)", pointer[1]);
591: for (i = 2; i < length; i++)
592: fprintf(NetTrace, " %d", pointer[i]);
593: }
594: break;
595:
596: case TELOPT_STATUS: {
597: register char *cp;
598: register int j, k;
599:
600: fprintf(NetTrace, "STATUS");
601:
602: switch (pointer[1]) {
603: default:
604: if (pointer[1] == TELQUAL_SEND)
605: fprintf(NetTrace, " SEND");
606: else
607: fprintf(NetTrace, " %d (unknown)", pointer[1]);
608: for (i = 2; i < length; i++)
609: fprintf(NetTrace, " ?%d?", pointer[i]);
610: break;
611: case TELQUAL_IS:
612: if (--want_status_response < 0)
613: want_status_response = 0;
614: if (NetTrace == stdout)
615: fprintf(NetTrace, " IS\r\n");
616: else
617: fprintf(NetTrace, " IS\n");
618:
619: for (i = 2; i < length; i++) {
620: switch(pointer[i]) {
621: case DO: cp = "DO"; goto common2;
622: case DONT: cp = "DONT"; goto common2;
623: case WILL: cp = "WILL"; goto common2;
624: case WONT: cp = "WONT"; goto common2;
625: common2:
626: i++;
627: if (TELOPT_OK((int)pointer[i]))
628: fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
629: else
630: fprintf(NetTrace, " %s %d", cp, pointer[i]);
631:
632: if (NetTrace == stdout)
633: fprintf(NetTrace, "\r\n");
634: else
635: fprintf(NetTrace, "\n");
636: break;
637:
638: case SB:
639: fprintf(NetTrace, " SB ");
640: i++;
641: j = k = i;
642: while (j < length) {
643: if (pointer[j] == SE) {
644: if (j+1 == length)
645: break;
646: if (pointer[j+1] == SE)
647: j++;
648: else
649: break;
650: }
651: pointer[k++] = pointer[j++];
652: }
653: printsub(0, &pointer[i], k - i);
654: if (i < length) {
655: fprintf(NetTrace, " SE");
656: i = j;
657: } else
658: i = j - 1;
659:
660: if (NetTrace == stdout)
661: fprintf(NetTrace, "\r\n");
662: else
663: fprintf(NetTrace, "\n");
664:
665: break;
1.2 niklas 666:
1.1 deraadt 667: default:
668: fprintf(NetTrace, " %d", pointer[i]);
669: break;
670: }
671: }
672: break;
673: }
674: break;
675: }
676:
677: case TELOPT_XDISPLOC:
678: fprintf(NetTrace, "X-DISPLAY-LOCATION ");
679: switch (pointer[1]) {
680: case TELQUAL_IS:
681: fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
682: break;
683: case TELQUAL_SEND:
684: fprintf(NetTrace, "SEND");
685: break;
686: default:
687: fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
688: pointer[1], pointer[1]);
689: }
690: break;
691:
692: case TELOPT_NEW_ENVIRON:
693: fprintf(NetTrace, "NEW-ENVIRON ");
694: #ifdef OLD_ENVIRON
695: goto env_common1;
696: case TELOPT_OLD_ENVIRON:
697: fprintf(NetTrace, "OLD-ENVIRON");
698: env_common1:
699: #endif
700: switch (pointer[1]) {
701: case TELQUAL_IS:
702: fprintf(NetTrace, "IS ");
703: goto env_common;
704: case TELQUAL_SEND:
705: fprintf(NetTrace, "SEND ");
706: goto env_common;
707: case TELQUAL_INFO:
708: fprintf(NetTrace, "INFO ");
709: env_common:
710: {
711: register int noquote = 2;
712: #if defined(ENV_HACK) && defined(OLD_ENVIRON)
713: extern int old_env_var, old_env_value;
714: #endif
715: for (i = 2; i < length; i++ ) {
716: switch (pointer[i]) {
717: case NEW_ENV_VALUE:
718: #ifdef OLD_ENVIRON
719: /* case NEW_ENV_OVAR: */
720: if (pointer[0] == TELOPT_OLD_ENVIRON) {
721: # ifdef ENV_HACK
722: if (old_env_var == OLD_ENV_VALUE)
723: fprintf(NetTrace, "\" (VALUE) " + noquote);
724: else
725: # endif
726: fprintf(NetTrace, "\" VAR " + noquote);
727: } else
728: #endif /* OLD_ENVIRON */
729: fprintf(NetTrace, "\" VALUE " + noquote);
730: noquote = 2;
731: break;
732:
733: case NEW_ENV_VAR:
734: #ifdef OLD_ENVIRON
735: /* case OLD_ENV_VALUE: */
736: if (pointer[0] == TELOPT_OLD_ENVIRON) {
737: # ifdef ENV_HACK
738: if (old_env_value == OLD_ENV_VAR)
739: fprintf(NetTrace, "\" (VAR) " + noquote);
740: else
741: # endif
742: fprintf(NetTrace, "\" VALUE " + noquote);
743: } else
744: #endif /* OLD_ENVIRON */
745: fprintf(NetTrace, "\" VAR " + noquote);
746: noquote = 2;
747: break;
748:
749: case ENV_ESC:
750: fprintf(NetTrace, "\" ESC " + noquote);
751: noquote = 2;
752: break;
753:
754: case ENV_USERVAR:
755: fprintf(NetTrace, "\" USERVAR " + noquote);
756: noquote = 2;
757: break;
758:
759: default:
760: if (isprint(pointer[i]) && pointer[i] != '"') {
761: if (noquote) {
762: putc('"', NetTrace);
763: noquote = 0;
764: }
765: putc(pointer[i], NetTrace);
766: } else {
767: fprintf(NetTrace, "\" %03o " + noquote,
768: pointer[i]);
769: noquote = 2;
770: }
771: break;
772: }
773: }
774: if (!noquote)
775: putc('"', NetTrace);
776: break;
777: }
778: }
779: break;
780:
781: default:
782: if (TELOPT_OK(pointer[0]))
783: fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
784: else
785: fprintf(NetTrace, "%d (unknown)", pointer[0]);
786: for (i = 1; i < length; i++)
787: fprintf(NetTrace, " %d", pointer[i]);
788: break;
789: }
790: if (direction) {
791: if (NetTrace == stdout)
792: fprintf(NetTrace, "\r\n");
793: else
794: fprintf(NetTrace, "\n");
795: }
796: if (NetTrace == stdout)
797: fflush(NetTrace);
798: }
799: }
800:
801: /* EmptyTerminal - called to make sure that the terminal buffer is empty.
802: * Note that we consider the buffer to run all the
803: * way to the kernel (thus the select).
804: */
805:
806: void
807: EmptyTerminal()
808: {
809: #if defined(unix)
810: fd_set o;
811:
812: FD_ZERO(&o);
813: #endif /* defined(unix) */
814:
815: if (TTYBYTES() == 0) {
816: #if defined(unix)
817: FD_SET(tout, &o);
818: (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
819: (struct timeval *) 0); /* wait for TTLOWAT */
820: #endif /* defined(unix) */
821: } else {
822: while (TTYBYTES()) {
823: (void) ttyflush(0);
824: #if defined(unix)
825: FD_SET(tout, &o);
826: (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
827: (struct timeval *) 0); /* wait for TTLOWAT */
828: #endif /* defined(unix) */
829: }
830: }
831: }
832:
833: void
834: SetForExit()
835: {
836: setconnmode(0);
837: #if defined(TN3270)
838: if (In3270) {
839: Finish3270();
840: }
841: #else /* defined(TN3270) */
842: do {
843: (void)telrcv(); /* Process any incoming data */
844: EmptyTerminal();
845: } while (ring_full_count(&netiring)); /* While there is any */
846: #endif /* defined(TN3270) */
847: setcommandmode();
848: fflush(stdout);
849: fflush(stderr);
850: #if defined(TN3270)
851: if (In3270) {
852: StopScreen(1);
853: }
854: #endif /* defined(TN3270) */
855: setconnmode(0);
856: EmptyTerminal(); /* Flush the path to the tty */
857: setcommandmode();
858: }
859:
860: void
861: Exit(returnCode)
862: int returnCode;
863: {
864: SetForExit();
865: exit(returnCode);
866: }
867:
868: void
869: ExitString(string, returnCode)
870: char *string;
871: int returnCode;
872: {
873: SetForExit();
874: fwrite(string, 1, strlen(string), stderr);
875: exit(returnCode);
876: }