]> granicus.if.org Git - nethack/commitdiff
SYSCF bits
authorkeni <keni>
Fri, 27 Jan 2012 20:15:31 +0000 (20:15 +0000)
committerkeni <keni>
Fri, 27 Jan 2012 20:15:31 +0000 (20:15 +0000)
(This covers some thing that Pat found and some things I found while working
on those.)
Unscramble duplicate use of GREPPATH and GDBPATH symbols.
Add some more info to config.h.
Make missing SYSCF_FILE a fatal error.
Make a parse error in SYSCF_FILE a fatal error.
Rename PANICTRACE_GLIBC (et al) to PANICTRACE_LIBC (et al) since FreeBSD
 and Mac OS X (at least) also implement the needed API.
Allow SYSCF_FILE to be unreadable by the user (for setgid installs).
If SYSCF, do NOT fall back to the compiled in WIZARD account.
Put WIZARD into sysopt and remove special cases in authorize_wizard_mode().

include/config.h
include/extern.h
include/global.h
include/sys.h
src/end.c
src/files.c
src/options.c
src/sys.c
sys/unix/sysconf
sys/unix/unixmain.c
sys/unix/unixunix.c

index 23b2b35bfb15fa4a1f18a3c6cbadb4d59e15aa11..13adba0d4a9d4df2ba82a7b9b9d3aa5f2812b31d 100644 (file)
  *             If SYSCF is defined, the following configuration info is
  *             available in a global config space, with the compiled-in
  *             entries as defaults:
- *             WIZARDS         ( a value of * allows anyone to be wizard)
+ *             WIZARDS         (a value of * allows anyone to be wizard)
+ *                              (this does NOT default to compiled-in value)
  *             MAXPLAYERS      (see MAX_NR_OF_PLAYERS above and nethack.sh)
  *             SUPPORT         (how to get local support)(no default)
  *             RECOVER         (how to recover a game at your site)(no default)
  *
  *             The following options select how the config space is stored:
  *             SYSCF_FILE      in the named file
+ *
+ *              The following options pertain to crash reporting:
+ *              GREPPATH       (the path to the system grep(1) utility)
+ *              GDBPATH                (the path to the system gdb(1) program)
  */
 
 #ifndef WIZARD         /* allow for compile-time or Makefile changes */
 # endif
 #endif
 
+#ifndef GDBPATH
+# define GDBPATH "/usr/bin/gdb"
+#endif
+#ifndef GREPPATH
+# define GREPPATH "/bin/grep"
+#endif
+
 #define LOGFILE "logfile"      /* larger file for debugging purposes */
 #define NEWS "news"            /* the file containing the latest hack news */
 #define PANICLOG "paniclog"    /* log of panic and impossible events */
index 1e8f1683b2eb0c6298f5b99edf50be3a879f8b42..19f00a20df4458d72fff2fbfc9124a1354d26ab1 100644 (file)
@@ -742,7 +742,7 @@ E void FDECL(unlock_file, (const char *));
 #ifdef USER_SOUNDS
 E boolean FDECL(can_read_file, (const char *));
 #endif
-E void FDECL(read_config_file, (const char *, int));
+E boolean FDECL(read_config_file, (const char *, int));
 E void FDECL(check_recordfile, (const char *));
 #if defined(WIZARD)
 E void NDECL(read_wizkit);
@@ -2357,6 +2357,9 @@ E void NDECL(port_help);
 E void FDECL(sethanguphandler, (void (*)(int)));
 E boolean NDECL(authorize_wizard_mode);
 E boolean FDECL(check_user_string, (char *));
+# ifdef SYSCF_FILE
+E void NDECL(assure_syscf_file);
+# endif
 #endif /* UNIX */
 
 /* ### unixtty.c ### */
@@ -2384,6 +2387,9 @@ E int NDECL(dosh);
 # if defined(SHELL) || defined(DEF_PAGER) || defined(DEF_MAILREADER)
 E int FDECL(child, (int));
 # endif
+# ifdef PANICTRACE
+E boolean FDECL(file_exists, (const char *));
+# endif
 #endif /* UNIX */
 
 /* ### unixres.c ### */
