From f0707fee6ed9a11626436657059ca45f86ca8858 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 3 Nov 2019 13:31:17 -0800 Subject: [PATCH 1/9] More tweaks to how windows deals with directory paths. --- include/decl.h | 1 + src/decl.c | 4 ++ src/files.c | 7 ++- sys/winnt/windmain.c | 115 ++++++++++++++++++++++--------------------- 4 files changed, 69 insertions(+), 58 deletions(-) diff --git a/include/decl.h b/include/decl.h index 974af0f10..1aa115983 100644 --- a/include/decl.h +++ b/include/decl.h @@ -398,6 +398,7 @@ E const char *const monexplain[], invisexplain[], *const oclass_names[]; #endif E char *fqn_prefix[PREFIX_COUNT]; +E boolean fqn_prefix_locked[PREFIX_COUNT]; #ifdef PREFIXES_IN_USE E char *fqn_prefix_names[PREFIX_COUNT]; #endif diff --git a/src/decl.c b/src/decl.c index a42cad2a0..d732df35c 100644 --- a/src/decl.c +++ b/src/decl.c @@ -286,6 +286,10 @@ char *fqn_prefix[PREFIX_COUNT] = { (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0 }; +boolean fqn_prefix_locked[PREFIX_COUNT] = { FALSE, FALSE, FALSE, + FALSE, FALSE, FALSE, + FALSE, FALSE, FALSE, + FALSE }; #ifdef PREFIXES_IN_USE char *fqn_prefix_names[PREFIX_COUNT] = { diff --git a/src/files.c b/src/files.c index f89e5e061..d6f1cf5da 100644 --- a/src/files.c +++ b/src/files.c @@ -2158,6 +2158,8 @@ int prefixid; if (!bufp) return; + if (fqn_prefix_locked[prefixid]) + return; /* Backward compatibility, ignore trailing ;n */ if ((ptr = index(bufp, ';')) != 0) *ptr = '\0'; @@ -3196,7 +3198,7 @@ fopen_sym_file() { FILE *fp; - fp = fopen_datafile(SYMBOLS, "r", HACKPREFIX); + fp = fopen_datafile(SYMBOLS, "r", CONFIGPREFIX); return fp; } @@ -3861,6 +3863,9 @@ assure_syscf_file() { int fd; + /* We are checking that the sysconf exists ... lock the path */ + fqn_prefix_locked[SYSCONFPREFIX] = TRUE; + /* * All we really care about is the end result - can we read the file? * So just check that directly. diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index 4574e9d1a..c14e3e7af 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -97,13 +97,16 @@ void build_known_folder_path( const KNOWNFOLDERID * folder_id, char * path, - size_t path_size) + size_t path_size, + boolean versioned) { get_known_folder_path(folder_id, path, path_size); strcat(path, "\\NetHack\\"); create_directory(path); - strcat(path, "3.6\\"); - create_directory(path); + if (versioned) { + strcat(path, "3.6\\"); + create_directory(path); + } } void @@ -190,51 +193,37 @@ set_default_prefix_locations(const char *programPath) char *envp = NULL; char *sptr = NULL; - static char hack_path[MAX_PATH]; static char executable_path[MAX_PATH]; - static char nethack_profile_path[MAX_PATH]; - static char nethack_per_user_data_path[MAX_PATH]; - static char nethack_global_data_path[MAX_PATH]; - static char sysconf_path[MAX_PATH]; + static char profile_path[MAX_PATH]; + static char versioned_profile_path[MAX_PATH]; + static char versioned_user_data_path[MAX_PATH]; + static char versioned_global_data_path[MAX_PATH]; strcpy(executable_path, get_executable_path()); append_slash(executable_path); - build_environment_path("NETHACKDIR", NULL, hack_path, sizeof(hack_path)); + build_known_folder_path(&FOLDERID_Profile, profile_path, + sizeof(profile_path), FALSE); - if (hack_path[0] == '\0') - build_environment_path("HACKDIR", NULL, hack_path, sizeof(hack_path)); - - build_known_folder_path(&FOLDERID_Profile, nethack_profile_path, - sizeof(nethack_profile_path)); + build_known_folder_path(&FOLDERID_Profile, versioned_profile_path, + sizeof(profile_path), TRUE); build_known_folder_path(&FOLDERID_LocalAppData, - nethack_per_user_data_path, sizeof(nethack_per_user_data_path)); + versioned_user_data_path, sizeof(versioned_user_data_path), TRUE); build_known_folder_path(&FOLDERID_ProgramData, - nethack_global_data_path, sizeof(nethack_global_data_path)); + versioned_global_data_path, sizeof(versioned_global_data_path), TRUE); - if (hack_path[0] == '\0') - strcpy(hack_path, nethack_profile_path); - - fqn_prefix[LEVELPREFIX] = nethack_per_user_data_path; - fqn_prefix[SAVEPREFIX] = nethack_per_user_data_path; - fqn_prefix[BONESPREFIX] = nethack_global_data_path; + fqn_prefix[LEVELPREFIX] = versioned_user_data_path; + fqn_prefix[SAVEPREFIX] = versioned_user_data_path; + fqn_prefix[BONESPREFIX] = versioned_global_data_path; fqn_prefix[DATAPREFIX] = executable_path; - fqn_prefix[SCOREPREFIX] = nethack_global_data_path; - fqn_prefix[LOCKPREFIX] = nethack_global_data_path; - fqn_prefix[CONFIGPREFIX] = nethack_profile_path; - - fqn_prefix[HACKPREFIX] = hack_path; - fqn_prefix[TROUBLEPREFIX] = hack_path; - - build_environment_path("COMMONPROGRAMFILES", "NetHack\\3.6", sysconf_path, - sizeof(sysconf_path)); - - if(!folder_file_exists(sysconf_path, SYSCF_FILE)) - strcpy(sysconf_path, hack_path); - - fqn_prefix[SYSCONFPREFIX] = sysconf_path; + fqn_prefix[SCOREPREFIX] = versioned_global_data_path; + fqn_prefix[LOCKPREFIX] = versioned_global_data_path; + fqn_prefix[CONFIGPREFIX] = profile_path; + fqn_prefix[HACKPREFIX] = versioned_profile_path; + fqn_prefix[TROUBLEPREFIX] = versioned_profile_path; + fqn_prefix[SYSCONFPREFIX] = versioned_global_data_path; } @@ -300,43 +289,51 @@ update_file( } -void copy_config_content() +void copy_sysconf_content() { - /* Keep templates up to date */ - /* TODO: Update the package to store config file as .nethackrc */ - update_file(fqn_prefix[CONFIGPREFIX], CONFIG_TEMPLATE, - fqn_prefix[DATAPREFIX], CONFIG_TEMPLATE, FALSE); + /* Using the SYSCONFPREFIX path, lock it so that it does not change */ + fqn_prefix_locked[SYSCONFPREFIX] = TRUE; + update_file(fqn_prefix[SYSCONFPREFIX], SYSCF_TEMPLATE, fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + /* If the required early game file does not exist, copy it */ + copy_file(fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, + fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE); +} + +void copy_config_content() +{ + /* Using the CONFIGPREFIX path, lock it so that it does not change */ + fqn_prefix_locked[CONFIGPREFIX] = TRUE; + + /* Keep templates up to date */ + update_file(fqn_prefix[CONFIGPREFIX], CONFIG_TEMPLATE, + fqn_prefix[DATAPREFIX], CONFIG_TEMPLATE, FALSE); + + update_file(fqn_prefix[CONFIGPREFIX], SYMBOLS_TEMPLATE, + fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, FALSE); + /* If the required early game file does not exist, copy it */ /* NOTE: We never replace .nethackrc or sysconf */ copy_file(fqn_prefix[CONFIGPREFIX], CONFIG_FILE, fqn_prefix[DATAPREFIX], CONFIG_TEMPLATE); - copy_file(fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, - fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE); - /* Update symbols and save a copy if we are replacing */ - /* TODO: Can't HACKDIR be changed during option parsing - causing us to perhaps be checking options against the wrong - symbols file? */ - update_file(fqn_prefix[HACKPREFIX], SYMBOLS, + update_file(fqn_prefix[CONFIGPREFIX], SYMBOLS, fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, TRUE); + } void copy_hack_content() { + nhassert(fqn_prefix_locked[HACKPREFIX]); + /* Keep Guidebook and opthelp up to date */ update_file(fqn_prefix[HACKPREFIX], GUIDEBOOK_FILE, fqn_prefix[DATAPREFIX], GUIDEBOOK_FILE, FALSE); update_file(fqn_prefix[HACKPREFIX], OPTIONFILE, fqn_prefix[DATAPREFIX], OPTIONFILE, FALSE); - - /* Keep templates up to date */ - update_file(fqn_prefix[HACKPREFIX], SYMBOLS_TEMPLATE, - fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, FALSE); - } /* @@ -407,22 +404,26 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ chdir(fqn_prefix[HACKPREFIX]); #endif - copy_config_content(); - if (GUILaunched || IsDebuggerPresent()) getreturn_enabled = TRUE; check_recordfile((char *) 0); iflags.windowtype_deferred = TRUE; + copy_sysconf_content(); initoptions(); + copy_config_content(); + process_options(argc, argv); + + /* Finished processing options, lock all directory paths */ + for(int i = 0; i < PREFIX_COUNT; i++) + fqn_prefix_locked[i] = TRUE; + if (!validate_prefix_locations(failbuf)) { raw_printf("Some invalid directory locations were specified:\n\t%s\n", failbuf); nethack_exit(EXIT_FAILURE); } - process_options(argc, argv); - copy_hack_content(); /* From da8525978240be8bcf10de2162d12d08579fd5d8 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 3 Nov 2019 14:06:49 -0800 Subject: [PATCH 2/9] Fixes to template files . --- sys/winnt/.nethackrc.template | 30 +++++++++++------------- sys/winnt/sysconf.template | 43 ++++++++++++++++------------------- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/sys/winnt/.nethackrc.template b/sys/winnt/.nethackrc.template index 39b7924cf..6bec6e108 100644 --- a/sys/winnt/.nethackrc.template +++ b/sys/winnt/.nethackrc.template @@ -142,28 +142,24 @@ OPTIONS=vary_msgcount:4 # IMPORTANT: If you change any of these locations, the directories they # point at must exist. NetHack will not create them for you. # -# HACKDIR is the default location for everything. -# Note: On Windows HACKDIR defaults to the location -# of the NetHack.exe or NetHackw.exe file so -# setting HACKDIR below to override that is -# not usually necessary or recommended. -#HACKDIR=c:\games\nethack +# The location that documentation and helps files are placed +#HACKDIR=c:\User\USERNAME\NetHack\3.6 # -# The location that level files in progress are stored (default=HACKDIR, writeable) -#LEVELDIR=c:\nethack\levels +# The location that level files in progress are stored (writeable) +#LEVELDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 # -# The location where saved games are kept (default=HACKDIR, writeable) -#SAVEDIR=c:\nethack\save +# The location where saved games are kept (writeable) +#SAVEDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 # -# The location that bones files are kept (default=HACKDIR, writeable) -#BONESDIR=c:\nethack\save +# The location that bones files are kept (writeable) +#BONESDIR=c:\ProgramData\NetHack\3.6 # -# The location that file synchronization locks are stored (default=HACKDIR, writeable) -#LOCKDIR=c:\nethack\levels +# The location that score files are kept (writeable) +#SCOREDIR=c:\ProgramData\NetHack\3.6 +# +# The location that file synchronization locks are stored (writeable) +#LOCKDIR=c:\ProgramData\NetHack\3.6 # -# The location that a record of game aborts and self-diagnosed game problems -# is kept (default=HACKDIR, writeable) -#TROUBLEDIR=c:\nethack\trouble # Finnish keyboards might need these modifications uncommented. # For \, @, $, [, | diff --git a/sys/winnt/sysconf.template b/sys/winnt/sysconf.template index 93aaa1ddc..058b29122 100644 --- a/sys/winnt/sysconf.template +++ b/sys/winnt/sysconf.template @@ -77,30 +77,27 @@ WIZARDS=* # IMPORTANT: If you change any of these locations, the directories they # point at must exist. NetHack will not create them for you. # -# HACKDIR is the default location for everything. -# Note: On Windows HACKDIR defaults to the location -# of the NetHack.exe or NetHackw.exe file so -# setting HACKDIR below to override that is -# not usually necessary or recommended. -#HACKDIR=c:\games\nethack -# # The location that users can adjust their config file startup options -#CONFIGDIR=c:\games\nethack -# -# The location that level files in progress are stored (default=HACKDIR, writeable) -#LEVELDIR=c:\nethack\levels -# -# The location where saved games are kept (default=HACKDIR, writeable) -#SAVEDIR=c:\nethack\save -# -# The location that bones files are kept (default=HACKDIR, writeable) -#BONESDIR=c:\nethack\save -# -# The location that file synchronization locks are stored (default=HACKDIR, writeable) -#LOCKDIR=c:\nethack\levels +#CONFIGDIR=c:\User\USERNAME\NetHack # # The location that a record of game aborts and self-diagnosed game problems # is kept (default=HACKDIR, writeable) -#TROUBLEDIR=c:\nethack\trouble - - +#TROUBLEDIR=c:\User\USERNAME\NetHack\3.6 +# +# The location that documentation and helps files are placed +#HACKDIR=c:\User\USERNAME\NetHack\3.6 +# +# The location that level files in progress are stored (writeable) +#LEVELDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 +# +# The location where saved games are kept (writeable) +#SAVEDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 +# +# The location that bones files are kept (writeable) +#BONESDIR=c:\ProgramData\NetHack\3.6 +# +# The location that score files are kept (writeable) +#SCOREDIR=c:\ProgramData\NetHack\3.6 +# +# The location that file synchronization locks are stored (writeable) +#LOCKDIR=c:\ProgramData\NetHack\3.6 From 7c5a2adfa54cb3e42d4f58c5a08ea54063cb84c7 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 3 Nov 2019 14:07:11 -0800 Subject: [PATCH 3/9] Lock TROUBLEPREFIX after parsing sysconf. --- sys/winnt/windmain.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index c14e3e7af..d226b26f1 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -410,7 +410,12 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ check_recordfile((char *) 0); iflags.windowtype_deferred = TRUE; copy_sysconf_content(); - initoptions(); + initoptions(); + + /* Now that sysconf has had a chance to set the TROUBLEPREFIX, don't + allow it to be changed from here on out. */ + fqn_prefix_locked[TROUBLEPREFIX] = TRUE; + copy_config_content(); process_options(argc, argv); From d4ff00cd4012dbb7e53afb6acdb3da95ba51aa12 Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 4 Nov 2019 19:34:03 -0800 Subject: [PATCH 4/9] Updated windows directory paths to latest iteration of design. --- sys/winnt/windmain.c | 65 +++++++++----------------------------------- 1 file changed, 13 insertions(+), 52 deletions(-) diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index d226b26f1..16f62267a 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -149,44 +149,6 @@ folder_file_exists(const char * folder, const char * file_name) return file_exists(path); } -/* - * Rules for setting prefix locations - * - * COMMON_NETHACK_PATH = %COMMONPROGRAMFILES%\NetHack\3.6\ - * PROFILE_PATH = %SystemDrive%\Users\%USERNAME%\ - * - * NETHACK_PROFILE_PATH = PROFILE_PATH\NetHack\3.6\ - * NETHACK_PER_USER_DATA_PATH = PROFILE_PATH\AppData\Local\NetHack\3.6\ - * NETHACK_GLOBAL_DATA_PATH = %SystemDrive%\ProgramData\NetHack\3.6\ - * EXECUTABLE_PATH = path to where .exe lives - * - * HACKPREFIX: - * - use environment variable NETHACKDIR if variable is defined - * - otherwise use environment variable HACKDIR if variable is defined - * - otherwise if store install use NETHACK_PROFILE_PATH - * - otherwise if manual install use EXECUTABLE_PATH - * - * LEVELPREFIX, SAVEPREFIX: - * - if store install use NETHACK_PER_USER_DATA_PATH - * - if manual install use HACKPREFIX - * - * BONESPREFIX, SCOREPREFIX, LOCKPREFIX: - * - if store install use NETHACK_GLOBAL_DATA_PATH - * - if manual install use HACKPREFIX - * - * DATAPREFIX - * - if store install use EXECUTABLE_PATH - * - if manual install use HACKPREFIX - * - * SYSCONFPREFIX - * - use COMMON_NETHACK_PATH if sysconf present - * - otherwise use HACKPREFIX - * - * CONFIGPREFIX - * - if manual install use PROFILE_PATH - * - if store install use NETHACK_PROFILE_PATH - */ - void set_default_prefix_locations(const char *programPath) { @@ -214,16 +176,16 @@ set_default_prefix_locations(const char *programPath) build_known_folder_path(&FOLDERID_ProgramData, versioned_global_data_path, sizeof(versioned_global_data_path), TRUE); - fqn_prefix[LEVELPREFIX] = versioned_user_data_path; - fqn_prefix[SAVEPREFIX] = versioned_user_data_path; - fqn_prefix[BONESPREFIX] = versioned_global_data_path; - fqn_prefix[DATAPREFIX] = executable_path; - fqn_prefix[SCOREPREFIX] = versioned_global_data_path; - fqn_prefix[LOCKPREFIX] = versioned_global_data_path; + fqn_prefix[SYSCONFPREFIX] = versioned_global_data_path; fqn_prefix[CONFIGPREFIX] = profile_path; fqn_prefix[HACKPREFIX] = versioned_profile_path; + fqn_prefix[SAVEPREFIX] = versioned_user_data_path; + fqn_prefix[LEVELPREFIX] = versioned_user_data_path; + fqn_prefix[BONESPREFIX] = versioned_global_data_path; + fqn_prefix[SCOREPREFIX] = versioned_global_data_path; + fqn_prefix[LOCKPREFIX] = versioned_global_data_path; fqn_prefix[TROUBLEPREFIX] = versioned_profile_path; - fqn_prefix[SYSCONFPREFIX] = versioned_global_data_path; + fqn_prefix[DATAPREFIX] = executable_path; } @@ -297,9 +259,15 @@ void copy_sysconf_content() update_file(fqn_prefix[SYSCONFPREFIX], SYSCF_TEMPLATE, fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + update_file(fqn_prefix[SYSCONFPREFIX], SYMBOLS_TEMPLATE, + fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, FALSE); + /* If the required early game file does not exist, copy it */ copy_file(fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE); + + update_file(fqn_prefix[SYSCONFPREFIX], SYMBOLS, + fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, TRUE); } void copy_config_content() @@ -311,17 +279,10 @@ void copy_config_content() update_file(fqn_prefix[CONFIGPREFIX], CONFIG_TEMPLATE, fqn_prefix[DATAPREFIX], CONFIG_TEMPLATE, FALSE); - update_file(fqn_prefix[CONFIGPREFIX], SYMBOLS_TEMPLATE, - fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, FALSE); - /* If the required early game file does not exist, copy it */ /* NOTE: We never replace .nethackrc or sysconf */ copy_file(fqn_prefix[CONFIGPREFIX], CONFIG_FILE, fqn_prefix[DATAPREFIX], CONFIG_TEMPLATE); - - update_file(fqn_prefix[CONFIGPREFIX], SYMBOLS, - fqn_prefix[DATAPREFIX], SYMBOLS_TEMPLATE, TRUE); - } void From c2bbbebd8eddc544207fce6e62118568ad254f82 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 Nov 2019 10:59:07 -0500 Subject: [PATCH 5/9] restrict a recent deaf message change to player actions only --- doc/fixes36.3 | 1 + src/zap.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 707de2ca2..1f7985f01 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -248,6 +248,7 @@ in symset:curses, symbol S_tree was accidentally set to horizontal line where plus-or-minus sign was meant; also, change S_bars to not-equals sign percentage highlighting for Xp broke up/down/changed highlighting for it; it was flagged as having gone up every time the percentage changed +deaf change to zap_over_floor needed to be restricted to player actions only curses: sometimes the message window would show a blank line after a prompt curses: the change to show map in columns 1..79 instead of 2..80 made the highlight for '@' show up in the wrong place if clipped map had been diff --git a/src/zap.c b/src/zap.c index bc4189a47..308754340 100644 --- a/src/zap.c +++ b/src/zap.c @@ -4443,7 +4443,9 @@ short exploding_wand_typ; } else if (is_pool(x, y)) { const char *msgtxt = (!Deaf) ? "You hear hissing gas." /* Deaf-aware */ - : "That seemed remarkably uneventful."; + : (type >= 0) + ? "That seemed remarkably uneventful." + : (const char *) 0; if (lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */ if (see_it) @@ -4457,7 +4459,8 @@ short exploding_wand_typ; if (see_it) msgtxt = "The water evaporates."; } - Norep("%s", msgtxt); + if (msgtxt) + Norep("%s", msgtxt); if (lev->typ == ROOM) newsym(x, y); } else if (IS_FOUNTAIN(lev->typ)) { From c2f7fb7d841eb170dbdd0c3bd37e85472aea26d6 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 11 Nov 2019 18:46:14 +0200 Subject: [PATCH 6/9] Fix heap-use-after-free bcsign was used on a freed obj --- src/muse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muse.c b/src/muse.c index ffaf63ab6..772a01777 100644 --- a/src/muse.c +++ b/src/muse.c @@ -2497,8 +2497,8 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */ vis = FALSE; /* skip makeknown() below */ res = FALSE; /* failed to cure sliming */ } else { - m_useup(mon, obj); /* before explode() */ dmg = (2 * (rn1(3, 3) + 2 * bcsign(obj)) + 1) / 3; + m_useup(mon, obj); /* before explode() */ /* -11 => monster's fireball */ explode(mon->mx, mon->my, -11, dmg, SCROLL_CLASS, /* by_you: override -11 for mon but not others */ From 91b4bd0da92a100e41d279ffdfca890948df3506 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 Nov 2019 11:46:49 -0500 Subject: [PATCH 7/9] new prefix_locked bits conditionalized to WIN32 --- include/decl.h | 2 ++ src/decl.c | 4 +++- src/files.c | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/decl.h b/include/decl.h index ff7404af3..c2e0648e1 100644 --- a/include/decl.h +++ b/include/decl.h @@ -398,7 +398,9 @@ E const char *const monexplain[], invisexplain[], *const oclass_names[]; #endif E char *fqn_prefix[PREFIX_COUNT]; +#ifdef WIN32 E boolean fqn_prefix_locked[PREFIX_COUNT]; +#endif #ifdef PREFIXES_IN_USE E char *fqn_prefix_names[PREFIX_COUNT]; #endif diff --git a/src/decl.c b/src/decl.c index d732df35c..d3706ef3b 100644 --- a/src/decl.c +++ b/src/decl.c @@ -286,11 +286,13 @@ char *fqn_prefix[PREFIX_COUNT] = { (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0 }; +#ifdef WIN32 boolean fqn_prefix_locked[PREFIX_COUNT] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; - +#endif + #ifdef PREFIXES_IN_USE char *fqn_prefix_names[PREFIX_COUNT] = { "hackdir", "leveldir", "savedir", "bonesdir", "datadir", diff --git a/src/files.c b/src/files.c index e9af0a3c5..f8e77cfdf 100644 --- a/src/files.c +++ b/src/files.c @@ -2159,8 +2159,10 @@ int prefixid; if (!bufp) return; +#ifdef WIN32 if (fqn_prefix_locked[prefixid]) return; +#endif /* Backward compatibility, ignore trailing ;n */ if ((ptr = index(bufp, ';')) != 0) *ptr = '\0'; @@ -3870,9 +3872,10 @@ assure_syscf_file() { int fd; +#ifdef WIN32 /* We are checking that the sysconf exists ... lock the path */ fqn_prefix_locked[SYSCONFPREFIX] = TRUE; - +#endif /* * All we really care about is the end result - can we read the file? * So just check that directly. From 6dfbff9d4bcd3aa0dfa43bae90ab3dbc39c1d663 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 Nov 2019 12:49:54 -0500 Subject: [PATCH 8/9] --showpaths wasn't returning the paths if there was an error in a config file Also, Windows only: Introduces some environment variable substitution for paths specified in a config file --- include/flag.h | 2 ++ src/files.c | 17 +++++++++++- src/options.c | 2 +- sys/unix/unixmain.c | 2 ++ sys/winnt/windmain.c | 61 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/include/flag.h b/include/flag.h index 8fe94339b..5370faab7 100644 --- a/include/flag.h +++ b/include/flag.h @@ -268,6 +268,8 @@ struct instance_flags { boolean mon_polycontrol; /* debug: control monster polymorphs */ boolean in_dumplog; /* doing the dumplog right now? */ boolean in_parse; /* is a command being parsed? */ + /* suppress terminate during options parsing, for --showpaths */ + boolean initoptions_noterminate; /* stuff that is related to options and/or user or platform preferences */ diff --git a/src/files.c b/src/files.c index f8e77cfdf..38a692113 100644 --- a/src/files.c +++ b/src/files.c @@ -151,6 +151,10 @@ static int lockptr; #ifndef WIN_CE #define DeleteFile unlink #endif +#ifdef WIN32 +/*from windmain.c */ +extern char *FDECL(translate_path_variables, (const char *, char *)); +#endif #endif #ifdef MAC @@ -350,6 +354,10 @@ const char *basenam; int whichprefix UNUSED_if_not_PREFIXES_IN_USE; int buffnum UNUSED_if_not_PREFIXES_IN_USE; { +#ifdef WIN32 + char tmpbuf[BUFSZ]; + +#endif #ifndef PREFIXES_IN_USE return basenam; #else @@ -367,9 +375,16 @@ int buffnum UNUSED_if_not_PREFIXES_IN_USE; basenam); return basenam; /* XXX */ } +#ifdef WIN32 + if (strchr(fqn_prefix[whichprefix], '%') || + strchr(fqn_prefix[whichprefix], '~')) + Strcpy(fqn_filename_buffer[buffnum], + translate_path_variables(fqn_prefix[whichprefix], tmpbuf)); + else +#endif Strcpy(fqn_filename_buffer[buffnum], fqn_prefix[whichprefix]); return strcat(fqn_filename_buffer[buffnum], basenam); -#endif +#endif /* !PREFIXES_IN_USE */ } int diff --git a/src/options.c b/src/options.c index bfeb08604..203532cde 100644 --- a/src/options.c +++ b/src/options.c @@ -673,7 +673,7 @@ initoptions() /* ... and _must_ parse correctly. */ if (!read_config_file(SYSCF_FILE, SET_IN_SYS)) { - if (config_error_done()) + if (config_error_done() && !iflags.initoptions_noterminate) nh_terminate(EXIT_FAILURE); } config_error_done(); diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 50c047ff8..c2690ce4a 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -118,7 +118,9 @@ char *argv[]; #ifdef CHDIR chdirx((char *) 0, 0); #endif + iflags.initoptions_noterminate = TRUE; initoptions(); + iflags.initoptions_noterminate = FALSE; reveal_paths(); exit(EXIT_SUCCESS); } diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index 22809751c..e1faeab50 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -24,6 +24,7 @@ static void FDECL(process_options, (int argc, char **argv)); static void NDECL(nhusage); static char *NDECL(get_executable_path); +char *FDECL(translate_path_variables, (char *, char *)); char *NDECL(exename); boolean NDECL(fakeconsole); void NDECL(freefakeconsole); @@ -62,8 +63,7 @@ char default_window_sys[] = "mswin"; static struct stat hbuf; #endif #include -#if defined(WIN32) || defined(MSDOS) -#endif + extern char orgdir[]; @@ -548,7 +548,9 @@ char *argv[]; nethack_exit(EXIT_SUCCESS); if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { + iflags.initoptions_noterminate = TRUE; initoptions(); + iflags.initoptions_noterminate = FALSE; reveal_paths(); nethack_exit(EXIT_SUCCESS); } @@ -853,6 +855,61 @@ get_executable_path() return path_buffer; } +char * +translate_path_variables(str, buf) +const char *str; +char *buf; +{ + const char *src; + char evar[BUFSZ], *dest, *envp, *eptr = (char *) 0; + boolean in_evar; + size_t ccount, ecount, destcount, slen = str ? strlen(str) : 0; + + if (!slen || !buf) { + if (buf) + *buf = '\0'; + return buf; + } + + dest = buf; + src = str; + in_evar = FALSE; + destcount = ecount = 0; + for (ccount = 0; ccount < slen && destcount < (BUFSZ - 1) && + ecount < (BUFSZ - 1); ++ccount, ++src) { + if (*src == '%') { + if (in_evar) { + *eptr = '\0'; + envp = nh_getenv(evar); + if (envp) { + size_t elen = strlen(envp); + + if ((elen + destcount) < (size_t) (BUFSZ - 1)) { + Strcpy(dest, envp); + dest += elen; + destcount += elen; + } + } + } else { + eptr = evar; + ecount = 0; + } + in_evar = !in_evar; + continue; + } + if (in_evar) { + *eptr++ = *src; + ecount++; + } else { + *dest++ = *src; + destcount++; + } + } + *dest = '\0'; + return buf; +} + + /*ARGSUSED*/ void windows_raw_print(str) From 02da5f2d38c3166d5c3c7d87dc876ddf358d80f6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 Nov 2019 14:19:16 -0500 Subject: [PATCH 9/9] more Windows path environ variable translation bits --- src/files.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/files.c b/src/files.c index 38a692113..454a80bc7 100644 --- a/src/files.c +++ b/src/files.c @@ -354,10 +354,13 @@ const char *basenam; int whichprefix UNUSED_if_not_PREFIXES_IN_USE; int buffnum UNUSED_if_not_PREFIXES_IN_USE; { +#ifdef PREFIXES_IN_USE + char *bufptr; +#endif #ifdef WIN32 char tmpbuf[BUFSZ]; - #endif + #ifndef PREFIXES_IN_USE return basenam; #else @@ -369,20 +372,17 @@ int buffnum UNUSED_if_not_PREFIXES_IN_USE; impossible("Invalid fqn_filename_buffer specified: %d", buffnum); buffnum = 0; } - if (strlen(fqn_prefix[whichprefix]) + strlen(basenam) - >= FQN_MAX_FILENAME) { - impossible("fqname too long: %s + %s", fqn_prefix[whichprefix], - basenam); + bufptr = fqn_prefix[whichprefix]; +#ifdef WIN32 + if (strchr(fqn_prefix[whichprefix], '%') + || strchr(fqn_prefix[whichprefix], '~')) + bufptr = translate_path_variables(fqn_prefix[whichprefix], tmpbuf); +#endif + if (strlen(bufptr) + strlen(basenam) >= FQN_MAX_FILENAME) { + impossible("fqname too long: %s + %s", bufptr, basenam); return basenam; /* XXX */ } -#ifdef WIN32 - if (strchr(fqn_prefix[whichprefix], '%') || - strchr(fqn_prefix[whichprefix], '~')) - Strcpy(fqn_filename_buffer[buffnum], - translate_path_variables(fqn_prefix[whichprefix], tmpbuf)); - else -#endif - Strcpy(fqn_filename_buffer[buffnum], fqn_prefix[whichprefix]); + Strcpy(fqn_filename_buffer[buffnum], bufptr); return strcat(fqn_filename_buffer[buffnum], basenam); #endif /* !PREFIXES_IN_USE */ }