]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_cf.cc
massive const patch from Markus Gyger
[thirdparty/squid.git] / src / cache_cf.cc
CommitLineData
30a4f2a8 1/*
0ee4272b 2 * $Id: cache_cf.cc,v 1.126 1996/11/04 18:12:10 wessels Exp $
30a4f2a8 3 *
4 * DEBUG: section 3 Configuration File Parsing
5 * AUTHOR: Harvest Derived
6 *
7 * SQUID Internet Object Cache http://www.nlanr.net/Squid/
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
30a4f2a8 31/*
32 * Copyright (c) 1994, 1995. All rights reserved.
33 *
34 * The Harvest software was developed by the Internet Research Task
35 * Force Research Group on Resource Discovery (IRTF-RD):
36 *
37 * Mic Bowman of Transarc Corporation.
38 * Peter Danzig of the University of Southern California.
39 * Darren R. Hardy of the University of Colorado at Boulder.
40 * Udi Manber of the University of Arizona.
41 * Michael F. Schwartz of the University of Colorado at Boulder.
42 * Duane Wessels of the University of Colorado at Boulder.
43 *
44 * This copyright notice applies to software in the Harvest
45 * ``src/'' directory only. Users should consult the individual
46 * copyright notices in the ``components/'' subdirectories for
47 * copyright information about other software bundled with the
48 * Harvest source code distribution.
49 *
50 * TERMS OF USE
51 *
52 * The Harvest software may be used and re-distributed without
53 * charge, provided that the software origin and research team are
54 * cited in any use of the system. Most commonly this is
55 * accomplished by including a link to the Harvest Home Page
56 * (http://harvest.cs.colorado.edu/) from the query page of any
57 * Broker you deploy, as well as in the query result pages. These
58 * links are generated automatically by the standard Broker
59 * software distribution.
60 *
61 * The Harvest software is provided ``as is'', without express or
62 * implied warranty, and with no support nor obligation to assist
63 * in its use, correction, modification or enhancement. We assume
64 * no liability with respect to the infringement of copyrights,
65 * trade secrets, or any patents, and are not responsible for
66 * consequential damages. Proper use of the Harvest software is
67 * entirely the responsibility of the user.
68 *
69 * DERIVATIVE WORKS
70 *
71 * Users may make derivative works from the Harvest software, subject
72 * to the following constraints:
73 *
74 * - You must include the above copyright notice and these
75 * accompanying paragraphs in all forms of derivative works,
76 * and any documentation and other materials related to such
77 * distribution and use acknowledge that the software was
78 * developed at the above institutions.
79 *
80 * - You must notify IRTF-RD regarding your distribution of
81 * the derivative work.
82 *
83 * - You must clearly notify users that your are distributing
84 * a modified version and not the original Harvest software.
85 *
86 * - Any derivative product is also subject to these copyright
87 * and use restrictions.
88 *
89 * Note that the Harvest software is NOT in the public domain. We
90 * retain copyright, as specified above.
91 *
92 * HISTORY OF FREE SOFTWARE STATUS
93 *
94 * Originally we required sites to license the software in cases
95 * where they were going to build commercial products/services
96 * around Harvest. In June 1995 we changed this policy. We now
97 * allow people to use the core Harvest software (the code found in
98 * the Harvest ``src/'' directory) for free. We made this change
99 * in the interest of encouraging the widest possible deployment of
100 * the technology. The Harvest software is really a reference
101 * implementation of a set of protocols and formats, some of which
102 * we intend to standardize. We encourage commercial
103 * re-implementations of code complying to this set of standards.
104 */
ed43818f 105
44a47c6e 106#include "squid.h"
090089c4 107
b6f794d6 108struct SquidConfig Config;
090089c4 109
e954773d 110#define DefaultMemMaxSize (8 << 20) /* 8 MB */
7813c6d5 111#define DefaultMemHighWaterMark 90 /* 90% */
112#define DefaultMemLowWaterMark 75 /* 75% */
090089c4 113#define DefaultSwapMaxSize (100 << 10) /* 100 MB (100*1024 kbytes) */
114#define DefaultSwapHighWaterMark 90 /* 90% */
234967c9 115#define DefaultSwapLowWaterMark 75 /* 75% */
090089c4 116
090089c4 117#define DefaultWaisRelayHost (char *)NULL
30a4f2a8 118#define DefaultWaisRelayPort 0
090089c4 119
66cedb85 120#define DefaultReferenceAge 0 /* disabled */
090089c4 121#define DefaultNegativeTtl (5 * 60) /* 5 min */
61d6fc5c 122#define DefaultNegativeDnsTtl (2 * 60) /* 2 min */
2639dac6 123#define DefaultPositiveDnsTtl (360 * 60) /* 6 hours */
090089c4 124#define DefaultReadTimeout (15 * 60) /* 15 min */
125#define DefaultLifetimeDefault (200 * 60) /* 3+ hours */
234967c9 126#define DefaultLifetimeShutdown 30 /* 30 seconds */
090089c4 127#define DefaultConnectTimeout (2 * 60) /* 2 min */
128#define DefaultDefaultAgeMax (3600 * 24 * 30) /* 30 days */
129#define DefaultCleanRate -1 /* disabled */
d2af9477 130#define DefaultDnsChildren 5 /* 5 processes */
131#define DefaultRedirectChildren 5 /* 5 processes */
234967c9 132#define DefaultMaxRequestSize (100 << 10) /* 100Kb */
090089c4 133
30a4f2a8 134#define DefaultHttpPortNum CACHE_HTTP_PORT
135#define DefaultIcpPortNum CACHE_ICP_PORT
090089c4 136
a26bdc75 137#define DefaultCacheLogFile DEFAULT_CACHE_LOG
138#define DefaultAccessLogFile DEFAULT_ACCESS_LOG
d8b45066 139#define DefaultStoreLogFile DEFAULT_STORE_LOG
5ad764e2 140#define DefaultSwapLogFile (char *)NULL /* default swappath(0) */
e81957b7 141#if USE_PROXY_AUTH
142#define DefaultProxyAuthFile (char *)NULL /* default NONE */
d6b73110 143#define DefaultProxyAuthIgnoreDomain (char *)NULL /* default NONE */
e81957b7 144#endif /* USE_PROXY_AUTH */
090089c4 145#define DefaultLogRotateNumber 10
146#define DefaultAdminEmail "webmaster"
a26bdc75 147#define DefaultFtpgetProgram DEFAULT_FTPGET
090089c4 148#define DefaultFtpgetOptions ""
a26bdc75 149#define DefaultDnsserverProgram DEFAULT_DNSSERVER
365a4bce 150#define DefaultPingerProgram DEFAULT_PINGER
d2af9477 151#define DefaultRedirectProgram (char *)NULL /* default NONE */
090089c4 152#define DefaultEffectiveUser (char *)NULL /* default NONE */
153#define DefaultEffectiveGroup (char *)NULL /* default NONE */
154#define DefaultAppendDomain (char *)NULL /* default NONE */
6e40f263 155#define DefaultErrHtmlText (char *)NULL /* default NONE */
090089c4 156
ccff9601 157#define DefaultDebugOptions "ALL,1" /* All sections at level 1 */
090089c4 158#define DefaultAccelHost (char *)NULL /* default NONE */
159#define DefaultAccelPrefix (char *)NULL /* default NONE */
160#define DefaultAccelPort 0 /* default off */
161#define DefaultAccelWithProxy 0 /* default off */
162#define DefaultSourcePing 0 /* default off */
1ef4c6c1 163#define DefaultCommonLogFormat 0 /* default off */
2ba42578 164#if LOG_FULL_HEADERS
e43efe50 165#define DefaultLogMimeHdrs 0 /* default off */
166#endif /* LOG_FULL_HEADERS */
c1c29eb6 167#define DefaultIdentLookup 0 /* default off */
2546fcb3 168#define DefaultQuickAbortMin -1 /* default off */
169#define DefaultQuickAbortPct 0 /* default off */
170#define DefaultQuickAbortMax 0 /* default off */
090089c4 171#define DefaultNeighborTimeout 2 /* 2 seconds */
234967c9 172#define DefaultStallDelay 1 /* 1 seconds */
090089c4 173#define DefaultSingleParentBypass 0 /* default off */
77ffc99f 174#define DefaultPidFilename (char *)NULL /* default NONE */
cf5fd929 175#define DefaultVisibleHostname (char *)NULL /* default NONE */
b8de7ebe 176#define DefaultFtpUser "squid@" /* Default without domain */
7d49daab 177#define DefaultAnnounceHost "sd.cache.nlanr.net"
178#define DefaultAnnouncePort 3131
7ba794f4 179#define DefaultAnnounceFile (char *)NULL /* default NONE */
30a4f2a8 180#define DefaultAnnounceRate 0 /* Default off */
7813c6d5 181#define DefaultTcpRcvBufsz 0 /* use system default */
30a4f2a8 182#define DefaultTcpIncomingAddr INADDR_ANY
183#define DefaultTcpOutgoingAddr INADDR_NONE
184#define DefaultUdpIncomingAddr INADDR_ANY
185#define DefaultUdpOutgoingAddr INADDR_NONE
86ee2017 186#define DefaultClientNetmask 0xFFFFFFFFul
98ffb7e4 187#define DefaultSslProxyPort 0
188#define DefaultSslProxyHost (char *)NULL
b15e6857 189#define DefaultIpcacheSize 1024
190#define DefaultIpcacheLow 90
191#define DefaultIpcacheHigh 95
4d311579 192#define DefaultMinDirectHops 4
38792624 193#define DefaultMaxObjectSize (4<<20) /* 4Mb */
194#define DefaultAvgObjectSize 20 /* 20k */
195#define DefaultObjectsPerBucket 50
ccff9601 196
090089c4 197int httpd_accel_mode = 0; /* for fast access */
0ee4272b 198const char *DefaultSwapDir = DEFAULT_SWAP_DIR;
199const char *DefaultConfigFile = DEFAULT_CONFIG_FILE;
cbbad1ed 200char *ConfigFile = NULL; /* the whole thing */
0ee4272b 201const char *cfg_filename = NULL; /* just the last part */
202char ForwardedBy[256] = "";
090089c4 203
0ee4272b 204const char *const w_space = " \t\n";
3003c0f3 205char config_input_line[BUFSIZ];
206int config_lineno = 0;
090089c4 207
24382924 208static char fatal_str[BUFSIZ];
0ee4272b 209static char *safe_xstrdup _PARAMS((const char *p));
210static int ip_acl_match _PARAMS((struct in_addr, const ip_acl *));
211static void addToIPACL _PARAMS((ip_acl **, const char *, ip_access_type));
67508012 212static void parseOnOff _PARAMS((int *));
213static void parseIntegerValue _PARAMS((int *));
24382924 214static void self_destruct _PARAMS((void));
0ee4272b 215static void wordlistAdd _PARAMS((wordlist **, const char *));
caebbe00 216
67508012 217static void configDoConfigure _PARAMS((void));
67508012 218static void configSetFactoryDefaults _PARAMS((void));
67508012 219static void parseAddressLine _PARAMS((struct in_addr *));
220static void parseAnnounceToLine _PARAMS((void));
221static void parseAppendDomainLine _PARAMS((void));
222static void parseCacheAnnounceLine _PARAMS((void));
223static void parseCacheHostLine _PARAMS((void));
224static void parseDebugOptionsLine _PARAMS((void));
67508012 225static void parseEffectiveUserLine _PARAMS((void));
226static void parseErrHtmlLine _PARAMS((void));
67508012 227static void parseFtpOptionsLine _PARAMS((void));
228static void parseFtpProgramLine _PARAMS((void));
229static void parseFtpUserLine _PARAMS((void));
67508012 230static void parseWordlist _PARAMS((wordlist **));
231static void parseHostAclLine _PARAMS((void));
232static void parseHostDomainLine _PARAMS((void));
67508012 233static void parseHttpPortLine _PARAMS((void));
234static void parseHttpdAccelLine _PARAMS((void));
235static void parseIPLine _PARAMS((ip_acl ** list));
236static void parseIcpPortLine _PARAMS((void));
0ee4272b 237static void parseLocalDomainFile _PARAMS((const char *fname));
67508012 238static void parseLocalDomainLine _PARAMS((void));
e90100aa 239static void parseMcastGroupLine _PARAMS((void));
67508012 240static void parseMemLine _PARAMS((void));
241static void parseMgrLine _PARAMS((void));
38792624 242static void parseKilobytes _PARAMS((int *));
67508012 243static void parseSwapLine _PARAMS((void));
a7e59001 244static void parseRefreshPattern _PARAMS((int icase));
67508012 245static void parseVisibleHostnameLine _PARAMS((void));
246static void parseWAISRelayLine _PARAMS((void));
247static void parseMinutesLine _PARAMS((int *));
248static void ip_acl_destroy _PARAMS((ip_acl **));
5ad764e2 249static void parsePathname _PARAMS((char **));
8203a132 250
24382924 251static void
0673c0ba 252self_destruct(void)
090089c4 253{
b8de7ebe 254 sprintf(fatal_str, "Bungled %s line %d: %s",
255 cfg_filename, config_lineno, config_input_line);
090089c4 256 fatal(fatal_str);
257}
258
24382924 259static int
0ee4272b 260ip_acl_match(struct in_addr c, const ip_acl *a)
c8bd12b1 261{
262 static struct in_addr h;
263
264 h.s_addr = c.s_addr & a->mask.s_addr;
265 if (h.s_addr == a->addr.s_addr)
266 return 1;
267 else
268 return 0;
269}
270
ea6f43cd 271static void
67508012 272ip_acl_destroy(ip_acl ** a)
caebbe00 273{
274 ip_acl *b;
275 ip_acl *n;
276 for (b = *a; b; b = n) {
277 n = b->next;
278 safe_free(b);
279 }
aa1b6e03 280 *a = NULL;
caebbe00 281}
c8bd12b1 282
8203a132 283ip_access_type
0ee4272b 284ip_access_check(struct in_addr address, const ip_acl *list)
c8bd12b1 285{
c7f37efb 286 static int init = 0;
287 static struct in_addr localhost;
0ee4272b 288 const ip_acl *p = NULL;
c8bd12b1 289 struct in_addr naddr; /* network byte-order IP addr */
c8bd12b1 290
291 if (!list)
292 return IP_ALLOW;
293
c7f37efb 294 if (!init) {
295 memset((char *) &localhost, '\0', sizeof(struct in_addr));
c8bd12b1 296 localhost.s_addr = inet_addr("127.0.0.1");
c7f37efb 297 init = 1;
298 }
c8bd12b1 299 naddr.s_addr = address.s_addr;
300 if (naddr.s_addr == localhost.s_addr)
301 return IP_ALLOW;
302
a4f583ee 303 debug(3, 5, "ip_access_check: using %s\n", inet_ntoa(naddr));
c8bd12b1 304
305 for (p = list; p; p = p->next) {
a4f583ee 306 debug(3, 5, "ip_access_check: %s vs %s/%s\n",
307 inet_ntoa(naddr),
308 inet_ntoa(p->addr),
309 inet_ntoa(p->mask));
c8bd12b1 310 if (ip_acl_match(naddr, p))
311 return p->access;
312 }
313 return IP_ALLOW;
314}
315
316
24382924 317static void
0ee4272b 318addToIPACL(ip_acl **list, const char *ip_str, ip_access_type access)
c8bd12b1 319{
320 ip_acl *p, *q;
321 int a1, a2, a3, a4;
322 int m1, m2, m3, m4;
323 struct in_addr lmask;
324 int c;
325
326 if (!ip_str) {
327 return;
328 }
329 if (!(*list)) {
330 /* empty list */
30a4f2a8 331 *list = xcalloc(1, sizeof(ip_acl));
c8bd12b1 332 (*list)->next = NULL;
333 q = *list;
334 } else {
335 /* find end of list */
336 p = *list;
337 while (p->next)
338 p = p->next;
30a4f2a8 339 q = xcalloc(1, sizeof(ip_acl));
c8bd12b1 340 q->next = NULL;
341 p->next = q;
342 }
343
344
345 /* decode ip address */
346 if (!strcasecmp(ip_str, "all")) {
347 a1 = a2 = a3 = a4 = 0;
348 lmask.s_addr = 0;
349 } else {
350 a1 = a2 = a3 = a4 = 0;
351 c = sscanf(ip_str, "%d.%d.%d.%d/%d.%d.%d.%d", &a1, &a2, &a3, &a4,
352 &m1, &m2, &m3, &m4);
353
354 switch (c) {
355 case 4:
d3c1a245 356 if (a1 == 0 && a2 == 0 && a3 == 0 && a4 == 0) /* world */
86ee2017 357 lmask.s_addr = 0x00000000ul;
d3c1a245 358 else if (a2 == 0 && a3 == 0 && a4 == 0) /* class A */
86ee2017 359 lmask.s_addr = htonl(0xff000000ul);
d3c1a245 360 else if (a3 == 0 && a4 == 0) /* class B */
86ee2017 361 lmask.s_addr = htonl(0xffff0000ul);
d3c1a245 362 else if (a4 == 0) /* class C */
86ee2017 363 lmask.s_addr = htonl(0xffffff00ul);
c8bd12b1 364 else
86ee2017 365 lmask.s_addr = 0xfffffffful;
c8bd12b1 366 break;
367
368 case 5:
369 if (m1 < 0 || m1 > 32) {
da00e850 370 debug(3, 0, "addToIPACL: Ignoring invalid IP acl line '%s'\n",
c8bd12b1 371 ip_str);
372 return;
373 }
86ee2017 374 lmask.s_addr = htonl(0xfffffffful << (32 - m1));
c8bd12b1 375 break;
376
377 case 8:
378 lmask.s_addr = htonl(m1 * 0x1000000 + m2 * 0x10000 + m3 * 0x100 + m4);
379 break;
380
381 default:
da00e850 382 debug(3, 0, "addToIPACL: Ignoring invalid IP acl line '%s'\n",
383 ip_str);
c8bd12b1 384 return;
385 }
386 }
387
388 q->access = access;
389 q->addr.s_addr = htonl(a1 * 0x1000000 + a2 * 0x10000 + a3 * 0x100 + a4);
390 q->mask.s_addr = lmask.s_addr;
391}
c837641d 392
8203a132 393void
394wordlistDestroy(wordlist ** list)
0ffd22bc 395{
396 wordlist *w = NULL;
397 wordlist *n = NULL;
398
84c6cc9f 399 for (w = *list; w; w = n) {
0ffd22bc 400 n = w->next;
401 safe_free(w->key);
402 safe_free(w);
403 }
404 *list = NULL;
405}
406
24382924 407static void
0ee4272b 408wordlistAdd(wordlist **list, const char *key)
090089c4 409{
0ffd22bc 410 wordlist *p = NULL;
411 wordlist *q = NULL;
090089c4 412
413 if (!(*list)) {
414 /* empty list */
30a4f2a8 415 *list = xcalloc(1, sizeof(wordlist));
090089c4 416 (*list)->key = xstrdup(key);
417 (*list)->next = NULL;
418 } else {
419 p = *list;
420 while (p->next)
421 p = p->next;
30a4f2a8 422 q = xcalloc(1, sizeof(wordlist));
090089c4 423 q->key = xstrdup(key);
424 q->next = NULL;
425 p->next = q;
426 }
427}
428
8203a132 429void
430intlistDestroy(intlist ** list)
92a6f4b1 431{
432 intlist *w = NULL;
433 intlist *n = NULL;
434
435 for (w = *list; w; w = n) {
436 n = w->next;
437 safe_free(w);
438 }
439 *list = NULL;
440}
441
403279e0 442
090089c4 443/* Use this #define in all the parse*() functions. Assumes
caebbe00 444 * char *token is defined */
090089c4 445
446#define GetInteger(var) \
447 token = strtok(NULL, w_space); \
30a4f2a8 448 if( token == NULL) \
3003c0f3 449 self_destruct(); \
090089c4 450 if (sscanf(token, "%d", &var) != 1) \
3003c0f3 451 self_destruct();
090089c4 452
453
8203a132 454static void
0673c0ba 455parseCacheHostLine(void)
090089c4 456{
457 char *type = NULL;
458 char *hostname = NULL;
459 char *token = NULL;
30a4f2a8 460 u_short http_port = CACHE_HTTP_PORT;
461 u_short icp_port = CACHE_ICP_PORT;
462 int options = 0;
fe113054 463 int weight = 1;
e90100aa 464 int mcast_ttl = 0;
30a4f2a8 465 int i;
090089c4 466
090089c4 467 if (!(hostname = strtok(NULL, w_space)))
3003c0f3 468 self_destruct();
090089c4 469 if (!(type = strtok(NULL, w_space)))
3003c0f3 470 self_destruct();
090089c4 471
30a4f2a8 472 GetInteger(i);
473 http_port = (u_short) i;
474 GetInteger(i);
475 icp_port = (u_short) i;
fe113054 476 while ((token = strtok(NULL, w_space))) {
477 if (!strcasecmp(token, "proxy-only")) {
30a4f2a8 478 options |= NEIGHBOR_PROXY_ONLY;
479 } else if (!strcasecmp(token, "no-query")) {
480 options |= NEIGHBOR_NO_QUERY;
c06a5b15 481 } else if (!strncasecmp(token, "weight=", 7)) {
a0bbd6c8 482 weight = atoi(token + 7);
e90100aa 483 } else if (!strncasecmp(token, "ttl=", 4)) {
484 mcast_ttl = atoi(token + 4);
fe113054 485 } else {
01f2d250 486 debug(3, 0, "parseCacheHostLine: token='%s'\n", token);
a0bbd6c8 487 self_destruct();
fe113054 488 }
090089c4 489 }
234967c9 490 if (weight < 1)
491 weight = 1;
e90100aa 492 neighbors_cf_add(hostname, type, http_port, icp_port, options,
493 weight, mcast_ttl);
090089c4 494}
495
24a1003d 496static neighbor_t
0ee4272b 497parseNeighborType(const char *token)
24a1003d 498{
499 if (!strcasecmp(token, "parent"))
500 return EDGE_PARENT;
501 if (!strcasecmp(token, "neighbor"))
502 return EDGE_SIBLING;
503 if (!strcasecmp(token, "neighbour"))
504 return EDGE_SIBLING;
505 if (!strcasecmp(token, "sibling"))
506 return EDGE_SIBLING;
507 return EDGE_NONE;
508}
509
510
8203a132 511static void
0673c0ba 512parseHostDomainLine(void)
090089c4 513{
514 char *host = NULL;
515 char *domain = NULL;
24a1003d 516 neighbor_t type = EDGE_NONE;
517 neighbor_t t;
30a4f2a8 518 if (!(host = strtok(NULL, w_space)))
519 self_destruct();
24a1003d 520 while ((domain = strtok(NULL, ", \t\n"))) {
521 if ((t = parseNeighborType(domain)) != EDGE_NONE) {
522 type = t;
523 continue;
524 }
525 neighbors_cf_domain(host, domain, type);
526 }
30a4f2a8 527}
090089c4 528
8203a132 529static void
0673c0ba 530parseHostAclLine(void)
30a4f2a8 531{
532 char *host = NULL;
533 char *aclname = NULL;
090089c4 534 if (!(host = strtok(NULL, w_space)))
3003c0f3 535 self_destruct();
30a4f2a8 536 while ((aclname = strtok(NULL, ", \t\n")))
537 neighbors_cf_acl(host, aclname);
090089c4 538}
539
8203a132 540static void
0673c0ba 541parseMemLine(void)
090089c4 542{
543 char *token;
544 int i;
545 GetInteger(i);
546 Config.Mem.maxSize = i << 20;
547}
548
8203a132 549static void
0673c0ba 550parseSwapLine(void)
090089c4 551{
552 char *token;
553 int i;
554 GetInteger(i);
555 Config.Swap.maxSize = i << 10;
556}
557
8203a132 558static void
a7e59001 559parseRefreshPattern(int icase)
090089c4 560{
561 char *token;
562 char *pattern;
a7e59001 563 time_t min = 0;
564 int pct = 0;
565 time_t max = 0;
090089c4 566 int i;
090089c4 567 token = strtok(NULL, w_space); /* token: regex pattern */
30a4f2a8 568 if (token == NULL)
3003c0f3 569 self_destruct();
090089c4 570 pattern = xstrdup(token);
a7e59001 571 GetInteger(i); /* token: min */
572 min = (time_t) (i * 60); /* convert minutes to seconds */
573 GetInteger(i); /* token: pct */
574 pct = i;
575 GetInteger(i); /* token: max */
576 max = (time_t) (i * 60); /* convert minutes to seconds */
577 refreshAddToList(pattern, icase, min, pct, max);
2546fcb3 578 safe_free(pattern);
579}
580
8203a132 581static void
0673c0ba 582parseQuickAbort(void)
2546fcb3 583{
584 char *token;
585 int i;
fea2e6e0 586 token = strtok(NULL, w_space);
587 if (!strcasecmp(token, "on")) {
588 Config.quickAbort.min = 10 << 10; /* 10k */
589 Config.quickAbort.pct = 64; /* 50% */
590 Config.quickAbort.max = 100 << 10; /* 100k */
591 } else if (!strcasecmp(token, "off")) {
592 Config.quickAbort.min = -1;
593 Config.quickAbort.pct = 0;
594 Config.quickAbort.max = 0;
595 } else {
6c93e119 596 if (sscanf(token, "%d", &i) != 1)
597 self_destruct();
fea2e6e0 598 Config.quickAbort.min = i * 1024;
599 GetInteger(i);
600 Config.quickAbort.pct = i * 128 / 100; /* 128 is full scale */
601 GetInteger(i);
602 Config.quickAbort.max = i * 1024;
603 }
2546fcb3 604}
605
8203a132 606static void
607parseMinutesLine(int *iptr)
090089c4 608{
609 char *token;
610 int i;
611 GetInteger(i);
79b5cc5f 612 *iptr = i * 60;
090089c4 613}
614
8203a132 615static void
38792624 616parseKilobytes(int *val)
fa966b74 617{
618 char *token;
619 int i;
620 GetInteger(i);
38792624 621 *val = i * 1024;
fa966b74 622}
623
8203a132 624static void
0673c0ba 625parseMgrLine(void)
090089c4 626{
627 char *token;
628 token = strtok(NULL, w_space);
30a4f2a8 629 if (token == NULL)
3003c0f3 630 self_destruct();
090089c4 631 safe_free(Config.adminEmail);
632 Config.adminEmail = xstrdup(token);
633}
634
e81957b7 635#if USE_PROXY_AUTH
8203a132 636static void
0673c0ba 637parseProxyAuthLine(void)
e81957b7 638{
639 char *token;
e81957b7 640 token = strtok(NULL, w_space);
641 if (token == NULL)
fea2e6e0 642 self_destruct();
e81957b7 643 safe_free(Config.proxyAuthFile);
644 safe_free(Config.proxyAuthIgnoreDomain);
645 Config.proxyAuthFile = xstrdup(token);
646 if ((token = strtok(NULL, w_space)))
fea2e6e0 647 Config.proxyAuthIgnoreDomain = xstrdup(token);
e81957b7 648}
649#endif /* USE_PROXY_AUTH */
650
8203a132 651static void
0673c0ba 652parseHttpdAccelLine(void)
090089c4 653{
654 char *token;
844327e4 655 LOCAL_ARRAY(char, buf, BUFSIZ);
090089c4 656 int i;
090089c4 657 token = strtok(NULL, w_space);
30a4f2a8 658 if (token == NULL)
3003c0f3 659 self_destruct();
090089c4 660 safe_free(Config.Accel.host);
661 Config.Accel.host = xstrdup(token);
662 GetInteger(i);
663 Config.Accel.port = i;
664 safe_free(Config.Accel.prefix);
665 sprintf(buf, "http://%s:%d", Config.Accel.host, Config.Accel.port);
666 Config.Accel.prefix = xstrdup(buf);
667 httpd_accel_mode = 1;
668}
669
8203a132 670static void
0673c0ba 671parseEffectiveUserLine(void)
090089c4 672{
673 char *token;
090089c4 674 token = strtok(NULL, w_space);
30a4f2a8 675 if (token == NULL)
3003c0f3 676 self_destruct();
090089c4 677 safe_free(Config.effectiveUser);
678 safe_free(Config.effectiveGroup);
679 Config.effectiveUser = xstrdup(token);
090089c4 680 token = strtok(NULL, w_space);
30a4f2a8 681 if (token == NULL)
090089c4 682 return; /* group is optional */
683 Config.effectiveGroup = xstrdup(token);
684}
685
8203a132 686static void
5ad764e2 687parsePathname(char **path)
090089c4 688{
689 char *token;
690 token = strtok(NULL, w_space);
30a4f2a8 691 if (token == NULL)
3003c0f3 692 self_destruct();
5ad764e2 693 safe_free(*path);
694 *path = xstrdup(token);
d8b45066 695}
696
8203a132 697static void
0673c0ba 698parseFtpProgramLine(void)
090089c4 699{
700 char *token;
701 token = strtok(NULL, w_space);
30a4f2a8 702 if (token == NULL)
3003c0f3 703 self_destruct();
090089c4 704 safe_free(Config.Program.ftpget);
705 Config.Program.ftpget = xstrdup(token);
706}
707
8203a132 708static void
0673c0ba 709parseFtpOptionsLine(void)
090089c4 710{
711 char *token;
0a21bd84 712 token = strtok(NULL, null_string);
30a4f2a8 713 if (token == NULL)
3003c0f3 714 self_destruct();
090089c4 715 safe_free(Config.Program.ftpget_opts);
716 Config.Program.ftpget_opts = xstrdup(token);
717}
718
8203a132 719static void
720parseOnOff(int *var)
090089c4 721{
722 char *token;
723 token = strtok(NULL, w_space);
30a4f2a8 724 if (token == NULL)
3003c0f3 725 self_destruct();
090089c4 726 if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
c1c29eb6 727 *var = 1;
090089c4 728 else
c1c29eb6 729 *var = 0;
090089c4 730}
731
8203a132 732static void
0673c0ba 733parseWAISRelayLine(void)
090089c4 734{
735 char *token;
736 int i;
737 token = strtok(NULL, w_space);
30a4f2a8 738 if (token == NULL)
3003c0f3 739 self_destruct();
090089c4 740 safe_free(Config.Wais.relayHost);
741 Config.Wais.relayHost = xstrdup(token);
742 GetInteger(i);
30a4f2a8 743 Config.Wais.relayPort = (u_short) i;
090089c4 744}
745
8203a132 746static void
747parseIPLine(ip_acl ** list)
090089c4 748{
749 char *token;
750 while ((token = strtok(NULL, w_space))) {
30a4f2a8 751 addToIPACL(list, token, IP_DENY);
090089c4 752 }
753}
754
8203a132 755static void
235c7b49 756parseWordlist(wordlist ** list)
30a4f2a8 757{
758 char *token;
759 while ((token = strtok(NULL, w_space)))
b15fe823 760 wordlistAdd(list, token);
30a4f2a8 761}
090089c4 762
8203a132 763static void
0673c0ba 764parseAppendDomainLine(void)
090089c4 765{
766 char *token;
767 token = strtok(NULL, w_space);
30a4f2a8 768 if (token == NULL)
3003c0f3 769 self_destruct();
090089c4 770 if (*token != '.')
3003c0f3 771 self_destruct();
090089c4 772 safe_free(Config.appendDomain);
773 Config.appendDomain = xstrdup(token);
774}
775
8203a132 776static void
777parseAddressLine(struct in_addr *addr)
090089c4 778{
779 char *token;
0ee4272b 780 const struct hostent *hp;
090089c4 781 token = strtok(NULL, w_space);
30a4f2a8 782 if (token == NULL)
783 self_destruct();
784 if (inet_addr(token) != INADDR_NONE)
785 (*addr).s_addr = inet_addr(token);
ceb8994e 786 else if ((hp = gethostbyname(token))) /* dont use ipcache */
1d73e33a 787 *addr = inaddrFromHostent(hp);
30a4f2a8 788 else
3003c0f3 789 self_destruct();
090089c4 790}
791
8203a132 792static void
0ee4272b 793parseLocalDomainFile(const char *fname)
983061ed 794{
844327e4 795 LOCAL_ARRAY(char, tmp_line, BUFSIZ);
983061ed 796 FILE *fp = NULL;
797 char *t = NULL;
983061ed 798 if ((fp = fopen(fname, "r")) == NULL) {
799 debug(3, 1, "parseLocalDomainFile: %s: %s\n", fname, xstrerror());
800 return;
801 }
802 memset(tmp_line, '\0', BUFSIZ);
803 while (fgets(tmp_line, BUFSIZ, fp)) {
804 if (tmp_line[0] == '#')
805 continue;
806 if (tmp_line[0] == '\0')
807 continue;
808 if (tmp_line[0] == '\n')
809 continue;
810 for (t = strtok(tmp_line, w_space); t; t = strtok(NULL, w_space)) {
811 debug(3, 1, "parseLocalDomainFileLine: adding %s\n", t);
812 wordlistAdd(&Config.local_domain_list, t);
813 }
814 }
815 fclose(fp);
816}
817
8203a132 818static void
0673c0ba 819parseLocalDomainLine(void)
090089c4 820{
983061ed 821 char *token = NULL;
822 struct stat sb;
090089c4 823 while ((token = strtok(NULL, w_space))) {
983061ed 824 if (stat(token, &sb) < 0) {
825 wordlistAdd(&Config.local_domain_list, token);
826 } else {
827 parseLocalDomainFile(token);
828 }
090089c4 829 }
830}
831
e90100aa 832static void
833parseMcastGroupLine(void)
834{
835 char *token = NULL;
836 while ((token = strtok(NULL, w_space)))
837 wordlistAdd(&Config.mcast_group_list, token);
838}
839
8203a132 840static void
0673c0ba 841parseHttpPortLine(void)
090089c4 842{
843 char *token;
844 int i;
845 GetInteger(i);
30a4f2a8 846 if (i < 0)
847 i = 0;
848 Config.Port.http = (u_short) i;
090089c4 849}
850
8203a132 851static void
0673c0ba 852parseIcpPortLine(void)
090089c4 853{
854 char *token;
855 int i;
856 GetInteger(i);
30a4f2a8 857 if (i < 0)
858 i = 0;
859 Config.Port.icp = (u_short) i;
090089c4 860}
861
8203a132 862static void
0673c0ba 863parseDebugOptionsLine(void)
090089c4 864{
12b9e9b1 865 char *token;
0a21bd84 866 token = strtok(NULL, null_string);
12b9e9b1 867 safe_free(Config.debugOptions);
30a4f2a8 868 if (token == NULL) {
12b9e9b1 869 Config.debugOptions = NULL;
870 return;
871 }
872 Config.debugOptions = xstrdup(token);
090089c4 873}
874
8203a132 875static void
0673c0ba 876parseVisibleHostnameLine(void)
cf5fd929 877{
878 char *token;
879 token = strtok(NULL, w_space);
880 safe_free(Config.visibleHostname);
30a4f2a8 881 if (token == NULL)
3003c0f3 882 self_destruct();
cf5fd929 883 Config.visibleHostname = xstrdup(token);
884}
885
8203a132 886static void
0673c0ba 887parseFtpUserLine(void)
fb263c4c 888{
889 char *token;
890 token = strtok(NULL, w_space);
30a4f2a8 891 if (token == NULL)
3003c0f3 892 self_destruct();
7d49daab 893 safe_free(Config.ftpUser);
fb263c4c 894 Config.ftpUser = xstrdup(token);
895}
896
8203a132 897static void
0673c0ba 898parseCacheAnnounceLine(void)
7d49daab 899{
900 char *token;
901 int i;
902 GetInteger(i);
903 Config.Announce.rate = i * 3600; /* hours to seconds */
904}
905
8203a132 906static void
0673c0ba 907parseAnnounceToLine(void)
7d49daab 908{
909 char *token;
910 int i;
911 token = strtok(NULL, w_space);
30a4f2a8 912 if (token == NULL)
3003c0f3 913 self_destruct();
7d49daab 914 safe_free(Config.Announce.host);
915 Config.Announce.host = xstrdup(token);
916 if ((token = strchr(Config.Announce.host, ':'))) {
917 *token++ = '\0';
918 if (sscanf(token, "%d", &i) != 1)
919 Config.Announce.port = i;
920 }
921 token = strtok(NULL, w_space);
30a4f2a8 922 if (token == NULL)
7d49daab 923 return;
924 safe_free(Config.Announce.file);
925 Config.Announce.file = xstrdup(token);
1d73e33a 926 Config.Announce.on = 1;
7d49daab 927}
928
752c3b27 929static void
930parseVizHackLine(void)
931{
932 char *token;
933 int i;
0ee4272b 934 const struct hostent *hp;
752c3b27 935 token = strtok(NULL, w_space);
07e959ff 936 memset((char *) &Config.vizHackAddr, '\0', sizeof(struct sockaddr_in));
752c3b27 937 Config.vizHackAddr.sin_family = AF_INET;
938 if (token == NULL)
939 self_destruct();
940 if (inet_addr(token) != INADDR_NONE)
941 Config.vizHackAddr.sin_addr.s_addr = inet_addr(token);
942 else if ((hp = gethostbyname(token))) /* dont use ipcache */
943 Config.vizHackAddr.sin_addr = inaddrFromHostent(hp);
944 else
945 self_destruct();
946 if ((token = strtok(NULL, w_space)) == NULL)
947 self_destruct();
948 if (sscanf(token, "%d", &i) == 1)
07e959ff 949 Config.vizHackAddr.sin_port = htons(i);
752c3b27 950}
951
8203a132 952static void
0673c0ba 953parseSslProxyLine(void)
98ffb7e4 954{
955 char *token;
956 char *t;
957 token = strtok(NULL, w_space);
958 if (token == NULL)
959 self_destruct();
960 safe_free(Config.sslProxy.host);
961 Config.sslProxy.port = 0;
962 if ((t = strchr(token, ':'))) {
963 *t++ = '\0';
964 Config.sslProxy.port = atoi(t);
965 }
966 Config.sslProxy.host = xstrdup(token);
967}
968
8203a132 969static void
970parseIntegerValue(int *iptr)
7813c6d5 971{
972 char *token;
973 int i;
974 GetInteger(i);
975 *iptr = i;
976}
977
8203a132 978static void
0673c0ba 979parseErrHtmlLine(void)
6e40f263 980{
981 char *token;
0a21bd84 982 if ((token = strtok(NULL, null_string)))
6e40f263 983 Config.errHtmlText = xstrdup(token);
984}
403279e0 985
8203a132 986int
0ee4272b 987parseConfigFile(const char *file_name)
090089c4 988{
12b9e9b1 989 FILE *fp = NULL;
990 char *token = NULL;
844327e4 991 LOCAL_ARRAY(char, tmp_line, BUFSIZ);
090089c4 992
0ffd22bc 993 configFreeMemory();
090089c4 994 configSetFactoryDefaults();
92a6f4b1 995 aclDestroyAcls();
ea1b5bd8 996 aclDestroyDenyInfoList(&DenyInfoList);
92a6f4b1 997 aclDestroyAccessList(&HTTPAccessList);
48270233 998 aclDestroyAccessList(&MISSAccessList);
92a6f4b1 999 aclDestroyAccessList(&ICPAccessList);
caebbe00 1000#if DELAY_HACK
1001 aclDestroyAccessList(&DelayAccessList);
1002#endif
33cdd606 1003 aclDestroyRegexList(Config.cache_stop_relist);
1004 Config.cache_stop_relist = NULL;
090089c4 1005
12b9e9b1 1006 if ((fp = fopen(file_name, "r")) == NULL) {
234967c9 1007 sprintf(fatal_str, "Unable to open configuration file: %s: %s",
1008 file_name, xstrerror());
090089c4 1009 fatal(fatal_str);
1010 }
b8de7ebe 1011 cfg_filename = file_name;
1012 if ((token = strrchr(cfg_filename, '/')))
4cd0ab45 1013 cfg_filename = token + 1;
3003c0f3 1014 memset(config_input_line, '\0', BUFSIZ);
1015 config_lineno = 0;
1016 while (fgets(config_input_line, BUFSIZ, fp)) {
1017 config_lineno++;
1018 if ((token = strchr(config_input_line, '\n')))
540830c4 1019 *token = '\0';
3003c0f3 1020 if (config_input_line[0] == '#')
540830c4 1021 continue;
3003c0f3 1022 if (config_input_line[0] == '\0')
090089c4 1023 continue;
3003c0f3 1024 debug(3, 5, "Processing: '%s'\n", config_input_line);
1025 strcpy(tmp_line, config_input_line);
92a6f4b1 1026 if ((token = strtok(tmp_line, w_space)) == NULL)
090089c4 1027 continue;
1028
090089c4 1029 if (!strcmp(token, "cache_host"))
3003c0f3 1030 parseCacheHostLine();
090089c4 1031
090089c4 1032 else if (!strcmp(token, "cache_host_domain"))
3003c0f3 1033 parseHostDomainLine();
30a4f2a8 1034 else if (!strcmp(token, "cache_host_acl"))
1035 parseHostAclLine();
090089c4 1036
090089c4 1037 else if (!strcmp(token, "neighbor_timeout"))
7813c6d5 1038 parseIntegerValue(&Config.neighborTimeout);
090089c4 1039 else if (!strcmp(token, "neighbour_timeout")) /* alternate spelling */
7813c6d5 1040 parseIntegerValue(&Config.neighborTimeout);
090089c4 1041
090089c4 1042 else if (!strcmp(token, "cache_dir"))
b15fe823 1043 parseWordlist(&Config.cache_dirs);
090089c4 1044
090089c4 1045 else if (!strcmp(token, "cache_log"))
5ad764e2 1046 parsePathname(&Config.Log.log);
090089c4 1047
090089c4 1048 else if (!strcmp(token, "cache_access_log"))
5ad764e2 1049 parsePathname(&Config.Log.access);
090089c4 1050
d8b45066 1051 else if (!strcmp(token, "cache_store_log"))
5ad764e2 1052 parsePathname(&Config.Log.store);
1053
1054 else if (!strcmp(token, "cache_swap_log"))
1055 parsePathname(&Config.Log.swap);
d8b45066 1056
090089c4 1057 else if (!strcmp(token, "logfile_rotate"))
7813c6d5 1058 parseIntegerValue(&Config.Log.rotateNumber);
090089c4 1059
090089c4 1060 else if (!strcmp(token, "httpd_accel_with_proxy"))
c1c29eb6 1061 parseOnOff(&Config.Accel.withProxy);
090089c4 1062
090089c4 1063 else if (!strcmp(token, "httpd_accel"))
3003c0f3 1064 parseHttpdAccelLine();
090089c4 1065
090089c4 1066 else if (!strcmp(token, "cache_effective_user"))
3003c0f3 1067 parseEffectiveUserLine();
090089c4 1068
090089c4 1069 else if (!strcmp(token, "cache_swap_high"))
7813c6d5 1070 parseIntegerValue(&Config.Swap.highWaterMark);
090089c4 1071
090089c4 1072 else if (!strcmp(token, "cache_swap_low"))
7c6c6f75 1073 parseIntegerValue(&Config.Swap.lowWaterMark);
090089c4 1074
090089c4 1075 else if (!strcmp(token, "cache_mem_high"))
7813c6d5 1076 parseIntegerValue(&Config.Mem.highWaterMark);
090089c4 1077
090089c4 1078 else if (!strcmp(token, "cache_mem_low"))
7813c6d5 1079 parseIntegerValue(&Config.Mem.lowWaterMark);
090089c4 1080
090089c4 1081 else if (!strcmp(token, "cache_mem"))
3003c0f3 1082 parseMemLine();
090089c4 1083
090089c4 1084 else if (!strcmp(token, "cache_swap"))
3003c0f3 1085 parseSwapLine();
090089c4 1086
090089c4 1087 else if (!strcmp(token, "cache_mgr"))
3003c0f3 1088 parseMgrLine();
090089c4 1089
8213067d 1090 else if (!strcmp(token, "acl"))
3003c0f3 1091 aclParseAclLine();
8213067d 1092
ea1b5bd8 1093 else if (!strcmp(token, "deny_info"))
1094 aclParseDenyInfoLine(&DenyInfoList);
1095
92a6f4b1 1096 else if (!strcmp(token, "http_access"))
1097 aclParseAccessLine(&HTTPAccessList);
1098
48270233 1099 else if (!strcmp(token, "miss_access"))
1100 aclParseAccessLine(&MISSAccessList);
1101
92a6f4b1 1102 else if (!strcmp(token, "icp_access"))
1103 aclParseAccessLine(&ICPAccessList);
8213067d 1104
30a4f2a8 1105 else if (!strcmp(token, "hierarchy_stoplist"))
b15fe823 1106 parseWordlist(&Config.hierarchy_stoplist);
1107
1108 else if (!strcmp(token, "cache_stoplist"))
1109 parseWordlist(&Config.cache_stoplist);
33cdd606 1110 else if (!strcmp(token, "cache_stoplist_pattern"))
1111 Config.cache_stop_relist = aclParseRegexList(0);
1112 else if (!strcmp(token, "cache_stoplist_pattern/i"))
1113 Config.cache_stop_relist = aclParseRegexList(1);
30a4f2a8 1114
caebbe00 1115#if DELAY_HACK
1116 else if (!strcmp(token, "delay_access"))
1117 aclParseAccessLine(&DelayAccessList);
1118#endif
1119
a7e59001 1120 else if (!strcmp(token, "refresh_pattern"))
1121 parseRefreshPattern(0);
1122 else if (!strcmp(token, "refresh_pattern/i"))
1123 parseRefreshPattern(1);
2546fcb3 1124
1125 else if (!strcmp(token, "quick_abort"))
1126 parseQuickAbort();
1127
090089c4 1128 else if (!strcmp(token, "negative_ttl"))
79b5cc5f 1129 parseMinutesLine(&Config.negativeTtl);
61d6fc5c 1130 else if (!strcmp(token, "negative_dns_ttl"))
79b5cc5f 1131 parseMinutesLine(&Config.negativeDnsTtl);
2639dac6 1132 else if (!strcmp(token, "positive_dns_ttl"))
79b5cc5f 1133 parseMinutesLine(&Config.positiveDnsTtl);
090089c4 1134 else if (!strcmp(token, "read_timeout"))
79b5cc5f 1135 parseMinutesLine(&Config.readTimeout);
090089c4 1136 else if (!strcmp(token, "clean_rate"))
79b5cc5f 1137 parseMinutesLine(&Config.cleanRate);
090089c4 1138 else if (!strcmp(token, "client_lifetime"))
79b5cc5f 1139 parseMinutesLine(&Config.lifetimeDefault);
66cedb85 1140 else if (!strcmp(token, "reference_age"))
1141 parseMinutesLine(&Config.referenceAge);
090089c4 1142
605ba5ca 1143 else if (!strcmp(token, "shutdown_lifetime"))
7813c6d5 1144 parseIntegerValue(&Config.lifetimeShutdown);
605ba5ca 1145
fa966b74 1146 else if (!strcmp(token, "request_size"))
38792624 1147 parseKilobytes(&Config.maxRequestSize);
fa966b74 1148
090089c4 1149 else if (!strcmp(token, "connect_timeout"))
7813c6d5 1150 parseIntegerValue(&Config.connectTimeout);
090089c4 1151
090089c4 1152 else if (!strcmp(token, "cache_ftp_program"))
3003c0f3 1153 parseFtpProgramLine();
c021888f 1154 else if (!strcmp(token, "ftpget_program"))
1155 parseFtpProgramLine();
090089c4 1156
090089c4 1157 else if (!strcmp(token, "cache_ftp_options"))
3003c0f3 1158 parseFtpOptionsLine();
c021888f 1159 else if (!strcmp(token, "ftpget_options"))
1160 parseFtpOptionsLine();
090089c4 1161
090089c4 1162 else if (!strcmp(token, "cache_dns_program"))
5ad764e2 1163 parsePathname(&Config.Program.dnsserver);
090089c4 1164
090089c4 1165 else if (!strcmp(token, "dns_children"))
7813c6d5 1166 parseIntegerValue(&Config.dnsChildren);
090089c4 1167
d2af9477 1168 else if (!strcmp(token, "redirect_program"))
5ad764e2 1169 parsePathname(&Config.Program.redirect);
98ffb7e4 1170
d2af9477 1171 else if (!strcmp(token, "redirect_children"))
7813c6d5 1172 parseIntegerValue(&Config.redirectChildren);
d2af9477 1173
e81957b7 1174#if USE_PROXY_AUTH
d6b73110 1175 else if (!strcmp(token, "proxy_auth"))
fea2e6e0 1176 parseProxyAuthLine();
e81957b7 1177#endif /* USE_PROXY_AUTH */
1178
090089c4 1179 else if (!strcmp(token, "source_ping"))
c1c29eb6 1180 parseOnOff(&Config.sourcePing);
090089c4 1181
090089c4 1182 else if (!strcmp(token, "emulate_httpd_log"))
c1c29eb6 1183 parseOnOff(&Config.commonLogFormat);
1184
2ba42578 1185#if LOG_FULL_HEADERS
e43efe50 1186 else if (!strcmp(token, "log_mime_hdrs"))
1187 parseOnOff(&Config.logMimeHdrs);
1188
1189#endif /* LOG_FULL_HEADERS */
7813c6d5 1190 else if (!strcmp(token, "ident_lookup"))
c1c29eb6 1191 parseOnOff(&Config.identLookup);
090089c4 1192
1193 else if (!strcmp(token, "append_domain"))
3003c0f3 1194 parseAppendDomainLine();
090089c4 1195
090089c4 1196 else if (!strcmp(token, "wais_relay"))
3003c0f3 1197 parseWAISRelayLine();
090089c4 1198
090089c4 1199 else if (!strcmp(token, "local_ip"))
b6f794d6 1200 parseIPLine(&Config.local_ip_list);
30a4f2a8 1201
1202 else if (!strcmp(token, "firewall_ip"))
b6f794d6 1203 parseIPLine(&Config.firewall_ip_list);
090089c4 1204
090089c4 1205 else if (!strcmp(token, "local_domain"))
3003c0f3 1206 parseLocalDomainLine();
090089c4 1207
e90100aa 1208 else if (!strcmp(token, "mcast_groups"))
1209 parseMcastGroupLine();
1210
30a4f2a8 1211 else if (!strcmp(token, "tcp_incoming_address"))
1212 parseAddressLine(&Config.Addrs.tcp_incoming);
1213
1214 else if (!strcmp(token, "tcp_outgoing_address"))
1215 parseAddressLine(&Config.Addrs.tcp_outgoing);
1216
1217 else if (!strcmp(token, "udp_incoming_address"))
1218 parseAddressLine(&Config.Addrs.udp_incoming);
1219
1220 else if (!strcmp(token, "udp_outgoing_address"))
1221 parseAddressLine(&Config.Addrs.udp_outgoing);
1222
844327e4 1223 else if (!strcmp(token, "client_netmask"))
1224 parseAddressLine(&Config.Addrs.client_netmask);
1225
7813c6d5 1226 else if (!strcmp(token, "tcp_recv_bufsize"))
1227 parseIntegerValue(&Config.tcpRcvBufsz);
1228
2c82dc1a 1229 else if (!strcmp(token, "log_fqdn"))
1230 parseOnOff(&Config.Log.log_fqdn);
1231
090089c4 1232 else if (!strcmp(token, "bind_address"))
30a4f2a8 1233 parseAddressLine(&Config.Addrs.tcp_incoming);
1234
1235 else if (!strcmp(token, "outbound_address"))
1236 parseAddressLine(&Config.Addrs.tcp_outgoing);
090089c4 1237
30a4f2a8 1238 else if (!strcmp(token, "http_port") || !strcmp(token, "ascii_port"))
1239 parseHttpPortLine();
090089c4 1240
30a4f2a8 1241 else if (!strcmp(token, "icp_port") || !strcmp(token, "udp_port"))
1242 parseIcpPortLine();
090089c4 1243
1244 else if (!strcmp(token, "inside_firewall"))
b15fe823 1245 parseWordlist(&Config.inside_firewall_list);
090089c4 1246
605ba5ca 1247 else if (!strcmp(token, "dns_testnames"))
b15fe823 1248 parseWordlist(&Config.dns_testname_list);
605ba5ca 1249
090089c4 1250 else if (!strcmp(token, "single_parent_bypass"))
c1c29eb6 1251 parseOnOff(&Config.singleParentBypass);
090089c4 1252
12b9e9b1 1253 else if (!strcmp(token, "debug_options"))
3003c0f3 1254 parseDebugOptionsLine();
12b9e9b1 1255
ccff9601 1256 else if (!strcmp(token, "pid_filename"))
5ad764e2 1257 parsePathname(&Config.pidFilename);
ccff9601 1258
cf5fd929 1259 else if (!strcmp(token, "visible_hostname"))
3003c0f3 1260 parseVisibleHostnameLine();
cf5fd929 1261
fb263c4c 1262 else if (!strcmp(token, "ftp_user"))
3003c0f3 1263 parseFtpUserLine();
fb263c4c 1264
7d49daab 1265 else if (!strcmp(token, "cache_announce"))
3003c0f3 1266 parseCacheAnnounceLine();
7d49daab 1267
1268 else if (!strcmp(token, "announce_to"))
3003c0f3 1269 parseAnnounceToLine();
7d49daab 1270
98ffb7e4 1271 else if (!strcmp(token, "ssl_proxy"))
1272 parseSslProxyLine();
1273
6e40f263 1274 else if (!strcmp(token, "err_html_text"))
1275 parseErrHtmlLine();
1276
b15e6857 1277 else if (!strcmp(token, "ipcache_size"))
1278 parseIntegerValue(&Config.ipcache.size);
1279 else if (!strcmp(token, "ipcache_low"))
1280 parseIntegerValue(&Config.ipcache.low);
1281 else if (!strcmp(token, "ipcache_high"))
1282 parseIntegerValue(&Config.ipcache.high);
1283
caebbe00 1284 else if (!strcmp(token, "memory_pools"))
1285 parseOnOff(&opt_mem_pools);
1286 else if (!strcmp(token, "udp_hit_obj"))
1287 parseOnOff(&opt_udp_hit_obj);
1288 else if (!strcmp(token, "forwarded_for"))
1289 parseOnOff(&opt_forwarded_for);
1290
4d311579 1291 else if (!strcmp(token, "minimum_direct_hops"))
1292 parseIntegerValue(&Config.minDirectHops);
1293
a7e59001 1294 else if (!strcmp(token, "store_objects_per_bucket"))
38792624 1295 parseIntegerValue(&Config.Store.objectsPerBucket);
a7e59001 1296 else if (!strcmp(token, "store_avg_object_size"))
38792624 1297 parseIntegerValue(&Config.Store.avgObjectSize);
1298 else if (!strcmp(token, "maximum_object_size"))
1299 parseKilobytes(&Config.Store.maxObjectSize);
a7e59001 1300
752c3b27 1301 else if (!strcmp(token, "viz_hack_addr"))
1302 parseVizHackLine();
1303
caebbe00 1304 /* If unknown, treat as a comment line */
090089c4 1305 else {
540830c4 1306 debug(3, 0, "parseConfigFile: line %d unrecognized: '%s'\n",
92a6f4b1 1307 config_lineno,
1308 config_input_line);
090089c4 1309 }
1310 }
1311
090089c4 1312 /* Sanity checks */
b6f794d6 1313 if (Config.lifetimeDefault < Config.readTimeout) {
090089c4 1314 printf("WARNING: client_lifetime (%d seconds) is less than read_timeout (%d seconds).\n",
b6f794d6 1315 Config.lifetimeDefault, Config.readTimeout);
090089c4 1316 printf(" This may cause serious problems with your cache!!!\n");
b8de7ebe 1317 printf(" Change your configuration file.\n");
090089c4 1318 fflush(stdout); /* print message */
1319 }
b6f794d6 1320 if (Config.Swap.maxSize < (Config.Mem.maxSize >> 10)) {
1321 printf("WARNING: cache_swap (%d kbytes) is less than cache_mem (%d bytes).\n", Config.Swap.maxSize, Config.Mem.maxSize);
090089c4 1322 printf(" This will cause serious problems with your cache!!!\n");
b8de7ebe 1323 printf(" Change your configuration file.\n");
090089c4 1324 fflush(stdout); /* print message */
1325 }
a4ebeb3b 1326 if (Config.cleanRate < 1)
28b2f45f 1327 Config.cleanRate = 86400 * 365; /* one year */
a4ebeb3b 1328 if (Config.Announce.rate < 1)
1329 Config.Announce.rate = 86400 * 365; /* one year */
c021888f 1330 if (Config.dnsChildren < 0)
1331 Config.dnsChildren = 0;
b6f794d6 1332 if (Config.dnsChildren < 1) {
c021888f 1333 printf("WARNING: dnsservers are disabled!\n");
1334 printf("WARNING: Cache performance may be very poor\n");
b6f794d6 1335 } else if (Config.dnsChildren > DefaultDnsChildrenMax) {
090089c4 1336 printf("WARNING: dns_children was set to a bad value: %d\n",
b6f794d6 1337 Config.dnsChildren);
090089c4 1338 printf("Setting it to the maximum (%d).\n", DefaultDnsChildrenMax);
1339 Config.dnsChildren = DefaultDnsChildrenMax;
1340 }
dd7ad0a4 1341 if (Config.Program.redirect) {
f6c78bd2 1342 if (Config.redirectChildren < 1) {
c021888f 1343 Config.redirectChildren = 0;
dd7ad0a4 1344 safe_free(Config.Program.redirect);
f6c78bd2 1345 } else if (Config.redirectChildren > DefaultRedirectChildrenMax) {
c021888f 1346 printf("WARNING: redirect_children was set to a bad value: %d\n",
f6c78bd2 1347 Config.redirectChildren);
c021888f 1348 printf("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax);
1349 Config.redirectChildren = DefaultRedirectChildrenMax;
f6c78bd2 1350 }
d2af9477 1351 }
090089c4 1352 fclose(fp);
090089c4 1353 configDoConfigure();
1354 return 0;
1355}
1356
8203a132 1357u_short
1358setHttpPortNum(u_short port)
090089c4 1359{
30a4f2a8 1360 return (Config.Port.http = port);
090089c4 1361}
8203a132 1362u_short
1363setIcpPortNum(u_short port)
30a4f2a8 1364{
1365 return (Config.Port.icp = port);
1366}
1367
8203a132 1368static char *
0ee4272b 1369safe_xstrdup(const char *p)
090089c4 1370{
0ee4272b 1371 return p ? xstrdup(p) : NULL;
090089c4 1372}
1373
0a21bd84 1374void
0673c0ba 1375configFreeMemory(void)
0ffd22bc 1376{
1377 safe_free(Config.Wais.relayHost);
1378 safe_free(Config.Log.log);
1379 safe_free(Config.Log.access);
983061ed 1380 safe_free(Config.Log.store);
5ad764e2 1381 safe_free(Config.Log.swap);
0ffd22bc 1382 safe_free(Config.adminEmail);
1383 safe_free(Config.effectiveUser);
1384 safe_free(Config.effectiveGroup);
1385 safe_free(Config.Program.ftpget);
1386 safe_free(Config.Program.ftpget_opts);
1387 safe_free(Config.Program.dnsserver);
d2af9477 1388 safe_free(Config.Program.redirect);
dd573602 1389 safe_free(Config.Program.pinger);
0ffd22bc 1390 safe_free(Config.Accel.host);
1391 safe_free(Config.Accel.prefix);
1392 safe_free(Config.appendDomain);
1393 safe_free(Config.debugOptions);
1394 safe_free(Config.pidFilename);
1395 safe_free(Config.visibleHostname);
1396 safe_free(Config.ftpUser);
e81957b7 1397#if USE_PROXY_AUTH
1398 safe_free(Config.proxyAuthFile);
1399 safe_free(Config.proxyAuthIgnoreDomain);
1400#endif /* USE_PROXY_AUTH */
0ffd22bc 1401 safe_free(Config.Announce.host);
1402 safe_free(Config.Announce.file);
6e40f263 1403 safe_free(Config.errHtmlText);
caebbe00 1404 safe_free(Config.sslProxy.host);
0ffd22bc 1405 wordlistDestroy(&Config.cache_dirs);
30a4f2a8 1406 wordlistDestroy(&Config.hierarchy_stoplist);
0ffd22bc 1407 wordlistDestroy(&Config.local_domain_list);
e90100aa 1408 wordlistDestroy(&Config.mcast_group_list);
0ffd22bc 1409 wordlistDestroy(&Config.inside_firewall_list);
605ba5ca 1410 wordlistDestroy(&Config.dns_testname_list);
caebbe00 1411 ip_acl_destroy(&Config.local_ip_list);
1412 ip_acl_destroy(&Config.firewall_ip_list);
a7e59001 1413 refreshFreeMemory();
0ffd22bc 1414}
1415
090089c4 1416
8203a132 1417static void
0673c0ba 1418configSetFactoryDefaults(void)
090089c4 1419{
bd4d054c 1420 memset((char *) &Config, '\0', sizeof(Config));
090089c4 1421 Config.Mem.maxSize = DefaultMemMaxSize;
7813c6d5 1422 Config.Mem.highWaterMark = DefaultMemHighWaterMark;
1423 Config.Mem.lowWaterMark = DefaultMemLowWaterMark;
090089c4 1424 Config.Swap.maxSize = DefaultSwapMaxSize;
7813c6d5 1425 Config.Swap.highWaterMark = DefaultSwapHighWaterMark;
090089c4 1426 Config.Swap.lowWaterMark = DefaultSwapLowWaterMark;
1427
090089c4 1428 Config.Wais.relayHost = safe_xstrdup(DefaultWaisRelayHost);
1429 Config.Wais.relayPort = DefaultWaisRelayPort;
090089c4 1430
66cedb85 1431 Config.referenceAge = DefaultReferenceAge;
090089c4 1432 Config.negativeTtl = DefaultNegativeTtl;
2639dac6 1433 Config.negativeDnsTtl = DefaultNegativeDnsTtl;
1434 Config.positiveDnsTtl = DefaultPositiveDnsTtl;
090089c4 1435 Config.readTimeout = DefaultReadTimeout;
1436 Config.lifetimeDefault = DefaultLifetimeDefault;
605ba5ca 1437 Config.lifetimeShutdown = DefaultLifetimeShutdown;
fa966b74 1438 Config.maxRequestSize = DefaultMaxRequestSize;
090089c4 1439 Config.connectTimeout = DefaultConnectTimeout;
1440 Config.ageMaxDefault = DefaultDefaultAgeMax;
1441 Config.cleanRate = DefaultCleanRate;
1442 Config.dnsChildren = DefaultDnsChildren;
d2af9477 1443 Config.redirectChildren = DefaultRedirectChildren;
090089c4 1444 Config.sourcePing = DefaultSourcePing;
2546fcb3 1445 Config.quickAbort.min = DefaultQuickAbortMin;
1446 Config.quickAbort.pct = DefaultQuickAbortPct;
1447 Config.quickAbort.max = DefaultQuickAbortMax;
090089c4 1448 Config.commonLogFormat = DefaultCommonLogFormat;
2ba42578 1449#if LOG_FULL_HEADERS
e43efe50 1450 Config.logMimeHdrs = DefaultLogMimeHdrs;
1451#endif /* LOG_FULL_HEADERS */
12b9e9b1 1452 Config.debugOptions = safe_xstrdup(DefaultDebugOptions);
090089c4 1453 Config.neighborTimeout = DefaultNeighborTimeout;
e5c22962 1454 Config.stallDelay = DefaultStallDelay;
090089c4 1455 Config.singleParentBypass = DefaultSingleParentBypass;
1456 Config.adminEmail = safe_xstrdup(DefaultAdminEmail);
1457 Config.effectiveUser = safe_xstrdup(DefaultEffectiveUser);
1458 Config.effectiveGroup = safe_xstrdup(DefaultEffectiveGroup);
1459 Config.appendDomain = safe_xstrdup(DefaultAppendDomain);
6e40f263 1460 Config.errHtmlText = safe_xstrdup(DefaultErrHtmlText);
090089c4 1461
30a4f2a8 1462 Config.Port.http = DefaultHttpPortNum;
1463 Config.Port.icp = DefaultIcpPortNum;
090089c4 1464 Config.Log.log = safe_xstrdup(DefaultCacheLogFile);
1465 Config.Log.access = safe_xstrdup(DefaultAccessLogFile);
d8b45066 1466 Config.Log.store = safe_xstrdup(DefaultStoreLogFile);
5ad764e2 1467 Config.Log.swap = safe_xstrdup(DefaultSwapLogFile);
090089c4 1468 Config.Log.rotateNumber = DefaultLogRotateNumber;
1469 Config.Program.ftpget = safe_xstrdup(DefaultFtpgetProgram);
1470 Config.Program.ftpget_opts = safe_xstrdup(DefaultFtpgetOptions);
1471 Config.Program.dnsserver = safe_xstrdup(DefaultDnsserverProgram);
d2af9477 1472 Config.Program.redirect = safe_xstrdup(DefaultRedirectProgram);
365a4bce 1473 Config.Program.pinger = safe_xstrdup(DefaultPingerProgram);
090089c4 1474 Config.Accel.host = safe_xstrdup(DefaultAccelHost);
1475 Config.Accel.prefix = safe_xstrdup(DefaultAccelPrefix);
1476 Config.Accel.port = DefaultAccelPort;
1477 Config.Accel.withProxy = DefaultAccelWithProxy;
ccff9601 1478 Config.pidFilename = safe_xstrdup(DefaultPidFilename);
cf5fd929 1479 Config.visibleHostname = safe_xstrdup(DefaultVisibleHostname);
e81957b7 1480#if USE_PROXY_AUTH
1481 Config.proxyAuthFile = safe_xstrdup(DefaultProxyAuthFile);
1482 Config.proxyAuthIgnoreDomain = safe_xstrdup(DefaultProxyAuthIgnoreDomain);
1483#endif /* USE_PROXY_AUTH */
fb263c4c 1484 Config.ftpUser = safe_xstrdup(DefaultFtpUser);
7d49daab 1485 Config.Announce.host = safe_xstrdup(DefaultAnnounceHost);
1486 Config.Announce.port = DefaultAnnouncePort;
1487 Config.Announce.file = safe_xstrdup(DefaultAnnounceFile);
1488 Config.Announce.rate = DefaultAnnounceRate;
1d73e33a 1489 Config.Announce.on = 0;
7813c6d5 1490 Config.tcpRcvBufsz = DefaultTcpRcvBufsz;
30a4f2a8 1491 Config.Addrs.tcp_outgoing.s_addr = DefaultTcpOutgoingAddr;
1492 Config.Addrs.tcp_incoming.s_addr = DefaultTcpIncomingAddr;
1493 Config.Addrs.udp_outgoing.s_addr = DefaultUdpOutgoingAddr;
1494 Config.Addrs.udp_incoming.s_addr = DefaultUdpIncomingAddr;
844327e4 1495 Config.Addrs.client_netmask.s_addr = DefaultClientNetmask;
98ffb7e4 1496 Config.sslProxy.port = DefaultSslProxyPort;
1497 Config.sslProxy.host = safe_xstrdup(DefaultSslProxyHost);
b15e6857 1498 Config.ipcache.size = DefaultIpcacheSize;
1499 Config.ipcache.low = DefaultIpcacheLow;
1500 Config.ipcache.high = DefaultIpcacheHigh;
4d311579 1501 Config.minDirectHops = DefaultMinDirectHops;
38792624 1502 Config.Store.maxObjectSize = DefaultMaxObjectSize;
1503 Config.Store.avgObjectSize = DefaultAvgObjectSize;
1504 Config.Store.objectsPerBucket = DefaultObjectsPerBucket;
090089c4 1505}
1506
8203a132 1507static void
0673c0ba 1508configDoConfigure(void)
090089c4 1509{
1510 httpd_accel_mode = Config.Accel.prefix ? 1 : 0;
de3a6e4e 1511 sprintf(ForwardedBy, "Forwarded: by http://%s:%d/ (Squid/%s)",
1512 getMyHostname(), Config.Port.http, SQUID_VERSION);
eb2d04cd 1513 if (Config.errHtmlText == NULL)
0a21bd84 1514 Config.errHtmlText = xstrdup(null_string);
b1c0cc67 1515 storeConfigure();
c021888f 1516 if (httpd_accel_mode && !Config.Accel.withProxy) {
dd7ad0a4 1517 safe_free(Config.Program.ftpget);
1518 Config.Program.ftpget = xstrdup("none");
c021888f 1519 }
ca2b438f 1520 if (httpd_accel_mode && !strcmp(Config.Accel.host, "virtual"))
1521 vhost_mode = 1;
090089c4 1522}