index f728c33c711e6a60e43d30afcfacfe455425e744..f7514f44f0de6a9201bd07e1b80eae5835974822 100644 (file)
@@ -382,7 +382,10 @@ struct savefile_info {
 #endif
 /* The following are meaningless if PANICTRACE is not defined: */
 #if defined(__linux__) && defined(__GLIBC__) && (__GLIBC__ >= 2)
-# define PANICTRACE_GLIBC
+# define PANICTRACE_LIBC
+#endif
+#if defined(MACOSX)
+# define PANICTRACE_LIBC
 #endif
 #ifdef UNIX
 # define PANICTRACE_GDB
index a45478fc49f3820e3018c12cb8ac7c2dd24bf2d0..24d27daa7cdaaa5db5d50d2f61a7ef34880ce7b8 100644 (file)
@@ -25,8 +25,8 @@ struct sysopt {
        char *gdbpath;
        char *greppath;
        int  panictrace_gdb;
-# ifdef PANICTRACE_GLIBC
-       int panictrace_glibc;
+# ifdef PANICTRACE_LIBC
+       int panictrace_libc;
 # endif
 #endif
        int seduce;
index 332a6277ab3fd6c5ca80b5cf97ee1307035e6b89..40dc61d22d372fd732e3df026c39d142b3bf50d7 100644 (file)
--- a/src/end.c
+++ b/src/end.c
@@ -77,13 +77,13 @@ extern void FDECL(nethack_exit,(int));
 
 #ifdef PANICTRACE
 # include <errno.h>
-# ifdef PANICTRACE_GLIBC
+# ifdef PANICTRACE_LIBC
 #  include <execinfo.h>
 # endif
 
 /* What do we try and in what order?  Tradeoffs:
- * glibc: +no external programs required
- *        -requires newish glibc
+ * libc: +no external programs required
+ *        -requires newish libc/glibc
  *        -requires -rdynamic
  * gdb:   +gives more detailed information
  *        +works on more OS versions
@@ -91,17 +91,17 @@ extern void FDECL(nethack_exit,(int));
  */
 # ifdef SYSCF
 #  define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
-#  ifdef PANICTRACE_GLIBC
-#   define SYSOPT_PANICTRACE_GLIBC sysopt.panictrace_glibc
+#  ifdef PANICTRACE_LIBC
+#   define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
 #  else
-#   define SYSOPT_PANICTRACE_GLIBC 0
+#   define SYSOPT_PANICTRACE_LIBC 0
 #  endif
 # else
 #  define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB")==0?0:2)
-#  ifdef PANICTRACE_GLIBC
-#   define SYSOPT_PANICTRACE_GLIBC 1
+#  ifdef PANICTRACE_LIBC
+#   define SYSOPT_PANICTRACE_LIBC 1
 #  else
-#   define SYSOPT_PANICTRACE_GLIBC 0
+#   define SYSOPT_PANICTRACE_LIBC 0
 #  endif
 # endif
 
@@ -109,7 +109,7 @@ static void NDECL(NH_abort);
 # ifndef NO_SIGNAL
 static void FDECL(panictrace_handler, (int));
 # endif
-static boolean NDECL(NH_panictrace_glibc);
+static boolean NDECL(NH_panictrace_libc);
 static boolean NDECL(NH_panictrace_gdb);
 
 # ifndef NO_SIGNAL
@@ -163,19 +163,19 @@ static void
 NH_abort()
 {
        int gdb_prio = SYSOPT_PANICTRACE_GDB;
-       int glibc_prio = SYSOPT_PANICTRACE_GLIBC;
+       int libc_prio = SYSOPT_PANICTRACE_LIBC;
        static boolean aborting = FALSE;
 
        if(aborting) return;
        aborting = TRUE;
 
 # ifndef VMS
-       if(gdb_prio == glibc_prio && gdb_prio > 0) gdb_prio++;
+       if(gdb_prio == libc_prio && gdb_prio > 0) gdb_prio++;
 
-       if(gdb_prio > glibc_prio){
-               NH_panictrace_gdb() || (glibc_prio && NH_panictrace_glibc());
+       if(gdb_prio > libc_prio){
+               NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc());
        } else {
-               NH_panictrace_glibc() || (gdb_prio && NH_panictrace_gdb());
+               NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb());
        }
 
 # else /* VMS */
@@ -183,7 +183,7 @@ NH_abort()
           traceback and exit; 2 = show traceback and stay in debugger */
      /* if (wizard && gdb_prio == 1) gdb_prio = 2; */
        vms_traceback(gdb_prio);
-       (void)glibc_prio;       /* half-hearted attempt at lint suppression */
+       (void)libc_prio;        /* half-hearted attempt at lint suppression */
 
 # endif /* ?VMS */
 
@@ -194,9 +194,9 @@ NH_abort()
 }
 
 static boolean
-NH_panictrace_glibc()
+NH_panictrace_libc()
 {
-# ifdef PANICTRACE_GLIBC
+# ifdef PANICTRACE_LIBC
        void *bt[20];
        size_t count;
        char **info;
@@ -212,22 +212,22 @@ NH_panictrace_glibc()
        return TRUE;
 # else
        return FALSE;
-# endif  /* !PANICTRACE_GLIBC */
+# endif  /* !PANICTRACE_LIBC */
 }
 
+/*
+ *   fooPATH  file system path for foo
+ *   fooVAR   (possibly const) variable containing fooPATH
+ */
 # ifdef PANICTRACE_GDB
 #  ifdef SYSCF
-#   define GDBPATH sysopt.gdbpath
-#   define GREPPATH sysopt.greppath
-#  else
-#   ifndef GDBPATH
-#    define GDBPATH "/usr/bin/gdb"
-#   endif
-#   ifndef GREPPATH
-#    define GREPPATH "/bin/grep"
-#   endif
-#  endif /* !SYSCF */
-# endif  /* PANICTRACE_GDB */
+#   define GDBVAR sysopt.gdbpath
+#   define GREPVAR sysopt.greppath
+#  else /* SYSCF */
+#   define GDBVAR GDBPATH
+#   define GREPVAR GREPPATH
+#  endif /* SYSCF */
+# endif /* PANICTRACE_GDB */
 
 static boolean
 NH_panictrace_gdb()
@@ -235,8 +235,8 @@ NH_panictrace_gdb()
 # ifdef PANICTRACE_GDB
        /* A (more) generic method to get a stack trace - invoke
         * gdb on ourself. */
-       char *gdbpath = GDBPATH;
-       char *greppath = GREPPATH;
+       char *gdbpath = GDBVAR;
+       char *greppath = GREPVAR;
        char buf[BUFSZ];
        FILE *gdb;
 
index 107c20574b545465b4bdda924922426c1cf64519..05afa76020daeffcd37ada43ada576b3375a65ea 100644 (file)
@@ -183,7 +183,7 @@ STATIC_DCL void FDECL(docompress_file, (const char *,BOOLEAN_P));
 STATIC_DCL boolean FDECL(make_compressed_name, (const char *, char *));
 #endif
 STATIC_DCL char *FDECL(make_lockname, (const char *,char *));
-STATIC_DCL FILE *FDECL(fopen_config_file, (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 *));
 int FDECL(parse_config_line, (FILE *,char *,char *,char *,int));
 #ifdef LOADSYMSETS
@@ -1772,8 +1772,9 @@ const char *backward_compat_configfile = "nethack.cnf";
 #endif
 
 STATIC_OVL FILE *
-fopen_config_file(filename)
+fopen_config_file(filename, src)
 const char *filename;
+int src;
 {
        FILE *fp;
 #if defined(UNIX) || defined(VMS)
@@ -1781,16 +1782,18 @@ const char *filename;
        char *envp;
 #endif
 
-       /* "filename" is an environment variable, so it should hang around */
-       /* if set, it is expected to be a full path name (if relevant) */
+       /* 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) {
 #ifdef UNIX
-               if (access(filename, 4) == -1) {
+               if ((src!=SET_IN_SYS) && access(filename, 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
+                        * control (but SYSCF_FILE is not under the player's
+                        * control so it's OK).
                         */
                        raw_printf("Access to %s denied (%d).",
                                        filename, errno);
@@ -2148,16 +2151,16 @@ int             src;
            }
            sysopt.pointsmin = temp;
 # ifdef PANICTRACE
-#  ifdef PANICTRACE_GLIBC
+#  ifdef PANICTRACE_LIBC
        } else if (src == SET_IN_SYS &&
-               match_varname(buf, "PANICTRACE_GLIBC", 16)) {
+               match_varname(buf, "PANICTRACE_LIBC", 15)) {
            int temp = atoi(bufp);
            if (temp < 0 || temp > 2) {
-               raw_printf("Illegal value in PANICTRACE_GLIBC (not 0,1,2).");
+               raw_printf("Illegal value in PANICTRACE_LIBC (not 0,1,2).");
                return 0;
            }
-           sysopt.panictrace_glibc = temp;
-#  endif /* PANICTRACE_GLIBC */
+           sysopt.panictrace_libc = temp;
+#  endif /* PANICTRACE_LIBC */
        } else if (src == SET_IN_SYS &&
                match_varname(buf, "PANICTRACE_GDB", 14)) {
            int temp = atoi(bufp);
@@ -2167,10 +2170,18 @@ int             src;
            }
            sysopt.panictrace_gdb = temp;
        } else if ( (src==SET_IN_SYS) && match_varname(buf, "GDBPATH", 7)) {
+           if(!file_exists(bufp)){
+               raw_printf("File specified in GDBPATH does not exist.");
+               return 0;
+           }
            if(sysopt.gdbpath) free(sysopt.gdbpath);
            sysopt.gdbpath = (char*)alloc(strlen(bufp)+1);
            Strcpy(sysopt.gdbpath, bufp);
        } else if ( (src==SET_IN_SYS) && match_varname(buf, "GREPPATH", 7)) {
+           if(!file_exists(bufp)){
+               raw_printf("File specified in GREPPATH does not exist.");
+               return 0;
+           }
            if(sysopt.greppath) free(sysopt.greppath);
            sysopt.greppath = (char*)alloc(strlen(bufp)+1);
            Strcpy(sysopt.greppath, bufp);
@@ -2377,7 +2388,7 @@ const char *filename;
 }
 #endif /* USER_SOUNDS */
 
