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