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

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
random statue names (default is 10).
.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.
Not defining this will prevent dumplog from being created. Only available
if your game is compiled with DUMPLOG. Allows the following placeholders:

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
unique people for the score file
%.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}]
A filename where the end-of-game dumplog is saved.
Not defining this will prevent dumplog from being created. Only available

View File

@@ -21,7 +21,8 @@ fix potential buffer overflow when parsing run-time configuration file
Platform- and/or Interface-Specific Fixes or Features
-----------------------------------------------------
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

View File

@@ -17,9 +17,6 @@ struct sysopt {
char *debugfiles; /* files to show debugplines in. '*' is all. */
#ifdef DUMPLOG
char *dumplogfile; /* where the dump file is saved */
#endif
#ifdef WIN32
char *portable_device_top; /* nethack configuration for a portable drive */
#endif
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
* so sysconf's DEBUGFILES shouldn't override it;
@@ -47,6 +44,9 @@ struct sysopt {
/* enable accessibility options */
int accessibility;
#ifdef WIN32
int portable_device_paths; /* nethack configuration for a portable device */
#endif
};
extern struct sysopt sysopt;

View File

@@ -2466,12 +2466,6 @@ char *origbuf;
if (sysopt.dumplogfile)
free((genericptr_t) sysopt.dumplogfile);
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
} else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) {
if (sysopt.genericusers)
@@ -2605,6 +2599,16 @@ char *origbuf;
return FALSE;
}
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 */
} 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);
#ifdef WIN32
if (sysopt.portable_device_top) {
if (sysopt.portable_device_paths) {
const char *pd = get_portable_device();
raw_printf("Writable folder for portable device config (sysconf %s):",
"portable_device_top");
raw_printf("portable_device_paths (set in sysconf):");
raw_printf(" \"%s\"", pd);
}
#endif

View File

@@ -34,9 +34,6 @@ sys_early_init()
#endif
#ifdef DUMPLOG
sysopt.dumplogfile = (char *) 0;
#endif
#ifdef WIN32
sysopt.portable_device_top = (char *) 0;
#endif
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
sysopt.shellers = (char *) 0;
@@ -84,6 +81,9 @@ sys_early_init()
sysopt.seduce = 1; /* if it's compiled in, default to on */
sysopt_seduce_set(sysopt.seduce);
sysopt.accessibility = 0;
#ifdef WIN32
sysopt.portable_device_paths = 0;
#endif
return;
}
@@ -106,12 +106,6 @@ sysopt_release()
#ifdef DUMPLOG
if (sysopt.dumplogfile)
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
if (sysopt.genericusers)
free((genericptr_t) sysopt.genericusers),

View File

@@ -168,25 +168,16 @@ folder_file_exists(const char * folder, const char * file_name)
boolean
test_portable_config(
const char *executable_path,
char *portable_device_top_path,
size_t portable_device_top_path_size)
char *portable_device_path,
size_t portable_device_path_size)
{
int lth = 0;
const char *sysconf = "sysconf";
char tmppath[MAX_PATH];
boolean retval = FALSE,
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
the exe path, which is not the way NetHack is initially distributed,
@@ -196,101 +187,38 @@ test_portable_config(
delve into that...
*/
*portable_device_top_path = '\0';
(void) strncpy(tmppath, executable_path, sizeof tmppath - (1 + sizeof "sysconf"));
tmppath[sizeof tmppath - (1 + sizeof "sysconf")] = '\0';
(void) strcat(tmppath, "sysconf");
/* split the path up */
#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, "\\");
*portable_device_path = '\0';
lth = sizeof tmppath - strlen(sysconf);
(void) strncpy(tmppath, executable_path, lth - 1);
tmppath[lth - 1] = '\0';
(void) strcat(tmppath, sysconf);
iflags.initoptions_noterminate = 1;
/* assure_syscf_file(); */
config_error_init(TRUE, tmppath, FALSE);
/* ... and _must_ parse correctly. */
if (read_config_file(tmppath, SET_IN_SYS)
&& sysopt.portable_device_top
&& (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);
&& sysopt.portable_device_paths)
retval = TRUE;
} else {
if (config_error_done())
retval = FALSE;
}
(void) config_error_done();
iflags.initoptions_noterminate = save_initoptions_noterminate;
sysopt_release();
if (retval)
Strcpy(portable_device_top_path, toppath);
free(toppath);
sysopt_release(); /* the real sysconf processing comes later */
}
if (retval) {
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;
}
static char portable_device_top_path[MAX_PATH];
static char portable_device_path[MAX_PATH];
const char *get_portable_device()
{
return (const char *) portable_device_top_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;
return (const char *) portable_device_path;
}
void
@@ -309,21 +237,17 @@ set_default_prefix_locations(const char *programPath)
strcpy(executable_path, get_executable_path());
append_slash(executable_path);
if (test_portable_config(executable_path, portable_device_top_path,
sizeof portable_device_top_path)) {
#if 0
if (illegal_dir(portable_device_top_path, executable_path))
windows_startup_state = 2;
#endif
if (test_portable_config(executable_path,
portable_device_path, sizeof portable_device_path)) {
fqn_prefix[SYSCONFPREFIX] = executable_path;
fqn_prefix[CONFIGPREFIX] = portable_device_top_path;
fqn_prefix[HACKPREFIX] = portable_device_top_path;
fqn_prefix[SAVEPREFIX] = portable_device_top_path;
fqn_prefix[LEVELPREFIX] = portable_device_top_path;
fqn_prefix[BONESPREFIX] = portable_device_top_path;
fqn_prefix[SCOREPREFIX] = portable_device_top_path;
fqn_prefix[LOCKPREFIX] = portable_device_top_path;
fqn_prefix[TROUBLEPREFIX] = portable_device_top_path;
fqn_prefix[CONFIGPREFIX] = portable_device_path;
fqn_prefix[HACKPREFIX] = portable_device_path;
fqn_prefix[SAVEPREFIX] = portable_device_path;
fqn_prefix[LEVELPREFIX] = portable_device_path;
fqn_prefix[BONESPREFIX] = portable_device_path;
fqn_prefix[SCOREPREFIX] = portable_device_path;
fqn_prefix[LOCKPREFIX] = portable_device_path;
fqn_prefix[TROUBLEPREFIX] = portable_device_path;
fqn_prefix[DATAPREFIX] = executable_path;
} else {
build_known_folder_path(&FOLDERID_Profile, profile_path,