-void
+boolean
 read_config_file(filename, src)
 const char *filename;
 int src;
@@ -2397,8 +2408,9 @@ int src;
 #endif
        char    buf[4*BUFSZ];
        FILE    *fp;
+       boolean rv = TRUE;      /* assume successful parse */
 
-       if (!(fp = fopen_config_file(filename))) return;
+       if (!(fp = fopen_config_file(filename, src))) return FALSE;
 
 #if defined(MICRO) || defined(WIN32)
 # ifdef MFLOPPY
@@ -2422,6 +2434,7 @@ OR: Forbid multiline stuff for alternate config sources.
                if (!parse_config_line(fp, buf, tmp_ramdisk, tmp_levels, src)) {
                        raw_printf("Bad option line:  \"%.50s\"", buf);
                        wait_synch();
+                       rv = FALSE;
                }
        }
        (void) fclose(fp);
@@ -2445,7 +2458,7 @@ OR: Forbid multiline stuff for alternate config sources.
        Strcpy(bones, levels);
 # endif /* MFLOPPY */
 #endif /* MICRO */
-       return;
+       return rv;
 }
 
 #ifdef WIZARD
index 220506ff8e3bab08fe070eecc6c1fe4dcb8f423f..ab93220d54b8970598af7414317c532f727eba36 100644 (file)
@@ -572,7 +572,13 @@ initoptions()
 #ifdef SYSCF
        /* someday there may be other SYSCF alternatives besides text file */
 # ifdef SYSCF_FILE
