133686Sbostic /*
262313Sbostic * Copyright (c) 1988, 1993
362313Sbostic * The Regents of the University of California. All rights reserved.
433686Sbostic *
544361Sborman * %sccs.include.redist.c%
633686Sbostic */
733686Sbostic
833686Sbostic #ifndef lint
9*69785Sdab static char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 05/30/95";
1033686Sbostic #endif /* not lint */
1133686Sbostic
1232149Sminshall #define TELOPTS
1338690Sborman #define TELCMDS
1446808Sdab #define SLC_NAMES
1532149Sminshall #include <arpa/telnet.h>
1632381Sminshall #include <sys/types.h>
1744361Sborman #include <sys/time.h>
1832149Sminshall
1932149Sminshall #include <ctype.h>
2032149Sminshall
2134305Sminshall #include "general.h"
2234305Sminshall
2336280Sminshall #include "fdset.h"
2436280Sminshall
2532381Sminshall #include "ring.h"
2632381Sminshall
2736278Sminshall #include "defines.h"
2836278Sminshall
2932149Sminshall #include "externs.h"
3032149Sminshall
3132149Sminshall FILE *NetTrace = 0; /* Not in bss, since needs to stay */
3238690Sborman int prettydump;
3332149Sminshall
3432149Sminshall /*
3532149Sminshall * upcase()
3632149Sminshall *
3732149Sminshall * Upcase (in place) the argument.
3832149Sminshall */
3932149Sminshall
4046808Sdab void
upcase(argument)4132149Sminshall upcase(argument)
4246808Sdab register char *argument;
4332149Sminshall {
4432149Sminshall register int c;
4532149Sminshall
4632149Sminshall while ((c = *argument) != 0) {
4732149Sminshall if (islower(c)) {
4832149Sminshall *argument = toupper(c);
4932149Sminshall }
5032149Sminshall argument++;
5132149Sminshall }
5232149Sminshall }
5332149Sminshall
5432149Sminshall /*
5532149Sminshall * SetSockOpt()
5632149Sminshall *
5732149Sminshall * Compensate for differences in 4.2 and 4.3 systems.
5832149Sminshall */
5932149Sminshall
6046808Sdab int
SetSockOpt(fd,level,option,yesno)6132149Sminshall SetSockOpt(fd, level, option, yesno)
6246808Sdab int fd, level, option, yesno;
6332149Sminshall {
6432149Sminshall #ifndef NOT43
6532149Sminshall return setsockopt(fd, level, option,
6632149Sminshall (char *)&yesno, sizeof yesno);
6732149Sminshall #else /* NOT43 */
6832149Sminshall if (yesno == 0) { /* Can't do that in 4.2! */
6932149Sminshall fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
7032149Sminshall option);
7132149Sminshall return -1;
7232149Sminshall }
7332149Sminshall return setsockopt(fd, level, option, 0, 0);
7432149Sminshall #endif /* NOT43 */
7532149Sminshall }
7632149Sminshall
7732149Sminshall /*
7832149Sminshall * The following are routines used to print out debugging information.
7932149Sminshall */
8032149Sminshall
8139529Sborman unsigned char NetTraceFile[256] = "(standard output)";
8232149Sminshall
8346808Sdab void
SetNetTrace(file)8438690Sborman SetNetTrace(file)
8546808Sdab register char *file;
8638690Sborman {
8738690Sborman if (NetTrace && NetTrace != stdout)
8838690Sborman fclose(NetTrace);
8938690Sborman if (file && (strcmp(file, "-") != 0)) {
9038690Sborman NetTrace = fopen(file, "w");
9138690Sborman if (NetTrace) {
9246808Sdab strcpy((char *)NetTraceFile, file);
9338690Sborman return;
9438690Sborman }
9538690Sborman fprintf(stderr, "Cannot open %s.\n", file);
9638690Sborman }
9738690Sborman NetTrace = stdout;
9846808Sdab strcpy((char *)NetTraceFile, "(standard output)");
9938690Sborman }
10038690Sborman
10146808Sdab void
Dump(direction,buffer,length)10232149Sminshall Dump(direction, buffer, length)
10346808Sdab char direction;
10446808Sdab unsigned char *buffer;
10546808Sdab int length;
10632149Sminshall {
10732149Sminshall # define BYTES_PER_LINE 32
10832149Sminshall # define min(x,y) ((x<y)? x:y)
10946808Sdab unsigned char *pThis;
11032149Sminshall int offset;
11138690Sborman extern pettydump;
11232149Sminshall
11332149Sminshall offset = 0;
11432149Sminshall
11532149Sminshall while (length) {
11632149Sminshall /* print one line */
11732149Sminshall fprintf(NetTrace, "%c 0x%x\t", direction, offset);
11832149Sminshall pThis = buffer;
11938690Sborman if (prettydump) {
12038909Sborman buffer = buffer + min(length, BYTES_PER_LINE/2);
12138690Sborman while (pThis < buffer) {
12238690Sborman fprintf(NetTrace, "%c%.2x",
12338690Sborman (((*pThis)&0xff) == 0xff) ? '*' : ' ',
12438690Sborman (*pThis)&0xff);
12538690Sborman pThis++;
12638690Sborman }
12738909Sborman length -= BYTES_PER_LINE/2;
12838909Sborman offset += BYTES_PER_LINE/2;
12938690Sborman } else {
13038909Sborman buffer = buffer + min(length, BYTES_PER_LINE);
13138690Sborman while (pThis < buffer) {
13238690Sborman fprintf(NetTrace, "%.2x", (*pThis)&0xff);
13338690Sborman pThis++;
13438690Sborman }
13538909Sborman length -= BYTES_PER_LINE;
13638909Sborman offset += BYTES_PER_LINE;
13732149Sminshall }
13837226Sminshall if (NetTrace == stdout) {
13938207Sminshall fprintf(NetTrace, "\r\n");
14038207Sminshall } else {
14137226Sminshall fprintf(NetTrace, "\n");
14237226Sminshall }
14332149Sminshall if (length < 0) {
14436693Sminshall fflush(NetTrace);
14532149Sminshall return;
14632149Sminshall }
14732149Sminshall /* find next unique line */
14832149Sminshall }
14936693Sminshall fflush(NetTrace);
15032149Sminshall }
15132149Sminshall
15232149Sminshall
15346808Sdab void
printoption(direction,cmd,option)15446808Sdab printoption(direction, cmd, option)
15546808Sdab char *direction;
15646808Sdab int cmd, option;
15732149Sminshall {
15832149Sminshall if (!showoptions)
15932149Sminshall return;
16046808Sdab if (cmd == IAC) {
16146808Sdab if (TELCMD_OK(option))
16246808Sdab fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
16346808Sdab else
16446808Sdab fprintf(NetTrace, "%s IAC %d", direction, option);
16546808Sdab } else {
16646808Sdab register char *fmt;
16746808Sdab fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
16846808Sdab (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
16946808Sdab if (fmt) {
17046808Sdab fprintf(NetTrace, "%s %s ", direction, fmt);
17146808Sdab if (TELOPT_OK(option))
17246808Sdab fprintf(NetTrace, "%s", TELOPT(option));
17346808Sdab else if (option == TELOPT_EXOPL)
17446808Sdab fprintf(NetTrace, "EXOPL");
17546808Sdab else
17646808Sdab fprintf(NetTrace, "%d", option);
17746808Sdab } else
17846808Sdab fprintf(NetTrace, "%s %d %d", direction, cmd, option);
17946808Sdab }
18065157Sdab if (NetTrace == stdout) {
18137226Sminshall fprintf(NetTrace, "\r\n");
18265157Sdab fflush(NetTrace);
18365157Sdab } else {
18437226Sminshall fprintf(NetTrace, "\n");
18565157Sdab }
18637226Sminshall return;
18732149Sminshall }
18832149Sminshall
18946808Sdab void
optionstatus()19038690Sborman optionstatus()
19138690Sborman {
19238690Sborman register int i;
19338690Sborman extern char will_wont_resp[], do_dont_resp[];
19438690Sborman
19538690Sborman for (i = 0; i < 256; i++) {
19638690Sborman if (do_dont_resp[i]) {
19738690Sborman if (TELOPT_OK(i))
19838690Sborman printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
19938690Sborman else if (TELCMD_OK(i))
20038690Sborman printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
20138690Sborman else
20238690Sborman printf("resp DO_DONT %d: %d\n", i,
20338690Sborman do_dont_resp[i]);
20438690Sborman if (my_want_state_is_do(i)) {
20538690Sborman if (TELOPT_OK(i))
20638690Sborman printf("want DO %s\n", TELOPT(i));
20738690Sborman else if (TELCMD_OK(i))
20838690Sborman printf("want DO %s\n", TELCMD(i));
20938690Sborman else
21038690Sborman printf("want DO %d\n", i);
21138690Sborman } else {
21238690Sborman if (TELOPT_OK(i))
21338690Sborman printf("want DONT %s\n", TELOPT(i));
21438690Sborman else if (TELCMD_OK(i))
21538690Sborman printf("want DONT %s\n", TELCMD(i));
21638690Sborman else
21738690Sborman printf("want DONT %d\n", i);
21838690Sborman }
21938690Sborman } else {
22038690Sborman if (my_state_is_do(i)) {
22138690Sborman if (TELOPT_OK(i))
22238690Sborman printf(" DO %s\n", TELOPT(i));
22338690Sborman else if (TELCMD_OK(i))
22438690Sborman printf(" DO %s\n", TELCMD(i));
22538690Sborman else
22638690Sborman printf(" DO %d\n", i);
22738690Sborman }
22838690Sborman }
22938690Sborman if (will_wont_resp[i]) {
23038690Sborman if (TELOPT_OK(i))
23138690Sborman printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
23238690Sborman else if (TELCMD_OK(i))
23338690Sborman printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
23438690Sborman else
23538690Sborman printf("resp WILL_WONT %d: %d\n",
23638690Sborman i, will_wont_resp[i]);
23738690Sborman if (my_want_state_is_will(i)) {
23838690Sborman if (TELOPT_OK(i))
23938690Sborman printf("want WILL %s\n", TELOPT(i));
24038690Sborman else if (TELCMD_OK(i))
24138690Sborman printf("want WILL %s\n", TELCMD(i));
24238690Sborman else
24338690Sborman printf("want WILL %d\n", i);
24438690Sborman } else {
24538690Sborman if (TELOPT_OK(i))
24638690Sborman printf("want WONT %s\n", TELOPT(i));
24738690Sborman else if (TELCMD_OK(i))
24838690Sborman printf("want WONT %s\n", TELCMD(i));
24938690Sborman else
25038690Sborman printf("want WONT %d\n", i);
25138690Sborman }
25238690Sborman } else {
25338690Sborman if (my_state_is_will(i)) {
25438690Sborman if (TELOPT_OK(i))
25538690Sborman printf(" WILL %s\n", TELOPT(i));
25638690Sborman else if (TELCMD_OK(i))
25738690Sborman printf(" WILL %s\n", TELCMD(i));
25838690Sborman else
25938690Sborman printf(" WILL %d\n", i);
26038690Sborman }
26138690Sborman }
26238690Sborman }
26338690Sborman
26438690Sborman }
26538690Sborman
26646808Sdab void
printsub(direction,pointer,length)26732149Sminshall printsub(direction, pointer, length)
26846808Sdab char direction; /* '<' or '>' */
26946808Sdab unsigned char *pointer; /* where suboption data sits */
27046808Sdab int length; /* length of suboption data */
27132149Sminshall {
27238690Sborman register int i;
27347608Sdab char buf[512];
27446808Sdab extern int want_status_response;
27538690Sborman
27646808Sdab if (showoptions || direction == 0 ||
27746808Sdab (want_status_response && (pointer[0] == TELOPT_STATUS))) {
27838909Sborman if (direction) {
27946808Sdab fprintf(NetTrace, "%s IAC SB ",
28046808Sdab (direction == '<')? "RCVD":"SENT");
28138909Sborman if (length >= 3) {
28238909Sborman register int j;
28338690Sborman
28438909Sborman i = pointer[length-2];
28538909Sborman j = pointer[length-1];
28638690Sborman
28738909Sborman if (i != IAC || j != SE) {
28838909Sborman fprintf(NetTrace, "(terminated by ");
28938909Sborman if (TELOPT_OK(i))
29038909Sborman fprintf(NetTrace, "%s ", TELOPT(i));
29138909Sborman else if (TELCMD_OK(i))
29238909Sborman fprintf(NetTrace, "%s ", TELCMD(i));
29338909Sborman else
29438909Sborman fprintf(NetTrace, "%d ", i);
29538909Sborman if (TELOPT_OK(j))
29638909Sborman fprintf(NetTrace, "%s", TELOPT(j));
29738909Sborman else if (TELCMD_OK(j))
29838909Sborman fprintf(NetTrace, "%s", TELCMD(j));
29938909Sborman else
30038909Sborman fprintf(NetTrace, "%d", j);
30138909Sborman fprintf(NetTrace, ", not IAC SE!) ");
30238909Sborman }
30338690Sborman }
30438909Sborman length -= 2;
30538690Sborman }
30638690Sborman if (length < 1) {
30765157Sdab fprintf(NetTrace, "(Empty suboption??\?)");
30865157Sdab if (NetTrace == stdout)
30965157Sdab fflush(NetTrace);
31038690Sborman return;
31138690Sborman }
31232149Sminshall switch (pointer[0]) {
31332149Sminshall case TELOPT_TTYPE:
31438690Sborman fprintf(NetTrace, "TERMINAL-TYPE ");
31532149Sminshall switch (pointer[1]) {
31632149Sminshall case TELQUAL_IS:
31744361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
31832149Sminshall break;
31932149Sminshall case TELQUAL_SEND:
32038690Sborman fprintf(NetTrace, "SEND");
32132149Sminshall break;
32232149Sminshall default:
32332149Sminshall fprintf(NetTrace,
32438690Sborman "- unknown qualifier %d (0x%x).",
32534849Sminshall pointer[1], pointer[1]);
32632149Sminshall }
32732149Sminshall break;
32838690Sborman case TELOPT_TSPEED:
32938690Sborman fprintf(NetTrace, "TERMINAL-SPEED");
33038690Sborman if (length < 2) {
33165157Sdab fprintf(NetTrace, " (empty suboption??\?)");
33238690Sborman break;
33338690Sborman }
33438690Sborman switch (pointer[1]) {
33538909Sborman case TELQUAL_IS:
33638690Sborman fprintf(NetTrace, " IS ");
33744361Sborman fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
33838690Sborman break;
33938690Sborman default:
34038690Sborman if (pointer[1] == 1)
34138690Sborman fprintf(NetTrace, " SEND");
34238690Sborman else
34344361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]);
34438690Sborman for (i = 2; i < length; i++)
34538690Sborman fprintf(NetTrace, " ?%d?", pointer[i]);
34638690Sborman break;
34738690Sborman }
34838690Sborman break;
34938690Sborman
35038690Sborman case TELOPT_LFLOW:
35138690Sborman fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
35238690Sborman if (length < 2) {
35365157Sdab fprintf(NetTrace, " (empty suboption??\?)");
35438690Sborman break;
35538690Sborman }
35638690Sborman switch (pointer[1]) {
35757598Sdab case LFLOW_OFF:
35838690Sborman fprintf(NetTrace, " OFF"); break;
35957598Sdab case LFLOW_ON:
36038690Sborman fprintf(NetTrace, " ON"); break;
36157598Sdab case LFLOW_RESTART_ANY:
36257598Sdab fprintf(NetTrace, " RESTART-ANY"); break;
36357598Sdab case LFLOW_RESTART_XON:
36457598Sdab fprintf(NetTrace, " RESTART-XON"); break;
36538690Sborman default:
36644361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]);
36738690Sborman }
36838690Sborman for (i = 2; i < length; i++)
36938690Sborman fprintf(NetTrace, " ?%d?", pointer[i]);
37038690Sborman break;
37138690Sborman
37238690Sborman case TELOPT_NAWS:
37338690Sborman fprintf(NetTrace, "NAWS");
37438690Sborman if (length < 2) {
37565157Sdab fprintf(NetTrace, " (empty suboption??\?)");
37638690Sborman break;
37738690Sborman }
37838690Sborman if (length == 2) {
37938690Sborman fprintf(NetTrace, " ?%d?", pointer[1]);
38038690Sborman break;
38138690Sborman }
38238690Sborman fprintf(NetTrace, " %d %d (%d)",
38338690Sborman pointer[1], pointer[2],
38444361Sborman (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
38538690Sborman if (length == 4) {
38638690Sborman fprintf(NetTrace, " ?%d?", pointer[3]);
38738690Sborman break;
38838690Sborman }
38938690Sborman fprintf(NetTrace, " %d %d (%d)",
39038690Sborman pointer[3], pointer[4],
39144361Sborman (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
39238690Sborman for (i = 5; i < length; i++)
39338690Sborman fprintf(NetTrace, " ?%d?", pointer[i]);
39438690Sborman break;
39538690Sborman
39657213Sdab #if defined(AUTHENTICATION)
39743320Skfall case TELOPT_AUTHENTICATION:
39846808Sdab fprintf(NetTrace, "AUTHENTICATION");
39946808Sdab if (length < 2) {
40065157Sdab fprintf(NetTrace, " (empty suboption??\?)");
40146808Sdab break;
40246808Sdab }
40343320Skfall switch (pointer[1]) {
40446808Sdab case TELQUAL_REPLY:
40543320Skfall case TELQUAL_IS:
40646808Sdab fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
40746808Sdab "IS" : "REPLY");
40846808Sdab if (AUTHTYPE_NAME_OK(pointer[2]))
40946808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
41046808Sdab else
41146808Sdab fprintf(NetTrace, "%d ", pointer[2]);
41246808Sdab if (length < 3) {
41365157Sdab fprintf(NetTrace, "(partial suboption??\?)");
41446808Sdab break;
41546808Sdab }
41646808Sdab fprintf(NetTrace, "%s|%s",
41747608Sdab ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
41846808Sdab "CLIENT" : "SERVER",
41947608Sdab ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
42046808Sdab "MUTUAL" : "ONE-WAY");
42143320Skfall
42246808Sdab auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
42346808Sdab fprintf(NetTrace, "%s", buf);
42446808Sdab break;
42546808Sdab
42646808Sdab case TELQUAL_SEND:
42746808Sdab i = 2;
42846808Sdab fprintf(NetTrace, " SEND ");
42946808Sdab while (i < length) {
43046808Sdab if (AUTHTYPE_NAME_OK(pointer[i]))
43146808Sdab fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
43246808Sdab else
43346808Sdab fprintf(NetTrace, "%d ", pointer[i]);
43446808Sdab if (++i >= length) {
43565157Sdab fprintf(NetTrace, "(partial suboption??\?)");
43643320Skfall break;
43746808Sdab }
43846808Sdab fprintf(NetTrace, "%s|%s ",
43947608Sdab ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
44046808Sdab "CLIENT" : "SERVER",
44147608Sdab ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
44246808Sdab "MUTUAL" : "ONE-WAY");
44346808Sdab ++i;
44443320Skfall }
44546808Sdab break;
44643320Skfall
44747608Sdab case TELQUAL_NAME:
44847608Sdab i = 2;
44947608Sdab fprintf(NetTrace, " NAME \"");
45047608Sdab while (i < length)
45147608Sdab putc(pointer[i++], NetTrace);
45247608Sdab putc('"', NetTrace);
45347608Sdab break;
45447608Sdab
45546808Sdab default:
45646808Sdab for (i = 2; i < length; i++)
45746808Sdab fprintf(NetTrace, " ?%d?", pointer[i]);
45846808Sdab break;
45943320Skfall }
46046808Sdab break;
46146808Sdab #endif
46246808Sdab
46360149Sdab #ifdef ENCRYPTION
46446808Sdab case TELOPT_ENCRYPT:
46546808Sdab fprintf(NetTrace, "ENCRYPT");
46646808Sdab if (length < 2) {
46765157Sdab fprintf(NetTrace, " (empty suboption??\?)");
46843320Skfall break;
46946808Sdab }
47046808Sdab switch (pointer[1]) {
47146808Sdab case ENCRYPT_START:
47246808Sdab fprintf(NetTrace, " START");
47346808Sdab break;
47443320Skfall
47546808Sdab case ENCRYPT_END:
47646808Sdab fprintf(NetTrace, " END");
47746808Sdab break;
47846808Sdab
47946808Sdab case ENCRYPT_REQSTART:
48046808Sdab fprintf(NetTrace, " REQUEST-START");
48146808Sdab break;
48246808Sdab
48346808Sdab case ENCRYPT_REQEND:
48446808Sdab fprintf(NetTrace, " REQUEST-END");
48546808Sdab break;
48646808Sdab
48746808Sdab case ENCRYPT_IS:
48846808Sdab case ENCRYPT_REPLY:
48946808Sdab fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ?
49046808Sdab "IS" : "REPLY");
49146808Sdab if (length < 3) {
49265157Sdab fprintf(NetTrace, " (partial suboption??\?)");
49346808Sdab break;
49446808Sdab }
49546808Sdab if (ENCTYPE_NAME_OK(pointer[2]))
49646808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2]));
49746808Sdab else
49846808Sdab fprintf(NetTrace, " %d (unknown)", pointer[2]);
49946808Sdab
50046808Sdab encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
50146808Sdab fprintf(NetTrace, "%s", buf);
50246808Sdab break;
50346808Sdab
50446808Sdab case ENCRYPT_SUPPORT:
50546808Sdab i = 2;
50646808Sdab fprintf(NetTrace, " SUPPORT ");
50746808Sdab while (i < length) {
50846808Sdab if (ENCTYPE_NAME_OK(pointer[i]))
50946808Sdab fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i]));
51046808Sdab else
51146808Sdab fprintf(NetTrace, "%d ", pointer[i]);
51246808Sdab i++;
51346808Sdab }
51446808Sdab break;
51546808Sdab
51647608Sdab case ENCRYPT_ENC_KEYID:
51747608Sdab fprintf(NetTrace, " ENC_KEYID ");
51847608Sdab goto encommon;
51947608Sdab
52047608Sdab case ENCRYPT_DEC_KEYID:
52147608Sdab fprintf(NetTrace, " DEC_KEYID ");
52247608Sdab goto encommon;
52347608Sdab
52443320Skfall default:
52547608Sdab fprintf(NetTrace, " %d (unknown)", pointer[1]);
52647608Sdab encommon:
52746808Sdab for (i = 2; i < length; i++)
52846808Sdab fprintf(NetTrace, " %d", pointer[i]);
52946808Sdab break;
53043320Skfall }
53143320Skfall break;
53260149Sdab #endif /* ENCRYPTION */
53343320Skfall
53438690Sborman case TELOPT_LINEMODE:
53538690Sborman fprintf(NetTrace, "LINEMODE ");
53638690Sborman if (length < 2) {
53765157Sdab fprintf(NetTrace, " (empty suboption??\?)");
53838690Sborman break;
53938690Sborman }
54038690Sborman switch (pointer[1]) {
54138690Sborman case WILL:
54238690Sborman fprintf(NetTrace, "WILL ");
54338690Sborman goto common;
54438690Sborman case WONT:
54538690Sborman fprintf(NetTrace, "WONT ");
54638690Sborman goto common;
54738690Sborman case DO:
54838690Sborman fprintf(NetTrace, "DO ");
54938690Sborman goto common;
55038690Sborman case DONT:
55138690Sborman fprintf(NetTrace, "DONT ");
55238690Sborman common:
55338690Sborman if (length < 3) {
55465157Sdab fprintf(NetTrace, "(no option??\?)");
55538690Sborman break;
55638690Sborman }
55738690Sborman switch (pointer[2]) {
55838690Sborman case LM_FORWARDMASK:
55938690Sborman fprintf(NetTrace, "Forward Mask");
56038690Sborman for (i = 3; i < length; i++)
56138690Sborman fprintf(NetTrace, " %x", pointer[i]);
56238690Sborman break;
56338690Sborman default:
56438690Sborman fprintf(NetTrace, "%d (unknown)", pointer[2]);
56538690Sborman for (i = 3; i < length; i++)
56638690Sborman fprintf(NetTrace, " %d", pointer[i]);
56738690Sborman break;
56838690Sborman }
56938690Sborman break;
570*69785Sdab
57138690Sborman case LM_SLC:
57238690Sborman fprintf(NetTrace, "SLC");
57338690Sborman for (i = 2; i < length - 2; i += 3) {
57446808Sdab if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
57546808Sdab fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
57638690Sborman else
57738690Sborman fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
57838690Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
57938690Sborman case SLC_NOSUPPORT:
58038690Sborman fprintf(NetTrace, " NOSUPPORT"); break;
58138690Sborman case SLC_CANTCHANGE:
58238690Sborman fprintf(NetTrace, " CANTCHANGE"); break;
58338690Sborman case SLC_VARIABLE:
58438690Sborman fprintf(NetTrace, " VARIABLE"); break;
58538690Sborman case SLC_DEFAULT:
58638690Sborman fprintf(NetTrace, " DEFAULT"); break;
58738690Sborman }
58838690Sborman fprintf(NetTrace, "%s%s%s",
58938690Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
59038690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
59138690Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
59238690Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
59338690Sborman SLC_FLUSHOUT| SLC_LEVELBITS))
59438690Sborman fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
59538690Sborman fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
59644361Sborman if ((pointer[i+SLC_VALUE] == IAC) &&
59744361Sborman (pointer[i+SLC_VALUE+1] == IAC))
59844361Sborman i++;
59938690Sborman }
60038690Sborman for (; i < length; i++)
60138690Sborman fprintf(NetTrace, " ?%d?", pointer[i]);
60238690Sborman break;
60338690Sborman
60438690Sborman case LM_MODE:
60538690Sborman fprintf(NetTrace, "MODE ");
60638690Sborman if (length < 3) {
60765157Sdab fprintf(NetTrace, "(no mode??\?)");
60838690Sborman break;
60938690Sborman }
61038690Sborman {
61144361Sborman char tbuf[64];
61244361Sborman sprintf(tbuf, "%s%s%s%s%s",
61338690Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "",
61438690Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
61544361Sborman pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
61644361Sborman pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
61738690Sborman pointer[2]&MODE_ACK ? "|ACK" : "");
61838690Sborman fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
61938690Sborman }
62046808Sdab if (pointer[2]&~(MODE_MASK))
62138690Sborman fprintf(NetTrace, " (0x%x)", pointer[2]);
62238690Sborman for (i = 3; i < length; i++)
62338690Sborman fprintf(NetTrace, " ?0x%x?", pointer[i]);
62438690Sborman break;
62538690Sborman default:
62638690Sborman fprintf(NetTrace, "%d (unknown)", pointer[1]);
62738690Sborman for (i = 2; i < length; i++)
62838690Sborman fprintf(NetTrace, " %d", pointer[i]);
62938690Sborman }
63038690Sborman break;
63138690Sborman
63238909Sborman case TELOPT_STATUS: {
63338909Sborman register char *cp;
63438909Sborman register int j, k;
63538909Sborman
63638909Sborman fprintf(NetTrace, "STATUS");
63738909Sborman
63838909Sborman switch (pointer[1]) {
63938909Sborman default:
64038909Sborman if (pointer[1] == TELQUAL_SEND)
64138909Sborman fprintf(NetTrace, " SEND");
64238909Sborman else
64344361Sborman fprintf(NetTrace, " %d (unknown)", pointer[1]);
64438909Sborman for (i = 2; i < length; i++)
64538909Sborman fprintf(NetTrace, " ?%d?", pointer[i]);
64638909Sborman break;
64738909Sborman case TELQUAL_IS:
64846808Sdab if (--want_status_response < 0)
64946808Sdab want_status_response = 0;
65038909Sborman if (NetTrace == stdout)
65138909Sborman fprintf(NetTrace, " IS\r\n");
65238909Sborman else
65338909Sborman fprintf(NetTrace, " IS\n");
65438909Sborman
65538909Sborman for (i = 2; i < length; i++) {
65638909Sborman switch(pointer[i]) {
65738909Sborman case DO: cp = "DO"; goto common2;
65838909Sborman case DONT: cp = "DONT"; goto common2;
65938909Sborman case WILL: cp = "WILL"; goto common2;
66038909Sborman case WONT: cp = "WONT"; goto common2;
66138909Sborman common2:
66238909Sborman i++;
66344361Sborman if (TELOPT_OK((int)pointer[i]))
66438909Sborman fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
66538909Sborman else
66638909Sborman fprintf(NetTrace, " %s %d", cp, pointer[i]);
66738909Sborman
66838909Sborman if (NetTrace == stdout)
66938909Sborman fprintf(NetTrace, "\r\n");
67038909Sborman else
67138909Sborman fprintf(NetTrace, "\n");
67238909Sborman break;
67338909Sborman
67438909Sborman case SB:
67538909Sborman fprintf(NetTrace, " SB ");
67638909Sborman i++;
67738909Sborman j = k = i;
67838909Sborman while (j < length) {
67938909Sborman if (pointer[j] == SE) {
68038909Sborman if (j+1 == length)
68138909Sborman break;
68238909Sborman if (pointer[j+1] == SE)
68338909Sborman j++;
68438909Sborman else
68538909Sborman break;
68638909Sborman }
68738909Sborman pointer[k++] = pointer[j++];
68838909Sborman }
68938909Sborman printsub(0, &pointer[i], k - i);
69038909Sborman if (i < length) {
69138909Sborman fprintf(NetTrace, " SE");
69238909Sborman i = j;
69338909Sborman } else
69438909Sborman i = j - 1;
69538909Sborman
69638909Sborman if (NetTrace == stdout)
69738909Sborman fprintf(NetTrace, "\r\n");
69838909Sborman else
69938909Sborman fprintf(NetTrace, "\n");
70038909Sborman
70138909Sborman break;
702*69785Sdab
70338909Sborman default:
70438909Sborman fprintf(NetTrace, " %d", pointer[i]);
70538909Sborman break;
70638909Sborman }
70738909Sborman }
70838909Sborman break;
70938909Sborman }
71038909Sborman break;
71138909Sborman }
71238909Sborman
71344361Sborman case TELOPT_XDISPLOC:
71444361Sborman fprintf(NetTrace, "X-DISPLAY-LOCATION ");
71544361Sborman switch (pointer[1]) {
71644361Sborman case TELQUAL_IS:
71744361Sborman fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
71844361Sborman break;
71944361Sborman case TELQUAL_SEND:
72044361Sborman fprintf(NetTrace, "SEND");
72144361Sborman break;
72244361Sborman default:
72344361Sborman fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
72444361Sborman pointer[1], pointer[1]);
72544361Sborman }
72644361Sborman break;
72744361Sborman
72865157Sdab case TELOPT_NEW_ENVIRON:
72965157Sdab fprintf(NetTrace, "NEW-ENVIRON ");
73065157Sdab #ifdef OLD_ENVIRON
73165157Sdab goto env_common1;
73265157Sdab case TELOPT_OLD_ENVIRON:
73365157Sdab fprintf(NetTrace, "OLD-ENVIRON");
73465157Sdab env_common1:
73565157Sdab #endif
73644361Sborman switch (pointer[1]) {
73744361Sborman case TELQUAL_IS:
73844361Sborman fprintf(NetTrace, "IS ");
73944361Sborman goto env_common;
74044361Sborman case TELQUAL_SEND:
74144361Sborman fprintf(NetTrace, "SEND ");
74244361Sborman goto env_common;
74344361Sborman case TELQUAL_INFO:
74444361Sborman fprintf(NetTrace, "INFO ");
74544361Sborman env_common:
74644361Sborman {
74744361Sborman register int noquote = 2;
74865157Sdab #if defined(ENV_HACK) && defined(OLD_ENVIRON)
74965157Sdab extern int old_env_var, old_env_value;
75058972Sdab #endif
75144361Sborman for (i = 2; i < length; i++ ) {
75244361Sborman switch (pointer[i]) {
75365157Sdab case NEW_ENV_VALUE:
75465157Sdab #ifdef OLD_ENVIRON
75565157Sdab /* case NEW_ENV_OVAR: */
75665157Sdab if (pointer[0] == TELOPT_OLD_ENVIRON) {
75765157Sdab # ifdef ENV_HACK
75865157Sdab if (old_env_var == OLD_ENV_VALUE)
75965157Sdab fprintf(NetTrace, "\" (VALUE) " + noquote);
76065157Sdab else
76165157Sdab # endif
76265157Sdab fprintf(NetTrace, "\" VAR " + noquote);
76365157Sdab } else
76465157Sdab #endif /* OLD_ENVIRON */
76565157Sdab fprintf(NetTrace, "\" VALUE " + noquote);
76644361Sborman noquote = 2;
76744361Sborman break;
76844361Sborman
76965157Sdab case NEW_ENV_VAR:
77065157Sdab #ifdef OLD_ENVIRON
77165157Sdab /* case OLD_ENV_VALUE: */
77265157Sdab if (pointer[0] == TELOPT_OLD_ENVIRON) {
77365157Sdab # ifdef ENV_HACK
77465157Sdab if (old_env_value == OLD_ENV_VAR)
77565157Sdab fprintf(NetTrace, "\" (VAR) " + noquote);
77665157Sdab else
77765157Sdab # endif
77865157Sdab fprintf(NetTrace, "\" VALUE " + noquote);
77965157Sdab } else
78065157Sdab #endif /* OLD_ENVIRON */
78165157Sdab fprintf(NetTrace, "\" VAR " + noquote);
78244361Sborman noquote = 2;
78344361Sborman break;
78444361Sborman
78544361Sborman case ENV_ESC:
78644361Sborman fprintf(NetTrace, "\" ESC " + noquote);
78744361Sborman noquote = 2;
78844361Sborman break;
78944361Sborman
79057213Sdab case ENV_USERVAR:
79157213Sdab fprintf(NetTrace, "\" USERVAR " + noquote);
79257213Sdab noquote = 2;
79357213Sdab break;
79457213Sdab
79544361Sborman default:
79644361Sborman def_case:
79744361Sborman if (isprint(pointer[i]) && pointer[i] != '"') {
79844361Sborman if (noquote) {
79944361Sborman putc('"', NetTrace);
80044361Sborman noquote = 0;
80144361Sborman }
80244361Sborman putc(pointer[i], NetTrace);
80344361Sborman } else {
80444361Sborman fprintf(NetTrace, "\" %03o " + noquote,
80544361Sborman pointer[i]);
80644361Sborman noquote = 2;
80744361Sborman }
80844361Sborman break;
80944361Sborman }
81044361Sborman }
81144361Sborman if (!noquote)
81244361Sborman putc('"', NetTrace);
81344361Sborman break;
81444361Sborman }
81544361Sborman }
81644361Sborman break;
81744361Sborman
81832149Sminshall default:
81946808Sdab if (TELOPT_OK(pointer[0]))
82046808Sdab fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
82146808Sdab else
82256860Storek fprintf(NetTrace, "%d (unknown)", pointer[0]);
82346808Sdab for (i = 1; i < length; i++)
82438690Sborman fprintf(NetTrace, " %d", pointer[i]);
82538690Sborman break;
82632149Sminshall }
82738909Sborman if (direction) {
82838909Sborman if (NetTrace == stdout)
82938909Sborman fprintf(NetTrace, "\r\n");
83038909Sborman else
83138909Sborman fprintf(NetTrace, "\n");
83238909Sborman }
83365157Sdab if (NetTrace == stdout)
83465157Sdab fflush(NetTrace);
83532149Sminshall }
83632149Sminshall }
83736278Sminshall
83836278Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty.
83936278Sminshall * Note that we consider the buffer to run all the
84036278Sminshall * way to the kernel (thus the select).
84136278Sminshall */
84236278Sminshall
84346808Sdab void
EmptyTerminal()84436278Sminshall EmptyTerminal()
84536278Sminshall {
84636278Sminshall #if defined(unix)
84736278Sminshall fd_set o;
84836278Sminshall
84936278Sminshall FD_ZERO(&o);
85036278Sminshall #endif /* defined(unix) */
85136278Sminshall
85236278Sminshall if (TTYBYTES() == 0) {
85336278Sminshall #if defined(unix)
85436278Sminshall FD_SET(tout, &o);
85536278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
85636278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */
85736278Sminshall #endif /* defined(unix) */
85836278Sminshall } else {
85936278Sminshall while (TTYBYTES()) {
86044361Sborman (void) ttyflush(0);
86136278Sminshall #if defined(unix)
86236278Sminshall FD_SET(tout, &o);
86336278Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
86436278Sminshall (struct timeval *) 0); /* wait for TTLOWAT */
86536278Sminshall #endif /* defined(unix) */
86636278Sminshall }
86736278Sminshall }
86836278Sminshall }
86936278Sminshall
87046808Sdab void
SetForExit()87136278Sminshall SetForExit()
87236278Sminshall {
87338690Sborman setconnmode(0);
87436278Sminshall #if defined(TN3270)
87536278Sminshall if (In3270) {
87636278Sminshall Finish3270();
87736278Sminshall }
87836279Sminshall #else /* defined(TN3270) */
87936279Sminshall do {
88044361Sborman (void)telrcv(); /* Process any incoming data */
88136279Sminshall EmptyTerminal();
88236279Sminshall } while (ring_full_count(&netiring)); /* While there is any */
88336278Sminshall #endif /* defined(TN3270) */
88436278Sminshall setcommandmode();
88536278Sminshall fflush(stdout);
88636278Sminshall fflush(stderr);
88736278Sminshall #if defined(TN3270)
88836278Sminshall if (In3270) {
88936278Sminshall StopScreen(1);
89036278Sminshall }
89136278Sminshall #endif /* defined(TN3270) */
89238690Sborman setconnmode(0);
89336278Sminshall EmptyTerminal(); /* Flush the path to the tty */
89436278Sminshall setcommandmode();
89536278Sminshall }
89636278Sminshall
89746808Sdab void
Exit(returnCode)89836278Sminshall Exit(returnCode)
89946808Sdab int returnCode;
90036278Sminshall {
90136278Sminshall SetForExit();
90236278Sminshall exit(returnCode);
90336278Sminshall }
90436278Sminshall
90546808Sdab void
ExitString(string,returnCode)90636278Sminshall ExitString(string, returnCode)
90746808Sdab char *string;
90846808Sdab int returnCode;
90936278Sminshall {
91036278Sminshall SetForExit();
91136278Sminshall fwrite(string, 1, strlen(string), stderr);
91236278Sminshall exit(returnCode);
91336278Sminshall }
914