]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_cf.cc
FUM fix
[thirdparty/squid.git] / src / cache_cf.cc
CommitLineData
30a4f2a8 1/*
b3264694 2 * $Id: cache_cf.cc,v 1.218 1997/08/25 02:17:45 wessels Exp $
30a4f2a8 3 *
4 * DEBUG: section 3 Configuration File Parsing
5 * AUTHOR: Harvest Derived
6 *
42c04c16 7 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
30a4f2a8 8 * --------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from the
11 * Internet community. Development is led by Duane Wessels of the
12 * National Laboratory for Applied Network Research and funded by
13 * the National Science Foundation.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
cf5fd929 30
44a47c6e 31#include "squid.h"
090089c4 32
8813e606 33static const char *const T_SECOND_STR = "second";
34static const char *const T_MINUTE_STR = "minute";
35static const char *const T_HOUR_STR = "hour";
36static const char *const T_DAY_STR = "day";
37static const char *const T_WEEK_STR = "week";
38static const char *const T_FORTNIGHT_STR = "fortnight";
39static const char *const T_MONTH_STR = "month";
40static const char *const T_YEAR_STR = "year";
41static const char *const T_DECADE_STR = "decade";
aa0a0c7c 42
9906e724 43static const char *const B_BYTES_STR = "bytes";
44static const char *const B_KBYTES_STR = "KB";
45static const char *const B_MBYTES_STR = "MB";
46static const char *const B_GBYTES_STR = "GB";
47
4db43fab 48static const char *const list_sep = ", \t\n\r";
090089c4 49
24382924 50static char fatal_str[BUFSIZ];
24382924 51static void self_destruct _PARAMS((void));
0ee4272b 52static void wordlistAdd _PARAMS((wordlist **, const char *));
caebbe00 53
67508012 54static void configDoConfigure _PARAMS((void));
f1dc9b30 55static void parse_refreshpattern _PARAMS((refresh_t **));
429fdbec 56static int parseTimeUnits _PARAMS((const char *unit));
a47b9029 57static void parseTimeLine _PARAMS((time_t * tptr, const char *units));
270b86af 58static void parse_string _PARAMS((char **));
59static void parse_wordlist _PARAMS((wordlist **));
270b86af 60static void default_all _PARAMS((void));
0153d498 61static int parse_line _PARAMS((char *));
a47b9029 62static void parseBytesLine _PARAMS((size_t * bptr, const char *units));
9906e724 63static size_t parseBytesUnits _PARAMS((const char *unit));
0153d498 64
65/* These come from cf_gen.c */
66static void default_all _PARAMS((void));
0153d498 67static void free_all _PARAMS((void));
270b86af 68
24382924 69static void
0673c0ba 70self_destruct(void)
090089c4 71{
b8de7ebe 72 sprintf(fatal_str, "Bungled %s line %d: %s",
73 cfg_filename, config_lineno, config_input_line);
090089c4 74 fatal(fatal_str);
75}
76
8203a132 77void
78wordlistDestroy(wordlist ** list)
0ffd22bc 79{
80 wordlist *w = NULL;
b5639035 81 while ((w = *list)) {
82 *list = w->next;
0ffd22bc 83 safe_free(w->key);
84 safe_free(w);
85 }
86 *list = NULL;
87}
88
24382924 89static void
fe4e214f 90wordlistAdd(wordlist ** list, const char *key)
090089c4 91{
0ffd22bc 92 wordlist *p = NULL;
93 wordlist *q = NULL;
090089c4 94
95 if (!(*list)) {
96 /* empty list */
30a4f2a8 97 *list = xcalloc(1, sizeof(wordlist));
090089c4 98 (*list)->key = xstrdup(key);
99 (*list)->next = NULL;
100 } else {
101 p = *list;
102 while (p->next)
103 p = p->next;
30a4f2a8 104 q = xcalloc(1, sizeof(wordlist));
090089c4 105 q->key = xstrdup(key);
106 q->next = NULL;
107 p->next = q;
108 }
109}
110
8203a132 111void
112intlistDestroy(intlist ** list)
92a6f4b1 113{
114 intlist *w = NULL;
115 intlist *n = NULL;
116
117 for (w = *list; w; w = n) {
118 n = w->next;
119 safe_free(w);
120 }
121 *list = NULL;
122}
123
403279e0 124
3c5557f9 125/*
126 * Use this #define in all the parse*() functions. Assumes char *token is
127 * defined
128 */
090089c4 129
130#define GetInteger(var) \
131 token = strtok(NULL, w_space); \
30a4f2a8 132 if( token == NULL) \
3003c0f3 133 self_destruct(); \
090089c4 134 if (sscanf(token, "%d", &var) != 1) \
3003c0f3 135 self_destruct();
090089c4 136
270b86af 137int
138parseConfigFile(const char *file_name)
2546fcb3 139{
270b86af 140 FILE *fp = NULL;
141 char *token = NULL;
72121e8b 142 char *tmp_line;
0153d498 143 free_all();
144 default_all();
270b86af 145 if ((fp = fopen(file_name, "r")) == NULL) {
146 sprintf(fatal_str, "Unable to open configuration file: %s: %s",
147 file_name, xstrerror());
148 fatal(fatal_str);
149 }
150 cfg_filename = file_name;
151 if ((token = strrchr(cfg_filename, '/')))
152 cfg_filename = token + 1;
153 memset(config_input_line, '\0', BUFSIZ);
154 config_lineno = 0;
155 while (fgets(config_input_line, BUFSIZ, fp)) {
156 config_lineno++;
157 if ((token = strchr(config_input_line, '\n')))
158 *token = '\0';
159 if (config_input_line[0] == '#')
160 continue;
161 if (config_input_line[0] == '\0')
162 continue;
163 debug(3, 5) ("Processing: '%s'\n", config_input_line);
72121e8b 164 tmp_line = xstrdup(config_input_line);
270b86af 165 if (!parse_line(tmp_line)) {
166 debug(3, 0) ("parseConfigFile: line %d unrecognized: '%s'\n",
167 config_lineno,
168 config_input_line);
169 }
72121e8b 170 safe_free(tmp_line);
270b86af 171 }
172
270b86af 173 /* Sanity checks */
174 if (Config.Swap.maxSize < (Config.Mem.maxSize >> 10)) {
175 printf("WARNING: cache_swap (%d kbytes) is less than cache_mem (%d bytes).\n", Config.Swap.maxSize, Config.Mem.maxSize);
176 printf(" This will cause serious problems with your cache!!!\n");
177 printf(" Change your configuration file.\n");
178 fflush(stdout); /* print message */
179 }
f1dc9b30 180 if (Config.Announce.period < 1) {
181 Config.Announce.period = 86400 * 365; /* one year */
17a0a4ee 182 Config.onoff.announce = 0;
270b86af 183 }
184 if (Config.dnsChildren < 0)
185 Config.dnsChildren = 0;
186 if (Config.dnsChildren < 1) {
187 printf("WARNING: dnsservers are disabled!\n");
188 printf("WARNING: Cache performance may be very poor\n");
189 } else if (Config.dnsChildren > DefaultDnsChildrenMax) {
190 printf("WARNING: dns_children was set to a bad value: %d\n",
191 Config.dnsChildren);
192 printf("Setting it to the maximum (%d).\n", DefaultDnsChildrenMax);
193 Config.dnsChildren = DefaultDnsChildrenMax;
194 }
195 if (Config.Program.redirect) {
196 if (Config.redirectChildren < 1) {
197 Config.redirectChildren = 0;
198 safe_free(Config.Program.redirect);
199 } else if (Config.redirectChildren > DefaultRedirectChildrenMax) {
200 printf("WARNING: redirect_children was set to a bad value: %d\n",
201 Config.redirectChildren);
202 printf("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax);
203 Config.redirectChildren = DefaultRedirectChildrenMax;
204 }
fea2e6e0 205 }
270b86af 206 fclose(fp);
207 configDoConfigure();
270b86af 208 return 0;
2546fcb3 209}
210
8203a132 211static void
270b86af 212configDoConfigure(void)
090089c4 213{
f1dc9b30 214 LOCAL_ARRAY(char, buf, BUFSIZ);
215 memset(&Config2, '\0', sizeof(SquidConfig2));
216 if (Config.Accel.host) {
a47b9029 217 snprintf(buf, BUFSIZ, "http://%s:%d", Config.Accel.host, Config.Accel.port);
218 Config2.Accel.prefix = xstrdup(buf);
219 Config2.Accel.on = 1;
f1dc9b30 220 }
221 if (Config.appendDomain)
222 if (*Config.appendDomain != '.')
223 fatal("append_domain must begin with a '.'");
270b86af 224 if (Config.errHtmlText == NULL)
225 Config.errHtmlText = xstrdup(null_string);
226 storeConfigure();
f1dc9b30 227 if (Config2.Accel.on && !strcmp(Config.Accel.host, "virtual"))
270b86af 228 vhost_mode = 1;
229 if (Config.Port.http == NULL)
230 fatal("No http_port specified!");
231 sprintf(ThisCache, "%s:%d (Squid/%s)",
232 getMyHostname(),
233 (int) Config.Port.http->i,
234 SQUID_VERSION);
235 if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF)
236 Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF;
237 if (Config.appendDomain)
238 Config.appendDomainLen = strlen(Config.appendDomain);
239 else
240 Config.appendDomainLen = 0;
f1dc9b30 241 safe_free(debug_options)
242 debug_options = xstrdup(Config.debugOptions);
090089c4 243}
244
270b86af 245/* Parse a time specification from the config file. Store the
f1dc9b30 246 * result in 'tptr', after converting it to 'units' */
8203a132 247static void
a47b9029 248parseTimeLine(time_t * tptr, const char *units)
090089c4 249{
250 char *token;
270b86af 251 double d;
f1dc9b30 252 time_t m;
253 time_t u;
270b86af 254 if ((u = parseTimeUnits(units)) == 0)
3003c0f3 255 self_destruct();
270b86af 256 if ((token = strtok(NULL, w_space)) == NULL)
3003c0f3 257 self_destruct();
270b86af 258 d = atof(token);
259 m = u; /* default to 'units' if none specified */
9e975e4e 260 if ((token = strtok(NULL, w_space)) == NULL)
a47b9029 261 debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
262 config_input_line, d, units);
9e975e4e 263 else if ((m = parseTimeUnits(token)) == 0)
a47b9029 264 self_destruct();
f1dc9b30 265 *tptr = m * d / u;
090089c4 266}
267
270b86af 268static int
269parseTimeUnits(const char *unit)
270{
271 if (!strncasecmp(unit, T_SECOND_STR, strlen(T_SECOND_STR)))
272 return 1;
273 if (!strncasecmp(unit, T_MINUTE_STR, strlen(T_MINUTE_STR)))
274 return 60;
275 if (!strncasecmp(unit, T_HOUR_STR, strlen(T_HOUR_STR)))
276 return 3600;
277 if (!strncasecmp(unit, T_DAY_STR, strlen(T_DAY_STR)))
278 return 86400;
279 if (!strncasecmp(unit, T_WEEK_STR, strlen(T_WEEK_STR)))
280 return 86400 * 7;
281 if (!strncasecmp(unit, T_FORTNIGHT_STR, strlen(T_FORTNIGHT_STR)))
282 return 86400 * 14;
283 if (!strncasecmp(unit, T_MONTH_STR, strlen(T_MONTH_STR)))
284 return 86400 * 30;
285 if (!strncasecmp(unit, T_YEAR_STR, strlen(T_YEAR_STR)))
286 return 86400 * 365.2522;
287 if (!strncasecmp(unit, T_DECADE_STR, strlen(T_DECADE_STR)))
288 return 86400 * 365.2522 * 10;
289 debug(3, 1) ("parseTimeUnits: unknown time unit '%s'\n", unit);
290 return 0;
291}
292
9906e724 293static void
9e975e4e 294parseBytesLine(size_t * bptr, const char *units)
9906e724 295{
296 char *token;
297 double d;
298 size_t m;
299 size_t u;
300 if ((u = parseBytesUnits(units)) == 0)
301 self_destruct();
302 if ((token = strtok(NULL, w_space)) == NULL)
303 self_destruct();
304 d = atof(token);
305 m = u; /* default to 'units' if none specified */
9e975e4e 306 if ((token = strtok(NULL, w_space)) == NULL)
307 debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
308 config_input_line, d, units);
309 else if ((m = parseBytesUnits(token)) == 0)
310 self_destruct();
9906e724 311 *bptr = m * d / u;
312}
313
314static size_t
315parseBytesUnits(const char *unit)
316{
317 if (!strncasecmp(unit, B_BYTES_STR, strlen(B_BYTES_STR)))
318 return 1;
319 if (!strncasecmp(unit, B_KBYTES_STR, strlen(B_KBYTES_STR)))
a47b9029 320 return 1 << 10;
9906e724 321 if (!strncasecmp(unit, B_MBYTES_STR, strlen(B_MBYTES_STR)))
a47b9029 322 return 1 << 20;
9906e724 323 if (!strncasecmp(unit, B_GBYTES_STR, strlen(B_GBYTES_STR)))
a47b9029 324 return 1 << 30;
9906e724 325 debug(3, 1) ("parseBytesUnits: unknown bytes unit '%s'\n", unit);
326 return 0;
327}
328
270b86af 329/*****************************************************************************
330 * Max
331 *****************************************************************************/
332
8203a132 333static void
a47b9029 334dump_acl(acl * acl)
090089c4 335{
b556b1e9 336 assert(0);
090089c4 337}
338
8203a132 339static void
a47b9029 340parse_acl(acl ** acl)
090089c4 341{
f1dc9b30 342 aclParseAclLine(acl);
343}
344
345static void
a47b9029 346free_acl(acl ** acl)
f1dc9b30 347{
348 aclDestroyAcls(acl);
090089c4 349}
350
8203a132 351static void
270b86af 352dump_acl_access(struct _acl_access *head)
30a4f2a8 353{
b556b1e9 354 assert(0);
30a4f2a8 355}
090089c4 356
8203a132 357static void
270b86af 358parse_acl_access(struct _acl_access **head)
090089c4 359{
270b86af 360 aclParseAccessLine(head);
090089c4 361}
362
0153d498 363static void
364free_acl_access(struct _acl_access **head)
365{
a47b9029 366 aclDestroyAccessList(head);
0153d498 367}
368
8203a132 369static void
270b86af 370dump_address(struct in_addr addr)
371{
372 printf("%s", inet_ntoa(addr));
373}
374
375static void
376parse_address(struct in_addr *addr)
090089c4 377{
0ee4272b 378 const struct hostent *hp;
270b86af 379 char *token = strtok(NULL, w_space);
380
30a4f2a8 381 if (token == NULL)
382 self_destruct();
429fdbec 383 if (safe_inet_addr(token, addr) == 1)
384 (void) 0;
ceb8994e 385 else if ((hp = gethostbyname(token))) /* dont use ipcache */
1d73e33a 386 *addr = inaddrFromHostent(hp);
30a4f2a8 387 else
3003c0f3 388 self_destruct();
090089c4 389}
390
0153d498 391static void
392free_address(struct in_addr *addr)
393{
a47b9029 394 memset(addr, '\0', sizeof(struct in_addr));
0153d498 395}
396
e90100aa 397static void
f1dc9b30 398dump_cachedir(struct _cacheSwap swap)
e90100aa 399{
b556b1e9 400 assert(0);
e90100aa 401}
402
8203a132 403static void
f1dc9b30 404parse_cachedir(struct _cacheSwap *swap)
090089c4 405{
406 char *token;
f1dc9b30 407 char *path;
752c3b27 408 int i;
270b86af 409 int size;
410 int l1;
411 int l2;
412 int readonly = 0;
f1dc9b30 413 SwapDir *tmp = NULL;
414 if ((path = strtok(NULL, w_space)) == NULL)
752c3b27 415 self_destruct();
f1dc9b30 416 if (strlen(path) > (SQUID_MAXPATHLEN - 32))
417 fatal_dump("cache_dir pathname is too long");
270b86af 418 GetInteger(i);
419 size = i << 10; /* Mbytes to kbytes */
270b86af 420 GetInteger(i);
421 l1 = i;
422 GetInteger(i);
423 l2 = i;
424 if ((token = strtok(NULL, w_space)))
425 if (!strcasecmp(token, "read-only"))
426 readonly = 1;
f1dc9b30 427 for (i = 0; i < swap->n_configured; i++) {
a47b9029 428 tmp = swap->swapDirs + i;
f1dc9b30 429 if (!strcmp(path, tmp->path)) {
430 /* just reconfigure it */
a47b9029 431 tmp->max_size = size;
432 tmp->read_only = readonly;
f1dc9b30 433 return;
434 }
435 }
436 if (swap->swapDirs == NULL) {
437 swap->n_allocated = 4;
438 swap->swapDirs = xcalloc(swap->n_allocated, sizeof(SwapDir));
439 }
440 if (swap->n_allocated == swap->n_configured) {
441 swap->n_allocated <<= 1;
442 tmp = xcalloc(swap->n_allocated, sizeof(SwapDir));
443 xmemcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir));
444 xfree(swap->swapDirs);
445 swap->swapDirs = tmp;
446 }
447 debug(20, 1) ("Creating Swap Dir #%d in %s\n", swap->n_configured + 1, path);
448 tmp = swap->swapDirs + swap->n_configured;
449 tmp->path = xstrdup(path);
450 tmp->max_size = size;
451 tmp->l1 = l1;
452 tmp->l2 = l2;
453 tmp->read_only = readonly;
454 tmp->map = file_map_create(MAX_FILES_PER_DIR);
455 tmp->swaplog_fd = -1;
62607543 456 swap->n_configured++;
9906e724 457 Config.Swap.maxSize += size;
752c3b27 458}
459
8203a132 460static void
f1dc9b30 461free_cachedir(struct _cacheSwap *swap)
462{
a47b9029 463 SwapDir *s;
464 int i;
465 for (i = 0; i < swap->n_configured; i++) {
466 s = swap->swapDirs + i;
f150dd4b 467 if (s->swaplog_fd > -1) {
468 file_close(s->swaplog_fd);
469 s->swaplog_fd = -1;
470 }
a47b9029 471 xfree(s->path);
472 filemapFreeMemory(s->map);
473 }
474 safe_free(swap->swapDirs);
475 swap->swapDirs = NULL;
476 swap->n_allocated = 0;
477 swap->n_configured = 0;
f1dc9b30 478}
479
480static void
40a1495e 481dump_peer(peer * p)
98ffb7e4 482{
b556b1e9 483 assert(0);
98ffb7e4 484}
485
8203a132 486static void
40a1495e 487parse_peer(peer ** head)
7813c6d5 488{
270b86af 489 char *token = NULL;
40a1495e 490 peer *p;
7813c6d5 491 int i;
40a1495e 492 ushortlist *u;
f9e5a344 493 const char *me = null_string; /* XXX */
40a1495e 494 p = xcalloc(1, sizeof(peer));
495 p->http_port = CACHE_HTTP_PORT;
496 p->icp_port = CACHE_ICP_PORT;
497 p->weight = 1;
e481c2dc 498 if ((token = strtok(NULL, w_space)) == NULL)
270b86af 499 self_destruct();
40a1495e 500 p->host = xstrdup(token);
e481c2dc 501 if ((token = strtok(NULL, w_space)) == NULL)
270b86af 502 self_destruct();
40a1495e 503 p->type = parseNeighborType(token);
270b86af 504 GetInteger(i);
40a1495e 505 p->http_port = (u_short) i;
7813c6d5 506 GetInteger(i);
40a1495e 507 p->icp_port = (u_short) i;
508 if (strcmp(p->host, me) == 0) {
509 for (u = Config.Port.http; u; u = u->next) {
510 if (p->http_port != u->i)
511 continue;
512 debug(15, 0) ("parse_peer: Peer looks like myself: %s %s/%d/%d\n",
513 p->type, p->host, p->http_port, p->icp_port);
514 self_destruct();
515 }
516 }
270b86af 517 while ((token = strtok(NULL, w_space))) {
518 if (!strcasecmp(token, "proxy-only")) {
40a1495e 519 p->options |= NEIGHBOR_PROXY_ONLY;
270b86af 520 } else if (!strcasecmp(token, "no-query")) {
40a1495e 521 p->options |= NEIGHBOR_NO_QUERY;
270b86af 522 } else if (!strcasecmp(token, "multicast-responder")) {
40a1495e 523 p->options |= NEIGHBOR_MCAST_RESPONDER;
270b86af 524 } else if (!strncasecmp(token, "weight=", 7)) {
40a1495e 525 p->weight = atoi(token + 7);
b3264694 526 } else if (!strncasecmp(token, "closest-only", 12)) {
527 p->options |= NEIGHBOR_CLOSEST_ONLY;
270b86af 528 } else if (!strncasecmp(token, "ttl=", 4)) {
40a1495e 529 p->mcast.ttl = atoi(token + 4);
530 if (p->mcast.ttl < 0)
531 p->mcast.ttl = 0;
532 if (p->mcast.ttl > 128)
533 p->mcast.ttl = 128;
270b86af 534 } else if (!strncasecmp(token, "default", 7)) {
40a1495e 535 p->options |= NEIGHBOR_DEFAULT_PARENT;
270b86af 536 } else if (!strncasecmp(token, "round-robin", 11)) {
40a1495e 537 p->options |= NEIGHBOR_ROUNDROBIN;
270b86af 538 } else {
40a1495e 539 debug(3, 0) ("parse_peer: token='%s'\n", token);
270b86af 540 self_destruct();
541 }
542 }
40a1495e 543 if (p->weight < 1)
544 p->weight = 1;
545 p->icp_version = ICP_VERSION_CURRENT;
546 p->tcp_up = 1;
547 cbdataAdd(p);
0153d498 548 while (*head != NULL)
549 head = &(*head)->next;
550 *head = p;
40a1495e 551 Config.npeers++;
0153d498 552}
553
554static void
40a1495e 555free_peer(peer ** P)
0153d498 556{
40a1495e 557 peer *p;
a47b9029 558 while ((p = *P)) {
559 *P = p->next;
40a1495e 560 peerDestroy(p);
a47b9029 561 }
270b86af 562}
563
564static void
a47b9029 565dump_cachemgrpasswd(cachemgr_passwd * list)
270b86af 566{
b556b1e9 567 assert(0);
270b86af 568}
569
570static void
a47b9029 571parse_cachemgrpasswd(cachemgr_passwd ** head)
270b86af 572{
573 char *passwd = NULL;
574 wordlist *actions = NULL;
575 parse_string(&passwd);
576 parse_wordlist(&actions);
f1dc9b30 577 objcachePasswdAdd(head, passwd, actions);
270b86af 578 wordlistDestroy(&actions);
579}
580
581static void
a47b9029 582free_cachemgrpasswd(cachemgr_passwd ** head)
270b86af 583{
a47b9029 584 cachemgr_passwd *p;
585 while ((p = *head)) {
586 *head = p->next;
587 xfree(p->passwd);
588 xfree(p);
589 }
270b86af 590}
591
270b86af 592
8203a132 593static void
f1dc9b30 594dump_denyinfo(struct _acl_deny_info_list *var)
270b86af 595{
b556b1e9 596 assert(0);
270b86af 597}
598
599static void
f1dc9b30 600parse_denyinfo(struct _acl_deny_info_list **var)
6e40f263 601{
f1dc9b30 602 aclParseDenyInfoLine(var);
6e40f263 603}
403279e0 604
1273d501 605void
a47b9029 606free_denyinfo(acl_deny_info_list ** list)
3c5557f9 607{
1273d501 608 struct _acl_deny_info_list *a = NULL;
609 struct _acl_deny_info_list *a_next = NULL;
610 struct _acl_name_list *l = NULL;
611 struct _acl_name_list *l_next = NULL;
612 for (a = *list; a; a = a_next) {
a47b9029 613 for (l = a->acl_list; l; l = l_next) {
614 l_next = l->next;
615 safe_free(l);
616 }
617 a_next = a->next;
618 safe_free(a);
1273d501 619 }
620 *list = NULL;
270b86af 621}
622
623static void
f1dc9b30 624parse_peeracl(void)
270b86af 625{
626 char *host = NULL;
627 char *aclname = NULL;
628 if (!(host = strtok(NULL, w_space)))
629 self_destruct();
f1dc9b30 630 while ((aclname = strtok(NULL, list_sep))) {
40a1495e 631 peer *p;
f1dc9b30 632 acl_list *L = NULL;
633 acl_list **Tail = NULL;
634 acl *a = NULL;
40a1495e 635 if ((p = peerFindByName(host)) == NULL) {
f1dc9b30 636 debug(15, 0) ("%s, line %d: No cache_host '%s'\n",
637 cfg_filename, config_lineno, host);
638 return;
639 }
640 L = xcalloc(1, sizeof(struct _acl_list));
641 L->op = 1;
642 if (*aclname == '!') {
643 L->op = 0;
644 aclname++;
645 }
646 debug(15, 3) ("neighborAddAcl: looking for ACL name '%s'\n", aclname);
647 a = aclFindByName(aclname);
648 if (a == NULL) {
649 debug(15, 0) ("%s line %d: %s\n",
650 cfg_filename, config_lineno, config_input_line);
651 debug(15, 0) ("neighborAddAcl: ACL name '%s' not found.\n", aclname);
652 xfree(L);
653 return;
654 }
655 L->acl = a;
656 for (Tail = &p->acls; *Tail; Tail = &(*Tail)->next);
657 *Tail = L;
658 }
270b86af 659}
660
270b86af 661static void
662parse_hostdomain(void)
663{
664 char *host = NULL;
665 char *domain = NULL;
666 if (!(host = strtok(NULL, w_space)))
667 self_destruct();
f1dc9b30 668 while ((domain = strtok(NULL, list_sep))) {
669 domain_ping *l = NULL;
670 domain_ping **L = NULL;
40a1495e 671 peer *p;
672 if ((p = peerFindByName(host)) == NULL) {
f1dc9b30 673 debug(15, 0) ("%s, line %d: No cache_host '%s'\n",
674 cfg_filename, config_lineno, host);
675 continue;
676 }
677 l = xcalloc(1, sizeof(struct _domain_ping));
678 l->do_ping = 1;
679 if (*domain == '!') { /* check for !.edu */
680 l->do_ping = 0;
681 domain++;
682 }
683 l->domain = xstrdup(domain);
684 for (L = &(p->pinglist); *L; L = &((*L)->next));
685 *L = l;
686 }
270b86af 687}
688
689static void
690parse_hostdomaintype(void)
691{
692 char *host = NULL;
693 char *type = NULL;
694 char *domain = NULL;
695 if (!(host = strtok(NULL, w_space)))
696 self_destruct();
697 if (!(type = strtok(NULL, w_space)))
698 self_destruct();
f1dc9b30 699 while ((domain = strtok(NULL, list_sep))) {
700 domain_type *l = NULL;
701 domain_type **L = NULL;
40a1495e 702 peer *p;
703 if ((p = peerFindByName(host)) == NULL) {
f1dc9b30 704 debug(15, 0) ("%s, line %d: No cache_host '%s'\n",
705 cfg_filename, config_lineno, host);
706 return;
707 }
708 l = xcalloc(1, sizeof(struct _domain_type));
709 l->type = parseNeighborType(type);
710 l->domain = xstrdup(domain);
711 for (L = &(p->typelist); *L; L = &((*L)->next));
712 *L = l;
713 }
270b86af 714}
715
716static void
717dump_httpanonymizer(int var)
718{
719 switch (var) {
720 case ANONYMIZER_NONE:
721 printf("off");
722 break;
723 case ANONYMIZER_STANDARD:
724 printf("paranoid");
725 break;
726 case ANONYMIZER_PARANOID:
727 printf("standard");
728 break;
729 }
730}
731
732static void
733parse_httpanonymizer(int *var)
fa562c67 734{
735 char *token;
736 token = strtok(NULL, w_space);
737 if (token == NULL)
bba6fa8f 738 self_destruct();
fa562c67 739 if (!strcasecmp(token, "off"))
270b86af 740 *var = ANONYMIZER_NONE;
fa562c67 741 else if (!strcasecmp(token, "paranoid"))
270b86af 742 *var = ANONYMIZER_PARANOID;
fa562c67 743 else
270b86af 744 *var = ANONYMIZER_STANDARD;
745}
746
641941c0 747
270b86af 748static void
a47b9029 749dump_ushortlist(ushortlist * u)
090089c4 750{
270b86af 751 while (u) {
752 printf("%d ", (int) u->i);
753 u = u->next;
754 }
755}
090089c4 756
270b86af 757static void
758parse_ushortlist(ushortlist ** P)
759{
760 char *token;
761 int i;
762 ushortlist *u;
763 ushortlist **U;
764 while ((token = strtok(NULL, w_space))) {
765 if (sscanf(token, "%d", &i) != 1)
766 self_destruct();
767 if (i < 0)
768 i = 0;
769 u = xcalloc(1, sizeof(ushortlist));
770 u->i = (u_short) i;
771 for (U = P; *U; U = &(*U)->next);
772 *U = u;
090089c4 773 }
270b86af 774}
090089c4 775
0153d498 776static void
a47b9029 777free_ushortlist(ushortlist ** P)
0153d498 778{
a47b9029 779 ushortlist *u;
780 while ((u = *P)) {
781 *P = u->next;
782 xfree(u);
783 }
0153d498 784}
785
270b86af 786static void
787dump_int(int var)
788{
789 printf("%d", var);
790}
c1c29eb6 791
270b86af 792static void
793parse_int(int *var)
794{
795 char *token;
796 int i;
270b86af 797 GetInteger(i);
798 *var = i;
799}
090089c4 800
0153d498 801static void
802free_int(int *var)
803{
a47b9029 804 *var = 0;
0153d498 805}
806
270b86af 807static void
808dump_onoff(int var)
809{
810 printf(var ? "on" : "off");
811}
090089c4 812
270b86af 813static void
814parse_onoff(int *var)
815{
816 char *token = strtok(NULL, w_space);
090089c4 817
270b86af 818 if (token == NULL)
819 self_destruct();
820 if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
821 *var = 1;
822 else
823 *var = 0;
824}
e90100aa 825
0153d498 826#define free_onoff free_int
f1dc9b30 827#define free_httpanonymizer free_int
0153d498 828#define dump_pathname_stat dump_string
829#define free_pathname_stat free_string
f1dc9b30 830#define dump_eol dump_string
831#define free_eol free_string
30a4f2a8 832
270b86af 833static void
0153d498 834parse_pathname_stat(char **path)
270b86af 835{
836 struct stat sb;
270b86af 837 parse_string(path);
270b86af 838 if (stat(*path, &sb) < 0) {
0153d498 839 debug(50, 1) ("parse_pathname_stat: %s: %s\n", *path, xstrerror());
270b86af 840 self_destruct();
841 }
842}
30a4f2a8 843
270b86af 844static void
a47b9029 845dump_refreshpattern(refresh_t * head)
270b86af 846{
b556b1e9 847 assert(0);
270b86af 848}
090089c4 849
270b86af 850static void
f1dc9b30 851parse_refreshpattern(refresh_t ** head)
270b86af 852{
f1dc9b30 853 char *token;
854 char *pattern;
855 time_t min = 0;
856 int pct = 0;
857 time_t max = 0;
858 int i;
859 refresh_t *t;
860 regex_t comp;
861 int errcode;
862 int flags = REG_EXTENDED | REG_NOSUB;
863 if ((token = strtok(NULL, w_space)) == NULL)
864 self_destruct();
865 if (strcmp(token, "-i") == 0) {
866 flags |= REG_ICASE;
867 token = strtok(NULL, w_space);
868 } else if (strcmp(token, "+i") == 0) {
869 flags &= ~REG_ICASE;
870 token = strtok(NULL, w_space);
871 }
872 if (token == NULL)
873 self_destruct();
874 pattern = xstrdup(token);
875 GetInteger(i); /* token: min */
876 min = (time_t) (i * 60); /* convert minutes to seconds */
877 GetInteger(i); /* token: pct */
878 pct = i;
879 GetInteger(i); /* token: max */
880 max = (time_t) (i * 60); /* convert minutes to seconds */
881 if ((errcode = regcomp(&comp, pattern, flags)) != 0) {
882 char errbuf[256];
883 regerror(errcode, &comp, errbuf, sizeof errbuf);
884 debug(22, 0) ("%s line %d: %s\n",
885 cfg_filename, config_lineno, config_input_line);
886 debug(22, 0) ("refreshAddToList: Invalid regular expression '%s': %s\n",
887 pattern, errbuf);
888 return;
889 }
890 pct = pct < 0 ? 0 : pct;
891 max = max < 0 ? 0 : max;
892 t = xcalloc(1, sizeof(refresh_t));
893 t->pattern = (char *) xstrdup(pattern);
894 t->compiled_pattern = comp;
895 t->min = min;
896 t->pct = pct;
897 t->max = max;
898 t->next = NULL;
899 while (*head)
900 head = &(*head)->next;
901 *head = t;
902 safe_free(pattern);
270b86af 903}
090089c4 904
270b86af 905static void
a47b9029 906free_refreshpattern(refresh_t ** head)
270b86af 907{
f1dc9b30 908 refresh_t *t;
909 while ((t = *head)) {
910 *head = t->next;
911 safe_free(t->pattern);
912 regfree(&t->compiled_pattern);
913 safe_free(t);
914 }
270b86af 915}
12b9e9b1 916
270b86af 917static void
918dump_regexlist(relist * var)
919{
b556b1e9 920 assert(0);
270b86af 921}
cf5fd929 922
270b86af 923static void
924parse_regexlist(relist ** var)
925{
0153d498 926 aclParseRegexList(var);
270b86af 927}
fb263c4c 928
270b86af 929static void
0153d498 930free_regexlist(relist ** var)
270b86af 931{
0153d498 932 aclDestroyRegexList(*var);
933 *var = NULL;
270b86af 934}
7d49daab 935
270b86af 936static void
0153d498 937dump_string(char *var)
270b86af 938{
939 printf("%s", var);
940}
98ffb7e4 941
270b86af 942static void
0153d498 943parse_string(char **var)
270b86af 944{
945 char *token = strtok(NULL, w_space);
270b86af 946 safe_free(*var);
947 if (token == NULL)
948 self_destruct();
949 *var = xstrdup(token);
950}
b15e6857 951
0153d498 952static void
953free_string(char **var)
954{
a47b9029 955 xfree(*var);
956 *var = NULL;
0153d498 957}
caebbe00 958
270b86af 959static void
f1dc9b30 960parse_eol(char *volatile *var)
270b86af 961{
962 char *token = strtok(NULL, null_string);
270b86af 963 safe_free(*var);
f1dc9b30 964 if (token == NULL)
965 self_destruct();
270b86af 966 *var = xstrdup(token);
967}
090089c4 968
270b86af 969static void
f1dc9b30 970dump_time_t(time_t var)
090089c4 971{
f1dc9b30 972 printf("%d", (int) var);
090089c4 973}
974
270b86af 975static void
a47b9029 976parse_time_t(time_t * var)
0ffd22bc 977{
f1dc9b30 978 parseTimeLine(var, T_SECOND_STR);
0ffd22bc 979}
980
270b86af 981static void
a47b9029 982free_time_t(time_t * var)
270b86af 983{
a47b9029 984 *var = 0;
270b86af 985}
9906e724 986
987static void
988dump_size_t(size_t var)
1b635117 989{
990 printf("%d", (int) var);
991}
992
993static void
994dump_b_size_t(size_t var)
9906e724 995{
996 printf("%d bytes", (int) var);
997}
998
999static void
1000dump_kb_size_t(size_t var)
1001{
1002 printf("%d KB", (int) var);
1003}
1004
1005static void
a47b9029 1006parse_size_t(size_t * var)
1b635117 1007{
1008 char *token;
1009 int i;
1010 GetInteger(i);
1011 *var = (size_t) i;
1012}
1013
1014static void
1015parse_b_size_t(size_t * var)
9906e724 1016{
1017 parseBytesLine(var, B_BYTES_STR);
1018}
1019
1020static void
a47b9029 1021parse_kb_size_t(size_t * var)
9906e724 1022{
1023 parseBytesLine(var, B_KBYTES_STR);
1024}
1025
1026static void
a47b9029 1027free_size_t(size_t * var)
9906e724 1028{
a47b9029 1029 *var = 0;
9906e724 1030}
1031
1b635117 1032#define free_b_size_t free_size_t
9906e724 1033#define free_kb_size_t free_size_t
1034#define free_mb_size_t free_size_t
1035#define free_gb_size_t free_size_t
090089c4 1036
8203a132 1037static void
270b86af 1038dump_ushort(u_short var)
090089c4 1039{
270b86af 1040 printf("%d", var);
1041}
090089c4 1042
0153d498 1043static void
a47b9029 1044free_ushort(u_short * u)
0153d498 1045{
1046 *u = 0;
1047}
1048
270b86af 1049static void
1050parse_ushort(u_short * var)
1051{
1052 char *token;
1053 int i;
090089c4 1054
270b86af 1055 GetInteger(i);
1056 if (i < 0)
1057 i = 0;
1058 *var = (u_short) i;
090089c4 1059}
1060
270b86af 1061static void
1062dump_wordlist(wordlist * list)
1063{
1064 printf("{");
1065 while (list != NULL) {
1066 printf("%s ", list->key);
1067 list = list->next;
429fdbec 1068 }
270b86af 1069 printf("}");
429fdbec 1070}
1071
270b86af 1072static void
1073parse_wordlist(wordlist ** list)
429fdbec 1074{
270b86af 1075 char *token;
1076
1077 while ((token = strtok(NULL, w_space)))
1078 wordlistAdd(list, token);
429fdbec 1079}
270b86af 1080
0153d498 1081#define free_wordlist wordlistDestroy
270b86af 1082
1083#include "cf_parser.c"
f1dc9b30 1084
1085peer_t
1086parseNeighborType(const char *s)
1087{
1088 if (!strcasecmp(s, "parent"))
1089 return PEER_PARENT;
1090 if (!strcasecmp(s, "neighbor"))
1091 return PEER_SIBLING;
1092 if (!strcasecmp(s, "neighbour"))
1093 return PEER_SIBLING;
1094 if (!strcasecmp(s, "sibling"))
1095 return PEER_SIBLING;
1096 if (!strcasecmp(s, "multicast"))
1097 return PEER_MULTICAST;
1098 debug(15, 0) ("WARNING: Unknown neighbor type: %s\n", s);
1099 return PEER_SIBLING;
1100}
f150dd4b 1101
1102void
1103configFreeMemory(void)
1104{
23ff6968 1105 free_all();
f150dd4b 1106}