|
|
1.1 root 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 provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)utilities.c 1.19 (Berkeley) 6/28/90";
22: #endif /* not lint */
23:
24: #define TELOPTS
25: #define TELCMDS
26: #include <arpa/telnet.h>
27: #include <sys/types.h>
28: #include <sys/time.h>
29:
30: #include <ctype.h>
31:
32: #include "general.h"
33:
34: #include "fdset.h"
35:
36: #include "ring.h"
37:
38: #include "defines.h"
39:
40: #include "externs.h"
41:
42: FILE *NetTrace = 0; /* Not in bss, since needs to stay */
43: int prettydump;
44:
45: /*
46: * upcase()
47: *
48: * Upcase (in place) the argument.
49: */
50:
51: void
52: upcase(argument)
53: register char *argument;
54: {
55: register int c;
56:
57: while ((c = *argument) != 0) {
58: if (islower(c)) {
59: *argument = toupper(c);
60: }
61: argument++;
62: }
63: }
64:
65: /*
66: * SetSockOpt()
67: *
68: * Compensate for differences in 4.2 and 4.3 systems.
69: */
70:
71: int
72: SetSockOpt(fd, level, option, yesno)
73: int
74: fd,
75: level,
76: option,
77: yesno;
78: {
79: #ifndef NOT43
80: return setsockopt(fd, level, option,
81: (char *)&yesno, sizeof yesno);
82: #else /* NOT43 */
83: if (yesno == 0) { /* Can't do that in 4.2! */
84: fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
85: option);
86: return -1;
87: }
88: return setsockopt(fd, level, option, 0, 0);
89: #endif /* NOT43 */
90: }
91:
92: /*
93: * The following are routines used to print out debugging information.
94: */
95:
96: unsigned char NetTraceFile[256] = "(standard output)";
97:
98: void
99: SetNetTrace(file)
100: register char *file;
101: {
102: if (NetTrace && NetTrace != stdout)
103: fclose(NetTrace);
104: if (file && (strcmp(file, "-") != 0)) {
105: NetTrace = fopen(file, "w");
106: if (NetTrace) {
107: strcpy(NetTraceFile, file);
108: return;
109: }
110: fprintf(stderr, "Cannot open %s.\n", file);
111: }
112: NetTrace = stdout;
113: strcpy(NetTraceFile, "(standard output)");
114: }
115:
116: void
117: Dump(direction, buffer, length)
118: char direction;
119: char *buffer;
120: int length;
121: {
122: # define BYTES_PER_LINE 32
123: # define min(x,y) ((x<y)? x:y)
124: char *pThis;
125: int offset;
126: extern pettydump;
127:
128: offset = 0;
129:
130: while (length) {
131: /* print one line */
132: fprintf(NetTrace, "%c 0x%x\t", direction, offset);
133: pThis = buffer;
134: if (prettydump) {
135: buffer = buffer + min(length, BYTES_PER_LINE/2);
136: while (pThis < buffer) {
137: fprintf(NetTrace, "%c%.2x",
138: (((*pThis)&0xff) == 0xff) ? '*' : ' ',
139: (*pThis)&0xff);
140: pThis++;
141: }
142: length -= BYTES_PER_LINE/2;
143: offset += BYTES_PER_LINE/2;
144: } else {
145: buffer = buffer + min(length, BYTES_PER_LINE);
146: while (pThis < buffer) {
147: fprintf(NetTrace, "%.2x", (*pThis)&0xff);
148: pThis++;
149: }
150: length -= BYTES_PER_LINE;
151: offset += BYTES_PER_LINE;
152: }
153: if (NetTrace == stdout) {
154: fprintf(NetTrace, "\r\n");
155: } else {
156: fprintf(NetTrace, "\n");
157: }
158: if (length < 0) {
159: fflush(NetTrace);
160: return;
161: }
162: /* find next unique line */
163: }
164: fflush(NetTrace);
165: }
166:
167:
168: void
169: printoption(direction, fmt, option)
170: char *direction, *fmt;
171: int option;
172: {
173: if (!showoptions)
174: return;
175: fprintf(NetTrace, "%s ", direction);
176: if (TELOPT_OK(option))
177: fprintf(NetTrace, "%s %s", fmt, TELOPT(option));
178: else if (TELCMD_OK(option))
179: fprintf(NetTrace, "%s %s", fmt, TELCMD(option));
180: else
181: fprintf(NetTrace, "%s %d", fmt, option);
182: if (NetTrace == stdout)
183: fprintf(NetTrace, "\r\n");
184: else
185: fprintf(NetTrace, "\n");
186: return;
187: }
188:
189: optionstatus()
190: {
191: register int i;
192: extern char will_wont_resp[], do_dont_resp[];
193:
194: for (i = 0; i < 256; i++) {
195: if (do_dont_resp[i]) {
196: if (TELOPT_OK(i))
197: printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
198: else if (TELCMD_OK(i))
199: printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
200: else
201: printf("resp DO_DONT %d: %d\n", i,
202: do_dont_resp[i]);
203: if (my_want_state_is_do(i)) {
204: if (TELOPT_OK(i))
205: printf("want DO %s\n", TELOPT(i));
206: else if (TELCMD_OK(i))
207: printf("want DO %s\n", TELCMD(i));
208: else
209: printf("want DO %d\n", i);
210: } else {
211: if (TELOPT_OK(i))
212: printf("want DONT %s\n", TELOPT(i));
213: else if (TELCMD_OK(i))
214: printf("want DONT %s\n", TELCMD(i));
215: else
216: printf("want DONT %d\n", i);
217: }
218: } else {
219: if (my_state_is_do(i)) {
220: if (TELOPT_OK(i))
221: printf(" DO %s\n", TELOPT(i));
222: else if (TELCMD_OK(i))
223: printf(" DO %s\n", TELCMD(i));
224: else
225: printf(" DO %d\n", i);
226: }
227: }
228: if (will_wont_resp[i]) {
229: if (TELOPT_OK(i))
230: printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
231: else if (TELCMD_OK(i))
232: printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
233: else
234: printf("resp WILL_WONT %d: %d\n",
235: i, will_wont_resp[i]);
236: if (my_want_state_is_will(i)) {
237: if (TELOPT_OK(i))
238: printf("want WILL %s\n", TELOPT(i));
239: else if (TELCMD_OK(i))
240: printf("want WILL %s\n", TELCMD(i));
241: else
242: printf("want WILL %d\n", i);
243: } else {
244: if (TELOPT_OK(i))
245: printf("want WONT %s\n", TELOPT(i));
246: else if (TELCMD_OK(i))
247: printf("want WONT %s\n", TELCMD(i));
248: else
249: printf("want WONT %d\n", i);
250: }
251: } else {
252: if (my_state_is_will(i)) {
253: if (TELOPT_OK(i))
254: printf(" WILL %s\n", TELOPT(i));
255: else if (TELCMD_OK(i))
256: printf(" WILL %s\n", TELCMD(i));
257: else
258: printf(" WILL %d\n", i);
259: }
260: }
261: }
262:
263: }
264:
265: char *slcnames[] = { SLC_NAMES };
266:
267: #ifdef KERBEROS
268: static char *authtypes[3] = { "NONE", "PRIVATE", "KERBEROS" };
269: #endif
270:
271: void
272: printsub(direction, pointer, length)
273: char direction; /* '<' or '>' */
274: unsigned char *pointer; /* where suboption data sits */
275: int length; /* length of suboption data */
276: {
277: register int i;
278:
279: if (showoptions) {
280: if (direction) {
281: fprintf(NetTrace, "%s suboption ",
282: (direction == '<')? "Received":"Sent");
283: if (length >= 3) {
284: register int j;
285:
286: i = pointer[length-2];
287: j = pointer[length-1];
288:
289: if (i != IAC || j != SE) {
290: fprintf(NetTrace, "(terminated by ");
291: if (TELOPT_OK(i))
292: fprintf(NetTrace, "%s ", TELOPT(i));
293: else if (TELCMD_OK(i))
294: fprintf(NetTrace, "%s ", TELCMD(i));
295: else
296: fprintf(NetTrace, "%d ", i);
297: if (TELOPT_OK(j))
298: fprintf(NetTrace, "%s", TELOPT(j));
299: else if (TELCMD_OK(j))
300: fprintf(NetTrace, "%s", TELCMD(j));
301: else
302: fprintf(NetTrace, "%d", j);
303: fprintf(NetTrace, ", not IAC SE!) ");
304: }
305: }
306: length -= 2;
307: }
308: if (length < 1) {
309: fprintf(NetTrace, "(Empty suboption???)");
310: return;
311: }
312: switch (pointer[0]) {
313: case TELOPT_TTYPE:
314: fprintf(NetTrace, "TERMINAL-TYPE ");
315: switch (pointer[1]) {
316: case TELQUAL_IS:
317: fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
318: break;
319: case TELQUAL_SEND:
320: fprintf(NetTrace, "SEND");
321: break;
322: default:
323: fprintf(NetTrace,
324: "- unknown qualifier %d (0x%x).",
325: pointer[1], pointer[1]);
326: }
327: break;
328: case TELOPT_TSPEED:
329: fprintf(NetTrace, "TERMINAL-SPEED");
330: if (length < 2) {
331: fprintf(NetTrace, " (empty suboption???)");
332: break;
333: }
334: switch (pointer[1]) {
335: case TELQUAL_IS:
336: fprintf(NetTrace, " IS ");
337: fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
338: break;
339: default:
340: if (pointer[1] == 1)
341: fprintf(NetTrace, " SEND");
342: else
343: fprintf(NetTrace, " %d (unknown)", pointer[1]);
344: for (i = 2; i < length; i++)
345: fprintf(NetTrace, " ?%d?", pointer[i]);
346: break;
347: }
348: break;
349:
350: case TELOPT_LFLOW:
351: fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
352: if (length < 2) {
353: fprintf(NetTrace, " (empty suboption???)");
354: break;
355: }
356: switch (pointer[1]) {
357: case 0:
358: fprintf(NetTrace, " OFF"); break;
359: case 1:
360: fprintf(NetTrace, " ON"); break;
361: default:
362: fprintf(NetTrace, " %d (unknown)", pointer[1]);
363: }
364: for (i = 2; i < length; i++)
365: fprintf(NetTrace, " ?%d?", pointer[i]);
366: break;
367:
368: case TELOPT_NAWS:
369: fprintf(NetTrace, "NAWS");
370: if (length < 2) {
371: fprintf(NetTrace, " (empty suboption???)");
372: break;
373: }
374: if (length == 2) {
375: fprintf(NetTrace, " ?%d?", pointer[1]);
376: break;
377: }
378: fprintf(NetTrace, " %d %d (%d)",
379: pointer[1], pointer[2],
380: (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
381: if (length == 4) {
382: fprintf(NetTrace, " ?%d?", pointer[3]);
383: break;
384: }
385: fprintf(NetTrace, " %d %d (%d)",
386: pointer[3], pointer[4],
387: (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
388: for (i = 5; i < length; i++)
389: fprintf(NetTrace, " ?%d?", pointer[i]);
390: break;
391:
392: #ifdef KERBEROS
393: case TELOPT_AUTHENTICATION:
394: fprintf(NetTrace, "Authentication information ");
395: switch (pointer[1]) {
396: case TELQUAL_IS:
397: switch (pointer[2]) {
398: case TELQUAL_AUTHTYPE_NONE:
399: case TELQUAL_AUTHTYPE_PRIVATE:
400: case TELQUAL_AUTHTYPE_KERBEROS:
401:
402: fprintf(NetTrace, "is type %s\r\n", authtypes[pointer[2]]);
403: break;
404: default:
405: fprintf(NetTrace, "is type unknown\r\n");
406: break;
407: }
408:
409: case TELQUAL_SEND:
410: {
411: int idx = 2;
412: fprintf(NetTrace, "- request to send, types");
413: for (idx = 2; idx < length - 1; idx++)
414: switch (pointer[idx]) {
415: case TELQUAL_AUTHTYPE_NONE:
416: case TELQUAL_AUTHTYPE_PRIVATE:
417: case TELQUAL_AUTHTYPE_KERBEROS:
418: fprintf(NetTrace, " %s",
419: authtypes[pointer[idx]]);
420: break;
421: default:
422: fprintf(NetTrace, " <unknown %u>",
423: pointer[idx]);
424: break;
425: }
426: fprintf(NetTrace, "\r\n");
427: }
428: break;
429:
430: default:
431: fprintf(NetTrace, " - unknown qualifier %d (0x%x).\r\n",
432: pointer[1], pointer[1]);
433: }
434: break;
435: #endif /* KERBEROS */
436:
437: case TELOPT_LINEMODE:
438: fprintf(NetTrace, "LINEMODE ");
439: if (length < 2) {
440: fprintf(NetTrace, " (empty suboption???)");
441: break;
442: }
443: switch (pointer[1]) {
444: case WILL:
445: fprintf(NetTrace, "WILL ");
446: goto common;
447: case WONT:
448: fprintf(NetTrace, "WONT ");
449: goto common;
450: case DO:
451: fprintf(NetTrace, "DO ");
452: goto common;
453: case DONT:
454: fprintf(NetTrace, "DONT ");
455: common:
456: if (length < 3) {
457: fprintf(NetTrace, "(no option???)");
458: break;
459: }
460: switch (pointer[2]) {
461: case LM_FORWARDMASK:
462: fprintf(NetTrace, "Forward Mask");
463: for (i = 3; i < length; i++)
464: fprintf(NetTrace, " %x", pointer[i]);
465: break;
466: default:
467: fprintf(NetTrace, "%d (unknown)", pointer[2]);
468: for (i = 3; i < length; i++)
469: fprintf(NetTrace, " %d", pointer[i]);
470: break;
471: }
472: break;
473:
474: case LM_SLC:
475: fprintf(NetTrace, "SLC");
476: for (i = 2; i < length - 2; i += 3) {
477: if (pointer[i+SLC_FUNC] <= NSLC)
478: fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]);
479: else
480: fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
481: switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
482: case SLC_NOSUPPORT:
483: fprintf(NetTrace, " NOSUPPORT"); break;
484: case SLC_CANTCHANGE:
485: fprintf(NetTrace, " CANTCHANGE"); break;
486: case SLC_VARIABLE:
487: fprintf(NetTrace, " VARIABLE"); break;
488: case SLC_DEFAULT:
489: fprintf(NetTrace, " DEFAULT"); break;
490: }
491: fprintf(NetTrace, "%s%s%s",
492: pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
493: pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
494: pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
495: if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
496: SLC_FLUSHOUT| SLC_LEVELBITS))
497: fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
498: fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
499: if ((pointer[i+SLC_VALUE] == IAC) &&
500: (pointer[i+SLC_VALUE+1] == IAC))
501: i++;
502: }
503: for (; i < length; i++)
504: fprintf(NetTrace, " ?%d?", pointer[i]);
505: break;
506:
507: case LM_MODE:
508: fprintf(NetTrace, "MODE ");
509: if (length < 3) {
510: fprintf(NetTrace, "(no mode???)");
511: break;
512: }
513: {
514: char tbuf[64];
515: sprintf(tbuf, "%s%s%s%s%s",
516: pointer[2]&MODE_EDIT ? "|EDIT" : "",
517: pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
518: pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
519: pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
520: pointer[2]&MODE_ACK ? "|ACK" : "");
521: fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
522: }
523: if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK))
524: fprintf(NetTrace, " (0x%x)", pointer[2]);
525: for (i = 3; i < length; i++)
526: fprintf(NetTrace, " ?0x%x?", pointer[i]);
527: break;
528: default:
529: fprintf(NetTrace, "%d (unknown)", pointer[1]);
530: for (i = 2; i < length; i++)
531: fprintf(NetTrace, " %d", pointer[i]);
532: }
533: break;
534:
535: case TELOPT_STATUS: {
536: register char *cp;
537: register int j, k;
538:
539: fprintf(NetTrace, "STATUS");
540:
541: switch (pointer[1]) {
542: default:
543: if (pointer[1] == TELQUAL_SEND)
544: fprintf(NetTrace, " SEND");
545: else
546: fprintf(NetTrace, " %d (unknown)", pointer[1]);
547: for (i = 2; i < length; i++)
548: fprintf(NetTrace, " ?%d?", pointer[i]);
549: break;
550: case TELQUAL_IS:
551: if (NetTrace == stdout)
552: fprintf(NetTrace, " IS\r\n");
553: else
554: fprintf(NetTrace, " IS\n");
555:
556: for (i = 2; i < length; i++) {
557: switch(pointer[i]) {
558: case DO: cp = "DO"; goto common2;
559: case DONT: cp = "DONT"; goto common2;
560: case WILL: cp = "WILL"; goto common2;
561: case WONT: cp = "WONT"; goto common2;
562: common2:
563: i++;
564: if (TELOPT_OK((int)pointer[i]))
565: fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
566: else
567: fprintf(NetTrace, " %s %d", cp, pointer[i]);
568:
569: if (NetTrace == stdout)
570: fprintf(NetTrace, "\r\n");
571: else
572: fprintf(NetTrace, "\n");
573: break;
574:
575: case SB:
576: fprintf(NetTrace, " SB ");
577: i++;
578: j = k = i;
579: while (j < length) {
580: if (pointer[j] == SE) {
581: if (j+1 == length)
582: break;
583: if (pointer[j+1] == SE)
584: j++;
585: else
586: break;
587: }
588: pointer[k++] = pointer[j++];
589: }
590: printsub(0, &pointer[i], k - i);
591: if (i < length) {
592: fprintf(NetTrace, " SE");
593: i = j;
594: } else
595: i = j - 1;
596:
597: if (NetTrace == stdout)
598: fprintf(NetTrace, "\r\n");
599: else
600: fprintf(NetTrace, "\n");
601:
602: break;
603:
604: default:
605: fprintf(NetTrace, " %d", pointer[i]);
606: break;
607: }
608: }
609: break;
610: }
611: break;
612: }
613:
614: case TELOPT_XDISPLOC:
615: fprintf(NetTrace, "X-DISPLAY-LOCATION ");
616: switch (pointer[1]) {
617: case TELQUAL_IS:
618: fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
619: break;
620: case TELQUAL_SEND:
621: fprintf(NetTrace, "SEND");
622: break;
623: default:
624: fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
625: pointer[1], pointer[1]);
626: }
627: break;
628:
629: case TELOPT_ENVIRON:
630: fprintf(NetTrace, "ENVIRON ");
631: switch (pointer[1]) {
632: case TELQUAL_IS:
633: fprintf(NetTrace, "IS ");
634: goto env_common;
635: case TELQUAL_SEND:
636: fprintf(NetTrace, "SEND ");
637: goto env_common;
638: case TELQUAL_INFO:
639: fprintf(NetTrace, "INFO ");
640: env_common:
641: {
642: register int noquote = 2;
643: for (i = 2; i < length; i++ ) {
644: switch (pointer[i]) {
645: case ENV_VAR:
646: if (pointer[1] == TELQUAL_SEND)
647: goto def_case;
648: fprintf(NetTrace, "\" VAR " + noquote);
649: noquote = 2;
650: break;
651:
652: case ENV_VALUE:
653: fprintf(NetTrace, "\" VALUE " + noquote);
654: noquote = 2;
655: break;
656:
657: case ENV_ESC:
658: fprintf(NetTrace, "\" ESC " + noquote);
659: noquote = 2;
660: break;
661:
662: default:
663: def_case:
664: if (isprint(pointer[i]) && pointer[i] != '"') {
665: if (noquote) {
666: putc('"', NetTrace);
667: noquote = 0;
668: }
669: putc(pointer[i], NetTrace);
670: } else {
671: fprintf(NetTrace, "\" %03o " + noquote,
672: pointer[i]);
673: noquote = 2;
674: }
675: break;
676: }
677: }
678: if (!noquote)
679: putc('"', NetTrace);
680: break;
681: }
682: }
683: break;
684:
685: default:
686: fprintf(NetTrace, "Unknown option ");
687: for (i = 0; i < length; i++)
688: fprintf(NetTrace, " %d", pointer[i]);
689: break;
690: }
691: if (direction) {
692: if (NetTrace == stdout)
693: fprintf(NetTrace, "\r\n");
694: else
695: fprintf(NetTrace, "\n");
696: }
697: }
698: }
699:
700: /* EmptyTerminal - called to make sure that the terminal buffer is empty.
701: * Note that we consider the buffer to run all the
702: * way to the kernel (thus the select).
703: */
704:
705: void
706: EmptyTerminal()
707: {
708: #if defined(unix)
709: fd_set o;
710:
711: FD_ZERO(&o);
712: #endif /* defined(unix) */
713:
714: if (TTYBYTES() == 0) {
715: #if defined(unix)
716: FD_SET(tout, &o);
717: (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
718: (struct timeval *) 0); /* wait for TTLOWAT */
719: #endif /* defined(unix) */
720: } else {
721: while (TTYBYTES()) {
722: (void) ttyflush(0);
723: #if defined(unix)
724: FD_SET(tout, &o);
725: (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
726: (struct timeval *) 0); /* wait for TTLOWAT */
727: #endif /* defined(unix) */
728: }
729: }
730: }
731:
732: void
733: SetForExit()
734: {
735: setconnmode(0);
736: #if defined(TN3270)
737: if (In3270) {
738: Finish3270();
739: }
740: #else /* defined(TN3270) */
741: do {
742: (void)telrcv(); /* Process any incoming data */
743: EmptyTerminal();
744: } while (ring_full_count(&netiring)); /* While there is any */
745: #endif /* defined(TN3270) */
746: setcommandmode();
747: fflush(stdout);
748: fflush(stderr);
749: #if defined(TN3270)
750: if (In3270) {
751: StopScreen(1);
752: }
753: #endif /* defined(TN3270) */
754: setconnmode(0);
755: EmptyTerminal(); /* Flush the path to the tty */
756: setcommandmode();
757: }
758:
759: void
760: Exit(returnCode)
761: int returnCode;
762: {
763: SetForExit();
764: exit(returnCode);
765: }
766:
767: void
768: ExitString(string, returnCode)
769: char *string;
770: int returnCode;
771: {
772: SetForExit();
773: fwrite(string, 1, strlen(string), stderr);
774: exit(returnCode);
775: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.