138905Sborman /*
261451Sbostic * Copyright (c) 1989, 1993
361451Sbostic * The Regents of the University of California. All rights reserved.
438905Sborman *
542673Sbostic * %sccs.include.redist.c%
638905Sborman */
738905Sborman
838905Sborman #ifndef lint
9*69786Sdab static char sccsid[] = "@(#)utility.c 8.4 (Berkeley) 05/30/95";
1038905Sborman #endif /* not lint */
1138905Sborman
1244364Sborman #define PRINTOPTIONS
1338905Sborman #include "telnetd.h"
1438905Sborman
1538905Sborman /*
1638905Sborman * utility functions performing io related tasks
1738905Sborman */
1838905Sborman
1938905Sborman /*
2038905Sborman * ttloop
2138905Sborman *
2238905Sborman * A small subroutine to flush the network output buffer, get some data
2338905Sborman * from the network, and pass it through the telnet state machine. We
2438905Sborman * also flush the pty input buffer (by dropping its data) if it becomes
2538905Sborman * too full.
2638905Sborman */
2738905Sborman
2846809Sdab void
ttloop()2938905Sborman ttloop()
3038905Sborman {
3138905Sborman void netflush();
3238905Sborman
3346809Sdab DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n");
3446809Sdab nfrontp += strlen(nfrontp);});
3538905Sborman if (nfrontp-nbackp) {
3638905Sborman netflush();
3738905Sborman }
3838905Sborman ncc = read(net, netibuf, sizeof netibuf);
3938905Sborman if (ncc < 0) {
4038905Sborman syslog(LOG_INFO, "ttloop: read: %m\n");
4138905Sborman exit(1);
4238905Sborman } else if (ncc == 0) {
4338905Sborman syslog(LOG_INFO, "ttloop: peer died: %m\n");
4438905Sborman exit(1);
4538905Sborman }
4646809Sdab DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc);
4746809Sdab nfrontp += strlen(nfrontp);});
4838905Sborman netip = netibuf;
4938905Sborman telrcv(); /* state machine */
5038905Sborman if (ncc > 0) {
5138905Sborman pfrontp = pbackp = ptyobuf;
5238905Sborman telrcv();
5338905Sborman }
5438905Sborman } /* end of ttloop */
5538905Sborman
5638905Sborman /*
5738905Sborman * Check a descriptor to see if out of band data exists on it.
5838905Sborman */
5946809Sdab int
stilloob(s)6038905Sborman stilloob(s)
6146809Sdab int s; /* socket number */
6238905Sborman {
6338905Sborman static struct timeval timeout = { 0 };
6438905Sborman fd_set excepts;
6538905Sborman int value;
6638905Sborman
6738905Sborman do {
6838905Sborman FD_ZERO(&excepts);
6938905Sborman FD_SET(s, &excepts);
7038905Sborman value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
7138905Sborman } while ((value == -1) && (errno == EINTR));
7238905Sborman
7338905Sborman if (value < 0) {
7438905Sborman fatalperror(pty, "select");
7538905Sborman }
7638905Sborman if (FD_ISSET(s, &excepts)) {
7738905Sborman return 1;
7838905Sborman } else {
7938905Sborman return 0;
8038905Sborman }
8138905Sborman }
8238905Sborman
8346809Sdab void
ptyflush()8438905Sborman ptyflush()
8538905Sborman {
8638905Sborman int n;
8738905Sborman
8844364Sborman if ((n = pfrontp - pbackp) > 0) {
8946809Sdab DIAG((TD_REPORT | TD_PTYDATA),
9046809Sdab { sprintf(nfrontp, "td: ptyflush %d chars\r\n", n);
9146809Sdab nfrontp += strlen(nfrontp); });
9246809Sdab DIAG(TD_PTYDATA, printdata("pd", pbackp, n));
9338905Sborman n = write(pty, pbackp, n);
9444364Sborman }
9546809Sdab if (n < 0) {
9646809Sdab if (errno == EWOULDBLOCK || errno == EINTR)
9746809Sdab return;
9846809Sdab cleanup(0);
9946809Sdab }
10038905Sborman pbackp += n;
10138905Sborman if (pbackp == pfrontp)
10238905Sborman pbackp = pfrontp = ptyobuf;
10338905Sborman }
10438905Sborman
10538905Sborman /*
10638905Sborman * nextitem()
10738905Sborman *
10838905Sborman * Return the address of the next "item" in the TELNET data
10938905Sborman * stream. This will be the address of the next character if
11038905Sborman * the current address is a user data character, or it will
11138905Sborman * be the address of the character following the TELNET command
11238905Sborman * if the current address is a TELNET IAC ("I Am a Command")
11338905Sborman * character.
11438905Sborman */
11546809Sdab char *
nextitem(current)11638905Sborman nextitem(current)
11746809Sdab char *current;
11838905Sborman {
11938905Sborman if ((*current&0xff) != IAC) {
12038905Sborman return current+1;
12138905Sborman }
12238905Sborman switch (*(current+1)&0xff) {
12338905Sborman case DO:
12438905Sborman case DONT:
12538905Sborman case WILL:
12638905Sborman case WONT:
12738905Sborman return current+3;
12838905Sborman case SB: /* loop forever looking for the SE */
12938905Sborman {
13038905Sborman register char *look = current+2;
13138905Sborman
13238905Sborman for (;;) {
13338905Sborman if ((*look++&0xff) == IAC) {
13438905Sborman if ((*look++&0xff) == SE) {
13538905Sborman return look;
13638905Sborman }
13738905Sborman }
13838905Sborman }
13938905Sborman }
14038905Sborman default:
14138905Sborman return current+2;
14238905Sborman }
14338905Sborman } /* end of nextitem */
14438905Sborman
14538905Sborman
14638905Sborman /*
14738905Sborman * netclear()
14838905Sborman *
14938905Sborman * We are about to do a TELNET SYNCH operation. Clear
15038905Sborman * the path to the network.
15138905Sborman *
15238905Sborman * Things are a bit tricky since we may have sent the first
15338905Sborman * byte or so of a previous TELNET command into the network.
15438905Sborman * So, we have to scan the network buffer from the beginning
15538905Sborman * until we are up to where we want to be.
15638905Sborman *
15738905Sborman * A side effect of what we do, just to keep things
15838905Sborman * simple, is to clear the urgent data pointer. The principal
15938905Sborman * caller should be setting the urgent data pointer AFTER calling
16038905Sborman * us in any case.
16138905Sborman */
16246809Sdab void
netclear()16338905Sborman netclear()
16438905Sborman {
16538905Sborman register char *thisitem, *next;
16638905Sborman char *good;
16738905Sborman #define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \
16838905Sborman ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
16938905Sborman
17060151Sdab #ifdef ENCRYPTION
17146809Sdab thisitem = nclearto > netobuf ? nclearto : netobuf;
17260151Sdab #else /* ENCRYPTION */
17338905Sborman thisitem = netobuf;
17460151Sdab #endif /* ENCRYPTION */
17538905Sborman
17638905Sborman while ((next = nextitem(thisitem)) <= nbackp) {
17738905Sborman thisitem = next;
17838905Sborman }
17938905Sborman
18038905Sborman /* Now, thisitem is first before/at boundary. */
18138905Sborman
18260151Sdab #ifdef ENCRYPTION
18346809Sdab good = nclearto > netobuf ? nclearto : netobuf;
18460151Sdab #else /* ENCRYPTION */
18538905Sborman good = netobuf; /* where the good bytes go */
18660151Sdab #endif /* ENCRYPTION */
18738905Sborman
18838905Sborman while (nfrontp > thisitem) {
18938905Sborman if (wewant(thisitem)) {
19038905Sborman int length;
19138905Sborman
19238905Sborman next = thisitem;
19338905Sborman do {
19438905Sborman next = nextitem(next);
19538905Sborman } while (wewant(next) && (nfrontp > next));
19638905Sborman length = next-thisitem;
197*69786Sdab memmove(good, thisitem, length);
19838905Sborman good += length;
19938905Sborman thisitem = next;
20038905Sborman } else {
20138905Sborman thisitem = nextitem(thisitem);
20238905Sborman }
20338905Sborman }
20438905Sborman
20538905Sborman nbackp = netobuf;
20638905Sborman nfrontp = good; /* next byte to be sent */
20738905Sborman neturg = 0;
20838905Sborman } /* end of netclear */
20938905Sborman
21038905Sborman /*
21138905Sborman * netflush
21238905Sborman * Send as much data as possible to the network,
21338905Sborman * handling requests for urgent data.
21438905Sborman */
21546809Sdab void
netflush()21638905Sborman netflush()
21738905Sborman {
21838905Sborman int n;
21938905Sborman extern int not42;
22038905Sborman
22138905Sborman if ((n = nfrontp - nbackp) > 0) {
22246809Sdab DIAG(TD_REPORT,
22346809Sdab { sprintf(nfrontp, "td: netflush %d chars\r\n", n);
22446809Sdab n += strlen(nfrontp); /* get count first */
22546809Sdab nfrontp += strlen(nfrontp); /* then move pointer */
22646809Sdab });
22760151Sdab #ifdef ENCRYPTION
22846809Sdab if (encrypt_output) {
22946809Sdab char *s = nclearto ? nclearto : nbackp;
23046809Sdab if (nfrontp - s > 0) {
23146809Sdab (*encrypt_output)((unsigned char *)s, nfrontp-s);
23246809Sdab nclearto = nfrontp;
23346809Sdab }
23444364Sborman }
23560151Sdab #endif /* ENCRYPTION */
23638905Sborman /*
23738905Sborman * if no urgent data, or if the other side appears to be an
23838905Sborman * old 4.2 client (and thus unable to survive TCP urgent data),
23938905Sborman * write the entire buffer in non-OOB mode.
24038905Sborman */
24138905Sborman if ((neturg == 0) || (not42 == 0)) {
24238905Sborman n = write(net, nbackp, n); /* normal write */
24338905Sborman } else {
24438905Sborman n = neturg - nbackp;
24538905Sborman /*
24638905Sborman * In 4.2 (and 4.3) systems, there is some question about
24738905Sborman * what byte in a sendOOB operation is the "OOB" data.
24838905Sborman * To make ourselves compatible, we only send ONE byte
24938905Sborman * out of band, the one WE THINK should be OOB (though
25038905Sborman * we really have more the TCP philosophy of urgent data
25138905Sborman * rather than the Unix philosophy of OOB data).
25238905Sborman */
25338905Sborman if (n > 1) {
25438905Sborman n = send(net, nbackp, n-1, 0); /* send URGENT all by itself */
25538905Sborman } else {
25638905Sborman n = send(net, nbackp, n, MSG_OOB); /* URGENT data */
25738905Sborman }
25838905Sborman }
25938905Sborman }
26038905Sborman if (n < 0) {
26138905Sborman if (errno == EWOULDBLOCK || errno == EINTR)
26238905Sborman return;
26346809Sdab cleanup(0);
26438905Sborman }
26538905Sborman nbackp += n;
26660151Sdab #ifdef ENCRYPTION
26746809Sdab if (nbackp > nclearto)
26846809Sdab nclearto = 0;
26960151Sdab #endif /* ENCRYPTION */
27038905Sborman if (nbackp >= neturg) {
27138905Sborman neturg = 0;
27238905Sborman }
27338905Sborman if (nbackp == nfrontp) {
27438905Sborman nbackp = nfrontp = netobuf;
27560151Sdab #ifdef ENCRYPTION
27646809Sdab nclearto = 0;
27760151Sdab #endif /* ENCRYPTION */
27838905Sborman }
27938905Sborman return;
28038905Sborman } /* end of netflush */
28138905Sborman
28238905Sborman
28338905Sborman /*
28438905Sborman * writenet
28538905Sborman *
28638905Sborman * Just a handy little function to write a bit of raw data to the net.
28738905Sborman * It will force a transmit of the buffer if necessary
28838905Sborman *
28938905Sborman * arguments
29038905Sborman * ptr - A pointer to a character string to write
29138905Sborman * len - How many bytes to write
29238905Sborman */
29346809Sdab void
writenet(ptr,len)29438905Sborman writenet(ptr, len)
29546809Sdab register unsigned char *ptr;
29646809Sdab register int len;
29738905Sborman {
29838905Sborman /* flush buffer if no room for new data) */
29938905Sborman if ((&netobuf[BUFSIZ] - nfrontp) < len) {
30038905Sborman /* if this fails, don't worry, buffer is a little big */
30138905Sborman netflush();
30238905Sborman }
30338905Sborman
304*69786Sdab memmove(nfrontp, ptr, len);
30538905Sborman nfrontp += len;
30638905Sborman
30738905Sborman } /* end of writenet */
30838905Sborman
30938905Sborman
31038905Sborman /*
31138905Sborman * miscellaneous functions doing a variety of little jobs follow ...
31238905Sborman */
31338905Sborman
31438905Sborman
31546809Sdab void
fatal(f,msg)31638905Sborman fatal(f, msg)
31738905Sborman int f;
31838905Sborman char *msg;
31938905Sborman {
32038905Sborman char buf[BUFSIZ];
32138905Sborman
32238905Sborman (void) sprintf(buf, "telnetd: %s.\r\n", msg);
32360151Sdab #ifdef ENCRYPTION
32446809Sdab if (encrypt_output) {
32546809Sdab /*
32646809Sdab * Better turn off encryption first....
32746809Sdab * Hope it flushes...
32846809Sdab */
32946809Sdab encrypt_send_end();
33046809Sdab netflush();
33146809Sdab }
33260151Sdab #endif /* ENCRYPTION */
33338905Sborman (void) write(f, buf, (int)strlen(buf));
33438905Sborman sleep(1); /*XXX*/
33538905Sborman exit(1);
33638905Sborman }
33738905Sborman
33846809Sdab void
fatalperror(f,msg)33938905Sborman fatalperror(f, msg)
34038905Sborman int f;
34138905Sborman char *msg;
34238905Sborman {
34342411Sbostic char buf[BUFSIZ], *strerror();
34438905Sborman
34568585Sdab (void) sprintf(buf, "%s: %s", msg, strerror(errno));
34638905Sborman fatal(f, buf);
34738905Sborman }
34838905Sborman
34938905Sborman char editedhost[32];
35038905Sborman
35146809Sdab void
edithost(pat,host)35238905Sborman edithost(pat, host)
35338905Sborman register char *pat;
35438905Sborman register char *host;
35538905Sborman {
35638905Sborman register char *res = editedhost;
35738905Sborman char *strncpy();
35838905Sborman
35938905Sborman if (!pat)
36038905Sborman pat = "";
36138905Sborman while (*pat) {
36238905Sborman switch (*pat) {
36338905Sborman
36438905Sborman case '#':
36538905Sborman if (*host)
36638905Sborman host++;
36738905Sborman break;
36838905Sborman
36938905Sborman case '@':
37038905Sborman if (*host)
37138905Sborman *res++ = *host++;
37238905Sborman break;
37338905Sborman
37438905Sborman default:
37538905Sborman *res++ = *pat;
37638905Sborman break;
37738905Sborman }
37838905Sborman if (res == &editedhost[sizeof editedhost - 1]) {
37938905Sborman *res = '\0';
38038905Sborman return;
38138905Sborman }
38238905Sborman pat++;
38338905Sborman }
38438905Sborman if (*host)
38538905Sborman (void) strncpy(res, host,
38638905Sborman sizeof editedhost - (res - editedhost) -1);
38738905Sborman else
38838905Sborman *res = '\0';
38938905Sborman editedhost[sizeof editedhost - 1] = '\0';
39038905Sborman }
39138905Sborman
39238905Sborman static char *putlocation;
39338905Sborman
39446809Sdab void
putstr(s)39538905Sborman putstr(s)
39646809Sdab register char *s;
39738905Sborman {
39838905Sborman
39938905Sborman while (*s)
40038905Sborman putchr(*s++);
40138905Sborman }
40238905Sborman
40346809Sdab void
putchr(cc)40438905Sborman putchr(cc)
40546809Sdab int cc;
40638905Sborman {
40738905Sborman *putlocation++ = cc;
40838905Sborman }
40938905Sborman
41046809Sdab /*
41146809Sdab * This is split on two lines so that SCCS will not see the M
41246809Sdab * between two % signs and expand it...
41346809Sdab */
41446809Sdab static char fmtstr[] = { "%l:%M\
41546809Sdab %P on %A, %d %B %Y" };
41646809Sdab
41746809Sdab void
putf(cp,where)41838905Sborman putf(cp, where)
41946809Sdab register char *cp;
42046809Sdab char *where;
42138905Sborman {
42246809Sdab char *slash;
42346123Sbostic time_t t;
42446809Sdab char db[100];
42565158Sdab #ifdef STREAMSPTY
426*69786Sdab extern char *strchr();
42765158Sdab #else
428*69786Sdab extern char *strrchr();
42965158Sdab #endif
43038905Sborman
43138905Sborman putlocation = where;
43238905Sborman
43338905Sborman while (*cp) {
43438905Sborman if (*cp != '%') {
43538905Sborman putchr(*cp++);
43638905Sborman continue;
43738905Sborman }
43838905Sborman switch (*++cp) {
43938905Sborman
44038905Sborman case 't':
44157212Sdab #ifdef STREAMSPTY
44257212Sdab /* names are like /dev/pts/2 -- we want pts/2 */
443*69786Sdab slash = strchr(line+1, '/');
44457212Sdab #else
445*69786Sdab slash = strrchr(line, '/');
44657212Sdab #endif
44738905Sborman if (slash == (char *) 0)
44838905Sborman putstr(line);
44938905Sborman else
45038905Sborman putstr(&slash[1]);
45138905Sborman break;
45238905Sborman
45338905Sborman case 'h':
45438905Sborman putstr(editedhost);
45538905Sborman break;
45638905Sborman
45746809Sdab case 'd':
45846123Sbostic (void)time(&t);
45946809Sdab (void)strftime(db, sizeof(db), fmtstr, localtime(&t));
46046123Sbostic putstr(db);
46138905Sborman break;
46238905Sborman
46338905Sborman case '%':
46438905Sborman putchr('%');
46538905Sborman break;
46638905Sborman }
46738905Sborman cp++;
46838905Sborman }
46938905Sborman }
47038905Sborman
47144364Sborman #ifdef DIAGNOSTICS
47244364Sborman /*
47344364Sborman * Print telnet options and commands in plain text, if possible.
47444364Sborman */
47546809Sdab void
printoption(fmt,option)47644364Sborman printoption(fmt, option)
47746809Sdab register char *fmt;
47846809Sdab register int option;
47944364Sborman {
48044364Sborman if (TELOPT_OK(option))
48144364Sborman sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option));
48244364Sborman else if (TELCMD_OK(option))
48344364Sborman sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option));
48444364Sborman else
48544364Sborman sprintf(nfrontp, "%s %d\r\n", fmt, option);
48644364Sborman nfrontp += strlen(nfrontp);
48744364Sborman return;
48844364Sborman }
48944364Sborman
49046809Sdab void
printsub(direction,pointer,length)49146809Sdab printsub(direction, pointer, length)
49246809Sdab char direction; /* '<' or '>' */
49346809Sdab unsigned char *pointer; /* where suboption data sits */
49446809Sdab int length; /* length of suboption data */
49544364Sborman {
49644364Sborman register int i;
49747611Sdab char buf[512];
49844364Sborman
499*69786Sdab if (!(diagnostic & TD_OPTIONS))
50046809Sdab return;
50146809Sdab
50246809Sdab if (direction) {
50346809Sdab sprintf(nfrontp, "td: %s suboption ",
50446809Sdab direction == '<' ? "recv" : "send");
50544364Sborman nfrontp += strlen(nfrontp);
50644364Sborman if (length >= 3) {
50744364Sborman register int j;
50844364Sborman
50944364Sborman i = pointer[length-2];
51044364Sborman j = pointer[length-1];
51144364Sborman
51244364Sborman if (i != IAC || j != SE) {
51344364Sborman sprintf(nfrontp, "(terminated by ");
51444364Sborman nfrontp += strlen(nfrontp);
51544364Sborman if (TELOPT_OK(i))
51644364Sborman sprintf(nfrontp, "%s ", TELOPT(i));
51744364Sborman else if (TELCMD_OK(i))
51844364Sborman sprintf(nfrontp, "%s ", TELCMD(i));
51944364Sborman else
52044364Sborman sprintf(nfrontp, "%d ", i);
52144364Sborman nfrontp += strlen(nfrontp);
52244364Sborman if (TELOPT_OK(j))
52344364Sborman sprintf(nfrontp, "%s", TELOPT(j));
52444364Sborman else if (TELCMD_OK(j))
52544364Sborman sprintf(nfrontp, "%s", TELCMD(j));
52644364Sborman else
52744364Sborman sprintf(nfrontp, "%d", j);
52844364Sborman nfrontp += strlen(nfrontp);
52944364Sborman sprintf(nfrontp, ", not IAC SE!) ");
53044364Sborman nfrontp += strlen(nfrontp);
53144364Sborman }
53244364Sborman }
53344364Sborman length -= 2;
53444364Sborman }
53544364Sborman if (length < 1) {
53665158Sdab sprintf(nfrontp, "(Empty suboption??\?)");
53744364Sborman nfrontp += strlen(nfrontp);
53844364Sborman return;
53944364Sborman }
54044364Sborman switch (pointer[0]) {
54144364Sborman case TELOPT_TTYPE:
54244364Sborman sprintf(nfrontp, "TERMINAL-TYPE ");
54344364Sborman nfrontp += strlen(nfrontp);
54444364Sborman switch (pointer[1]) {
54544364Sborman case TELQUAL_IS:
54644364Sborman sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
54744364Sborman break;
54844364Sborman case TELQUAL_SEND:
54944364Sborman sprintf(nfrontp, "SEND");
55044364Sborman break;
55144364Sborman default:
55244364Sborman sprintf(nfrontp,
55344364Sborman "- unknown qualifier %d (0x%x).",
55444364Sborman pointer[1], pointer[1]);
55544364Sborman }
55644364Sborman nfrontp += strlen(nfrontp);
55744364Sborman break;
55844364Sborman case TELOPT_TSPEED:
55944364Sborman sprintf(nfrontp, "TERMINAL-SPEED");
56044364Sborman nfrontp += strlen(nfrontp);
56144364Sborman if (length < 2) {
56265158Sdab sprintf(nfrontp, " (empty suboption??\?)");
56344364Sborman nfrontp += strlen(nfrontp);
56444364Sborman break;
56544364Sborman }
56644364Sborman switch (pointer[1]) {
56744364Sborman case TELQUAL_IS:
56844364Sborman sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2);
56944364Sborman nfrontp += strlen(nfrontp);
57044364Sborman break;
57144364Sborman default:
57244364Sborman if (pointer[1] == 1)
57344364Sborman sprintf(nfrontp, " SEND");
57444364Sborman else
57544364Sborman sprintf(nfrontp, " %d (unknown)", pointer[1]);
57644364Sborman nfrontp += strlen(nfrontp);
57744364Sborman for (i = 2; i < length; i++) {
57844364Sborman sprintf(nfrontp, " ?%d?", pointer[i]);
57944364Sborman nfrontp += strlen(nfrontp);
58044364Sborman }
58144364Sborman break;
58244364Sborman }
58344364Sborman break;
58444364Sborman
58544364Sborman case TELOPT_LFLOW:
58644364Sborman sprintf(nfrontp, "TOGGLE-FLOW-CONTROL");
58744364Sborman nfrontp += strlen(nfrontp);
58844364Sborman if (length < 2) {
58965158Sdab sprintf(nfrontp, " (empty suboption??\?)");
59044364Sborman nfrontp += strlen(nfrontp);
59144364Sborman break;
59244364Sborman }
59344364Sborman switch (pointer[1]) {
59457597Sdab case LFLOW_OFF:
59544364Sborman sprintf(nfrontp, " OFF"); break;
59657597Sdab case LFLOW_ON:
59744364Sborman sprintf(nfrontp, " ON"); break;
59857597Sdab case LFLOW_RESTART_ANY:
59957597Sdab sprintf(nfrontp, " RESTART-ANY"); break;
60057597Sdab case LFLOW_RESTART_XON:
60157597Sdab sprintf(nfrontp, " RESTART-XON"); break;
60244364Sborman default:
60344364Sborman sprintf(nfrontp, " %d (unknown)", pointer[1]);
60444364Sborman }
60544364Sborman nfrontp += strlen(nfrontp);
60644364Sborman for (i = 2; i < length; i++) {
60744364Sborman sprintf(nfrontp, " ?%d?", pointer[i]);
60844364Sborman nfrontp += strlen(nfrontp);
60944364Sborman }
61044364Sborman break;
61144364Sborman
61244364Sborman case TELOPT_NAWS:
61344364Sborman sprintf(nfrontp, "NAWS");
61444364Sborman nfrontp += strlen(nfrontp);
61544364Sborman if (length < 2) {
61665158Sdab sprintf(nfrontp, " (empty suboption??\?)");
61744364Sborman nfrontp += strlen(nfrontp);
61844364Sborman break;
61944364Sborman }
62044364Sborman if (length == 2) {
62144364Sborman sprintf(nfrontp, " ?%d?", pointer[1]);
62244364Sborman nfrontp += strlen(nfrontp);
62344364Sborman break;
62444364Sborman }
62544364Sborman sprintf(nfrontp, " %d %d (%d)",
62644364Sborman pointer[1], pointer[2],
62744364Sborman (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
62844364Sborman nfrontp += strlen(nfrontp);
62944364Sborman if (length == 4) {
63044364Sborman sprintf(nfrontp, " ?%d?", pointer[3]);
63144364Sborman nfrontp += strlen(nfrontp);
63244364Sborman break;
63344364Sborman }
63444364Sborman sprintf(nfrontp, " %d %d (%d)",
63544364Sborman pointer[3], pointer[4],
63644364Sborman (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
63744364Sborman nfrontp += strlen(nfrontp);
63844364Sborman for (i = 5; i < length; i++) {
63944364Sborman sprintf(nfrontp, " ?%d?", pointer[i]);
64044364Sborman nfrontp += strlen(nfrontp);
64144364Sborman }
64244364Sborman break;
64344364Sborman
64444364Sborman case TELOPT_LINEMODE:
64544364Sborman sprintf(nfrontp, "LINEMODE ");
64644364Sborman nfrontp += strlen(nfrontp);
64744364Sborman if (length < 2) {
64865158Sdab sprintf(nfrontp, " (empty suboption??\?)");
64944364Sborman nfrontp += strlen(nfrontp);
65044364Sborman break;
65144364Sborman }
65244364Sborman switch (pointer[1]) {
65344364Sborman case WILL:
65444364Sborman sprintf(nfrontp, "WILL ");
65544364Sborman goto common;
65644364Sborman case WONT:
65744364Sborman sprintf(nfrontp, "WONT ");
65844364Sborman goto common;
65944364Sborman case DO:
66044364Sborman sprintf(nfrontp, "DO ");
66144364Sborman goto common;
66244364Sborman case DONT:
66344364Sborman sprintf(nfrontp, "DONT ");
66444364Sborman common:
66544364Sborman nfrontp += strlen(nfrontp);
66644364Sborman if (length < 3) {
66765158Sdab sprintf(nfrontp, "(no option??\?)");
66844364Sborman nfrontp += strlen(nfrontp);
66944364Sborman break;
67044364Sborman }
67144364Sborman switch (pointer[2]) {
67244364Sborman case LM_FORWARDMASK:
67344364Sborman sprintf(nfrontp, "Forward Mask");
67444364Sborman nfrontp += strlen(nfrontp);
67544364Sborman for (i = 3; i < length; i++) {
67644364Sborman sprintf(nfrontp, " %x", pointer[i]);
67744364Sborman nfrontp += strlen(nfrontp);
67844364Sborman }
67944364Sborman break;
68044364Sborman default:
68144364Sborman sprintf(nfrontp, "%d (unknown)", pointer[2]);
68244364Sborman nfrontp += strlen(nfrontp);
68344364Sborman for (i = 3; i < length; i++) {
68444364Sborman sprintf(nfrontp, " %d", pointer[i]);
68544364Sborman nfrontp += strlen(nfrontp);
68644364Sborman }
68744364Sborman break;
68844364Sborman }
68944364Sborman break;
690*69786Sdab
69144364Sborman case LM_SLC:
69244364Sborman sprintf(nfrontp, "SLC");
69344364Sborman nfrontp += strlen(nfrontp);
69444364Sborman for (i = 2; i < length - 2; i += 3) {
69546809Sdab if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
69646809Sdab sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
69744364Sborman else
69844364Sborman sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]);
69944364Sborman nfrontp += strlen(nfrontp);
70044364Sborman switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
70144364Sborman case SLC_NOSUPPORT:
70244364Sborman sprintf(nfrontp, " NOSUPPORT"); break;
70344364Sborman case SLC_CANTCHANGE:
70444364Sborman sprintf(nfrontp, " CANTCHANGE"); break;
70544364Sborman case SLC_VARIABLE:
70644364Sborman sprintf(nfrontp, " VARIABLE"); break;
70744364Sborman case SLC_DEFAULT:
70844364Sborman sprintf(nfrontp, " DEFAULT"); break;
70944364Sborman }
71044364Sborman nfrontp += strlen(nfrontp);
71144364Sborman sprintf(nfrontp, "%s%s%s",
71244364Sborman pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
71344364Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
71444364Sborman pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
71544364Sborman nfrontp += strlen(nfrontp);
71644364Sborman if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
71744364Sborman SLC_FLUSHOUT| SLC_LEVELBITS)) {
71844364Sborman sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]);
71944364Sborman nfrontp += strlen(nfrontp);
72044364Sborman }
72144364Sborman sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]);
72244364Sborman nfrontp += strlen(nfrontp);
72344364Sborman if ((pointer[i+SLC_VALUE] == IAC) &&
72444364Sborman (pointer[i+SLC_VALUE+1] == IAC))
72544364Sborman i++;
72644364Sborman }
72744364Sborman for (; i < length; i++) {
72844364Sborman sprintf(nfrontp, " ?%d?", pointer[i]);
72944364Sborman nfrontp += strlen(nfrontp);
73044364Sborman }
73144364Sborman break;
73244364Sborman
73344364Sborman case LM_MODE:
73444364Sborman sprintf(nfrontp, "MODE ");
73544364Sborman nfrontp += strlen(nfrontp);
73644364Sborman if (length < 3) {
73765158Sdab sprintf(nfrontp, "(no mode??\?)");
73844364Sborman nfrontp += strlen(nfrontp);
73944364Sborman break;
74044364Sborman }
74144364Sborman {
74244364Sborman char tbuf[32];
74344364Sborman sprintf(tbuf, "%s%s%s%s%s",
74444364Sborman pointer[2]&MODE_EDIT ? "|EDIT" : "",
74544364Sborman pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
74644364Sborman pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
74744364Sborman pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
74844364Sborman pointer[2]&MODE_ACK ? "|ACK" : "");
74944364Sborman sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0");
75044364Sborman nfrontp += strlen(nfrontp);
75144364Sborman }
75244364Sborman if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) {
75344364Sborman sprintf(nfrontp, " (0x%x)", pointer[2]);
75444364Sborman nfrontp += strlen(nfrontp);
75544364Sborman }
75644364Sborman for (i = 3; i < length; i++) {
75744364Sborman sprintf(nfrontp, " ?0x%x?", pointer[i]);
75844364Sborman nfrontp += strlen(nfrontp);
75944364Sborman }
76044364Sborman break;
76144364Sborman default:
76244364Sborman sprintf(nfrontp, "%d (unknown)", pointer[1]);
76344364Sborman nfrontp += strlen(nfrontp);
76444364Sborman for (i = 2; i < length; i++) {
76544364Sborman sprintf(nfrontp, " %d", pointer[i]);
76644364Sborman nfrontp += strlen(nfrontp);
76744364Sborman }
76844364Sborman }
76944364Sborman break;
77044364Sborman
77144364Sborman case TELOPT_STATUS: {
77244364Sborman register char *cp;
77344364Sborman register int j, k;
77444364Sborman
77544364Sborman sprintf(nfrontp, "STATUS");
77644364Sborman nfrontp += strlen(nfrontp);
77744364Sborman
77844364Sborman switch (pointer[1]) {
77944364Sborman default:
78044364Sborman if (pointer[1] == TELQUAL_SEND)
78144364Sborman sprintf(nfrontp, " SEND");
78244364Sborman else
78344364Sborman sprintf(nfrontp, " %d (unknown)", pointer[1]);
78444364Sborman nfrontp += strlen(nfrontp);
78544364Sborman for (i = 2; i < length; i++) {
78644364Sborman sprintf(nfrontp, " ?%d?", pointer[i]);
78744364Sborman nfrontp += strlen(nfrontp);
78844364Sborman }
78944364Sborman break;
79044364Sborman case TELQUAL_IS:
79144364Sborman sprintf(nfrontp, " IS\r\n");
79244364Sborman nfrontp += strlen(nfrontp);
79344364Sborman
79444364Sborman for (i = 2; i < length; i++) {
79544364Sborman switch(pointer[i]) {
79644364Sborman case DO: cp = "DO"; goto common2;
79744364Sborman case DONT: cp = "DONT"; goto common2;
79844364Sborman case WILL: cp = "WILL"; goto common2;
79944364Sborman case WONT: cp = "WONT"; goto common2;
80044364Sborman common2:
80144364Sborman i++;
80258971Sdab if (TELOPT_OK(pointer[i]))
80344364Sborman sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i]));
80444364Sborman else
80544364Sborman sprintf(nfrontp, " %s %d", cp, pointer[i]);
80644364Sborman nfrontp += strlen(nfrontp);
80744364Sborman
80844364Sborman sprintf(nfrontp, "\r\n");
80944364Sborman nfrontp += strlen(nfrontp);
81044364Sborman break;
81144364Sborman
81244364Sborman case SB:
81344364Sborman sprintf(nfrontp, " SB ");
81444364Sborman nfrontp += strlen(nfrontp);
81544364Sborman i++;
81644364Sborman j = k = i;
81744364Sborman while (j < length) {
81844364Sborman if (pointer[j] == SE) {
81944364Sborman if (j+1 == length)
82044364Sborman break;
82144364Sborman if (pointer[j+1] == SE)
82244364Sborman j++;
82344364Sborman else
82444364Sborman break;
82544364Sborman }
82644364Sborman pointer[k++] = pointer[j++];
82744364Sborman }
82844364Sborman printsub(0, &pointer[i], k - i);
82944364Sborman if (i < length) {
83044364Sborman sprintf(nfrontp, " SE");
83144364Sborman nfrontp += strlen(nfrontp);
83244364Sborman i = j;
83344364Sborman } else
83444364Sborman i = j - 1;
83544364Sborman
83644364Sborman sprintf(nfrontp, "\r\n");
83744364Sborman nfrontp += strlen(nfrontp);
83844364Sborman
83944364Sborman break;
840*69786Sdab
84144364Sborman default:
84244364Sborman sprintf(nfrontp, " %d", pointer[i]);
84344364Sborman nfrontp += strlen(nfrontp);
84444364Sborman break;
84544364Sborman }
84644364Sborman }
84744364Sborman break;
84844364Sborman }
84944364Sborman break;
85044364Sborman }
85144364Sborman
85244364Sborman case TELOPT_XDISPLOC:
85344364Sborman sprintf(nfrontp, "X-DISPLAY-LOCATION ");
85444364Sborman nfrontp += strlen(nfrontp);
85544364Sborman switch (pointer[1]) {
85644364Sborman case TELQUAL_IS:
85744364Sborman sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
85844364Sborman break;
85944364Sborman case TELQUAL_SEND:
86044364Sborman sprintf(nfrontp, "SEND");
86144364Sborman break;
86244364Sborman default:
86344364Sborman sprintf(nfrontp, "- unknown qualifier %d (0x%x).",
86444364Sborman pointer[1], pointer[1]);
86544364Sborman }
86644364Sborman nfrontp += strlen(nfrontp);
86744364Sborman break;
86844364Sborman
86965158Sdab case TELOPT_NEW_ENVIRON:
87065158Sdab sprintf(nfrontp, "NEW-ENVIRON ");
87165158Sdab goto env_common1;
87265158Sdab case TELOPT_OLD_ENVIRON:
87365158Sdab sprintf(nfrontp, "OLD-ENVIRON");
87465158Sdab env_common1:
87544364Sborman nfrontp += strlen(nfrontp);
87644364Sborman switch (pointer[1]) {
87744364Sborman case TELQUAL_IS:
87844364Sborman sprintf(nfrontp, "IS ");
87944364Sborman goto env_common;
88044364Sborman case TELQUAL_SEND:
88144364Sborman sprintf(nfrontp, "SEND ");
88244364Sborman goto env_common;
88344364Sborman case TELQUAL_INFO:
88444364Sborman sprintf(nfrontp, "INFO ");
88544364Sborman env_common:
88665158Sdab nfrontp += strlen(nfrontp);
88744364Sborman {
88844364Sborman register int noquote = 2;
88944364Sborman for (i = 2; i < length; i++ ) {
89044364Sborman switch (pointer[i]) {
89165158Sdab case NEW_ENV_VAR:
89244364Sborman sprintf(nfrontp, "\" VAR " + noquote);
89344364Sborman nfrontp += strlen(nfrontp);
89444364Sborman noquote = 2;
89544364Sborman break;
89644364Sborman
89765158Sdab case NEW_ENV_VALUE:
89844364Sborman sprintf(nfrontp, "\" VALUE " + noquote);
89944364Sborman nfrontp += strlen(nfrontp);
90044364Sborman noquote = 2;
90144364Sborman break;
90244364Sborman
90344364Sborman case ENV_ESC:
90444364Sborman sprintf(nfrontp, "\" ESC " + noquote);
90544364Sborman nfrontp += strlen(nfrontp);
90644364Sborman noquote = 2;
90744364Sborman break;
90844364Sborman
90957212Sdab case ENV_USERVAR:
91057212Sdab sprintf(nfrontp, "\" USERVAR " + noquote);
91157212Sdab nfrontp += strlen(nfrontp);
91257212Sdab noquote = 2;
91357212Sdab break;
91457212Sdab
91544364Sborman default:
91644364Sborman def_case:
91744364Sborman if (isprint(pointer[i]) && pointer[i] != '"') {
91844364Sborman if (noquote) {
91944364Sborman *nfrontp++ = '"';
92044364Sborman noquote = 0;
92144364Sborman }
92244364Sborman *nfrontp++ = pointer[i];
92344364Sborman } else {
92444364Sborman sprintf(nfrontp, "\" %03o " + noquote,
92544364Sborman pointer[i]);
92644364Sborman nfrontp += strlen(nfrontp);
92744364Sborman noquote = 2;
92844364Sborman }
92944364Sborman break;
93044364Sborman }
93144364Sborman }
93244364Sborman if (!noquote)
93344364Sborman *nfrontp++ = '"';
93444364Sborman break;
93544364Sborman }
93644364Sborman }
93744364Sborman break;
93844364Sborman
93957212Sdab #if defined(AUTHENTICATION)
94046809Sdab case TELOPT_AUTHENTICATION:
94146809Sdab sprintf(nfrontp, "AUTHENTICATION");
94246809Sdab nfrontp += strlen(nfrontp);
943*69786Sdab
94446809Sdab if (length < 2) {
94565158Sdab sprintf(nfrontp, " (empty suboption??\?)");
94646809Sdab nfrontp += strlen(nfrontp);
94746809Sdab break;
94846809Sdab }
94946809Sdab switch (pointer[1]) {
95046809Sdab case TELQUAL_REPLY:
95146809Sdab case TELQUAL_IS:
95246809Sdab sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ?
95346809Sdab "IS" : "REPLY");
95446809Sdab nfrontp += strlen(nfrontp);
95546809Sdab if (AUTHTYPE_NAME_OK(pointer[2]))
95646809Sdab sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2]));
95746809Sdab else
95846809Sdab sprintf(nfrontp, "%d ", pointer[2]);
95946809Sdab nfrontp += strlen(nfrontp);
96046809Sdab if (length < 3) {
96165158Sdab sprintf(nfrontp, "(partial suboption??\?)");
96246809Sdab nfrontp += strlen(nfrontp);
96346809Sdab break;
96446809Sdab }
96546809Sdab sprintf(nfrontp, "%s|%s",
96647611Sdab ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
96746809Sdab "CLIENT" : "SERVER",
96847611Sdab ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
96946809Sdab "MUTUAL" : "ONE-WAY");
97046809Sdab nfrontp += strlen(nfrontp);
97146809Sdab
97246809Sdab auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
97346809Sdab sprintf(nfrontp, "%s", buf);
97446809Sdab nfrontp += strlen(nfrontp);
97546809Sdab break;
97646809Sdab
97746809Sdab case TELQUAL_SEND:
97846809Sdab i = 2;
97946809Sdab sprintf(nfrontp, " SEND ");
98046809Sdab nfrontp += strlen(nfrontp);
98146809Sdab while (i < length) {
98246809Sdab if (AUTHTYPE_NAME_OK(pointer[i]))
98346809Sdab sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i]));
98446809Sdab else
98546809Sdab sprintf(nfrontp, "%d ", pointer[i]);
98646809Sdab nfrontp += strlen(nfrontp);
98746809Sdab if (++i >= length) {
98865158Sdab sprintf(nfrontp, "(partial suboption??\?)");
98946809Sdab nfrontp += strlen(nfrontp);
99046809Sdab break;
99146809Sdab }
99246809Sdab sprintf(nfrontp, "%s|%s ",
99347611Sdab ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
99446809Sdab "CLIENT" : "SERVER",
99547611Sdab ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
99646809Sdab "MUTUAL" : "ONE-WAY");
99746809Sdab nfrontp += strlen(nfrontp);
99846809Sdab ++i;
99946809Sdab }
100046809Sdab break;
100146809Sdab
100247611Sdab case TELQUAL_NAME:
100347611Sdab i = 2;
100447611Sdab sprintf(nfrontp, " NAME \"");
100547611Sdab nfrontp += strlen(nfrontp);
100647611Sdab while (i < length)
100747611Sdab *nfrontp += pointer[i++];
100847611Sdab *nfrontp += '"';
100947611Sdab break;
101047611Sdab
101146809Sdab default:
101246809Sdab for (i = 2; i < length; i++) {
101346809Sdab sprintf(nfrontp, " ?%d?", pointer[i]);
101446809Sdab nfrontp += strlen(nfrontp);
101546809Sdab }
101646809Sdab break;
101746809Sdab }
101846809Sdab break;
101946809Sdab #endif
102046809Sdab
102160151Sdab #ifdef ENCRYPTION
102246809Sdab case TELOPT_ENCRYPT:
102346809Sdab sprintf(nfrontp, "ENCRYPT");
102446809Sdab nfrontp += strlen(nfrontp);
102546809Sdab if (length < 2) {
102665158Sdab sprintf(nfrontp, " (empty suboption??\?)");
102746809Sdab nfrontp += strlen(nfrontp);
102846809Sdab break;
102946809Sdab }
103046809Sdab switch (pointer[1]) {
103146809Sdab case ENCRYPT_START:
103246809Sdab sprintf(nfrontp, " START");
103346809Sdab nfrontp += strlen(nfrontp);
103446809Sdab break;
103546809Sdab
103646809Sdab case ENCRYPT_END:
103746809Sdab sprintf(nfrontp, " END");
103846809Sdab nfrontp += strlen(nfrontp);
103946809Sdab break;
104046809Sdab
104146809Sdab case ENCRYPT_REQSTART:
104246809Sdab sprintf(nfrontp, " REQUEST-START");
104346809Sdab nfrontp += strlen(nfrontp);
104446809Sdab break;
104546809Sdab
104646809Sdab case ENCRYPT_REQEND:
104746809Sdab sprintf(nfrontp, " REQUEST-END");
104846809Sdab nfrontp += strlen(nfrontp);
104946809Sdab break;
105046809Sdab
105146809Sdab case ENCRYPT_IS:
105246809Sdab case ENCRYPT_REPLY:
105346809Sdab sprintf(nfrontp, " %s ", (pointer[1] == ENCRYPT_IS) ?
105446809Sdab "IS" : "REPLY");
105546809Sdab nfrontp += strlen(nfrontp);
105646809Sdab if (length < 3) {
105765158Sdab sprintf(nfrontp, " (partial suboption??\?)");
105846809Sdab nfrontp += strlen(nfrontp);
105946809Sdab break;
106046809Sdab }
106146809Sdab if (ENCTYPE_NAME_OK(pointer[2]))
106246809Sdab sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[2]));
106346809Sdab else
106446809Sdab sprintf(nfrontp, " %d (unknown)", pointer[2]);
106546809Sdab nfrontp += strlen(nfrontp);
106646809Sdab
106746809Sdab encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
106846809Sdab sprintf(nfrontp, "%s", buf);
106946809Sdab nfrontp += strlen(nfrontp);
107046809Sdab break;
107146809Sdab
107246809Sdab case ENCRYPT_SUPPORT:
107346809Sdab i = 2;
107446809Sdab sprintf(nfrontp, " SUPPORT ");
107546809Sdab nfrontp += strlen(nfrontp);
107646809Sdab while (i < length) {
107746809Sdab if (ENCTYPE_NAME_OK(pointer[i]))
107846809Sdab sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[i]));
107946809Sdab else
108046809Sdab sprintf(nfrontp, "%d ", pointer[i]);
108146809Sdab nfrontp += strlen(nfrontp);
108246809Sdab i++;
108346809Sdab }
108446809Sdab break;
108546809Sdab
108647611Sdab case ENCRYPT_ENC_KEYID:
108747611Sdab sprintf(nfrontp, " ENC_KEYID", pointer[1]);
108847611Sdab nfrontp += strlen(nfrontp);
108947611Sdab goto encommon;
109047611Sdab
109147611Sdab case ENCRYPT_DEC_KEYID:
109247611Sdab sprintf(nfrontp, " DEC_KEYID", pointer[1]);
109347611Sdab nfrontp += strlen(nfrontp);
109447611Sdab goto encommon;
109547611Sdab
109646809Sdab default:
109747611Sdab sprintf(nfrontp, " %d (unknown)", pointer[1]);
109846809Sdab nfrontp += strlen(nfrontp);
109947611Sdab encommon:
110046809Sdab for (i = 2; i < length; i++) {
110146809Sdab sprintf(nfrontp, " %d", pointer[i]);
110246809Sdab nfrontp += strlen(nfrontp);
110346809Sdab }
110446809Sdab break;
110546809Sdab }
110646809Sdab break;
110760151Sdab #endif /* ENCRYPTION */
110846809Sdab
110944364Sborman default:
111046809Sdab if (TELOPT_OK(pointer[0]))
1111*69786Sdab sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0]));
111246809Sdab else
1113*69786Sdab sprintf(nfrontp, "%d (unknown)", pointer[i]);
111444364Sborman nfrontp += strlen(nfrontp);
111546809Sdab for (i = 1; i < length; i++) {
111644364Sborman sprintf(nfrontp, " %d", pointer[i]);
111744364Sborman nfrontp += strlen(nfrontp);
111844364Sborman }
111944364Sborman break;
112044364Sborman }
112144364Sborman sprintf(nfrontp, "\r\n");
112244364Sborman nfrontp += strlen(nfrontp);
112344364Sborman }
112444364Sborman
112544364Sborman /*
112644364Sborman * Dump a data buffer in hex and ascii to the output data stream.
112744364Sborman */
112846809Sdab void
printdata(tag,ptr,cnt)112944364Sborman printdata(tag, ptr, cnt)
113046809Sdab register char *tag;
113146809Sdab register char *ptr;
113246809Sdab register int cnt;
113344364Sborman {
113446809Sdab register int i;
113546809Sdab char xbuf[30];
113644364Sborman
113744364Sborman while (cnt) {
113844364Sborman /* flush net output buffer if no room for new data) */
113944364Sborman if ((&netobuf[BUFSIZ] - nfrontp) < 80) {
114044364Sborman netflush();
114144364Sborman }
114244364Sborman
114344364Sborman /* add a line of output */
114444364Sborman sprintf(nfrontp, "%s: ", tag);
114544364Sborman nfrontp += strlen(nfrontp);
114644364Sborman for (i = 0; i < 20 && cnt; i++) {
114744364Sborman sprintf(nfrontp, "%02x", *ptr);
1148*69786Sdab nfrontp += strlen(nfrontp);
114944364Sborman if (isprint(*ptr)) {
115044364Sborman xbuf[i] = *ptr;
115144364Sborman } else {
115244364Sborman xbuf[i] = '.';
115344364Sborman }
1154*69786Sdab if (i % 2) {
115544364Sborman *nfrontp = ' ';
115644364Sborman nfrontp++;
115744364Sborman }
115844364Sborman cnt--;
115944364Sborman ptr++;
116044364Sborman }
116144364Sborman xbuf[i] = '\0';
116244364Sborman sprintf(nfrontp, " %s\r\n", xbuf );
116344364Sborman nfrontp += strlen(nfrontp);
1164*69786Sdab }
116544364Sborman }
116644364Sborman #endif /* DIAGNOSTICS */
1167