diff --git a/ctrl/dosemu.conf b/ctrl/dosemu.conf new file mode 100644 index 0000000000000000000000000000000000000000..811ae914c64f82e620f87b5a64cf20fba650d27e --- /dev/null +++ b/ctrl/dosemu.conf @@ -0,0 +1,20 @@ +$_cpu = "80486" +$_cpu_emu = "fullsim" +$_floppy_a = "" +$_cdrom = "" +$_xms = (1024) +$_ems = (1024) +$_ems_frame = (0xe000) +$_external_char_set = "cp437" +$_internal_char_set = "cp437" +$_term_updfreq = (8) +$_layout = "us" +$_rawkeyboard = (auto) +$_mouse_internal = (on) +$_mouse_dev = "" +$_joy_device = "" +$_lpt1 = "" +$_lp2 = "" +$_speaker = "" +$_sound = (off) +$_sb_dsp = "" diff --git a/ctrl/sbbs.ini b/ctrl/sbbs.ini index b83519c86805740880cea7947befd6ee790a052f..31c73dfe1cf2a1d316b71248d2af8e929ec4207e 100644 --- a/ctrl/sbbs.ini +++ b/ctrl/sbbs.ini @@ -98,8 +98,12 @@ ; Must install install/termcap or terminfo to use the following TERM setting: ; ExternalTermANSI = ansi-bbs ExternalTermDumb = dumb -; To change the default dosemu/doscmd path, uncomment and set: -; DOSemuPath = + +; To setup the dosemu cmd path and ini: +UseDOSemu = false +DOSemuPath = /usr/bin/dosemu.bin +; leave off dir path to use ctrl dir +DOSemuConfPath = dosemu.conf ; At what size to send the current output buffer regardless of timeout ; ie: Send output whenever there are at least this many bytes waiting. diff --git a/exec/dosemu.ini b/exec/dosemu.ini new file mode 100644 index 0000000000000000000000000000000000000000..72ff5e7237d0c09eb9f17d35c0dedd16ef8d0ace --- /dev/null +++ b/exec/dosemu.ini @@ -0,0 +1,22 @@ +; This contains the command line to execute DOSEMU +; +; You can copy this file to customize for any specific external programs +; that need changes by placing a copy of this file into the external program's +; startup directory. +; +; The following substitutions will be performed on this file: +; $TERM sets 'TERM=linux' (used on events, etc.) +; $CTRLDIR = path to synchronet ctrl dir +; $NODEDIR = path to synchronet node dir +; $DOSEMUBIN = path to dosemu.bin +; $VIRTCONF = appends virtual when needed (ie fossil) (-I"serial { virtual com 1 }") +; $DOSEMUCONF = path to global dosemu conf +; $EXTBAT = batch file to execute (external.bat) +; $EXTLOG = external log (used on events) +; add -I'keystroke "\r"' if you need that behavior back +; +; for com/uart/fossil i/o external programs, put it in the global "cmd" key +; for intercept i/o programs, you can override by putting "cmd" key under [stdio] section +cmd=/usr/bin/env $TERM HOME=$CTRLDIR QUIET=1 DOSDRIVE_D=$NODEDIR NODEDIR=$NODEDIR $DOSEMUBIN -I"video { none }" $VIRTUALCONF -f$DOSEMUCONF -E$EXTBAT -o$NODEDIRdosemu_boot.log $EXTLOG +[stdio] +cmd=/usr/bin/env $TERM HOME=$CTRLDIR QUIET=1 DOSDRIVE_D=$NODEDIR NODEDIR=$NODEDIR $DOSEMUBIN -I"video { none }" -I'keystroke "\n"' $VIRTUALCONF -f$DOSEMUCONF -E$EXTBAT -o$NODEDIRdosemu_boot.log $EXTLOG diff --git a/exec/external.bat b/exec/external.bat new file mode 100644 index 0000000000000000000000000000000000000000..9b6ffeaed53858ff56f53caa159d4ec574d7cab5 --- /dev/null +++ b/exec/external.bat @@ -0,0 +1,47 @@ +@lredir D: linux\fs$NODEDIR >NUL +@lredir E: linux\fs$XTRNDIR >NUL +@lredir F: linux\fs$CTRLDIR >NUL +@lredir G: linux\fs$DATADIR >NUL +@lredir H: linux\fs$EXECDIR >NUL + +E: + +REM Switch to startup dir, unless its not defined +REM If not defined, go to node dir (external editors use this) +IF "%STARTDIR%"=="" D: +IF NOT "%STARTDIR%"=="" CD %STARTDIR% + +REM Optionally call emusetup.bat or put that stuff here for global (in NOEMU) +REM Looks in startup dir, then ctrl dir +IF EXIST EMUSETUP.BAT GOTO EMULOCAL +IF EXIST F:\EMUSETUP.BAT GOTO EMUGLOBAL +IF EXIST E:\DOSUTILS\NUL GOTO NOEMU +IF EXIST H:\DOSUTILS\NUL GOTO NOEMU +ECHO ERROR: No emusetup.bat in E:\%STARTDIR% or F, or DOSUTILS is missing +GOTO EXEC + +:EMULOCAL +CALL EMUSETUP.BAT +GOTO EXEC + +:EMUGLOBAL +CALL F:\EMUSETUP.BAT +GOTO EXEC + +:NOEMU +@set PATH=%PATH%;E:\dosutils;H:\dosutils +REM fossil driver, such as x00, bnu, or dosemu fossil.com +rem IF "$RUNTYPE" == "FOSSIL" @fossil.com >NUL +rem IF "$RUNTYPE" == "FOSSIL" bnu.com /P1 /L0=11520 >NUL +IF "$RUNTYPE" == "FOSSIL" x00.exe eliminate >NUL +REM share.exe for multinode file locking +@share >NUL + +GOTO EXEC + +:EXEC +$CMDLINE + +IF NOT "%1" == "TEST" exitemu + + diff --git a/install/GNUmakefile b/install/GNUmakefile index 7b6abd6a4ce375d8e5642c4e61e1938533cfeff0..e10ce423e64b9b4aa82445d4f3296df610c4dc5a 100644 --- a/install/GNUmakefile +++ b/install/GNUmakefile @@ -28,7 +28,6 @@ # NO_X = Don't include build conio library (ciolib) for X # NO_GTK = Don't build GTK-based sysop tools # X_PATH = /path/to/X (if not /usr/X11R6) -# USE_DOSEMU = Set to 1 to enable Linux-DOSEMU support # the magic bit: MKFLAGS += MAKEFLAGS= @@ -131,10 +130,6 @@ ifdef X_PATH MKFLAGS += X_PATH=$(X_PATH) endif -ifdef USE_DOSEMU - MKFLAGS += USE_DOSEMU=$(USE_DOSEMU) -endif - # Check for GLADE ifndef NO_GTK ifeq ($(shell pkg-config libglade-2.0 --exists && echo YES),YES) diff --git a/src/sbbs3/CMakeLists.txt b/src/sbbs3/CMakeLists.txt index 88947d97ea87867411fabdda0c742540e437b116..a475dc78542ba9ff94e1b5baaad1a372edd5db61 100644 --- a/src/sbbs3/CMakeLists.txt +++ b/src/sbbs3/CMakeLists.txt @@ -5,11 +5,6 @@ cmake_minimum_required(VERSION 2.8.11) INCLUDE (../build/SynchronetMacros.cmake) INCLUDE (CheckFunctionExists) -if(UNIX) - set(SBBS_USE_DOSEMU FALSE - CACHE BOOL "Set if you intend on using dosemu on Linux" - ) -endif() set(SBBS_BUILD_JSDOCS FALSE CACHE INTERNAL "DEVELOPER ONLY - Build only to run jsdocs.js (not a BBS)" ) diff --git a/src/sbbs3/GNUmakefile b/src/sbbs3/GNUmakefile index b5446d7b7580efefb4df80e7601df0765e8ba507..6a7f6b068ae32e9b6563c16e78d44055276e309c 100644 --- a/src/sbbs3/GNUmakefile +++ b/src/sbbs3/GNUmakefile @@ -11,8 +11,6 @@ # Optional build targets: dlls, utils, mono, all (default) # ######################################################################### -# $Id: GNUmakefile,v 1.248 2020/04/03 19:54:31 rswindell Exp $ - PWD := $(shell pwd) SRC_ROOT ?= ${PWD}/.. include $(SRC_ROOT)/build/Common.gmake @@ -43,10 +41,6 @@ ifdef PREFIX CFLAGS += -DPREFIX=$(PREFIX) endif -ifdef USE_DOSEMU - CFLAGS += -DUSE_DOSEMU -endif - ifdef DONT_BLAME_SYNCHRONET CFLAGS += -DDONT_BLAME_SYNCHRONET endif diff --git a/src/sbbs3/chk_ar.cpp b/src/sbbs3/chk_ar.cpp index 88842c7a03ebd0af0f770366c6e0fb9f95976f7e..95f36075e94a78531e4056e81a5f383a952e4503 100644 --- a/src/sbbs3/chk_ar.cpp +++ b/src/sbbs3/chk_ar.cpp @@ -223,8 +223,11 @@ bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client) result=_not; if(startup->options&BBS_OPT_NO_DOS) break; - #if defined(_WIN32) || (defined(__linux__) && defined(USE_DOSEMU)) || defined(__FreeBSD__) + #if defined(_WIN32) || defined(__FreeBSD__) result=!_not; + #elif defined(__linux__) + if (startup->usedosemu) + result=!_not; #endif break; case AR_WIN32: diff --git a/src/sbbs3/install/sbbsinst.c b/src/sbbs3/install/sbbsinst.c index 60fa9a9d79c35b0b52cb925bf207e1d1f2575331..9cdb03536f38491bcf04a58d8c3177c81c8bbd0d 100644 --- a/src/sbbs3/install/sbbsinst.c +++ b/src/sbbs3/install/sbbsinst.c @@ -121,9 +121,6 @@ struct { struct utsname name; char sbbsuser[9]; /* Historical UName limit of 8 chars */ char sbbsgroup[17]; /* Can't find historical limit for group names */ -#ifdef __linux__ - BOOL use_dosemu; -#endif } params; /* Build parameters */ #define MAKEFILE "/tmp/SBBSmakefile" @@ -230,9 +227,6 @@ int main(int argc, char **argv) SAFECOPY(params.sbbsuser,p); if((p=getenv("GROUP"))!=NULL) SAFECOPY(params.sbbsgroup,p); -#ifdef __linux__ - params.use_dosemu=FALSE; -#endif sscanf("$Revision: 1.100 $", "%*s %s", revision); umask(077); @@ -380,9 +374,7 @@ int main(int argc, char **argv) sprintf(mopt[i++],"%-27.27s%s","Make Command-line",params.make_cmdline); sprintf(mopt[i++],"%-27.27s%s","File Owner",params.sbbsuser); sprintf(mopt[i++],"%-27.27s%s","File Group",params.sbbsgroup); -#ifdef __linux__ - sprintf(mopt[i++],"%-27.27s%s","Integrate DOSEmu support",params.use_dosemu?"Yes":"No"); -#endif + sprintf(mopt[i++],"%-27.27s","Start Installation..."); mopt[i][0]=0; @@ -488,26 +480,8 @@ int main(int argc, char **argv) "\n"; uifc.input(WIN_MID,0,0,"",params.sbbsgroup,32,K_EDIT); break; -#ifdef __linux__ - case 11: - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - i=params.use_dosemu?0:1; - uifc.helpbuf= "`Include DOSEmu Support`\n" - "\nToDo: Add help."; - i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 - ,"Integrate DOSEmu support into Synchronet?",opt); - if(!i) - params.use_dosemu=TRUE; - else if(i==1) - params.use_dosemu=FALSE; - i=0; - break; - case 12: -#else + case 11: -#endif install_sbbs(distlist[dist],distlist[dist]->type==LOCAL_FILE?NULL:distlist[dist]->servers[server]); bail(0); break; @@ -754,11 +728,6 @@ void install_sbbs(dist_t *dist,struct server_ent_t *server) { sprintf(sbbsgroup,"SBBSGROUP=%s",params.sbbsgroup); putenv(sbbsgroup); } -#ifdef __linux__ - if(params.use_dosemu==TRUE) { - putenv("USE_DOSEMU=1"); - } -#endif if(params.usebcc) putenv("bcc=1"); diff --git a/src/sbbs3/sbbs_ini.c b/src/sbbs3/sbbs_ini.c index 0454ec9566fd1b7d286fcf3a209b98636ca787f8..f42808d34ee226f9c6725e3e6f40707f6d5e693f 100644 --- a/src/sbbs3/sbbs_ini.c +++ b/src/sbbs3/sbbs_ini.c @@ -251,6 +251,7 @@ void sbbs_read_ini( const char* section; const char* default_term_ansi; const char* default_dosemu_path; + const char* default_dosemuconf_path; char value[INI_MAX_VALUE_LEN]; str_list_t list; global_startup_t global_buf; @@ -366,10 +367,14 @@ void sbbs_read_ini( default_dosemu_path="/usr/local/bin/doscmd"; #else default_dosemu_path="/usr/bin/dosemu.bin"; + default_dosemuconf_path=""; #endif + bbs->usedosemu=iniGetBool(list,section,"UseDOSemu",TRUE); SAFECOPY(bbs->dosemu_path ,iniGetString(list,section,"DOSemuPath",default_dosemu_path,value)); + SAFECOPY(bbs->dosemuconf_path + ,iniGetString(list,section,"DOSemuConfPath",default_dosemuconf_path,value)); SAFECOPY(bbs->answer_sound ,iniGetString(list,section,strAnswerSound,nulstr,value)); @@ -839,7 +844,10 @@ BOOL sbbs_write_ini( break; if(!iniSetString(lp,section,"DOSemuPath",bbs->dosemu_path,&style)) break; - + if(!iniSetString(lp,section,"DOSemuConfPath",bbs->dosemuconf_path,&style)) + break; + if(!iniSetBool(lp,section,"UseDOSemu",bbs->usedosemu,&style)) + break; if(!iniSetString(lp,section,strAnswerSound,bbs->answer_sound,&style)) break; if(!iniSetString(lp,section,strHangupSound,bbs->hangup_sound,&style)) diff --git a/src/sbbs3/startup.h b/src/sbbs3/startup.h index ad869edfe8adf0e48dceca8fe219877d4ef4c1db..e4febaaa63fdb9c4628f96c14908248804de37dc 100644 --- a/src/sbbs3/startup.h +++ b/src/sbbs3/startup.h @@ -113,12 +113,14 @@ typedef struct { /* Paths */ char ctrl_dir[128]; char dosemu_path[128]; + char dosemuconf_path[128]; char temp_dir[128]; char answer_sound[128]; char hangup_sound[128]; char ini_fname[128]; /* Miscellaneous */ + BOOL usedosemu; char xtrn_term_ansi[32]; /* external ANSI terminal type (e.g. "ansi-bbs") */ char xtrn_term_dumb[32]; /* external dumb terminal type (e.g. "dumb") */ char host_name[128]; diff --git a/src/sbbs3/str_util.c b/src/sbbs3/str_util.c index 23457c253542eec9cc217a7236e82c8095d78497..67ab24cfa4e193c45175fa882c201872e5b884df 100644 --- a/src/sbbs3/str_util.c +++ b/src/sbbs3/str_util.c @@ -649,6 +649,79 @@ char* ascii_str(uchar* str) return((char*)str); } +char* replace_named_values(const char* src + ,char* buf + ,size_t buflen /* includes '\0' terminator */ + ,const char* escape_seq + ,named_string_t* string_list + ,named_int_t* int_list + ,BOOL case_sensitive) + { + char val[32]; + size_t i; + size_t esc_len=0; + size_t name_len; + size_t value_len; + char* p = buf; + int (*cmp)(const char*, const char*, size_t); + + if(case_sensitive) + cmp=strncmp; + else + cmp=strnicmp; + + if(escape_seq!=NULL) + esc_len = strlen(escape_seq); + + while(*src && (size_t)(p-buf) < buflen-1) { + if(esc_len) { + if(cmp(src, escape_seq, esc_len)!=0) { + *p++ = *src++; + continue; + } + src += esc_len; /* skip the escape seq */ + } + if(string_list) { + for(i=0; string_list[i].name!=NULL /* terminator */; i++) { + name_len = strlen(string_list[i].name); + if(cmp(src, string_list[i].name, name_len)==0) { + value_len = strlen(string_list[i].value); + if((p-buf)+value_len > buflen-1) /* buffer overflow? */ + value_len = (buflen-1)-(p-buf); /* truncate value */ + memcpy(p, string_list[i].value, value_len); + p += value_len; + src += name_len; + break; + } + } + if(string_list[i].name!=NULL) /* variable match */ + continue; + } + if(int_list) { + for(i=0; int_list[i].name!=NULL /* terminator */; i++) { + name_len = strlen(int_list[i].name); + if(cmp(src, int_list[i].name, name_len)==0) { + SAFEPRINTF(val,"%d",int_list[i].value); + value_len = strlen(val); + if((p-buf)+value_len > buflen-1) /* buffer overflow? */ + value_len = (buflen-1)-(p-buf); /* truncate value */ + memcpy(p, val, value_len); + p += value_len; + src += name_len; + break; + } + } + if(int_list[i].name!=NULL) /* variable match */ + continue; + } + + *p++ = *src++; + } + *p=0; /* terminate string in destination buffer */ + + return(buf); + } + /****************************************************************************/ /* Condense consecutive white-space chars in a string to single spaces */ /****************************************************************************/ diff --git a/src/sbbs3/str_util.h b/src/sbbs3/str_util.h index 4ffac35a80b52a563ae6547b526e589ecd0bfae2..e0657bfe2a17eb7a633b4bc06dca93ec012ad6f7 100644 --- a/src/sbbs3/str_util.h +++ b/src/sbbs3/str_util.h @@ -39,6 +39,9 @@ DLLEXPORT char * remove_ctrl_a(const char* instr, char* outstr); DLLEXPORT char ctrl_a_to_ascii_char(char code); DLLEXPORT char * truncstr(char* str, const char* set); DLLEXPORT char * ascii_str(uchar* str); +DLLEXPORT char * replace_named_values(const char* src ,char* buf, size_t buflen, + const char* escape_seq, named_string_t* string_list, + named_int_t* int_list, BOOL case_sensitive); DLLEXPORT char * condense_whitespace(char* str); DLLEXPORT char exascii_to_ascii_char(uchar ch); DLLEXPORT BOOL findstr(const char *insearch, const char *fname); diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index 855d05724ac410df25afd4931042a55ff4d2b861..44f6079cef58e0b753a7dc5541d7e7c10506ab84 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -1763,7 +1763,7 @@ static BOOL ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user, client_t* client) #endif break; case AR_DOS: - #if defined(_WIN32) || (defined(__linux__) && defined(USE_DOSEMU)) || defined(__FreeBSD__) + #if defined(_WIN32) || defined(__linux__) || defined(__FreeBSD__) result=!not; #else result=not; diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index 79a7ef73c696b453799d641cb2ac1e89847b44e1..9f39b4d633ec903a13e2e2c33037a60c7b8a43ec 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -1174,20 +1174,29 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) SAFECOPY(str,fullcmdline); sprintf(fullcmdline,"%s -F %s",startup->dosemu_path,str); -#elif defined(__linux__) && defined(USE_DOSEMU) +#elif defined(__linux__) - /* dosemu integration -- Ryan Underwood, <nemesis @ icequake.net> */ + /* dosemu integration -- originally by Ryan Underwood, <nemesis @ icequake.net> */ - FILE *dosemubat; - int setup_override; + FILE *dosemubatfp; + FILE *externalbatfp; + FILE *de_launch_inifp; char tok[MAX_PATH+1]; + char buf[1024]; + char bufout[1024]; + char cmdlinebatch[MAX_PATH+1]; + char externalbatsrc[MAX_PATH+1]; + char externalbat[MAX_PATH+1]; char dosemuconf[MAX_PATH+1]; + char de_launch_cmd[INI_MAX_VALUE_LEN]; char dosemubinloc[MAX_PATH+1]; char virtualconf[75]; char dosterm[15]; char log_external[MAX_PATH+1]; - + const char* runtype; + str_list_t de_launch_ini; + /* on the Unix side. xtrndir is the parent of the door's startup dir. */ char xtrndir[MAX_PATH+1]; @@ -1196,15 +1205,18 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) char ctrldir_dos[MAX_PATH+1]; char datadir_dos[MAX_PATH+1]; char execdir_dos[MAX_PATH+1]; + char nodedir_dos[MAX_PATH+1]; /* Default locations that can be overridden by * the sysop in emusetup.bat */ - const char nodedrive[] = DOSEMU_NODE_DRIVE; - const char xtrndrive[] = DOSEMU_XTRN_DRIVE; const char ctrldrive[] = DOSEMU_CTRL_DRIVE; const char datadrive[] = DOSEMU_DATA_DRIVE; const char execdrive[] = DOSEMU_EXEC_DRIVE; + const char nodedrive[] = DOSEMU_NODE_DRIVE; + + const char external_bat_fn[] = "external.bat"; + const char dosemu_cnf_fn[] = "dosemu.conf"; SAFECOPY(str,startup_dir); if(*(p=lastchar(str))=='/') /* kill trailing slash */ @@ -1214,8 +1226,9 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) SAFECOPY(xtrndir,str); - /* construct DOS equivalents for the unix directories */ - + SAFECOPY(xtrndir_dos,xtrndir); + REPLACE_CHARS(xtrndir_dos,'/','\\',p); + SAFECOPY(ctrldir_dos,cfg.ctrl_dir); REPLACE_CHARS(ctrldir_dos,'/','\\',p); @@ -1234,28 +1247,52 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) p=lastchar(execdir_dos); if (*p=='\\') *p=0; - SAFECOPY(xtrndir_dos,xtrndir); - REPLACE_CHARS(xtrndir_dos,'/','\\',p); + SAFECOPY(nodedir_dos,cfg.node_dir); + REPLACE_CHARS(nodedir_dos,'/','\\',p); + + p=lastchar(nodedir_dos); + if (*p=='\\') *p=0; - /* check for existence of a dosemu.conf in the door directory. - * It is a good idea to be able to use separate configs for each - * door. */ + /* must have sbbs.ini bbs useDOSemu=1 (or empty), cannot be =0 */ + if (!startup->usedosemu) { + lprintf((mode&EX_OFFLINE) ? LOG_ERR : LOG_WARNING, "DOSEMU disabled, program not run"); + bprintf("Sorry, DOSEMU is not supported on this node.\r\n"); + return -1; + } - sprintf(str,"%sdosemu.conf",startup_dir); - if (!fexist(str)) { + /* must have sbbs.ini bbs DOSemuPath set to valid path */ + SAFECOPY(dosemubinloc,(cmdstr(startup->dosemu_path,nulstr,nulstr,tok))); + if (dosemubinloc[0] == '\0') { + lprintf((mode&EX_OFFLINE) ? LOG_ERR : LOG_WARNING, "DOSEMU invalid DOSEmuPath, program not run"); + bprintf("Sorry, DOSEMU is not supported on this node.\r\n"); + return -1; + } - /* If we can't find it in the door dir, look for a global one - * in the ctrl dir. */ + if (!fexist(dosemubinloc)) { + lprintf((mode&EX_OFFLINE) ? LOG_ERR : LOG_WARNING, "DOSEMU not found: %s", dosemubinloc); + bprintf("Sorry, DOSEMU is not supported on this node.\r\n"); + return -1; + } - sprintf(str,"%sdosemu.conf",cfg.ctrl_dir); + /* check for existence of a dosemu.conf in the door directory. + * It is a good idea to be able to use separate configs for each + * door. + * + * First check startup_dir, then check cfg.ctrl_dir + */ + SAFEPRINTF2(str,"%s%s",startup_dir, dosemu_cnf_fn); + if (!fexist(str)) { + /* If we can't find it in the door dir, look for the configured one */ + SAFECOPY(str,startup->dosemuconf_path); + if (!isabspath(str)) { + SAFEPRINTF2(str,"%s%s", cfg.ctrl_dir, startup->dosemuconf_path); + } if (!fexist(str)) { - - /* If we couldn't find either, try for the system one, then - * error out. */ - SAFECOPY(str,"/etc/dosemu/dosemu.conf"); + /* If we couldn't find either, try for the system one, then + * error out. */ + SAFEPRINTF(str,"/etc/dosemu/%s", dosemu_cnf_fn); if (!fexist(str)) { - - SAFECOPY(str,"/etc/dosemu.conf"); + SAFEPRINTF(str,"/etc/%s", dosemu_cnf_fn); if (!fexist(str)) { errormsg(WHERE,ERR_READ,str,0); return(-1); @@ -1268,144 +1305,134 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) } else SAFECOPY(dosemuconf,str); /* using door-specific conf */ - /* same deal for emusetup.bat. */ - - sprintf(str,"%semusetup.bat",startup_dir); - if (!fexist(str)) { - - /* If we can't find it in the door dir, look for a global one - * in the ctrl dir. */ - - sprintf(str,"%semusetup.bat",cfg.ctrl_dir); - if (!fexist(str)) { - - /* If we couldn't find either, set an error condition. */ - setup_override = -1; - } - else setup_override = 0; /* using global bat */ - } - else setup_override = 1; /* using door-specific bat */ - /* Create the external bat here to be placed in the node dir. */ - - sprintf(str,"%sexternal.bat",cfg.node_dir); - if(!(dosemubat=fopen(str,"w+"))) { + SAFEPRINTF2(str,"%s%s",cfg.node_dir,external_bat_fn); + if(!(dosemubatfp=fopen(str,"w+"))) { errormsg(WHERE,ERR_CREATE,str,0); return(-1); } - fprintf(dosemubat,"@echo off\r\n"); - fprintf(dosemubat,"set DSZLOG=%s\\PROTOCOL.LOG\r\n",nodedrive); - fprintf(dosemubat,"set SBBSNODE=%s\r\n",nodedrive); - fprintf(dosemubat,"set SBBSNNUM=%d\r\n",cfg.node_num); - fprintf(dosemubat,"set SBBSCTRL=%s\r\n",ctrldrive); - fprintf(dosemubat,"set SBBSDATA=%s\r\n",datadrive); - fprintf(dosemubat,"set SBBSEXEC=%s\r\n",execdrive); - fprintf(dosemubat,"set PCBNODE=%d\r\n",cfg.node_num); - fprintf(dosemubat,"set PCBDRIVE=%s\r\n",nodedrive); - fprintf(dosemubat,"set PCBDIR=\\\r\n"); - - // let's do this cleanly like dosemu's default autoexec.bat does -wk42 - /* clear existing redirections on dos side and */ - /* redirect necessary drive letters to unix paths */ - fprintf(dosemubat,"unix -s DOSDRIVE_E\r\n"); - fprintf(dosemubat,"if '%%DOSDRIVE_E%%' == '' goto nodriveE\r\n"); - fprintf(dosemubat,"lredir del %s\r\n",xtrndrive); - fprintf(dosemubat,":nodriveE\r\n"); - fprintf(dosemubat,"lredir %s linux\\fs%s\r\n",xtrndrive,xtrndir_dos); - - fprintf(dosemubat,"unix -s DOSDRIVE_F\r\n"); - fprintf(dosemubat,"if '%%DOSDRIVE_F%%' == '' goto nodriveF\r\n"); - fprintf(dosemubat,"lredir del %s\r\n",ctrldrive); - fprintf(dosemubat,":nodriveF\r\n"); - fprintf(dosemubat,"lredir %s linux\\fs%s\r\n",ctrldrive,ctrldir_dos); - - fprintf(dosemubat,"unix -s DOSDRIVE_G\r\n"); - fprintf(dosemubat,"if '%%DOSDRIVE_G%%' == '' goto nodriveG\r\n"); - fprintf(dosemubat,"lredir del %s\r\n",datadrive); - fprintf(dosemubat,":nodriveG\r\n"); - fprintf(dosemubat,"lredir %s linux\\fs%s\r\n",datadrive,datadir_dos); - - fprintf(dosemubat,"unix -s DOSDRIVE_H\r\n"); - fprintf(dosemubat,"if '%%DOSDRIVE_H%%' == '' goto nodriveH\r\n"); - fprintf(dosemubat,"lredir del %s\r\n",execdrive); - fprintf(dosemubat,":nodriveH\r\n"); - fprintf(dosemubat,"lredir %s linux\\fs%s\r\n",execdrive,execdir_dos); - - /* change to the drive where the parent of the startup_dir is mounted */ - fprintf(dosemubat,"%s\r\n",xtrndrive); - - const char* gamedir = ""; + fprintf(dosemubatfp,"@ECHO OFF\r\n"); + fprintf(dosemubatfp,"SET DSZLOG=%s\\PROTOCOL.LOG\r\n",nodedrive); + fprintf(dosemubatfp,"SET SBBSNODE=%s\r\n",nodedrive); + fprintf(dosemubatfp,"SET SBBSNNUM=%d\r\n",cfg.node_num); + fprintf(dosemubatfp,"SET SBBSCTRL=%s\r\n",ctrldrive); + fprintf(dosemubatfp,"SET SBBSDATA=%s\r\n",datadrive); + fprintf(dosemubatfp,"SET SBBSEXEC=%s\r\n",execdrive); + fprintf(dosemubatfp,"SET PCBNODE=%d\r\n",cfg.node_num); + fprintf(dosemubatfp,"SET PCBDRIVE=%s\r\n",nodedrive); + fprintf(dosemubatfp,"SET PCBDIR=\\\r\n"); + + char gamedir[MAX_PATH+1]; if(startup_dir!=NULL && startup_dir[0]) { SAFECOPY(str, startup_dir); *lastchar(str) = 0; - gamedir = getfname(str); + SAFECOPY(gamedir, getfname(str)); } + if(*gamedir == 0) { lprintf(LOG_ERR, "No startup directory configured for DOS command-line: %s", cmdline); return -1; } - fprintf(dosemubat,"cd %s\r\n", gamedir); - - if (setup_override == 1) - fprintf(dosemubat,"call %s\\%s\\emusetup.bat %s\r\n",xtrndrive,gamedir,cmdline); - else if (setup_override == 0) - fprintf(dosemubat,"call %s\\emusetup.bat\r\n",ctrldrive); - /* if (setup_override == -1) do_nothing */ - - /* Check if it's a bat file, to prepend "call" to the command */ - - SAFECOPY(tok,cmdline); - truncstr(tok," "); - p = getfext(tok); /* check if it's a bat file */ - if (p != NULL && stricmp(p, ".bat") == 0) - fprintf(dosemubat,"call "); /* if so, "call" it */ - - fprintf(dosemubat,"%s\r\n",cmdline); - fprintf(dosemubat,"exitemu\r\n"); + /* external editors use node dir so unset this */ + if (startup_dir == cfg.node_dir) { + *gamedir = '\0'; + } + + fprintf(dosemubatfp,"SET STARTDIR=%s\r\n",gamedir); /* Check the "Stdio Interception" flag from scfg for this door. If it's * enabled, we enable doorway mode. Else, it's vmodem for us, unless * it's a timed event. */ - if (!(mode&(EX_STDIO)) && online!=ON_LOCAL) + if (!(mode&(EX_STDIO)) && online!=ON_LOCAL) { SAFECOPY(virtualconf,"-I\"serial { virtual com 1 }\""); - else + runtype = "FOSSIL"; + } else { virtualconf[0] = '\0'; + runtype = "STDIO"; + } - /* Set the interception bits, since we are always going to want Synchronet - * to intercept dos programs under Unix. - */ + /* now append exec/external.bat (which is editable) to this + generated file */ + SAFEPRINTF2(str,"%s%s",startup_dir,external_bat_fn); - mode |= EX_STDIO; + if ((startup_dir == cfg.node_dir) || !fexist(str)) { + SAFEPRINTF2(str,"%s%s",cfg.exec_dir, external_bat_fn); + if (!fexist(str)) { + errormsg(WHERE,ERR_READ,str,0); + return(-1); + } + } - /* See if we have the dosemu link in the door's dir. If so, use the dosemu - * that it points to as our command to execute. If not, use DOSemuPath. - */ + SAFECOPY(externalbatsrc, str); - sprintf(str,"%sdosemu.bin",startup_dir); - if (!fexist(str)) { - SAFECOPY(dosemubinloc,(cmdstr(startup->dosemu_path,nulstr,nulstr,tok))); + if (!(externalbatfp=fopen(externalbatsrc,"r"))) { + errormsg(WHERE,ERR_OPEN,externalbatsrc,0); + return(-1); + } + + /* append the command line to the batch file */ + SAFECOPY(tok,cmdline); + truncstr(tok," "); + p = getfext(tok); + /* check if it's a bat file */ + if (p != NULL && stricmp(p, ".bat") == 0) { + SAFEPRINTF(cmdlinebatch, "CALL %s", cmdline); + } else { + SAFECOPY(cmdlinebatch, cmdline); } - else { - SAFECOPY(dosemubinloc,str); + + named_string_t externalbat_replacements[] = { + {(char*)"CMDLINE", cmdlinebatch}, + {(char*)"DSZLOG", (char*)nodedrive}, + {(char*)"SBBSNODE", (char*)nodedrive}, + {(char*)"SBBSCTRL", (char*)ctrldrive}, + {(char*)"SBBSDATA", (char*)datadrive}, + {(char*)"SBBSEXEC", (char*)execdrive}, + {(char*)"XTRNDIR", xtrndir_dos}, + {(char*)"CTRLDIR", ctrldir_dos}, + {(char*)"DATADIR", datadir_dos}, + {(char*)"EXECDIR", execdir_dos}, + {(char*)"NODEDIR", nodedir_dos}, + {(char*)"STARTDIR", (char*)gamedir}, + {(char*)"RUNTYPE", (char *)runtype}, + {NULL, NULL} + }; + + named_int_t externalbat_int_replacements[] = { + {(char*)"SBBSNNUM", cfg.node_num }, + }; + + while(!feof(externalbatfp)) { + if (fgets(buf, sizeof(buf), externalbatfp)!=NULL) { + replace_named_values(buf, bufout, sizeof(bufout), "$", externalbat_replacements, + externalbat_int_replacements, FALSE); + fprintf(dosemubatfp,"%s",bufout); + } } + fclose(externalbatfp); + + /* Set the interception bits, since we are always going to want Synchronet + * to intercept dos programs under Unix. + */ + + mode |= EX_STDIO; + /* Attempt to keep dosemu from prompting for a disclaimer. */ sprintf(str, "%s/.dosemu", cfg.ctrl_dir); if (!isdir(str)) { mkdir(str, 0755); } - strcat(str, "/disclaimer"); ftouch(str); /* Set up the command for dosemu to execute with 'unix -e'. */ - - sprintf(str,"%sexternal.bat",nodedrive); + SAFEPRINTF2(externalbat,"%s%s",nodedrive, external_bat_fn); /* need TERM=linux for maintenance programs to work * (dosemu won't start with no controlling terminal) @@ -1421,15 +1448,56 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) log_external[0] = '\0'; } - /* Drum roll. */ + /* + * Get the global emu launch command + */ + /* look for file in startup dir */ + SAFEPRINTF(str,"%sdosemu.ini",startup_dir); + if (!fexist(str)) { + /* look for file in exec dir */ + SAFEPRINTF(str,"%sdosemu.ini",cfg.exec_dir); + if (!fexist(str)) { + errormsg(WHERE,ERR_OPEN,"dosemu.ini", 0); + return(-1); + } + } - safe_snprintf(fullcmdline, sizeof(fullcmdline), - // remove unneeded redirection and fix faulty keystroke command -wk42 - "/usr/bin/env %s HOME=%s QUIET=1 DOSDRIVE_D=%s %s -I\"video { none }\" -I'keystroke \"\\r\"' %s -f%s -E%s -o%sdosemu_boot.log %s", - dosterm,cfg.ctrl_dir,cfg.node_dir,dosemubinloc,virtualconf,dosemuconf,str,cfg.node_dir,log_external); + /* if file found, then open and process it */ + if ((de_launch_inifp=iniOpenFile(str, false))==NULL) { + errormsg(WHERE,ERR_OPEN,str, 0); + return(-1); + } + de_launch_ini = iniReadFile(de_launch_inifp); + iniCloseFile(de_launch_inifp); + SAFECOPY(de_launch_cmd, ""); + iniGetString(de_launch_ini, ROOT_SECTION, "cmd", nulstr, de_launch_cmd); + if (virtualconf[0] == '\0') { + iniGetString(de_launch_ini, "stdio", "cmd", de_launch_cmd, de_launch_cmd); + } + iniFreeStringList(de_launch_ini); - fprintf(dosemubat,"REM For debugging: %s\r\n",fullcmdline); - fclose(dosemubat); + named_string_t de_ini_replacements[] = + { + {(char*)"TERM", dosterm}, + {(char*)"CTRLDIR", cfg.ctrl_dir}, + {(char*)"NODEDIR", cfg.node_dir}, + {(char*)"DOSEMUBIN", dosemubinloc}, + {(char*)"VIRTUALCONF", virtualconf}, + {(char*)"DOSEMUCONF", dosemuconf}, + {(char*)"EXTBAT", externalbat}, + {(char*)"EXTLOG", log_external}, + {(char*)"RUNTYPE", (char *)runtype}, + {NULL, NULL} + }; + named_int_t de_ini_int_replacements[] = { + {(char*)"NNUM", cfg.node_num }, + }; + replace_named_values(de_launch_cmd, fullcmdline, sizeof(fullcmdline), (char*)"$", + de_ini_replacements, de_ini_int_replacements, FALSE); + + /* Drum roll. */ + fprintf(dosemubatfp,"REM For debugging: %s\r\n",fullcmdline); + fclose(dosemubatfp); #else lprintf((mode&EX_OFFLINE) ? LOG_ERR : LOG_WARNING, "DOS programs not supported: %s", cmdline); @@ -1875,7 +1943,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch strncat(cmd,ultoa((ulong)cur_cps*10,str,10), avail); break; case 'F': /* File path */ -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native && strncmp(fpath, cfg.node_dir, strlen(cfg.node_dir)) == 0) { strncat(cmd, DOSEMU_NODE_DIR, avail); strncat(cmd, fpath + strlen(cfg.node_dir), avail); @@ -1885,7 +1953,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch strncat(cmd,QUOTED_STRING(instr[i],fpath,str,sizeof(str)), avail); break; case 'G': /* Temp directory */ -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native) strncat(cmd, DOSEMU_TEMP_DIR, avail); else @@ -1899,7 +1967,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch strncat(cmd,cid, avail); break; case 'J': -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native) strncat(cmd, DOSEMU_DATA_DIR, avail); else @@ -1907,7 +1975,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch strncat(cmd,cfg.data_dir, avail); break; case 'K': -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native) strncat(cmd, DOSEMU_CTRL_DIR, avail); else @@ -1921,7 +1989,7 @@ 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) */ -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native) strncat(cmd, DOSEMU_NODE_DIR, avail); else @@ -1966,7 +2034,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch strncat(cmd,comspec, avail); break; case 'Z': -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native) strncat(cmd, DOSEMU_TEXT_DIR, avail); else @@ -1984,7 +2052,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch #endif break; case '!': /* EXEC Directory */ -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(!native) strncat(cmd, DOSEMU_EXEC_DIR, avail); else diff --git a/src/sbbs3/xtrn_sec.cpp b/src/sbbs3/xtrn_sec.cpp index 9c71e517439c19ce743cfec0eaa787f561cc1076..859e5e2b69626a8178037c95306e634964e2a415 100644 --- a/src/sbbs3/xtrn_sec.cpp +++ b/src/sbbs3/xtrn_sec.cpp @@ -1595,7 +1595,7 @@ bool sbbs_t::exec_xtrn(uint xtrnnum) char drop_file[MAX_PATH + 1]; char startup_dir[MAX_PATH + 1]; -#if defined(__linux__) && defined(USE_DOSEMU) +#if defined(__linux__) if(cfg.xtrn[xtrnnum]->cmd[0] != '?' && cfg.xtrn[xtrnnum]->cmd[0] != '*' && !(cfg.xtrn[xtrnnum]->misc & XTRN_NATIVE)) { SAFEPRINTF2(startup_dir, "%s\\%s", DOSEMU_XTRN_DRIVE, getdirname(cfg.xtrn[xtrnnum]->path)); backslash(startup_dir);