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*65158Sdab static char sccsid[] = "@(#)utility.c 8.2 (Berkeley) 12/15/93"; 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 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 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 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 * 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 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; 19738905Sborman bcopy(thisitem, good, 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 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 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 30438905Sborman bcopy(ptr, nfrontp, 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 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 33938905Sborman fatalperror(f, msg) 34038905Sborman int f; 34138905Sborman char *msg; 34238905Sborman { 34342411Sbostic char buf[BUFSIZ], *strerror(); 34438905Sborman 34542411Sbostic (void) sprintf(buf, "%s: %s\r\n", msg, strerror(errno)); 34638905Sborman fatal(f, buf); 34738905Sborman } 34838905Sborman 34938905Sborman char editedhost[32]; 35038905Sborman 35146809Sdab void 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 39538905Sborman putstr(s) 39646809Sdab register char *s; 39738905Sborman { 39838905Sborman 39938905Sborman while (*s) 40038905Sborman putchr(*s++); 40138905Sborman } 40238905Sborman 40346809Sdab void 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 41838905Sborman putf(cp, where) 41946809Sdab register char *cp; 42046809Sdab char *where; 42138905Sborman { 42246809Sdab char *slash; 42346123Sbostic time_t t; 42446809Sdab char db[100]; 425*65158Sdab #ifdef STREAMSPTY 426*65158Sdab extern char *index(); 427*65158Sdab #else 42838905Sborman extern char *rindex(); 429*65158Sdab #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 */ 44357212Sdab slash = index(line+1, '/'); 44457212Sdab #else 44538905Sborman slash = rindex(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 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 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 49946809Sdab 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) { 536*65158Sdab 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) { 562*65158Sdab 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) { 589*65158Sdab 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) { 616*65158Sdab 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) { 648*65158Sdab 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) { 667*65158Sdab 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; 69044364Sborman 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) { 737*65158Sdab 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; 84044364Sborman 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 869*65158Sdab case TELOPT_NEW_ENVIRON: 870*65158Sdab sprintf(nfrontp, "NEW-ENVIRON "); 871*65158Sdab goto env_common1; 872*65158Sdab case TELOPT_OLD_ENVIRON: 873*65158Sdab sprintf(nfrontp, "OLD-ENVIRON"); 874*65158Sdab 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: 886*65158Sdab nfrontp += strlen(nfrontp); 88744364Sborman { 88844364Sborman register int noquote = 2; 88944364Sborman for (i = 2; i < length; i++ ) { 89044364Sborman switch (pointer[i]) { 891*65158Sdab case NEW_ENV_VAR: 89244364Sborman sprintf(nfrontp, "\" VAR " + noquote); 89344364Sborman nfrontp += strlen(nfrontp); 89444364Sborman noquote = 2; 89544364Sborman break; 89644364Sborman 897*65158Sdab 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); 94346809Sdab 94446809Sdab if (length < 2) { 945*65158Sdab 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) { 961*65158Sdab 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) { 988*65158Sdab 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) { 1026*65158Sdab 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) { 1057*65158Sdab 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])) 111146809Sdab sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0])); 111246809Sdab else 111346809Sdab 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 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); 114844364Sborman nfrontp += strlen(nfrontp); 114944364Sborman if (isprint(*ptr)) { 115044364Sborman xbuf[i] = *ptr; 115144364Sborman } else { 115244364Sborman xbuf[i] = '.'; 115344364Sborman } 115444364Sborman 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); 116444364Sborman } 116544364Sborman } 116644364Sborman #endif /* DIAGNOSTICS */ 1167