From d13fc8f62aa0596cab6a05b98c4b187b9dbd1a04 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Sat, 21 Feb 2009 11:14:55 +0000
Subject: [PATCH] sbbs_t::bputs() now checks online value in while() loop.
 sbbs_t::rputs() now: * Can accept an optional length argument which allows it
 to output strings with embedded NULs if desired. * If a call to outcom()
 fails, terminates and returns the sent number of chars. * Performs Telnet IAC
 escaping when appropriate. * Checks online value in while() loop. * No longer
 output to log if "on local" - event scripts aren't expected to use this
 function. JS console.write() and writeln() now use rputs() instead of
 putcom() so that Telnet IAC chars are escaped when necessary and
 saveline/restoreline will work. sbbs_t::putcom() now returns the number of
 chars sent successfully.

---
 src/sbbs3/con_out.cpp    | 34 ++++++++++++++++++++--------------
 src/sbbs3/js_console.cpp |  2 +-
 src/sbbs3/main.cpp       | 14 ++++++++------
 src/sbbs3/sbbs.h         | 10 +++++-----
 4 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp
index fa8704b9c6..ad18e06ea3 100644
--- a/src/sbbs3/con_out.cpp
+++ b/src/sbbs3/con_out.cpp
@@ -45,7 +45,7 @@
 
 /****************************************************************************/
 /* Outputs a NULL terminated string locally and remotely (if applicable)    */
-/* Handles ctrl-a characters                                                */
+/* Handles ctrl-a codes, Telnet-escaping, column & line count, auto-pausing */
 /****************************************************************************/
 int sbbs_t::bputs(const char *str)
 {
@@ -55,7 +55,7 @@ int sbbs_t::bputs(const char *str)
 	if(online==ON_LOCAL && console&CON_L_ECHO) 	/* script running as event */
 		return(eprintf(LOG_INFO,"%s",str));
 
-	while(str[l]) {
+	while(str[l] && online) {
 		if(str[l]==CTRL_A && str[l+1]!=0) {
 			l++;
 			if(toupper(str[l])=='Z')	/* EOF */
@@ -88,21 +88,24 @@ int sbbs_t::bputs(const char *str)
 }
 
 /****************************************************************************/
-/* Outputs a NULL terminated string remotely (if applicable)				*/
-/* Does not expand ctrl-A codes or track line counter, etc. (raw)           */
+/* Raw put string (remotely)												*/
+/* Performs Telnet IAC escaping												*/
+/* Performs saveline buffering (for restoreline)							*/
+/* DOES NOT expand ctrl-A codes, track colunms, lines, auto-pause, etc.     */
 /****************************************************************************/
-int sbbs_t::rputs(const char *str)
+int sbbs_t::rputs(const char *str, size_t len)
 {
-    ulong l=0;
+    size_t	l;
 
-	if(online==ON_LOCAL && console&CON_L_ECHO)	/* script running as event */
-		return(eprintf(LOG_INFO,"%s",str));
-	
-	while(str[l]) {
-		outcom(str[l]);
+	if(len==0)
+		len=strlen(str);
+	for(l=0;l<len && online;l++) {
+		if(str[l]==(char)TELNET_IAC && !(telnet_mode&TELNET_MODE_OFF))
+			outcom(TELNET_IAC);	/* Must escape Telnet IAC char (255) */
+		if(outcom(str[l])!=0)
+			break;
 		if(lbuflen<LINE_BUFSIZE)
 			lbuf[lbuflen++]=str[l]; 
-		l++;
 	}
 	return(l);
 }
@@ -164,8 +167,11 @@ long sbbs_t::term_supports(long cmp_flags)
 }
 
 /****************************************************************************/
-/* Outputs character locally and remotely (if applicable), preforming echo  */
-/* translations (X's and r0dent emulation) if applicable.					*/
+/* Outputs character														*/
+/* Performs terminal translations (e.g. EXASCII-to-ASCII, FF->ESC[2J)		*/
+/* Performs Telnet IAC escaping												*/
+/* Performs column counting, line counting, and auto-pausing				*/
+/* Performs saveline buffering (for restoreline)							*/
 /****************************************************************************/
 void sbbs_t::outchar(char ch)
 {
diff --git a/src/sbbs3/js_console.cpp b/src/sbbs3/js_console.cpp
index 8ced6d4cf3..76f399d47a 100644
--- a/src/sbbs3/js_console.cpp
+++ b/src/sbbs3/js_console.cpp
@@ -900,7 +900,7 @@ js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 		if((str=js_ValueToStringBytes(cx, argv[i], &len))==NULL)
 		    return(JS_FALSE);
 		rc=JS_SUSPENDREQUEST(cx);
-		sbbs->putcom(str, len);
+		sbbs->rputs(str, len);
 		JS_RESUMEREQUEST(cx, rc);
 	}
 
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 8e01944a42..7f0ebbf17f 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -3560,14 +3560,16 @@ int sbbs_t::outcom(uchar ch)
 	return(0);
 }
 
-void sbbs_t::putcom(const char *str, int len)
+int sbbs_t::putcom(const char *str, size_t len)
 {
-	int i;
+	size_t i;
 
-    if(!len)
-    	len=strlen(str);
-    for(i=0;i<len && online; i++)
-        outcom(str[i]);
+	if(!len)
+		len=strlen(str);
+    for(i=0;i<len && online;i++)
+        if(outcom(str[i])!=0)
+			break;
+	return i;
 }
 
 /* Legacy Remote I/O Control Interface */
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 96eb9853d0..a48ca88eac 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -202,7 +202,7 @@ public:
 
 	void	spymsg(const char *msg);		// send message to active spies
 
-	void	putcom(const char *str, int len=0);  // Send string
+	int		putcom(const char *str, size_t len=0);  // Send string
 	void	hangup(void);		   // Hangup modem
 
 	uchar	telnet_local_option[0x100];
@@ -512,10 +512,10 @@ public:
 	int		bulkmailhdr(smb_t*, smbmsg_t*, uint usernum);
 
 	/* con_out.cpp */
-	int		bputs(const char *str);				/* BBS puts function */
-	int		rputs(const char *str);				/* BBS raw puts function */
-	int		bprintf(const char *fmt, ...);		/* BBS printf function */
-	int		rprintf(const char *fmt, ...);		/* BBS raw printf function */
+	int		bputs(const char *str);					/* BBS puts function */
+	int		rputs(const char *str, size_t len=0);	/* BBS raw puts function */
+	int		bprintf(const char *fmt, ...);			/* BBS printf function */
+	int		rprintf(const char *fmt, ...);			/* BBS raw printf function */
 	void	backspace(void);				/* Output a destructive backspace via outchar */
 	void	outchar(char ch);				/* Output a char - check echo and emu.  */
 	void	center(char *str);
-- 
GitLab