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:
@@ -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:
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user