* feature from the game; otherwise set the appropriate wizard
* name. LOGFILE, NEWS and PANICLOG refer to files in the
* playground.
+ *
+ * If SYSCF is defined, the following configuration info is
+ * available in a global config space, with the compiled-in
+ * entries as defaults:
+ * WIZARD ( a value of * allows anyone to be wizard)
+ *
+ * The following options select how the config space is stored:
+ * SYSCF_FILE in the named file
*/
#ifndef WIZARD /* allow for compile-time or Makefile changes */
# ifndef KR1ED
# define WIZARD "wizard" /* the person allowed to use the -D option */
+/* #define SYSCF */ /* use a global configuration */
+/* #define SYSCF_FILE "sysconf" */ /* global configuration is in a file */
# else
# define WIZARD
# define WIZARD_NAME "wizard"
E const char *nomovemsg;
E const char nul[];
E char lock[];
+#ifdef SYSCF
+E char wizards[];
+#endif
E const schar xdir[], ydir[], zdir[];
#ifdef USER_SOUNDS
E boolean FDECL(can_read_file, (const char *));
#endif
-E void FDECL(read_config_file, (const char *));
+E void FDECL(read_config_file, (const char *, int));
E void FDECL(check_recordfile, (const char *));
#if defined(WIZARD)
E void NDECL(read_wizkit);
E boolean FDECL(match_optname, (const char *,const char *,int,BOOLEAN_P));
E void NDECL(initoptions);
+E void NDECL(initoptions_init);
+E void NDECL(initoptions_finish);
E void FDECL(parseoptions, (char *,BOOLEAN_P,BOOLEAN_P));
E int NDECL(doset);
E int NDECL(dotogglepickup);
* Each higher number includes the characteristics of the numbers
* below it.
*/
-#define SET_IN_FILE 0 /* config file option only */
-#define SET_VIA_PROG 1 /* may be set via extern program, not seen in game */
-#define DISP_IN_GAME 2 /* may be set via extern program, displayed in game */
-#define SET_IN_GAME 3 /* may be set via extern program or set in the game */
+/* XXX This should be replaced with a bitmap. */
+#define SET_IN_SYS 0 /* system config file option only */
+#define SET_IN_FILE 1 /* config file option only */
+#define SET_VIA_PROG 2 /* may be set via extern program, not seen in game */
+#define DISP_IN_GAME 3 /* may be set via extern program, displayed in game */
+#define SET_IN_GAME 4 /* may be set via extern program or set in the game */
+#define SET__IS_VALUE_VALID(s) ( (s < SET_IN_SYS) || (s > SET_IN_GAME) )
#define FEATURE_NOTICE_VER(major,minor,patch) (((unsigned long)major << 24) | \
((unsigned long)minor << 16) | \
NEARDATA long yn_number = 0L;
const char disclosure_options[] = "iavgc";
+#ifdef SYSCF
+char wizards[PL_PSIZ] = DUMMY;
+#endif
#if defined(MICRO) || defined(WIN32)
char hackdir[PATHLEN]; /* where rumors, help, record are */
STATIC_DCL char *FDECL(make_lockname, (const char *,char *));
STATIC_DCL FILE *FDECL(fopen_config_file, (const char *));
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 FDECL(parse_config_line, (FILE *,char *,char *,char *,int));
#ifdef LOADSYMSETS
STATIC_DCL FILE *NDECL(fopen_sym_file);
STATIC_DCL void FDECL(set_symhandling, (char *,int));
/*ARGSUSED*/
int
-parse_config_line(fp, buf, tmp_ramdisk, tmp_levels)
+parse_config_line(fp, buf, tmp_ramdisk, tmp_levels, src)
FILE *fp;
char *buf;
char *tmp_ramdisk;
char *tmp_levels;
+int src;
{
#if (defined(macintosh) && (defined(__SC__) || defined(__MRC__))) || defined(__MWERKS__)
# pragma unused(tmp_ramdisk,tmp_levels)
(void) strncpy(dogname, bufp, PL_PSIZ-1);
} else if (match_varname(buf, "CATNAME", 3)) {
(void) strncpy(catname, bufp, PL_PSIZ-1);
+#ifdef SYSCF
+ } else if ( (src==SET_IN_SYS) && match_varname(buf, "WIZARDS", 6)) {
+ (void) strncpy(wizards, bufp, PL_PSIZ-1);
+#endif
} else if (match_varname(buf, "BOULDER", 3)) {
(void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
#endif /* USER_SOUNDS */
void
-read_config_file(filename)
+read_config_file(filename, src)
const char *filename;
+int src;
{
#define tmp_levels (char *)0
#define tmp_ramdisk (char *)0
set_duplicate_opt_detection(1);
while (fgets(buf, 4*BUFSZ, fp)) {
- if (!parse_config_line(fp, buf, tmp_ramdisk, tmp_levels)) {
+#ifdef notyet
+/*
+XXX Don't call read() in parse_config_line, read as callback or reassemble line
+at this level.
+OR: Forbid multiline stuff for alternate config sources.
+*/
+#endif
+ if (!parse_config_line(fp, buf, tmp_ramdisk, tmp_levels, src)) {
raw_printf("Bad option line: \"%.50s\"", buf);
wait_synch();
}
{ "windowcolors", "the foreground/background colors of windows", /*WC*/
80, DISP_IN_GAME },
{ "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
+#ifdef SYSCF
+ { "wizards", "users with access to wizard mode (etc)", PL_PSIZ, SET_IN_SYS},
+#endif
#ifdef BACKWARD_COMPAT
{"DECgraphics", "load DECGraphics display symbols", 70, SET_IN_FILE},
{"IBMgraphics", "load IBMGraphics display symbols", 70, SET_IN_FILE},
return (char *)0;
}
+/* Split initoptions into 2 parts for SYSCF but don't break anything not
+ * using SYSCF. */
+void
+initoptions(){
+ initoptions_init();
+ initoptions_finish();
+}
+
void
-initoptions()
+initoptions_init()
{
#ifndef MAC
char *opts;
/* since this is done before init_objects(), do partial init here */
objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
+}
+void
+initoptions_finish(){
#ifndef MAC
- opts = getenv("NETHACKOPTIONS");
+ char *opts = getenv("NETHACKOPTIONS");
if (!opts) opts = getenv("HACKOPTIONS");
if (opts) {
if (*opts == '/' || *opts == '\\' || *opts == '@') {
if (*opts == '@') opts++; /* @filename */
/* looks like a filename */
if (strlen(opts) < BUFSZ/2)
- read_config_file(opts);
+ read_config_file(opts, SET_IN_FILE);
} else {
- read_config_file((char *)0);
+ read_config_file((char *)0, SET_IN_FILE);
/* let the total length of options be long;
* parseoptions() will check each individually
*/
}
} else
#endif
- read_config_file((char *)0);
+ read_config_file((char *)0, SET_IN_FILE);
(void)fruitadd(pl_fruit);
/* Remove "slime mold" from list of object names; this will */
return;
}
+#ifdef SYSCF
+ fullname = "wizards";
+ if (wizard && match_optname(opts, fullname, 6, TRUE)) {
+ if (duplicate) {
+ complain_about_duplicate(opts,1);
+ return;
+ }
+ if (negated) {
+ bad_negation(fullname, FALSE);
+ return;
+ } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+ nmcpy(wizards, op, PL_PSIZ);
+ }
+ return;
+ }
+#endif
+
/* menustyle:traditional or combo or full or partial */
if (match_optname(opts, "menustyle", 4, TRUE)) {
int tmp;
"Compounds (selecting will prompt for new value):",
MENU_UNSELECTED);
+#ifdef notyet /* SYSCF */
+/* XXX I think this is still fragile. Fixing initial/from_file and/or changing
+ the SET_* etc to bitmaps will let me make this better. */
+ if(wizard)
+ startpass = SET_IN_SYS;
+ else
+#endif
startpass = DISP_IN_GAME;
endpass = SET_IN_GAME;
#endif
else if (!strcmp(optname, "catname"))
Sprintf(buf, "%s", catname[0] ? catname : none );
+#ifdef SYSCF
+ else if (!strcmp(optname, "wizards"))
+# ifdef KR1ED
+ Sprintf(buf, "%s", wizards[0] ? wizards : WIZARD_NAME);
+# else
+ Sprintf(buf, "%s", wizards[0] ? wizards : WIZARD);
+# endif
+#endif
else if (!strcmp(optname, "disclose")) {
for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
char topt[2];
{(char *)0, 0L}
};
-
/*
- * If a port wants to change or ensure that the
+ * If a port wants to change or ensure that the SET_IN_SYS,
* SET_IN_FILE, DISP_IN_GAME, or SET_IN_GAME status of an option is
* correct (for controlling its display in the option menu) call
* set_option_mod_status()
- * with the second argument of 0,2, or 3 respectively.
+ * with the appropriate second argument.
*/
void
set_option_mod_status(optnam, status)
int status;
{
int k;
- if (status < SET_IN_FILE || status > SET_IN_GAME) {
+ if ( SET__IS_VALUE_VALID(status) ) {
impossible("set_option_mod_status: status out of range %d.",
status);
return;
int status;
{
int k = 0;
- if (status < SET_IN_FILE || status > SET_IN_GAME) {
+ if ( SET__IS_VALUE_VALID(status) ) {
impossible("set_wc_option_mod_status: status out of range %d.",
status);
return;
int status;
{
int k = 0;
- if (status < SET_IN_FILE || status > SET_IN_GAME) {
+ if ( SET__IS_VALUE_VALID(status) ) {
impossible("set_wc2_option_mod_status: status out of range %d.",
status);
return;
a game that was in progress. The recover command is installed in the
HACKDIR by default.
+9. If you specified SYSCF (and SYSCF_FILE) in config.h, create the file
+ defined as SYSCF_FILE and fill in any of the following values if you
+ wish to override the compiled-in defaults:
+ WIZARDS= a space-separated list of usernames who can use -D
+ If the first character is '*' then any user can use -D.
+ This is a standards config file, so blank lines and lines starting with
+ pound signs are ignored; while other, standard options (such as catname)
+ can be specified in this file, this is considered a bug and may be changed
+ in the future.
+
Notes:
1. Save files and bones files from previous versions will not work with
#PREFIX = /usr
GAME = nethack
# GAME = nethack.prg
-GAMEUID = games
-GAMEGRP = bin
+#GAMEUID = games
+#GAMEGRP = bin
# Permissions - some places use setgid instead of setuid, for instance
# See also the option "SECURE" in include/config.h
-GAMEPERM = 04755
+#GAMEPERM = 04755
FILEPERM = 0644
+# VARFILEPERM = 0644
EXEPERM = 0755
DIRPERM = 0755
+# VARDIRPERM = 0755
# VARDIR may also appear in unixconf.h as "VAR_PLAYGROUND" else HACKDIR
#
@echo You may also want to install the man pages via the doc Makefile.
install: $(GAME) recover $(VARDAT) dungeon spec_levs
+ true; $(PREINSTALL)
# set up the directories
# not all mkdirs have -p; those that don't will create a -p directory
-mkdir -p $(SHELLDIR)
-rmdir ./-p
-$(CHOWN) $(GAMEUID) $(HACKDIR) $(VARDIR) $(VARDIR)/save
$(CHGRP) $(GAMEGRP) $(HACKDIR) $(VARDIR) $(VARDIR)/save
- chmod $(DIRPERM) $(HACKDIR) $(VARDIR) $(VARDIR)/save
+# order counts here:
+ chmod $(DIRPERM) $(HACKDIR)
+ chmod $(VARDIRPERM) $(VARDIR) $(VARDIR)/save
# set up the game files
( $(MAKE) dofiles )
# set up some additional files
touch $(VARDIR)/perm $(VARDIR)/record $(VARDIR)/logfile
-( cd $(VARDIR) ; $(CHOWN) $(GAMEUID) perm record logfile ; \
$(CHGRP) $(GAMEGRP) perm record logfile ; \
- chmod $(FILEPERM) perm record logfile )
+ chmod $(VARFILEPERM) perm record logfile )
true; $(POSTINSTALL)
# and a reminder
@echo You may also want to reinstall the man pages via the doc Makefile.
CHOWN=true
CHGRP=true
+
+VARDIRPERM = 0755
CHOWN=true
CHGRP=true
+VARDIRPERM = 0755
POSTINSTALL= bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; (cd $(HACKDIR); mkfontdir)
CHOWN=true
CHGRP=true
+VARDIRPERM = 0755
--- /dev/null
+#
+# SCCS Id: @(#)macosx-mu 3.5 2007/12/12
+# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007.
+# NetHack may be freely redistributed. See license for details.
+#
+# Mac OS X (Darwin) hints file
+# This is for Mac OS X 10.4.10 (Darwin 8.10). If this doesn't work for some
+# other version of either Darwin or Mac OS X, make a new file for that OS,
+# don't change this one.
+# Useful info: http://www.opensource.apple.com/darwinsource/index.html
+
+# This is a tty build for a system with multiple users (since it is a tty
+# build it does not try to look like a .app application).
+# NetHack will be owned by user "games" and group "bin" - change the next 2
+# lines if this is a problem:
+GAMEUID = games
+GAMEGRP = bin
+# NB: "make install" should be run as an admin user:
+# sudo make install
+
+# NB: do NOT use $(wildcard ~$(GAMEUID)) since the user may not exist yet.
+PREFIX:=/Users/$(GAMEUID)
+SHELLDIR=$(PREFIX)/bin
+HACKDIR=$(PREFIX)/nethackdir
+
+CC=gcc -W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN
+
+# XXX -g vs -O should go here, -I../include goes in the makefile
+CFLAGS=-g -I../include $(CFLAGS2) $(CFLAGS3)
+CFLAGS2=-DNOCLIPPING -DNOMAIL -DNOTPARMDECL -DHACKDIR=\"$(HACKDIR)\"
+CFLAGS3=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE
+
+WINSRC = $(WINTTYSRC)
+WINOBJ = $(WINTTYOBJ)
+WINLIB = $(WINTTYLIB)
+
+WINTTYLIB=-lncurses
+
+CHOWN=chown
+CHGRP=chgrp
+
+# We run sgid so the game has access to both HACKDIR and user preferences.
+GAMEPERM = 02755
+VARFILEPERM = 0664
+VARDIRPERM = 0775
+
+# make sure we have group GAMEUID and group GAMEGRP
+PREINSTALL= . sys/unix/hints/macosx.sh user $(GAMEUID); . sys/unix/hints/macosx.sh group $(GAMEGRP); mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR)
+POSTINSTALL= touch $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf
+
+
+# notes:
+#1) ~games/games is owned by root.
+#2) group games exists because user games was created via Accounts pane.
+#3) who should own/be able to run recover?
WINSRC = $(WINX11SRC)
WINOBJ = $(WINX11OBJ)
WINLIB = $(WINX11LIB)
+VARDIRPERM = 0755
VARDATND = x11tiles NetHack.ad pet_mark.xbm
--- /dev/null
+#!/bin/sh
+# SCCS Id: @(#)macosx-mu.sh 3.5 2007/12/12
+# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007.
+# NetHack may be freely redistributed. See license for details.
+#
+# hints helper script for macosx
+# DO NOT invoke directly
+
+cmd=$1
+
+case "x$cmd" in
+xuser)
+ user=$2
+ gotuser=`niutil -readval . /users/$user name 0 2>/dev/null`
+ [ -z $gotuser ] && (echo "User $user does not exist."
+ exit 1;
+ )
+ exit 0
+ ;;
+#name: dummy1
+#_writers_passwd: dummy1
+#_writers_tim_password: dummy1
+#_writers_picture: dummy1
+#home: /Users/dummy1
+#gid: 504
+#picture: /Library/User Pictures/Animals/Dragonfly.tif
+#uid: 504
+#hint: dummy1
+#_writers_hint: dummy1
+#sharedDir:
+#_shadow_passwd:
+#_writers_realname: dummy1
+#shell: /bin/bash
+#passwd: ********
+#authentication_authority: ;ShadowHash;
+#realname: dummyname1
+#generateduid: F6D4991C-BDF5-481F-A407-D84C6A2D0E2A
+xgroup)
+ group=$2
+ gotgrp=`niutil -readval . /groups/$group name 0 2>/dev/null`
+ [ -z $gotgrp ] && ( echo "Group $group does not exist."
+ exit 1
+ )
+ exit 0
+ ;;
+#niutil -read . /groups/bin name 0
+#name: bin
+#gid: 7
+#passwd: *
+#generateduid: ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000007
+#smb_sid: S-1-5-21-107
+#realname: Binary
+
+*) echo "Unknown command $cmd"
+ exit 1
+ ;;
+esac
CHOWN=chown
CHGRP=chgrp
+
+GAMEUID = games
+GAMEGRP = bin
+
+GAMEPERM = 04755
+VARFILEPERM = 0644
+VARDIRPERM = 0755
if (!strncmp(argv[1], "-s", 2) && strncmp(argv[1], "-style", 6)) {
#ifdef CHDIR
chdirx(dir,0);
+#endif
+#ifdef SYSCF
+ initoptions_init();
+ read_config_file(SYSCF_FILE, SET_IN_SYS);
+ initoptions_finish();
#endif
prscore(argc, argv);
exit(EXIT_SUCCESS);
#ifdef __linux__
check_linux_console();
#endif
- initoptions();
+ initoptions_init();
+#ifdef SYSCF
+ read_config_file(SYSCF_FILE, SET_IN_SYS);
+#endif
+ initoptions_finish();
exact_username = whoami();
/*
pw = getpwuid(uid);
}
}
+#ifdef SYSCF
+ if (pw && wizards[0]) {
+ if(wizards[0] == '*') return TRUE; /*allow any user to be wizard*/
+ int pwlen = strlen(pw->pw_name);
+ char *eop = eos(wizards);
+ char *w = wizards;
+ while( w+pwlen <= eop ){
+ if( ! *w ) break;
+ if( isspace(*w) ){ w++; continue;}
+ if( !strncmp(w, pw->pw_name, pwlen) ){
+ if( !w[pwlen] || isspace(w[pwlen]) ) return TRUE;
+ }
+ while( *w && !isspace(*w) ) w++;
+ }
+ } else
+#endif
if (pw && !strcmp(pw->pw_name, WIZARD_NAME)) return TRUE;
#endif /* WIZARD */
return FALSE;