-       read_config_file(SYSCF_FILE, SET_IN_SYS);
+               /* If SYSCF_FILE is specified, it _must_ exist... */
+       assure_syscf_file();
+               /* ... and _must_ parse correctly. */
+       if(!read_config_file(SYSCF_FILE, SET_IN_SYS)){
+               raw_printf("Error(s) found in SYSCF_FILE, quitting.");
+               terminate(EXIT_FAILURE);
+       }
 # endif
 #endif
        initoptions_finish();
index be2aaf5fa6f91ff8556b07b6a2214a309865f399..595373308314cf56a36d1e4fa5049bb881892e85 100644 (file)
--- a/src/sys.c
+++ b/src/sys.c
@@ -4,16 +4,25 @@
 
 #include "hack.h"
 
+/* for KR1ED config, WIZARD is 0 or 1 and WIZARD_NAME is a string;
+   for usual config, WIZARD is the string; forcing WIZARD_NAME to match it
+   eliminates conditional testing for which one to use in string ops */
+#ifndef KR1ED
+# undef WIZARD_NAME
+# define WIZARD_NAME WIZARD
+#endif
+
 struct sysopt sysopt;
 
 void
 sys_early_init(){
        sysopt.support = NULL;
        sysopt.recover = NULL;
-#ifdef notyet
-       /* replace use of WIZARD vs WIZARD_NAME vs KR1ED, by filling this in */
-#endif
+#ifdef SYSCF
        sysopt.wizards = NULL;
+#else
+       sysopt.wizards = WIZARD_NAME;
+#endif
        sysopt.shellers = NULL;
        sysopt.maxplayers = 0;  /* XXX eventually replace MAX_NR_OF_PLAYERS */
 
@@ -32,17 +41,17 @@ sys_early_init(){
 
 #ifdef PANICTRACE
                /* panic options */
-       sysopt.gdbpath = NULL;
-       sysopt.greppath = NULL;
+       sysopt.gdbpath = strdup(GDBPATH);
+       sysopt.greppath = strdup(GREPPATH);
 # ifdef BETA
        sysopt.panictrace_gdb = 1;
-#  ifdef PANICTRACE_GLIBC
-       sysopt.panictrace_glibc = 2;
+#  ifdef PANICTRACE_LIBC
+       sysopt.panictrace_libc = 2;
 #  endif
 # else
        sysopt.panictrace_gdb = 0;
-#  ifdef PANICTRACE_GLIBC
-       sysopt.panictrace_glibc = 0;
+#  ifdef PANICTRACE_LIBC
+       sysopt.panictrace_libc = 0;
 #  endif
 # endif
 #endif
index 1f9da26ee6fda8de494a997bd062b742729dd90b..34efdcb8a412d2eba8fa5cddae967a4097004323 100644 (file)
@@ -41,12 +41,12 @@ MAXPLAYERS=10
 
 # Try to get more info in case of a program bug or crash.  Using GDB can
 # get more information and works on more systems but requires gdb be available;
-# using GLIBC only works if NetHack is linked with glibc.  Both require
-# certain compilation options.  See src/end.c and sys/unix/hints/* for
-# more information.
+# using LIBC only works if NetHack is linked with a libc that supports the
+# backtrace(3) API.  Both require certain compilation options.  See
+# src/end.c and sys/unix/hints/* for more information.
 GDBPATH=/usr/bin/gdb
 GREPPATH=/bin/grep
 # Values are priorities: 0 - do not use this method, 1 - low priority,
 # 2 - high priority.  Non-zero priority methods are tried in order.
 PANICTRACE_GDB=1
-PANICTRACE_GLIBC=2
+PANICTRACE_LIBC=2
index 55a429f4e6276c69d1b58febc1fed42a2f24a0bb..be3617170533cb99aaa0e310465bd1e88cb98786 100644 (file)
@@ -555,26 +555,15 @@ port_help()
 }
 #endif
 
-/* for KR1ED config, WIZARD is 0 or 1 and WIZARD_NAME is a string;
-   for usual config, WIZARD is the string; forcing WIZARD_NAME to match it
-   eliminates conditional testing for which one to use in string ops */
-#ifndef KR1ED
-# undef WIZARD_NAME
-# define WIZARD_NAME WIZARD
-#endif
-
 /* validate wizard mode if player has requested access to it */
 boolean
 authorize_wizard_mode()
 {
 #ifdef WIZARD
        struct passwd *pw = get_unix_pw();
-#ifdef SYSCF
        if (pw && sysopt.wizards && sysopt.wizards[0]) {
            if(check_user_string(sysopt.wizards)) return TRUE;
-       } else
-#endif
-       if (pw && !strcmp(pw->pw_name, WIZARD_NAME)) return TRUE;
+       }
 #endif /* WIZARD */
        wiz_error_flag = TRUE;  /* not being allowed into wizard mode */
        return FALSE;
@@ -585,17 +574,12 @@ wd_message()
 {
        if (wiz_error_flag) {
 #ifdef WIZARD
-# ifdef SYSCF
            if (sysopt.wizards && sysopt.wizards[0]) {
                char *tmp = build_english_list(sysopt.wizards);
                pline("Only user%s %s may access debug (wizard) mode.",
                        index(sysopt.wizards, ' ')?"s":"", tmp);
                free(tmp);
            } else
-# else
-               pline("Only user \"%s\" may access debug (wizard) mode.",
-                     WIZARD_NAME);
-# endif
 #else
                pline("Debug mode is not available.");
 #endif
@@ -675,4 +659,21 @@ get_unix_pw()
        }
        return pw;
 }
+
+#ifdef SYSCF_FILE
+void
+assure_syscf_file(){
+       /* All we really care about is the end result - can we read the file?
+        * So just check that directly. */
+       int fd;
+       fd = open(SYSCF_FILE, O_RDONLY);
+       if(fd >= 0){
+               /* readable */
+               close(fd);
+               return;
+       }
+       raw_printf("Unable to open SYSCF_FILE.\n");
+       exit(EXIT_FAILURE);
+}
+#endif
 /*unixmain.c*/
index 3078dacef282bc13db737fa5305df34631b159ea..978dd477a5fc070e986edb869533227b0a2c346a 100644 (file)
@@ -371,3 +371,18 @@ gid_t
 }
 
 #endif /* GETRES_SUPPORT */
+
+/* XXX should be ifdef PANICTRACE_GDB, but there's no such symbol yet */
+#ifdef PANICTRACE
+boolean
+file_exists(const char *path){
+       /* Just see if it's there - trying to figure out if we can actually
+        * execute it in all cases is too hard - we really just want to
+        * catch typos in SYSCF. */
+       struct stat sb;
+       if(stat(path, &sb)){
+               return FALSE;
+       }
+       return TRUE;
+}
+#endif