From ae36a7b4014880804d49bdb6a4ef7905958478eb Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Tue, 24 Nov 2020 21:48:39 -0800
Subject: [PATCH] Insure %j %k %n %! all expand special Linux-DOSEMU "drives"

... when running DOS programs on Linux with a DOSEMU-enabled build.
---
 src/sbbs3/chat.cpp     |  2 +-
 src/sbbs3/download.cpp | 16 +++++++++-------
 src/sbbs3/sbbs.h       |  2 +-
 src/sbbs3/sbbsdefs.h   |  1 +
 src/sbbs3/writemsg.cpp |  4 ++--
 src/sbbs3/xtrn.cpp     | 30 +++++++++++++++++++++++++-----
 src/sbbs3/xtrn_sec.cpp |  4 ++--
 7 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 321c907bd0..a32dfefc3f 100644
--- a/src/sbbs3/chat.cpp
+++ b/src/sbbs3/chat.cpp
@@ -723,7 +723,7 @@ bool sbbs_t::sysop_page(void)
 				mode|= EX_NATIVE;
 			if(cfg.page[i]->misc&XTRN_SH)
 				mode |= EX_SH;
-			external(cmdstr(cfg.page[i]->cmd,nulstr,nulstr,NULL), mode); 
+			external(cmdstr(cfg.page[i]->cmd,nulstr,nulstr,NULL,mode), mode); 
 		}
 		else if(cfg.sys_misc&SM_SHRTPAGE) {
 			bprintf(text[PagingGuru],cfg.sys_op);
diff --git a/src/sbbs3/download.cpp b/src/sbbs3/download.cpp
index cabc773004..ede4e70455 100644
--- a/src/sbbs3/download.cpp
+++ b/src/sbbs3/download.cpp
@@ -219,13 +219,7 @@ int sbbs_t::protocol(prot_t* prot, enum XFER_TYPE type
 		p=cfg.temp_dir;
 	else
 		p=NULL;
-	cmdline=cmdstr(protcmdline(prot,type),fpath,fspec,NULL);
-	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);
+
 	ex_mode = EX_BIN;
 	if(prot->misc&PROT_NATIVE)
 		ex_mode|=EX_NATIVE;
@@ -234,6 +228,14 @@ int sbbs_t::protocol(prot_t* prot, enum XFER_TYPE type
 		ex_mode|=EX_STDIO;
 #endif
 
+	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);
+
 	i=external(cmdline,ex_mode,p);
 	/* Got back to Text/NVT mode */
 	request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX);
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 46ff730d9f..18d963b305 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -675,7 +675,7 @@ public:
 	bool	inputnstime32(time32_t *dt);
 	bool	inputnstime(time_t *dt);
 	bool	chkpass(char *pass, user_t* user, bool unique);
-	char *	cmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr);
+	char *	cmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr, long mode = EX_UNSPECIFIED);
 	char	cmdstr_output[512];
 
 	void	subinfo(uint subnum);
diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h
index 45fdbca9b9..88d2659069 100644
--- a/src/sbbs3/sbbsdefs.h
+++ b/src/sbbs3/sbbsdefs.h
@@ -842,6 +842,7 @@ enum {							/* readmail and delmailidx which types		*/
 #define EX_JS_CX	(1<<24)		/* New JavaScript context */
 #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
 
 #if defined(__unix__)
 #define EX_WILDCARD	EX_SH		/* Expand wildcards using 'sh' on Unix		*/
diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index 5c77a02567..2e3ae1a6d2 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -597,7 +597,7 @@ bool sbbs_t::writemsg(const char *fname, const char *top, char *subj, long mode,
 
 		CLS;
 		rioctl(IOCM|PAUSE|ABORT);
-		const char* cmd = cmdstr(cfg.xedit[useron_xedit-1]->rcmd, msgtmp, nulstr, NULL);
+		const char* cmd = cmdstr(cfg.xedit[useron_xedit-1]->rcmd, msgtmp, nulstr, NULL, ex_mode);
 		int result = external(cmd, ex_mode, cfg.node_dir);
 		lprintf(LOG_DEBUG, "'%s' returned %d", cmd, result);
 		rioctl(IOSM|PAUSE|ABORT); 
@@ -1251,7 +1251,7 @@ bool sbbs_t::editfile(char *fname, bool msg)
 		}
 		CLS;
 		rioctl(IOCM|PAUSE|ABORT);
-		if(external(cmdstr(cfg.xedit[useron_xedit-1]->rcmd,msgtmp,nulstr,NULL),mode,cfg.node_dir)!=0)
+		if(external(cmdstr(cfg.xedit[useron_xedit-1]->rcmd,msgtmp,nulstr,NULL,mode), mode, cfg.node_dir)!=0)
 			return false;
 		l=process_edited_file(msgtmp, path, /* mode: */WM_EDIT, &lines,maxlines);
 		if(l>0) {
diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp
index 5382d44780..20e6fb8d83 100644
--- a/src/sbbs3/xtrn.cpp
+++ b/src/sbbs3/xtrn.cpp
@@ -1847,7 +1847,7 @@ const char* quoted_string(const char* str, char* buf, size_t maxlen)
 /*****************************************************************************/
 /* Returns command line generated from instr with %c replacements            */
 /*****************************************************************************/
-char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr)
+char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr, long mode)
 {
 	char	str[MAX_PATH+1],*cmd;
     int		i,j,len;
@@ -1895,10 +1895,20 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch
                     strncat(cmd,cid, avail);
                     break;
                 case 'J':
-                    strncat(cmd,cfg.data_dir, avail);
+#if defined(__linux__) && defined(USE_DOSEMU)
+					if(mode != EX_UNSPECIFIED && !(mode & EX_NATIVE))
+						strncat(cmd, DOSEMU_DATA_DRIVE "\\", avail);
+					else
+#endif
+						strncat(cmd,cfg.data_dir, avail);
                     break;
                 case 'K':
-                    strncat(cmd,cfg.ctrl_dir, avail);
+#if defined(__linux__) && defined(USE_DOSEMU)
+					if(mode != EX_UNSPECIFIED && !(mode & EX_NATIVE))
+						strncat(cmd, DOSEMU_CTRL_DRIVE "\\", avail);
+					else
+#endif
+	                    strncat(cmd,cfg.ctrl_dir, avail);
                     break;
                 case 'L':   /* Lines per message */
                     strncat(cmd,ultoa(cfg.level_linespermsg[useron.level],str,10), avail);
@@ -1907,7 +1917,12 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch
                     strncat(cmd,ultoa(useron.min,str,10), avail);
                     break;
                 case 'N':   /* Node Directory (same as SBBSNODE environment var) */
-                    strncat(cmd,cfg.node_dir, avail);
+#if defined(__linux__) && defined(USE_DOSEMU)
+					if(mode != EX_UNSPECIFIED && !(mode & EX_NATIVE))
+						strncat(cmd, DOSEMU_NODE_DRIVE "\\", avail);
+					else
+#endif
+	                    strncat(cmd,cfg.node_dir, avail);
                     break;
                 case 'O':   /* SysOp */
                     strncat(cmd,QUOTED_STRING(instr[i],cfg.sys_op,str,sizeof(str)), avail);
@@ -1960,7 +1975,12 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch
 #endif
 					break;
                 case '!':   /* EXEC Directory */
-                    strncat(cmd,cfg.exec_dir, avail);
+#if defined(__linux__) && defined(USE_DOSEMU)
+					if(mode != EX_UNSPECIFIED && !(mode & EX_NATIVE))
+						strncat(cmd, DOSEMU_EXEC_DRIVE "\\", avail);
+					else
+#endif
+	                    strncat(cmd,cfg.exec_dir, avail);
                     break;
                 case '@':   /* EXEC Directory for DOS/OS2/Win32, blank for Unix */
 #ifndef __unix__
diff --git a/src/sbbs3/xtrn_sec.cpp b/src/sbbs3/xtrn_sec.cpp
index 9b9675c0dc..6389d61bac 100644
--- a/src/sbbs3/xtrn_sec.cpp
+++ b/src/sbbs3/xtrn_sec.cpp
@@ -1625,14 +1625,14 @@ bool sbbs_t::exec_xtrn(uint xtrnnum)
 	}
 
 	start=time(NULL);
-	external(cmdstr(cfg.xtrn[xtrnnum]->cmd, drop_file, startup_dir, NULL)
+	external(cmdstr(cfg.xtrn[xtrnnum]->cmd, drop_file, startup_dir, NULL, mode)
 		,mode
 		,cfg.xtrn[xtrnnum]->path);
 	end=time(NULL);
 	if(cfg.xtrn[xtrnnum]->misc&FREETIME)
 		starttime+=end-start;
 	if(cfg.xtrn[xtrnnum]->clean[0]) {
-		external(cmdstr(cfg.xtrn[xtrnnum]->clean, drop_file, startup_dir, NULL)
+		external(cmdstr(cfg.xtrn[xtrnnum]->clean, drop_file, startup_dir, NULL, mode)
 			,mode&~(EX_STDIN|EX_CONIO), cfg.xtrn[xtrnnum]->path); 
 	}
 	/* Re-open the logfile */
-- 
GitLab