diff --git a/include/config.h b/include/config.h index 5509d5356..a7514b1e1 100644 --- a/include/config.h +++ b/include/config.h @@ -155,6 +155,11 @@ * SUPPORT (how to get local support)(no default) * RECOVER (how to recover a game at your site)(no default) * SHELLERS (who can use !, syntax as WIZARDS) + * for the record file (see topten.c): + * PERSMAX (max entries for one person) + * ENTRYMAX (max entries in the record file) + * POINTSMIN (min points to get an entry) + * PERS_IS_UID (0 or 1 - person is name or (numeric) userid) * * The following options select how the config space is stored: * SYSCF_FILE in the named file @@ -175,6 +180,27 @@ #define NEWS "news" /* the file containing the latest hack news */ #define PANICLOG "paniclog" /* log of panic and impossible events */ +#ifndef PERSMAX +# define PERSMAX 3 /* entries per name/uid per char. allowed */ +#endif +#ifndef POINTSMIN +# define POINTSMIN 1 /* must be > 0 */ +#endif +#ifndef ENTRYMAX +# define ENTRYMAX 100 /* must be >= 10 */ +#endif +#ifndef PERS_IS_UID +# define PERS_IS_UID 1 /* delete for PERSMAX per name; now per uid */ +#endif +#ifndef PERS_IS_UID +# if !defined(MICRO) && !defined(MAC) && !defined(WIN32) +# define PERS_IS_UID 1 /* delete for PERSMAX per name; now per uid */ +# else +# define PERS_IS_UID 0 +# endif +#endif + + /* * If COMPRESS is defined, it should contain the full path name of your * 'compress' program. diff --git a/include/sys.h b/include/sys.h index 587fb01bb..a5a2e925e 100644 --- a/include/sys.h +++ b/include/sys.h @@ -15,6 +15,11 @@ struct sysopt { char *wizards; char *shellers; /* like wizards, for ! command (-DSHELL) */ int maxplayers; + /* record file */ + int persmax; + int pers_is_uid; + int entrymax; + int pointsmin; }; E struct sysopt sysopt; diff --git a/src/files.c b/src/files.c index 6537a54bd..2db4e8424 100644 --- a/src/files.c +++ b/src/files.c @@ -2068,19 +2068,19 @@ int src; #ifdef SYSCF } else if ( (src==SET_IN_SYS) && match_varname(buf, "WIZARDS", 7)) { if(sysopt.wizards) free(sysopt.wizards); - sysopt.wizards = alloc(strlen(bufp)+1); + sysopt.wizards = (char*)alloc(strlen(bufp)+1); Strcpy(sysopt.wizards, bufp); } else if ( (src==SET_IN_SYS) && match_varname(buf, "SHELLERS", 8)) { if(sysopt.shellers) free(sysopt.shellers); - sysopt.shellers = alloc(strlen(bufp)+1); + sysopt.shellers = (char*)alloc(strlen(bufp)+1); Strcpy(sysopt.shellers, bufp); } else if ( (src==SET_IN_SYS) && match_varname(buf, "SUPPORT", 7)) { if(sysopt.support) free(sysopt.support); - sysopt.support = alloc(strlen(bufp)+1); + sysopt.support = (char*)alloc(strlen(bufp)+1); Strcpy(sysopt.support, bufp); } else if ( (src==SET_IN_SYS) && match_varname(buf, "RECOVER", 7)) { if(sysopt.recover) free(sysopt.recover); - sysopt.recover = alloc(strlen(bufp)+1); + sysopt.recover = (char*)alloc(strlen(bufp)+1); Strcpy(sysopt.recover, bufp); } else if ( (src==SET_IN_SYS) && match_varname(buf, "MAXPLAYERS", 10)) { int temp = atoi(bufp); @@ -2091,6 +2091,34 @@ int src; raw_printf("Illegal value in MAXPLAYERS."); return 0; } + } else if ( (src==SET_IN_SYS) && match_varname(buf, "PERSMAX", 7)) { + int temp = atoi(bufp); + if(temp < 1){ + raw_printf("Illegal value in PERSMAX (minimum is 1)."); + return 0; + } + sysopt.persmax = temp; + } else if ( (src==SET_IN_SYS) && match_varname(buf, "PERS_IS_UID", 11)) { + int temp = atoi(bufp); + if(temp != 0 && temp != 1){ + raw_printf("Illegal value in PERS_IS_UID (must be 0 or 1)."); + return 0; + } + sysopt.pers_is_uid = temp; + } else if ( (src==SET_IN_SYS) && match_varname(buf, "ENTRYMAX", 8)) { + int temp = atoi(bufp); + if(temp < 10){ + raw_printf("Illegal value in ENTRYMAX (minimum is 10)."); + return 0; + } + sysopt.entrymax = temp; + } else if ( (src==SET_IN_SYS) && match_varname(buf, "POINTSMIN", 9)) { + int temp = atoi(bufp); + if(temp < 1){ + raw_printf("Illegal value in POINTSMIN (minimum is 1)."); + return 0; + } + sysopt.pointsmin = temp; #endif } else if (match_varname(buf, "BOULDER", 3)) { (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, diff --git a/src/sys.c b/src/sys.c index 2575d6624..b0174ae6d 100644 --- a/src/sys.c +++ b/src/sys.c @@ -16,5 +16,18 @@ sys_early_init(){ sysopt.wizards = NULL; sysopt.shellers = NULL; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ + + /* record file */ + sysopt.persmax = PERSMAX; + sysopt.entrymax = ENTRYMAX; + sysopt.pointsmin = POINTSMIN; + sysopt.pers_is_uid = PERS_IS_UID; + + /* sanity checks */ + if(PERSMAX<1) sysopt.persmax = 1; + if(ENTRYMAX<10) sysopt.entrymax = 10; + if(POINTSMIN<1) sysopt.pointsmin = 1; + if(PERS_IS_UID != 0 && PERS_IS_UID != 1) + die("config error: PERS_IS_UID must be either 0 or 1"); } diff --git a/src/topten.c b/src/topten.c index 4d3a20c47..64631d454 100644 --- a/src/topten.c +++ b/src/topten.c @@ -33,13 +33,7 @@ static long final_fpos; #define NAMSZ 10 #define DTHSZ 100 #define ROLESZ 3 -#define PERSMAX 3 /* entries per name/uid per char. allowed */ -#define POINTSMIN 1 /* must be > 0 */ -#define ENTRYMAX 100 /* must be >= 10 */ -#if !defined(MICRO) && !defined(MAC) && !defined(WIN32) -#define PERS_IS_UID /* delete for PERSMAX per name; now per uid */ -#endif struct toptenentry { struct toptenentry *tt_next; #ifdef UPDATE_RECORD_IN_PLACE @@ -282,7 +276,7 @@ int how; { int uid = getuid(); int rank, rank0 = -1, rank1 = 0; - int occ_cnt = PERSMAX; + int occ_cnt = sysopt.persmax; register struct toptenentry *t0, *tprev; struct toptenentry *t1; FILE *rfile; @@ -411,14 +405,14 @@ int how; HUP topten_print(""); /* assure minimum number of points */ - if(t0->points < POINTSMIN) t0->points = 0; + if(t0->points < sysopt.pointsmin) t0->points = 0; t1 = tt_head = newttentry(); tprev = 0; /* rank0: -1 undefined, 0 not_on_list, n n_th on list */ for(rank = 1; ; ) { readentry(rfile, t1); - if (t1->points < POINTSMIN) t1->points = 0; + if (t1->points < sysopt.pointsmin) t1->points = 0; if(rank0 < 0 && t1->points < t0->points) { rank0 = rank++; if(tprev == 0) @@ -436,11 +430,10 @@ int how; if(t1->points == 0) break; if( -#ifdef PERS_IS_UID - t1->uid == t0->uid && -#else - strncmp(t1->name, t0->name, NAMSZ) == 0 && -#endif + (sysopt.pers_is_uid + ? t1->uid == t0->uid + : strncmp(t1->name, t0->name, NAMSZ) == 0 + ) && !strncmp(t1->plrole, t0->plrole, ROLESZ) && --occ_cnt <= 0) { if(rank0 < 0) { @@ -460,12 +453,12 @@ int how; continue; } } - if(rank <= ENTRYMAX) { + if(rank <= sysopt.entrymax) { t1->tt_next = newttentry(); t1 = t1->tt_next; rank++; } - if(rank > ENTRYMAX) { + if(rank > sysopt.entrymax) { t1->points = 0; break; } @@ -490,7 +483,7 @@ int how; char pbuf[BUFSZ]; Sprintf(pbuf, "You reached the %d%s place on the top %d list.", - rank0, ordin(rank0), ENTRYMAX); + rank0, ordin(rank0), sysopt.entrymax); topten_print(pbuf); } topten_print(""); @@ -511,11 +504,10 @@ int how; (rank < rank0 - flags.end_around || rank > rank0 + flags.end_around) && (!flags.end_own || -#ifdef PERS_IS_UID - t1->uid != t0->uid -#else - strncmp(t1->name, t0->name, NAMSZ) -#endif + (sysopt.pers_is_uid + ? t1->uid == t0->uid + : strncmp(t1->name, t0->name, NAMSZ) == 0 + ) )) continue; if (rank == rank0 - flags.end_around && rank0 > flags.end_top + flags.end_around + 1 && @@ -597,7 +589,8 @@ boolean so; if (rank) Sprintf(eos(linebuf), "%3d", rank); else Strcat(linebuf, " "); - Sprintf(eos(linebuf), " %10ld %.10s", t1->points, t1->name); + Sprintf(eos(linebuf), " %10ld %.10s", t1->points?t1->points:u.urexp, + t1->name); Sprintf(eos(linebuf), "-%s", t1->plrole); if (t1->plrace[0] != '?') Sprintf(eos(linebuf), "-%s", t1->plrace); @@ -740,10 +733,8 @@ int uid; t1->patchlevel != PATCHLEVEL)) return 0; -#ifdef PERS_IS_UID - if (!playerct && t1->uid == uid) + if (sysopt.pers_is_uid && !playerct && t1->uid == uid) return 1; -#endif for (i = 0; i < playerct; i++) { if (players[i][0] == '-' && index("pr", players[i][1]) && @@ -785,9 +776,7 @@ char **argv; register int i; char pbuf[BUFSZ]; int uid = -1; -#ifndef PERS_IS_UID const char *player0; -#endif if (argc < 2 || strncmp(argv[1], "-s", 2)) { raw_printf("prscore: bad arguments (%d)", argc); @@ -828,11 +817,11 @@ char **argv; } if (argc <= 1) { -#ifdef PERS_IS_UID + if(sysopt.pers_is_uid){ uid = getuid(); playerct = 0; players = (const char **)0; -#else + } else { player0 = plname; if (!*player0) # ifdef AMIGA @@ -842,7 +831,7 @@ char **argv; # endif playerct = 1; players = &player0; -#endif + } } else { playerct = --argc; players = (const char **)++argv; @@ -871,7 +860,7 @@ char **argv; t1 = tt_head; for (rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) { if (score_wanted(current_ver, rank, t1, playerct, players, uid)) - (void) outentry(rank, t1, 0); + (void) outentry(rank, t1, FALSE); } } else { Sprintf(pbuf, "Cannot find any %sentries for ", diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index f328f741e..080376a37 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -31,6 +31,9 @@ If you are using the traditional configuration system, see Install.unx. 4. Install: Depending on your configuration, this step may or may not need to be done as root; check the hints file. + NB: "make install" deletes nethackdir and recreates it from scratch - so + if you want the record, logfile, or sysconf files, you must save and + restore them manually. cd $Top make install diff --git a/sys/unix/hints/macosx10.5 b/sys/unix/hints/macosx10.5 index e0225f3c5..e487f58f7 100644 --- a/sys/unix/hints/macosx10.5 +++ b/sys/unix/hints/macosx10.5 @@ -46,7 +46,7 @@ endif # Consider a non-shared install (WANT_SHARE_INSTALL=0) instead. # - 'make install' must be run as "sudo make install" #WANT_SHARE_INSTALL=1 -GAMEUID = keni +GAMEUID = $(USER) GAMEGRP = games #CC=gcc -W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN @@ -128,9 +128,10 @@ endif VARFILEPERM = 0664 VARDIRPERM = 0775 ROOTCHECK= [[ `id -u` == 0 ]] || ( echo "Must run install with sudo."; exit 1) +# XXX it's nice we don't write over sysconf, but we've already erased it # make sure we have group GAMEUID and group GAMEGRP PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); . sys/unix/hints/macosx.sh group2 $(GAMEGRP); mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) -POSTINSTALL= touch $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf +POSTINSTALL= cp -n sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE else PREFIX:=$(wildcard ~) @@ -142,7 +143,8 @@ GAMEPERM = 0700 VARFILEPERM = 0600 VARDIRPERM = 0700 ifdef WANT_WIN_X11 -# XXX install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists +# install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists +PREINSTALL= cp -n win/X11/nethack.rc ~/.nethackrc endif endif diff --git a/sys/unix/sysconf b/sys/unix/sysconf new file mode 100644 index 000000000..6b8e71fdd --- /dev/null +++ b/sys/unix/sysconf @@ -0,0 +1,37 @@ +# +# NetHack 3.5 sysconf $Date$ $Revision$ +# +# Sample sysconf file. +# The sysconf file is only used if NetHack is compiled with SYSCF defined. +# This file uses the same syntax as nethack.cf. + +# Which users can use WIZARD (debugging) mode (the -D flag). +# A value of * allows anyone to enter debugging mode. +WIZARDS=root,games + +# Users allowed to use the ! (shell escape) command. Uses the same syntax +# as the WIZARDS option above. +#SHELLERS= + +# Limit the number of simultaneous games (see also and nethack.sh). +MAXPLAYERS=10 + +# If not null, added to string "To get local support, " in the support +# information help. +#SUPPORT=call Izchak at extension 42. + +# If not null, displayed at the end of a panic-save sequence. +#RECOVER=Run the recover program. + +# Record (high score) file options. +# CAUTION: changing these after people have started playing games can +# lead to lost high scores! +# Maximum entries for one persion. +#PERSMAX=10 +# Maximum entries in the record file. +#ENTRYMAX=100 +# Minimum points to get an entry. +#POINTSMIN=1 +# Determine identity of "person" in the score file with name (0) or +# numeric (1) user id. +#PERS_IS_UID=1 diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 4a70d666d..1fa145909 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -549,7 +549,7 @@ authorize_wizard_mode() #ifdef WIZARD struct passwd *pw = get_unix_pw(); #ifdef SYSCF - if (pw && sysopt.wizards[0]) { + if (pw && sysopt.wizards && sysopt.wizards[0]) { if(check_user_string(sysopt.wizards)) return TRUE; } else #endif diff --git a/util/makedefs.c b/util/makedefs.c index c8b82c3d1..e0cdcbd48 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1288,6 +1288,9 @@ static const char *build_opts[] = { #endif #ifdef RLECOMP "run-length compression of map in save files", +#endif +#ifdef SYSCF + "system configuration", #endif save_bones_compat_buf, "basic NetHack features"