]>
Commit | Line | Data |
---|---|---|
30a4f2a8 | 1 | /* |
f150dd4b | 2 | * $Id: cache_cf.cc,v 1.212 1997/07/16 22:56:12 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 | 33 | static const char *const T_SECOND_STR = "second"; |
34 | static const char *const T_MINUTE_STR = "minute"; | |
35 | static const char *const T_HOUR_STR = "hour"; | |
36 | static const char *const T_DAY_STR = "day"; | |
37 | static const char *const T_WEEK_STR = "week"; | |
38 | static const char *const T_FORTNIGHT_STR = "fortnight"; | |
39 | static const char *const T_MONTH_STR = "month"; | |
40 | static const char *const T_YEAR_STR = "year"; | |
41 | static const char *const T_DECADE_STR = "decade"; | |
aa0a0c7c | 42 | |
9906e724 | 43 | static const char *const B_BYTES_STR = "bytes"; |
44 | static const char *const B_KBYTES_STR = "KB"; | |
45 | static const char *const B_MBYTES_STR = "MB"; | |
46 | static const char *const B_GBYTES_STR = "GB"; | |
47 | ||
4db43fab | 48 | static const char *const list_sep = ", \t\n\r"; |
090089c4 | 49 | |
24382924 | 50 | static char fatal_str[BUFSIZ]; |
24382924 | 51 | static void self_destruct _PARAMS((void)); |
0ee4272b | 52 | static void wordlistAdd _PARAMS((wordlist **, const char *)); |
caebbe00 | 53 | |
67508012 | 54 | static void configDoConfigure _PARAMS((void)); |
f1dc9b30 | 55 | static void parse_refreshpattern _PARAMS((refresh_t **)); |
429fdbec | 56 | static int parseTimeUnits _PARAMS((const char *unit)); |
a47b9029 | 57 | static void parseTimeLine _PARAMS((time_t * tptr, const char *units)); |
270b86af | 58 | static void parse_string _PARAMS((char **)); |
59 | static void parse_wordlist _PARAMS((wordlist **)); | |
270b86af | 60 | static void default_all _PARAMS((void)); |
0153d498 | 61 | static int parse_line _PARAMS((char *)); |
a47b9029 | 62 | static void parseBytesLine _PARAMS((size_t * bptr, const char *units)); |
9906e724 | 63 | static size_t parseBytesUnits _PARAMS((const char *unit)); |
0153d498 | 64 | |
65 | /* These come from cf_gen.c */ | |
66 | static void default_all _PARAMS((void)); | |
0153d498 | 67 | static void free_all _PARAMS((void)); |
270b86af | 68 | |
24382924 | 69 | static void |
0673c0ba | 70 | self_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 | 77 | void |
78 | wordlistDestroy(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 | 89 | static void |
fe4e214f | 90 | wordlistAdd(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 | 111 | void |
112 | intlistDestroy(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 | 137 | int |
138 | parseConfigFile(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 */ | |
270b86af | 182 | Config.Announce.on = 0; |
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 | 211 | static void |
270b86af | 212 | configDoConfigure(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 | 247 | static void |
a47b9029 | 248 | parseTimeLine(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 | 268 | static int |
269 | parseTimeUnits(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 | 293 | static void |
9e975e4e | 294 | parseBytesLine(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 | ||
314 | static size_t | |
315 | parseBytesUnits(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 | 333 | static void |
a47b9029 | 334 | dump_acl(acl * acl) |
090089c4 | 335 | { |
b556b1e9 | 336 | assert(0); |
090089c4 | 337 | } |
338 | ||
8203a132 | 339 | static void |
a47b9029 | 340 | parse_acl(acl ** acl) |
090089c4 | 341 | { |
f1dc9b30 | 342 | aclParseAclLine(acl); |
343 | } | |
344 | ||
345 | static void | |
a47b9029 | 346 | free_acl(acl ** acl) |
f1dc9b30 | 347 | { |
348 | aclDestroyAcls(acl); | |
090089c4 | 349 | } |
350 | ||
8203a132 | 351 | static void |
270b86af | 352 | dump_acl_access(struct _acl_access *head) |
30a4f2a8 | 353 | { |
b556b1e9 | 354 | assert(0); |
30a4f2a8 | 355 | } |
090089c4 | 356 | |
8203a132 | 357 | static void |
270b86af | 358 | parse_acl_access(struct _acl_access **head) |
090089c4 | 359 | { |
270b86af | 360 | aclParseAccessLine(head); |
090089c4 | 361 | } |
362 | ||
0153d498 | 363 | static void |
364 | free_acl_access(struct _acl_access **head) | |
365 | { | |
a47b9029 | 366 | aclDestroyAccessList(head); |
0153d498 | 367 | } |
368 | ||
8203a132 | 369 | static void |
270b86af | 370 | dump_address(struct in_addr addr) |
371 | { | |
372 | printf("%s", inet_ntoa(addr)); | |
373 | } | |
374 | ||
375 | static void | |
376 | parse_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 | 391 | static void |
392 | free_address(struct in_addr *addr) | |
393 | { | |
a47b9029 | 394 | memset(addr, '\0', sizeof(struct in_addr)); |
0153d498 | 395 | } |
396 | ||
e90100aa | 397 | static void |
f1dc9b30 | 398 | dump_cachedir(struct _cacheSwap swap) |
e90100aa | 399 | { |
b556b1e9 | 400 | assert(0); |
e90100aa | 401 | } |
402 | ||
8203a132 | 403 | static void |
f1dc9b30 | 404 | parse_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 | 460 | static void |
f1dc9b30 | 461 | free_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 | ||
480 | static void | |
40a1495e | 481 | dump_peer(peer * p) |
98ffb7e4 | 482 | { |
b556b1e9 | 483 | assert(0); |
98ffb7e4 | 484 | } |
485 | ||
8203a132 | 486 | static void |
40a1495e | 487 | parse_peer(peer ** head) |
7813c6d5 | 488 | { |
270b86af | 489 | char *token = NULL; |
40a1495e | 490 | peer *p; |
7813c6d5 | 491 | int i; |
40a1495e | 492 | ushortlist *u; |
e481c2dc | 493 | const char *me = getMyHostname();; |
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); |
270b86af | 526 | } else if (!strncasecmp(token, "ttl=", 4)) { |
40a1495e | 527 | p->mcast.ttl = atoi(token + 4); |
528 | if (p->mcast.ttl < 0) | |
529 | p->mcast.ttl = 0; | |
530 | if (p->mcast.ttl > 128) | |
531 | p->mcast.ttl = 128; | |
270b86af | 532 | } else if (!strncasecmp(token, "default", 7)) { |
40a1495e | 533 | p->options |= NEIGHBOR_DEFAULT_PARENT; |
270b86af | 534 | } else if (!strncasecmp(token, "round-robin", 11)) { |
40a1495e | 535 | p->options |= NEIGHBOR_ROUNDROBIN; |
270b86af | 536 | } else { |
40a1495e | 537 | debug(3, 0) ("parse_peer: token='%s'\n", token); |
270b86af | 538 | self_destruct(); |
539 | } | |
540 | } | |
40a1495e | 541 | if (p->weight < 1) |
542 | p->weight = 1; | |
543 | p->icp_version = ICP_VERSION_CURRENT; | |
544 | p->tcp_up = 1; | |
545 | cbdataAdd(p); | |
0153d498 | 546 | while (*head != NULL) |
547 | head = &(*head)->next; | |
548 | *head = p; | |
40a1495e | 549 | Config.npeers++; |
0153d498 | 550 | } |
551 | ||
552 | static void | |
40a1495e | 553 | free_peer(peer ** P) |
0153d498 | 554 | { |
40a1495e | 555 | peer *p; |
a47b9029 | 556 | while ((p = *P)) { |
557 | *P = p->next; | |
40a1495e | 558 | peerDestroy(p); |
a47b9029 | 559 | } |
270b86af | 560 | } |
561 | ||
562 | static void | |
a47b9029 | 563 | dump_cachemgrpasswd(cachemgr_passwd * list) |
270b86af | 564 | { |
b556b1e9 | 565 | assert(0); |
270b86af | 566 | } |
567 | ||
568 | static void | |
a47b9029 | 569 | parse_cachemgrpasswd(cachemgr_passwd ** head) |
270b86af | 570 | { |
571 | char *passwd = NULL; | |
572 | wordlist *actions = NULL; | |
573 | parse_string(&passwd); | |
574 | parse_wordlist(&actions); | |
f1dc9b30 | 575 | objcachePasswdAdd(head, passwd, actions); |
270b86af | 576 | wordlistDestroy(&actions); |
577 | } | |
578 | ||
579 | static void | |
a47b9029 | 580 | free_cachemgrpasswd(cachemgr_passwd ** head) |
270b86af | 581 | { |
a47b9029 | 582 | cachemgr_passwd *p; |
583 | while ((p = *head)) { | |
584 | *head = p->next; | |
585 | xfree(p->passwd); | |
586 | xfree(p); | |
587 | } | |
270b86af | 588 | } |
589 | ||
270b86af | 590 | |
8203a132 | 591 | static void |
f1dc9b30 | 592 | dump_denyinfo(struct _acl_deny_info_list *var) |
270b86af | 593 | { |
b556b1e9 | 594 | assert(0); |
270b86af | 595 | } |
596 | ||
597 | static void | |
f1dc9b30 | 598 | parse_denyinfo(struct _acl_deny_info_list **var) |
6e40f263 | 599 | { |
f1dc9b30 | 600 | aclParseDenyInfoLine(var); |
6e40f263 | 601 | } |
403279e0 | 602 | |
1273d501 | 603 | void |
a47b9029 | 604 | free_denyinfo(acl_deny_info_list ** list) |
3c5557f9 | 605 | { |
1273d501 | 606 | struct _acl_deny_info_list *a = NULL; |
607 | struct _acl_deny_info_list *a_next = NULL; | |
608 | struct _acl_name_list *l = NULL; | |
609 | struct _acl_name_list *l_next = NULL; | |
610 | for (a = *list; a; a = a_next) { | |
a47b9029 | 611 | for (l = a->acl_list; l; l = l_next) { |
612 | l_next = l->next; | |
613 | safe_free(l); | |
614 | } | |
615 | a_next = a->next; | |
616 | safe_free(a); | |
1273d501 | 617 | } |
618 | *list = NULL; | |
270b86af | 619 | } |
620 | ||
621 | static void | |
f1dc9b30 | 622 | parse_peeracl(void) |
270b86af | 623 | { |
624 | char *host = NULL; | |
625 | char *aclname = NULL; | |
626 | if (!(host = strtok(NULL, w_space))) | |
627 | self_destruct(); | |
f1dc9b30 | 628 | while ((aclname = strtok(NULL, list_sep))) { |
40a1495e | 629 | peer *p; |
f1dc9b30 | 630 | acl_list *L = NULL; |
631 | acl_list **Tail = NULL; | |
632 | acl *a = NULL; | |
40a1495e | 633 | if ((p = peerFindByName(host)) == NULL) { |
f1dc9b30 | 634 | debug(15, 0) ("%s, line %d: No cache_host '%s'\n", |
635 | cfg_filename, config_lineno, host); | |
636 | return; | |
637 | } | |
638 | L = xcalloc(1, sizeof(struct _acl_list)); | |
639 | L->op = 1; | |
640 | if (*aclname == '!') { | |
641 | L->op = 0; | |
642 | aclname++; | |
643 | } | |
644 | debug(15, 3) ("neighborAddAcl: looking for ACL name '%s'\n", aclname); | |
645 | a = aclFindByName(aclname); | |
646 | if (a == NULL) { | |
647 | debug(15, 0) ("%s line %d: %s\n", | |
648 | cfg_filename, config_lineno, config_input_line); | |
649 | debug(15, 0) ("neighborAddAcl: ACL name '%s' not found.\n", aclname); | |
650 | xfree(L); | |
651 | return; | |
652 | } | |
653 | L->acl = a; | |
654 | for (Tail = &p->acls; *Tail; Tail = &(*Tail)->next); | |
655 | *Tail = L; | |
656 | } | |
270b86af | 657 | } |
658 | ||
270b86af | 659 | static void |
660 | parse_hostdomain(void) | |
661 | { | |
662 | char *host = NULL; | |
663 | char *domain = NULL; | |
664 | if (!(host = strtok(NULL, w_space))) | |
665 | self_destruct(); | |
f1dc9b30 | 666 | while ((domain = strtok(NULL, list_sep))) { |
667 | domain_ping *l = NULL; | |
668 | domain_ping **L = NULL; | |
40a1495e | 669 | peer *p; |
670 | if ((p = peerFindByName(host)) == NULL) { | |
f1dc9b30 | 671 | debug(15, 0) ("%s, line %d: No cache_host '%s'\n", |
672 | cfg_filename, config_lineno, host); | |
673 | continue; | |
674 | } | |
675 | l = xcalloc(1, sizeof(struct _domain_ping)); | |
676 | l->do_ping = 1; | |
677 | if (*domain == '!') { /* check for !.edu */ | |
678 | l->do_ping = 0; | |
679 | domain++; | |
680 | } | |
681 | l->domain = xstrdup(domain); | |
682 | for (L = &(p->pinglist); *L; L = &((*L)->next)); | |
683 | *L = l; | |
684 | } | |
270b86af | 685 | } |
686 | ||
687 | static void | |
688 | parse_hostdomaintype(void) | |
689 | { | |
690 | char *host = NULL; | |
691 | char *type = NULL; | |
692 | char *domain = NULL; | |
693 | if (!(host = strtok(NULL, w_space))) | |
694 | self_destruct(); | |
695 | if (!(type = strtok(NULL, w_space))) | |
696 | self_destruct(); | |
f1dc9b30 | 697 | while ((domain = strtok(NULL, list_sep))) { |
698 | domain_type *l = NULL; | |
699 | domain_type **L = NULL; | |
40a1495e | 700 | peer *p; |
701 | if ((p = peerFindByName(host)) == NULL) { | |
f1dc9b30 | 702 | debug(15, 0) ("%s, line %d: No cache_host '%s'\n", |
703 | cfg_filename, config_lineno, host); | |
704 | return; | |
705 | } | |
706 | l = xcalloc(1, sizeof(struct _domain_type)); | |
707 | l->type = parseNeighborType(type); | |
708 | l->domain = xstrdup(domain); | |
709 | for (L = &(p->typelist); *L; L = &((*L)->next)); | |
710 | *L = l; | |
711 | } | |
270b86af | 712 | } |
713 | ||
714 | static void | |
715 | dump_httpanonymizer(int var) | |
716 | { | |
717 | switch (var) { | |
718 | case ANONYMIZER_NONE: | |
719 | printf("off"); | |
720 | break; | |
721 | case ANONYMIZER_STANDARD: | |
722 | printf("paranoid"); | |
723 | break; | |
724 | case ANONYMIZER_PARANOID: | |
725 | printf("standard"); | |
726 | break; | |
727 | } | |
728 | } | |
729 | ||
730 | static void | |
731 | parse_httpanonymizer(int *var) | |
fa562c67 | 732 | { |
733 | char *token; | |
734 | token = strtok(NULL, w_space); | |
735 | if (token == NULL) | |
bba6fa8f | 736 | self_destruct(); |
fa562c67 | 737 | if (!strcasecmp(token, "off")) |
270b86af | 738 | *var = ANONYMIZER_NONE; |
fa562c67 | 739 | else if (!strcasecmp(token, "paranoid")) |
270b86af | 740 | *var = ANONYMIZER_PARANOID; |
fa562c67 | 741 | else |
270b86af | 742 | *var = ANONYMIZER_STANDARD; |
743 | } | |
744 | ||
641941c0 | 745 | |
270b86af | 746 | static void |
a47b9029 | 747 | dump_ushortlist(ushortlist * u) |
090089c4 | 748 | { |
270b86af | 749 | while (u) { |
750 | printf("%d ", (int) u->i); | |
751 | u = u->next; | |
752 | } | |
753 | } | |
090089c4 | 754 | |
270b86af | 755 | static void |
756 | parse_ushortlist(ushortlist ** P) | |
757 | { | |
758 | char *token; | |
759 | int i; | |
760 | ushortlist *u; | |
761 | ushortlist **U; | |
762 | while ((token = strtok(NULL, w_space))) { | |
763 | if (sscanf(token, "%d", &i) != 1) | |
764 | self_destruct(); | |
765 | if (i < 0) | |
766 | i = 0; | |
767 | u = xcalloc(1, sizeof(ushortlist)); | |
768 | u->i = (u_short) i; | |
769 | for (U = P; *U; U = &(*U)->next); | |
770 | *U = u; | |
090089c4 | 771 | } |
270b86af | 772 | } |
090089c4 | 773 | |
0153d498 | 774 | static void |
a47b9029 | 775 | free_ushortlist(ushortlist ** P) |
0153d498 | 776 | { |
a47b9029 | 777 | ushortlist *u; |
778 | while ((u = *P)) { | |
779 | *P = u->next; | |
780 | xfree(u); | |
781 | } | |
0153d498 | 782 | } |
783 | ||
270b86af | 784 | static void |
785 | dump_int(int var) | |
786 | { | |
787 | printf("%d", var); | |
788 | } | |
c1c29eb6 | 789 | |
270b86af | 790 | static void |
791 | parse_int(int *var) | |
792 | { | |
793 | char *token; | |
794 | int i; | |
85034133 | 795 | |
270b86af | 796 | GetInteger(i); |
797 | *var = i; | |
798 | } | |
090089c4 | 799 | |
0153d498 | 800 | static void |
801 | free_int(int *var) | |
802 | { | |
a47b9029 | 803 | *var = 0; |
0153d498 | 804 | } |
805 | ||
270b86af | 806 | static void |
807 | dump_onoff(int var) | |
808 | { | |
809 | printf(var ? "on" : "off"); | |
810 | } | |
090089c4 | 811 | |
270b86af | 812 | static void |
813 | parse_onoff(int *var) | |
814 | { | |
815 | char *token = strtok(NULL, w_space); | |
090089c4 | 816 | |
270b86af | 817 | if (token == NULL) |
818 | self_destruct(); | |
819 | if (!strcasecmp(token, "on") || !strcasecmp(token, "enable")) | |
820 | *var = 1; | |
821 | else | |
822 | *var = 0; | |
823 | } | |
e90100aa | 824 | |
0153d498 | 825 | #define free_onoff free_int |
f1dc9b30 | 826 | #define free_httpanonymizer free_int |
0153d498 | 827 | #define dump_pathname_stat dump_string |
828 | #define free_pathname_stat free_string | |
f1dc9b30 | 829 | #define dump_eol dump_string |
830 | #define free_eol free_string | |
30a4f2a8 | 831 | |
270b86af | 832 | static void |
0153d498 | 833 | parse_pathname_stat(char **path) |
270b86af | 834 | { |
835 | struct stat sb; | |
270b86af | 836 | parse_string(path); |
270b86af | 837 | if (stat(*path, &sb) < 0) { |
0153d498 | 838 | debug(50, 1) ("parse_pathname_stat: %s: %s\n", *path, xstrerror()); |
270b86af | 839 | self_destruct(); |
840 | } | |
841 | } | |
30a4f2a8 | 842 | |
270b86af | 843 | static void |
a47b9029 | 844 | dump_refreshpattern(refresh_t * head) |
270b86af | 845 | { |
b556b1e9 | 846 | assert(0); |
270b86af | 847 | } |
090089c4 | 848 | |
270b86af | 849 | static void |
f1dc9b30 | 850 | parse_refreshpattern(refresh_t ** head) |
270b86af | 851 | { |
f1dc9b30 | 852 | char *token; |
853 | char *pattern; | |
854 | time_t min = 0; | |
855 | int pct = 0; | |
856 | time_t max = 0; | |
857 | int i; | |
858 | refresh_t *t; | |
859 | regex_t comp; | |
860 | int errcode; | |
861 | int flags = REG_EXTENDED | REG_NOSUB; | |
862 | if ((token = strtok(NULL, w_space)) == NULL) | |
863 | self_destruct(); | |
864 | if (strcmp(token, "-i") == 0) { | |
865 | flags |= REG_ICASE; | |
866 | token = strtok(NULL, w_space); | |
867 | } else if (strcmp(token, "+i") == 0) { | |
868 | flags &= ~REG_ICASE; | |
869 | token = strtok(NULL, w_space); | |
870 | } | |
871 | if (token == NULL) | |
872 | self_destruct(); | |
873 | pattern = xstrdup(token); | |
874 | GetInteger(i); /* token: min */ | |
875 | min = (time_t) (i * 60); /* convert minutes to seconds */ | |
876 | GetInteger(i); /* token: pct */ | |
877 | pct = i; | |
878 | GetInteger(i); /* token: max */ | |
879 | max = (time_t) (i * 60); /* convert minutes to seconds */ | |
880 | if ((errcode = regcomp(&comp, pattern, flags)) != 0) { | |
881 | char errbuf[256]; | |
882 | regerror(errcode, &comp, errbuf, sizeof errbuf); | |
883 | debug(22, 0) ("%s line %d: %s\n", | |
884 | cfg_filename, config_lineno, config_input_line); | |
885 | debug(22, 0) ("refreshAddToList: Invalid regular expression '%s': %s\n", | |
886 | pattern, errbuf); | |
887 | return; | |
888 | } | |
889 | pct = pct < 0 ? 0 : pct; | |
890 | max = max < 0 ? 0 : max; | |
891 | t = xcalloc(1, sizeof(refresh_t)); | |
892 | t->pattern = (char *) xstrdup(pattern); | |
893 | t->compiled_pattern = comp; | |
894 | t->min = min; | |
895 | t->pct = pct; | |
896 | t->max = max; | |
897 | t->next = NULL; | |
898 | while (*head) | |
899 | head = &(*head)->next; | |
900 | *head = t; | |
901 | safe_free(pattern); | |
270b86af | 902 | } |
090089c4 | 903 | |
270b86af | 904 | static void |
a47b9029 | 905 | free_refreshpattern(refresh_t ** head) |
270b86af | 906 | { |
f1dc9b30 | 907 | refresh_t *t; |
908 | while ((t = *head)) { | |
909 | *head = t->next; | |
910 | safe_free(t->pattern); | |
911 | regfree(&t->compiled_pattern); | |
912 | safe_free(t); | |
913 | } | |
270b86af | 914 | } |
12b9e9b1 | 915 | |
270b86af | 916 | static void |
917 | dump_regexlist(relist * var) | |
918 | { | |
b556b1e9 | 919 | assert(0); |
270b86af | 920 | } |
cf5fd929 | 921 | |
270b86af | 922 | static void |
923 | parse_regexlist(relist ** var) | |
924 | { | |
0153d498 | 925 | aclParseRegexList(var); |
270b86af | 926 | } |
fb263c4c | 927 | |
270b86af | 928 | static void |
0153d498 | 929 | free_regexlist(relist ** var) |
270b86af | 930 | { |
0153d498 | 931 | aclDestroyRegexList(*var); |
932 | *var = NULL; | |
270b86af | 933 | } |
7d49daab | 934 | |
270b86af | 935 | static void |
0153d498 | 936 | dump_string(char *var) |
270b86af | 937 | { |
938 | printf("%s", var); | |
939 | } | |
98ffb7e4 | 940 | |
270b86af | 941 | static void |
0153d498 | 942 | parse_string(char **var) |
270b86af | 943 | { |
944 | char *token = strtok(NULL, w_space); | |
270b86af | 945 | safe_free(*var); |
946 | if (token == NULL) | |
947 | self_destruct(); | |
948 | *var = xstrdup(token); | |
949 | } | |
b15e6857 | 950 | |
0153d498 | 951 | static void |
952 | free_string(char **var) | |
953 | { | |
a47b9029 | 954 | xfree(*var); |
955 | *var = NULL; | |
0153d498 | 956 | } |
caebbe00 | 957 | |
270b86af | 958 | static void |
f1dc9b30 | 959 | parse_eol(char *volatile *var) |
270b86af | 960 | { |
961 | char *token = strtok(NULL, null_string); | |
270b86af | 962 | safe_free(*var); |
f1dc9b30 | 963 | if (token == NULL) |
964 | self_destruct(); | |
270b86af | 965 | *var = xstrdup(token); |
966 | } | |
090089c4 | 967 | |
270b86af | 968 | static void |
f1dc9b30 | 969 | dump_time_t(time_t var) |
090089c4 | 970 | { |
f1dc9b30 | 971 | printf("%d", (int) var); |
090089c4 | 972 | } |
973 | ||
270b86af | 974 | static void |
a47b9029 | 975 | parse_time_t(time_t * var) |
0ffd22bc | 976 | { |
f1dc9b30 | 977 | parseTimeLine(var, T_SECOND_STR); |
0ffd22bc | 978 | } |
979 | ||
270b86af | 980 | static void |
a47b9029 | 981 | free_time_t(time_t * var) |
270b86af | 982 | { |
a47b9029 | 983 | *var = 0; |
270b86af | 984 | } |
9906e724 | 985 | |
986 | static void | |
987 | dump_size_t(size_t var) | |
988 | { | |
989 | printf("%d bytes", (int) var); | |
990 | } | |
991 | ||
992 | static void | |
993 | dump_kb_size_t(size_t var) | |
994 | { | |
995 | printf("%d KB", (int) var); | |
996 | } | |
997 | ||
998 | static void | |
a47b9029 | 999 | parse_size_t(size_t * var) |
9906e724 | 1000 | { |
1001 | parseBytesLine(var, B_BYTES_STR); | |
1002 | } | |
1003 | ||
1004 | static void | |
a47b9029 | 1005 | parse_kb_size_t(size_t * var) |
9906e724 | 1006 | { |
1007 | parseBytesLine(var, B_KBYTES_STR); | |
1008 | } | |
1009 | ||
1010 | static void | |
a47b9029 | 1011 | free_size_t(size_t * var) |
9906e724 | 1012 | { |
a47b9029 | 1013 | *var = 0; |
9906e724 | 1014 | } |
1015 | ||
1016 | #define free_kb_size_t free_size_t | |
1017 | #define free_mb_size_t free_size_t | |
1018 | #define free_gb_size_t free_size_t | |
090089c4 | 1019 | |
8203a132 | 1020 | static void |
270b86af | 1021 | dump_ushort(u_short var) |
090089c4 | 1022 | { |
270b86af | 1023 | printf("%d", var); |
1024 | } | |
090089c4 | 1025 | |
0153d498 | 1026 | static void |
a47b9029 | 1027 | free_ushort(u_short * u) |
0153d498 | 1028 | { |
1029 | *u = 0; | |
1030 | } | |
1031 | ||
270b86af | 1032 | static void |
1033 | parse_ushort(u_short * var) | |
1034 | { | |
1035 | char *token; | |
1036 | int i; | |
090089c4 | 1037 | |
270b86af | 1038 | GetInteger(i); |
1039 | if (i < 0) | |
1040 | i = 0; | |
1041 | *var = (u_short) i; | |
090089c4 | 1042 | } |
1043 | ||
270b86af | 1044 | static void |
1045 | dump_wordlist(wordlist * list) | |
1046 | { | |
1047 | printf("{"); | |
1048 | while (list != NULL) { | |
1049 | printf("%s ", list->key); | |
1050 | list = list->next; | |
429fdbec | 1051 | } |
270b86af | 1052 | printf("}"); |
429fdbec | 1053 | } |
1054 | ||
270b86af | 1055 | static void |
1056 | parse_wordlist(wordlist ** list) | |
429fdbec | 1057 | { |
270b86af | 1058 | char *token; |
1059 | ||
1060 | while ((token = strtok(NULL, w_space))) | |
1061 | wordlistAdd(list, token); | |
429fdbec | 1062 | } |
270b86af | 1063 | |
0153d498 | 1064 | #define free_wordlist wordlistDestroy |
270b86af | 1065 | |
1066 | #include "cf_parser.c" | |
f1dc9b30 | 1067 | |
1068 | peer_t | |
1069 | parseNeighborType(const char *s) | |
1070 | { | |
1071 | if (!strcasecmp(s, "parent")) | |
1072 | return PEER_PARENT; | |
1073 | if (!strcasecmp(s, "neighbor")) | |
1074 | return PEER_SIBLING; | |
1075 | if (!strcasecmp(s, "neighbour")) | |
1076 | return PEER_SIBLING; | |
1077 | if (!strcasecmp(s, "sibling")) | |
1078 | return PEER_SIBLING; | |
1079 | if (!strcasecmp(s, "multicast")) | |
1080 | return PEER_MULTICAST; | |
1081 | debug(15, 0) ("WARNING: Unknown neighbor type: %s\n", s); | |
1082 | return PEER_SIBLING; | |
1083 | } | |
f150dd4b | 1084 | |
1085 | void | |
1086 | configFreeMemory(void) | |
1087 | { | |
1088 | free_all(); | |
1089 | } |