diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 321c907bd00b5c7822e40a09cd5a56d5ab15c67a..a32dfefc3f7837e491a3bf9ab24dfd75f7402b1e 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 cabc7730049567086e01385d74fc21929518c4db..ede4e70455baf1e0438b48cc358d3db2a2fa951d 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 46ff730d9f58dd663fcce7b5b819660b8341446e..18d963b305b19b3aec1d88488d4eb0d245cedbfd 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 45fdbca9b9e1be4d620b16a0ba4fbf448add528c..88d26590697657601bbcc7561bd0ce378d049c44 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 5c77a025671b1018ae5a7b46f92ee1273c38b814..2e3ae1a6d2c271d1b4b96b825798d41cb8851a01 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 5382d44780bf639c1f4352cdc46a0fabc4b077b6..20e6fb8d8333aacba979c50e5c4980a44283a73d 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 9b9675c0dc28577e87fe342befa86638f360a97e..6389d61bac73b0e753c064cb1657bcf26c34fcd6 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 */