aboutsummaryrefslogtreecommitdiff
path: root/share/security/patches/SA-01:49/telnetd-crypto.patch
diff options
context:
space:
mode:
Diffstat (limited to 'share/security/patches/SA-01:49/telnetd-crypto.patch')
-rw-r--r--share/security/patches/SA-01:49/telnetd-crypto.patch2651
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 */