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 */
