xref: /dflybsd-src/games/hunt/huntd/conf.c (revision d9f85b3315fdf3905eee2057d79dd723366a8bf6)
16693db17SSascha Wildner /*-
282a5c12eSMatthew Dillon  * David Leonard <d@openbsd.org>, 1999. Public domain.
382a5c12eSMatthew Dillon  *
482a5c12eSMatthew Dillon  * $OpenBSD: conf.c,v 1.7 2007/03/20 03:43:50 tedu Exp $
582a5c12eSMatthew Dillon  */
682a5c12eSMatthew Dillon #include <sys/param.h>
782a5c12eSMatthew Dillon #include <sys/types.h>
882a5c12eSMatthew Dillon #include <stdio.h>
982a5c12eSMatthew Dillon #include <string.h>
1082a5c12eSMatthew Dillon #include <dirent.h>
1182a5c12eSMatthew Dillon #include <stdlib.h>
1282a5c12eSMatthew Dillon #include <ctype.h>
1382a5c12eSMatthew Dillon #include <syslog.h>
1482a5c12eSMatthew Dillon #include <errno.h>
1582a5c12eSMatthew Dillon 
1682a5c12eSMatthew Dillon #include "hunt.h"
1782a5c12eSMatthew Dillon #include "server.h"
1882a5c12eSMatthew Dillon #include "conf.h"
1982a5c12eSMatthew Dillon 
2082a5c12eSMatthew Dillon /* Configuration option variables for the server: */
2182a5c12eSMatthew Dillon 
2282a5c12eSMatthew Dillon int conf_random =	1;
2382a5c12eSMatthew Dillon int conf_reflect =	1;
2482a5c12eSMatthew Dillon int conf_monitor =	1;
2582a5c12eSMatthew Dillon int conf_ooze =		1;
2682a5c12eSMatthew Dillon int conf_fly =		1;
2782a5c12eSMatthew Dillon int conf_volcano =	1;
2882a5c12eSMatthew Dillon int conf_drone =	1;
2982a5c12eSMatthew Dillon int conf_boots =	1;
3082a5c12eSMatthew Dillon int conf_scan =		1;
3182a5c12eSMatthew Dillon int conf_cloak =	1;
3282a5c12eSMatthew Dillon int conf_logerr =	1;
3382a5c12eSMatthew Dillon int conf_syslog =	0;
3482a5c12eSMatthew Dillon 
3582a5c12eSMatthew Dillon int conf_scoredecay =	15;
3682a5c12eSMatthew Dillon int conf_maxremove =	40;
3782a5c12eSMatthew Dillon int conf_linger =	90;
3882a5c12eSMatthew Dillon 
3982a5c12eSMatthew Dillon int conf_flytime =	20;
4082a5c12eSMatthew Dillon int conf_flystep =	5;
4182a5c12eSMatthew Dillon int conf_volcano_max =	50;
4282a5c12eSMatthew Dillon int conf_ptrip_face =	2;
4382a5c12eSMatthew Dillon int conf_ptrip_back =	95;
4482a5c12eSMatthew Dillon int conf_ptrip_side =	50;
4582a5c12eSMatthew Dillon int conf_prandom =	1;
4682a5c12eSMatthew Dillon int conf_preflect =	1;
4782a5c12eSMatthew Dillon int conf_pshot_coll =	5;
4882a5c12eSMatthew Dillon int conf_pgren_coll =	10;
4982a5c12eSMatthew Dillon int conf_pgren_catch =	10;
5082a5c12eSMatthew Dillon int conf_pmiss =	5;
5182a5c12eSMatthew Dillon int conf_pdroneabsorb =	1;
5282a5c12eSMatthew Dillon int conf_fall_frac =	5;
5382a5c12eSMatthew Dillon 
5482a5c12eSMatthew Dillon int conf_bulspd =	5;
5582a5c12eSMatthew Dillon int conf_ishots =	15;
5682a5c12eSMatthew Dillon int conf_nshots =	5;
5782a5c12eSMatthew Dillon int conf_maxncshot =	2;
5882a5c12eSMatthew Dillon int conf_maxdam =	10;
5982a5c12eSMatthew Dillon int conf_mindam =	5;
6082a5c12eSMatthew Dillon int conf_stabdam =	2;
6182a5c12eSMatthew Dillon int conf_killgain =	2;
6282a5c12eSMatthew Dillon int conf_slimefactor =	3;
6382a5c12eSMatthew Dillon int conf_slimespeed =	5;
6482a5c12eSMatthew Dillon int conf_lavaspeed =	1;
6582a5c12eSMatthew Dillon int conf_cloaklen =	20;
6682a5c12eSMatthew Dillon int conf_scanlen =	20;
6782a5c12eSMatthew Dillon int conf_mindshot =	2;
6882a5c12eSMatthew Dillon int conf_simstep =	0;
6982a5c12eSMatthew Dillon 
7082a5c12eSMatthew Dillon 
7182a5c12eSMatthew Dillon struct kwvar {
7282a5c12eSMatthew Dillon 	const char *	kw;
7382a5c12eSMatthew Dillon 	void *	var;
7482a5c12eSMatthew Dillon 	enum vartype { Vint, Vchar, Vstring, Vdouble } type;
7582a5c12eSMatthew Dillon };
7682a5c12eSMatthew Dillon 
7782a5c12eSMatthew Dillon static struct kwvar keywords[] = {
7882a5c12eSMatthew Dillon 	{ "random",		&conf_random,		Vint },
7982a5c12eSMatthew Dillon 	{ "reflect",		&conf_reflect,		Vint },
8082a5c12eSMatthew Dillon 	{ "monitor",		&conf_monitor,		Vint },
8182a5c12eSMatthew Dillon 	{ "ooze",		&conf_ooze,		Vint },
8282a5c12eSMatthew Dillon 	{ "fly",		&conf_fly,		Vint },
8382a5c12eSMatthew Dillon 	{ "volcano",		&conf_volcano,		Vint },
8482a5c12eSMatthew Dillon 	{ "drone",		&conf_drone,		Vint },
8582a5c12eSMatthew Dillon 	{ "boots",		&conf_boots,		Vint },
8682a5c12eSMatthew Dillon 	{ "scan",		&conf_scan,		Vint },
8782a5c12eSMatthew Dillon 	{ "cloak",		&conf_cloak,		Vint },
8882a5c12eSMatthew Dillon 	{ "logerr",		&conf_logerr,		Vint },
8982a5c12eSMatthew Dillon 	{ "syslog",		&conf_syslog,		Vint },
9082a5c12eSMatthew Dillon 	{ "scoredecay",		&conf_scoredecay,	Vint },
9182a5c12eSMatthew Dillon 	{ "maxremove",		&conf_maxremove,	Vint },
9282a5c12eSMatthew Dillon 	{ "linger",		&conf_linger,		Vint },
9382a5c12eSMatthew Dillon 
9482a5c12eSMatthew Dillon 	{ "flytime",		&conf_flytime,		Vint },
9582a5c12eSMatthew Dillon 	{ "flystep",		&conf_flystep,		Vint },
9682a5c12eSMatthew Dillon 	{ "volcano_max",	&conf_volcano_max,	Vint },
9782a5c12eSMatthew Dillon 	{ "ptrip_face",		&conf_ptrip_face,	Vint },
9882a5c12eSMatthew Dillon 	{ "ptrip_back",		&conf_ptrip_back,	Vint },
9982a5c12eSMatthew Dillon 	{ "ptrip_side",		&conf_ptrip_side,	Vint },
10082a5c12eSMatthew Dillon 	{ "prandom",		&conf_prandom,		Vint },
10182a5c12eSMatthew Dillon 	{ "preflect",		&conf_preflect,		Vint },
10282a5c12eSMatthew Dillon 	{ "pshot_coll",		&conf_pshot_coll,	Vint },
10382a5c12eSMatthew Dillon 	{ "pgren_coll",		&conf_pgren_coll,	Vint },
10482a5c12eSMatthew Dillon 	{ "pgren_catch",	&conf_pgren_catch,	Vint },
10582a5c12eSMatthew Dillon 	{ "pmiss",		&conf_pmiss,		Vint },
10682a5c12eSMatthew Dillon 	{ "pdroneabsorb",	&conf_pdroneabsorb,	Vint },
10782a5c12eSMatthew Dillon 	{ "fall_frac",		&conf_fall_frac,	Vint },
10882a5c12eSMatthew Dillon 
10982a5c12eSMatthew Dillon 	{ "bulspd",		&conf_bulspd,		Vint },
11082a5c12eSMatthew Dillon 	{ "ishots",		&conf_ishots,		Vint },
11182a5c12eSMatthew Dillon 	{ "nshots",		&conf_nshots,		Vint },
11282a5c12eSMatthew Dillon 	{ "maxncshot",		&conf_maxncshot,	Vint },
11382a5c12eSMatthew Dillon 	{ "maxdam",		&conf_maxdam,		Vint },
11482a5c12eSMatthew Dillon 	{ "mindam",		&conf_mindam,		Vint },
11582a5c12eSMatthew Dillon 	{ "stabdam",		&conf_stabdam,		Vint },
11682a5c12eSMatthew Dillon 	{ "killgain",		&conf_killgain,		Vint },
11782a5c12eSMatthew Dillon 	{ "slimefactor",	&conf_slimefactor,	Vint },
11882a5c12eSMatthew Dillon 	{ "slimespeed",		&conf_slimespeed,	Vint },
11982a5c12eSMatthew Dillon 	{ "lavaspeed",		&conf_lavaspeed,	Vint },
12082a5c12eSMatthew Dillon 	{ "cloaklen",		&conf_cloaklen,		Vint },
12182a5c12eSMatthew Dillon 	{ "scanlen",		&conf_scanlen,		Vint },
12282a5c12eSMatthew Dillon 	{ "mindshot",		&conf_mindshot,		Vint },
12382a5c12eSMatthew Dillon 	{ "simstep",		&conf_simstep,		Vint },
12482a5c12eSMatthew Dillon 
12582a5c12eSMatthew Dillon 	{ NULL, NULL, Vint }
12682a5c12eSMatthew Dillon };
12782a5c12eSMatthew Dillon 
12882a5c12eSMatthew Dillon static char *
parse_int(char * p,struct kwvar * kvp,const char * fnm,int * linep)12982a5c12eSMatthew Dillon parse_int(char *p, struct kwvar *kvp, const char *fnm, int *linep)
13082a5c12eSMatthew Dillon {
13182a5c12eSMatthew Dillon 	char *valuestart, *digitstart;
13282a5c12eSMatthew Dillon 	char savec;
13382a5c12eSMatthew Dillon 	int newval;
13482a5c12eSMatthew Dillon 
13582a5c12eSMatthew Dillon 	/* expect a number */
13682a5c12eSMatthew Dillon 	valuestart = p;
13782a5c12eSMatthew Dillon 	if (*p == '-')
13882a5c12eSMatthew Dillon 		p++;
13982a5c12eSMatthew Dillon 	digitstart = p;
14082a5c12eSMatthew Dillon 	while (isdigit(*p))
14182a5c12eSMatthew Dillon 		p++;
14282a5c12eSMatthew Dillon 	if ((*p == '\0' || isspace(*p) || *p == '#') && digitstart != p) {
14382a5c12eSMatthew Dillon 		savec = *p;
14482a5c12eSMatthew Dillon 		*p = '\0';
14582a5c12eSMatthew Dillon 		newval = atoi(valuestart);
14682a5c12eSMatthew Dillon 		*p = savec;
14782a5c12eSMatthew Dillon 		logx(LOG_INFO, "%s:%d: %s: %d -> %d",
14882a5c12eSMatthew Dillon 			fnm, *linep, kvp->kw, *(int *)kvp->var, newval);
14982a5c12eSMatthew Dillon 		*(int *)kvp->var = newval;
15082a5c12eSMatthew Dillon 		return p;
15182a5c12eSMatthew Dillon 	} else {
15282a5c12eSMatthew Dillon 		logx(LOG_ERR, "%s:%d: invalid integer value \"%s\"",
15382a5c12eSMatthew Dillon 		    fnm, *linep, valuestart);
15482a5c12eSMatthew Dillon 		return NULL;
15582a5c12eSMatthew Dillon 	}
15682a5c12eSMatthew Dillon }
15782a5c12eSMatthew Dillon 
15882a5c12eSMatthew Dillon static char *
parse_value(char * p,struct kwvar * kvp,const char * fnm,int * linep)15982a5c12eSMatthew Dillon parse_value(char *p, struct kwvar *kvp, const char *fnm, int *linep)
16082a5c12eSMatthew Dillon {
16182a5c12eSMatthew Dillon 
16282a5c12eSMatthew Dillon 	switch (kvp->type) {
16382a5c12eSMatthew Dillon 	case Vint:
16482a5c12eSMatthew Dillon 		return parse_int(p, kvp, fnm, linep);
16582a5c12eSMatthew Dillon 	case Vchar:
16682a5c12eSMatthew Dillon 	case Vstring:
16782a5c12eSMatthew Dillon 	case Vdouble:
16882a5c12eSMatthew Dillon 		/* tbd */
16982a5c12eSMatthew Dillon 	default:
17082a5c12eSMatthew Dillon 		abort();
17182a5c12eSMatthew Dillon 	}
17282a5c12eSMatthew Dillon }
17382a5c12eSMatthew Dillon 
17482a5c12eSMatthew Dillon static void
parse_line(char * buf,const char * fnm,int * line)17582a5c12eSMatthew Dillon parse_line(char *buf, const char *fnm, int *line)
17682a5c12eSMatthew Dillon {
17782a5c12eSMatthew Dillon 	char *p;
17882a5c12eSMatthew Dillon 	char *word;
17982a5c12eSMatthew Dillon 	char *endword;
18082a5c12eSMatthew Dillon 	struct kwvar *kvp;
18182a5c12eSMatthew Dillon 	char savec;
18282a5c12eSMatthew Dillon 
18382a5c12eSMatthew Dillon 	p = buf;
18482a5c12eSMatthew Dillon 
18582a5c12eSMatthew Dillon 	/* skip leading white */
18682a5c12eSMatthew Dillon 	while (isspace(*p))
18782a5c12eSMatthew Dillon 		p++;
18882a5c12eSMatthew Dillon 	/* allow blank lines and comment lines */
18982a5c12eSMatthew Dillon 	if (*p == '\0' || *p == '#')
19082a5c12eSMatthew Dillon 		return;
19182a5c12eSMatthew Dillon 
19282a5c12eSMatthew Dillon 	/* walk to the end of the word: */
19382a5c12eSMatthew Dillon 	word = p;
19482a5c12eSMatthew Dillon 	if (isalpha(*p) || *p == '_') {
19582a5c12eSMatthew Dillon 		p++;
19682a5c12eSMatthew Dillon 		while (isalpha(*p) || isdigit(*p) || *p == '_')
19782a5c12eSMatthew Dillon 			p++;
19882a5c12eSMatthew Dillon 	}
19982a5c12eSMatthew Dillon 	endword = p;
20082a5c12eSMatthew Dillon 
20182a5c12eSMatthew Dillon 	if (endword == word) {
20282a5c12eSMatthew Dillon 		logx(LOG_ERR, "%s:%d: expected variable name",
20382a5c12eSMatthew Dillon 			fnm, *line);
20482a5c12eSMatthew Dillon 		return;
20582a5c12eSMatthew Dillon 	}
20682a5c12eSMatthew Dillon 
20782a5c12eSMatthew Dillon 	/* match the configuration variable name */
20882a5c12eSMatthew Dillon 	savec = *endword;
20982a5c12eSMatthew Dillon 	*endword = '\0';
21082a5c12eSMatthew Dillon 	for (kvp = keywords; kvp->kw; kvp++)
21182a5c12eSMatthew Dillon 		if (strcmp(kvp->kw, word) == 0)
21282a5c12eSMatthew Dillon 			break;
21382a5c12eSMatthew Dillon 	*endword = savec;
21482a5c12eSMatthew Dillon 
21582a5c12eSMatthew Dillon 	if (kvp->kw == NULL) {
21682a5c12eSMatthew Dillon 		logx(LOG_ERR,
21782a5c12eSMatthew Dillon 		    "%s:%d: unrecognised variable \"%.*s\"",
2187383c38bSSascha Wildner 		    fnm, *line, (int)(endword - word), word);
21982a5c12eSMatthew Dillon 		return;
22082a5c12eSMatthew Dillon 	}
22182a5c12eSMatthew Dillon 
22282a5c12eSMatthew Dillon 	/* skip whitespace */
22382a5c12eSMatthew Dillon 	while (isspace(*p))
22482a5c12eSMatthew Dillon 		p++;
22582a5c12eSMatthew Dillon 
22682a5c12eSMatthew Dillon 	if (*p++ != '=') {
22782a5c12eSMatthew Dillon 		logx(LOG_ERR, "%s:%d: expected `=' after %s", fnm, *line, word);
22882a5c12eSMatthew Dillon 		return;
22982a5c12eSMatthew Dillon 	}
23082a5c12eSMatthew Dillon 
23182a5c12eSMatthew Dillon 	/* skip whitespace */
23282a5c12eSMatthew Dillon 	while (isspace(*p))
23382a5c12eSMatthew Dillon 		p++;
23482a5c12eSMatthew Dillon 
23582a5c12eSMatthew Dillon 	/* parse the value */
23682a5c12eSMatthew Dillon 	p = parse_value(p, kvp, fnm, line);
23782a5c12eSMatthew Dillon 	if (!p)
23882a5c12eSMatthew Dillon 		return;
23982a5c12eSMatthew Dillon 
24082a5c12eSMatthew Dillon 	/* skip trailing whitespace */
24182a5c12eSMatthew Dillon 	while (isspace(*p))
24282a5c12eSMatthew Dillon 		p++;
24382a5c12eSMatthew Dillon 
24482a5c12eSMatthew Dillon 	if (*p && *p != '#') {
24582a5c12eSMatthew Dillon 		logx(LOG_WARNING, "%s:%d: trailing garbage ignored",
24682a5c12eSMatthew Dillon 			fnm, *line);
24782a5c12eSMatthew Dillon 	}
24882a5c12eSMatthew Dillon }
24982a5c12eSMatthew Dillon 
25082a5c12eSMatthew Dillon 
25182a5c12eSMatthew Dillon static void
load_config(FILE * f,char * fnm)25282a5c12eSMatthew Dillon load_config(FILE *f, char *fnm)
25382a5c12eSMatthew Dillon {
25482a5c12eSMatthew Dillon 	char buf[BUFSIZ];
25582a5c12eSMatthew Dillon 	size_t len;
25682a5c12eSMatthew Dillon 	int line;
25782a5c12eSMatthew Dillon 	char *p;
25882a5c12eSMatthew Dillon 
25982a5c12eSMatthew Dillon 	line = 0;
26082a5c12eSMatthew Dillon 	while ((p = fgetln(f, &len)) != NULL) {
26182a5c12eSMatthew Dillon 		line++;
26282a5c12eSMatthew Dillon 		if (p[len-1] == '\n')
26382a5c12eSMatthew Dillon 			len--;
26482a5c12eSMatthew Dillon 		if (len >= sizeof(buf)) {
26582a5c12eSMatthew Dillon 			logx(LOG_ERR, "%s:%d: line too long", fnm, line);
26682a5c12eSMatthew Dillon 			continue;
26782a5c12eSMatthew Dillon 		}
268*d9f85b33Szrj 		memcpy(buf, p, len);
26982a5c12eSMatthew Dillon 		buf[len] = '\0';
27082a5c12eSMatthew Dillon 		parse_line(buf, fnm, &line);
27182a5c12eSMatthew Dillon 	}
27282a5c12eSMatthew Dillon }
27382a5c12eSMatthew Dillon 
27482a5c12eSMatthew Dillon /*
27582a5c12eSMatthew Dillon  * load various config file, allowing later ones to
27682a5c12eSMatthew Dillon  * overwrite earlier values
27782a5c12eSMatthew Dillon  */
27882a5c12eSMatthew Dillon void
config(void)2796beb426bSSascha Wildner config(void)
28082a5c12eSMatthew Dillon {
28182a5c12eSMatthew Dillon 	const char *home;
28282a5c12eSMatthew Dillon 	char nm[MAXPATHLEN + 1];
28382a5c12eSMatthew Dillon 	static const char *fnms[] = {
28482a5c12eSMatthew Dillon 		"/etc/hunt.conf",
28582a5c12eSMatthew Dillon 		"%s/.hunt.conf",
28682a5c12eSMatthew Dillon 		".hunt.conf",
28782a5c12eSMatthew Dillon 		NULL
28882a5c12eSMatthew Dillon 	};
28982a5c12eSMatthew Dillon 	int fn;
29082a5c12eSMatthew Dillon 	FILE *f;
29182a5c12eSMatthew Dillon 
29282a5c12eSMatthew Dillon 	/* All the %s's get converted to $HOME */
29382a5c12eSMatthew Dillon 	if ((home = getenv("HOME")) == NULL)
29482a5c12eSMatthew Dillon 		home = "";
29582a5c12eSMatthew Dillon 
29682a5c12eSMatthew Dillon 	for (fn = 0; fnms[fn]; fn++) {
29782a5c12eSMatthew Dillon 		snprintf(nm, sizeof nm, fnms[fn], home);
29882a5c12eSMatthew Dillon 		if ((f = fopen(nm, "r")) != NULL) {
29982a5c12eSMatthew Dillon 			load_config(f, nm);
30082a5c12eSMatthew Dillon 			fclose(f);
30182a5c12eSMatthew Dillon 		}
30282a5c12eSMatthew Dillon 		else if (errno != ENOENT)
30382a5c12eSMatthew Dillon 			logit(LOG_WARNING, "%s", nm);
30482a5c12eSMatthew Dillon 	}
30582a5c12eSMatthew Dillon }
30682a5c12eSMatthew Dillon 
30782a5c12eSMatthew Dillon /*
30882a5c12eSMatthew Dillon  * Parse a single configuration argument given on the command line
30982a5c12eSMatthew Dillon  */
31082a5c12eSMatthew Dillon void
config_arg(char * arg)3116beb426bSSascha Wildner config_arg(char *arg)
31282a5c12eSMatthew Dillon {
31382a5c12eSMatthew Dillon 	int line = 0;
31482a5c12eSMatthew Dillon 
31582a5c12eSMatthew Dillon 	parse_line(arg, "*Initialisation*", &line);
31682a5c12eSMatthew Dillon }
317