Add recordfile control to SYSCF.

Add sys/unix/sysconf, a sample sysconf file.
Move defines from topten.c to config.h so they can be seen globally.
Add persmax, pers_is_uid, entrymax, and pointsmin to struct sysopt, use
 in topten.c, populate in files.c
Warning cleanup in files.c.
BUGFIX: don't crash in unixmain.c if WIZARDS left unspecified.
hints/macosx10.5: don't hardcode "keni"; install sample sysconf; install
 sample ~/nethackrc
makedefs: add "system configuration" to compiled-with options list.
BUGFIX: if a game doesn't meet the criteria for making the record file it's
 shown to the user as having zero points because t1->points is set to zero
 to indicate that it doesn't get written back; display u.urexp instead.
This commit is contained in:
keni
2009-05-03 14:08:15 +00:00
parent ce89e6dc33
commit 8593cf6547
10 changed files with 146 additions and 40 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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,

View File

@@ -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");
}

View File

@@ -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 ",

View File

@@ -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

View File

@@ -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

37
sys/unix/sysconf Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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"