]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_cf.cc
Squid SNMP code rewrite
[thirdparty/squid.git] / src / cache_cf.cc
CommitLineData
be335c22 1
30a4f2a8 2/*
dba79ac5 3 * $Id: cache_cf.cc,v 1.309 1998/11/11 20:04:12 glenn Exp $
30a4f2a8 4 *
5 * DEBUG: section 3 Configuration File Parsing
6 * AUTHOR: Harvest Derived
7 *
42c04c16 8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
e25c139f 9 * ----------------------------------------------------------
30a4f2a8 10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
e25c139f 13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
30a4f2a8 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
30a4f2a8 34 */
cf5fd929 35
44a47c6e 36#include "squid.h"
1df370e3 37
38#if SQUID_SNMP
a97cfa48 39#include "snmp.h"
1df370e3 40#endif
090089c4 41
8813e606 42static const char *const T_SECOND_STR = "second";
43static const char *const T_MINUTE_STR = "minute";
44static const char *const T_HOUR_STR = "hour";
45static const char *const T_DAY_STR = "day";
46static const char *const T_WEEK_STR = "week";
47static const char *const T_FORTNIGHT_STR = "fortnight";
48static const char *const T_MONTH_STR = "month";
49static const char *const T_YEAR_STR = "year";
50static const char *const T_DECADE_STR = "decade";
aa0a0c7c 51
9906e724 52static const char *const B_BYTES_STR = "bytes";
53static const char *const B_KBYTES_STR = "KB";
54static const char *const B_MBYTES_STR = "MB";
55static const char *const B_GBYTES_STR = "GB";
56
4db43fab 57static const char *const list_sep = ", \t\n\r";
090089c4 58
f5b8bbc4 59static void self_destruct(void);
caebbe00 60
f5b8bbc4 61static void configDoConfigure(void);
62static void parse_refreshpattern(refresh_t **);
63static int parseTimeUnits(const char *unit);
64static void parseTimeLine(time_t * tptr, const char *units);
65static void parse_string(char **);
66static void parse_wordlist(wordlist **);
67static void default_all(void);
68static void defaults_if_none(void);
69static int parse_line(char *);
70static void parseBytesLine(size_t * bptr, const char *units);
71static size_t parseBytesUnits(const char *unit);
f5b8bbc4 72static void free_all(void);
f0b19334 73static void requirePathnameExists(const char *name, const char *path);
ed7f5615 74static OBJH dump_config;
270b86af 75
24382924 76static void
0673c0ba 77self_destruct(void)
090089c4 78{
137ee196 79 fatalf("Bungled %s line %d: %s",
b8de7ebe 80 cfg_filename, config_lineno, config_input_line);
090089c4 81}
82
8203a132 83void
84wordlistDestroy(wordlist ** list)
0ffd22bc 85{
86 wordlist *w = NULL;
79d39a72 87 while ((w = *list) != NULL) {
b5639035 88 *list = w->next;
0ffd22bc 89 safe_free(w->key);
90 safe_free(w);
91 }
92 *list = NULL;
93}
94
74addf6c 95void
fe4e214f 96wordlistAdd(wordlist ** list, const char *key)
090089c4 97{
0ffd22bc 98 wordlist *p = NULL;
99 wordlist *q = NULL;
090089c4 100
101 if (!(*list)) {
102 /* empty list */
30a4f2a8 103 *list = xcalloc(1, sizeof(wordlist));
090089c4 104 (*list)->key = xstrdup(key);
105 (*list)->next = NULL;
106 } else {
107 p = *list;
108 while (p->next)
109 p = p->next;
30a4f2a8 110 q = xcalloc(1, sizeof(wordlist));
090089c4 111 q->key = xstrdup(key);
112 q->next = NULL;
113 p->next = q;
114 }
115}
116
137ee196 117void
eeb423fb 118wordlistCat(const wordlist * w, MemBuf * mb)
5da06f20 119{
5da06f20 120 while (NULL != w) {
137ee196 121 memBufPrintf(mb, "%s\n", w->key);
5da06f20 122 w = w->next;
123 }
5da06f20 124}
125
8203a132 126void
127intlistDestroy(intlist ** list)
92a6f4b1 128{
129 intlist *w = NULL;
130 intlist *n = NULL;
92a6f4b1 131 for (w = *list; w; w = n) {
132 n = w->next;
133 safe_free(w);
134 }
135 *list = NULL;
136}
137
5db53b8f 138int
139intlistFind(intlist * list, int i)
140{
141 intlist *w = NULL;
142 for (w = list; w; w = w->next)
143 if (w->i == i)
144 return 1;
145 return 0;
146}
147
403279e0 148
3c5557f9 149/*
150 * Use this #define in all the parse*() functions. Assumes char *token is
151 * defined
152 */
090089c4 153
154#define GetInteger(var) \
155 token = strtok(NULL, w_space); \
30a4f2a8 156 if( token == NULL) \
3003c0f3 157 self_destruct(); \
090089c4 158 if (sscanf(token, "%d", &var) != 1) \
3003c0f3 159 self_destruct();
090089c4 160
270b86af 161int
162parseConfigFile(const char *file_name)
2546fcb3 163{
270b86af 164 FILE *fp = NULL;
165 char *token = NULL;
72121e8b 166 char *tmp_line;
0153d498 167 free_all();
168 default_all();
137ee196 169 if ((fp = fopen(file_name, "r")) == NULL)
170 fatalf("Unable to open configuration file: %s: %s",
270b86af 171 file_name, xstrerror());
270b86af 172 cfg_filename = file_name;
173 if ((token = strrchr(cfg_filename, '/')))
174 cfg_filename = token + 1;
175 memset(config_input_line, '\0', BUFSIZ);
176 config_lineno = 0;
177 while (fgets(config_input_line, BUFSIZ, fp)) {
178 config_lineno++;
179 if ((token = strchr(config_input_line, '\n')))
180 *token = '\0';
181 if (config_input_line[0] == '#')
182 continue;
183 if (config_input_line[0] == '\0')
184 continue;
185 debug(3, 5) ("Processing: '%s'\n", config_input_line);
72121e8b 186 tmp_line = xstrdup(config_input_line);
270b86af 187 if (!parse_line(tmp_line)) {
188 debug(3, 0) ("parseConfigFile: line %d unrecognized: '%s'\n",
189 config_lineno,
190 config_input_line);
191 }
72121e8b 192 safe_free(tmp_line);
270b86af 193 }
f0b19334 194 fclose(fp);
195 defaults_if_none();
196 configDoConfigure();
22f3fd98 197 cachemgrRegister("config",
198 "Current Squid Configuration",
199 dump_config,
1da3b90b 200 1, 1);
f0b19334 201 return 0;
202}
270b86af 203
f0b19334 204static void
205configDoConfigure(void)
206{
207 LOCAL_ARRAY(char, buf, BUFSIZ);
208 memset(&Config2, '\0', sizeof(SquidConfig2));
7021844c 209 /* init memory as early as possible */
210 memConfigure();
270b86af 211 /* Sanity checks */
a95856a0 212 if (Config.cacheSwap.swapDirs == NULL)
213 fatal("No cache_dir's specified in config file");
9fa8263f 214 /* calculate Config.Swap.maxSize */
f4e3fa54 215 storeDirConfigure();
f0b19334 216 if (Config.Swap.maxSize < (Config.Mem.maxSize >> 10))
217 fatal("cache_swap is lower than cache_mem");
84f42bac 218 if (Config.Announce.period > 0) {
219 Config.onoff.announce = 1;
220 } else if (Config.Announce.period < 1) {
f1dc9b30 221 Config.Announce.period = 86400 * 365; /* one year */
17a0a4ee 222 Config.onoff.announce = 0;
270b86af 223 }
f0b19334 224 if (Config.dnsChildren < 1)
225 fatal("No dnsservers allocated");
226 if (Config.dnsChildren > DefaultDnsChildrenMax) {
227 debug(3, 0) ("WARNING: dns_children was set to a bad value: %d\n",
270b86af 228 Config.dnsChildren);
f0b19334 229 debug(3, 0) ("Setting it to the maximum (%d).\n",
230 DefaultDnsChildrenMax);
270b86af 231 Config.dnsChildren = DefaultDnsChildrenMax;
232 }
233 if (Config.Program.redirect) {
234 if (Config.redirectChildren < 1) {
235 Config.redirectChildren = 0;
236 safe_free(Config.Program.redirect);
237 } else if (Config.redirectChildren > DefaultRedirectChildrenMax) {
f0b19334 238 debug(3, 0) ("WARNING: redirect_children was set to a bad value: %d\n",
270b86af 239 Config.redirectChildren);
f0b19334 240 debug(3, 0) ("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax);
270b86af 241 Config.redirectChildren = DefaultRedirectChildrenMax;
242 }
fea2e6e0 243 }
73e67ee0 244 if (Config.Program.authenticate) {
245 if (Config.authenticateChildren < 1) {
246 Config.authenticateChildren = 0;
6c20b822 247 wordlistDestroy(&Config.Program.authenticate);
73e67ee0 248 } else if (Config.authenticateChildren > DefaultAuthenticateChildrenMax) {
249 debug(3, 0) ("WARNING: authenticate_children was set to a bad value: %d\n",
250 Config.authenticateChildren);
251 debug(3, 0) ("Setting it to the maximum (%d).\n", DefaultAuthenticateChildrenMax);
252 Config.authenticateChildren = DefaultAuthenticateChildrenMax;
253 }
254 }
f1dc9b30 255 if (Config.Accel.host) {
a47b9029 256 snprintf(buf, BUFSIZ, "http://%s:%d", Config.Accel.host, Config.Accel.port);
257 Config2.Accel.prefix = xstrdup(buf);
258 Config2.Accel.on = 1;
f1dc9b30 259 }
260 if (Config.appendDomain)
261 if (*Config.appendDomain != '.')
262 fatal("append_domain must begin with a '.'");
270b86af 263 if (Config.errHtmlText == NULL)
264 Config.errHtmlText = xstrdup(null_string);
265 storeConfigure();
f1dc9b30 266 if (Config2.Accel.on && !strcmp(Config.Accel.host, "virtual"))
270b86af 267 vhost_mode = 1;
268 if (Config.Port.http == NULL)
269 fatal("No http_port specified!");
137ee196 270 snprintf(ThisCache, sizeof(ThisCache), "%s:%d (%s)",
98829f69 271 uniqueHostname(),
270b86af 272 (int) Config.Port.http->i,
137ee196 273 full_appname_string);
270b86af 274 if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF)
275 Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF;
276 if (Config.appendDomain)
277 Config.appendDomainLen = strlen(Config.appendDomain);
278 else
279 Config.appendDomainLen = 0;
f1dc9b30 280 safe_free(debug_options)
281 debug_options = xstrdup(Config.debugOptions);
22c653cd 282 if (Config.retry.timeout < 5)
283 fatal("minimum_retry_timeout must be at least 5 seconds");
284 if (Config.retry.maxtries > 10)
285 fatal("maximum_single_addr_tries cannot be larger than 10");
286 if (Config.retry.maxtries < 1) {
22c653cd 287 debug(3, 0) ("WARNING: resetting 'maximum_single_addr_tries to 1\n");
5210854d 288 Config.retry.maxtries = 1;
289 }
290 if (Config.referenceAge < 300) {
291 debug(3, 0) ("WARNING: resetting 'reference_age' to 1 week\n");
292 Config.referenceAge = 86400 * 7;
22c653cd 293 }
f0b19334 294 requirePathnameExists("MIME Config Table", Config.mimeTablePathname);
295 requirePathnameExists("cache_dns_program", Config.Program.dnsserver);
296 requirePathnameExists("unlinkd_program", Config.Program.unlinkd);
297 if (Config.Program.redirect)
298 requirePathnameExists("redirect_program", Config.Program.redirect);
73e67ee0 299 if (Config.Program.authenticate)
6c20b822 300 requirePathnameExists("authenticate_program", Config.Program.authenticate->key);
f0b19334 301 requirePathnameExists("Icon Directory", Config.icons.directory);
302 requirePathnameExists("Error Directory", Config.errorDirectory);
9f60cfdf 303#if HTTP_VIOLATIONS
304 {
49c0f46d 305 const refresh_t *R;
306 for (R = Config.Refresh; R; R = R->next) {
307 if (!R->flags.override_expire)
308 continue;
309 debug(22, 1) ("WARNING: use of 'override-expire' in 'refresh_pattern' violates HTTP\n");
310 break;
311 }
312 for (R = Config.Refresh; R; R = R->next) {
313 if (!R->flags.override_lastmod)
314 continue;
315 debug(22, 1) ("WARNING: use of 'override-lastmod' in 'refresh_pattern' violates HTTP\n");
316 break;
317 }
9f60cfdf 318 }
319#endif
090089c4 320}
321
270b86af 322/* Parse a time specification from the config file. Store the
f1dc9b30 323 * result in 'tptr', after converting it to 'units' */
8203a132 324static void
a47b9029 325parseTimeLine(time_t * tptr, const char *units)
090089c4 326{
327 char *token;
270b86af 328 double d;
f1dc9b30 329 time_t m;
330 time_t u;
270b86af 331 if ((u = parseTimeUnits(units)) == 0)
3003c0f3 332 self_destruct();
270b86af 333 if ((token = strtok(NULL, w_space)) == NULL)
3003c0f3 334 self_destruct();
270b86af 335 d = atof(token);
336 m = u; /* default to 'units' if none specified */
10738561 337 if (0 == d)
338 (void) 0;
339 else if ((token = strtok(NULL, w_space)) == NULL)
a47b9029 340 debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
341 config_input_line, d, units);
9e975e4e 342 else if ((m = parseTimeUnits(token)) == 0)
a47b9029 343 self_destruct();
f1dc9b30 344 *tptr = m * d / u;
090089c4 345}
346
270b86af 347static int
348parseTimeUnits(const char *unit)
349{
350 if (!strncasecmp(unit, T_SECOND_STR, strlen(T_SECOND_STR)))
351 return 1;
352 if (!strncasecmp(unit, T_MINUTE_STR, strlen(T_MINUTE_STR)))
353 return 60;
354 if (!strncasecmp(unit, T_HOUR_STR, strlen(T_HOUR_STR)))
355 return 3600;
356 if (!strncasecmp(unit, T_DAY_STR, strlen(T_DAY_STR)))
357 return 86400;
358 if (!strncasecmp(unit, T_WEEK_STR, strlen(T_WEEK_STR)))
359 return 86400 * 7;
360 if (!strncasecmp(unit, T_FORTNIGHT_STR, strlen(T_FORTNIGHT_STR)))
361 return 86400 * 14;
362 if (!strncasecmp(unit, T_MONTH_STR, strlen(T_MONTH_STR)))
363 return 86400 * 30;
364 if (!strncasecmp(unit, T_YEAR_STR, strlen(T_YEAR_STR)))
365 return 86400 * 365.2522;
366 if (!strncasecmp(unit, T_DECADE_STR, strlen(T_DECADE_STR)))
367 return 86400 * 365.2522 * 10;
368 debug(3, 1) ("parseTimeUnits: unknown time unit '%s'\n", unit);
369 return 0;
370}
371
9906e724 372static void
9e975e4e 373parseBytesLine(size_t * bptr, const char *units)
9906e724 374{
375 char *token;
376 double d;
377 size_t m;
378 size_t u;
379 if ((u = parseBytesUnits(units)) == 0)
380 self_destruct();
381 if ((token = strtok(NULL, w_space)) == NULL)
382 self_destruct();
383 d = atof(token);
384 m = u; /* default to 'units' if none specified */
10738561 385 if (0 == d)
386 (void) 0;
4860dc1b 387 else if ((token = strtok(NULL, w_space)) == NULL)
9e975e4e 388 debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
389 config_input_line, d, units);
390 else if ((m = parseBytesUnits(token)) == 0)
391 self_destruct();
9906e724 392 *bptr = m * d / u;
393}
394
395static size_t
396parseBytesUnits(const char *unit)
397{
398 if (!strncasecmp(unit, B_BYTES_STR, strlen(B_BYTES_STR)))
399 return 1;
400 if (!strncasecmp(unit, B_KBYTES_STR, strlen(B_KBYTES_STR)))
a47b9029 401 return 1 << 10;
9906e724 402 if (!strncasecmp(unit, B_MBYTES_STR, strlen(B_MBYTES_STR)))
a47b9029 403 return 1 << 20;
9906e724 404 if (!strncasecmp(unit, B_GBYTES_STR, strlen(B_GBYTES_STR)))
a47b9029 405 return 1 << 30;
9906e724 406 debug(3, 1) ("parseBytesUnits: unknown bytes unit '%s'\n", unit);
407 return 0;
408}
409
270b86af 410/*****************************************************************************
411 * Max
412 *****************************************************************************/
413
8203a132 414static void
9ef28b60 415dump_acl(StoreEntry * entry, const char *name, acl * ae)
090089c4 416{
56b63fa1 417 wordlist *w;
418 wordlist *v;
9ef28b60 419 while (ae != NULL) {
420 v = w = aclDumpGeneric(ae);
56b63fa1 421 while (v != NULL) {
16300b58 422 storeAppendPrintf(entry, "%s %s %s %s\n",
423 name,
9ef28b60 424 ae->name,
425 aclTypeToStr(ae->type),
16300b58 426 v->key);
56b63fa1 427 v = v->next;
428 }
429 wordlistDestroy(&w);
9ef28b60 430 ae = ae->next;
56b63fa1 431 }
090089c4 432}
433
8203a132 434static void
9ef28b60 435parse_acl(acl ** ae)
090089c4 436{
9ef28b60 437 aclParseAclLine(ae);
f1dc9b30 438}
439
440static void
9ef28b60 441free_acl(acl ** ae)
f1dc9b30 442{
9ef28b60 443 aclDestroyAcls(ae);
090089c4 444}
445
8203a132 446static void
16300b58 447dump_acl_access(StoreEntry * entry, const char *name, acl_access * head)
30a4f2a8 448{
56b63fa1 449 acl_list *l;
450 while (head != NULL) {
505e35db 451 storeAppendPrintf(entry, "%s %s",
0cdcddb9 452 name,
505e35db 453 head->allow ? "Allow" : "Deny");
454 for (l = head->acl_list; l != NULL; l = l->next) {
455 storeAppendPrintf(entry, " %s%s",
456 l->op ? null_string : "!",
56b63fa1 457 l->acl->name);
16300b58 458 }
505e35db 459 storeAppendPrintf(entry, "\n");
56b63fa1 460 head = head->next;
461 }
30a4f2a8 462}
090089c4 463
8203a132 464static void
16300b58 465parse_acl_access(acl_access ** head)
090089c4 466{
270b86af 467 aclParseAccessLine(head);
090089c4 468}
469
0153d498 470static void
16300b58 471free_acl_access(acl_access ** head)
0153d498 472{
a47b9029 473 aclDestroyAccessList(head);
0153d498 474}
475
8203a132 476static void
a7d59104 477dump_address(StoreEntry * entry, const char *name, struct in_addr addr)
270b86af 478{
f53b06f9 479 storeAppendPrintf(entry, "%s %s\n", name, inet_ntoa(addr));
270b86af 480}
481
482static void
483parse_address(struct in_addr *addr)
090089c4 484{
0ee4272b 485 const struct hostent *hp;
270b86af 486 char *token = strtok(NULL, w_space);
487
30a4f2a8 488 if (token == NULL)
489 self_destruct();
429fdbec 490 if (safe_inet_addr(token, addr) == 1)
491 (void) 0;
ceb8994e 492 else if ((hp = gethostbyname(token))) /* dont use ipcache */
1d73e33a 493 *addr = inaddrFromHostent(hp);
30a4f2a8 494 else
3003c0f3 495 self_destruct();
090089c4 496}
497
0153d498 498static void
499free_address(struct in_addr *addr)
500{
a47b9029 501 memset(addr, '\0', sizeof(struct in_addr));
0153d498 502}
503
e90100aa 504static void
56b63fa1 505dump_cachedir(StoreEntry * entry, const char *name, cacheSwap swap)
e90100aa 506{
f53b06f9 507 SwapDir *s;
508 int i;
a7d59104 509 for (i = 0; i < swap.n_configured; i++) {
510 s = swap.swapDirs + i;
f53b06f9 511 storeAppendPrintf(entry, "%s %s %d %d %d\n",
512 name,
513 s->path,
a7d59104 514 s->max_size >> 10,
f53b06f9 515 s->l1,
516 s->l2);
517 }
518}
519
520static int
56b63fa1 521check_null_cachedir(cacheSwap swap)
f53b06f9 522{
523 return swap.swapDirs == NULL;
e90100aa 524}
525
53ad48e6 526static int
527check_null_string(char *s)
528{
529 return s == NULL;
530}
531
8203a132 532static void
16300b58 533parse_cachedir(cacheSwap * swap)
090089c4 534{
535 char *token;
7da279d6 536 char *path;
752c3b27 537 int i;
270b86af 538 int size;
539 int l1;
540 int l2;
541 int readonly = 0;
f1dc9b30 542 SwapDir *tmp = NULL;
543 if ((path = strtok(NULL, w_space)) == NULL)
752c3b27 544 self_destruct();
270b86af 545 GetInteger(i);
546 size = i << 10; /* Mbytes to kbytes */
893dbb06 547 if (size <= 0)
548 fatal("parse_cachedir: invalid size value");
270b86af 549 GetInteger(i);
550 l1 = i;
893dbb06 551 if (l1 <= 0)
552 fatal("parse_cachedir: invalid level 1 directories value");
270b86af 553 GetInteger(i);
554 l2 = i;
893dbb06 555 if (l2 <= 0)
556 fatal("parse_cachedir: invalid level 2 directories value");
270b86af 557 if ((token = strtok(NULL, w_space)))
558 if (!strcasecmp(token, "read-only"))
559 readonly = 1;
f1dc9b30 560 for (i = 0; i < swap->n_configured; i++) {
a47b9029 561 tmp = swap->swapDirs + i;
f1dc9b30 562 if (!strcmp(path, tmp->path)) {
563 /* just reconfigure it */
860ee7e3 564 if (size == tmp->max_size)
d61b4908 565 debug(3, 1) ("Cache dir '%s' size remains unchanged at %d KB\n",
be335c22 566 path, size);
860ee7e3 567 else
d61b4908 568 debug(3, 1) ("Cache dir '%s' size changed to %d KB\n",
be335c22 569 path, size);
a47b9029 570 tmp->max_size = size;
860ee7e3 571 if (tmp->read_only != readonly)
be335c22 572 debug(3, 1) ("Cache dir '%s' now %s\n",
573 readonly ? "Read-Only" : "Read-Write");
a47b9029 574 tmp->read_only = readonly;
f1dc9b30 575 return;
576 }
577 }
578 if (swap->swapDirs == NULL) {
579 swap->n_allocated = 4;
580 swap->swapDirs = xcalloc(swap->n_allocated, sizeof(SwapDir));
581 }
582 if (swap->n_allocated == swap->n_configured) {
583 swap->n_allocated <<= 1;
584 tmp = xcalloc(swap->n_allocated, sizeof(SwapDir));
585 xmemcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir));
586 xfree(swap->swapDirs);
587 swap->swapDirs = tmp;
588 }
f1dc9b30 589 tmp = swap->swapDirs + swap->n_configured;
590 tmp->path = xstrdup(path);
591 tmp->max_size = size;
592 tmp->l1 = l1;
593 tmp->l2 = l2;
594 tmp->read_only = readonly;
f1dc9b30 595 tmp->swaplog_fd = -1;
62607543 596 swap->n_configured++;
752c3b27 597}
598
8203a132 599static void
16300b58 600free_cachedir(cacheSwap * swap)
f1dc9b30 601{
a47b9029 602 SwapDir *s;
603 int i;
860ee7e3 604 /* DON'T FREE THESE FOR RECONFIGURE */
5cd39a10 605 if (reconfiguring)
860ee7e3 606 return;
a47b9029 607 for (i = 0; i < swap->n_configured; i++) {
608 s = swap->swapDirs + i;
f150dd4b 609 if (s->swaplog_fd > -1) {
610 file_close(s->swaplog_fd);
611 s->swaplog_fd = -1;
612 }
a47b9029 613 xfree(s->path);
614 filemapFreeMemory(s->map);
615 }
616 safe_free(swap->swapDirs);
617 swap->swapDirs = NULL;
618 swap->n_allocated = 0;
619 swap->n_configured = 0;
f1dc9b30 620}
621
505e35db 622const char *
623peer_type_str(const peer_t type)
624{
0cdcddb9 625 switch (type) {
505e35db 626 case PEER_PARENT:
627 return "parent";
628 break;
629 case PEER_SIBLING:
630 return "sibling";
631 break;
632 case PEER_MULTICAST:
633 return "multicast";
634 break;
635 default:
636 return "unknown";
637 break;
638 }
639}
640
f1dc9b30 641static void
a7d59104 642dump_peer(StoreEntry * entry, const char *name, peer * p)
98ffb7e4 643{
505e35db 644 domain_ping *d;
645 acl_access *a;
646 domain_type *t;
647 LOCAL_ARRAY(char, xname, 128);
d41de3c1 648 while (p != NULL) {
649 storeAppendPrintf(entry, "%s %s %s %d %d",
650 name,
651 p->host,
652 neighborTypeStr(p),
653 p->http_port,
399cabec 654 p->icp.port);
a369131d 655 dump_peer_options(entry, p);
505e35db 656 for (d = p->pinglist; d; d = d->next) {
657 storeAppendPrintf(entry, "cache_peer_domain %s %s%s\n",
658 p->host,
659 d->do_ping ? null_string : "!",
660 d->domain);
661 }
662 if ((a = p->access)) {
663 snprintf(xname, 128, "cache_peer_access %s", p->host);
664 dump_acl_access(entry, xname, p->access);
665 }
666 for (t = p->typelist; t; t = t->next) {
667 storeAppendPrintf(entry, "neighbor_type_domain %s %s %s\n",
668 p->host,
669 peer_type_str(t->type),
670 t->domain);
671 }
d41de3c1 672 p = p->next;
673 }
98ffb7e4 674}
675
8203a132 676static void
40a1495e 677parse_peer(peer ** head)
7813c6d5 678{
270b86af 679 char *token = NULL;
40a1495e 680 peer *p;
7813c6d5 681 int i;
40a1495e 682 ushortlist *u;
f9e5a344 683 const char *me = null_string; /* XXX */
40a1495e 684 p = xcalloc(1, sizeof(peer));
685 p->http_port = CACHE_HTTP_PORT;
399cabec 686 p->icp.port = CACHE_ICP_PORT;
40a1495e 687 p->weight = 1;
dc835977 688 p->stats.logged_state = PEER_ALIVE;
e481c2dc 689 if ((token = strtok(NULL, w_space)) == NULL)
270b86af 690 self_destruct();
40a1495e 691 p->host = xstrdup(token);
e481c2dc 692 if ((token = strtok(NULL, w_space)) == NULL)
270b86af 693 self_destruct();
40a1495e 694 p->type = parseNeighborType(token);
270b86af 695 GetInteger(i);
40a1495e 696 p->http_port = (u_short) i;
e8d185d2 697 GetInteger(i);
399cabec 698 p->icp.port = (u_short) i;
40a1495e 699 if (strcmp(p->host, me) == 0) {
700 for (u = Config.Port.http; u; u = u->next) {
701 if (p->http_port != u->i)
702 continue;
703 debug(15, 0) ("parse_peer: Peer looks like myself: %s %s/%d/%d\n",
399cabec 704 p->type, p->host, p->http_port, p->icp.port);
40a1495e 705 self_destruct();
706 }
707 }
270b86af 708 while ((token = strtok(NULL, w_space))) {
709 if (!strcasecmp(token, "proxy-only")) {
cd196bc8 710 p->options.proxy_only = 1;
270b86af 711 } else if (!strcasecmp(token, "no-query")) {
cd196bc8 712 p->options.no_query = 1;
8638fc66 713 } else if (!strcasecmp(token, "no-digest")) {
cd196bc8 714 p->options.no_digest = 1;
270b86af 715 } else if (!strcasecmp(token, "multicast-responder")) {
cd196bc8 716 p->options.mcast_responder = 1;
270b86af 717 } else if (!strncasecmp(token, "weight=", 7)) {
40a1495e 718 p->weight = atoi(token + 7);
0103c4c1 719 } else if (!strcasecmp(token, "closest-only")) {
cd196bc8 720 p->options.closest_only = 1;
270b86af 721 } else if (!strncasecmp(token, "ttl=", 4)) {
40a1495e 722 p->mcast.ttl = atoi(token + 4);
723 if (p->mcast.ttl < 0)
724 p->mcast.ttl = 0;
725 if (p->mcast.ttl > 128)
726 p->mcast.ttl = 128;
0103c4c1 727 } else if (!strcasecmp(token, "default")) {
cd196bc8 728 p->options.default_parent = 1;
0103c4c1 729 } else if (!strcasecmp(token, "round-robin")) {
cd196bc8 730 p->options.roundrobin = 1;
dc9d133b 731#if USE_HTCP
0103c4c1 732 } else if (!strcasecmp(token, "htcp")) {
cd196bc8 733 p->options.htcp = 1;
dc9d133b 734#endif
0103c4c1 735 } else if (!strcasecmp(token, "no-netdb-exchange")) {
cd196bc8 736 p->options.no_netdb_exchange = 1;
afd88fbe 737#if USE_CARP
738 } else if (!strncasecmp(token, "carp-load-factor=", 17)) {
739 if (p->type != PEER_PARENT)
0cdcddb9 740 debug(3, 0) ("parse_peer: Ignoring carp-load-factor for non-parent %s/%d\n", p->host, p->http_port);
741 else
742 p->carp.load_factor = atof(token + 17);
95e36d02 743#endif
744#if DELAY_POOLS
745 } else if (!strcasecmp(token, "no-delay")) {
cd196bc8 746 p->options.no_delay = 1;
afd88fbe 747#endif
270b86af 748 } else {
40a1495e 749 debug(3, 0) ("parse_peer: token='%s'\n", token);
270b86af 750 self_destruct();
751 }
752 }
40a1495e 753 if (p->weight < 1)
754 p->weight = 1;
399cabec 755 p->icp.version = ICP_VERSION_CURRENT;
98829f69 756 p->tcp_up = PEER_TCP_MAGIC_COUNT;
afd88fbe 757#if USE_CARP
758 if (p->carp.load_factor) {
0cdcddb9 759 /*
760 * calculate this peers hash for use in CARP
761 */
762 p->carp.hash = 0;
763 for (token = p->host; *token != 0; token++)
764 p->carp.hash += (p->carp.hash << 19) + *token;
afd88fbe 765 }
766#endif
3f6c0fb2 767 cbdataAdd(p, MEM_NONE);
0153d498 768 while (*head != NULL)
769 head = &(*head)->next;
770 *head = p;
40a1495e 771 Config.npeers++;
0153d498 772}
773
774static void
40a1495e 775free_peer(peer ** P)
0153d498 776{
40a1495e 777 peer *p;
79d39a72 778 while ((p = *P) != NULL) {
a47b9029 779 *P = p->next;
40a1495e 780 peerDestroy(p);
a47b9029 781 }
987c67d1 782 Config.npeers = 0;
270b86af 783}
784
785static void
a7d59104 786dump_cachemgrpasswd(StoreEntry * entry, const char *name, cachemgr_passwd * list)
270b86af 787{
d41de3c1 788 wordlist *w;
789 while (list != NULL) {
790 storeAppendPrintf(entry, "%s XXXXXXXXXX", name);
791 for (w = list->actions; w != NULL; w = w->next) {
792 storeAppendPrintf(entry, " %s", w->key);
793 }
794 storeAppendPrintf(entry, "\n");
795 list = list->next;
796 }
270b86af 797}
798
799static void
a47b9029 800parse_cachemgrpasswd(cachemgr_passwd ** head)
270b86af 801{
802 char *passwd = NULL;
803 wordlist *actions = NULL;
22f3fd98 804 cachemgr_passwd *p;
805 cachemgr_passwd **P;
270b86af 806 parse_string(&passwd);
807 parse_wordlist(&actions);
22f3fd98 808 p = xcalloc(1, sizeof(cachemgr_passwd));
809 p->passwd = passwd;
810 p->actions = actions;
811 for (P = head; *P; P = &(*P)->next);
812 *P = p;
270b86af 813}
814
815static void
a47b9029 816free_cachemgrpasswd(cachemgr_passwd ** head)
270b86af 817{
a47b9029 818 cachemgr_passwd *p;
79d39a72 819 while ((p = *head) != NULL) {
a47b9029 820 *head = p->next;
821 xfree(p->passwd);
22f3fd98 822 wordlistDestroy(&p->actions);
a47b9029 823 xfree(p);
824 }
270b86af 825}
826
8203a132 827static void
16300b58 828dump_denyinfo(StoreEntry * entry, const char *name, acl_deny_info_list * var)
270b86af 829{
d41de3c1 830 acl_name_list *a;
831 while (var != NULL) {
02922e76 832 storeAppendPrintf(entry, "%s %s", name, var->err_page_name);
d41de3c1 833 for (a = var->acl_list; a != NULL; a = a->next)
834 storeAppendPrintf(entry, " %s", a->name);
835 storeAppendPrintf(entry, "\n");
836 var = var->next;
837 }
270b86af 838}
839
840static void
16300b58 841parse_denyinfo(acl_deny_info_list ** var)
6e40f263 842{
f1dc9b30 843 aclParseDenyInfoLine(var);
6e40f263 844}
403279e0 845
1273d501 846void
a47b9029 847free_denyinfo(acl_deny_info_list ** list)
3c5557f9 848{
56b63fa1 849 acl_deny_info_list *a = NULL;
850 acl_deny_info_list *a_next = NULL;
851 acl_name_list *l = NULL;
852 acl_name_list *l_next = NULL;
1273d501 853 for (a = *list; a; a = a_next) {
a47b9029 854 for (l = a->acl_list; l; l = l_next) {
855 l_next = l->next;
856 safe_free(l);
857 }
858 a_next = a->next;
859 safe_free(a);
1273d501 860 }
861 *list = NULL;
270b86af 862}
863
864static void
505e35db 865parse_peer_access(void)
270b86af 866{
867 char *host = NULL;
505e35db 868 peer *p;
270b86af 869 if (!(host = strtok(NULL, w_space)))
870 self_destruct();
0cdcddb9 871 if ((p = peerFindByName(host)) == NULL) {
872 debug(15, 0) ("%s, line %d: No cache_peer '%s'\n",
873 cfg_filename, config_lineno, host);
874 return;
875 }
505e35db 876 aclParseAccessLine(&p->access);
270b86af 877}
878
270b86af 879static void
880parse_hostdomain(void)
881{
882 char *host = NULL;
883 char *domain = NULL;
884 if (!(host = strtok(NULL, w_space)))
885 self_destruct();
f1dc9b30 886 while ((domain = strtok(NULL, list_sep))) {
887 domain_ping *l = NULL;
888 domain_ping **L = NULL;
40a1495e 889 peer *p;
890 if ((p = peerFindByName(host)) == NULL) {
43c3424b 891 debug(15, 0) ("%s, line %d: No cache_peer '%s'\n",
f1dc9b30 892 cfg_filename, config_lineno, host);
893 continue;
894 }
56b63fa1 895 l = xcalloc(1, sizeof(domain_ping));
f1dc9b30 896 l->do_ping = 1;
897 if (*domain == '!') { /* check for !.edu */
898 l->do_ping = 0;
899 domain++;
900 }
901 l->domain = xstrdup(domain);
902 for (L = &(p->pinglist); *L; L = &((*L)->next));
903 *L = l;
904 }
270b86af 905}
906
907static void
908parse_hostdomaintype(void)
909{
910 char *host = NULL;
911 char *type = NULL;
912 char *domain = NULL;
913 if (!(host = strtok(NULL, w_space)))
914 self_destruct();
915 if (!(type = strtok(NULL, w_space)))
916 self_destruct();
f1dc9b30 917 while ((domain = strtok(NULL, list_sep))) {
918 domain_type *l = NULL;
919 domain_type **L = NULL;
40a1495e 920 peer *p;
921 if ((p = peerFindByName(host)) == NULL) {
43c3424b 922 debug(15, 0) ("%s, line %d: No cache_peer '%s'\n",
f1dc9b30 923 cfg_filename, config_lineno, host);
924 return;
925 }
56b63fa1 926 l = xcalloc(1, sizeof(domain_type));
f1dc9b30 927 l->type = parseNeighborType(type);
928 l->domain = xstrdup(domain);
929 for (L = &(p->typelist); *L; L = &((*L)->next));
930 *L = l;
931 }
270b86af 932}
933
934static void
a7d59104 935dump_httpanonymizer(StoreEntry * entry, const char *name, int var)
270b86af 936{
937 switch (var) {
938 case ANONYMIZER_NONE:
f0b19334 939 storeAppendPrintf(entry, "%s off\n", name);
270b86af 940 break;
941 case ANONYMIZER_STANDARD:
f0b19334 942 storeAppendPrintf(entry, "%s paranoid\n", name);
270b86af 943 break;
944 case ANONYMIZER_PARANOID:
f0b19334 945 storeAppendPrintf(entry, "%s standard\n", name);
270b86af 946 break;
947 }
948}
949
950static void
951parse_httpanonymizer(int *var)
fa562c67 952{
953 char *token;
954 token = strtok(NULL, w_space);
955 if (token == NULL)
bba6fa8f 956 self_destruct();
fa562c67 957 if (!strcasecmp(token, "off"))
270b86af 958 *var = ANONYMIZER_NONE;
fa562c67 959 else if (!strcasecmp(token, "paranoid"))
270b86af 960 *var = ANONYMIZER_PARANOID;
fa562c67 961 else
270b86af 962 *var = ANONYMIZER_STANDARD;
963}
964
641941c0 965
270b86af 966static void
a7d59104 967dump_ushortlist(StoreEntry * entry, const char *name, ushortlist * u)
090089c4 968{
270b86af 969 while (u) {
f53b06f9 970 storeAppendPrintf(entry, "%s %d\n", name, (int) u->i);
270b86af 971 u = u->next;
972 }
973}
090089c4 974
f53b06f9 975static int
976check_null_ushortlist(ushortlist * u)
977{
978 return u == NULL;
979}
980
270b86af 981static void
982parse_ushortlist(ushortlist ** P)
983{
984 char *token;
985 int i;
986 ushortlist *u;
987 ushortlist **U;
988 while ((token = strtok(NULL, w_space))) {
989 if (sscanf(token, "%d", &i) != 1)
990 self_destruct();
991 if (i < 0)
992 i = 0;
993 u = xcalloc(1, sizeof(ushortlist));
994 u->i = (u_short) i;
995 for (U = P; *U; U = &(*U)->next);
996 *U = u;
090089c4 997 }
270b86af 998}
090089c4 999
0153d498 1000static void
a47b9029 1001free_ushortlist(ushortlist ** P)
0153d498 1002{
a47b9029 1003 ushortlist *u;
79d39a72 1004 while ((u = *P) != NULL) {
a47b9029 1005 *P = u->next;
1006 xfree(u);
1007 }
0153d498 1008}
1009
270b86af 1010static void
a7d59104 1011dump_int(StoreEntry * entry, const char *name, int var)
270b86af 1012{
f53b06f9 1013 storeAppendPrintf(entry, "%s %d\n", name, var);
270b86af 1014}
c1c29eb6 1015
270b86af 1016static void
1017parse_int(int *var)
1018{
1019 char *token;
1020 int i;
270b86af 1021 GetInteger(i);
1022 *var = i;
1023}
090089c4 1024
0153d498 1025static void
1026free_int(int *var)
1027{
a47b9029 1028 *var = 0;
0153d498 1029}
1030
270b86af 1031static void
a7d59104 1032dump_onoff(StoreEntry * entry, const char *name, int var)
270b86af 1033{
f53b06f9 1034 storeAppendPrintf(entry, "%s %s\n", name, var ? "on" : "off");
270b86af 1035}
090089c4 1036
270b86af 1037static void
1038parse_onoff(int *var)
1039{
1040 char *token = strtok(NULL, w_space);
090089c4 1041
270b86af 1042 if (token == NULL)
1043 self_destruct();
1044 if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
1045 *var = 1;
1046 else
1047 *var = 0;
1048}
e90100aa 1049
0153d498 1050#define free_onoff free_int
f1dc9b30 1051#define free_httpanonymizer free_int
f1dc9b30 1052#define dump_eol dump_string
1053#define free_eol free_string
30a4f2a8 1054
270b86af 1055static void
a7d59104 1056dump_refreshpattern(StoreEntry * entry, const char *name, refresh_t * head)
270b86af 1057{
d41de3c1 1058 while (head != NULL) {
9f60cfdf 1059 storeAppendPrintf(entry, "%s%s %s %d %d%% %d\n",
c3f6d204 1060 name,
1061 head->flags.icase ? " -i" : null_string,
1062 head->pattern,
1063 (int) head->min / 60,
1064 (int) (100.0 * head->pct + 0.5),
9f60cfdf 1065 (int) head->max / 60);
1066#if HTTP_VIOLATIONS
1067 if (head->flags.override_expire)
1068 storeAppendPrintf(entry, " override-expire");
1069 if (head->flags.override_lastmod)
1070 storeAppendPrintf(entry, " override-lastmod");
1071 if (head->flags.reload_into_ims)
1072 storeAppendPrintf(entry, " reload-into-ims");
1073 if (head->flags.ignore_reload)
1074 storeAppendPrintf(entry, " ignore-reload");
1075#endif
1076 storeAppendPrintf(entry, "\n");
d41de3c1 1077 head = head->next;
1078 }
270b86af 1079}
090089c4 1080
270b86af 1081static void
f1dc9b30 1082parse_refreshpattern(refresh_t ** head)
270b86af 1083{
f1dc9b30 1084 char *token;
1085 char *pattern;
1086 time_t min = 0;
c3f6d204 1087 double pct = 0.0;
f1dc9b30 1088 time_t max = 0;
9f60cfdf 1089#if HTTP_VIOLATIONS
1dfa1d81 1090 int override_expire = 0;
1091 int override_lastmod = 0;
cbe3a719 1092 int reload_into_ims = 0;
1093 int ignore_reload = 0;
9f60cfdf 1094#endif
f1dc9b30 1095 int i;
1096 refresh_t *t;
1097 regex_t comp;
1098 int errcode;
1099 int flags = REG_EXTENDED | REG_NOSUB;
1100 if ((token = strtok(NULL, w_space)) == NULL)
1101 self_destruct();
1102 if (strcmp(token, "-i") == 0) {
1103 flags |= REG_ICASE;
1104 token = strtok(NULL, w_space);
1105 } else if (strcmp(token, "+i") == 0) {
1106 flags &= ~REG_ICASE;
1107 token = strtok(NULL, w_space);
1108 }
1109 if (token == NULL)
1110 self_destruct();
1111 pattern = xstrdup(token);
1112 GetInteger(i); /* token: min */
1113 min = (time_t) (i * 60); /* convert minutes to seconds */
1114 GetInteger(i); /* token: pct */
c3f6d204 1115 pct = (double) i / 100.0;
f1dc9b30 1116 GetInteger(i); /* token: max */
1117 max = (time_t) (i * 60); /* convert minutes to seconds */
1dfa1d81 1118 /* Options */
1119 while ((token = strtok(NULL, w_space)) != NULL) {
9f60cfdf 1120#if HTTP_VIOLATIONS
1dfa1d81 1121 if (!strcmp(token, "override-expire"))
1122 override_expire = 1;
255d6021 1123 else if (!strcmp(token, "override-lastmod"))
1dfa1d81 1124 override_lastmod = 1;
cbe3a719 1125 else if (!strcmp(token, "reload-into-ims")) {
1126 reload_into_ims = 1;
1127 refresh_nocache_hack = 1;
1128 /* tell client_side.c that this is used */
1129 } else if (!strcmp(token, "ignore-reload")) {
1130 ignore_reload = 1;
1131 refresh_nocache_hack = 1;
1132 /* tell client_side.c that this is used */
1133 } else
9f60cfdf 1134#endif
cbe3a719 1135 debug(22, 0) ("redreshAddToList: Unknown option '%s': %s\n",
1dfa1d81 1136 pattern, token);
1137 }
f1dc9b30 1138 if ((errcode = regcomp(&comp, pattern, flags)) != 0) {
1139 char errbuf[256];
1140 regerror(errcode, &comp, errbuf, sizeof errbuf);
1141 debug(22, 0) ("%s line %d: %s\n",
1142 cfg_filename, config_lineno, config_input_line);
1143 debug(22, 0) ("refreshAddToList: Invalid regular expression '%s': %s\n",
1144 pattern, errbuf);
1145 return;
1146 }
c3f6d204 1147 pct = pct < 0.0 ? 0.0 : pct;
f1dc9b30 1148 max = max < 0 ? 0 : max;
1149 t = xcalloc(1, sizeof(refresh_t));
1150 t->pattern = (char *) xstrdup(pattern);
1151 t->compiled_pattern = comp;
1152 t->min = min;
c3f6d204 1153 t->pct = pct;
f1dc9b30 1154 t->max = max;
c3f6d204 1155 if (flags & REG_ICASE)
1156 t->flags.icase = 1;
9f60cfdf 1157#if HTTP_VIOLATIONS
1dfa1d81 1158 if (override_expire)
1159 t->flags.override_expire = 1;
1160 if (override_lastmod)
1161 t->flags.override_lastmod = 1;
cbe3a719 1162 if (reload_into_ims)
1163 t->flags.reload_into_ims = 1;
1164 if (ignore_reload)
1165 t->flags.ignore_reload = 1;
9f60cfdf 1166#endif
f1dc9b30 1167 t->next = NULL;
1168 while (*head)
1169 head = &(*head)->next;
1170 *head = t;
1171 safe_free(pattern);
270b86af 1172}
090089c4 1173
270b86af 1174static void
a47b9029 1175free_refreshpattern(refresh_t ** head)
270b86af 1176{
f1dc9b30 1177 refresh_t *t;
79d39a72 1178 while ((t = *head) != NULL) {
f1dc9b30 1179 *head = t->next;
1180 safe_free(t->pattern);
1181 regfree(&t->compiled_pattern);
1182 safe_free(t);
1183 }
270b86af 1184}
12b9e9b1 1185
270b86af 1186static void
a7d59104 1187dump_string(StoreEntry * entry, const char *name, char *var)
270b86af 1188{
f53b06f9 1189 if (var != NULL)
a7d59104 1190 storeAppendPrintf(entry, "%s %s\n", name, var);
270b86af 1191}
98ffb7e4 1192
270b86af 1193static void
0153d498 1194parse_string(char **var)
270b86af 1195{
1196 char *token = strtok(NULL, w_space);
270b86af 1197 safe_free(*var);
1198 if (token == NULL)
1199 self_destruct();
1200 *var = xstrdup(token);
1201}
b15e6857 1202
0153d498 1203static void
1204free_string(char **var)
1205{
027acbaf 1206 safe_free(*var);
0153d498 1207}
caebbe00 1208
270b86af 1209static void
f1dc9b30 1210parse_eol(char *volatile *var)
270b86af 1211{
1212 char *token = strtok(NULL, null_string);
270b86af 1213 safe_free(*var);
f1dc9b30 1214 if (token == NULL)
1215 self_destruct();
270b86af 1216 *var = xstrdup(token);
1217}
090089c4 1218
270b86af 1219static void
a7d59104 1220dump_time_t(StoreEntry * entry, const char *name, time_t var)
090089c4 1221{
f53b06f9 1222 storeAppendPrintf(entry, "%s %d seconds\n", name, (int) var);
090089c4 1223}
1224
270b86af 1225static void
a47b9029 1226parse_time_t(time_t * var)
0ffd22bc 1227{
f1dc9b30 1228 parseTimeLine(var, T_SECOND_STR);
0ffd22bc 1229}
1230
270b86af 1231static void
a47b9029 1232free_time_t(time_t * var)
270b86af 1233{
a47b9029 1234 *var = 0;
270b86af 1235}
9906e724 1236
1237static void
a7d59104 1238dump_size_t(StoreEntry * entry, const char *name, size_t var)
1b635117 1239{
f53b06f9 1240 storeAppendPrintf(entry, "%s %d\n", name, (int) var);
1b635117 1241}
1242
1243static void
a7d59104 1244dump_b_size_t(StoreEntry * entry, const char *name, size_t var)
9906e724 1245{
f53b06f9 1246 storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR);
9906e724 1247}
1248
1249static void
a7d59104 1250dump_kb_size_t(StoreEntry * entry, const char *name, size_t var)
9906e724 1251{
f53b06f9 1252 storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_KBYTES_STR);
9906e724 1253}
1254
1255static void
a47b9029 1256parse_size_t(size_t * var)
1b635117 1257{
1258 char *token;
1259 int i;
1260 GetInteger(i);
1261 *var = (size_t) i;
1262}
1263
1264static void
1265parse_b_size_t(size_t * var)
9906e724 1266{
1267 parseBytesLine(var, B_BYTES_STR);
1268}
1269
1270static void
a47b9029 1271parse_kb_size_t(size_t * var)
9906e724 1272{
1273 parseBytesLine(var, B_KBYTES_STR);
1274}
1275
1276static void
a47b9029 1277free_size_t(size_t * var)
9906e724 1278{
a47b9029 1279 *var = 0;
9906e724 1280}
1281
1b635117 1282#define free_b_size_t free_size_t
9906e724 1283#define free_kb_size_t free_size_t
1284#define free_mb_size_t free_size_t
1285#define free_gb_size_t free_size_t
090089c4 1286
8203a132 1287static void
a7d59104 1288dump_ushort(StoreEntry * entry, const char *name, u_short var)
090089c4 1289{
f53b06f9 1290 storeAppendPrintf(entry, "%s %d\n", name, var);
270b86af 1291}
090089c4 1292
0153d498 1293static void
a47b9029 1294free_ushort(u_short * u)
0153d498 1295{
1296 *u = 0;
1297}
1298
270b86af 1299static void
1300parse_ushort(u_short * var)
1301{
1302 char *token;
1303 int i;
090089c4 1304
270b86af 1305 GetInteger(i);
1306 if (i < 0)
1307 i = 0;
1308 *var = (u_short) i;
090089c4 1309}
1310
270b86af 1311static void
a7d59104 1312dump_wordlist(StoreEntry * entry, const char *name, wordlist * list)
270b86af 1313{
270b86af 1314 while (list != NULL) {
f53b06f9 1315 storeAppendPrintf(entry, "%s %s\n", name, list->key);
270b86af 1316 list = list->next;
429fdbec 1317 }
429fdbec 1318}
1319
270b86af 1320static void
1321parse_wordlist(wordlist ** list)
429fdbec 1322{
270b86af 1323 char *token;
270b86af 1324 while ((token = strtok(NULL, w_space)))
1325 wordlistAdd(list, token);
429fdbec 1326}
270b86af 1327
f8d9f54a 1328static int
5da06f20 1329check_null_wordlist(wordlist * w)
f8d9f54a 1330{
1331 return w == NULL;
1332}
1333
0153d498 1334#define free_wordlist wordlistDestroy
270b86af 1335
d548ee64 1336#define free_uri_whitespace free_int
1337
1338static void
1339parse_uri_whitespace(int *var)
1340{
1341 char *token = strtok(NULL, w_space);
1342 if (token == NULL)
1343 self_destruct();
1344 if (!strcasecmp(token, "deny"))
1345 *var = URI_WHITESPACE_DENY;
1346 else if (!strcasecmp(token, "allow"))
1347 *var = URI_WHITESPACE_ALLOW;
1348 else if (!strcasecmp(token, "encode"))
1349 *var = URI_WHITESPACE_ENCODE;
1350 else if (!strcasecmp(token, "chop"))
1351 *var = URI_WHITESPACE_CHOP;
1352 else
1353 self_destruct();
1354}
1355
1356
1357static void
1358dump_uri_whitespace(StoreEntry * entry, const char *name, int var)
1359{
1360 char *s;
1361 if (var == URI_WHITESPACE_ALLOW)
1362 s = "allow";
1363 else if (var == URI_WHITESPACE_ENCODE)
1364 s = "encode";
1365 else if (var == URI_WHITESPACE_CHOP)
1366 s = "chop";
1367 else
1368 s = "deny";
1369 storeAppendPrintf(entry, "%s %s\n", name, s);
1370}
1371
270b86af 1372#include "cf_parser.c"
f1dc9b30 1373
1374peer_t
1375parseNeighborType(const char *s)
1376{
1377 if (!strcasecmp(s, "parent"))
1378 return PEER_PARENT;
1379 if (!strcasecmp(s, "neighbor"))
1380 return PEER_SIBLING;
1381 if (!strcasecmp(s, "neighbour"))
1382 return PEER_SIBLING;
1383 if (!strcasecmp(s, "sibling"))
1384 return PEER_SIBLING;
1385 if (!strcasecmp(s, "multicast"))
1386 return PEER_MULTICAST;
1387 debug(15, 0) ("WARNING: Unknown neighbor type: %s\n", s);
1388 return PEER_SIBLING;
1389}
f150dd4b 1390
1391void
1392configFreeMemory(void)
1393{
23ff6968 1394 free_all();
f150dd4b 1395}
f0b19334 1396
1397static void
1398requirePathnameExists(const char *name, const char *path)
1399{
1400 struct stat sb;
f0b19334 1401 assert(path != NULL);
137ee196 1402 if (stat(path, &sb) < 0)
1403 fatalf("%s: %s", path, xstrerror());
f0b19334 1404}