From 0fba2f8774cceb657e277a6fa7bfeeb3da2d7c6f Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Debian Linux)" <rob@synchro.net>
Date: Sat, 6 May 2023 12:51:18 -0700
Subject: [PATCH] Perform input translation (e.g. DEL<->BKSPC, PETSCII chars)
 in input_thread()

My first idea was to have a per-external-program setting to enable input
translation, but Deuce suggested it would be better done in input_thread() and
after some thought, I agree. Translations are not done in data/file transfer
mode, so use the CON_RAW_IN console flag to indicate this condition. So even
JS console.getbyte() will return a translated char unless the console is set
raw input mode (this could be surprising behavior for some!).

I considered saving/restoring the console mode when performing a file transfer
but will leave that to a time when obviously needed.

This fixes issue #497 in automatic way (no option needed).
---
 src/sbbs3/download.cpp | 30 ++++++++++++++++++++----------
 src/sbbs3/inkey.cpp    |  4 +---
 src/sbbs3/main.cpp     |  3 +++
 src/sbbs3/sbbs.h       |  4 +++-
 src/sbbs3/sbbsdefs.h   |  2 --
 5 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/src/sbbs3/download.cpp b/src/sbbs3/download.cpp
index 1cb0316d45..031097d563 100644
--- a/src/sbbs3/download.cpp
+++ b/src/sbbs3/download.cpp
@@ -101,6 +101,24 @@ const char* sbbs_t::protcmdline(prot_t* prot, enum XFER_TYPE type)
 	return("invalid transfer type");
 }
 
+void sbbs_t::data_transfer_begin(void)
+{
+	sys_status|=SS_FILEXFER;	/* disable spy during file xfer */
+	/* enable telnet binary transmission in both directions */
+	request_telnet_opt(TELNET_DO,TELNET_BINARY_TX);
+	request_telnet_opt(TELNET_WILL,TELNET_BINARY_TX);
+	console |= CON_RAW_IN;
+}
+
+void sbbs_t::data_transfer_end(void)
+{
+	sys_status&=~SS_FILEXFER;
+	/* Got back to Text/NVT mode */
+	request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX);
+	request_telnet_opt(TELNET_WONT,TELNET_BINARY_TX);
+	console &= ~CON_RAW_IN;
+}
+
 /****************************************************************************/
 /* Handles start and stop routines for transfer protocols                   */
 /****************************************************************************/
@@ -143,19 +161,11 @@ int sbbs_t::protocol(prot_t* prot, enum XFER_TYPE type
 	cmdline=cmdstr(protcmdline(prot,type), fpath, fspec, NULL, ex_mode);
 	SAFEPRINTF(msg,"Transferring %s",cmdline);
 	spymsg(msg);
-	sys_status|=SS_FILEXFER;	/* disable spy during file xfer */
-	/* enable telnet binary transmission in both directions */
-	request_telnet_opt(TELNET_DO,TELNET_BINARY_TX);
-	request_telnet_opt(TELNET_WILL,TELNET_BINARY_TX);
-
+	data_transfer_begin();
 	time_t start = time(NULL);
 	i=external(cmdline,ex_mode,p);
 	time_t end = time(NULL);
-	/* Got back to Text/NVT mode */
-	request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX);
-	request_telnet_opt(TELNET_WONT,TELNET_BINARY_TX);
-
-	sys_status&=~SS_FILEXFER;
+	data_transfer_end();
 
 	// Save DSZLOG to logfile
 	if((stream=fnopen(NULL,protlog,O_RDONLY))!=NULL) {
diff --git a/src/sbbs3/inkey.cpp b/src/sbbs3/inkey.cpp
index ec45bb1c57..f3c3ae96a3 100644
--- a/src/sbbs3/inkey.cpp
+++ b/src/sbbs3/inkey.cpp
@@ -40,8 +40,6 @@ int sbbs_t::kbincom(unsigned int timeout)
 	}
 	ch = incom(timeout);
 
-	if(ch != NOINP)
-		ch = translate_input(ch);
 	return ch;
 }
 
@@ -86,7 +84,7 @@ int sbbs_t::translate_input(int ch)
 	return ch;
 }
 
-void sbbs_t::translate_input(char* buf, size_t len)
+void sbbs_t::translate_input(uchar* buf, size_t len)
 {
 	for(size_t i =0; i < len; i++)
 		buf[i] = translate_input(buf[i]);
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 044767cbb1..bf19a832d5 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -2131,6 +2131,9 @@ void input_thread(void *arg)
 		if(wr > (int)sizeof(telbuf))
 			lprintf(LOG_ERR,"!TELBUF OVERFLOW (%d>%d)",wr,(int)sizeof(telbuf));
 
+		if(!(sbbs->console & CON_RAW_IN))
+			sbbs->translate_input(wrbuf, wr);
+
 		if(sbbs->passthru_socket_active == true) {
 			BOOL writable = FALSE;
 			if(socket_check(sbbs->passthru_socket, NULL, &writable, 1000) && writable)
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 600be5a12c..dc6f5d345b 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -449,7 +449,7 @@ public:
 	int 	incom(unsigned int timeout=0);		   // receive character
 	int 	kbincom(unsigned int timeout=0);	   // " " or return keyboard buffer
 	int		translate_input(int ch);
-	void	translate_input(char* buf, size_t);
+	void	translate_input(uchar* buf, size_t);
 
 	void	spymsg(const char *msg);		// send message to active spies
 
@@ -1053,6 +1053,8 @@ public:
 	bool	bulkupload(uint dirnum);
 
 	/* download.cpp */
+	void	data_transfer_begin(void);
+	void	data_transfer_end(void);
 	void	downloadedfile(file_t* f);
 	void	notdownloaded(off_t size, time_t elapsed);
 	void	downloadedbytes(off_t size, time_t elapsed);
diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h
index 11ea36c005..731a113508 100644
--- a/src/sbbs3/sbbsdefs.h
+++ b/src/sbbs3/sbbsdefs.h
@@ -418,7 +418,6 @@ typedef enum {						/* Values for xtrn_t.event				*/
 #define XTRN_UART		(1<<25)		/* Enable the virtual UART driver		*/
 #define XTRN_FOSSIL		(1<<26)		/* Enable the int14h/FOSSIL driver		*/
 #define XTRN_NODISPLAY	(1<<27)		/* Disable local screen/display			*/
-#define XTRN_COOKEDINP	(1<<28)		/* Perform keyboard input translations	*/
 #define XTRN_CONIO		(1<<31)		/* Intercept Windows Console I/O (Drwy)	*/
 
 									/* Bits in user.qwk 					*/
@@ -753,7 +752,6 @@ enum {							/* readmail and delmailidx which types		*/
 #define EX_UART		XTRN_UART
 #define EX_FOSSIL	XTRN_FOSSIL
 #define EX_NODISPLAY XTRN_NODISPLAY
-#define EX_COOKEDINP XTRN_COOKEDINP
 #define EX_NOLOG	(1<<30)		/* Don't log intercepted stdio				*/
 #define EX_CONIO	(1<<31)		/* Intercept Windows console I/O (doorway)	*/
 #define EX_UNSPECIFIED	-1
-- 
GitLab