]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cache_cf.cc
make storeCopy() static
[thirdparty/squid.git] / src / cache_cf.cc
CommitLineData
30a4f2a8 1/*
2ba42578 2 * $Id: cache_cf.cc,v 1.86 1996/09/13 20:50:48 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
110#define DefaultMemMaxSize (16 << 20) /* 16 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
30a4f2a8 117#define DefaultFtpDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
090089c4 118#define DefaultFtpMaxObjSize (4 << 20) /* 4 MB */
30a4f2a8 119#define DefaultGopherDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
090089c4 120#define DefaultGopherMaxObjSize (4 << 20) /* 4 MB */
30a4f2a8 121#define DefaultHttpDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
090089c4 122#define DefaultHttpMaxObjSize (4 << 20) /* 4 MB */
30a4f2a8 123#define DefaultWaisDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
090089c4 124#define DefaultWaisMaxObjSize (4 << 20) /* 4 MB */
125#define DefaultWaisRelayHost (char *)NULL
30a4f2a8 126#define DefaultWaisRelayPort 0
090089c4 127
79b5cc5f 128#define DefaultExpireAge (86400 * 7) /* 1 week */
090089c4 129#define DefaultNegativeTtl (5 * 60) /* 5 min */
61d6fc5c 130#define DefaultNegativeDnsTtl (2 * 60) /* 2 min */
2639dac6 131#define DefaultPositiveDnsTtl (360 * 60) /* 6 hours */
090089c4 132#define DefaultReadTimeout (15 * 60) /* 15 min */
133#define DefaultLifetimeDefault (200 * 60) /* 3+ hours */
234967c9 134#define DefaultLifetimeShutdown 30 /* 30 seconds */
090089c4 135#define DefaultConnectTimeout (2 * 60) /* 2 min */
136#define DefaultDefaultAgeMax (3600 * 24 * 30) /* 30 days */
137#define DefaultCleanRate -1 /* disabled */
d2af9477 138#define DefaultDnsChildren 5 /* 5 processes */
139#define DefaultRedirectChildren 5 /* 5 processes */
234967c9 140#define DefaultMaxRequestSize (100 << 10) /* 100Kb */
090089c4 141#define DefaultHotVmFactor 0.0 /* disabled */
142
30a4f2a8 143#define DefaultHttpPortNum CACHE_HTTP_PORT
144#define DefaultIcpPortNum CACHE_ICP_PORT
090089c4 145
a26bdc75 146#define DefaultCacheLogFile DEFAULT_CACHE_LOG
147#define DefaultAccessLogFile DEFAULT_ACCESS_LOG
d8b45066 148#define DefaultStoreLogFile DEFAULT_STORE_LOG
e81957b7 149#if USE_PROXY_AUTH
150#define DefaultProxyAuthFile (char *)NULL /* default NONE */
d6b73110 151#define DefaultProxyAuthIgnoreDomain (char *)NULL /* default NONE */
e81957b7 152#endif /* USE_PROXY_AUTH */
090089c4 153#define DefaultLogRotateNumber 10
154#define DefaultAdminEmail "webmaster"
a26bdc75 155#define DefaultFtpgetProgram DEFAULT_FTPGET
090089c4 156#define DefaultFtpgetOptions ""
a26bdc75 157#define DefaultDnsserverProgram DEFAULT_DNSSERVER
d2af9477 158#define DefaultRedirectProgram (char *)NULL /* default NONE */
090089c4 159#define DefaultEffectiveUser (char *)NULL /* default NONE */
160#define DefaultEffectiveGroup (char *)NULL /* default NONE */
161#define DefaultAppendDomain (char *)NULL /* default NONE */
6e40f263 162#define DefaultErrHtmlText (char *)NULL /* default NONE */
090089c4 163
ccff9601 164#define DefaultDebugOptions "ALL,1" /* All sections at level 1 */
090089c4 165#define DefaultAccelHost (char *)NULL /* default NONE */
166#define DefaultAccelPrefix (char *)NULL /* default NONE */
167#define DefaultAccelPort 0 /* default off */
168#define DefaultAccelWithProxy 0 /* default off */
169#define DefaultSourcePing 0 /* default off */
1ef4c6c1 170#define DefaultCommonLogFormat 0 /* default off */
2ba42578 171#if LOG_FULL_HEADERS
e43efe50 172#define DefaultLogMimeHdrs 0 /* default off */
173#endif /* LOG_FULL_HEADERS */
c1c29eb6 174#define DefaultIdentLookup 0 /* default off */
2546fcb3 175#define DefaultQuickAbortMin -1 /* default off */
176#define DefaultQuickAbortPct 0 /* default off */
177#define DefaultQuickAbortMax 0 /* default off */
090089c4 178#define DefaultNeighborTimeout 2 /* 2 seconds */
234967c9 179#define DefaultStallDelay 1 /* 1 seconds */
090089c4 180#define DefaultSingleParentBypass 0 /* default off */
77ffc99f 181#define DefaultPidFilename (char *)NULL /* default NONE */
cf5fd929 182#define DefaultVisibleHostname (char *)NULL /* default NONE */
b8de7ebe 183#define DefaultFtpUser "squid@" /* Default without domain */
7d49daab 184#define DefaultAnnounceHost "sd.cache.nlanr.net"
185#define DefaultAnnouncePort 3131
7ba794f4 186#define DefaultAnnounceFile (char *)NULL /* default NONE */
30a4f2a8 187#define DefaultAnnounceRate 0 /* Default off */
7813c6d5 188#define DefaultTcpRcvBufsz 0 /* use system default */
30a4f2a8 189#define DefaultTcpIncomingAddr INADDR_ANY
190#define DefaultTcpOutgoingAddr INADDR_NONE
191#define DefaultUdpIncomingAddr INADDR_ANY
192#define DefaultUdpOutgoingAddr INADDR_NONE
b15e6857 193#define DefaultClientNetmask 0xFFFFFFFF
98ffb7e4 194#define DefaultSslProxyPort 0
195#define DefaultSslProxyHost (char *)NULL
b15e6857 196#define DefaultIpcacheSize 1024
197#define DefaultIpcacheLow 90
198#define DefaultIpcacheHigh 95
ccff9601 199
090089c4 200int httpd_accel_mode = 0; /* for fast access */
f133a434 201char *DefaultSwapDir = DEFAULT_SWAP_DIR;
00fac1f8 202char *DefaultConfigFile = DEFAULT_CONFIG_FILE;
cbbad1ed 203char *ConfigFile = NULL; /* the whole thing */
fe1c7f28 204char *cfg_filename = NULL; /* just the last part */
30a4f2a8 205char ForwardedBy[256];
090089c4 206
12b9e9b1 207char w_space[] = " \t\n";
3003c0f3 208char config_input_line[BUFSIZ];
209int config_lineno = 0;
090089c4 210
30a4f2a8 211static char *safe_xstrdup _PARAMS((char *p));
c1c29eb6 212static void parseOnOff _PARAMS((int *));
7813c6d5 213static void parseIntegerValue _PARAMS((int *));
cf5fd929 214static char fatal_str[BUFSIZ];
1c481e00 215static void configDoConfigure _PARAMS((void));
216static void configFreeMemory _PARAMS((void));
217static void configSetFactoryDefaults _PARAMS((void));
218static void parseAccessLogLine _PARAMS((void));
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));
1c481e00 224static void parseDebugOptionsLine _PARAMS((void));
225static void parseDirLine _PARAMS((void));
226static void parseDnsProgramLine _PARAMS((void));
227static void parseDnsTestnameLine _PARAMS((void));
228static void parseEffectiveUserLine _PARAMS((void));
229static void parseErrHtmlLine _PARAMS((void));
230static void parseFtpLine _PARAMS((void));
231static void parseFtpOptionsLine _PARAMS((void));
232static void parseFtpProgramLine _PARAMS((void));
233static void parseFtpUserLine _PARAMS((void));
234static void parseGopherLine _PARAMS((void));
235static void parseHierarchyStoplistLine _PARAMS((void));
236static void parseHostAclLine _PARAMS((void));
237static void parseHostDomainLine _PARAMS((void));
238static void parseHotVmFactorLine _PARAMS((void));
239static void parseHttpLine _PARAMS((void));
240static void parseHttpPortLine _PARAMS((void));
241static void parseHttpdAccelLine _PARAMS((void));
242static void parseIPLine _PARAMS((ip_acl ** list));
243static void parseIcpPortLine _PARAMS((void));
244static void parseInsideFirewallLine _PARAMS((void));
1c481e00 245static void parseLocalDomainFile _PARAMS((char *fname));
246static void parseLocalDomainLine _PARAMS((void));
247static void parseLogLine _PARAMS((void));
248static void parseMemLine _PARAMS((void));
249static void parseMgrLine _PARAMS((void));
1c481e00 250static void parsePidFilenameLine _PARAMS((void));
1c481e00 251static void parseRequestSizeLine _PARAMS((void));
252static void parseStoreLogLine _PARAMS((void));
253static void parseSwapLine _PARAMS((void));
254static void parseTTLPattern _PARAMS((int icase, int force));
255static void parseVisibleHostnameLine _PARAMS((void));
256static void parseWAISRelayLine _PARAMS((void));
79b5cc5f 257static void parseMinutesLine _PARAMS((int *));
090089c4 258
3003c0f3 259void self_destruct()
090089c4 260{
b8de7ebe 261 sprintf(fatal_str, "Bungled %s line %d: %s",
262 cfg_filename, config_lineno, config_input_line);
090089c4 263 fatal(fatal_str);
264}
265
c8bd12b1 266int ip_acl_match(c, a)
267 struct in_addr c;
268 ip_acl *a;
269{
270 static struct in_addr h;
271
272 h.s_addr = c.s_addr & a->mask.s_addr;
273 if (h.s_addr == a->addr.s_addr)
274 return 1;
275 else
276 return 0;
277}
278
279
c837641d 280ip_access_type ip_access_check(address, list)
c8bd12b1 281 struct in_addr address;
282 ip_acl *list;
283{
c7f37efb 284 static int init = 0;
285 static struct in_addr localhost;
c837641d 286 ip_acl *p = NULL;
c8bd12b1 287 struct in_addr naddr; /* network byte-order IP addr */
c8bd12b1 288
289 if (!list)
290 return IP_ALLOW;
291
c7f37efb 292 if (!init) {
293 memset((char *) &localhost, '\0', sizeof(struct in_addr));
c8bd12b1 294 localhost.s_addr = inet_addr("127.0.0.1");
c7f37efb 295 init = 1;
296 }
c8bd12b1 297 naddr.s_addr = address.s_addr;
298 if (naddr.s_addr == localhost.s_addr)
299 return IP_ALLOW;
300
a4f583ee 301 debug(3, 5, "ip_access_check: using %s\n", inet_ntoa(naddr));
c8bd12b1 302
303 for (p = list; p; p = p->next) {
a4f583ee 304 debug(3, 5, "ip_access_check: %s vs %s/%s\n",
305 inet_ntoa(naddr),
306 inet_ntoa(p->addr),
307 inet_ntoa(p->mask));
c8bd12b1 308 if (ip_acl_match(naddr, p))
309 return p->access;
310 }
311 return IP_ALLOW;
312}
313
314
315void addToIPACL(list, ip_str, access)
316 ip_acl **list;
317 char *ip_str;
318 ip_access_type access;
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 */
b2bc6f9e 357 lmask.s_addr = 0x00000000;
d3c1a245 358 else if (a2 == 0 && a3 == 0 && a4 == 0) /* class A */
b2bc6f9e 359 lmask.s_addr = htonl(0xff000000);
d3c1a245 360 else if (a3 == 0 && a4 == 0) /* class B */
b2bc6f9e 361 lmask.s_addr = htonl(0xffff0000);
d3c1a245 362 else if (a4 == 0) /* class C */
b2bc6f9e 363 lmask.s_addr = htonl(0xffffff00);
c8bd12b1 364 else
365 lmask.s_addr = 0xffffffff;
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 }
374 lmask.s_addr = htonl(0xffffffff << (32 - m1));
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
92a6f4b1 393void wordlistDestroy(list)
84c6cc9f 394 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
407void wordlistAdd(list, key)
408 wordlist **list;
090089c4 409 char *key;
410{
0ffd22bc 411 wordlist *p = NULL;
412 wordlist *q = NULL;
090089c4 413
414 if (!(*list)) {
415 /* empty list */
30a4f2a8 416 *list = xcalloc(1, sizeof(wordlist));
090089c4 417 (*list)->key = xstrdup(key);
418 (*list)->next = NULL;
419 } else {
420 p = *list;
421 while (p->next)
422 p = p->next;
30a4f2a8 423 q = xcalloc(1, sizeof(wordlist));
090089c4 424 q->key = xstrdup(key);
425 q->next = NULL;
426 p->next = q;
427 }
428}
429
92a6f4b1 430void intlistDestroy(list)
431 intlist **list;
432{
433 intlist *w = NULL;
434 intlist *n = NULL;
435
436 for (w = *list; w; w = n) {
437 n = w->next;
438 safe_free(w);
439 }
440 *list = NULL;
441}
442
403279e0 443
090089c4 444/* Use this #define in all the parse*() functions. Assumes
3003c0f3 445 * ** char *token is defined
090089c4 446 */
447
448#define GetInteger(var) \
449 token = strtok(NULL, w_space); \
30a4f2a8 450 if( token == NULL) \
3003c0f3 451 self_destruct(); \
090089c4 452 if (sscanf(token, "%d", &var) != 1) \
3003c0f3 453 self_destruct();
090089c4 454
455
3003c0f3 456static void parseCacheHostLine()
090089c4 457{
458 char *type = NULL;
459 char *hostname = NULL;
460 char *token = NULL;
30a4f2a8 461 u_short http_port = CACHE_HTTP_PORT;
462 u_short icp_port = CACHE_ICP_PORT;
463 int options = 0;
fe113054 464 int weight = 1;
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);
fe113054 483 } else {
01f2d250 484 debug(3, 0, "parseCacheHostLine: token='%s'\n", token);
a0bbd6c8 485 self_destruct();
fe113054 486 }
090089c4 487 }
234967c9 488 if (weight < 1)
489 weight = 1;
30a4f2a8 490 neighbors_cf_add(hostname, type, http_port, icp_port, options, weight);
090089c4 491}
492
3003c0f3 493static void parseHostDomainLine()
090089c4 494{
495 char *host = NULL;
496 char *domain = NULL;
30a4f2a8 497 if (!(host = strtok(NULL, w_space)))
498 self_destruct();
499 while ((domain = strtok(NULL, ", \t\n")))
500 neighbors_cf_domain(host, domain);
501}
090089c4 502
30a4f2a8 503static void parseHostAclLine()
504{
505 char *host = NULL;
506 char *aclname = NULL;
090089c4 507 if (!(host = strtok(NULL, w_space)))
3003c0f3 508 self_destruct();
30a4f2a8 509 while ((aclname = strtok(NULL, ", \t\n")))
510 neighbors_cf_acl(host, aclname);
090089c4 511}
512
090089c4 513
3003c0f3 514static void parseMemLine()
090089c4 515{
516 char *token;
517 int i;
518 GetInteger(i);
519 Config.Mem.maxSize = i << 20;
520}
521
3003c0f3 522static void parseHotVmFactorLine()
090089c4 523{
524 char *token = NULL;
525 double d;
526
527 token = strtok(NULL, w_space);
30a4f2a8 528 if (token == NULL)
3003c0f3 529 self_destruct();
090089c4 530 if (sscanf(token, "%lf", &d) != 1)
3003c0f3 531 self_destruct();
090089c4 532 if (d < 0)
3003c0f3 533 self_destruct();
090089c4 534 Config.hotVmFactor = d;
535}
536
3003c0f3 537static void parseSwapLine()
090089c4 538{
539 char *token;
540 int i;
541 GetInteger(i);
542 Config.Swap.maxSize = i << 10;
543}
544
3003c0f3 545static void parseHttpLine()
090089c4 546{
547 char *token;
548 int i;
549 GetInteger(i);
550 Config.Http.maxObjSize = i << 20;
551 GetInteger(i);
552 Config.Http.defaultTtl = i * 60;
553}
554
3003c0f3 555static void parseGopherLine()
090089c4 556{
557 char *token;
558 int i;
559 GetInteger(i);
560 Config.Gopher.maxObjSize = i << 20;
561 GetInteger(i);
562 Config.Gopher.defaultTtl = i * 60;
563}
564
3003c0f3 565static void parseFtpLine()
090089c4 566{
567 char *token;
568 int i;
569 GetInteger(i);
570 Config.Ftp.maxObjSize = i << 20;
571 GetInteger(i);
572 Config.Ftp.defaultTtl = i * 60;
573}
574
1c481e00 575static void parseTTLPattern(icase, force)
576 int icase;
577 int force;
090089c4 578{
579 char *token;
580 char *pattern;
581 time_t abs_ttl = 0;
582 int pct_age = 0;
583 time_t age_max = Config.ageMaxDefault;
584 int i;
585
586 token = strtok(NULL, w_space); /* token: regex pattern */
30a4f2a8 587 if (token == NULL)
3003c0f3 588 self_destruct();
090089c4 589 pattern = xstrdup(token);
590
591 GetInteger(i); /* token: abs_ttl */
592 abs_ttl = (time_t) (i * 60); /* convert minutes to seconds */
593
594 token = strtok(NULL, w_space); /* token: pct_age */
595 if (token != (char *) NULL) { /* pct_age is optional */
596 if (sscanf(token, "%d", &pct_age) != 1)
3003c0f3 597 self_destruct();
2546fcb3 598
599 token = strtok(NULL, w_space); /* token: age_max */
600 if (token != (char *) NULL) { /* age_max is optional */
601 if (sscanf(token, "%d", &i) != 1)
602 self_destruct();
603 age_max = (time_t) (i * 60); /* convert minutes to seconds */
604 }
090089c4 605 }
1c481e00 606 ttlAddToList(pattern, icase, force, abs_ttl, pct_age, age_max);
2546fcb3 607 safe_free(pattern);
608}
609
610static void parseQuickAbort()
611{
612 char *token;
613 int i;
fea2e6e0 614 token = strtok(NULL, w_space);
615 if (!strcasecmp(token, "on")) {
616 Config.quickAbort.min = 10 << 10; /* 10k */
617 Config.quickAbort.pct = 64; /* 50% */
618 Config.quickAbort.max = 100 << 10; /* 100k */
619 } else if (!strcasecmp(token, "off")) {
620 Config.quickAbort.min = -1;
621 Config.quickAbort.pct = 0;
622 Config.quickAbort.max = 0;
623 } else {
6c93e119 624 if (sscanf(token, "%d", &i) != 1)
625 self_destruct();
fea2e6e0 626 Config.quickAbort.min = i * 1024;
627 GetInteger(i);
628 Config.quickAbort.pct = i * 128 / 100; /* 128 is full scale */
629 GetInteger(i);
630 Config.quickAbort.max = i * 1024;
631 }
2546fcb3 632}
633
79b5cc5f 634static void parseMinutesLine(iptr)
635 int *iptr;
090089c4 636{
637 char *token;
638 int i;
639 GetInteger(i);
79b5cc5f 640 *iptr = i * 60;
090089c4 641}
642
3003c0f3 643static void parseRequestSizeLine()
fa966b74 644{
645 char *token;
646 int i;
647 GetInteger(i);
648 Config.maxRequestSize = i * 1024;
649}
650
3003c0f3 651static void parseMgrLine()
090089c4 652{
653 char *token;
654 token = strtok(NULL, w_space);
30a4f2a8 655 if (token == NULL)
3003c0f3 656 self_destruct();
090089c4 657 safe_free(Config.adminEmail);
658 Config.adminEmail = xstrdup(token);
659}
660
3003c0f3 661static void parseDirLine()
090089c4 662{
663 char *token;
664
665 token = strtok(NULL, w_space);
30a4f2a8 666 if (token == NULL)
3003c0f3 667 self_destruct();
0ffd22bc 668 wordlistAdd(&Config.cache_dirs, token);
090089c4 669}
670
e81957b7 671#if USE_PROXY_AUTH
672static void parseProxyAuthLine()
673{
674 char *token;
675
676 token = strtok(NULL, w_space);
677 if (token == NULL)
fea2e6e0 678 self_destruct();
e81957b7 679 safe_free(Config.proxyAuthFile);
680 safe_free(Config.proxyAuthIgnoreDomain);
681 Config.proxyAuthFile = xstrdup(token);
682 if ((token = strtok(NULL, w_space)))
fea2e6e0 683 Config.proxyAuthIgnoreDomain = xstrdup(token);
e81957b7 684}
685#endif /* USE_PROXY_AUTH */
686
3003c0f3 687static void parseHttpdAccelLine()
090089c4 688{
689 char *token;
844327e4 690 LOCAL_ARRAY(char, buf, BUFSIZ);
090089c4 691 int i;
692
693 token = strtok(NULL, w_space);
30a4f2a8 694 if (token == NULL)
3003c0f3 695 self_destruct();
090089c4 696 safe_free(Config.Accel.host);
697 Config.Accel.host = xstrdup(token);
698 GetInteger(i);
699 Config.Accel.port = i;
700 safe_free(Config.Accel.prefix);
701 sprintf(buf, "http://%s:%d", Config.Accel.host, Config.Accel.port);
702 Config.Accel.prefix = xstrdup(buf);
703 httpd_accel_mode = 1;
704}
705
3003c0f3 706static void parseEffectiveUserLine()
090089c4 707{
708 char *token;
709
710 token = strtok(NULL, w_space);
30a4f2a8 711 if (token == NULL)
3003c0f3 712 self_destruct();
090089c4 713 safe_free(Config.effectiveUser);
714 safe_free(Config.effectiveGroup);
715 Config.effectiveUser = xstrdup(token);
716
717 token = strtok(NULL, w_space);
30a4f2a8 718 if (token == NULL)
090089c4 719 return; /* group is optional */
720 Config.effectiveGroup = xstrdup(token);
721}
722
3003c0f3 723static void parseLogLine()
090089c4 724{
725 char *token;
090089c4 726 token = strtok(NULL, w_space);
30a4f2a8 727 if (token == NULL)
3003c0f3 728 self_destruct();
090089c4 729 safe_free(Config.Log.log);
730 Config.Log.log = xstrdup(token);
090089c4 731}
732
3003c0f3 733static void parseAccessLogLine()
090089c4 734{
735 char *token;
736 token = strtok(NULL, w_space);
30a4f2a8 737 if (token == NULL)
3003c0f3 738 self_destruct();
090089c4 739 safe_free(Config.Log.access);
740 Config.Log.access = xstrdup(token);
741}
742
d8b45066 743static void parseStoreLogLine()
744{
745 char *token;
746 token = strtok(NULL, w_space);
30a4f2a8 747 if (token == NULL)
d8b45066 748 self_destruct();
749 safe_free(Config.Log.store);
750 Config.Log.store = xstrdup(token);
751}
752
3003c0f3 753static void parseFtpProgramLine()
090089c4 754{
755 char *token;
756 token = strtok(NULL, w_space);
30a4f2a8 757 if (token == NULL)
3003c0f3 758 self_destruct();
090089c4 759 safe_free(Config.Program.ftpget);
760 Config.Program.ftpget = xstrdup(token);
761}
762
3003c0f3 763static void parseFtpOptionsLine()
090089c4 764{
765 char *token;
766 token = strtok(NULL, ""); /* Note "", don't separate these */
30a4f2a8 767 if (token == NULL)
3003c0f3 768 self_destruct();
090089c4 769 safe_free(Config.Program.ftpget_opts);
770 Config.Program.ftpget_opts = xstrdup(token);
771}
772
3003c0f3 773static void parseDnsProgramLine()
090089c4 774{
775 char *token;
776 token = strtok(NULL, w_space);
30a4f2a8 777 if (token == NULL)
3003c0f3 778 self_destruct();
090089c4 779 safe_free(Config.Program.dnsserver);
780 Config.Program.dnsserver = xstrdup(token);
781}
782
d2af9477 783static void parseRedirectProgramLine()
784{
785 char *token;
786 token = strtok(NULL, w_space);
787 if (token == NULL)
788 self_destruct();
789 safe_free(Config.Program.redirect);
790 Config.Program.redirect = xstrdup(token);
791}
792
c1c29eb6 793static void parseOnOff(var)
55bb9c51 794 int *var;
090089c4 795{
796 char *token;
797 token = strtok(NULL, w_space);
30a4f2a8 798 if (token == NULL)
3003c0f3 799 self_destruct();
090089c4 800 if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
c1c29eb6 801 *var = 1;
090089c4 802 else
c1c29eb6 803 *var = 0;
090089c4 804}
805
3003c0f3 806static void parseWAISRelayLine()
090089c4 807{
808 char *token;
809 int i;
810 token = strtok(NULL, w_space);
30a4f2a8 811 if (token == NULL)
3003c0f3 812 self_destruct();
090089c4 813 safe_free(Config.Wais.relayHost);
814 Config.Wais.relayHost = xstrdup(token);
815 GetInteger(i);
30a4f2a8 816 Config.Wais.relayPort = (u_short) i;
090089c4 817 GetInteger(i);
818 Config.Wais.maxObjSize = i << 20;
819}
820
30a4f2a8 821static void parseIPLine(list)
822 ip_acl **list;
090089c4 823{
824 char *token;
825 while ((token = strtok(NULL, w_space))) {
30a4f2a8 826 addToIPACL(list, token, IP_DENY);
090089c4 827 }
828}
829
30a4f2a8 830static void parseHierarchyStoplistLine()
831{
832 char *token;
833 while ((token = strtok(NULL, w_space)))
834 wordlistAdd(&Config.hierarchy_stoplist, token);
835}
090089c4 836
3003c0f3 837static void parseAppendDomainLine()
090089c4 838{
839 char *token;
840 token = strtok(NULL, w_space);
30a4f2a8 841 if (token == NULL)
3003c0f3 842 self_destruct();
090089c4 843 if (*token != '.')
3003c0f3 844 self_destruct();
090089c4 845 safe_free(Config.appendDomain);
846 Config.appendDomain = xstrdup(token);
847}
848
30a4f2a8 849static void parseAddressLine(addr)
850 struct in_addr *addr;
090089c4 851{
852 char *token;
30a4f2a8 853 struct hostent *hp = NULL;
090089c4 854 token = strtok(NULL, w_space);
30a4f2a8 855 if (token == NULL)
856 self_destruct();
857 if (inet_addr(token) != INADDR_NONE)
858 (*addr).s_addr = inet_addr(token);
859 else if ((hp = gethostbyname(token)))
860 xmemcpy(addr, hp->h_addr, hp->h_length);
861 else
3003c0f3 862 self_destruct();
090089c4 863}
864
983061ed 865static void parseLocalDomainFile(fname)
866 char *fname;
867{
844327e4 868 LOCAL_ARRAY(char, tmp_line, BUFSIZ);
983061ed 869 FILE *fp = NULL;
870 char *t = NULL;
871
872 if ((fp = fopen(fname, "r")) == NULL) {
873 debug(3, 1, "parseLocalDomainFile: %s: %s\n", fname, xstrerror());
874 return;
875 }
876 memset(tmp_line, '\0', BUFSIZ);
877 while (fgets(tmp_line, BUFSIZ, fp)) {
878 if (tmp_line[0] == '#')
879 continue;
880 if (tmp_line[0] == '\0')
881 continue;
882 if (tmp_line[0] == '\n')
883 continue;
884 for (t = strtok(tmp_line, w_space); t; t = strtok(NULL, w_space)) {
885 debug(3, 1, "parseLocalDomainFileLine: adding %s\n", t);
886 wordlistAdd(&Config.local_domain_list, t);
887 }
888 }
889 fclose(fp);
890}
891
3003c0f3 892static void parseLocalDomainLine()
090089c4 893{
983061ed 894 char *token = NULL;
895 struct stat sb;
090089c4 896 while ((token = strtok(NULL, w_space))) {
983061ed 897 if (stat(token, &sb) < 0) {
898 wordlistAdd(&Config.local_domain_list, token);
899 } else {
900 parseLocalDomainFile(token);
901 }
090089c4 902 }
903}
904
3003c0f3 905static void parseInsideFirewallLine()
090089c4 906{
907 char *token;
908 while ((token = strtok(NULL, w_space))) {
0ffd22bc 909 wordlistAdd(&Config.inside_firewall_list, token);
090089c4 910 }
911}
912
605ba5ca 913static void parseDnsTestnameLine()
914{
915 char *token;
916 while ((token = strtok(NULL, w_space))) {
917 wordlistAdd(&Config.dns_testname_list, token);
918 }
919}
920
30a4f2a8 921static void parseHttpPortLine()
090089c4 922{
923 char *token;
924 int i;
925 GetInteger(i);
30a4f2a8 926 if (i < 0)
927 i = 0;
928 Config.Port.http = (u_short) i;
090089c4 929}
930
30a4f2a8 931static void parseIcpPortLine()
090089c4 932{
933 char *token;
934 int i;
935 GetInteger(i);
30a4f2a8 936 if (i < 0)
937 i = 0;
938 Config.Port.icp = (u_short) i;
090089c4 939}
940
3003c0f3 941static void parseDebugOptionsLine()
090089c4 942{
12b9e9b1 943 char *token;
944 token = strtok(NULL, ""); /* Note "", don't separate these */
945 safe_free(Config.debugOptions);
30a4f2a8 946 if (token == NULL) {
12b9e9b1 947 Config.debugOptions = NULL;
948 return;
949 }
950 Config.debugOptions = xstrdup(token);
090089c4 951}
952
3003c0f3 953static void parsePidFilenameLine()
ccff9601 954{
955 char *token;
956 token = strtok(NULL, w_space);
957 safe_free(Config.pidFilename);
30a4f2a8 958 if (token == NULL)
3003c0f3 959 self_destruct();
ccff9601 960 Config.pidFilename = xstrdup(token);
961}
962
3003c0f3 963static void parseVisibleHostnameLine()
cf5fd929 964{
965 char *token;
966 token = strtok(NULL, w_space);
967 safe_free(Config.visibleHostname);
30a4f2a8 968 if (token == NULL)
3003c0f3 969 self_destruct();
cf5fd929 970 Config.visibleHostname = xstrdup(token);
971}
972
3003c0f3 973static void parseFtpUserLine()
fb263c4c 974{
975 char *token;
976 token = strtok(NULL, w_space);
30a4f2a8 977 if (token == NULL)
3003c0f3 978 self_destruct();
7d49daab 979 safe_free(Config.ftpUser);
fb263c4c 980 Config.ftpUser = xstrdup(token);
981}
982
3003c0f3 983static void parseCacheAnnounceLine()
7d49daab 984{
985 char *token;
986 int i;
987 GetInteger(i);
988 Config.Announce.rate = i * 3600; /* hours to seconds */
989}
990
3003c0f3 991static void parseAnnounceToLine()
7d49daab 992{
993 char *token;
994 int i;
995 token = strtok(NULL, w_space);
30a4f2a8 996 if (token == NULL)
3003c0f3 997 self_destruct();
7d49daab 998 safe_free(Config.Announce.host);
999 Config.Announce.host = xstrdup(token);
1000 if ((token = strchr(Config.Announce.host, ':'))) {
1001 *token++ = '\0';
1002 if (sscanf(token, "%d", &i) != 1)
1003 Config.Announce.port = i;
1004 }
1005 token = strtok(NULL, w_space);
30a4f2a8 1006 if (token == NULL)
7d49daab 1007 return;
1008 safe_free(Config.Announce.file);
1009 Config.Announce.file = xstrdup(token);
1010}
1011
98ffb7e4 1012static void parseSslProxyLine()
1013{
1014 char *token;
1015 char *t;
1016 token = strtok(NULL, w_space);
1017 if (token == NULL)
1018 self_destruct();
1019 safe_free(Config.sslProxy.host);
1020 Config.sslProxy.port = 0;
1021 if ((t = strchr(token, ':'))) {
1022 *t++ = '\0';
1023 Config.sslProxy.port = atoi(t);
1024 }
1025 Config.sslProxy.host = xstrdup(token);
1026}
1027
7813c6d5 1028static void parseIntegerValue(iptr)
b6f794d6 1029 int *iptr;
7813c6d5 1030{
1031 char *token;
1032 int i;
1033 GetInteger(i);
1034 *iptr = i;
1035}
1036
6e40f263 1037static void parseErrHtmlLine()
1038{
1039 char *token;
1040 if ((token = strtok(NULL, "")))
1041 Config.errHtmlText = xstrdup(token);
1042}
403279e0 1043
090089c4 1044int parseConfigFile(file_name)
1045 char *file_name;
1046{
12b9e9b1 1047 FILE *fp = NULL;
1048 char *token = NULL;
844327e4 1049 LOCAL_ARRAY(char, tmp_line, BUFSIZ);
090089c4 1050
0ffd22bc 1051 configFreeMemory();
090089c4 1052 configSetFactoryDefaults();
92a6f4b1 1053 aclDestroyAcls();
ea1b5bd8 1054 aclDestroyDenyInfoList(&DenyInfoList);
92a6f4b1 1055 aclDestroyAccessList(&HTTPAccessList);
1056 aclDestroyAccessList(&ICPAccessList);
090089c4 1057
12b9e9b1 1058 if ((fp = fopen(file_name, "r")) == NULL) {
234967c9 1059 sprintf(fatal_str, "Unable to open configuration file: %s: %s",
1060 file_name, xstrerror());
090089c4 1061 fatal(fatal_str);
1062 }
b8de7ebe 1063 cfg_filename = file_name;
1064 if ((token = strrchr(cfg_filename, '/')))
4cd0ab45 1065 cfg_filename = token + 1;
3003c0f3 1066 memset(config_input_line, '\0', BUFSIZ);
1067 config_lineno = 0;
1068 while (fgets(config_input_line, BUFSIZ, fp)) {
1069 config_lineno++;
1070 if ((token = strchr(config_input_line, '\n')))
540830c4 1071 *token = '\0';
3003c0f3 1072 if (config_input_line[0] == '#')
540830c4 1073 continue;
3003c0f3 1074 if (config_input_line[0] == '\0')
090089c4 1075 continue;
3003c0f3 1076 debug(3, 5, "Processing: '%s'\n", config_input_line);
1077 strcpy(tmp_line, config_input_line);
92a6f4b1 1078 if ((token = strtok(tmp_line, w_space)) == NULL)
090089c4 1079 continue;
1080
090089c4 1081 if (!strcmp(token, "cache_host"))
3003c0f3 1082 parseCacheHostLine();
090089c4 1083
090089c4 1084 else if (!strcmp(token, "cache_host_domain"))
3003c0f3 1085 parseHostDomainLine();
30a4f2a8 1086 else if (!strcmp(token, "cache_host_acl"))
1087 parseHostAclLine();
090089c4 1088
090089c4 1089 else if (!strcmp(token, "neighbor_timeout"))
7813c6d5 1090 parseIntegerValue(&Config.neighborTimeout);
090089c4 1091 else if (!strcmp(token, "neighbour_timeout")) /* alternate spelling */
7813c6d5 1092 parseIntegerValue(&Config.neighborTimeout);
090089c4 1093
090089c4 1094 else if (!strcmp(token, "cache_dir"))
3003c0f3 1095 parseDirLine();
090089c4 1096
090089c4 1097 else if (!strcmp(token, "cache_log"))
3003c0f3 1098 parseLogLine();
090089c4 1099
090089c4 1100 else if (!strcmp(token, "cache_access_log"))
3003c0f3 1101 parseAccessLogLine();
090089c4 1102
d8b45066 1103 else if (!strcmp(token, "cache_store_log"))
1104 parseStoreLogLine();
1105
090089c4 1106 else if (!strcmp(token, "logfile_rotate"))
7813c6d5 1107 parseIntegerValue(&Config.Log.rotateNumber);
090089c4 1108
090089c4 1109 else if (!strcmp(token, "httpd_accel_with_proxy"))
c1c29eb6 1110 parseOnOff(&Config.Accel.withProxy);
090089c4 1111
090089c4 1112 else if (!strcmp(token, "httpd_accel"))
3003c0f3 1113 parseHttpdAccelLine();
090089c4 1114
090089c4 1115 else if (!strcmp(token, "cache_effective_user"))
3003c0f3 1116 parseEffectiveUserLine();
090089c4 1117
090089c4 1118 else if (!strcmp(token, "cache_swap_high"))
7813c6d5 1119 parseIntegerValue(&Config.Swap.highWaterMark);
090089c4 1120
090089c4 1121 else if (!strcmp(token, "cache_swap_low"))
7c6c6f75 1122 parseIntegerValue(&Config.Swap.lowWaterMark);
090089c4 1123
090089c4 1124 else if (!strcmp(token, "cache_mem_high"))
7813c6d5 1125 parseIntegerValue(&Config.Mem.highWaterMark);
090089c4 1126
090089c4 1127 else if (!strcmp(token, "cache_mem_low"))
7813c6d5 1128 parseIntegerValue(&Config.Mem.lowWaterMark);
090089c4 1129
090089c4 1130 else if (!strcmp(token, "cache_hot_vm_factor"))
3003c0f3 1131 parseHotVmFactorLine();
090089c4 1132
090089c4 1133 else if (!strcmp(token, "cache_mem"))
3003c0f3 1134 parseMemLine();
090089c4 1135
090089c4 1136 else if (!strcmp(token, "cache_swap"))
3003c0f3 1137 parseSwapLine();
090089c4 1138
090089c4 1139 else if (!strcmp(token, "cache_mgr"))
3003c0f3 1140 parseMgrLine();
090089c4 1141
8213067d 1142 else if (!strcmp(token, "acl"))
3003c0f3 1143 aclParseAclLine();
8213067d 1144
ea1b5bd8 1145 else if (!strcmp(token, "deny_info"))
1146 aclParseDenyInfoLine(&DenyInfoList);
1147
92a6f4b1 1148 else if (!strcmp(token, "http_access"))
1149 aclParseAccessLine(&HTTPAccessList);
1150
1151 else if (!strcmp(token, "icp_access"))
1152 aclParseAccessLine(&ICPAccessList);
8213067d 1153
30a4f2a8 1154 else if (!strcmp(token, "hierarchy_stoplist"))
1155 parseHierarchyStoplistLine();
1156
090089c4 1157 else if (!strcmp(token, "gopher"))
3003c0f3 1158 parseGopherLine();
090089c4 1159
090089c4 1160 else if (!strcmp(token, "http"))
3003c0f3 1161 parseHttpLine();
090089c4 1162
090089c4 1163 else if (!strcmp(token, "ftp"))
3003c0f3 1164 parseFtpLine();
090089c4 1165
1166 else if (!strcmp(token, "ttl_pattern"))
1c481e00 1167 parseTTLPattern(0, 0);
1168 else if (!strcmp(token, "ttl_pattern/i"))
1169 parseTTLPattern(1, 0);
2546fcb3 1170 else if (!strcmp(token, "ttl_force_pattern"))
1c481e00 1171 parseTTLPattern(0, 1);
1172 else if (!strcmp(token, "ttl_force_pattern/i"))
1173 parseTTLPattern(1, 1);
2546fcb3 1174
1175 else if (!strcmp(token, "quick_abort"))
1176 parseQuickAbort();
1177
090089c4 1178 else if (!strcmp(token, "negative_ttl"))
79b5cc5f 1179 parseMinutesLine(&Config.negativeTtl);
61d6fc5c 1180 else if (!strcmp(token, "negative_dns_ttl"))
79b5cc5f 1181 parseMinutesLine(&Config.negativeDnsTtl);
2639dac6 1182 else if (!strcmp(token, "positive_dns_ttl"))
79b5cc5f 1183 parseMinutesLine(&Config.positiveDnsTtl);
090089c4 1184 else if (!strcmp(token, "read_timeout"))
79b5cc5f 1185 parseMinutesLine(&Config.readTimeout);
090089c4 1186 else if (!strcmp(token, "clean_rate"))
79b5cc5f 1187 parseMinutesLine(&Config.cleanRate);
090089c4 1188 else if (!strcmp(token, "client_lifetime"))
79b5cc5f 1189 parseMinutesLine(&Config.lifetimeDefault);
1190 else if (!strcmp(token, "expire_age"))
1191 parseMinutesLine(&Config.expireAge);
090089c4 1192
605ba5ca 1193 else if (!strcmp(token, "shutdown_lifetime"))
7813c6d5 1194 parseIntegerValue(&Config.lifetimeShutdown);
605ba5ca 1195
fa966b74 1196 else if (!strcmp(token, "request_size"))
3003c0f3 1197 parseRequestSizeLine();
fa966b74 1198
090089c4 1199 else if (!strcmp(token, "connect_timeout"))
7813c6d5 1200 parseIntegerValue(&Config.connectTimeout);
090089c4 1201
090089c4 1202 else if (!strcmp(token, "cache_ftp_program"))
3003c0f3 1203 parseFtpProgramLine();
090089c4 1204
090089c4 1205 else if (!strcmp(token, "cache_ftp_options"))
3003c0f3 1206 parseFtpOptionsLine();
090089c4 1207
090089c4 1208 else if (!strcmp(token, "cache_dns_program"))
3003c0f3 1209 parseDnsProgramLine();
090089c4 1210
090089c4 1211 else if (!strcmp(token, "dns_children"))
7813c6d5 1212 parseIntegerValue(&Config.dnsChildren);
090089c4 1213
d2af9477 1214 else if (!strcmp(token, "redirect_program"))
1215 parseRedirectProgramLine();
98ffb7e4 1216
d2af9477 1217 else if (!strcmp(token, "redirect_children"))
7813c6d5 1218 parseIntegerValue(&Config.redirectChildren);
d2af9477 1219
e81957b7 1220#if USE_PROXY_AUTH
d6b73110 1221 else if (!strcmp(token, "proxy_auth"))
fea2e6e0 1222 parseProxyAuthLine();
e81957b7 1223#endif /* USE_PROXY_AUTH */
1224
090089c4 1225 else if (!strcmp(token, "source_ping"))
c1c29eb6 1226 parseOnOff(&Config.sourcePing);
090089c4 1227
090089c4 1228 else if (!strcmp(token, "emulate_httpd_log"))
c1c29eb6 1229 parseOnOff(&Config.commonLogFormat);
1230
2ba42578 1231#if LOG_FULL_HEADERS
e43efe50 1232 else if (!strcmp(token, "log_mime_hdrs"))
1233 parseOnOff(&Config.logMimeHdrs);
1234
1235#endif /* LOG_FULL_HEADERS */
7813c6d5 1236 else if (!strcmp(token, "ident_lookup"))
c1c29eb6 1237 parseOnOff(&Config.identLookup);
090089c4 1238
1239 else if (!strcmp(token, "append_domain"))
3003c0f3 1240 parseAppendDomainLine();
090089c4 1241
090089c4 1242 else if (!strcmp(token, "wais_relay"))
3003c0f3 1243 parseWAISRelayLine();
090089c4 1244
090089c4 1245 else if (!strcmp(token, "local_ip"))
b6f794d6 1246 parseIPLine(&Config.local_ip_list);
30a4f2a8 1247
1248 else if (!strcmp(token, "firewall_ip"))
b6f794d6 1249 parseIPLine(&Config.firewall_ip_list);
090089c4 1250
090089c4 1251 else if (!strcmp(token, "local_domain"))
3003c0f3 1252 parseLocalDomainLine();
090089c4 1253
30a4f2a8 1254 else if (!strcmp(token, "tcp_incoming_address"))
1255 parseAddressLine(&Config.Addrs.tcp_incoming);
1256
1257 else if (!strcmp(token, "tcp_outgoing_address"))
1258 parseAddressLine(&Config.Addrs.tcp_outgoing);
1259
1260 else if (!strcmp(token, "udp_incoming_address"))
1261 parseAddressLine(&Config.Addrs.udp_incoming);
1262
1263 else if (!strcmp(token, "udp_outgoing_address"))
1264 parseAddressLine(&Config.Addrs.udp_outgoing);
1265
844327e4 1266 else if (!strcmp(token, "client_netmask"))
1267 parseAddressLine(&Config.Addrs.client_netmask);
1268
7813c6d5 1269 else if (!strcmp(token, "tcp_recv_bufsize"))
1270 parseIntegerValue(&Config.tcpRcvBufsz);
1271
2c82dc1a 1272 else if (!strcmp(token, "log_fqdn"))
1273 parseOnOff(&Config.Log.log_fqdn);
1274
090089c4 1275 else if (!strcmp(token, "bind_address"))
30a4f2a8 1276 parseAddressLine(&Config.Addrs.tcp_incoming);
1277
1278 else if (!strcmp(token, "outbound_address"))
1279 parseAddressLine(&Config.Addrs.tcp_outgoing);
090089c4 1280
30a4f2a8 1281 else if (!strcmp(token, "http_port") || !strcmp(token, "ascii_port"))
1282 parseHttpPortLine();
090089c4 1283
30a4f2a8 1284 else if (!strcmp(token, "icp_port") || !strcmp(token, "udp_port"))
1285 parseIcpPortLine();
090089c4 1286
1287 else if (!strcmp(token, "inside_firewall"))
3003c0f3 1288 parseInsideFirewallLine();
090089c4 1289
605ba5ca 1290 else if (!strcmp(token, "dns_testnames"))
1291 parseDnsTestnameLine();
1292
090089c4 1293 else if (!strcmp(token, "single_parent_bypass"))
c1c29eb6 1294 parseOnOff(&Config.singleParentBypass);
090089c4 1295
12b9e9b1 1296 else if (!strcmp(token, "debug_options"))
3003c0f3 1297 parseDebugOptionsLine();
12b9e9b1 1298
ccff9601 1299 else if (!strcmp(token, "pid_filename"))
3003c0f3 1300 parsePidFilenameLine();
ccff9601 1301
cf5fd929 1302 else if (!strcmp(token, "visible_hostname"))
3003c0f3 1303 parseVisibleHostnameLine();
cf5fd929 1304
fb263c4c 1305 else if (!strcmp(token, "ftp_user"))
3003c0f3 1306 parseFtpUserLine();
fb263c4c 1307
7d49daab 1308 else if (!strcmp(token, "cache_announce"))
3003c0f3 1309 parseCacheAnnounceLine();
7d49daab 1310
1311 else if (!strcmp(token, "announce_to"))
3003c0f3 1312 parseAnnounceToLine();
7d49daab 1313
98ffb7e4 1314 else if (!strcmp(token, "ssl_proxy"))
1315 parseSslProxyLine();
1316
6e40f263 1317 else if (!strcmp(token, "err_html_text"))
1318 parseErrHtmlLine();
1319
b15e6857 1320 else if (!strcmp(token, "ipcache_size"))
1321 parseIntegerValue(&Config.ipcache.size);
1322 else if (!strcmp(token, "ipcache_low"))
1323 parseIntegerValue(&Config.ipcache.low);
1324 else if (!strcmp(token, "ipcache_high"))
1325 parseIntegerValue(&Config.ipcache.high);
1326
090089c4 1327 else {
540830c4 1328 debug(3, 0, "parseConfigFile: line %d unrecognized: '%s'\n",
92a6f4b1 1329 config_lineno,
1330 config_input_line);
090089c4 1331 }
1332 }
1333
090089c4 1334 /* Sanity checks */
b6f794d6 1335 if (Config.lifetimeDefault < Config.readTimeout) {
090089c4 1336 printf("WARNING: client_lifetime (%d seconds) is less than read_timeout (%d seconds).\n",
b6f794d6 1337 Config.lifetimeDefault, Config.readTimeout);
090089c4 1338 printf(" This may cause serious problems with your cache!!!\n");
b8de7ebe 1339 printf(" Change your configuration file.\n");
090089c4 1340 fflush(stdout); /* print message */
1341 }
b6f794d6 1342 if (Config.Swap.maxSize < (Config.Mem.maxSize >> 10)) {
1343 printf("WARNING: cache_swap (%d kbytes) is less than cache_mem (%d bytes).\n", Config.Swap.maxSize, Config.Mem.maxSize);
090089c4 1344 printf(" This will cause serious problems with your cache!!!\n");
b8de7ebe 1345 printf(" Change your configuration file.\n");
090089c4 1346 fflush(stdout); /* print message */
1347 }
a4ebeb3b 1348 if (Config.cleanRate < 1)
28b2f45f 1349 Config.cleanRate = 86400 * 365; /* one year */
a4ebeb3b 1350 if (Config.Announce.rate < 1)
1351 Config.Announce.rate = 86400 * 365; /* one year */
b6f794d6 1352 if (Config.dnsChildren < 1) {
090089c4 1353 printf("WARNING: dns_children was set to a bad value: %d\n",
b6f794d6 1354 Config.dnsChildren);
d2af9477 1355 Config.dnsChildren = DefaultDnsChildren;
1356 printf("Setting it to the default (%d).\n", DefaultDnsChildren);
b6f794d6 1357 } else if (Config.dnsChildren > DefaultDnsChildrenMax) {
090089c4 1358 printf("WARNING: dns_children was set to a bad value: %d\n",
b6f794d6 1359 Config.dnsChildren);
090089c4 1360 printf("Setting it to the maximum (%d).\n", DefaultDnsChildrenMax);
1361 Config.dnsChildren = DefaultDnsChildrenMax;
1362 }
b6f794d6 1363 if (Config.redirectChildren < 1) {
d2af9477 1364 printf("WARNING: redirect_children was set to a bad value: %d\n",
b6f794d6 1365 Config.redirectChildren);
d2af9477 1366 Config.redirectChildren = DefaultRedirectChildren;
1367 printf("Setting it to the default (%d).\n", DefaultRedirectChildren);
b6f794d6 1368 } else if (Config.redirectChildren > DefaultRedirectChildrenMax) {
d2af9477 1369 printf("WARNING: redirect_children was set to a bad value: %d\n",
b6f794d6 1370 Config.redirectChildren);
d2af9477 1371 printf("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax);
1372 Config.redirectChildren = DefaultRedirectChildrenMax;
1373 }
090089c4 1374 fclose(fp);
1375
1376 configDoConfigure();
1377 return 0;
1378}
1379
30a4f2a8 1380u_short setHttpPortNum(port)
1381 u_short port;
090089c4 1382{
30a4f2a8 1383 return (Config.Port.http = port);
090089c4 1384}
30a4f2a8 1385u_short setIcpPortNum(port)
1386 u_short port;
1387{
1388 return (Config.Port.icp = port);
1389}
1390
30a4f2a8 1391static char *safe_xstrdup(p)
090089c4 1392 char *p;
1393{
30a4f2a8 1394 return p ? xstrdup(p) : p;
090089c4 1395}
1396
0ffd22bc 1397static void configFreeMemory()
1398{
1399 safe_free(Config.Wais.relayHost);
1400 safe_free(Config.Log.log);
1401 safe_free(Config.Log.access);
983061ed 1402 safe_free(Config.Log.store);
0ffd22bc 1403 safe_free(Config.adminEmail);
1404 safe_free(Config.effectiveUser);
1405 safe_free(Config.effectiveGroup);
1406 safe_free(Config.Program.ftpget);
1407 safe_free(Config.Program.ftpget_opts);
1408 safe_free(Config.Program.dnsserver);
d2af9477 1409 safe_free(Config.Program.redirect);
0ffd22bc 1410 safe_free(Config.Accel.host);
1411 safe_free(Config.Accel.prefix);
1412 safe_free(Config.appendDomain);
1413 safe_free(Config.debugOptions);
1414 safe_free(Config.pidFilename);
1415 safe_free(Config.visibleHostname);
1416 safe_free(Config.ftpUser);
e81957b7 1417#if USE_PROXY_AUTH
1418 safe_free(Config.proxyAuthFile);
1419 safe_free(Config.proxyAuthIgnoreDomain);
1420#endif /* USE_PROXY_AUTH */
0ffd22bc 1421 safe_free(Config.Announce.host);
1422 safe_free(Config.Announce.file);
6e40f263 1423 safe_free(Config.errHtmlText);
0ffd22bc 1424 wordlistDestroy(&Config.cache_dirs);
30a4f2a8 1425 wordlistDestroy(&Config.hierarchy_stoplist);
0ffd22bc 1426 wordlistDestroy(&Config.local_domain_list);
1427 wordlistDestroy(&Config.inside_firewall_list);
605ba5ca 1428 wordlistDestroy(&Config.dns_testname_list);
98ffb7e4 1429 safe_free(Config.sslProxy.host);
2546fcb3 1430 ttlFreeList();
0ffd22bc 1431}
1432
090089c4 1433
1434static void configSetFactoryDefaults()
1435{
1436 Config.Mem.maxSize = DefaultMemMaxSize;
7813c6d5 1437 Config.Mem.highWaterMark = DefaultMemHighWaterMark;
1438 Config.Mem.lowWaterMark = DefaultMemLowWaterMark;
090089c4 1439 Config.Swap.maxSize = DefaultSwapMaxSize;
7813c6d5 1440 Config.Swap.highWaterMark = DefaultSwapHighWaterMark;
090089c4 1441 Config.Swap.lowWaterMark = DefaultSwapLowWaterMark;
1442
1443 Config.Ftp.defaultTtl = DefaultFtpDefaultTtl;
1444 Config.Ftp.maxObjSize = DefaultFtpMaxObjSize;
1445 Config.Gopher.defaultTtl = DefaultGopherDefaultTtl;
1446 Config.Gopher.maxObjSize = DefaultGopherMaxObjSize;
1447 Config.Http.defaultTtl = DefaultHttpDefaultTtl;
1448 Config.Http.maxObjSize = DefaultHttpMaxObjSize;
090089c4 1449 Config.Wais.defaultTtl = DefaultWaisDefaultTtl;
1450 Config.Wais.maxObjSize = DefaultWaisMaxObjSize;
1451 Config.Wais.relayHost = safe_xstrdup(DefaultWaisRelayHost);
1452 Config.Wais.relayPort = DefaultWaisRelayPort;
090089c4 1453
79b5cc5f 1454 Config.expireAge = DefaultExpireAge;
090089c4 1455 Config.negativeTtl = DefaultNegativeTtl;
2639dac6 1456 Config.negativeDnsTtl = DefaultNegativeDnsTtl;
1457 Config.positiveDnsTtl = DefaultPositiveDnsTtl;
090089c4 1458 Config.readTimeout = DefaultReadTimeout;
1459 Config.lifetimeDefault = DefaultLifetimeDefault;
605ba5ca 1460 Config.lifetimeShutdown = DefaultLifetimeShutdown;
fa966b74 1461 Config.maxRequestSize = DefaultMaxRequestSize;
090089c4 1462 Config.connectTimeout = DefaultConnectTimeout;
1463 Config.ageMaxDefault = DefaultDefaultAgeMax;
1464 Config.cleanRate = DefaultCleanRate;
1465 Config.dnsChildren = DefaultDnsChildren;
d2af9477 1466 Config.redirectChildren = DefaultRedirectChildren;
090089c4 1467 Config.hotVmFactor = DefaultHotVmFactor;
1468 Config.sourcePing = DefaultSourcePing;
2546fcb3 1469 Config.quickAbort.min = DefaultQuickAbortMin;
1470 Config.quickAbort.pct = DefaultQuickAbortPct;
1471 Config.quickAbort.max = DefaultQuickAbortMax;
090089c4 1472 Config.commonLogFormat = DefaultCommonLogFormat;
2ba42578 1473#if LOG_FULL_HEADERS
e43efe50 1474 Config.logMimeHdrs = DefaultLogMimeHdrs;
1475#endif /* LOG_FULL_HEADERS */
12b9e9b1 1476 Config.debugOptions = safe_xstrdup(DefaultDebugOptions);
090089c4 1477 Config.neighborTimeout = DefaultNeighborTimeout;
e5c22962 1478 Config.stallDelay = DefaultStallDelay;
090089c4 1479 Config.singleParentBypass = DefaultSingleParentBypass;
1480 Config.adminEmail = safe_xstrdup(DefaultAdminEmail);
1481 Config.effectiveUser = safe_xstrdup(DefaultEffectiveUser);
1482 Config.effectiveGroup = safe_xstrdup(DefaultEffectiveGroup);
1483 Config.appendDomain = safe_xstrdup(DefaultAppendDomain);
6e40f263 1484 Config.errHtmlText = safe_xstrdup(DefaultErrHtmlText);
090089c4 1485
30a4f2a8 1486 Config.Port.http = DefaultHttpPortNum;
1487 Config.Port.icp = DefaultIcpPortNum;
090089c4 1488 Config.Log.log = safe_xstrdup(DefaultCacheLogFile);
1489 Config.Log.access = safe_xstrdup(DefaultAccessLogFile);
d8b45066 1490 Config.Log.store = safe_xstrdup(DefaultStoreLogFile);
090089c4 1491 Config.Log.rotateNumber = DefaultLogRotateNumber;
1492 Config.Program.ftpget = safe_xstrdup(DefaultFtpgetProgram);
1493 Config.Program.ftpget_opts = safe_xstrdup(DefaultFtpgetOptions);
1494 Config.Program.dnsserver = safe_xstrdup(DefaultDnsserverProgram);
d2af9477 1495 Config.Program.redirect = safe_xstrdup(DefaultRedirectProgram);
090089c4 1496 Config.Accel.host = safe_xstrdup(DefaultAccelHost);
1497 Config.Accel.prefix = safe_xstrdup(DefaultAccelPrefix);
1498 Config.Accel.port = DefaultAccelPort;
1499 Config.Accel.withProxy = DefaultAccelWithProxy;
ccff9601 1500 Config.pidFilename = safe_xstrdup(DefaultPidFilename);
cf5fd929 1501 Config.visibleHostname = safe_xstrdup(DefaultVisibleHostname);
e81957b7 1502#if USE_PROXY_AUTH
1503 Config.proxyAuthFile = safe_xstrdup(DefaultProxyAuthFile);
1504 Config.proxyAuthIgnoreDomain = safe_xstrdup(DefaultProxyAuthIgnoreDomain);
1505#endif /* USE_PROXY_AUTH */
fb263c4c 1506 Config.ftpUser = safe_xstrdup(DefaultFtpUser);
7d49daab 1507 Config.Announce.host = safe_xstrdup(DefaultAnnounceHost);
1508 Config.Announce.port = DefaultAnnouncePort;
1509 Config.Announce.file = safe_xstrdup(DefaultAnnounceFile);
1510 Config.Announce.rate = DefaultAnnounceRate;
7813c6d5 1511 Config.tcpRcvBufsz = DefaultTcpRcvBufsz;
30a4f2a8 1512 Config.Addrs.tcp_outgoing.s_addr = DefaultTcpOutgoingAddr;
1513 Config.Addrs.tcp_incoming.s_addr = DefaultTcpIncomingAddr;
1514 Config.Addrs.udp_outgoing.s_addr = DefaultUdpOutgoingAddr;
1515 Config.Addrs.udp_incoming.s_addr = DefaultUdpIncomingAddr;
844327e4 1516 Config.Addrs.client_netmask.s_addr = DefaultClientNetmask;
98ffb7e4 1517 Config.sslProxy.port = DefaultSslProxyPort;
1518 Config.sslProxy.host = safe_xstrdup(DefaultSslProxyHost);
b15e6857 1519 Config.ipcache.size = DefaultIpcacheSize;
1520 Config.ipcache.low = DefaultIpcacheLow;
1521 Config.ipcache.high = DefaultIpcacheHigh;
090089c4 1522}
1523
1524static void configDoConfigure()
1525{
1526 httpd_accel_mode = Config.Accel.prefix ? 1 : 0;
30a4f2a8 1527 sprintf(ForwardedBy, "Forwarded: by http://%s:%d/",
b6f794d6 1528 getMyHostname(), Config.Port.http);
eb2d04cd 1529 if (Config.errHtmlText == NULL)
1530 Config.errHtmlText = xstrdup("");
b1c0cc67 1531 storeConfigure();
090089c4 1532}