From: nhmall Date: Wed, 18 Dec 2019 04:16:44 +0000 (-0500) Subject: update and simplify the windows portable_device_paths sysconf option X-Git-Tag: NetHack-3.6.4_Released~5 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f0d06fb80ac4945a863b11ff06a2481b2254af0;p=nethack update and simplify the windows portable_device_paths sysconf option Requires a sysconf file in the windows executable directory in order to work --- diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 8d753d9f8..7466911c4 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -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: diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 36d459db0..8c6214a57 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -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 diff --git a/doc/fixes36.4 b/doc/fixes36.4 index 441dd7770..529cbfeca 100644 --- a/doc/fixes36.4 +++ b/doc/fixes36.4 @@ -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 diff --git a/include/sys.h b/include/sys.h index 392987660..ed2f57859 100644 --- a/include/sys.h +++ b/include/sys.h @@ -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; diff --git a/src/files.c b/src/files.c index a25a038e6..44413f230 100644 --- a/src/files.c +++ b/src/files.c @@ -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 diff --git a/src/sys.c b/src/sys.c index f8c0a91c5..6a0c52da8 100644 --- a/src/sys.c +++ b/src/sys.c @@ -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), diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index 29c12ffbc..4ca0c6bfc 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -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,