games: Massive style(9) cleanup commit. Reduces differences to NetBSD.
[dragonfly.git] / games / hunt / huntd / conf.c
blob19ec1a45d44ad2528b870a359f9b1012432f3123
1 /*-
2 * David Leonard <d@openbsd.org>, 1999. Public domain.
4 * $OpenBSD: conf.c,v 1.7 2007/03/20 03:43:50 tedu Exp $
5 * $DragonFly: src/games/hunt/huntd/conf.c,v 1.3 2008/11/10 15:28:13 swildner Exp $
6 */
7 #include <sys/param.h>
8 #include <sys/types.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <dirent.h>
12 #include <stdlib.h>
13 #include <ctype.h>
14 #include <syslog.h>
15 #include <errno.h>
17 #include "hunt.h"
18 #include "server.h"
19 #include "conf.h"
21 /* Configuration option variables for the server: */
23 int conf_random = 1;
24 int conf_reflect = 1;
25 int conf_monitor = 1;
26 int conf_ooze = 1;
27 int conf_fly = 1;
28 int conf_volcano = 1;
29 int conf_drone = 1;
30 int conf_boots = 1;
31 int conf_scan = 1;
32 int conf_cloak = 1;
33 int conf_logerr = 1;
34 int conf_syslog = 0;
36 int conf_scoredecay = 15;
37 int conf_maxremove = 40;
38 int conf_linger = 90;
40 int conf_flytime = 20;
41 int conf_flystep = 5;
42 int conf_volcano_max = 50;
43 int conf_ptrip_face = 2;
44 int conf_ptrip_back = 95;
45 int conf_ptrip_side = 50;
46 int conf_prandom = 1;
47 int conf_preflect = 1;
48 int conf_pshot_coll = 5;
49 int conf_pgren_coll = 10;
50 int conf_pgren_catch = 10;
51 int conf_pmiss = 5;
52 int conf_pdroneabsorb = 1;
53 int conf_fall_frac = 5;
55 int conf_bulspd = 5;
56 int conf_ishots = 15;
57 int conf_nshots = 5;
58 int conf_maxncshot = 2;
59 int conf_maxdam = 10;
60 int conf_mindam = 5;
61 int conf_stabdam = 2;
62 int conf_killgain = 2;
63 int conf_slimefactor = 3;
64 int conf_slimespeed = 5;
65 int conf_lavaspeed = 1;
66 int conf_cloaklen = 20;
67 int conf_scanlen = 20;
68 int conf_mindshot = 2;
69 int conf_simstep = 0;
72 struct kwvar {
73 const char * kw;
74 void * var;
75 enum vartype { Vint, Vchar, Vstring, Vdouble } type;
78 static struct kwvar keywords[] = {
79 { "random", &conf_random, Vint },
80 { "reflect", &conf_reflect, Vint },
81 { "monitor", &conf_monitor, Vint },
82 { "ooze", &conf_ooze, Vint },
83 { "fly", &conf_fly, Vint },
84 { "volcano", &conf_volcano, Vint },
85 { "drone", &conf_drone, Vint },
86 { "boots", &conf_boots, Vint },
87 { "scan", &conf_scan, Vint },
88 { "cloak", &conf_cloak, Vint },
89 { "logerr", &conf_logerr, Vint },
90 { "syslog", &conf_syslog, Vint },
91 { "scoredecay", &conf_scoredecay, Vint },
92 { "maxremove", &conf_maxremove, Vint },
93 { "linger", &conf_linger, Vint },
95 { "flytime", &conf_flytime, Vint },
96 { "flystep", &conf_flystep, Vint },
97 { "volcano_max", &conf_volcano_max, Vint },
98 { "ptrip_face", &conf_ptrip_face, Vint },
99 { "ptrip_back", &conf_ptrip_back, Vint },
100 { "ptrip_side", &conf_ptrip_side, Vint },
101 { "prandom", &conf_prandom, Vint },
102 { "preflect", &conf_preflect, Vint },
103 { "pshot_coll", &conf_pshot_coll, Vint },
104 { "pgren_coll", &conf_pgren_coll, Vint },
105 { "pgren_catch", &conf_pgren_catch, Vint },
106 { "pmiss", &conf_pmiss, Vint },
107 { "pdroneabsorb", &conf_pdroneabsorb, Vint },
108 { "fall_frac", &conf_fall_frac, Vint },
110 { "bulspd", &conf_bulspd, Vint },
111 { "ishots", &conf_ishots, Vint },
112 { "nshots", &conf_nshots, Vint },
113 { "maxncshot", &conf_maxncshot, Vint },
114 { "maxdam", &conf_maxdam, Vint },
115 { "mindam", &conf_mindam, Vint },
116 { "stabdam", &conf_stabdam, Vint },
117 { "killgain", &conf_killgain, Vint },
118 { "slimefactor", &conf_slimefactor, Vint },
119 { "slimespeed", &conf_slimespeed, Vint },
120 { "lavaspeed", &conf_lavaspeed, Vint },
121 { "cloaklen", &conf_cloaklen, Vint },
122 { "scanlen", &conf_scanlen, Vint },
123 { "mindshot", &conf_mindshot, Vint },
124 { "simstep", &conf_simstep, Vint },
126 { NULL, NULL, Vint }
129 static char *
130 parse_int(char *p, struct kwvar *kvp, const char *fnm, int *linep)
132 char *valuestart, *digitstart;
133 char savec;
134 int newval;
136 /* expect a number */
137 valuestart = p;
138 if (*p == '-')
139 p++;
140 digitstart = p;
141 while (isdigit(*p))
142 p++;
143 if ((*p == '\0' || isspace(*p) || *p == '#') && digitstart != p) {
144 savec = *p;
145 *p = '\0';
146 newval = atoi(valuestart);
147 *p = savec;
148 logx(LOG_INFO, "%s:%d: %s: %d -> %d",
149 fnm, *linep, kvp->kw, *(int *)kvp->var, newval);
150 *(int *)kvp->var = newval;
151 return p;
152 } else {
153 logx(LOG_ERR, "%s:%d: invalid integer value \"%s\"",
154 fnm, *linep, valuestart);
155 return NULL;
159 static char *
160 parse_value(char *p, struct kwvar *kvp, const char *fnm, int *linep)
163 switch (kvp->type) {
164 case Vint:
165 return parse_int(p, kvp, fnm, linep);
166 case Vchar:
167 case Vstring:
168 case Vdouble:
169 /* tbd */
170 default:
171 abort();
175 static void
176 parse_line(char *buf, const char *fnm, int *line)
178 char *p;
179 char *word;
180 char *endword;
181 struct kwvar *kvp;
182 char savec;
184 p = buf;
186 /* skip leading white */
187 while (isspace(*p))
188 p++;
189 /* allow blank lines and comment lines */
190 if (*p == '\0' || *p == '#')
191 return;
193 /* walk to the end of the word: */
194 word = p;
195 if (isalpha(*p) || *p == '_') {
196 p++;
197 while (isalpha(*p) || isdigit(*p) || *p == '_')
198 p++;
200 endword = p;
202 if (endword == word) {
203 logx(LOG_ERR, "%s:%d: expected variable name",
204 fnm, *line);
205 return;
208 /* match the configuration variable name */
209 savec = *endword;
210 *endword = '\0';
211 for (kvp = keywords; kvp->kw; kvp++)
212 if (strcmp(kvp->kw, word) == 0)
213 break;
214 *endword = savec;
216 if (kvp->kw == NULL) {
217 logx(LOG_ERR,
218 "%s:%d: unrecognised variable \"%.*s\"",
219 fnm, *line, (int)(endword - word), word);
220 return;
223 /* skip whitespace */
224 while (isspace(*p))
225 p++;
227 if (*p++ != '=') {
228 logx(LOG_ERR, "%s:%d: expected `=' after %s", fnm, *line, word);
229 return;
232 /* skip whitespace */
233 while (isspace(*p))
234 p++;
236 /* parse the value */
237 p = parse_value(p, kvp, fnm, line);
238 if (!p)
239 return;
241 /* skip trailing whitespace */
242 while (isspace(*p))
243 p++;
245 if (*p && *p != '#') {
246 logx(LOG_WARNING, "%s:%d: trailing garbage ignored",
247 fnm, *line);
252 static void
253 load_config(FILE *f, char *fnm)
255 char buf[BUFSIZ];
256 size_t len;
257 int line;
258 char *p;
260 line = 0;
261 while ((p = fgetln(f, &len)) != NULL) {
262 line++;
263 if (p[len-1] == '\n')
264 len--;
265 if (len >= sizeof(buf)) {
266 logx(LOG_ERR, "%s:%d: line too long", fnm, line);
267 continue;
269 (void)memcpy(buf, p, len);
270 buf[len] = '\0';
271 parse_line(buf, fnm, &line);
276 * load various config file, allowing later ones to
277 * overwrite earlier values
279 void
280 config(void)
282 const char *home;
283 char nm[MAXPATHLEN + 1];
284 static const char *fnms[] = {
285 "/etc/hunt.conf",
286 "%s/.hunt.conf",
287 ".hunt.conf",
288 NULL
290 int fn;
291 FILE *f;
293 /* All the %s's get converted to $HOME */
294 if ((home = getenv("HOME")) == NULL)
295 home = "";
297 for (fn = 0; fnms[fn]; fn++) {
298 snprintf(nm, sizeof nm, fnms[fn], home);
299 if ((f = fopen(nm, "r")) != NULL) {
300 load_config(f, nm);
301 fclose(f);
303 else if (errno != ENOENT)
304 logit(LOG_WARNING, "%s", nm);
309 * Parse a single configuration argument given on the command line
311 void
312 config_arg(char *arg)
314 int line = 0;
316 parse_line(arg, "*Initialisation*", &line);