diff options
Diffstat (limited to 'share/security/patches/SA-01:49/telnetd-crypto.patch')
-rw-r--r-- | share/security/patches/SA-01:49/telnetd-crypto.patch | 2651 |
1 files changed, 2651 insertions, 0 deletions
diff --git a/share/security/patches/SA-01:49/telnetd-crypto.patch b/share/security/patches/SA-01:49/telnetd-crypto.patch new file mode 100644 index 0000000000..41bc004459 --- /dev/null +++ b/share/security/patches/SA-01:49/telnetd-crypto.patch @@ -0,0 +1,2651 @@ +Index: libexec/telnetd/ext.h +=================================================================== +RCS file: /home/ncvs/src/libexec/telnetd/ext.h,v +retrieving revision 1.8 +retrieving revision 1.10 +diff -u -r1.8 -r1.10 +--- libexec/telnetd/ext.h 2000/11/19 10:01:27 1.8 ++++ libexec/telnetd/ext.h 2001/07/23 22:00:51 1.10 +@@ -76,7 +76,7 @@ + + extern char netibuf[BUFSIZ], *netip; + +-extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; ++extern char netobuf[BUFSIZ], *nfrontp, *nbackp; + extern char *neturg; /* one past last bye of urgent data */ + + extern int pcc, ncc; +@@ -189,8 +189,10 @@ + tty_setsofttab P((int)), + tty_tspeed P((int)), + willoption P((int)), +- wontoption P((int)), +- writenet P((unsigned char *, int)); ++ wontoption P((int)); ++ ++int output_data __P((const char *, ...)) __printflike(1, 2); ++void output_datalen __P((const char *, int)); + + + +Index: libexec/telnetd/slc.c +=================================================================== +RCS file: /home/ncvs/src/libexec/telnetd/slc.c,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -u -r1.9 -r1.11 +--- libexec/telnetd/slc.c 2001/02/07 22:18:58 1.9 ++++ libexec/telnetd/slc.c 2001/07/23 22:00:51 1.11 +@@ -176,7 +176,6 @@ + register unsigned char **bufp; + { + register int len; +- void netflush(); + + /* + * If a change has occured, store the new terminal control +@@ -204,7 +203,7 @@ + (void) sprintf((char *)slcptr, "%c%c", IAC, SE); + slcptr += 2; + len = slcptr - slcbuf; +- writenet(slcbuf, len); ++ output_datalen(slcbuf, len); + netflush(); /* force it out immediately */ + DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2);); + } +Index: libexec/telnetd/state.c +=================================================================== +RCS file: /home/ncvs/src/libexec/telnetd/state.c,v +retrieving revision 1.12 +retrieving revision 1.14 +diff -u -r1.12 -r1.14 +--- libexec/telnetd/state.c 2001/02/18 10:25:15 1.12 ++++ libexec/telnetd/state.c 2001/07/23 22:00:51 1.14 +@@ -39,6 +39,7 @@ + "$FreeBSD$"; + #endif /* not lint */ + ++#include <stdarg.h> + #include "telnetd.h" + #if defined(AUTHENTICATION) + #include <libtelnet/auth.h> +@@ -190,8 +191,7 @@ + } + + netclear(); /* clear buffer back */ +- *nfrontp++ = IAC; +- *nfrontp++ = DM; ++ output_data("%c%c", IAC, DM); + neturg = nfrontp-1; /* off by one XXX */ + DIAG(TD_OPTIONS, + printoption("td: send IAC", DM)); +@@ -444,8 +444,7 @@ + set_his_want_state_will(option); + do_dont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)doopt, option); +- nfrontp += sizeof (dont) - 2; ++ output_data((const char *)doopt, option); + + DIAG(TD_OPTIONS, printoption("td: send do", option)); + } +@@ -650,8 +649,7 @@ + set_his_want_state_wont(option); + do_dont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)dont, option); +- nfrontp += sizeof (doopt) - 2; ++ output_data((const char *)dont, option); + + DIAG(TD_OPTIONS, printoption("td: send dont", option)); + } +@@ -800,8 +798,7 @@ + set_my_want_state_will(option); + will_wont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)will, option); +- nfrontp += sizeof (doopt) - 2; ++ output_data((const char *)will, option); + + DIAG(TD_OPTIONS, printoption("td: send will", option)); + } +@@ -954,8 +951,7 @@ + set_my_want_state_wont(option); + will_wont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)wont, option); +- nfrontp += sizeof (wont) - 2; ++ output_data((const char *)wont, option); + + DIAG(TD_OPTIONS, printoption("td: send wont", option)); + } +@@ -1351,9 +1347,8 @@ + env_ovar_wrong: + env_ovar = OLD_ENV_VALUE; + env_ovalue = OLD_ENV_VAR; +- DIAG(TD_OPTIONS, {sprintf(nfrontp, +- "ENVIRON VALUE and VAR are reversed!\r\n"); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_OPTIONS, ++ output_data("ENVIRON VALUE and VAR are reversed!\r\n")); + + } + } +@@ -1542,9 +1537,55 @@ + ADD(IAC); + ADD(SE); + +- writenet(statusbuf, ncp - statusbuf); ++ output_datalen(statusbuf, ncp - statusbuf); + netflush(); /* Send it on its way */ + + DIAG(TD_OPTIONS, + {printsub('>', statusbuf, ncp - statusbuf); netflush();}); ++} ++ ++/* ++ * This function appends data to nfrontp and advances nfrontp. ++ * Returns the number of characters written altogether (the ++ * buffer may have been flushed in the process). ++ */ ++ ++int ++output_data(const char *format, ...) ++{ ++ va_list args; ++ int len; ++ char *buf; ++ ++ va_start(args, format); ++ if ((len = vasprintf(&buf, format, args)) == -1) ++ return -1; ++ output_datalen(buf, len); ++ va_end(args); ++ free(buf); ++ return (len); ++} ++ ++void ++output_datalen(const char *buf, int len) ++{ ++ int remaining, copied; ++ ++ remaining = BUFSIZ - (nfrontp - netobuf); ++ while (len > 0) { ++ /* Free up enough space if the room is too low*/ ++ if ((len > BUFSIZ ? BUFSIZ : len) > remaining) { ++ netflush(); ++ remaining = BUFSIZ - (nfrontp - netobuf); ++ } ++ ++ /* Copy out as much as will fit */ ++ copied = remaining > len ? len : remaining; ++ memmove(nfrontp, buf, copied); ++ nfrontp += copied; ++ len -= copied; ++ remaining -= copied; ++ buf += copied; ++ } ++ return; + } +Index: libexec/telnetd/telnetd.c +=================================================================== +RCS file: /home/ncvs/src/libexec/telnetd/telnetd.c,v +retrieving revision 1.27 +retrieving revision 1.29 +diff -u -r1.27 -r1.29 +--- libexec/telnetd/telnetd.c 2001/02/06 09:24:52 1.27 ++++ libexec/telnetd/telnetd.c 2001/07/23 22:00:51 1.29 +@@ -644,34 +644,29 @@ + static unsigned char sb[] = + { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; + +- bcopy(sb, nfrontp, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + } + if (his_state_is_will(TELOPT_XDISPLOC)) { + static unsigned char sb[] = + { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; + +- bcopy(sb, nfrontp, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + } + if (his_state_is_will(TELOPT_NEW_ENVIRON)) { + static unsigned char sb[] = + { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; + +- bcopy(sb, nfrontp, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + } + else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { + static unsigned char sb[] = + { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; + +- bcopy(sb, nfrontp, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + } + if (his_state_is_will(TELOPT_TTYPE)) { + +- bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf); +- nfrontp += sizeof ttytype_sbbuf; ++ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf); + } + if (his_state_is_will(TELOPT_TSPEED)) { + while (sequenceIs(tspeedsubopt, baseline)) +@@ -748,8 +743,7 @@ + if (his_state_is_wont(TELOPT_TTYPE)) + return; + settimer(baseline); +- bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf); +- nfrontp += sizeof ttytype_sbbuf; ++ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf); + while (sequenceIs(ttypesubopt, baseline)) + ttloop(); + } +@@ -915,8 +909,6 @@ + int if_fd; + struct stat statbuf; + +- void netflush(); +- + /* + * Initialize the slc mapping table. + */ +@@ -1000,9 +992,7 @@ + * mode, which we do not want. + */ + if (his_want_state_is_will(TELOPT_ECHO)) { +- DIAG(TD_OPTIONS, +- {sprintf(nfrontp, "td: simulating recv\r\n"); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_OPTIONS, output_data("td: simulating recv\r\n")); + willoption(TELOPT_ECHO); + } + +@@ -1148,9 +1138,7 @@ + localstat(); + #endif /* LINEMODE */ + +- DIAG(TD_REPORT, +- {sprintf(nfrontp, "td: Entering processing loop\r\n"); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_REPORT, output_data("td: Entering processing loop\r\n")); + + /* + * Startup the login process on the slave side of the terminal +@@ -1278,8 +1266,7 @@ + netip = netibuf; + } + DIAG((TD_REPORT | TD_NETDATA), +- {sprintf(nfrontp, "td: netread %d chars\r\n", ncc); +- nfrontp += strlen(nfrontp);}); ++ output_data("td: netread %d chars\r\n", ncc)); + DIAG(TD_NETDATA, printdata("nd", netip, ncc)); + } + +@@ -1326,8 +1313,7 @@ + * royally if we send them urgent + * mode data. + */ +- *nfrontp++ = IAC; +- *nfrontp++ = DM; ++ output_data("%c%c", IAC, DM); + neturg = nfrontp-1; /* off by one XXX */ + #endif + } +@@ -1338,13 +1324,11 @@ + ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; + if (newflow != flowmode) { + flowmode = newflow; +- (void) sprintf(nfrontp, +- "%c%c%c%c%c%c", ++ output_data("%c%c%c%c%c%c", + IAC, SB, TELOPT_LFLOW, + flowmode ? LFLOW_ON + : LFLOW_OFF, + IAC, SE); +- nfrontp += 6; + } + } + pcc--; +@@ -1367,19 +1351,19 @@ + break; + c = *ptyip++ & 0377, pcc--; + if (c == IAC) +- *nfrontp++ = c; ++ output_data("%c", c); + #if defined(CRAY2) && defined(UNICOS5) + else if (c == '\n' && + my_state_is_wont(TELOPT_BINARY) && newmap) +- *nfrontp++ = '\r'; ++ output_data("\r"); + #endif /* defined(CRAY2) && defined(UNICOS5) */ +- *nfrontp++ = c; ++ output_data("%c", c); + if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) { + if (pcc > 0 && ((*ptyip & 0377) == '\n')) { +- *nfrontp++ = *ptyip++ & 0377; ++ output_data("%c", *ptyip++ & 0377); + pcc--; + } else +- *nfrontp++ = '\0'; ++ output_data("%c", '\0'); + } + } + #if defined(CRAY2) && defined(UNICOS5) +@@ -1564,8 +1548,7 @@ + return; + } + #endif +- (void) strcpy(nfrontp, "\r\n[Yes]\r\n"); +- nfrontp += 9; ++ output_data("\r\n[Yes]\r\n"); + } + + void +Index: libexec/telnetd/termstat.c +=================================================================== +RCS file: /home/ncvs/src/libexec/telnetd/termstat.c,v +retrieving revision 1.10 +retrieving revision 1.12 +diff -u -r1.10 -r1.12 +--- libexec/telnetd/termstat.c 2001/02/06 10:39:24 1.10 ++++ libexec/telnetd/termstat.c 2001/07/23 22:00:51 1.12 +@@ -136,7 +136,6 @@ + void + localstat() + { +- void netflush(); + int need_will_echo = 0; + + #if defined(CRAY2) && defined(UNICOS5) +@@ -279,10 +278,9 @@ + # endif /* KLUDGELINEMODE */ + send_do(TELOPT_LINEMODE, 1); + /* send along edit modes */ +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, ++ output_data("%c%c%c%c%c%c%c", IAC, SB, + TELOPT_LINEMODE, LM_MODE, useeditmode, + IAC, SE); +- nfrontp += 7; + editmode = useeditmode; + # ifdef KLUDGELINEMODE + } +@@ -308,10 +306,9 @@ + /* + * Send along appropriate edit mode mask. + */ +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, ++ output_data("%c%c%c%c%c%c%c", IAC, SB, + TELOPT_LINEMODE, LM_MODE, useeditmode, + IAC, SE); +- nfrontp += 7; + editmode = useeditmode; + } + +@@ -355,20 +352,18 @@ + if (his_state_is_will(TELOPT_LFLOW)) { + if (tty_flowmode() != flowmode) { + flowmode = tty_flowmode(); +- (void) sprintf(nfrontp, "%c%c%c%c%c%c", ++ output_data("%c%c%c%c%c%c", + IAC, SB, TELOPT_LFLOW, + flowmode ? LFLOW_ON : LFLOW_OFF, + IAC, SE); +- nfrontp += 6; + } + if (tty_restartany() != restartany) { + restartany = tty_restartany(); +- (void) sprintf(nfrontp, "%c%c%c%c%c%c", ++ output_data("%c%c%c%c%c%c", + IAC, SB, TELOPT_LFLOW, + restartany ? LFLOW_RESTART_ANY + : LFLOW_RESTART_XON, + IAC, SE); +- nfrontp += 6; + } + } + } +@@ -385,7 +380,6 @@ + clientstat(code, parm1, parm2) + register int code, parm1, parm2; + { +- void netflush(); + + /* + * Get a copy of terminal characteristics. +@@ -441,10 +435,9 @@ + useeditmode |= MODE_SOFT_TAB; + if (tty_islitecho()) + useeditmode |= MODE_LIT_ECHO; +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, ++ output_data("%c%c%c%c%c%c%c", IAC, + SB, TELOPT_LINEMODE, LM_MODE, + useeditmode, IAC, SE); +- nfrontp += 7; + editmode = useeditmode; + } + +@@ -500,11 +493,10 @@ + set_termbuf(); + + if (!ack) { +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, ++ output_data("%c%c%c%c%c%c%c", IAC, + SB, TELOPT_LINEMODE, LM_MODE, + useeditmode|MODE_ACK, + IAC, SE); +- nfrontp += 7; + } + + editmode = useeditmode; +Index: libexec/telnetd/utility.c +=================================================================== +RCS file: /home/ncvs/src/libexec/telnetd/utility.c,v +retrieving revision 1.14 +retrieving revision 1.16 +diff -u -r1.14 -r1.16 +--- libexec/telnetd/utility.c 2000/10/31 05:29:54 1.14 ++++ libexec/telnetd/utility.c 2001/07/23 22:00:51 1.16 +@@ -62,11 +62,9 @@ + void + ttloop() + { +- void netflush(); + +- DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n"); +- nfrontp += strlen(nfrontp);}); +- if (nfrontp-nbackp) { ++ DIAG(TD_REPORT, output_data("td: ttloop\r\n")); ++ if (nfrontp - nbackp > 0) { + netflush(); + } + ncc = read(net, netibuf, sizeof netibuf); +@@ -77,8 +75,7 @@ + syslog(LOG_INFO, "ttloop: peer died: %m"); + exit(1); + } +- DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_REPORT, output_data("td: ttloop read %d chars\r\n", ncc)); + netip = netibuf; + telrcv(); /* state machine */ + if (ncc > 0) { +@@ -121,9 +118,8 @@ + int n; + + if ((n = pfrontp - pbackp) > 0) { +- DIAG((TD_REPORT | TD_PTYDATA), +- { sprintf(nfrontp, "td: ptyflush %d chars\r\n", n); +- nfrontp += strlen(nfrontp); }); ++ DIAG(TD_REPORT | TD_PTYDATA, ++ output_data("td: ptyflush %d chars\r\n", n)); + DIAG(TD_PTYDATA, printdata("pd", pbackp, n)); + n = write(pty, pbackp, n); + } +@@ -245,12 +241,13 @@ + int n; + extern int not42; + +- if ((n = nfrontp - nbackp) > 0) { +- DIAG(TD_REPORT, +- { sprintf(nfrontp, "td: netflush %d chars\r\n", n); +- n += strlen(nfrontp); /* get count first */ +- nfrontp += strlen(nfrontp); /* then move pointer */ +- }); ++ while ((n = nfrontp - nbackp) > 0) { ++#if 0 ++ /* XXX This causes output_data() to recurse and die */ ++ DIAG(TD_REPORT, { ++ n += output_data("td: netflush %d chars\r\n", n); ++ }); ++#endif + /* + * if no urgent data, or if the other side appears to be an + * old 4.2 client (and thus unable to survive TCP urgent data), +@@ -274,51 +271,25 @@ + n = send(net, nbackp, n, MSG_OOB); /* URGENT data */ + } + } +- } +- if (n < 0) { +- if (errno == EWOULDBLOCK || errno == EINTR) +- return; +- cleanup(0); +- } +- nbackp += n; +- if (nbackp >= neturg) { +- neturg = 0; +- } +- if (nbackp == nfrontp) { +- nbackp = nfrontp = netobuf; ++ if (n == -1) { ++ if (errno == EWOULDBLOCK || errno == EINTR) ++ continue; ++ cleanup(0); ++ /* NOTREACHED */ ++ } ++ nbackp += n; ++ if (nbackp >= neturg) { ++ neturg = 0; ++ } ++ if (nbackp == nfrontp) { ++ nbackp = nfrontp = netobuf; ++ } + } + return; + } /* end of netflush */ + + + /* +- * writenet +- * +- * Just a handy little function to write a bit of raw data to the net. +- * It will force a transmit of the buffer if necessary +- * +- * arguments +- * ptr - A pointer to a character string to write +- * len - How many bytes to write +- */ +- void +-writenet(ptr, len) +- register unsigned char *ptr; +- register int len; +-{ +- /* flush buffer if no room for new data) */ +- if ((&netobuf[BUFSIZ] - nfrontp) < len) { +- /* if this fails, don't worry, buffer is a little big */ +- netflush(); +- } +- +- bcopy(ptr, nfrontp, len); +- nfrontp += len; +- +-} /* end of writenet */ +- +- +-/* + * miscellaneous functions doing a variety of little jobs follow ... + */ + +@@ -513,12 +484,11 @@ + register int option; + { + if (TELOPT_OK(option)) +- sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option)); ++ output_data("%s %s\r\n", fmt, TELOPT(option)); + else if (TELCMD_OK(option)) +- sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option)); ++ output_data("%s %s\r\n", fmt, TELCMD(option)); + else +- sprintf(nfrontp, "%s %d\r\n", fmt, option); +- nfrontp += strlen(nfrontp); ++ output_data("%s %d\r\n", fmt, option); + return; + } + +@@ -534,9 +504,8 @@ + return; + + if (direction) { +- sprintf(nfrontp, "td: %s suboption ", ++ output_data("td: %s suboption ", + direction == '<' ? "recv" : "send"); +- nfrontp += strlen(nfrontp); + if (length >= 3) { + register int j; + +@@ -544,232 +513,192 @@ + j = pointer[length-1]; + + if (i != IAC || j != SE) { +- sprintf(nfrontp, "(terminated by "); +- nfrontp += strlen(nfrontp); ++ output_data("(terminated by "); + if (TELOPT_OK(i)) +- sprintf(nfrontp, "%s ", TELOPT(i)); ++ output_data("%s ", TELOPT(i)); + else if (TELCMD_OK(i)) +- sprintf(nfrontp, "%s ", TELCMD(i)); ++ output_data("%s ", TELCMD(i)); + else +- sprintf(nfrontp, "%d ", i); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", i); + if (TELOPT_OK(j)) +- sprintf(nfrontp, "%s", TELOPT(j)); ++ output_data("%s", TELOPT(j)); + else if (TELCMD_OK(j)) +- sprintf(nfrontp, "%s", TELCMD(j)); ++ output_data("%s", TELCMD(j)); + else +- sprintf(nfrontp, "%d", j); +- nfrontp += strlen(nfrontp); +- sprintf(nfrontp, ", not IAC SE!) "); +- nfrontp += strlen(nfrontp); ++ output_data("%d", j); ++ output_data(", not IAC SE!) "); + } + } + length -= 2; + } + if (length < 1) { +- sprintf(nfrontp, "(Empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(Empty suboption??\?)"); + return; + } + switch (pointer[0]) { + case TELOPT_TTYPE: +- sprintf(nfrontp, "TERMINAL-TYPE "); +- nfrontp += strlen(nfrontp); ++ output_data("TERMINAL-TYPE "); + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); ++ output_data("IS \"%.*s\"", length-2, (char *)pointer+2); + break; + case TELQUAL_SEND: +- sprintf(nfrontp, "SEND"); ++ output_data("SEND"); + break; + default: +- sprintf(nfrontp, ++ output_data( + "- unknown qualifier %d (0x%x).", + pointer[1], pointer[1]); + } +- nfrontp += strlen(nfrontp); + break; + case TELOPT_TSPEED: +- sprintf(nfrontp, "TERMINAL-SPEED"); +- nfrontp += strlen(nfrontp); ++ output_data("TERMINAL-SPEED"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2); +- nfrontp += strlen(nfrontp); ++ output_data(" IS %.*s", length-2, (char *)pointer+2); + break; + default: + if (pointer[1] == 1) +- sprintf(nfrontp, " SEND"); ++ output_data(" SEND"); + else +- sprintf(nfrontp, " %d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d (unknown)", pointer[1]); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + } + break; + + case TELOPT_LFLOW: +- sprintf(nfrontp, "TOGGLE-FLOW-CONTROL"); +- nfrontp += strlen(nfrontp); ++ output_data("TOGGLE-FLOW-CONTROL"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case LFLOW_OFF: +- sprintf(nfrontp, " OFF"); break; ++ output_data(" OFF"); break; + case LFLOW_ON: +- sprintf(nfrontp, " ON"); break; ++ output_data(" ON"); break; + case LFLOW_RESTART_ANY: +- sprintf(nfrontp, " RESTART-ANY"); break; ++ output_data(" RESTART-ANY"); break; + case LFLOW_RESTART_XON: +- sprintf(nfrontp, " RESTART-XON"); break; ++ output_data(" RESTART-XON"); break; + default: +- sprintf(nfrontp, " %d (unknown)", pointer[1]); ++ output_data(" %d (unknown)", pointer[1]); + } +- nfrontp += strlen(nfrontp); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + + case TELOPT_NAWS: +- sprintf(nfrontp, "NAWS"); +- nfrontp += strlen(nfrontp); ++ output_data("NAWS"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + if (length == 2) { +- sprintf(nfrontp, " ?%d?", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[1]); + break; + } +- sprintf(nfrontp, " %d %d (%d)", ++ output_data(" %d %d (%d)", + pointer[1], pointer[2], + (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); +- nfrontp += strlen(nfrontp); + if (length == 4) { +- sprintf(nfrontp, " ?%d?", pointer[3]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[3]); + break; + } +- sprintf(nfrontp, " %d %d (%d)", ++ output_data(" %d %d (%d)", + pointer[3], pointer[4], + (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); +- nfrontp += strlen(nfrontp); + for (i = 5; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + + case TELOPT_LINEMODE: +- sprintf(nfrontp, "LINEMODE "); +- nfrontp += strlen(nfrontp); ++ output_data("LINEMODE "); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case WILL: +- sprintf(nfrontp, "WILL "); ++ output_data("WILL "); + goto common; + case WONT: +- sprintf(nfrontp, "WONT "); ++ output_data("WONT "); + goto common; + case DO: +- sprintf(nfrontp, "DO "); ++ output_data("DO "); + goto common; + case DONT: +- sprintf(nfrontp, "DONT "); ++ output_data("DONT "); + common: +- nfrontp += strlen(nfrontp); + if (length < 3) { +- sprintf(nfrontp, "(no option??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(no option??\?)"); + break; + } + switch (pointer[2]) { + case LM_FORWARDMASK: +- sprintf(nfrontp, "Forward Mask"); +- nfrontp += strlen(nfrontp); ++ output_data("Forward Mask"); + for (i = 3; i < length; i++) { +- sprintf(nfrontp, " %x", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %x", pointer[i]); + } + break; + default: +- sprintf(nfrontp, "%d (unknown)", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data("%d (unknown)", pointer[2]); + for (i = 3; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + break; + } + break; + + case LM_SLC: +- sprintf(nfrontp, "SLC"); +- nfrontp += strlen(nfrontp); ++ output_data("SLC"); + for (i = 2; i < length - 2; i += 3) { + if (SLC_NAME_OK(pointer[i+SLC_FUNC])) +- sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC])); ++ output_data(" %s", SLC_NAME(pointer[i+SLC_FUNC])); + else +- sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i+SLC_FUNC]); + switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { + case SLC_NOSUPPORT: +- sprintf(nfrontp, " NOSUPPORT"); break; ++ output_data(" NOSUPPORT"); break; + case SLC_CANTCHANGE: +- sprintf(nfrontp, " CANTCHANGE"); break; ++ output_data(" CANTCHANGE"); break; + case SLC_VARIABLE: +- sprintf(nfrontp, " VARIABLE"); break; ++ output_data(" VARIABLE"); break; + case SLC_DEFAULT: +- sprintf(nfrontp, " DEFAULT"); break; ++ output_data(" DEFAULT"); break; + } +- nfrontp += strlen(nfrontp); +- sprintf(nfrontp, "%s%s%s", ++ output_data("%s%s%s", + pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", + pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", + pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); +- nfrontp += strlen(nfrontp); + if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| + SLC_FLUSHOUT| SLC_LEVELBITS)) { +- sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]); +- nfrontp += strlen(nfrontp); ++ output_data("(0x%x)", pointer[i+SLC_FLAGS]); + } +- sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d;", pointer[i+SLC_VALUE]); + if ((pointer[i+SLC_VALUE] == IAC) && + (pointer[i+SLC_VALUE+1] == IAC)) + i++; + } + for (; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + + case LM_MODE: +- sprintf(nfrontp, "MODE "); +- nfrontp += strlen(nfrontp); ++ output_data("MODE "); + if (length < 3) { +- sprintf(nfrontp, "(no mode??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(no mode??\?)"); + break; + } + { +@@ -780,24 +709,19 @@ + pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", + pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", + pointer[2]&MODE_ACK ? "|ACK" : ""); +- sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0"); +- nfrontp += strlen(nfrontp); ++ output_data("%s", tbuf[1] ? &tbuf[1] : "0"); + } + if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) { +- sprintf(nfrontp, " (0x%x)", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data(" (0x%x)", pointer[2]); + } + for (i = 3; i < length; i++) { +- sprintf(nfrontp, " ?0x%x?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?0x%x?", pointer[i]); + } + break; + default: +- sprintf(nfrontp, "%d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data("%d (unknown)", pointer[1]); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + } + break; +@@ -806,24 +730,20 @@ + register char *cp; + register int j, k; + +- sprintf(nfrontp, "STATUS"); +- nfrontp += strlen(nfrontp); ++ output_data("STATUS"); + + switch (pointer[1]) { + default: + if (pointer[1] == TELQUAL_SEND) +- sprintf(nfrontp, " SEND"); ++ output_data(" SEND"); + else +- sprintf(nfrontp, " %d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d (unknown)", pointer[1]); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + case TELQUAL_IS: +- sprintf(nfrontp, " IS\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data(" IS\r\n"); + + for (i = 2; i < length; i++) { + switch(pointer[i]) { +@@ -834,18 +754,15 @@ + common2: + i++; + if (TELOPT_OK(pointer[i])) +- sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i])); ++ output_data(" %s %s", cp, TELOPT(pointer[i])); + else +- sprintf(nfrontp, " %s %d", cp, pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %s %d", cp, pointer[i]); + +- sprintf(nfrontp, "\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data("\r\n"); + break; + + case SB: +- sprintf(nfrontp, " SB "); +- nfrontp += strlen(nfrontp); ++ output_data(" SB "); + i++; + j = k = i; + while (j < length) { +@@ -861,20 +778,17 @@ + } + printsub(0, &pointer[i], k - i); + if (i < length) { +- sprintf(nfrontp, " SE"); +- nfrontp += strlen(nfrontp); ++ output_data(" SE"); + i = j; + } else + i = j - 1; + +- sprintf(nfrontp, "\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data("\r\n"); + + break; + + default: +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + break; + } + } +@@ -884,86 +798,77 @@ + } + + case TELOPT_XDISPLOC: +- sprintf(nfrontp, "X-DISPLAY-LOCATION "); +- nfrontp += strlen(nfrontp); ++ output_data("X-DISPLAY-LOCATION "); + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); ++ output_data("IS \"%.*s\"", length-2, (char *)pointer+2); + break; + case TELQUAL_SEND: +- sprintf(nfrontp, "SEND"); ++ output_data("SEND"); + break; + default: +- sprintf(nfrontp, "- unknown qualifier %d (0x%x).", ++ output_data("- unknown qualifier %d (0x%x).", + pointer[1], pointer[1]); + } +- nfrontp += strlen(nfrontp); + break; + + case TELOPT_NEW_ENVIRON: +- sprintf(nfrontp, "NEW-ENVIRON "); ++ output_data("NEW-ENVIRON "); + goto env_common1; + case TELOPT_OLD_ENVIRON: +- sprintf(nfrontp, "OLD-ENVIRON"); ++ output_data("OLD-ENVIRON"); + env_common1: +- nfrontp += strlen(nfrontp); + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, "IS "); ++ output_data("IS "); + goto env_common; + case TELQUAL_SEND: +- sprintf(nfrontp, "SEND "); ++ output_data("SEND "); + goto env_common; + case TELQUAL_INFO: +- sprintf(nfrontp, "INFO "); ++ output_data("INFO "); + env_common: +- nfrontp += strlen(nfrontp); + { + register int noquote = 2; + for (i = 2; i < length; i++ ) { + switch (pointer[i]) { + case NEW_ENV_VAR: +- sprintf(nfrontp, "\" VAR " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" VAR " + noquote); + noquote = 2; + break; + + case NEW_ENV_VALUE: +- sprintf(nfrontp, "\" VALUE " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" VALUE " + noquote); + noquote = 2; + break; + + case ENV_ESC: +- sprintf(nfrontp, "\" ESC " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" ESC " + noquote); + noquote = 2; + break; + + case ENV_USERVAR: +- sprintf(nfrontp, "\" USERVAR " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" USERVAR " + noquote); + noquote = 2; + break; + + default: + if (isprint(pointer[i]) && pointer[i] != '"') { + if (noquote) { +- *nfrontp++ = '"'; ++ output_data("\""); + noquote = 0; + } +- *nfrontp++ = pointer[i]; ++ output_data("%c", pointer[i]); + } else { +- sprintf(nfrontp, "\" %03o " + noquote, ++ output_data("\" %03o " + noquote, + pointer[i]); +- nfrontp += strlen(nfrontp); + noquote = 2; + } + break; + } + } + if (!noquote) +- *nfrontp++ = '"'; ++ output_data("\""); + break; + } + } +@@ -971,83 +876,66 @@ + + #if defined(AUTHENTICATION) + case TELOPT_AUTHENTICATION: +- sprintf(nfrontp, "AUTHENTICATION"); +- nfrontp += strlen(nfrontp); ++ output_data("AUTHENTICATION"); + + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case TELQUAL_REPLY: + case TELQUAL_IS: +- sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ? ++ output_data(" %s ", (pointer[1] == TELQUAL_IS) ? + "IS" : "REPLY"); +- nfrontp += strlen(nfrontp); + if (AUTHTYPE_NAME_OK(pointer[2])) +- sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2])); ++ output_data("%s ", AUTHTYPE_NAME(pointer[2])); + else +- sprintf(nfrontp, "%d ", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", pointer[2]); + if (length < 3) { +- sprintf(nfrontp, "(partial suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(partial suboption??\?)"); + break; + } +- sprintf(nfrontp, "%s|%s", ++ output_data("%s|%s", + ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? + "CLIENT" : "SERVER", + ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? + "MUTUAL" : "ONE-WAY"); +- nfrontp += strlen(nfrontp); + + { + char buf[512]; + auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); +- sprintf(nfrontp, "%s", buf); ++ output_data("%s", buf); + } +- nfrontp += strlen(nfrontp); + break; + + case TELQUAL_SEND: + i = 2; +- sprintf(nfrontp, " SEND "); +- nfrontp += strlen(nfrontp); ++ output_data(" SEND "); + while (i < length) { + if (AUTHTYPE_NAME_OK(pointer[i])) +- sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i])); ++ output_data("%s ", AUTHTYPE_NAME(pointer[i])); + else +- sprintf(nfrontp, "%d ", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", pointer[i]); + if (++i >= length) { +- sprintf(nfrontp, "(partial suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(partial suboption??\?)"); + break; + } +- sprintf(nfrontp, "%s|%s ", ++ output_data("%s|%s ", + ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? + "CLIENT" : "SERVER", + ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? + "MUTUAL" : "ONE-WAY"); +- nfrontp += strlen(nfrontp); + ++i; + } + break; + + case TELQUAL_NAME: +- i = 2; +- sprintf(nfrontp, " NAME \""); +- nfrontp += strlen(nfrontp); +- while (i < length) +- *nfrontp += pointer[i++]; +- *nfrontp += '"'; ++ output_data(" NAME \"%.*s\"", length - 2, pointer + 2); + break; + + default: + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + } +@@ -1057,18 +945,15 @@ + + default: + if (TELOPT_OK(pointer[0])) +- sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0])); ++ output_data("%s (unknown)", TELOPT(pointer[0])); + else +- sprintf(nfrontp, "%d (unknown)", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data("%d (unknown)", pointer[i]); + for (i = 1; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + break; + } +- sprintf(nfrontp, "\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data("\r\n"); + } + + /* +@@ -1090,26 +975,22 @@ + } + + /* add a line of output */ +- sprintf(nfrontp, "%s: ", tag); +- nfrontp += strlen(nfrontp); ++ output_data("%s: ", tag); + for (i = 0; i < 20 && cnt; i++) { +- sprintf(nfrontp, "%02x", *ptr); +- nfrontp += strlen(nfrontp); ++ output_data("%02x", *ptr); + if (isprint(*ptr)) { + xbuf[i] = *ptr; + } else { + xbuf[i] = '.'; + } + if (i % 2) { +- *nfrontp = ' '; +- nfrontp++; ++ output_data(" "); + } + cnt--; + ptr++; + } + xbuf[i] = '\0'; +- sprintf(nfrontp, " %s\r\n", xbuf ); +- nfrontp += strlen(nfrontp); ++ output_data(" %s\r\n", xbuf ); + } + } + #endif /* DIAGNOSTICS */ +Index: crypto/telnet/telnetd/authenc.c +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/authenc.c,v +retrieving revision 1.5 +retrieving revision 1.6 +diff -u -r1.5 -r1.6 +--- crypto/telnet/telnetd/authenc.c 2000/07/16 05:52:45 1.5 ++++ crypto/telnet/telnetd/authenc.c 2001/07/19 17:48:57 1.6 +@@ -49,8 +49,7 @@ + int len; + { + if (nfrontp + len < netobuf + BUFSIZ) { +- memmove((void *)nfrontp, (void *)str, len); +- nfrontp += len; ++ output_datalen(str, len); + return(len); + } + return(0); +Index: crypto/telnet/telnetd/ext.h +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/ext.h,v +retrieving revision 1.4 +retrieving revision 1.7 +diff -u -r1.4 -r1.7 +--- crypto/telnet/telnetd/ext.h 2000/07/16 05:52:45 1.4 ++++ crypto/telnet/telnetd/ext.h 2001/07/23 21:52:26 1.7 +@@ -74,7 +74,7 @@ + + extern char netibuf[BUFSIZ], *netip; + +-extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; ++extern char netobuf[BUFSIZ], *nfrontp, *nbackp; + extern char *neturg; /* one past last bye of urgent data */ + + extern int pcc, ncc; +@@ -187,8 +187,10 @@ + tty_setsofttab P((int)), + tty_tspeed P((int)), + willoption P((int)), +- wontoption P((int)), +- writenet P((unsigned char *, int)); ++ wontoption P((int)); ++ ++int output_data __P((const char *, ...)) __printflike(1, 2); ++void output_datalen __P((const char *, int)); + + #ifdef ENCRYPTION + extern void (*encrypt_output) P((unsigned char *, int)); +Index: crypto/telnet/telnetd/slc.c +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/slc.c,v +retrieving revision 1.5 +retrieving revision 1.7 +diff -u -r1.5 -r1.7 +--- crypto/telnet/telnetd/slc.c 2000/07/16 05:52:45 1.5 ++++ crypto/telnet/telnetd/slc.c 2001/07/23 21:52:26 1.7 +@@ -176,7 +176,6 @@ + register unsigned char **bufp; + { + register int len; +- void netflush(); + + /* + * If a change has occured, store the new terminal control +@@ -204,7 +203,7 @@ + (void) sprintf((char *)slcptr, "%c%c", IAC, SE); + slcptr += 2; + len = slcptr - slcbuf; +- writenet(slcbuf, len); ++ output_datalen(slcbuf, len); + netflush(); /* force it out immediately */ + DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2);); + } +Index: crypto/telnet/telnetd/state.c +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/state.c,v +retrieving revision 1.5 +retrieving revision 1.9 +diff -u -r1.5 -r1.9 +--- crypto/telnet/telnetd/state.c 2000/07/16 05:52:45 1.5 ++++ crypto/telnet/telnetd/state.c 2001/07/23 21:52:26 1.9 +@@ -39,6 +39,7 @@ + "$FreeBSD$"; + #endif /* not lint */ + ++#include <stdarg.h> + #include "telnetd.h" + #if defined(AUTHENTICATION) + #include <libtelnet/auth.h> +@@ -205,8 +206,7 @@ + } + + netclear(); /* clear buffer back */ +- *nfrontp++ = IAC; +- *nfrontp++ = DM; ++ output_data("%c%c", IAC, DM); + neturg = nfrontp-1; /* off by one XXX */ + DIAG(TD_OPTIONS, + printoption("td: send IAC", DM)); +@@ -459,8 +459,7 @@ + set_his_want_state_will(option); + do_dont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)doopt, option); +- nfrontp += sizeof (dont) - 2; ++ output_data((const char *)doopt, option); + + DIAG(TD_OPTIONS, printoption("td: send do", option)); + } +@@ -679,8 +678,7 @@ + set_his_want_state_wont(option); + do_dont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)dont, option); +- nfrontp += sizeof (doopt) - 2; ++ output_data((const char *)dont, option); + + DIAG(TD_OPTIONS, printoption("td: send dont", option)); + } +@@ -828,8 +826,7 @@ + set_my_want_state_will(option); + will_wont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)will, option); +- nfrontp += sizeof (doopt) - 2; ++ output_data((const char *)will, option); + + DIAG(TD_OPTIONS, printoption("td: send will", option)); + } +@@ -987,8 +984,7 @@ + set_my_want_state_wont(option); + will_wont_resp[option]++; + } +- (void) sprintf(nfrontp, (char *)wont, option); +- nfrontp += sizeof (wont) - 2; ++ output_data((const char *)wont, option); + + DIAG(TD_OPTIONS, printoption("td: send wont", option)); + } +@@ -1384,9 +1380,8 @@ + env_ovar_wrong: + env_ovar = OLD_ENV_VALUE; + env_ovalue = OLD_ENV_VAR; +- DIAG(TD_OPTIONS, {sprintf(nfrontp, +- "ENVIRON VALUE and VAR are reversed!\r\n"); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_OPTIONS, ++ output_data("ENVIRON VALUE and VAR are reversed!\r\n")); + + } + } +@@ -1611,9 +1606,55 @@ + ADD(IAC); + ADD(SE); + +- writenet(statusbuf, ncp - statusbuf); ++ output_datalen(statusbuf, ncp - statusbuf); + netflush(); /* Send it on its way */ + + DIAG(TD_OPTIONS, + {printsub('>', statusbuf, ncp - statusbuf); netflush();}); ++} ++ ++/* ++ * This function appends data to nfrontp and advances nfrontp. ++ * Returns the number of characters written altogether (the ++ * buffer may have been flushed in the process). ++ */ ++ ++int ++output_data(const char *format, ...) ++{ ++ va_list args; ++ int len; ++ char *buf; ++ ++ va_start(args, format); ++ if ((len = vasprintf(&buf, format, args)) == -1) ++ return -1; ++ output_datalen(buf, len); ++ va_end(args); ++ free(buf); ++ return (len); ++} ++ ++void ++output_datalen(const char *buf, int len) ++{ ++ int remaining, copied; ++ ++ remaining = BUFSIZ - (nfrontp - netobuf); ++ while (len > 0) { ++ /* Free up enough space if the room is too low*/ ++ if ((len > BUFSIZ ? BUFSIZ : len) > remaining) { ++ netflush(); ++ remaining = BUFSIZ - (nfrontp - netobuf); ++ } ++ ++ /* Copy out as much as will fit */ ++ copied = remaining > len ? len : remaining; ++ memmove(nfrontp, buf, copied); ++ nfrontp += copied; ++ len -= copied; ++ remaining -= copied; ++ buf += copied; ++ } ++ return; + } +Index: crypto/telnet/telnetd/telnetd.c +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/telnetd.c,v +retrieving revision 1.15 +retrieving revision 1.17 +diff -u -r1.15 -r1.17 +--- crypto/telnet/telnetd/telnetd.c 2001/02/06 09:32:26 1.15 ++++ crypto/telnet/telnetd/telnetd.c 2001/07/23 21:52:26 1.17 +@@ -683,38 +683,33 @@ + static unsigned char sb[] = + { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; + +- memmove(nfrontp, sb, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); + } + if (his_state_is_will(TELOPT_XDISPLOC)) { + static unsigned char sb[] = + { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; + +- memmove(nfrontp, sb, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); + } + if (his_state_is_will(TELOPT_NEW_ENVIRON)) { + static unsigned char sb[] = + { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; + +- memmove(nfrontp, sb, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); + } + else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { + static unsigned char sb[] = + { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; + +- memmove(nfrontp, sb, sizeof sb); +- nfrontp += sizeof sb; ++ output_datalen(sb, sizeof sb); + DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); + } + if (his_state_is_will(TELOPT_TTYPE)) { + +- memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); +- nfrontp += sizeof ttytype_sbbuf; ++ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf); + DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, + sizeof ttytype_sbbuf - 2);); + } +@@ -793,8 +788,7 @@ + if (his_state_is_wont(TELOPT_TTYPE)) + return; + settimer(baseline); +- memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); +- nfrontp += sizeof ttytype_sbbuf; ++ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf); + DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2, + sizeof ttytype_sbbuf - 2);); + while (sequenceIs(ttypesubopt, baseline)) +@@ -958,7 +952,6 @@ + char *HE; + char *HN; + char *IM; +- void netflush(); + int nfd; + + /* +@@ -1044,9 +1037,7 @@ + * mode, which we do not want. + */ + if (his_want_state_is_will(TELOPT_ECHO)) { +- DIAG(TD_OPTIONS, +- {sprintf(nfrontp, "td: simulating recv\r\n"); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_OPTIONS, output_data("td: simulating recv\r\n")); + willoption(TELOPT_ECHO); + } + +@@ -1181,9 +1172,7 @@ + localstat(); + #endif /* LINEMODE */ + +- DIAG(TD_REPORT, +- {sprintf(nfrontp, "td: Entering processing loop\r\n"); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_REPORT, output_data("td: Entering processing loop\r\n")); + + /* + * Startup the login process on the slave side of the terminal +@@ -1312,8 +1301,7 @@ + netip = netibuf; + } + DIAG((TD_REPORT | TD_NETDATA), +- {sprintf(nfrontp, "td: netread %d chars\r\n", ncc); +- nfrontp += strlen(nfrontp);}); ++ output_data("td: netread %d chars\r\n", ncc)); + DIAG(TD_NETDATA, printdata("nd", netip, ncc)); + } + +@@ -1360,8 +1348,7 @@ + * royally if we send them urgent + * mode data. + */ +- *nfrontp++ = IAC; +- *nfrontp++ = DM; ++ output_data("%c%c", IAC, DM); + neturg = nfrontp-1; /* off by one XXX */ + DIAG(TD_OPTIONS, + printoption("td: send IAC", DM)); +@@ -1375,13 +1362,11 @@ + ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; + if (newflow != flowmode) { + flowmode = newflow; +- (void) sprintf(nfrontp, +- "%c%c%c%c%c%c", ++ output_data("%c%c%c%c%c%c", + IAC, SB, TELOPT_LFLOW, + flowmode ? LFLOW_ON + : LFLOW_OFF, + IAC, SE); +- nfrontp += 6; + DIAG(TD_OPTIONS, printsub('>', + (unsigned char *)nfrontp-4, + 4);); +@@ -1407,19 +1392,19 @@ + break; + c = *ptyip++ & 0377, pcc--; + if (c == IAC) +- *nfrontp++ = c; ++ output_data("%c", c); + #if defined(CRAY2) && defined(UNICOS5) + else if (c == '\n' && + my_state_is_wont(TELOPT_BINARY) && newmap) +- *nfrontp++ = '\r'; ++ output_data("\r"); + #endif /* defined(CRAY2) && defined(UNICOS5) */ +- *nfrontp++ = c; ++ output_data("%c", c); + if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) { + if (pcc > 0 && ((*ptyip & 0377) == '\n')) { +- *nfrontp++ = *ptyip++ & 0377; ++ output_data("%c", *ptyip++ & 0377); + pcc--; + } else +- *nfrontp++ = '\0'; ++ output_data("%c", '\0'); + } + } + #if defined(CRAY2) && defined(UNICOS5) +@@ -1613,8 +1598,7 @@ + return; + } + #endif +- (void) strcpy(nfrontp, "\r\n[Yes]\r\n"); +- nfrontp += 9; ++ output_data("\r\n[Yes]\r\n"); + } + + void +Index: crypto/telnet/telnetd/termstat.c +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/termstat.c,v +retrieving revision 1.6 +retrieving revision 1.8 +diff -u -r1.6 -r1.8 +--- crypto/telnet/telnetd/termstat.c 2001/02/06 10:38:58 1.6 ++++ crypto/telnet/telnetd/termstat.c 2001/07/23 21:52:26 1.8 +@@ -140,7 +140,6 @@ + void + localstat() + { +- void netflush(); + int need_will_echo = 0; + + #if defined(CRAY2) && defined(UNICOS5) +@@ -302,10 +301,9 @@ + # endif /* KLUDGELINEMODE */ + send_do(TELOPT_LINEMODE, 1); + /* send along edit modes */ +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, ++ output_data("%c%c%c%c%c%c%c", IAC, SB, + TELOPT_LINEMODE, LM_MODE, useeditmode, + IAC, SE); +- nfrontp += 7; + editmode = useeditmode; + # ifdef KLUDGELINEMODE + } +@@ -331,10 +329,9 @@ + /* + * Send along appropriate edit mode mask. + */ +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, ++ output_data("%c%c%c%c%c%c%c", IAC, SB, + TELOPT_LINEMODE, LM_MODE, useeditmode, + IAC, SE); +- nfrontp += 7; + editmode = useeditmode; + } + +@@ -378,20 +375,18 @@ + if (his_state_is_will(TELOPT_LFLOW)) { + if (tty_flowmode() != flowmode) { + flowmode = tty_flowmode(); +- (void) sprintf(nfrontp, "%c%c%c%c%c%c", ++ output_data("%c%c%c%c%c%c", + IAC, SB, TELOPT_LFLOW, + flowmode ? LFLOW_ON : LFLOW_OFF, + IAC, SE); +- nfrontp += 6; + } + if (tty_restartany() != restartany) { + restartany = tty_restartany(); +- (void) sprintf(nfrontp, "%c%c%c%c%c%c", ++ output_data("%c%c%c%c%c%c", + IAC, SB, TELOPT_LFLOW, + restartany ? LFLOW_RESTART_ANY + : LFLOW_RESTART_XON, + IAC, SE); +- nfrontp += 6; + } + } + } +@@ -408,7 +403,6 @@ + clientstat(code, parm1, parm2) + register int code, parm1, parm2; + { +- void netflush(); + + /* + * Get a copy of terminal characteristics. +@@ -464,10 +458,9 @@ + useeditmode |= MODE_SOFT_TAB; + if (tty_islitecho()) + useeditmode |= MODE_LIT_ECHO; +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, ++ output_data("%c%c%c%c%c%c%c", IAC, + SB, TELOPT_LINEMODE, LM_MODE, + useeditmode, IAC, SE); +- nfrontp += 7; + editmode = useeditmode; + } + +@@ -523,11 +516,10 @@ + set_termbuf(); + + if (!ack) { +- (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, ++ output_data("%c%c%c%c%c%c%c", IAC, + SB, TELOPT_LINEMODE, LM_MODE, + useeditmode|MODE_ACK, + IAC, SE); +- nfrontp += 7; + } + + editmode = useeditmode; +Index: crypto/telnet/telnetd/utility.c +=================================================================== +RCS file: /home/ncvs/src/crypto/telnet/telnetd/utility.c,v +retrieving revision 1.7 +retrieving revision 1.10 +diff -u -r1.7 -r1.10 +--- crypto/telnet/telnetd/utility.c 2000/11/30 10:55:25 1.7 ++++ crypto/telnet/telnetd/utility.c 2001/07/23 21:52:26 1.10 +@@ -69,11 +69,9 @@ + void + ttloop() + { +- void netflush(); + +- DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n"); +- nfrontp += strlen(nfrontp);}); +- if (nfrontp-nbackp) { ++ DIAG(TD_REPORT, output_data("td: ttloop\r\n")); ++ if (nfrontp - nbackp > 0) { + netflush(); + } + ncc = read(net, netibuf, sizeof netibuf); +@@ -84,8 +82,7 @@ + syslog(LOG_INFO, "ttloop: peer died: %m"); + exit(1); + } +- DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc); +- nfrontp += strlen(nfrontp);}); ++ DIAG(TD_REPORT, output_data("td: ttloop read %d chars\r\n", ncc)); + netip = netibuf; + telrcv(); /* state machine */ + if (ncc > 0) { +@@ -128,9 +125,8 @@ + int n; + + if ((n = pfrontp - pbackp) > 0) { +- DIAG((TD_REPORT | TD_PTYDATA), +- { sprintf(nfrontp, "td: ptyflush %d chars\r\n", n); +- nfrontp += strlen(nfrontp); }); ++ DIAG(TD_REPORT | TD_PTYDATA, ++ output_data("td: ptyflush %d chars\r\n", n)); + DIAG(TD_PTYDATA, printdata("pd", pbackp, n)); + n = write(pty, pbackp, n); + } +@@ -260,12 +256,13 @@ + int n; + extern int not42; + +- if ((n = nfrontp - nbackp) > 0) { +- DIAG(TD_REPORT, +- { sprintf(nfrontp, "td: netflush %d chars\r\n", n); +- n += strlen(nfrontp); /* get count first */ +- nfrontp += strlen(nfrontp); /* then move pointer */ +- }); ++ while ((n = nfrontp - nbackp) > 0) { ++#if 0 ++ /* XXX This causes output_data() to recurse and die */ ++ DIAG(TD_REPORT, { ++ n += output_data("td: netflush %d chars\r\n", n); ++ }); ++#endif + #ifdef ENCRYPTION + if (encrypt_output) { + char *s = nclearto ? nclearto : nbackp; +@@ -298,58 +295,32 @@ + n = send(net, nbackp, n, MSG_OOB); /* URGENT data */ + } + } +- } +- if (n < 0) { +- if (errno == EWOULDBLOCK || errno == EINTR) +- return; +- cleanup(0); +- } +- nbackp += n; ++ if (n == -1) { ++ if (errno == EWOULDBLOCK || errno == EINTR) ++ continue; ++ cleanup(0); ++ /* NOTREACHED */ ++ } ++ nbackp += n; + #ifdef ENCRYPTION +- if (nbackp > nclearto) +- nclearto = 0; ++ if (nbackp > nclearto) ++ nclearto = 0; + #endif /* ENCRYPTION */ +- if (nbackp >= neturg) { +- neturg = 0; +- } +- if (nbackp == nfrontp) { +- nbackp = nfrontp = netobuf; ++ if (nbackp >= neturg) { ++ neturg = 0; ++ } ++ if (nbackp == nfrontp) { ++ nbackp = nfrontp = netobuf; + #ifdef ENCRYPTION +- nclearto = 0; ++ nclearto = 0; + #endif /* ENCRYPTION */ ++ } + } + return; + } /* end of netflush */ + + + /* +- * writenet +- * +- * Just a handy little function to write a bit of raw data to the net. +- * It will force a transmit of the buffer if necessary +- * +- * arguments +- * ptr - A pointer to a character string to write +- * len - How many bytes to write +- */ +- void +-writenet(ptr, len) +- register unsigned char *ptr; +- register int len; +-{ +- /* flush buffer if no room for new data) */ +- if ((&netobuf[BUFSIZ] - nfrontp) < len) { +- /* if this fails, don't worry, buffer is a little big */ +- netflush(); +- } +- +- memmove(nfrontp, ptr, len); +- nfrontp += len; +- +-} /* end of writenet */ +- +- +-/* + * miscellaneous functions doing a variety of little jobs follow ... + */ + +@@ -554,12 +525,11 @@ + register int option; + { + if (TELOPT_OK(option)) +- sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option)); ++ output_data("%s %s\r\n", fmt, TELOPT(option)); + else if (TELCMD_OK(option)) +- sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option)); ++ output_data("%s %s\r\n", fmt, TELCMD(option)); + else +- sprintf(nfrontp, "%s %d\r\n", fmt, option); +- nfrontp += strlen(nfrontp); ++ output_data("%s %d\r\n", fmt, option); + return; + } + +@@ -575,9 +545,8 @@ + return; + + if (direction) { +- sprintf(nfrontp, "td: %s suboption ", ++ output_data("td: %s suboption ", + direction == '<' ? "recv" : "send"); +- nfrontp += strlen(nfrontp); + if (length >= 3) { + register int j; + +@@ -585,232 +554,192 @@ + j = pointer[length-1]; + + if (i != IAC || j != SE) { +- sprintf(nfrontp, "(terminated by "); +- nfrontp += strlen(nfrontp); ++ output_data("(terminated by "); + if (TELOPT_OK(i)) +- sprintf(nfrontp, "%s ", TELOPT(i)); ++ output_data("%s ", TELOPT(i)); + else if (TELCMD_OK(i)) +- sprintf(nfrontp, "%s ", TELCMD(i)); ++ output_data("%s ", TELCMD(i)); + else +- sprintf(nfrontp, "%d ", i); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", i); + if (TELOPT_OK(j)) +- sprintf(nfrontp, "%s", TELOPT(j)); ++ output_data("%s", TELOPT(j)); + else if (TELCMD_OK(j)) +- sprintf(nfrontp, "%s", TELCMD(j)); ++ output_data("%s", TELCMD(j)); + else +- sprintf(nfrontp, "%d", j); +- nfrontp += strlen(nfrontp); +- sprintf(nfrontp, ", not IAC SE!) "); +- nfrontp += strlen(nfrontp); ++ output_data("%d", j); ++ output_data(", not IAC SE!) "); + } + } + length -= 2; + } + if (length < 1) { +- sprintf(nfrontp, "(Empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(Empty suboption??\?)"); + return; + } + switch (pointer[0]) { + case TELOPT_TTYPE: +- sprintf(nfrontp, "TERMINAL-TYPE "); +- nfrontp += strlen(nfrontp); ++ output_data("TERMINAL-TYPE "); + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); ++ output_data("IS \"%.*s\"", length-2, (char *)pointer+2); + break; + case TELQUAL_SEND: +- sprintf(nfrontp, "SEND"); ++ output_data("SEND"); + break; + default: +- sprintf(nfrontp, ++ output_data( + "- unknown qualifier %d (0x%x).", + pointer[1], pointer[1]); + } +- nfrontp += strlen(nfrontp); + break; + case TELOPT_TSPEED: +- sprintf(nfrontp, "TERMINAL-SPEED"); +- nfrontp += strlen(nfrontp); ++ output_data("TERMINAL-SPEED"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2); +- nfrontp += strlen(nfrontp); ++ output_data(" IS %.*s", length-2, (char *)pointer+2); + break; + default: + if (pointer[1] == 1) +- sprintf(nfrontp, " SEND"); ++ output_data(" SEND"); + else +- sprintf(nfrontp, " %d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d (unknown)", pointer[1]); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + } + break; + + case TELOPT_LFLOW: +- sprintf(nfrontp, "TOGGLE-FLOW-CONTROL"); +- nfrontp += strlen(nfrontp); ++ output_data("TOGGLE-FLOW-CONTROL"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case LFLOW_OFF: +- sprintf(nfrontp, " OFF"); break; ++ output_data(" OFF"); break; + case LFLOW_ON: +- sprintf(nfrontp, " ON"); break; ++ output_data(" ON"); break; + case LFLOW_RESTART_ANY: +- sprintf(nfrontp, " RESTART-ANY"); break; ++ output_data(" RESTART-ANY"); break; + case LFLOW_RESTART_XON: +- sprintf(nfrontp, " RESTART-XON"); break; ++ output_data(" RESTART-XON"); break; + default: +- sprintf(nfrontp, " %d (unknown)", pointer[1]); ++ output_data(" %d (unknown)", pointer[1]); + } +- nfrontp += strlen(nfrontp); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + + case TELOPT_NAWS: +- sprintf(nfrontp, "NAWS"); +- nfrontp += strlen(nfrontp); ++ output_data("NAWS"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + if (length == 2) { +- sprintf(nfrontp, " ?%d?", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[1]); + break; + } +- sprintf(nfrontp, " %d %d (%d)", ++ output_data(" %d %d (%d)", + pointer[1], pointer[2], + (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); +- nfrontp += strlen(nfrontp); + if (length == 4) { +- sprintf(nfrontp, " ?%d?", pointer[3]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[3]); + break; + } +- sprintf(nfrontp, " %d %d (%d)", ++ output_data(" %d %d (%d)", + pointer[3], pointer[4], + (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); +- nfrontp += strlen(nfrontp); + for (i = 5; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + + case TELOPT_LINEMODE: +- sprintf(nfrontp, "LINEMODE "); +- nfrontp += strlen(nfrontp); ++ output_data("LINEMODE "); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case WILL: +- sprintf(nfrontp, "WILL "); ++ output_data("WILL "); + goto common; + case WONT: +- sprintf(nfrontp, "WONT "); ++ output_data("WONT "); + goto common; + case DO: +- sprintf(nfrontp, "DO "); ++ output_data("DO "); + goto common; + case DONT: +- sprintf(nfrontp, "DONT "); ++ output_data("DONT "); + common: +- nfrontp += strlen(nfrontp); + if (length < 3) { +- sprintf(nfrontp, "(no option??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(no option??\?)"); + break; + } + switch (pointer[2]) { + case LM_FORWARDMASK: +- sprintf(nfrontp, "Forward Mask"); +- nfrontp += strlen(nfrontp); ++ output_data("Forward Mask"); + for (i = 3; i < length; i++) { +- sprintf(nfrontp, " %x", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %x", pointer[i]); + } + break; + default: +- sprintf(nfrontp, "%d (unknown)", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data("%d (unknown)", pointer[2]); + for (i = 3; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + break; + } + break; + + case LM_SLC: +- sprintf(nfrontp, "SLC"); +- nfrontp += strlen(nfrontp); ++ output_data("SLC"); + for (i = 2; i < length - 2; i += 3) { + if (SLC_NAME_OK(pointer[i+SLC_FUNC])) +- sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC])); ++ output_data(" %s", SLC_NAME(pointer[i+SLC_FUNC])); + else +- sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i+SLC_FUNC]); + switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { + case SLC_NOSUPPORT: +- sprintf(nfrontp, " NOSUPPORT"); break; ++ output_data(" NOSUPPORT"); break; + case SLC_CANTCHANGE: +- sprintf(nfrontp, " CANTCHANGE"); break; ++ output_data(" CANTCHANGE"); break; + case SLC_VARIABLE: +- sprintf(nfrontp, " VARIABLE"); break; ++ output_data(" VARIABLE"); break; + case SLC_DEFAULT: +- sprintf(nfrontp, " DEFAULT"); break; ++ output_data(" DEFAULT"); break; + } +- nfrontp += strlen(nfrontp); +- sprintf(nfrontp, "%s%s%s", ++ output_data("%s%s%s", + pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", + pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", + pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); +- nfrontp += strlen(nfrontp); + if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| + SLC_FLUSHOUT| SLC_LEVELBITS)) { +- sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]); +- nfrontp += strlen(nfrontp); ++ output_data("(0x%x)", pointer[i+SLC_FLAGS]); + } +- sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d;", pointer[i+SLC_VALUE]); + if ((pointer[i+SLC_VALUE] == IAC) && + (pointer[i+SLC_VALUE+1] == IAC)) + i++; + } + for (; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + + case LM_MODE: +- sprintf(nfrontp, "MODE "); +- nfrontp += strlen(nfrontp); ++ output_data("MODE "); + if (length < 3) { +- sprintf(nfrontp, "(no mode??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(no mode??\?)"); + break; + } + { +@@ -821,24 +750,19 @@ + pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "", + pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "", + pointer[2]&MODE_ACK ? "|ACK" : ""); +- sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0"); +- nfrontp += strlen(nfrontp); ++ output_data("%s", tbuf[1] ? &tbuf[1] : "0"); + } + if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) { +- sprintf(nfrontp, " (0x%x)", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data(" (0x%x)", pointer[2]); + } + for (i = 3; i < length; i++) { +- sprintf(nfrontp, " ?0x%x?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?0x%x?", pointer[i]); + } + break; + default: +- sprintf(nfrontp, "%d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data("%d (unknown)", pointer[1]); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + } + break; +@@ -847,24 +771,20 @@ + register char *cp; + register int j, k; + +- sprintf(nfrontp, "STATUS"); +- nfrontp += strlen(nfrontp); ++ output_data("STATUS"); + + switch (pointer[1]) { + default: + if (pointer[1] == TELQUAL_SEND) +- sprintf(nfrontp, " SEND"); ++ output_data(" SEND"); + else +- sprintf(nfrontp, " %d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d (unknown)", pointer[1]); + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + case TELQUAL_IS: +- sprintf(nfrontp, " IS\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data(" IS\r\n"); + + for (i = 2; i < length; i++) { + switch(pointer[i]) { +@@ -875,18 +795,15 @@ + common2: + i++; + if (TELOPT_OK(pointer[i])) +- sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i])); ++ output_data(" %s %s", cp, TELOPT(pointer[i])); + else +- sprintf(nfrontp, " %s %d", cp, pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %s %d", cp, pointer[i]); + +- sprintf(nfrontp, "\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data("\r\n"); + break; + + case SB: +- sprintf(nfrontp, " SB "); +- nfrontp += strlen(nfrontp); ++ output_data(" SB "); + i++; + j = k = i; + while (j < length) { +@@ -902,20 +819,17 @@ + } + printsub(0, &pointer[i], k - i); + if (i < length) { +- sprintf(nfrontp, " SE"); +- nfrontp += strlen(nfrontp); ++ output_data(" SE"); + i = j; + } else + i = j - 1; + +- sprintf(nfrontp, "\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data("\r\n"); + + break; + + default: +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + break; + } + } +@@ -925,86 +839,77 @@ + } + + case TELOPT_XDISPLOC: +- sprintf(nfrontp, "X-DISPLAY-LOCATION "); +- nfrontp += strlen(nfrontp); ++ output_data("X-DISPLAY-LOCATION "); + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); ++ output_data("IS \"%.*s\"", length-2, (char *)pointer+2); + break; + case TELQUAL_SEND: +- sprintf(nfrontp, "SEND"); ++ output_data("SEND"); + break; + default: +- sprintf(nfrontp, "- unknown qualifier %d (0x%x).", ++ output_data("- unknown qualifier %d (0x%x).", + pointer[1], pointer[1]); + } +- nfrontp += strlen(nfrontp); + break; + + case TELOPT_NEW_ENVIRON: +- sprintf(nfrontp, "NEW-ENVIRON "); ++ output_data("NEW-ENVIRON "); + goto env_common1; + case TELOPT_OLD_ENVIRON: +- sprintf(nfrontp, "OLD-ENVIRON"); ++ output_data("OLD-ENVIRON"); + env_common1: +- nfrontp += strlen(nfrontp); + switch (pointer[1]) { + case TELQUAL_IS: +- sprintf(nfrontp, "IS "); ++ output_data("IS "); + goto env_common; + case TELQUAL_SEND: +- sprintf(nfrontp, "SEND "); ++ output_data("SEND "); + goto env_common; + case TELQUAL_INFO: +- sprintf(nfrontp, "INFO "); ++ output_data("INFO "); + env_common: +- nfrontp += strlen(nfrontp); + { + register int noquote = 2; + for (i = 2; i < length; i++ ) { + switch (pointer[i]) { + case NEW_ENV_VAR: +- sprintf(nfrontp, "\" VAR " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" VAR " + noquote); + noquote = 2; + break; + + case NEW_ENV_VALUE: +- sprintf(nfrontp, "\" VALUE " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" VALUE " + noquote); + noquote = 2; + break; + + case ENV_ESC: +- sprintf(nfrontp, "\" ESC " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" ESC " + noquote); + noquote = 2; + break; + + case ENV_USERVAR: +- sprintf(nfrontp, "\" USERVAR " + noquote); +- nfrontp += strlen(nfrontp); ++ output_data("\" USERVAR " + noquote); + noquote = 2; + break; + + default: + if (isprint(pointer[i]) && pointer[i] != '"') { + if (noquote) { +- *nfrontp++ = '"'; ++ output_data("\""); + noquote = 0; + } +- *nfrontp++ = pointer[i]; ++ output_data("%c", pointer[i]); + } else { +- sprintf(nfrontp, "\" %03o " + noquote, ++ output_data("\" %03o " + noquote, + pointer[i]); +- nfrontp += strlen(nfrontp); + noquote = 2; + } + break; + } + } + if (!noquote) +- *nfrontp++ = '"'; ++ output_data("\""); + break; + } + } +@@ -1012,83 +917,66 @@ + + #if defined(AUTHENTICATION) + case TELOPT_AUTHENTICATION: +- sprintf(nfrontp, "AUTHENTICATION"); +- nfrontp += strlen(nfrontp); ++ output_data("AUTHENTICATION"); + + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case TELQUAL_REPLY: + case TELQUAL_IS: +- sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ? ++ output_data(" %s ", (pointer[1] == TELQUAL_IS) ? + "IS" : "REPLY"); +- nfrontp += strlen(nfrontp); + if (AUTHTYPE_NAME_OK(pointer[2])) +- sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2])); ++ output_data("%s ", AUTHTYPE_NAME(pointer[2])); + else +- sprintf(nfrontp, "%d ", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", pointer[2]); + if (length < 3) { +- sprintf(nfrontp, "(partial suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(partial suboption??\?)"); + break; + } +- sprintf(nfrontp, "%s|%s", ++ output_data("%s|%s", + ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? + "CLIENT" : "SERVER", + ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? + "MUTUAL" : "ONE-WAY"); +- nfrontp += strlen(nfrontp); + + { + char buf[512]; + auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); +- sprintf(nfrontp, "%s", buf); ++ output_data("%s", buf); + } +- nfrontp += strlen(nfrontp); + break; + + case TELQUAL_SEND: + i = 2; +- sprintf(nfrontp, " SEND "); +- nfrontp += strlen(nfrontp); ++ output_data(" SEND "); + while (i < length) { + if (AUTHTYPE_NAME_OK(pointer[i])) +- sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i])); ++ output_data("%s ", AUTHTYPE_NAME(pointer[i])); + else +- sprintf(nfrontp, "%d ", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", pointer[i]); + if (++i >= length) { +- sprintf(nfrontp, "(partial suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data("(partial suboption??\?)"); + break; + } +- sprintf(nfrontp, "%s|%s ", ++ output_data("%s|%s ", + ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? + "CLIENT" : "SERVER", + ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? + "MUTUAL" : "ONE-WAY"); +- nfrontp += strlen(nfrontp); + ++i; + } + break; + + case TELQUAL_NAME: +- i = 2; +- sprintf(nfrontp, " NAME \""); +- nfrontp += strlen(nfrontp); +- while (i < length) +- *nfrontp += pointer[i++]; +- *nfrontp += '"'; ++ output_data(" NAME \"%.*s\"", length - 2, pointer + 2); + break; + + default: + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " ?%d?", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" ?%d?", pointer[i]); + } + break; + } +@@ -1097,89 +985,73 @@ + + #ifdef ENCRYPTION + case TELOPT_ENCRYPT: +- sprintf(nfrontp, "ENCRYPT"); +- nfrontp += strlen(nfrontp); ++ output_data("ENCRYPT"); + if (length < 2) { +- sprintf(nfrontp, " (empty suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (empty suboption??\?)"); + break; + } + switch (pointer[1]) { + case ENCRYPT_START: +- sprintf(nfrontp, " START"); +- nfrontp += strlen(nfrontp); ++ output_data(" START"); + break; + + case ENCRYPT_END: +- sprintf(nfrontp, " END"); +- nfrontp += strlen(nfrontp); ++ output_data(" END"); + break; + + case ENCRYPT_REQSTART: +- sprintf(nfrontp, " REQUEST-START"); +- nfrontp += strlen(nfrontp); ++ output_data(" REQUEST-START"); + break; + + case ENCRYPT_REQEND: +- sprintf(nfrontp, " REQUEST-END"); +- nfrontp += strlen(nfrontp); ++ output_data(" REQUEST-END"); + break; + + case ENCRYPT_IS: + case ENCRYPT_REPLY: +- sprintf(nfrontp, " %s ", (pointer[1] == ENCRYPT_IS) ? ++ output_data(" %s ", (pointer[1] == ENCRYPT_IS) ? + "IS" : "REPLY"); +- nfrontp += strlen(nfrontp); + if (length < 3) { +- sprintf(nfrontp, " (partial suboption??\?)"); +- nfrontp += strlen(nfrontp); ++ output_data(" (partial suboption??\?)"); + break; + } + if (ENCTYPE_NAME_OK(pointer[2])) +- sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[2])); ++ output_data("%s ", ENCTYPE_NAME(pointer[2])); + else +- sprintf(nfrontp, " %d (unknown)", pointer[2]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d (unknown)", pointer[2]); + + { + char buf[512]; + encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); +- sprintf(nfrontp, "%s", buf); ++ output_data("%s", buf); + } +- nfrontp += strlen(nfrontp); + break; + + case ENCRYPT_SUPPORT: + i = 2; +- sprintf(nfrontp, " SUPPORT "); +- nfrontp += strlen(nfrontp); ++ output_data(" SUPPORT "); + while (i < length) { + if (ENCTYPE_NAME_OK(pointer[i])) +- sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[i])); ++ output_data("%s ", ENCTYPE_NAME(pointer[i])); + else +- sprintf(nfrontp, "%d ", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data("%d ", pointer[i]); + i++; + } + break; + + case ENCRYPT_ENC_KEYID: +- sprintf(nfrontp, " ENC_KEYID"); +- nfrontp += strlen(nfrontp); ++ output_data(" ENC_KEYID"); + goto encommon; + + case ENCRYPT_DEC_KEYID: +- sprintf(nfrontp, " DEC_KEYID"); +- nfrontp += strlen(nfrontp); ++ output_data(" DEC_KEYID"); + goto encommon; + + default: +- sprintf(nfrontp, " %d (unknown)", pointer[1]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d (unknown)", pointer[1]); + encommon: + for (i = 2; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + break; + } +@@ -1188,18 +1060,15 @@ + + default: + if (TELOPT_OK(pointer[0])) +- sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0])); ++ output_data("%s (unknown)", TELOPT(pointer[0])); + else +- sprintf(nfrontp, "%d (unknown)", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data("%d (unknown)", pointer[i]); + for (i = 1; i < length; i++) { +- sprintf(nfrontp, " %d", pointer[i]); +- nfrontp += strlen(nfrontp); ++ output_data(" %d", pointer[i]); + } + break; + } +- sprintf(nfrontp, "\r\n"); +- nfrontp += strlen(nfrontp); ++ output_data("\r\n"); + } + + /* +@@ -1221,26 +1090,22 @@ + } + + /* add a line of output */ +- sprintf(nfrontp, "%s: ", tag); +- nfrontp += strlen(nfrontp); ++ output_data("%s: ", tag); + for (i = 0; i < 20 && cnt; i++) { +- sprintf(nfrontp, "%02x", *ptr); +- nfrontp += strlen(nfrontp); ++ output_data("%02x", *ptr); + if (isprint(*ptr)) { + xbuf[i] = *ptr; + } else { + xbuf[i] = '.'; + } + if (i % 2) { +- *nfrontp = ' '; +- nfrontp++; ++ output_data(" "); + } + cnt--; + ptr++; + } + xbuf[i] = '\0'; +- sprintf(nfrontp, " %s\r\n", xbuf ); +- nfrontp += strlen(nfrontp); ++ output_data(" %s\r\n", xbuf ); + } + } + #endif /* DIAGNOSTICS */ |