update and simplify the windows portable_device_paths sysconf option

Requires a sysconf file in the windows executable directory in order to work
This commit is contained in:
nhmall
2019-12-17 23:16:44 -05:00
parent 0ee445ce0b
commit 5f0d06fb80
7 changed files with 70 additions and 131 deletions
+7
View File
@@ -4789,6 +4789,13 @@ to identify unique people for the score file.
MAX_STATUENAME_RANK\ =\ Maximum number of score file entries to use for MAX_STATUENAME_RANK\ =\ Maximum number of score file entries to use for
random statue names (default is 10). random statue names (default is 10).
.lp .lp
ACCESSIBILITY\ =\ 0 or 1 to disable or enable, respectively, the ability for players
to set S_pet_override and S_hero_override symbols in their configuration file.
.lp
PORTABLE_DEVICE_PATHS\ =\ 0 or 1 Windows OS only, the game will look
for all of its external files, and write to all of its output files in one place
rather than at the standard locations.
.lp
DUMPLOGFILE\ =\ A filename where the end-of-game dumplog is saved. DUMPLOGFILE\ =\ A filename where the end-of-game dumplog is saved.
Not defining this will prevent dumplog from being created. Only available Not defining this will prevent dumplog from being created. Only available
if your game is compiled with DUMPLOG. Allows the following placeholders: if your game is compiled with DUMPLOG. Allows the following placeholders:
+10
View File
@@ -5297,6 +5297,16 @@ Minimum number of points to get an entry in the score file.
0 or 1 to use user names or numeric userids, respectively, to identify 0 or 1 to use user names or numeric userids, respectively, to identify
unique people for the score file unique people for the score file
%.lp %.lp
\item[\ib{ACCESSIBILITY}]
0 or 1 to disable or enable, respectively, the ability for players
to set S\verb+_+pet\verb+_+override and S\verb+_+hero\verb+_+override
symbols in their configuration file.
%.lp
\item[\ib{PORTABLE\verb+_+DEVICE\verb+_+PATHS}]
0 or 1 Windows OS only, the game will look for all of its external
files, and write to all of its output files in one place
rather than at the standard locations.
%.lp
\item[\ib{DUMPLOGFILE}] \item[\ib{DUMPLOGFILE}]
A filename where the end-of-game dumplog is saved. A filename where the end-of-game dumplog is saved.
Not defining this will prevent dumplog from being created. Only available Not defining this will prevent dumplog from being created. Only available
+2 -1
View File
@@ -21,7 +21,8 @@ fix potential buffer overflow when parsing run-time configuration file
Platform- and/or Interface-Specific Fixes or Features Platform- and/or Interface-Specific Fixes or Features
----------------------------------------------------- -----------------------------------------------------
fix compilation on platforms that split the ncurses and tinfo libraries fix compilation on platforms that split the ncurses and tinfo libraries
allow run-from-removable-device on Windows Windows: allow all game files to be on a portable device via the sysconf
option 'portable_device_paths'
General New Features General New Features
+3 -3
View File
@@ -17,9 +17,6 @@ struct sysopt {
char *debugfiles; /* files to show debugplines in. '*' is all. */ char *debugfiles; /* files to show debugplines in. '*' is all. */
#ifdef DUMPLOG #ifdef DUMPLOG
char *dumplogfile; /* where the dump file is saved */ char *dumplogfile; /* where the dump file is saved */
#endif
#ifdef WIN32
char *portable_device_top; /* nethack configuration for a portable drive */
#endif #endif
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES") int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
* so sysconf's DEBUGFILES shouldn't override it; * so sysconf's DEBUGFILES shouldn't override it;
@@ -47,6 +44,9 @@ struct sysopt {
/* enable accessibility options */ /* enable accessibility options */
int accessibility; int accessibility;
#ifdef WIN32
int portable_device_paths; /* nethack configuration for a portable device */
#endif
}; };
extern struct sysopt sysopt; extern struct sysopt sysopt;
+12 -9
View File
@@ -2466,12 +2466,6 @@ char *origbuf;
if (sysopt.dumplogfile) if (sysopt.dumplogfile)
free((genericptr_t) sysopt.dumplogfile); free((genericptr_t) sysopt.dumplogfile);
sysopt.dumplogfile = dupstr(bufp); sysopt.dumplogfile = dupstr(bufp);
#endif
#ifdef WIN32
} else if (src == SET_IN_SYS && match_varname(buf, "portable_device_top", 8)) {
if (sysopt.portable_device_top)
free((genericptr_t) sysopt.portable_device_top);
sysopt.portable_device_top = dupstr(bufp);
#endif #endif
} else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) { } else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) {
if (sysopt.genericusers) if (sysopt.genericusers)
@@ -2605,6 +2599,16 @@ char *origbuf;
return FALSE; return FALSE;
} }
sysopt.accessibility = n; sysopt.accessibility = n;
#ifdef WIN32
} else if (src == SET_IN_SYS
&& match_varname(buf, "portable_device_paths", 8)) {
n = atoi(bufp);
if (n < 0 || n > 1) {
config_error_add("Illegal value in portable_device_paths (not 0,1).");
return FALSE;
}
sysopt.portable_device_paths = n;
#endif
#endif /* SYSCF */ #endif /* SYSCF */
} else if (match_varname(buf, "BOULDER", 3)) { } else if (match_varname(buf, "BOULDER", 3)) {
@@ -4160,11 +4164,10 @@ reveal_paths(VOID_ARGS)
raw_printf("No end-of-game disclosure file (%s).", nodumpreason); raw_printf("No end-of-game disclosure file (%s).", nodumpreason);
#ifdef WIN32 #ifdef WIN32
if (sysopt.portable_device_top) { if (sysopt.portable_device_paths) {
const char *pd = get_portable_device(); const char *pd = get_portable_device();
raw_printf("Writable folder for portable device config (sysconf %s):", raw_printf("portable_device_paths (set in sysconf):");
"portable_device_top");
raw_printf(" \"%s\"", pd); raw_printf(" \"%s\"", pd);
} }
#endif #endif
+3 -9
View File
@@ -34,9 +34,6 @@ sys_early_init()
#endif #endif
#ifdef DUMPLOG #ifdef DUMPLOG
sysopt.dumplogfile = (char *) 0; sysopt.dumplogfile = (char *) 0;
#endif
#ifdef WIN32
sysopt.portable_device_top = (char *) 0;
#endif #endif
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */ sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
sysopt.shellers = (char *) 0; sysopt.shellers = (char *) 0;
@@ -84,6 +81,9 @@ sys_early_init()
sysopt.seduce = 1; /* if it's compiled in, default to on */ sysopt.seduce = 1; /* if it's compiled in, default to on */
sysopt_seduce_set(sysopt.seduce); sysopt_seduce_set(sysopt.seduce);
sysopt.accessibility = 0; sysopt.accessibility = 0;
#ifdef WIN32
sysopt.portable_device_paths = 0;
#endif
return; return;
} }
@@ -106,12 +106,6 @@ sysopt_release()
#ifdef DUMPLOG #ifdef DUMPLOG
if (sysopt.dumplogfile) if (sysopt.dumplogfile)
free((genericptr_t)sysopt.dumplogfile), sysopt.dumplogfile=(char *)0; free((genericptr_t)sysopt.dumplogfile), sysopt.dumplogfile=(char *)0;
#endif
#ifdef WIN32
if (sysopt.portable_device_top) {
free((genericptr_t) sysopt.portable_device_top);
sysopt.portable_device_top = (char *) 0;
}
#endif #endif
if (sysopt.genericusers) if (sysopt.genericusers)
free((genericptr_t) sysopt.genericusers), free((genericptr_t) sysopt.genericusers),
+33 -109
View File
@@ -168,25 +168,16 @@ folder_file_exists(const char * folder, const char * file_name)
boolean boolean
test_portable_config( test_portable_config(
const char *executable_path, const char *executable_path,
char *portable_device_top_path, char *portable_device_path,
size_t portable_device_top_path_size) size_t portable_device_path_size)
{ {
int lth = 0;
const char *sysconf = "sysconf";
char tmppath[MAX_PATH];
boolean retval = FALSE, boolean retval = FALSE,
save_initoptions_noterminate = iflags.initoptions_noterminate; save_initoptions_noterminate = iflags.initoptions_noterminate;
char tmppath[MAX_PATH], *toppath, *sysconftop;
#ifdef UNICODE
TCHAR wdrive[_MAX_DRIVE];
TCHAR wthisdir[_MAX_DIR];
TCHAR wfname[_MAX_FNAME];
TCHAR wext[_MAX_EXT];
#endif
char drive[_MAX_DRIVE];
char thisdir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
errno_t err;
if (portable_device_top_path && folder_file_exists(executable_path, "sysconf")) { if (portable_device_path && folder_file_exists(executable_path, "sysconf")) {
/* /*
There is a sysconf file (not just sysconf.template) present in There is a sysconf file (not just sysconf.template) present in
the exe path, which is not the way NetHack is initially distributed, the exe path, which is not the way NetHack is initially distributed,
@@ -196,101 +187,38 @@ test_portable_config(
delve into that... delve into that...
*/ */
*portable_device_top_path = '\0'; *portable_device_path = '\0';
(void) strncpy(tmppath, executable_path, sizeof tmppath - (1 + sizeof "sysconf")); lth = sizeof tmppath - strlen(sysconf);
tmppath[sizeof tmppath - (1 + sizeof "sysconf")] = '\0'; (void) strncpy(tmppath, executable_path, lth - 1);
(void) strcat(tmppath, "sysconf"); tmppath[lth - 1] = '\0';
/* split the path up */ (void) strcat(tmppath, sysconf);
#ifdef UNICODE
{
int sz, wchars_num = MultiByteToWideChar( CP_ACP, 0, tmppath, -1, NULL, 0);
wchar_t *wstr;
if (wchars_num) {
wstr = (wchar_t *) alloc(wchars_num * sizeof(wchar_t));
MultiByteToWideChar( CP_ACP, 0, tmppath, -1, wstr, wchars_num);
err = _wsplitpath_s(wstr, wdrive, _MAX_DRIVE, wthisdir, _MAX_DIR,
wfname, _MAX_FNAME, wext, _MAX_EXT);
free(wstr);
}
sz = WideCharToMultiByte(CP_ACP, 0, wdrive, -1, drive,
0, NULL, NULL);
if (sz <= sizeof drive)
WideCharToMultiByte(CP_ACP, 0, wdrive, -1, drive,
sz, NULL, NULL);
}
#else
err = _splitpath_s(tmppath, drive, _MAX_DRIVE, thisdir, _MAX_DIR,
fname, _MAX_FNAME, ext, _MAX_EXT);
#endif
if (err != 0)
goto done_test;
toppath = (char *) alloc(portable_device_top_path_size);
*toppath = '\0';
/* -2 because we need to append the path separator */
(void) strncpy(toppath, drive, portable_device_top_path_size - 2);
toppath[portable_device_top_path_size - 2] = '\0';
(void) strcat(toppath, "\\");
iflags.initoptions_noterminate = 1; iflags.initoptions_noterminate = 1;
/* assure_syscf_file(); */ /* assure_syscf_file(); */
config_error_init(TRUE, tmppath, FALSE); config_error_init(TRUE, tmppath, FALSE);
/* ... and _must_ parse correctly. */ /* ... and _must_ parse correctly. */
if (read_config_file(tmppath, SET_IN_SYS) if (read_config_file(tmppath, SET_IN_SYS)
&& sysopt.portable_device_top && sysopt.portable_device_paths)
&& (strlen(sysopt.portable_device_top) + strlen(toppath)
< portable_device_top_path_size - 3)) {
sysconftop = sysopt.portable_device_top;
if (sysconftop[1] == ':')
sysconftop += 2; /* skip the device if specified */
if (*sysconftop == '\\')
sysconftop += 1; /* skip the root folder if specified */
(void) strcat(toppath, sysconftop);
append_slash(toppath);
retval = TRUE; retval = TRUE;
} else { (void) config_error_done();
if (config_error_done())
retval = FALSE;
}
iflags.initoptions_noterminate = save_initoptions_noterminate; iflags.initoptions_noterminate = save_initoptions_noterminate;
sysopt_release(); sysopt_release(); /* the real sysconf processing comes later */
if (retval) }
Strcpy(portable_device_top_path, toppath); if (retval) {
free(toppath); lth = strlen(executable_path);
if (lth <= (int) portable_device_path_size - 1)
Strcpy(portable_device_path, executable_path);
else
retval = FALSE;
} }
done_test:
return retval; return retval;
} }
static char portable_device_top_path[MAX_PATH]; static char portable_device_path[MAX_PATH];
const char *get_portable_device() const char *get_portable_device()
{ {
return (const char *) portable_device_top_path; return (const char *) portable_device_path;
}
boolean illegal_dir(const char *d1, const char *d2)
{
int i;
char tmpbuf[MAX_PATH];
if (!strcmpi(d1, d2)) {
(void) strncpy(tmpbuf, &portable_device_top_path[3],
sizeof tmpbuf - 1);
tmpbuf[sizeof tmpbuf - 1] = '\0';
i = (int) strlen(tmpbuf) - 1;
if (tmpbuf[i] == '\\')
tmpbuf[i] = '\0';
raw_printf("Illegal \"portable_device_top = %s\" in your sysconf file",
tmpbuf);
raw_printf("because the exe is running from that folder.");
raw_printf("Point 'portable_device_top' to a different folder.");
return TRUE;
}
return FALSE;
} }
void void
@@ -309,21 +237,17 @@ set_default_prefix_locations(const char *programPath)
strcpy(executable_path, get_executable_path()); strcpy(executable_path, get_executable_path());
append_slash(executable_path); append_slash(executable_path);
if (test_portable_config(executable_path, portable_device_top_path, if (test_portable_config(executable_path,
sizeof portable_device_top_path)) { portable_device_path, sizeof portable_device_path)) {
#if 0
if (illegal_dir(portable_device_top_path, executable_path))
windows_startup_state = 2;
#endif
fqn_prefix[SYSCONFPREFIX] = executable_path; fqn_prefix[SYSCONFPREFIX] = executable_path;
fqn_prefix[CONFIGPREFIX] = portable_device_top_path; fqn_prefix[CONFIGPREFIX] = portable_device_path;
fqn_prefix[HACKPREFIX] = portable_device_top_path; fqn_prefix[HACKPREFIX] = portable_device_path;
fqn_prefix[SAVEPREFIX] = portable_device_top_path; fqn_prefix[SAVEPREFIX] = portable_device_path;
fqn_prefix[LEVELPREFIX] = portable_device_top_path; fqn_prefix[LEVELPREFIX] = portable_device_path;
fqn_prefix[BONESPREFIX] = portable_device_top_path; fqn_prefix[BONESPREFIX] = portable_device_path;
fqn_prefix[SCOREPREFIX] = portable_device_top_path; fqn_prefix[SCOREPREFIX] = portable_device_path;
fqn_prefix[LOCKPREFIX] = portable_device_top_path; fqn_prefix[LOCKPREFIX] = portable_device_path;
fqn_prefix[TROUBLEPREFIX] = portable_device_top_path; fqn_prefix[TROUBLEPREFIX] = portable_device_path;
fqn_prefix[DATAPREFIX] = executable_path; fqn_prefix[DATAPREFIX] = executable_path;
} else { } else {
build_known_folder_path(&FOLDERID_Profile, profile_path, build_known_folder_path(&FOLDERID_Profile, profile_path,