From 696af8929902c07d247b068412ad4a00f6793551 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 19 Oct 2024 10:47:53 +0300 Subject: [PATCH] Change MSGHANDLER from compile-time to sysconf --- doc/Guidebook.mn | 4 ++++ doc/Guidebook.tex | 5 +++++ doc/fixes3-7-0.txt | 1 + include/config.h | 6 ------ include/sys.h | 1 + src/files.c | 11 +++++++++++ src/mdlib.c | 3 --- src/pline.c | 26 ++++++-------------------- src/sys.c | 3 +++ sys/unix/sysconf | 4 ++++ sys/windows/sysconf.template | 4 ++++ 11 files changed, 39 insertions(+), 29 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 549f9c0b7..4b9dbe4a0 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6064,6 +6064,10 @@ escape command (!). The syntax is the same as WIZARDS. EXPLORERS\ =\ A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. .lp +MSGHANDLER\ =\ A path and filename of executable. Whenever a message-window +message is shown, NetHack runs this program. The program will get +the message as the only parameter. +.lp MAXPLAYERS\ =\ Limit the maximum number of games that can be running at the same time. .lp diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index d71cbd330..95d7d5314 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -6703,6 +6703,11 @@ The syntax is the same as WIZARDS. A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. %.lp +\item[\ib{MSGHANDLER}] +A path and filename of executable. Whenever a message-window +message is shown, NetHack runs this program. The program will get +the message as the only parameter. +%.lp \item[\ib{MAXPLAYERS}] Limit the maximum number of games that can be running at the same time. %.lp diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index d6059729b..08db1ae00 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1474,6 +1474,7 @@ interactively setting a status highlight for hunger with 'O' and choosing a pet with the hides-under attribute could "move reluctantly over" a cursed object and then hide under it prevent monster generation in the sokoban trap hallway +change MSGHANDLER from compile-time to sysconf option Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/config.h b/include/config.h index 9b77a7d10..64910138b 100644 --- a/include/config.h +++ b/include/config.h @@ -641,12 +641,6 @@ typedef unsigned char uchar; * at least 28 additional rows beneath the status window on your terminal */ /* #define TTY_PERM_INVENT */ -/* NetHack will execute an external program whenever a new message-window - * message is shown. The program to execute is given in environment variable - * NETHACK_MSGHANDLER. It will get the message as the only parameter. - * Only available with POSIX_TYPES, GNU C, or WIN32 */ -/* #define MSGHANDLER */ - /* enable status highlighting via STATUS_HILITE directives in run-time config file and the 'statushilites' option */ #define STATUS_HILITES /* support hilites of status fields */ diff --git a/include/sys.h b/include/sys.h index 32d9221cc..764d7435f 100644 --- a/include/sys.h +++ b/include/sys.h @@ -15,6 +15,7 @@ struct sysopt { char *shellers; /* like wizards, for ! command (-DSHELL); also ^Z */ char *genericusers; /* usernames that prompt for user name */ char *debugfiles; /* files to show debugplines in. '*' is all. */ + char *msghandler; #ifdef DUMPLOG char *dumplogfile; /* where the dump file is saved */ #endif diff --git a/src/files.c b/src/files.c index e4834e2ae..b214c7a55 100644 --- a/src/files.c +++ b/src/files.c @@ -173,6 +173,7 @@ staticfn boolean cnf_line_catname(char *); #ifdef SYSCF staticfn boolean cnf_line_WIZARDS(char *); staticfn boolean cnf_line_SHELLERS(char *); +staticfn boolean cnf_line_MSGHANDLER(char *); staticfn boolean cnf_line_EXPLORERS(char *); staticfn boolean cnf_line_DEBUGFILES(char *); staticfn boolean cnf_line_DUMPLOGFILE(char *); @@ -2756,6 +2757,15 @@ cnf_line_SHELLERS(char *bufp) return TRUE; } +staticfn boolean +cnf_line_MSGHANDLER(char *bufp) +{ + if (sysopt.msghandler) + free((genericptr_t) sysopt.msghandler); + sysopt.msghandler = dupstr(bufp); + return TRUE; +} + staticfn boolean cnf_line_EXPLORERS(char *bufp) { @@ -3272,6 +3282,7 @@ static const struct match_config_line_stmt { #ifdef SYSCF CNFL_S(WIZARDS, 7), CNFL_S(SHELLERS, 8), + CNFL_S(MSGHANDLER, 9), CNFL_S(EXPLORERS, 7), CNFL_S(DEBUGFILES, 5), CNFL_S(DUMPLOGFILE, 7), diff --git a/src/mdlib.c b/src/mdlib.c index b6da48e33..9e7700cc8 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -478,9 +478,6 @@ static const char *const build_opts[] = { #ifdef HOLD_LOCKFILE_OPEN "exclusive lock on level 0 file", #endif -#ifdef MSGHANDLER - "external program as a message handler", -#endif #if defined(HANGUPHANDLING) && !defined(NO_SIGNAL) #ifdef SAFERHANGUP "deferred handling of hangup signal", diff --git a/src/pline.c b/src/pline.c index 4ca4a79a7..4cf52bc2e 100644 --- a/src/pline.c +++ b/src/pline.c @@ -11,9 +11,7 @@ staticfn void putmesg(const char *); staticfn char *You_buf(int); -#if defined(MSGHANDLER) staticfn void execplinehandler(const char *); -#endif #ifdef USER_SOUNDS extern void maybe_play_sound(const char *); #endif @@ -262,9 +260,7 @@ vpline(const char *line, va_list the_args) putmesg(line); -#if defined(MSGHANDLER) execplinehandler(line); -#endif /* this gets cleared after every pline message */ iflags.last_msg = PLNMSG_UNKNOWN; @@ -564,9 +560,7 @@ vraw_printf(const char *line, va_list the_args) pbuf[BUFSZ - 1] = '\0'; /* terminate strncpy or truncate vsprintf */ } raw_print(line); -#if defined(MSGHANDLER) execplinehandler(line); -#endif if (!program_state.beyond_savefile_load) ge.early_raw_messages++; } @@ -626,7 +620,6 @@ impossible(const char *s, ...) RESTORE_WARNING_FORMAT_NONLITERAL -#if defined(MSGHANDLER) static boolean use_pline_handler = TRUE; staticfn void @@ -636,27 +629,21 @@ execplinehandler(const char *line) int f; #endif const char *args[3]; - char *env; - if (!use_pline_handler) + if (!use_pline_handler || !sysopt.msghandler) return; - if (!(env = nh_getenv("NETHACK_MSGHANDLER"))) { - use_pline_handler = FALSE; - return; - } - #if defined(POSIX_TYPES) || defined(__GNUC__) f = fork(); if (f == 0) { /* child */ - args[0] = env; + args[0] = sysopt.msghandler; args[1] = line; args[2] = NULL; (void) setgid(getgid()); (void) setuid(getuid()); (void) execv(args[0], (char *const *) args); perror((char *) 0); - (void) fprintf(stderr, "Exec to message handler %s failed.\n", env); + (void) fprintf(stderr, "Exec to message handler %s failed.\n", sysopt.msghandler); nh_terminate(EXIT_FAILURE); } else if (f > 0) { int status; @@ -670,16 +657,15 @@ execplinehandler(const char *line) #elif defined(WIN32) { intptr_t ret; - args[0] = env; + args[0] = sysopt.msghandler; args[1] = line; args[2] = NULL; - ret = _spawnv(_P_NOWAIT, env, args); + ret = _spawnv(_P_NOWAIT, sysopt.msghandler, args); } #else -#error MSGHANDLER is not implemented on this system. + use_pline_handler = FALSE; #endif } -#endif /* MSGHANDLER */ /* * varargs handling for files.c diff --git a/src/sys.c b/src/sys.c index ad2274fbe..2cef92a87 100644 --- a/src/sys.c +++ b/src/sys.c @@ -48,6 +48,7 @@ sys_early_init(void) sysopt.shellers = (char *) 0; sysopt.explorers = (char *) 0; sysopt.genericusers = (char *) 0; + sysopt.msghandler = (char *) 0; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ sysopt.bones_pools = 0; sysopt.livelog = LL_NONE; @@ -115,6 +116,8 @@ sysopt_release(void) free((genericptr_t) sysopt.debugfiles), sysopt.debugfiles = (char *) 0; sysopt.env_dbgfl = 0; + if (sysopt.msghandler) + free((genericptr_t) sysopt.msghandler), sysopt.msghandler = (char *) 0; #ifdef DUMPLOG if (sysopt.dumplogfile) free((genericptr_t) sysopt.dumplogfile), sysopt.dumplogfile=(char *) 0; diff --git a/sys/unix/sysconf b/sys/unix/sysconf index e10b4e34c..34926903b 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -32,6 +32,10 @@ EXPLORERS=* # Uses the same syntax as the WIZARDS and EXPLORERS options above. #SHELLERS= +# Execute this program whenever a new message-window message is shown. +# The program will get the message text as the only parameter. +#MSGHANDLER=/usr/bin/espeak + # If the user name is found in this list, prompt for username instead. # Uses the same syntax as the WIZARDS option above. # A public server should probably disable this. diff --git a/sys/windows/sysconf.template b/sys/windows/sysconf.template index 36f3651bc..90095dc1b 100644 --- a/sys/windows/sysconf.template +++ b/sys/windows/sysconf.template @@ -15,6 +15,10 @@ WIZARDS=* # Uses the same syntax as the WIZARDS option above. #SHELLERS= +# Execute this program whenever a new message-window message is shown. +# The program will get the message text as the only parameter. +#MSGHANDLER=\path\program + # Show debugging information originating from these source files. # Use '*' for all, or list source files separated by spaces. # Only available if game has been compiled with DEBUG.