]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_cf.cc
gindent
[thirdparty/squid.git] / src / cache_cf.cc
CommitLineData
30a4f2a8 1/*
a4394ebd 2 * $Id: cache_cf.cc,v 1.197 1997/06/21 02:38:04 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
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% */
3e347513 113#define DefaultSwapMaxSize 0
e924600d 114#define DefaultSwapHighWaterMark 95 /* 95% */
115#define DefaultSwapLowWaterMark 90 /* 90% */
d0f4739d 116#define DefaultNetdbHigh 1000 /* counts, not percents */
117#define DefaultNetdbLow 900
429fdbec 118#define DefaultNetdbPeriod 300 /* 5 minutes */
090089c4 119
090089c4 120#define DefaultWaisRelayHost (char *)NULL
30a4f2a8 121#define DefaultWaisRelayPort 0
090089c4 122
429fdbec 123#define DefaultReferenceAge (86400*365) /* 1 year */
090089c4 124#define DefaultNegativeTtl (5 * 60) /* 5 min */
61d6fc5c 125#define DefaultNegativeDnsTtl (2 * 60) /* 2 min */
2639dac6 126#define DefaultPositiveDnsTtl (360 * 60) /* 6 hours */
4f92c80c 127#define DefaultReadTimeout (15 * 60) /* 15 min */
128#define DefaultConnectTimeout 120 /* 2 min */
129#define DefaultDeferTimeout 3600 /* 1 hour */
812ed90c 130#define DefaultRequestTimeout 30 /* 30 seconds */
4f92c80c 131#define DefaultClientLifetime 86400 /* 1 day */
132#define DefaultShutdownLifetime 30 /* 30 seconds */
133#define DefaultCleanRate -1 /* disabled */
d2af9477 134#define DefaultDnsChildren 5 /* 5 processes */
e924600d 135#define DefaultOptionsResDefnames 0 /* default off */
136#define DefaultOptionsAnonymizer 0 /* default off */
d2af9477 137#define DefaultRedirectChildren 5 /* 5 processes */
234967c9 138#define DefaultMaxRequestSize (100 << 10) /* 100Kb */
090089c4 139
30a4f2a8 140#define DefaultHttpPortNum CACHE_HTTP_PORT
141#define DefaultIcpPortNum CACHE_ICP_PORT
090089c4 142
e924600d 143#define DefaultLogLogFqdn 0 /* default off */
a26bdc75 144#define DefaultCacheLogFile DEFAULT_CACHE_LOG
145#define DefaultAccessLogFile DEFAULT_ACCESS_LOG
48f44632 146#define DefaultUseragentLogFile (char *)NULL /* default NONE */
d8b45066 147#define DefaultStoreLogFile DEFAULT_STORE_LOG
5ad764e2 148#define DefaultSwapLogFile (char *)NULL /* default swappath(0) */
e81957b7 149#if USE_PROXY_AUTH
150#define DefaultProxyAuthFile (char *)NULL /* default NONE */
e81957b7 151#endif /* USE_PROXY_AUTH */
090089c4 152#define DefaultLogRotateNumber 10
153#define DefaultAdminEmail "webmaster"
a26bdc75 154#define DefaultDnsserverProgram DEFAULT_DNSSERVER
365a4bce 155#define DefaultPingerProgram DEFAULT_PINGER
429fdbec 156#define DefaultUnlinkdProgram DEFAULT_UNLINKD
d2af9477 157#define DefaultRedirectProgram (char *)NULL /* default NONE */
090089c4 158#define DefaultEffectiveUser (char *)NULL /* default NONE */
159#define DefaultEffectiveGroup (char *)NULL /* default NONE */
160#define DefaultAppendDomain (char *)NULL /* default NONE */
6e40f263 161#define DefaultErrHtmlText (char *)NULL /* default NONE */
090089c4 162
ccff9601 163#define DefaultDebugOptions "ALL,1" /* All sections at level 1 */
090089c4 164#define DefaultAccelHost (char *)NULL /* default NONE */
165#define DefaultAccelPrefix (char *)NULL /* default NONE */
166#define DefaultAccelPort 0 /* default off */
167#define DefaultAccelWithProxy 0 /* default off */
168#define DefaultSourcePing 0 /* default off */
1ef4c6c1 169#define DefaultCommonLogFormat 0 /* default off */
e43efe50 170#define DefaultLogMimeHdrs 0 /* default off */
c1c29eb6 171#define DefaultIdentLookup 0 /* default off */
2546fcb3 172#define DefaultQuickAbortMin -1 /* default off */
173#define DefaultQuickAbortPct 0 /* default off */
174#define DefaultQuickAbortMax 0 /* default off */
090089c4 175#define DefaultNeighborTimeout 2 /* 2 seconds */
234967c9 176#define DefaultStallDelay 1 /* 1 seconds */
090089c4 177#define DefaultSingleParentBypass 0 /* default off */
0b4639af 178#define DefaultPidFilename DEFAULT_PID_FILE
812ed90c 179#define DefaultMimeTable DEFAULT_MIME_TABLE
cf5fd929 180#define DefaultVisibleHostname (char *)NULL /* default NONE */
e34e0322 181#define DefaultFtpAnonUser "squid@" /* Default without domain */
7d49daab 182#define DefaultAnnounceHost "sd.cache.nlanr.net"
183#define DefaultAnnouncePort 3131
7ba794f4 184#define DefaultAnnounceFile (char *)NULL /* default NONE */
30a4f2a8 185#define DefaultAnnounceRate 0 /* Default off */
7813c6d5 186#define DefaultTcpRcvBufsz 0 /* use system default */
9e205701 187#define DefaultUdpMaxHitObjsz SQUID_UDP_SO_SNDBUF /* from configure */
30a4f2a8 188#define DefaultTcpIncomingAddr INADDR_ANY
429fdbec 189#define DefaultTcpOutgoingAddr no_addr.s_addr
30a4f2a8 190#define DefaultUdpIncomingAddr INADDR_ANY
429fdbec 191#define DefaultUdpOutgoingAddr no_addr.s_addr
86ee2017 192#define DefaultClientNetmask 0xFFFFFFFFul
e924600d 193#define DefaultPassProxy NULL
194#define DefaultSslProxy NULL
b15e6857 195#define DefaultIpcacheSize 1024
196#define DefaultIpcacheLow 90
197#define DefaultIpcacheHigh 95
4d311579 198#define DefaultMinDirectHops 4
38792624 199#define DefaultMaxObjectSize (4<<20) /* 4Mb */
200#define DefaultAvgObjectSize 20 /* 20k */
201#define DefaultObjectsPerBucket 50
ccff9601 202
ee4a1f5d 203#define DefaultOptionsLogUdp 1 /* on */
e924600d 204#define DefaultOptionsEnablePurge 0 /* default off */
429fdbec 205#define DefaultOptionsClientDb 1 /* default on */
206#define DefaultOptionsQueryIcmp 0 /* default off */
207
3fdadc70 208#define DefaultFtpIconPrefix "internal-"
209#define DefaultFtpIconSuffix null_string
210#define DefaultFtpListWidth 32
211#define DefaultFtpListWrap 0
212
8813e606 213static const char *const T_SECOND_STR = "second";
214static const char *const T_MINUTE_STR = "minute";
215static const char *const T_HOUR_STR = "hour";
216static const char *const T_DAY_STR = "day";
217static const char *const T_WEEK_STR = "week";
218static const char *const T_FORTNIGHT_STR = "fortnight";
219static const char *const T_MONTH_STR = "month";
220static const char *const T_YEAR_STR = "year";
221static const char *const T_DECADE_STR = "decade";
aa0a0c7c 222
090089c4 223int httpd_accel_mode = 0; /* for fast access */
0ee4272b 224const char *DefaultSwapDir = DEFAULT_SWAP_DIR;
225const char *DefaultConfigFile = DEFAULT_CONFIG_FILE;
cbbad1ed 226char *ConfigFile = NULL; /* the whole thing */
0ee4272b 227const char *cfg_filename = NULL; /* just the last part */
090089c4 228
4db43fab 229static const char *const list_sep = ", \t\n\r";
3003c0f3 230char config_input_line[BUFSIZ];
231int config_lineno = 0;
090089c4 232
24382924 233static char fatal_str[BUFSIZ];
0ee4272b 234static char *safe_xstrdup _PARAMS((const char *p));
67508012 235static void parseOnOff _PARAMS((int *));
236static void parseIntegerValue _PARAMS((int *));
3c5557f9 237static void parseString _PARAMS((char **));
24382924 238static void self_destruct _PARAMS((void));
0ee4272b 239static void wordlistAdd _PARAMS((wordlist **, const char *));
caebbe00 240
67508012 241static void configDoConfigure _PARAMS((void));
67508012 242static void configSetFactoryDefaults _PARAMS((void));
67508012 243static void parseAddressLine _PARAMS((struct in_addr *));
244static void parseAnnounceToLine _PARAMS((void));
245static void parseAppendDomainLine _PARAMS((void));
246static void parseCacheAnnounceLine _PARAMS((void));
247static void parseCacheHostLine _PARAMS((void));
248static void parseDebugOptionsLine _PARAMS((void));
67508012 249static void parseEffectiveUserLine _PARAMS((void));
250static void parseErrHtmlLine _PARAMS((void));
67508012 251static void parseWordlist _PARAMS((wordlist **));
252static void parseHostAclLine _PARAMS((void));
253static void parseHostDomainLine _PARAMS((void));
b012353a 254static void parseHostDomainTypeLine _PARAMS((void));
67508012 255static void parseHttpPortLine _PARAMS((void));
256static void parseHttpdAccelLine _PARAMS((void));
67508012 257static void parseIcpPortLine _PARAMS((void));
e90100aa 258static void parseMcastGroupLine _PARAMS((void));
67508012 259static void parseMemLine _PARAMS((void));
260static void parseMgrLine _PARAMS((void));
38792624 261static void parseKilobytes _PARAMS((int *));
a7e59001 262static void parseRefreshPattern _PARAMS((int icase));
67508012 263static void parseVisibleHostnameLine _PARAMS((void));
264static void parseWAISRelayLine _PARAMS((void));
3c5557f9 265static void parseCachemgrPasswd _PARAMS((void));
429fdbec 266static void parsePathname _PARAMS((char **, int fatal));
deb79f06 267static void parseProxyLine _PARAMS((peer **));
fa562c67 268static void parseHttpAnonymizer _PARAMS((int *));
429fdbec 269static int parseTimeUnits _PARAMS((const char *unit));
270static void parseTimeLine _PARAMS((int *iptr, const char *units));
8203a132 271
24382924 272static void
0673c0ba 273self_destruct(void)
090089c4 274{
b8de7ebe 275 sprintf(fatal_str, "Bungled %s line %d: %s",
276 cfg_filename, config_lineno, config_input_line);
090089c4 277 fatal(fatal_str);
278}
279
8203a132 280void
281wordlistDestroy(wordlist ** list)
0ffd22bc 282{
283 wordlist *w = NULL;
b5639035 284 while ((w = *list)) {
285 *list = w->next;
0ffd22bc 286 safe_free(w->key);
287 safe_free(w);
288 }
289 *list = NULL;
290}
291
24382924 292static void
fe4e214f 293wordlistAdd(wordlist ** list, const char *key)
090089c4 294{
0ffd22bc 295 wordlist *p = NULL;
296 wordlist *q = NULL;
090089c4 297
298 if (!(*list)) {
299 /* empty list */
30a4f2a8 300 *list = xcalloc(1, sizeof(wordlist));
090089c4 301 (*list)->key = xstrdup(key);
302 (*list)->next = NULL;
303 } else {
304 p = *list;
305 while (p->next)
306 p = p->next;
30a4f2a8 307 q = xcalloc(1, sizeof(wordlist));
090089c4 308 q->key = xstrdup(key);
309 q->next = NULL;
310 p->next = q;
311 }
312}
313
8203a132 314void
315intlistDestroy(intlist ** list)
92a6f4b1 316{
317 intlist *w = NULL;
318 intlist *n = NULL;
319
320 for (w = *list; w; w = n) {
321 n = w->next;
322 safe_free(w);
323 }
324 *list = NULL;
325}
326
403279e0 327
3c5557f9 328/*
329 * Use this #define in all the parse*() functions. Assumes char *token is
330 * defined
331 */
090089c4 332
333#define GetInteger(var) \
334 token = strtok(NULL, w_space); \
30a4f2a8 335 if( token == NULL) \
3003c0f3 336 self_destruct(); \
090089c4 337 if (sscanf(token, "%d", &var) != 1) \
3003c0f3 338 self_destruct();
090089c4 339
340
8203a132 341static void
0673c0ba 342parseCacheHostLine(void)
090089c4 343{
344 char *type = NULL;
345 char *hostname = NULL;
346 char *token = NULL;
30a4f2a8 347 u_short http_port = CACHE_HTTP_PORT;
348 u_short icp_port = CACHE_ICP_PORT;
349 int options = 0;
fe113054 350 int weight = 1;
e90100aa 351 int mcast_ttl = 0;
30a4f2a8 352 int i;
090089c4 353
090089c4 354 if (!(hostname = strtok(NULL, w_space)))
3003c0f3 355 self_destruct();
090089c4 356 if (!(type = strtok(NULL, w_space)))
3003c0f3 357 self_destruct();
090089c4 358
30a4f2a8 359 GetInteger(i);
360 http_port = (u_short) i;
361 GetInteger(i);
362 icp_port = (u_short) i;
fe113054 363 while ((token = strtok(NULL, w_space))) {
364 if (!strcasecmp(token, "proxy-only")) {
30a4f2a8 365 options |= NEIGHBOR_PROXY_ONLY;
366 } else if (!strcasecmp(token, "no-query")) {
367 options |= NEIGHBOR_NO_QUERY;
7b3bd12c 368 } else if (!strcasecmp(token, "multicast-responder")) {
369 options |= NEIGHBOR_MCAST_RESPONDER;
c06a5b15 370 } else if (!strncasecmp(token, "weight=", 7)) {
a0bbd6c8 371 weight = atoi(token + 7);
e90100aa 372 } else if (!strncasecmp(token, "ttl=", 4)) {
373 mcast_ttl = atoi(token + 4);
429fdbec 374 if (mcast_ttl < 0)
375 mcast_ttl = 0;
376 if (mcast_ttl > 128)
377 mcast_ttl = 128;
5269d0bd 378 } else if (!strncasecmp(token, "default", 7)) {
379 options |= NEIGHBOR_DEFAULT_PARENT;
48b38d01 380 } else if (!strncasecmp(token, "round-robin", 11)) {
381 options |= NEIGHBOR_ROUNDROBIN;
fe113054 382 } else {
a3d5953d 383 debug(3, 0) ("parseCacheHostLine: token='%s'\n", token);
a0bbd6c8 384 self_destruct();
fe113054 385 }
090089c4 386 }
234967c9 387 if (weight < 1)
388 weight = 1;
b012353a 389 neighborAdd(hostname, type, http_port, icp_port, options,
e90100aa 390 weight, mcast_ttl);
090089c4 391}
392
b012353a 393
394static void
395parseHostDomainLine(void)
24a1003d 396{
b012353a 397 char *host = NULL;
398 char *domain = NULL;
399 if (!(host = strtok(NULL, w_space)))
400 self_destruct();
401 while ((domain = strtok(NULL, list_sep)))
402 neighborAddDomainPing(host, domain);
24a1003d 403}
404
8203a132 405static void
b012353a 406parseHostDomainTypeLine(void)
090089c4 407{
408 char *host = NULL;
b012353a 409 char *type = NULL;
090089c4 410 char *domain = NULL;
30a4f2a8 411 if (!(host = strtok(NULL, w_space)))
412 self_destruct();
b012353a 413 if (!(type = strtok(NULL, w_space)))
414 self_destruct();
415 while ((domain = strtok(NULL, list_sep)))
416 neighborAddDomainType(host, domain, type);
30a4f2a8 417}
090089c4 418
8203a132 419static void
0673c0ba 420parseHostAclLine(void)
30a4f2a8 421{
422 char *host = NULL;
423 char *aclname = NULL;
090089c4 424 if (!(host = strtok(NULL, w_space)))
3003c0f3 425 self_destruct();
b012353a 426 while ((aclname = strtok(NULL, list_sep)))
427 neighborAddAcl(host, aclname);
090089c4 428}
429
8203a132 430static void
0673c0ba 431parseMemLine(void)
090089c4 432{
433 char *token;
434 int i;
435 GetInteger(i);
436 Config.Mem.maxSize = i << 20;
437}
438
090089c4 439
8203a132 440static void
a7e59001 441parseRefreshPattern(int icase)
090089c4 442{
443 char *token;
444 char *pattern;
a7e59001 445 time_t min = 0;
446 int pct = 0;
447 time_t max = 0;
090089c4 448 int i;
090089c4 449 token = strtok(NULL, w_space); /* token: regex pattern */
30a4f2a8 450 if (token == NULL)
3003c0f3 451 self_destruct();
090089c4 452 pattern = xstrdup(token);
a7e59001 453 GetInteger(i); /* token: min */
454 min = (time_t) (i * 60); /* convert minutes to seconds */
455 GetInteger(i); /* token: pct */
456 pct = i;
457 GetInteger(i); /* token: max */
458 max = (time_t) (i * 60); /* convert minutes to seconds */
459 refreshAddToList(pattern, icase, min, pct, max);
2546fcb3 460 safe_free(pattern);
461}
462
8203a132 463static void
0673c0ba 464parseQuickAbort(void)
2546fcb3 465{
466 char *token;
467 int i;
fea2e6e0 468 token = strtok(NULL, w_space);
469 if (!strcasecmp(token, "on")) {
470 Config.quickAbort.min = 10 << 10; /* 10k */
471 Config.quickAbort.pct = 64; /* 50% */
472 Config.quickAbort.max = 100 << 10; /* 100k */
473 } else if (!strcasecmp(token, "off")) {
474 Config.quickAbort.min = -1;
475 Config.quickAbort.pct = 0;
476 Config.quickAbort.max = 0;
477 } else {
6c93e119 478 if (sscanf(token, "%d", &i) != 1)
479 self_destruct();
fea2e6e0 480 Config.quickAbort.min = i * 1024;
481 GetInteger(i);
482 Config.quickAbort.pct = i * 128 / 100; /* 128 is full scale */
483 GetInteger(i);
484 Config.quickAbort.max = i * 1024;
485 }
2546fcb3 486}
487
8203a132 488static void
38792624 489parseKilobytes(int *val)
fa966b74 490{
491 char *token;
492 int i;
493 GetInteger(i);
38792624 494 *val = i * 1024;
fa966b74 495}
496
8203a132 497static void
0673c0ba 498parseMgrLine(void)
090089c4 499{
500 char *token;
501 token = strtok(NULL, w_space);
30a4f2a8 502 if (token == NULL)
3003c0f3 503 self_destruct();
090089c4 504 safe_free(Config.adminEmail);
505 Config.adminEmail = xstrdup(token);
506}
507
e81957b7 508#if USE_PROXY_AUTH
8203a132 509static void
0673c0ba 510parseProxyAuthLine(void)
e81957b7 511{
512 char *token;
e81957b7 513 token = strtok(NULL, w_space);
514 if (token == NULL)
fea2e6e0 515 self_destruct();
e924600d 516 safe_free(Config.proxyAuth.File);
517 aclDestroyRegexList(Config.proxyAuth.IgnoreDomains);
518 Config.proxyAuth.IgnoreDomains = NULL;
519 Config.proxyAuth.File = xstrdup(token);
520 aclParseRegexList(&Config.proxyAuth.IgnoreDomains, 1);
e81957b7 521}
522#endif /* USE_PROXY_AUTH */
523
8203a132 524static void
0673c0ba 525parseHttpdAccelLine(void)
090089c4 526{
527 char *token;
844327e4 528 LOCAL_ARRAY(char, buf, BUFSIZ);
090089c4 529 int i;
090089c4 530 token = strtok(NULL, w_space);
30a4f2a8 531 if (token == NULL)
3003c0f3 532 self_destruct();
090089c4 533 safe_free(Config.Accel.host);
534 Config.Accel.host = xstrdup(token);
535 GetInteger(i);
536 Config.Accel.port = i;
537 safe_free(Config.Accel.prefix);
538 sprintf(buf, "http://%s:%d", Config.Accel.host, Config.Accel.port);
539 Config.Accel.prefix = xstrdup(buf);
540 httpd_accel_mode = 1;
541}
542
8203a132 543static void
0673c0ba 544parseEffectiveUserLine(void)
090089c4 545{
546 char *token;
090089c4 547 token = strtok(NULL, w_space);
30a4f2a8 548 if (token == NULL)
3003c0f3 549 self_destruct();
090089c4 550 safe_free(Config.effectiveUser);
551 safe_free(Config.effectiveGroup);
552 Config.effectiveUser = xstrdup(token);
090089c4 553 token = strtok(NULL, w_space);
30a4f2a8 554 if (token == NULL)
090089c4 555 return; /* group is optional */
556 Config.effectiveGroup = xstrdup(token);
557}
558
8203a132 559static void
429fdbec 560parsePathname(char **path, int fatal)
090089c4 561{
562 char *token;
429fdbec 563 struct stat sb;
090089c4 564 token = strtok(NULL, w_space);
30a4f2a8 565 if (token == NULL)
3003c0f3 566 self_destruct();
5ad764e2 567 safe_free(*path);
568 *path = xstrdup(token);
429fdbec 569 if (fatal && stat(token, &sb) < 0) {
a3d5953d 570 debug(50, 1) ("parsePathname: %s: %s\n", token, xstrerror());
3003c0f3 571 self_destruct();
429fdbec 572 }
090089c4 573}
574
8203a132 575static void
576parseOnOff(int *var)
090089c4 577{
578 char *token;
579 token = strtok(NULL, w_space);
30a4f2a8 580 if (token == NULL)
3003c0f3 581 self_destruct();
090089c4 582 if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
c1c29eb6 583 *var = 1;
090089c4 584 else
c1c29eb6 585 *var = 0;
090089c4 586}
587
8203a132 588static void
0673c0ba 589parseWAISRelayLine(void)
090089c4 590{
591 char *token;
592 int i;
593 token = strtok(NULL, w_space);
30a4f2a8 594 if (token == NULL)
3003c0f3 595 self_destruct();
090089c4 596 safe_free(Config.Wais.relayHost);
597 Config.Wais.relayHost = xstrdup(token);
598 GetInteger(i);
30a4f2a8 599 Config.Wais.relayPort = (u_short) i;
090089c4 600}
601
8203a132 602static void
235c7b49 603parseWordlist(wordlist ** list)
30a4f2a8 604{
605 char *token;
606 while ((token = strtok(NULL, w_space)))
b15fe823 607 wordlistAdd(list, token);
30a4f2a8 608}
090089c4 609
8203a132 610static void
0673c0ba 611parseAppendDomainLine(void)
090089c4 612{
613 char *token;
614 token = strtok(NULL, w_space);
30a4f2a8 615 if (token == NULL)
3003c0f3 616 self_destruct();
090089c4 617 if (*token != '.')
3003c0f3 618 self_destruct();
090089c4 619 safe_free(Config.appendDomain);
620 Config.appendDomain = xstrdup(token);
621}
622
8203a132 623static void
624parseAddressLine(struct in_addr *addr)
090089c4 625{
626 char *token;
0ee4272b 627 const struct hostent *hp;
090089c4 628 token = strtok(NULL, w_space);
30a4f2a8 629 if (token == NULL)
630 self_destruct();
429fdbec 631 if (safe_inet_addr(token, addr) == 1)
632 (void) 0;
ceb8994e 633 else if ((hp = gethostbyname(token))) /* dont use ipcache */
1d73e33a 634 *addr = inaddrFromHostent(hp);
30a4f2a8 635 else
3003c0f3 636 self_destruct();
090089c4 637}
638
e90100aa 639static void
640parseMcastGroupLine(void)
641{
642 char *token = NULL;
643 while ((token = strtok(NULL, w_space)))
644 wordlistAdd(&Config.mcast_group_list, token);
645}
646
8203a132 647static void
0673c0ba 648parseHttpPortLine(void)
090089c4 649{
650 char *token;
651 int i;
812ed90c 652 if (Config.Port.n_http == MAXHTTPPORTS) {
653 sprintf(fatal_str, "Limit of %d HTTP Ports exceeded, redefine MAXHTTPPORTS.\n",
654 MAXHTTPPORTS);
655 fatal(fatal_str);
656 }
090089c4 657 GetInteger(i);
30a4f2a8 658 if (i < 0)
659 i = 0;
812ed90c 660 Config.Port.http[Config.Port.n_http++] = (u_short) i;
090089c4 661}
662
8203a132 663static void
0673c0ba 664parseIcpPortLine(void)
090089c4 665{
666 char *token;
667 int i;
668 GetInteger(i);
30a4f2a8 669 if (i < 0)
670 i = 0;
671 Config.Port.icp = (u_short) i;
090089c4 672}
673
8203a132 674static void
0673c0ba 675parseDebugOptionsLine(void)
090089c4 676{
12b9e9b1 677 char *token;
0a21bd84 678 token = strtok(NULL, null_string);
12b9e9b1 679 safe_free(Config.debugOptions);
30a4f2a8 680 if (token == NULL) {
12b9e9b1 681 Config.debugOptions = NULL;
682 return;
683 }
684 Config.debugOptions = xstrdup(token);
090089c4 685}
686
8203a132 687static void
0673c0ba 688parseVisibleHostnameLine(void)
cf5fd929 689{
690 char *token;
691 token = strtok(NULL, w_space);
692 safe_free(Config.visibleHostname);
30a4f2a8 693 if (token == NULL)
3003c0f3 694 self_destruct();
cf5fd929 695 Config.visibleHostname = xstrdup(token);
696}
697
8203a132 698static void
0673c0ba 699parseCacheAnnounceLine(void)
7d49daab 700{
701 char *token;
702 int i;
703 GetInteger(i);
704 Config.Announce.rate = i * 3600; /* hours to seconds */
0670a3cb 705 if (Config.Announce.rate > 0)
b3b64e58 706 Config.Announce.on = 1;
7d49daab 707}
708
8203a132 709static void
0673c0ba 710parseAnnounceToLine(void)
7d49daab 711{
712 char *token;
713 int i;
714 token = strtok(NULL, w_space);
30a4f2a8 715 if (token == NULL)
3003c0f3 716 self_destruct();
7d49daab 717 safe_free(Config.Announce.host);
718 Config.Announce.host = xstrdup(token);
719 if ((token = strchr(Config.Announce.host, ':'))) {
720 *token++ = '\0';
721 if (sscanf(token, "%d", &i) != 1)
722 Config.Announce.port = i;
723 }
724 token = strtok(NULL, w_space);
30a4f2a8 725 if (token == NULL)
7d49daab 726 return;
727 safe_free(Config.Announce.file);
728 Config.Announce.file = xstrdup(token);
729}
730
752c3b27 731static void
732parseVizHackLine(void)
733{
734 char *token;
735 int i;
0ee4272b 736 const struct hostent *hp;
752c3b27 737 token = strtok(NULL, w_space);
752c3b27 738 if (token == NULL)
739 self_destruct();
429fdbec 740 if (safe_inet_addr(token, &Config.vizHack.addr) == 1)
741 (void) 0;
752c3b27 742 else if ((hp = gethostbyname(token))) /* dont use ipcache */
9d4b2981 743 Config.vizHack.addr = inaddrFromHostent(hp);
752c3b27 744 else
745 self_destruct();
746 if ((token = strtok(NULL, w_space)) == NULL)
747 self_destruct();
748 if (sscanf(token, "%d", &i) == 1)
9d4b2981 749 Config.vizHack.port = i;
750 Config.vizHack.mcast_ttl = 64;
30e9cbfa 751 if ((token = strtok(NULL, w_space)) == NULL)
9d4b2981 752 return;
753 if (sscanf(token, "%d", &i) == 1)
754 Config.vizHack.mcast_ttl = i;
752c3b27 755}
756
8203a132 757static void
deb79f06 758parseProxyLine(peer ** E)
98ffb7e4 759{
760 char *token;
761 char *t;
deb79f06 762 peer *e;
98ffb7e4 763 token = strtok(NULL, w_space);
764 if (token == NULL)
765 self_destruct();
e6e3b09b 766 if (*E) {
deb79f06 767 peerDestroy(*E);
e6e3b09b 768 *E = NULL;
769 }
deb79f06 770 e = xcalloc(1, sizeof(peer));
98ffb7e4 771 if ((t = strchr(token, ':'))) {
772 *t++ = '\0';
e6e3b09b 773 e->http_port = atoi(t);
98ffb7e4 774 }
e6e3b09b 775 e->host = xstrdup(token);
b5639035 776 e->tcp_up = 1;
e6e3b09b 777 *E = e;
98ffb7e4 778}
779
8203a132 780static void
781parseIntegerValue(int *iptr)
7813c6d5 782{
783 char *token;
784 int i;
785 GetInteger(i);
786 *iptr = i;
787}
788
3c5557f9 789static void
790parseString(char **sptr)
791{
792 char *token;
793 token = strtok(NULL, w_space);
794 if (token == NULL)
795 self_destruct();
796 *sptr = xstrdup(token);
797}
798
8203a132 799static void
0673c0ba 800parseErrHtmlLine(void)
6e40f263 801{
802 char *token;
0a21bd84 803 if ((token = strtok(NULL, null_string)))
6e40f263 804 Config.errHtmlText = xstrdup(token);
805}
403279e0 806
3c5557f9 807static void
808parseCachemgrPasswd(void)
809{
810 char *passwd = NULL;
811 wordlist *actions = NULL;
812 parseString(&passwd);
813 parseWordlist(&actions);
814 objcachePasswdAdd(&Config.passwd_list, passwd, actions);
815 wordlistDestroy(&actions);
816}
817
fa562c67 818static void
819parseHttpAnonymizer(int *iptr)
820{
821 char *token;
822 token = strtok(NULL, w_space);
823 if (token == NULL)
bba6fa8f 824 self_destruct();
fa562c67 825 if (!strcasecmp(token, "off"))
826 *iptr = ANONYMIZER_NONE;
827 else if (!strcasecmp(token, "paranoid"))
828 *iptr = ANONYMIZER_PARANOID;
829 else
830 *iptr = ANONYMIZER_STANDARD;
831}
832
641941c0 833static void
834parseCacheDir(void)
835{
836 char *token;
837 char *dir;
838 int i;
839 int size;
840 int l1;
841 int l2;
842 int readonly = 0;
843 if ((token = strtok(NULL, w_space)) == NULL)
844 self_destruct();
845 dir = token;
846 GetInteger(i);
3e347513 847 size = i << 10; /* Mbytes to kbytes */
76fefb77 848 Config.Swap.maxSize += size;
641941c0 849 GetInteger(i);
850 l1 = i;
851 GetInteger(i);
852 l2 = i;
853 if ((token = strtok(NULL, w_space)))
854 if (!strcasecmp(token, "read-only"))
855 readonly = 1;
2bd8a8a8 856 if (configured_once)
b5639035 857 storeReconfigureSwapDisk(dir, size, l1, l2, readonly);
2bd8a8a8 858 else
b5639035 859 storeAddSwapDisk(dir, size, l1, l2, readonly);
641941c0 860}
861
8203a132 862int
0ee4272b 863parseConfigFile(const char *file_name)
090089c4 864{
12b9e9b1 865 FILE *fp = NULL;
866 char *token = NULL;
844327e4 867 LOCAL_ARRAY(char, tmp_line, BUFSIZ);
090089c4 868
0ffd22bc 869 configFreeMemory();
090089c4 870 configSetFactoryDefaults();
92a6f4b1 871 aclDestroyAcls();
85034133 872 aclDestroyDenyInfoList(&Config.denyInfoList);
873 aclDestroyAccessList(&Config.accessList.HTTP);
874 aclDestroyAccessList(&Config.accessList.ICP);
875 aclDestroyAccessList(&Config.accessList.MISS);
876 aclDestroyAccessList(&Config.accessList.NeverDirect);
877 aclDestroyAccessList(&Config.accessList.AlwaysDirect);
33cdd606 878 aclDestroyRegexList(Config.cache_stop_relist);
879 Config.cache_stop_relist = NULL;
090089c4 880
12b9e9b1 881 if ((fp = fopen(file_name, "r")) == NULL) {
234967c9 882 sprintf(fatal_str, "Unable to open configuration file: %s: %s",
883 file_name, xstrerror());
090089c4 884 fatal(fatal_str);
885 }
b8de7ebe 886 cfg_filename = file_name;
887 if ((token = strrchr(cfg_filename, '/')))
4cd0ab45 888 cfg_filename = token + 1;
3003c0f3 889 memset(config_input_line, '\0', BUFSIZ);
890 config_lineno = 0;
891 while (fgets(config_input_line, BUFSIZ, fp)) {
892 config_lineno++;
893 if ((token = strchr(config_input_line, '\n')))
540830c4 894 *token = '\0';
3003c0f3 895 if (config_input_line[0] == '#')
540830c4 896 continue;
3003c0f3 897 if (config_input_line[0] == '\0')
090089c4 898 continue;
a3d5953d 899 debug(3, 5) ("Processing: '%s'\n", config_input_line);
3003c0f3 900 strcpy(tmp_line, config_input_line);
92a6f4b1 901 if ((token = strtok(tmp_line, w_space)) == NULL)
090089c4 902 continue;
903
090089c4 904 if (!strcmp(token, "cache_host"))
3003c0f3 905 parseCacheHostLine();
090089c4 906
090089c4 907 else if (!strcmp(token, "cache_host_domain"))
3003c0f3 908 parseHostDomainLine();
30a4f2a8 909 else if (!strcmp(token, "cache_host_acl"))
910 parseHostAclLine();
b012353a 911 else if (!strcmp(token, "neighbor_type_domain"))
912 parseHostDomainTypeLine();
090089c4 913
090089c4 914 else if (!strcmp(token, "neighbor_timeout"))
8813e606 915 parseTimeLine(&Config.neighborTimeout, T_SECOND_STR);
090089c4 916 else if (!strcmp(token, "neighbour_timeout")) /* alternate spelling */
8813e606 917 parseTimeLine(&Config.neighborTimeout, T_SECOND_STR);
090089c4 918
090089c4 919 else if (!strcmp(token, "cache_dir"))
641941c0 920 parseCacheDir();
090089c4 921
090089c4 922 else if (!strcmp(token, "cache_log"))
429fdbec 923 parsePathname(&Config.Log.log, 0);
090089c4 924
090089c4 925 else if (!strcmp(token, "cache_access_log"))
429fdbec 926 parsePathname(&Config.Log.access, 0);
090089c4 927
d8b45066 928 else if (!strcmp(token, "cache_store_log"))
429fdbec 929 parsePathname(&Config.Log.store, 0);
5ad764e2 930
931 else if (!strcmp(token, "cache_swap_log"))
429fdbec 932 parsePathname(&Config.Log.swap, 0);
d8b45066 933
b012353a 934#if USE_USERAGENT_LOG
935 else if (!strcmp(token, "useragent_log"))
429fdbec 936 parsePathname(&Config.Log.useragent, 0);
b012353a 937#endif
938
090089c4 939 else if (!strcmp(token, "logfile_rotate"))
7813c6d5 940 parseIntegerValue(&Config.Log.rotateNumber);
090089c4 941
090089c4 942 else if (!strcmp(token, "httpd_accel_with_proxy"))
c1c29eb6 943 parseOnOff(&Config.Accel.withProxy);
090089c4 944
0dc8ff75 945 else if (!strcmp(token, "httpd_accel_uses_host_header"))
dbea6b4f 946 parseOnOff(&opt_accel_uses_host);
0dc8ff75 947
090089c4 948 else if (!strcmp(token, "httpd_accel"))
3003c0f3 949 parseHttpdAccelLine();
090089c4 950
090089c4 951 else if (!strcmp(token, "cache_effective_user"))
3003c0f3 952 parseEffectiveUserLine();
090089c4 953
090089c4 954 else if (!strcmp(token, "cache_swap_high"))
7813c6d5 955 parseIntegerValue(&Config.Swap.highWaterMark);
090089c4 956
090089c4 957 else if (!strcmp(token, "cache_swap_low"))
7c6c6f75 958 parseIntegerValue(&Config.Swap.lowWaterMark);
090089c4 959
090089c4 960 else if (!strcmp(token, "cache_mem_high"))
7813c6d5 961 parseIntegerValue(&Config.Mem.highWaterMark);
090089c4 962
090089c4 963 else if (!strcmp(token, "cache_mem_low"))
7813c6d5 964 parseIntegerValue(&Config.Mem.lowWaterMark);
090089c4 965
090089c4 966 else if (!strcmp(token, "cache_mem"))
3003c0f3 967 parseMemLine();
090089c4 968
090089c4 969 else if (!strcmp(token, "cache_mgr"))
3003c0f3 970 parseMgrLine();
090089c4 971
8213067d 972 else if (!strcmp(token, "acl"))
3003c0f3 973 aclParseAclLine();
8213067d 974
ea1b5bd8 975 else if (!strcmp(token, "deny_info"))
85034133 976 aclParseDenyInfoLine(&Config.denyInfoList);
ea1b5bd8 977
92a6f4b1 978 else if (!strcmp(token, "http_access"))
85034133 979 aclParseAccessLine(&Config.accessList.HTTP);
92a6f4b1 980 else if (!strcmp(token, "icp_access"))
85034133 981 aclParseAccessLine(&Config.accessList.ICP);
982 else if (!strcmp(token, "miss_access"))
983 aclParseAccessLine(&Config.accessList.MISS);
984 else if (!strcmp(token, "never_direct"))
985 aclParseAccessLine(&Config.accessList.NeverDirect);
986 else if (!strcmp(token, "always_direct"))
987 aclParseAccessLine(&Config.accessList.AlwaysDirect);
8213067d 988
30a4f2a8 989 else if (!strcmp(token, "hierarchy_stoplist"))
b15fe823 990 parseWordlist(&Config.hierarchy_stoplist);
991
992 else if (!strcmp(token, "cache_stoplist"))
993 parseWordlist(&Config.cache_stoplist);
33cdd606 994 else if (!strcmp(token, "cache_stoplist_pattern"))
52cd89fd 995 aclParseRegexList(&Config.cache_stop_relist, 0);
33cdd606 996 else if (!strcmp(token, "cache_stoplist_pattern/i"))
52cd89fd 997 aclParseRegexList(&Config.cache_stop_relist, 1);
30a4f2a8 998
a7e59001 999 else if (!strcmp(token, "refresh_pattern"))
1000 parseRefreshPattern(0);
1001 else if (!strcmp(token, "refresh_pattern/i"))
1002 parseRefreshPattern(1);
2546fcb3 1003
1004 else if (!strcmp(token, "quick_abort"))
1005 parseQuickAbort();
1006
090089c4 1007 else if (!strcmp(token, "negative_ttl"))
06d12d57 1008 parseTimeLine(&Config.negativeTtl, T_SECOND_STR);
61d6fc5c 1009 else if (!strcmp(token, "negative_dns_ttl"))
06d12d57 1010 parseTimeLine(&Config.negativeDnsTtl, T_SECOND_STR);
2639dac6 1011 else if (!strcmp(token, "positive_dns_ttl"))
06d12d57 1012 parseTimeLine(&Config.positiveDnsTtl, T_SECOND_STR);
4f92c80c 1013 else if (!strcmp(token, "read_timeout"))
06d12d57 1014 parseTimeLine(&Config.Timeout.read, T_SECOND_STR);
4f92c80c 1015 else if (!strcmp(token, "connect_timeout"))
8813e606 1016 parseTimeLine(&Config.Timeout.connect, T_SECOND_STR);
4f92c80c 1017 else if (!strcmp(token, "defer_timeout"))
06d12d57 1018 parseTimeLine(&Config.Timeout.defer, T_SECOND_STR);
812ed90c 1019 else if (!strcmp(token, "request_timeout"))
1020 parseTimeLine(&Config.Timeout.request, T_SECOND_STR);
4f92c80c 1021 else if (!strcmp(token, "client_lifetime"))
06d12d57 1022 parseTimeLine(&Config.Timeout.lifetime, T_SECOND_STR);
4f92c80c 1023 else if (!strcmp(token, "shutdown_lifetime"))
8813e606 1024 parseTimeLine(&Config.shutdownLifetime, T_SECOND_STR);
090089c4 1025 else if (!strcmp(token, "clean_rate"))
06d12d57 1026 parseTimeLine(&Config.cleanRate, T_SECOND_STR);
66cedb85 1027 else if (!strcmp(token, "reference_age"))
8813e606 1028 parseTimeLine(&Config.referenceAge, T_MINUTE_STR);
090089c4 1029
fa966b74 1030 else if (!strcmp(token, "request_size"))
38792624 1031 parseKilobytes(&Config.maxRequestSize);
fa966b74 1032
090089c4 1033 else if (!strcmp(token, "cache_dns_program"))
429fdbec 1034 parsePathname(&Config.Program.dnsserver, 1);
090089c4 1035
090089c4 1036 else if (!strcmp(token, "dns_children"))
7813c6d5 1037 parseIntegerValue(&Config.dnsChildren);
a0bb9c7a 1038 else if (!strcmp(token, "dns_defnames"))
1039 parseOnOff(&Config.Options.res_defnames);
090089c4 1040
d2af9477 1041 else if (!strcmp(token, "redirect_program"))
429fdbec 1042 parsePathname(&Config.Program.redirect, 1);
98ffb7e4 1043
d2af9477 1044 else if (!strcmp(token, "redirect_children"))
7813c6d5 1045 parseIntegerValue(&Config.redirectChildren);
d2af9477 1046
429fdbec 1047 else if (!strcmp(token, "pinger_program"))
1048 parsePathname(&Config.Program.pinger, 1);
1049
1050 else if (!strcmp(token, "unlinkd_program"))
1051 parsePathname(&Config.Program.unlinkd, 1);
1052
e81957b7 1053#if USE_PROXY_AUTH
d6b73110 1054 else if (!strcmp(token, "proxy_auth"))
fea2e6e0 1055 parseProxyAuthLine();
e924600d 1056 else if (!strcmp(token, "proxy_auth_ignore"))
1057 aclParseRegexList(&Config.proxyAuth.IgnoreDomains, 1);
e81957b7 1058#endif /* USE_PROXY_AUTH */
1059
090089c4 1060 else if (!strcmp(token, "source_ping"))
c1c29eb6 1061 parseOnOff(&Config.sourcePing);
090089c4 1062
090089c4 1063 else if (!strcmp(token, "emulate_httpd_log"))
c1c29eb6 1064 parseOnOff(&Config.commonLogFormat);
1065
e43efe50 1066 else if (!strcmp(token, "log_mime_hdrs"))
1067 parseOnOff(&Config.logMimeHdrs);
85034133 1068
7813c6d5 1069 else if (!strcmp(token, "ident_lookup"))
c1c29eb6 1070 parseOnOff(&Config.identLookup);
090089c4 1071
1072 else if (!strcmp(token, "append_domain"))
3003c0f3 1073 parseAppendDomainLine();
090089c4 1074
090089c4 1075 else if (!strcmp(token, "wais_relay"))
3003c0f3 1076 parseWAISRelayLine();
090089c4 1077
e90100aa 1078 else if (!strcmp(token, "mcast_groups"))
1079 parseMcastGroupLine();
1080
30a4f2a8 1081 else if (!strcmp(token, "tcp_incoming_address"))
1082 parseAddressLine(&Config.Addrs.tcp_incoming);
1083
1084 else if (!strcmp(token, "tcp_outgoing_address"))
1085 parseAddressLine(&Config.Addrs.tcp_outgoing);
1086
1087 else if (!strcmp(token, "udp_incoming_address"))
1088 parseAddressLine(&Config.Addrs.udp_incoming);
1089
1090 else if (!strcmp(token, "udp_outgoing_address"))
1091 parseAddressLine(&Config.Addrs.udp_outgoing);
1092
844327e4 1093 else if (!strcmp(token, "client_netmask"))
1094 parseAddressLine(&Config.Addrs.client_netmask);
1095
7813c6d5 1096 else if (!strcmp(token, "tcp_recv_bufsize"))
1097 parseIntegerValue(&Config.tcpRcvBufsz);
1098
2c82dc1a 1099 else if (!strcmp(token, "log_fqdn"))
1100 parseOnOff(&Config.Log.log_fqdn);
1101
090089c4 1102 else if (!strcmp(token, "bind_address"))
30a4f2a8 1103 parseAddressLine(&Config.Addrs.tcp_incoming);
1104
1105 else if (!strcmp(token, "outbound_address"))
1106 parseAddressLine(&Config.Addrs.tcp_outgoing);
090089c4 1107
30a4f2a8 1108 else if (!strcmp(token, "http_port") || !strcmp(token, "ascii_port"))
1109 parseHttpPortLine();
090089c4 1110
30a4f2a8 1111 else if (!strcmp(token, "icp_port") || !strcmp(token, "udp_port"))
1112 parseIcpPortLine();
090089c4 1113
605ba5ca 1114 else if (!strcmp(token, "dns_testnames"))
b15fe823 1115 parseWordlist(&Config.dns_testname_list);
605ba5ca 1116
090089c4 1117 else if (!strcmp(token, "single_parent_bypass"))
c1c29eb6 1118 parseOnOff(&Config.singleParentBypass);
090089c4 1119
12b9e9b1 1120 else if (!strcmp(token, "debug_options"))
3003c0f3 1121 parseDebugOptionsLine();
12b9e9b1 1122
ccff9601 1123 else if (!strcmp(token, "pid_filename"))
429fdbec 1124 parsePathname(&Config.pidFilename, 0);
c0f3ef9c 1125 else if (!strcmp(token, "mime_table"))
1126 parsePathname(&Config.mimeTablePathname, 1);
cf5fd929 1127 else if (!strcmp(token, "visible_hostname"))
3003c0f3 1128 parseVisibleHostnameLine();
cf5fd929 1129
fb263c4c 1130 else if (!strcmp(token, "ftp_user"))
e34e0322 1131 parseString(&Config.Ftp.anon_user);
fb263c4c 1132
7d49daab 1133 else if (!strcmp(token, "cache_announce"))
3003c0f3 1134 parseCacheAnnounceLine();
7d49daab 1135
1136 else if (!strcmp(token, "announce_to"))
3003c0f3 1137 parseAnnounceToLine();
7d49daab 1138
98ffb7e4 1139 else if (!strcmp(token, "ssl_proxy"))
e6e3b09b 1140 parseProxyLine(&Config.sslProxy);
1141 else if (!strcmp(token, "passthrough_proxy"))
1142 parseProxyLine(&Config.passProxy);
98ffb7e4 1143
6e40f263 1144 else if (!strcmp(token, "err_html_text"))
1145 parseErrHtmlLine();
1146
b15e6857 1147 else if (!strcmp(token, "ipcache_size"))
1148 parseIntegerValue(&Config.ipcache.size);
1149 else if (!strcmp(token, "ipcache_low"))
1150 parseIntegerValue(&Config.ipcache.low);
1151 else if (!strcmp(token, "ipcache_high"))
1152 parseIntegerValue(&Config.ipcache.high);
1153
caebbe00 1154 else if (!strcmp(token, "memory_pools"))
1155 parseOnOff(&opt_mem_pools);
1156 else if (!strcmp(token, "udp_hit_obj"))
1157 parseOnOff(&opt_udp_hit_obj);
9e205701 1158 else if (!strcmp(token, "udp_hit_obj_size"))
1159 parseIntegerValue(&Config.udpMaxHitObjsz);
caebbe00 1160 else if (!strcmp(token, "forwarded_for"))
1161 parseOnOff(&opt_forwarded_for);
ab3ce7fb 1162 else if (!strcmp(token, "log_icp_queries"))
1163 parseOnOff(&Config.Options.log_udp);
fa562c67 1164 else if (!strcmp(token, "http_anonymizer"))
1165 parseHttpAnonymizer(&Config.Options.anonymizer);
429fdbec 1166 else if (!strcmp(token, "client_db"))
1167 parseOnOff(&Config.Options.client_db);
1168 else if (!strcmp(token, "query_icmp"))
1169 parseOnOff(&Config.Options.query_icmp);
caebbe00 1170
4d311579 1171 else if (!strcmp(token, "minimum_direct_hops"))
1172 parseIntegerValue(&Config.minDirectHops);
1173
3c5557f9 1174 else if (!strcmp(token, "cachemgr_passwd"))
1175 parseCachemgrPasswd();
1176
a7e59001 1177 else if (!strcmp(token, "store_objects_per_bucket"))
38792624 1178 parseIntegerValue(&Config.Store.objectsPerBucket);
a7e59001 1179 else if (!strcmp(token, "store_avg_object_size"))
38792624 1180 parseIntegerValue(&Config.Store.avgObjectSize);
1181 else if (!strcmp(token, "maximum_object_size"))
1182 parseKilobytes(&Config.Store.maxObjectSize);
a7e59001 1183
752c3b27 1184 else if (!strcmp(token, "viz_hack_addr"))
1185 parseVizHackLine();
1186
d0f4739d 1187 else if (!strcmp(token, "netdb_high"))
1188 parseIntegerValue(&Config.Netdb.high);
1189 else if (!strcmp(token, "netdb_low"))
1190 parseIntegerValue(&Config.Netdb.low);
429fdbec 1191 else if (!strcmp(token, "netdb_ping_period"))
8813e606 1192 parseTimeLine(&Config.Netdb.period, T_SECOND_STR);
d0f4739d 1193
caebbe00 1194 /* If unknown, treat as a comment line */
090089c4 1195 else {
a3d5953d 1196 debug(3, 0) ("parseConfigFile: line %d unrecognized: '%s'\n",
92a6f4b1 1197 config_lineno,
1198 config_input_line);
090089c4 1199 }
1200 }
1201
090089c4 1202 /* Sanity checks */
b6f794d6 1203 if (Config.Swap.maxSize < (Config.Mem.maxSize >> 10)) {
1204 printf("WARNING: cache_swap (%d kbytes) is less than cache_mem (%d bytes).\n", Config.Swap.maxSize, Config.Mem.maxSize);
090089c4 1205 printf(" This will cause serious problems with your cache!!!\n");
b8de7ebe 1206 printf(" Change your configuration file.\n");
090089c4 1207 fflush(stdout); /* print message */
1208 }
a4ebeb3b 1209 if (Config.cleanRate < 1)
28b2f45f 1210 Config.cleanRate = 86400 * 365; /* one year */
0670a3cb 1211 if (Config.Announce.rate < 1) {
a4ebeb3b 1212 Config.Announce.rate = 86400 * 365; /* one year */
0670a3cb 1213 Config.Announce.on = 0;
1214 }
c021888f 1215 if (Config.dnsChildren < 0)
1216 Config.dnsChildren = 0;
b6f794d6 1217 if (Config.dnsChildren < 1) {
c021888f 1218 printf("WARNING: dnsservers are disabled!\n");
1219 printf("WARNING: Cache performance may be very poor\n");
b6f794d6 1220 } else if (Config.dnsChildren > DefaultDnsChildrenMax) {
090089c4 1221 printf("WARNING: dns_children was set to a bad value: %d\n",
b6f794d6 1222 Config.dnsChildren);
090089c4 1223 printf("Setting it to the maximum (%d).\n", DefaultDnsChildrenMax);
1224 Config.dnsChildren = DefaultDnsChildrenMax;
1225 }
dd7ad0a4 1226 if (Config.Program.redirect) {
f6c78bd2 1227 if (Config.redirectChildren < 1) {
c021888f 1228 Config.redirectChildren = 0;
dd7ad0a4 1229 safe_free(Config.Program.redirect);
f6c78bd2 1230 } else if (Config.redirectChildren > DefaultRedirectChildrenMax) {
c021888f 1231 printf("WARNING: redirect_children was set to a bad value: %d\n",
f6c78bd2 1232 Config.redirectChildren);
c021888f 1233 printf("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax);
1234 Config.redirectChildren = DefaultRedirectChildrenMax;
f6c78bd2 1235 }
d2af9477 1236 }
090089c4 1237 fclose(fp);
090089c4 1238 configDoConfigure();
1239 return 0;
1240}
1241
8203a132 1242static char *
0ee4272b 1243safe_xstrdup(const char *p)
090089c4 1244{
0ee4272b 1245 return p ? xstrdup(p) : NULL;
090089c4 1246}
1247
0a21bd84 1248void
0673c0ba 1249configFreeMemory(void)
0ffd22bc 1250{
1251 safe_free(Config.Wais.relayHost);
1252 safe_free(Config.Log.log);
1253 safe_free(Config.Log.access);
983061ed 1254 safe_free(Config.Log.store);
5ad764e2 1255 safe_free(Config.Log.swap);
0ffd22bc 1256 safe_free(Config.adminEmail);
1257 safe_free(Config.effectiveUser);
1258 safe_free(Config.effectiveGroup);
0ffd22bc 1259 safe_free(Config.Program.dnsserver);
d2af9477 1260 safe_free(Config.Program.redirect);
429fdbec 1261 safe_free(Config.Program.unlinkd);
dd573602 1262 safe_free(Config.Program.pinger);
0ffd22bc 1263 safe_free(Config.Accel.host);
1264 safe_free(Config.Accel.prefix);
1265 safe_free(Config.appendDomain);
1266 safe_free(Config.debugOptions);
1267 safe_free(Config.pidFilename);
812ed90c 1268 safe_free(Config.mimeTablePathname);
0ffd22bc 1269 safe_free(Config.visibleHostname);
e81957b7 1270#if USE_PROXY_AUTH
e924600d 1271 safe_free(Config.proxyAuth.File);
1272 aclDestroyRegexList(Config.proxyAuth.IgnoreDomains);
1273 Config.proxyAuth.IgnoreDomains = NULL;
e81957b7 1274#endif /* USE_PROXY_AUTH */
0ffd22bc 1275 safe_free(Config.Announce.host);
1276 safe_free(Config.Announce.file);
6e40f263 1277 safe_free(Config.errHtmlText);
e34e0322 1278 safe_free(Config.Ftp.icon_prefix);
1279 safe_free(Config.Ftp.icon_suffix);
1280 safe_free(Config.Ftp.anon_user);
deb79f06 1281 peerDestroy(Config.sslProxy);
1282 peerDestroy(Config.passProxy);
30a4f2a8 1283 wordlistDestroy(&Config.hierarchy_stoplist);
e90100aa 1284 wordlistDestroy(&Config.mcast_group_list);
605ba5ca 1285 wordlistDestroy(&Config.dns_testname_list);
ee4a1f5d 1286 wordlistDestroy(&Config.cache_stoplist);
3c5557f9 1287 objcachePasswdDestroy(&Config.passwd_list);
a7e59001 1288 refreshFreeMemory();
0ffd22bc 1289}
1290
090089c4 1291
8203a132 1292static void
0673c0ba 1293configSetFactoryDefaults(void)
090089c4 1294{
e924600d 1295 memset(&Config, '\0', sizeof(Config));
090089c4 1296 Config.Mem.maxSize = DefaultMemMaxSize;
7813c6d5 1297 Config.Mem.highWaterMark = DefaultMemHighWaterMark;
1298 Config.Mem.lowWaterMark = DefaultMemLowWaterMark;
090089c4 1299 Config.Swap.maxSize = DefaultSwapMaxSize;
7813c6d5 1300 Config.Swap.highWaterMark = DefaultSwapHighWaterMark;
090089c4 1301 Config.Swap.lowWaterMark = DefaultSwapLowWaterMark;
d0f4739d 1302 Config.Netdb.high = DefaultNetdbHigh;
1303 Config.Netdb.low = DefaultNetdbLow;
429fdbec 1304 Config.Netdb.period = DefaultNetdbPeriod;
090089c4 1305
090089c4 1306 Config.Wais.relayHost = safe_xstrdup(DefaultWaisRelayHost);
1307 Config.Wais.relayPort = DefaultWaisRelayPort;
090089c4 1308
66cedb85 1309 Config.referenceAge = DefaultReferenceAge;
090089c4 1310 Config.negativeTtl = DefaultNegativeTtl;
2639dac6 1311 Config.negativeDnsTtl = DefaultNegativeDnsTtl;
1312 Config.positiveDnsTtl = DefaultPositiveDnsTtl;
5c5783a2 1313 Config.Timeout.read = DefaultReadTimeout;
1314 Config.Timeout.connect = DefaultConnectTimeout;
1315 Config.Timeout.defer = DefaultDeferTimeout;
812ed90c 1316 Config.Timeout.request = DefaultRequestTimeout;
5c5783a2 1317 Config.Timeout.lifetime = DefaultClientLifetime;
1318 Config.shutdownLifetime = DefaultShutdownLifetime;
fa966b74 1319 Config.maxRequestSize = DefaultMaxRequestSize;
090089c4 1320 Config.cleanRate = DefaultCleanRate;
1321 Config.dnsChildren = DefaultDnsChildren;
d2af9477 1322 Config.redirectChildren = DefaultRedirectChildren;
090089c4 1323 Config.sourcePing = DefaultSourcePing;
2546fcb3 1324 Config.quickAbort.min = DefaultQuickAbortMin;
1325 Config.quickAbort.pct = DefaultQuickAbortPct;
1326 Config.quickAbort.max = DefaultQuickAbortMax;
090089c4 1327 Config.commonLogFormat = DefaultCommonLogFormat;
e43efe50 1328 Config.logMimeHdrs = DefaultLogMimeHdrs;
e924600d 1329 Config.identLookup = DefaultIdentLookup;
12b9e9b1 1330 Config.debugOptions = safe_xstrdup(DefaultDebugOptions);
090089c4 1331 Config.neighborTimeout = DefaultNeighborTimeout;
e5c22962 1332 Config.stallDelay = DefaultStallDelay;
090089c4 1333 Config.singleParentBypass = DefaultSingleParentBypass;
1334 Config.adminEmail = safe_xstrdup(DefaultAdminEmail);
1335 Config.effectiveUser = safe_xstrdup(DefaultEffectiveUser);
1336 Config.effectiveGroup = safe_xstrdup(DefaultEffectiveGroup);
1337 Config.appendDomain = safe_xstrdup(DefaultAppendDomain);
6e40f263 1338 Config.errHtmlText = safe_xstrdup(DefaultErrHtmlText);
812ed90c 1339 Config.Port.n_http = 0;
30a4f2a8 1340 Config.Port.icp = DefaultIcpPortNum;
e924600d 1341 Config.Log.log_fqdn = DefaultLogLogFqdn;
090089c4 1342 Config.Log.log = safe_xstrdup(DefaultCacheLogFile);
1343 Config.Log.access = safe_xstrdup(DefaultAccessLogFile);
d8b45066 1344 Config.Log.store = safe_xstrdup(DefaultStoreLogFile);
5ad764e2 1345 Config.Log.swap = safe_xstrdup(DefaultSwapLogFile);
b012353a 1346#if USE_USERAGENT_LOG
1347 Config.Log.useragent = safe_xstrdup(DefaultUseragentLogFile);
1348#endif
090089c4 1349 Config.Log.rotateNumber = DefaultLogRotateNumber;
090089c4 1350 Config.Program.dnsserver = safe_xstrdup(DefaultDnsserverProgram);
d2af9477 1351 Config.Program.redirect = safe_xstrdup(DefaultRedirectProgram);
365a4bce 1352 Config.Program.pinger = safe_xstrdup(DefaultPingerProgram);
429fdbec 1353 Config.Program.unlinkd = safe_xstrdup(DefaultUnlinkdProgram);
090089c4 1354 Config.Accel.host = safe_xstrdup(DefaultAccelHost);
1355 Config.Accel.prefix = safe_xstrdup(DefaultAccelPrefix);
1356 Config.Accel.port = DefaultAccelPort;
1357 Config.Accel.withProxy = DefaultAccelWithProxy;
ccff9601 1358 Config.pidFilename = safe_xstrdup(DefaultPidFilename);
812ed90c 1359 Config.mimeTablePathname = safe_xstrdup(DefaultMimeTable);
cf5fd929 1360 Config.visibleHostname = safe_xstrdup(DefaultVisibleHostname);
e81957b7 1361#if USE_PROXY_AUTH
e924600d 1362 Config.proxyAuth.File = safe_xstrdup(DefaultProxyAuthFile);
1363/* Config.proxyAuth.IgnoreDomains = safe_xstrdup(DefaultproxyAuthIgnoreDomains); */
e81957b7 1364#endif /* USE_PROXY_AUTH */
7d49daab 1365 Config.Announce.host = safe_xstrdup(DefaultAnnounceHost);
1366 Config.Announce.port = DefaultAnnouncePort;
1367 Config.Announce.file = safe_xstrdup(DefaultAnnounceFile);
1368 Config.Announce.rate = DefaultAnnounceRate;
1d73e33a 1369 Config.Announce.on = 0;
7813c6d5 1370 Config.tcpRcvBufsz = DefaultTcpRcvBufsz;
dfc52ac5 1371 Config.udpMaxHitObjsz = DefaultUdpMaxHitObjsz;
30a4f2a8 1372 Config.Addrs.tcp_outgoing.s_addr = DefaultTcpOutgoingAddr;
1373 Config.Addrs.tcp_incoming.s_addr = DefaultTcpIncomingAddr;
1374 Config.Addrs.udp_outgoing.s_addr = DefaultUdpOutgoingAddr;
1375 Config.Addrs.udp_incoming.s_addr = DefaultUdpIncomingAddr;
844327e4 1376 Config.Addrs.client_netmask.s_addr = DefaultClientNetmask;
e924600d 1377 Config.passProxy = DefaultPassProxy;
1378 Config.sslProxy = DefaultSslProxy;
b15e6857 1379 Config.ipcache.size = DefaultIpcacheSize;
1380 Config.ipcache.low = DefaultIpcacheLow;
1381 Config.ipcache.high = DefaultIpcacheHigh;
4d311579 1382 Config.minDirectHops = DefaultMinDirectHops;
38792624 1383 Config.Store.maxObjectSize = DefaultMaxObjectSize;
1384 Config.Store.avgObjectSize = DefaultAvgObjectSize;
1385 Config.Store.objectsPerBucket = DefaultObjectsPerBucket;
ee4a1f5d 1386 Config.Options.log_udp = DefaultOptionsLogUdp;
e924600d 1387 Config.Options.res_defnames = DefaultOptionsResDefnames;
1388 Config.Options.anonymizer = DefaultOptionsAnonymizer;
1389 Config.Options.enable_purge = DefaultOptionsEnablePurge;
429fdbec 1390 Config.Options.client_db = DefaultOptionsClientDb;
1391 Config.Options.query_icmp = DefaultOptionsQueryIcmp;
3fdadc70 1392 Config.Ftp.icon_prefix = safe_xstrdup(DefaultFtpIconPrefix);
1393 Config.Ftp.icon_suffix = safe_xstrdup(DefaultFtpIconSuffix);
1394 Config.Ftp.list_width = DefaultFtpListWidth;
1395 Config.Ftp.list_wrap = DefaultFtpListWrap;
f88211e8 1396 Config.Ftp.anon_user = safe_xstrdup(DefaultFtpAnonUser);
090089c4 1397}
1398
8203a132 1399static void
0673c0ba 1400configDoConfigure(void)
090089c4 1401{
1402 httpd_accel_mode = Config.Accel.prefix ? 1 : 0;
eb2d04cd 1403 if (Config.errHtmlText == NULL)
0a21bd84 1404 Config.errHtmlText = xstrdup(null_string);
b1c0cc67 1405 storeConfigure();
ca2b438f 1406 if (httpd_accel_mode && !strcmp(Config.Accel.host, "virtual"))
1407 vhost_mode = 1;
a08307eb 1408 sprintf(ThisCache, "%s:%d (Squid/%s)",
1409 getMyHostname(),
812ed90c 1410 (int) Config.Port.http[0],
8e81a68a 1411 SQUID_VERSION);
dfc52ac5 1412 if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF)
9e205701 1413 Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF;
ba0fd1b6 1414 if (Config.appendDomain)
1415 Config.appendDomainLen = strlen(Config.appendDomain);
1416 else
1417 Config.appendDomainLen = 0;
0e92bb84 1418 if (Config.Port.n_http == 0)
6c841d34 1419 Config.Port.http[Config.Port.n_http++] = DefaultHttpPortNum;
090089c4 1420}
429fdbec 1421
1422/* Parse a time specification from the config file. Store the
1423 * result in 'iptr', after converting it to 'units' */
1424static void
1425parseTimeLine(int *iptr, const char *units)
1426{
1427 char *token;
1428 double d;
1429 int m;
1430 int u;
1431 if ((u = parseTimeUnits(units)) == 0)
1432 self_destruct();
1433 if ((token = strtok(NULL, w_space)) == NULL)
1434 self_destruct();
1435 d = atof(token);
1436 m = u; /* default to 'units' if none specified */
1437 if ((token = strtok(NULL, w_space)) != NULL) {
1438 if ((m = parseTimeUnits(token)) == 0)
1439 self_destruct();
1440 }
1441 *iptr = m * d / u;
1442}
1443
1444static int
1445parseTimeUnits(const char *unit)
1446{
8813e606 1447 if (!strncasecmp(unit, T_SECOND_STR, strlen(T_SECOND_STR)))
429fdbec 1448 return 1;
8813e606 1449 if (!strncasecmp(unit, T_MINUTE_STR, strlen(T_MINUTE_STR)))
429fdbec 1450 return 60;
8813e606 1451 if (!strncasecmp(unit, T_HOUR_STR, strlen(T_HOUR_STR)))
429fdbec 1452 return 3600;
8813e606 1453 if (!strncasecmp(unit, T_DAY_STR, strlen(T_DAY_STR)))
429fdbec 1454 return 86400;
8813e606 1455 if (!strncasecmp(unit, T_WEEK_STR, strlen(T_WEEK_STR)))
429fdbec 1456 return 86400 * 7;
8813e606 1457 if (!strncasecmp(unit, T_FORTNIGHT_STR, strlen(T_FORTNIGHT_STR)))
429fdbec 1458 return 86400 * 14;
8813e606 1459 if (!strncasecmp(unit, T_MONTH_STR, strlen(T_MONTH_STR)))
429fdbec 1460 return 86400 * 30;
8813e606 1461 if (!strncasecmp(unit, T_YEAR_STR, strlen(T_YEAR_STR)))
429fdbec 1462 return 86400 * 365.2522;
8813e606 1463 if (!strncasecmp(unit, T_DECADE_STR, strlen(T_DECADE_STR)))
429fdbec 1464 return 86400 * 365.2522 * 10;
a3d5953d 1465 debug(3, 1) ("parseTimeUnits: unknown time unit '%s'\n", unit);
429fdbec 1466 return 0;
1467}