diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 7a87418db..ec56d335f 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -288,6 +288,8 @@ using /? to look up something by name, supplying multiple spaces (with no add support for the 'altmeta' option to the 'what-does' command ('&' or '?f') when wielded weapon becomes untouchable (after alignment change or polymorph) hero could be 'blasted by its power' twice in succession +at startup, if sysconf had been read but user's own config file couldn't be + read, sysconf got processed again as if it contained user's options Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/include/decl.h b/include/decl.h index 7898d17ce..21edb3cac 100644 --- a/include/decl.h +++ b/include/decl.h @@ -185,8 +185,6 @@ E NEARDATA struct kinfo { } killer; E long done_money; -E const char *configfile; -E char lastconfigfile[BUFSZ]; /* used for messaging */ E NEARDATA char plname[PL_NSIZ]; E NEARDATA char dogname[]; E NEARDATA char catname[]; diff --git a/src/files.c b/src/files.c index b505a4db7..51a76f188 100644 --- a/src/files.c +++ b/src/files.c @@ -188,6 +188,7 @@ STATIC_DCL boolean FDECL(make_compressed_name, (const char *, char *)); #ifndef USE_FCNTL STATIC_DCL char *FDECL(make_lockname, (const char *, char *)); #endif +STATIC_DCL void FDECL(set_configfile_name, (const char *)); STATIC_DCL FILE *FDECL(fopen_config_file, (const char *, int)); STATIC_DCL int FDECL(get_uchars, (FILE *, char *, char *, uchar *, BOOLEAN_P, int, const char *)); @@ -1821,7 +1822,7 @@ const char *filename; /* ---------- BEGIN CONFIG FILE HANDLING ----------- */ -const char *configfile = +const char *default_configfile = #ifdef UNIX ".nethackrc"; #else @@ -1837,7 +1838,7 @@ const char *configfile = #endif /* used for messaging */ -char lastconfigfile[BUFSZ]; +char configfile[BUFSZ]; #ifdef MSDOS /* conflict with speed-dial under windows @@ -1850,6 +1851,16 @@ char lastconfigfile[BUFSZ]; const char *backward_compat_configfile = "nethack.cnf"; #endif +/* remember the name of the file we're accessing; + if may be used in option reject messages */ +STATIC_OVL void +set_configfile_name(fname) +const char *fname; +{ + (void) strncpy(configfile, fname, sizeof configfile - 1); + configfile[sizeof configfile - 1] = '\0'; +} + #ifndef MFLOPPY #define fopenp fopen #endif @@ -1865,84 +1876,86 @@ int src; char *envp; #endif + if (src == SET_IN_SYS) { + /* SYSCF_FILE; if we can't open it, caller will bail */ + if (filename && *filename) { + set_configfile_name(fqname(filename, SYSCONFPREFIX, 0)); + fp = fopenp(configfile, "r"); + } else + fp = (FILE *) 0; + return fp; + } /* If src != SET_IN_SYS, "filename" is an environment variable, so it * should hang around. If set, it is expected to be a full path name - * (if relevant) */ - if (filename) { + * (if relevant) + */ + if (filename && *filename) { + set_configfile_name(filename); #ifdef UNIX - if ((src != SET_IN_SYS) && access(filename, 4) == -1) { - /* 4 is R_OK on newer systems */ + if (access(configfile, 4) == -1) { /* 4 is R_OK on newer systems */ /* nasty sneaky attempt to read file through * NetHack's setuid permissions -- this is the only * place a file name may be wholly under the player's * control (but SYSCF_FILE is not under the player's * control so it's OK). */ - raw_printf("Access to %s denied (%d).", filename, errno); + raw_printf("Access to %s denied (%d).", configfile, errno); wait_synch(); /* fall through to standard names */ } else #endif -#ifdef PREFIXES_IN_USE - if (src == SET_IN_SYS) { - (void) strncpy(lastconfigfile, fqname(filename, SYSCONFPREFIX, 0), - BUFSZ - 1); - } else -#endif - /* always honor sysconf first before anything else */ - (void) strncpy(lastconfigfile, filename, BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) - return fp; - if ((fp = fopenp(filename, "r")) != (FILE *) 0) { + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) { return fp; #if defined(UNIX) || defined(VMS) } else { /* access() above probably caught most problems for UNIX */ raw_printf("Couldn't open requested config file %s (%d).", - filename, errno); + configfile, errno); wait_synch(); -/* fall through to standard names */ #endif } } + /* fall through to standard names */ #if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32) - if ((fp = fopenp(fqname(configfile, CONFIGPREFIX, 0), "r")) != (FILE *) 0) - return fp; - if ((fp = fopenp(configfile, "r")) != (FILE *) 0) + set_configfile_name(fqname(default_configfile, CONFIGPREFIX, 0)): + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) { return fp; + } else if (strcmp(default_configfile, configfile)) { + set_configfile_name(default_configfile); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) + return fp; + } #ifdef MSDOS - if ((fp = fopenp(fqname(backward_compat_configfile, CONFIGPREFIX, 0), - "r")) != (FILE *) 0) - return fp; - if ((fp = fopenp(backward_compat_configfile, "r")) != (FILE *) 0) + set_configfile_name(fqname(backward_compat_configfile, CONFIGPREFIX, 0)); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) { return fp; + } else if (strcmp(backwad_compat_configfile, configfile)) { + set_configfile_name(backward_compat_configfile); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) + return fp; + } #endif #else /* constructed full path names don't need fqname() */ #ifdef VMS - (void) strncpy(lastconfigfile, fqname("nethackini", CONFIGPREFIX, 0), - BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) { + /* no punctuation, so might be a logical name */ + set_configfile_name(fqname("nethackini", CONFIGPREFIX, 0)); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; - } - (void) strncpy(lastconfigfile, "sys$login:nethack.ini", BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) { + set_configfile_name("sys$login:nethack.ini"); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; - } envp = nh_getenv("HOME"); - if (!envp) + if (!envp || !*envp) Strcpy(tmp_config, "NetHack.cnf"); else - Sprintf(tmp_config, "%s%s", envp, "NetHack.cnf"); - - (void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(tmp_config, "r")) != (FILE *) 0) + Sprintf(tmp_config, "%s%s%s", envp, + !index(":]>/", envp[strlen(envp) - 1]) ? "/" : "", + "NetHack.cnf"); + set_configfile_name(tmp_config); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; #else /* should be only UNIX left */ envp = nh_getenv("HOME"); @@ -1951,43 +1964,41 @@ int src; else Sprintf(tmp_config, "%s/%s", envp, ".nethackrc"); - (void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) + set_configfile_name(tmp_config); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; -#if defined(__APPLE__) +#if defined(__APPLE__) /* UNIX+__APPLE__ => MacOSX */ /* try an alternative */ if (envp) { + /* OSX-style configuration settings */ Sprintf(tmp_config, "%s/%s", envp, "Library/Preferences/NetHack Defaults"); - (void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) + set_configfile_name(tmp_config); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; + /* may be easier for user to edit if filename as '.txt' suffix */ Sprintf(tmp_config, "%s/%s", envp, "Library/Preferences/NetHack Defaults.txt"); - (void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1); - lastconfigfile[BUFSZ - 1] = '\0'; - if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) + set_configfile_name(tmp_config); + if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; } -#endif +#endif /*__APPLE__*/ if (errno != ENOENT) { const char *details; -/* e.g., problems when setuid NetHack can't search home - * directory restricted to user */ - + /* e.g., problems when setuid NetHack can't search home + directory restricted to user */ #if defined(NHSTDC) && !defined(NOTSTDC) if ((details = strerror(errno)) == 0) #endif details = ""; raw_printf("Couldn't open default config file %s %s(%d).", - lastconfigfile, details, errno); + configfile, details, errno); wait_synch(); } -#endif /* Unix */ -#endif +#endif /* !VMS => Unix */ +#endif /* !(MICRO || MAC || __BEOS__ || WIN32) */ return (FILE *) 0; } diff --git a/src/options.c b/src/options.c index 69db5926f..1245c276b 100644 --- a/src/options.c +++ b/src/options.c @@ -420,6 +420,8 @@ static struct Comp_Opt { #else /* use rest of file */ +extern char configfile[]; /* for messages */ + extern struct symparse loadsyms[]; static boolean need_redraw; /* for doset() */ @@ -917,10 +919,10 @@ rejectoption(optname) const char *optname; { #ifdef MICRO - pline("\"%s\" settable only from %s.", optname, lastconfigfile); + pline("\"%s\" settable only from %s.", optname, configfile); #else pline("%s can be set only from NETHACKOPTIONS or %s.", optname, - lastconfigfile); + configfile); #endif } @@ -941,7 +943,7 @@ const char *opts; #endif if (from_file) - raw_printf("Bad syntax in OPTIONS in %s: %s%s.\n", lastconfigfile, + raw_printf("Bad syntax in OPTIONS in %s: %s%s.\n", configfile, #ifdef WIN32 "\n", #else @@ -5318,7 +5320,7 @@ option_help() winid datawin; datawin = create_nhwindow(NHW_TEXT); - Sprintf(buf, "Set options as OPTIONS= in %s", lastconfigfile); + Sprintf(buf, "Set options as OPTIONS= in %s", configfile); opt_intro[CONFIG_SLOT] = (const char *) buf; for (i = 0; opt_intro[i]; i++) putstr(datawin, 0, opt_intro[i]); diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index a5e4b95fb..3d59f5960 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -55,7 +55,7 @@ void ClearCol(struct Window *w); void EditColor() { - extern const char *configfile; + extern char configfile[]; int i, done = 0, okay = 0; long code, qual, class; register struct Gadget *gd, *dgad;