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