3 * $Id: cache_cf.cc,v 1.515 2007/08/13 17:20:51 hno Exp $
5 * DEBUG: section 3 Configuration File Parsing
6 * AUTHOR: Harvest Derived
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37 #include "authenticate.h"
38 #include "AuthConfig.h"
39 #include "AuthScheme.h"
40 #include "CacheManager.h"
43 #include "ConfigParser.h"
45 #include "StoreFileSystem.h"
54 #include "ESIParser.h"
58 #include "ICAP/ICAPConfig.h"
60 static void parse_icap_service_type(ICAPConfig
*);
61 static void dump_icap_service_type(StoreEntry
*, const char *, const ICAPConfig
&);
62 static void free_icap_service_type(ICAPConfig
*);
63 static void parse_icap_class_type(ICAPConfig
*);
64 static void dump_icap_class_type(StoreEntry
*, const char *, const ICAPConfig
&);
65 static void free_icap_class_type(ICAPConfig
*);
66 static void parse_icap_access_type(ICAPConfig
*);
67 static void dump_icap_access_type(StoreEntry
*, const char *, const ICAPConfig
&);
68 static void free_icap_access_type(ICAPConfig
*);
74 static const char *const T_SECOND_STR
= "second";
75 static const char *const T_MINUTE_STR
= "minute";
76 static const char *const T_HOUR_STR
= "hour";
77 static const char *const T_DAY_STR
= "day";
78 static const char *const T_WEEK_STR
= "week";
79 static const char *const T_FORTNIGHT_STR
= "fortnight";
80 static const char *const T_MONTH_STR
= "month";
81 static const char *const T_YEAR_STR
= "year";
82 static const char *const T_DECADE_STR
= "decade";
84 static const char *const B_BYTES_STR
= "bytes";
85 static const char *const B_KBYTES_STR
= "KB";
86 static const char *const B_MBYTES_STR
= "MB";
87 static const char *const B_GBYTES_STR
= "GB";
89 static const char *const list_sep
= ", \t\n\r";
91 static void parse_logformat(logformat
** logformat_definitions
);
92 static void parse_access_log(customlog
** customlog_definitions
);
93 static int check_null_access_log(customlog
*customlog_definitions
);
95 static void dump_logformat(StoreEntry
* entry
, const char *name
, logformat
* definitions
);
96 static void dump_access_log(StoreEntry
* entry
, const char *name
, customlog
* definitions
);
97 static void free_logformat(logformat
** definitions
);
98 static void free_access_log(customlog
** definitions
);
100 static void update_maxobjsize(void);
101 static void configDoConfigure(void);
102 static void parse_refreshpattern(refresh_t
**);
103 static int parseTimeUnits(const char *unit
);
104 static void parseTimeLine(time_t * tptr
, const char *units
);
105 static void parse_ushort(u_short
* var
);
106 static void parse_string(char **);
107 static void default_all(void);
108 static void defaults_if_none(void);
109 static int parse_line(char *);
110 static void parseBytesLine(size_t * bptr
, const char *units
);
111 static size_t parseBytesUnits(const char *unit
);
112 static void free_all(void);
113 void requirePathnameExists(const char *name
, const char *path
);
114 static OBJH dump_config
;
116 static void dump_http_header_access(StoreEntry
* entry
, const char *name
, header_mangler header
[]);
117 static void parse_http_header_access(header_mangler header
[]);
118 static void free_http_header_access(header_mangler header
[]);
119 static void dump_http_header_replace(StoreEntry
* entry
, const char *name
, header_mangler header
[]);
120 static void parse_http_header_replace(header_mangler
* header
);
121 static void free_http_header_replace(header_mangler
* header
);
123 static void parse_denyinfo(acl_deny_info_list
** var
);
124 static void dump_denyinfo(StoreEntry
* entry
, const char *name
, acl_deny_info_list
* var
);
125 static void free_denyinfo(acl_deny_info_list
** var
);
127 static void parse_sockaddr_in_list(sockaddr_in_list
**);
128 static void dump_sockaddr_in_list(StoreEntry
*, const char *, const sockaddr_in_list
*);
129 static void free_sockaddr_in_list(sockaddr_in_list
**);
131 static int check_null_sockaddr_in_list(const sockaddr_in_list
*);
132 #endif /* CURRENTLY_UNUSED */
134 static void parse_http_port_list(http_port_list
**);
135 static void dump_http_port_list(StoreEntry
*, const char *, const http_port_list
*);
136 static void free_http_port_list(http_port_list
**);
138 static void parse_https_port_list(https_port_list
**);
139 static void dump_https_port_list(StoreEntry
*, const char *, const https_port_list
*);
140 static void free_https_port_list(https_port_list
**);
142 static int check_null_https_port_list(const https_port_list
*);
145 static void parse_b_size_t(size_t * var
);
146 static void parse_b_int64_t(int64_t * var
);
149 * LegacyParser is a parser for legacy code that uses the global
150 * approach. This is static so that it is only exposed to cache_cf.
151 * Other modules needing access to a ConfigParser should have it
152 * provided to them in their parserFOO methods.
154 static ConfigParser LegacyParser
= ConfigParser();
159 LegacyParser
.destruct();
163 update_maxobjsize(void)
168 for (i
= 0; i
< Config
.cacheSwap
.n_configured
; i
++) {
169 assert (Config
.cacheSwap
.swapDirs
[i
].getRaw());
171 if (dynamic_cast<SwapDir
*>(Config
.cacheSwap
.swapDirs
[i
].getRaw())->
173 ms
= dynamic_cast<SwapDir
*>(Config
.cacheSwap
.swapDirs
[i
].getRaw())->max_objsize
;
175 store_maxobjsize
= ms
;
179 SetConfigFilename(char const *file_name
, bool is_pipe
)
181 cfg_filename
= file_name
;
186 cfg_filename
= file_name
+ 1;
187 else if ((token
= strrchr(cfg_filename
, '/')))
188 cfg_filename
= token
+ 1;
192 skip_ws(const char* s
)
201 parseConfigFile(const char *file_name
, CacheManager
& manager
)
205 char *tmp_line
= NULL
;
206 int tmp_line_len
= 0;
212 if (file_name
[0] == '!' || file_name
[0] == '|') {
213 fp
= popen(file_name
+ 1, "r");
216 fp
= fopen(file_name
, "r");
220 fatalf("Unable to open configuration file: %s: %s",
221 file_name
, xstrerror());
225 setmode(fileno(fp
), O_TEXT
);
229 SetConfigFilename(file_name
, bool(is_pipe
));
231 memset(config_input_line
, '\0', BUFSIZ
);
235 while (fgets(config_input_line
, BUFSIZ
, fp
)) {
238 if ((token
= strchr(config_input_line
, '\n')))
241 if ((token
= strchr(config_input_line
, '\r')))
244 if (strncmp(config_input_line
, "#line ", 6) == 0) {
245 static char new_file_name
[1024];
247 static char new_lineno
;
248 token
= config_input_line
+ 6;
249 new_lineno
= strtol(token
, &file
, 0) - 1;
252 continue; /* Not a valid #line directive, may be a comment */
254 while (*file
&& xisspace((unsigned char) *file
))
259 continue; /* Not a valid #line directive, may be a comment */
261 xstrncpy(new_file_name
, file
+ 1, sizeof(new_file_name
));
263 if ((token
= strchr(new_file_name
, '"')))
266 cfg_filename
= new_file_name
;
268 #if PROBABLY_NOT_WANTED_HERE
270 SetConfigFilename(cfg_filename
, false);
276 config_lineno
= new_lineno
;
279 if (config_input_line
[0] == '#')
282 if (config_input_line
[0] == '\0')
285 const char* append
= tmp_line_len
? skip_ws(config_input_line
) : config_input_line
;
287 size_t append_len
= strlen(append
);
289 tmp_line
= (char*)xrealloc(tmp_line
, tmp_line_len
+ append_len
+ 1);
291 strcpy(tmp_line
+ tmp_line_len
, append
);
293 tmp_line_len
+= append_len
;
295 if (tmp_line
[tmp_line_len
-1] == '\\') {
296 debugs(3, 5, "parseConfigFile: tmp_line='" << tmp_line
<< "'");
297 tmp_line
[--tmp_line_len
] = '\0';
301 debugs(3, 5, "Processing: '" << tmp_line
<< "'");
303 if (!parse_line(tmp_line
)) {
304 debugs(3, 0, "parseConfigFile: '" << cfg_filename
<< "' line " <<
305 config_lineno
<< " unrecognized: '" << config_input_line
<< "'");
315 int ret
= pclose(fp
);
318 fatalf("parseConfigFile: '%s' failed with exit code %d\n", file_name
, ret
);
326 * We must call configDoConfigure() before leave_suid() because
327 * configDoConfigure() is where we turn username strings into
332 if (!Config
.chroot_dir
) {
334 _db_init(Config
.Log
.log
, Config
.debugOptions
);
338 if (opt_send_signal
== -1) {
339 manager
.registerAction("config",
340 "Current Squid Configuration",
349 configDoConfigure(void)
351 memset(&Config2
, '\0', sizeof(SquidConfig2
));
352 /* init memory as early as possible */
356 if (Config
.cacheSwap
.swapDirs
== NULL
)
357 fatal("No cache_dir's specified in config file");
359 if (0 == Store::Root().maxSize())
360 /* people might want a zero-sized cache on purpose */
362 else if (Store::Root().maxSize() < (Config
.memMaxSize
>> 10))
363 /* This is bogus. folk with NULL caches will want this */
364 debugs(3, 0, "WARNING cache_mem is larger than total disk cache space!");
366 if (Config
.Announce
.period
> 0) {
367 Config
.onoff
.announce
= 1;
368 } else if (Config
.Announce
.period
< 1) {
369 Config
.Announce
.period
= 86400 * 365; /* one year */
370 Config
.onoff
.announce
= 0;
373 if (Config
.onoff
.httpd_suppress_version_string
)
374 visible_appname_string
= (char *)appname_string
;
376 visible_appname_string
= (char *)full_appname_string
;
380 if (Config
.dnsChildren
< 1)
381 fatal("No dnsservers allocated");
385 if (Config
.Program
.redirect
) {
386 if (Config
.redirectChildren
< 1) {
387 Config
.redirectChildren
= 0;
388 wordlistDestroy(&Config
.Program
.redirect
);
392 if (Config
.appendDomain
)
393 if (*Config
.appendDomain
!= '.')
394 fatal("append_domain must begin with a '.'");
396 if (Config
.errHtmlText
== NULL
)
397 Config
.errHtmlText
= xstrdup(null_string
);
401 snprintf(ThisCache
, sizeof(ThisCache
), "%s (%s)",
403 visible_appname_string
);
406 * the extra space is for loop detection in client_side.c -- we search
407 * for substrings in the Via header.
409 snprintf(ThisCache2
, sizeof(ThisCache
), " %s (%s)",
411 visible_appname_string
);
413 if (!Config
.udpMaxHitObjsz
|| Config
.udpMaxHitObjsz
> SQUID_UDP_SO_SNDBUF
)
414 Config
.udpMaxHitObjsz
= SQUID_UDP_SO_SNDBUF
;
416 if (Config
.appendDomain
)
417 Config
.appendDomainLen
= strlen(Config
.appendDomain
);
419 Config
.appendDomainLen
= 0;
421 safe_free(debug_options
)
422 debug_options
= xstrdup(Config
.debugOptions
);
424 if (Config
.retry
.maxtries
> 10)
425 fatal("maximum_single_addr_tries cannot be larger than 10");
427 if (Config
.retry
.maxtries
< 1) {
428 debugs(3, 0, "WARNING: resetting 'maximum_single_addr_tries to 1");
429 Config
.retry
.maxtries
= 1;
432 requirePathnameExists("MIME Config Table", Config
.mimeTablePathname
);
435 requirePathnameExists("cache_dns_program", Config
.Program
.dnsserver
);
439 requirePathnameExists("unlinkd_program", Config
.Program
.unlinkd
);
442 if (Config
.Program
.redirect
)
443 requirePathnameExists("redirect_program", Config
.Program
.redirect
->key
);
445 requirePathnameExists("Icon Directory", Config
.icons
.directory
);
447 requirePathnameExists("Error Directory", Config
.errorDirectory
);
454 for (R
= Config
.Refresh
; R
; R
= R
->next
)
456 if (!R
->flags
.override_expire
)
459 debugs(22, 1, "WARNING: use of 'override-expire' in 'refresh_pattern' violates HTTP");
464 for (R
= Config
.Refresh
; R
; R
= R
->next
)
466 if (!R
->flags
.override_lastmod
)
469 debugs(22, 1, "WARNING: use of 'override-lastmod' in 'refresh_pattern' violates HTTP");
474 for (R
= Config
.Refresh
; R
; R
= R
->next
)
476 if (!R
->flags
.reload_into_ims
)
479 debugs(22, 1, "WARNING: use of 'reload-into-ims' in 'refresh_pattern' violates HTTP");
484 for (R
= Config
.Refresh
; R
; R
= R
->next
)
486 if (!R
->flags
.ignore_reload
)
489 debugs(22, 1, "WARNING: use of 'ignore-reload' in 'refresh_pattern' violates HTTP");
494 for (R
= Config
.Refresh
; R
; R
= R
->next
)
496 if (!R
->flags
.ignore_no_cache
)
499 debugs(22, 1, "WARNING: use of 'ignore-no-cache' in 'refresh_pattern' violates HTTP");
504 for (R
= Config
.Refresh
; R
; R
= R
->next
)
506 if (!R
->flags
.ignore_no_store
)
509 debugs(22, 1, "WARNING: use of 'ignore-no-store' in 'refresh_pattern' violates HTTP");
514 for (R
= Config
.Refresh
; R
; R
= R
->next
)
516 if (!R
->flags
.ignore_private
)
519 debugs(22, 1, "WARNING: use of 'ignore-private' in 'refresh_pattern' violates HTTP");
524 for (R
= Config
.Refresh
; R
; R
= R
->next
)
526 if (!R
->flags
.ignore_auth
)
529 debugs(22, 1, "WARNING: use of 'ignore-auth' in 'refresh_pattern' violates HTTP");
537 Config
.onoff
.via
= 1;
540 if (!Config
.onoff
.via
)
541 debugs(22, 1, "WARNING: HTTP requires the use of Via");
545 if (aclPurgeMethodInUse(Config
.accessList
.http
))
546 Config2
.onoff
.enable_purge
= 1;
548 Config2
.onoff
.mangle_request_headers
= httpReqHdrManglersConfigured();
550 if (geteuid() == 0) {
551 if (NULL
!= Config
.effectiveUser
) {
553 struct passwd
*pwd
= getpwnam(Config
.effectiveUser
);
557 * Andres Kroonmaa <andre@online.ee>:
558 * Some getpwnam() implementations (Solaris?) require
559 * an available FD < 256 for opening a FILE* to the
562 * This should be safe at startup, but might still fail
563 * during reconfigure.
565 fatalf("getpwnam failed to find userid for effective user '%s'",
566 Config
.effectiveUser
);
568 Config2
.effectiveUserID
= pwd
->pw_uid
;
570 Config2
.effectiveGroupID
= pwd
->pw_gid
;
574 if (pwd
->pw_dir
&& *pwd
->pw_dir
) {
576 char *env_str
= (char *)xcalloc((len
= strlen(pwd
->pw_dir
) + 6), 1);
577 snprintf(env_str
, len
, "HOME=%s", pwd
->pw_dir
);
585 Config2
.effectiveUserID
= geteuid();
586 Config2
.effectiveGroupID
= getegid();
589 if (NULL
!= Config
.effectiveGroup
) {
591 struct group
*grp
= getgrnam(Config
.effectiveGroup
);
594 fatalf("getgrnam failed to find groupid for effective group '%s'",
595 Config
.effectiveGroup
);
597 Config2
.effectiveGroupID
= grp
->gr_gid
;
600 HttpRequestMethod::Configure(Config
);
603 debugs(3, 1, "Initializing https proxy context");
605 Config
.ssl_client
.sslContext
= sslCreateClientContext(Config
.ssl_client
.cert
, Config
.ssl_client
.key
, Config
.ssl_client
.version
, Config
.ssl_client
.cipher
, Config
.ssl_client
.options
, Config
.ssl_client
.flags
, Config
.ssl_client
.cafile
, Config
.ssl_client
.capath
, Config
.ssl_client
.crlfile
);
611 for (p
= Config
.peers
; p
!= NULL
; p
= p
->next
) {
613 debugs(3, 1, "Initializing cache_peer " << p
->name
<< " SSL context");
614 p
->sslContext
= sslCreateClientContext(p
->sslcert
, p
->sslkey
, p
->sslversion
, p
->sslcipher
, p
->ssloptions
, p
->sslflags
, p
->sslcafile
, p
->sslcapath
, p
->sslcrlfile
);
623 for (s
= Config
.Sockaddr
.https
; s
!= NULL
; s
= (https_port_list
*) s
->http
.next
) {
624 debugs(3, 1, "Initializing https_port " <<
625 inet_ntoa(s
->http
.s
.sin_addr
) << ":" <<
626 ntohs(s
->http
.s
.sin_port
) << " SSL context");
628 s
->sslContext
= sslCreateServerContext(s
->cert
, s
->key
, s
->version
, s
->cipher
, s
->options
, s
->sslflags
, s
->clientca
, s
->cafile
, s
->capath
, s
->crlfile
, s
->dhfile
, s
->sslcontext
);
635 /* Parse a time specification from the config file. Store the
636 * result in 'tptr', after converting it to 'units' */
638 parseTimeLine(time_t * tptr
, const char *units
)
645 if ((u
= parseTimeUnits(units
)) == 0)
648 if ((token
= strtok(NULL
, w_space
)) == NULL
)
653 m
= u
; /* default to 'units' if none specified */
657 else if ((token
= strtok(NULL
, w_space
)) == NULL
)
658 debugs(3, 0, "WARNING: No units on '" <<
659 config_input_line
<< "', assuming " <<
661 else if ((m
= parseTimeUnits(token
)) == 0)
664 *tptr
= static_cast<time_t> (m
* d
/ u
);
668 parseTimeUnits(const char *unit
)
670 if (!strncasecmp(unit
, T_SECOND_STR
, strlen(T_SECOND_STR
)))
673 if (!strncasecmp(unit
, T_MINUTE_STR
, strlen(T_MINUTE_STR
)))
676 if (!strncasecmp(unit
, T_HOUR_STR
, strlen(T_HOUR_STR
)))
679 if (!strncasecmp(unit
, T_DAY_STR
, strlen(T_DAY_STR
)))
682 if (!strncasecmp(unit
, T_WEEK_STR
, strlen(T_WEEK_STR
)))
685 if (!strncasecmp(unit
, T_FORTNIGHT_STR
, strlen(T_FORTNIGHT_STR
)))
688 if (!strncasecmp(unit
, T_MONTH_STR
, strlen(T_MONTH_STR
)))
691 if (!strncasecmp(unit
, T_YEAR_STR
, strlen(T_YEAR_STR
)))
692 return static_cast<int>(86400 * 365.2522);
694 if (!strncasecmp(unit
, T_DECADE_STR
, strlen(T_DECADE_STR
)))
695 return static_cast<int>(86400 * 365.2522 * 10);
697 debugs(3, 1, "parseTimeUnits: unknown time unit '" << unit
<< "'");
703 parseBytesLine64(int64_t * bptr
, const char *units
)
710 if ((u
= parseBytesUnits(units
)) == 0)
713 if ((token
= strtok(NULL
, w_space
)) == NULL
)
716 if (strcmp(token
, "none") == 0 || strcmp(token
, "-1") == 0) {
717 *bptr
= static_cast<size_t>(-1);
723 m
= u
; /* default to 'units' if none specified */
727 else if ((token
= strtok(NULL
, w_space
)) == NULL
)
728 debugs(3, 0, "WARNING: No units on '" <<
729 config_input_line
<< "', assuming " <<
731 else if ((m
= parseBytesUnits(token
)) == 0)
734 *bptr
= static_cast<int64_t>(m
* d
/ u
);
736 if (static_cast<double>(*bptr
) * 2 != m
* d
/ u
* 2)
742 parseBytesLine(size_t * bptr
, const char *units
)
749 if ((u
= parseBytesUnits(units
)) == 0)
752 if ((token
= strtok(NULL
, w_space
)) == NULL
)
755 if (strcmp(token
, "none") == 0 || strcmp(token
, "-1") == 0) {
756 *bptr
= static_cast<size_t>(-1);
762 m
= u
; /* default to 'units' if none specified */
766 else if ((token
= strtok(NULL
, w_space
)) == NULL
)
767 debugs(3, 0, "WARNING: No units on '" <<
768 config_input_line
<< "', assuming " <<
770 else if ((m
= parseBytesUnits(token
)) == 0)
773 *bptr
= static_cast<size_t>(m
* d
/ u
);
775 if (static_cast<double>(*bptr
) * 2 != m
* d
/ u
* 2)
780 parseBytesUnits(const char *unit
)
782 if (!strncasecmp(unit
, B_BYTES_STR
, strlen(B_BYTES_STR
)))
785 if (!strncasecmp(unit
, B_KBYTES_STR
, strlen(B_KBYTES_STR
)))
788 if (!strncasecmp(unit
, B_MBYTES_STR
, strlen(B_MBYTES_STR
)))
791 if (!strncasecmp(unit
, B_GBYTES_STR
, strlen(B_GBYTES_STR
)))
794 debugs(3, 1, "parseBytesUnits: unknown bytes unit '" << unit
<< "'");
799 /*****************************************************************************
801 *****************************************************************************/
804 dump_acl(StoreEntry
* entry
, const char *name
, ACL
* ae
)
810 debugs(3, 3, "dump_acl: " << name
<< " " << ae
->name
);
811 storeAppendPrintf(entry
, "%s %s %s ",
818 debugs(3, 3, "dump_acl: " << name
<< " " << ae
->name
<< " " << v
->key
);
819 storeAppendPrintf(entry
, "%s ", v
->key
);
823 storeAppendPrintf(entry
, "\n");
832 ACL::ParseAclLine(LegacyParser
, ae
);
842 dump_acl_list(StoreEntry
* entry
, acl_list
* head
)
846 for (l
= head
; l
; l
= l
->next
) {
847 storeAppendPrintf(entry
, " %s%s",
848 l
->op
? null_string
: "!",
854 dump_acl_access(StoreEntry
* entry
, const char *name
, acl_access
* head
)
858 for (l
= head
; l
; l
= l
->next
) {
859 storeAppendPrintf(entry
, "%s %s",
861 l
->allow
? "Allow" : "Deny");
862 dump_acl_list(entry
, l
->aclList
);
863 storeAppendPrintf(entry
, "\n");
868 parse_acl_access(acl_access
** head
)
870 aclParseAccessLine(LegacyParser
, head
);
874 free_acl_access(acl_access
** head
)
876 aclDestroyAccessList(head
);
881 dump_address(StoreEntry
* entry
, const char *name
, struct IN_ADDR addr
)
883 storeAppendPrintf(entry
, "%s %s\n", name
, inet_ntoa(addr
));
888 parse_address(struct IN_ADDR
*addr
)
891 const struct hostent
*hp
;
892 char *token
= strtok(NULL
, w_space
);
897 if (safe_inet_addr(token
, addr
) == 1)
899 else if ((hp
= gethostbyname(token
))) /* dont use ipcache */
900 *addr
= inaddrFromHostent(hp
);
907 free_address(struct IN_ADDR
*addr
)
910 memset(addr
, '\0', sizeof(struct IN_ADDR
));
913 CBDATA_TYPE(acl_address
);
916 dump_acl_address(StoreEntry
* entry
, const char *name
, acl_address
* head
)
920 for (l
= head
; l
; l
= l
->next
) {
921 if (l
->addr
.s_addr
!= INADDR_ANY
)
922 storeAppendPrintf(entry
, "%s %s", name
, inet_ntoa(l
->addr
));
924 storeAppendPrintf(entry
, "%s autoselect", name
);
926 dump_acl_list(entry
, l
->aclList
);
928 storeAppendPrintf(entry
, "\n");
933 freed_acl_address(void *data
)
935 acl_address
*l
= static_cast<acl_address
*>(data
);
936 aclDestroyAclList(&l
->aclList
);
940 parse_acl_address(acl_address
** head
)
943 acl_address
**tail
= head
; /* sane name below */
944 CBDATA_INIT_TYPE_FREECB(acl_address
, freed_acl_address
);
945 l
= cbdataAlloc(acl_address
);
946 parse_address(&l
->addr
);
947 aclParseAclList(LegacyParser
, &l
->aclList
);
950 tail
= &(*tail
)->next
;
956 free_acl_address(acl_address
** head
)
959 acl_address
*l
= *head
;
965 CBDATA_TYPE(acl_tos
);
968 dump_acl_tos(StoreEntry
* entry
, const char *name
, acl_tos
* head
)
972 for (l
= head
; l
; l
= l
->next
) {
974 storeAppendPrintf(entry
, "%s 0x%02X", name
, l
->tos
);
976 storeAppendPrintf(entry
, "%s none", name
);
978 dump_acl_list(entry
, l
->aclList
);
980 storeAppendPrintf(entry
, "\n");
985 freed_acl_tos(void *data
)
987 acl_tos
*l
= static_cast<acl_tos
*>(data
);
988 aclDestroyAclList(&l
->aclList
);
992 parse_acl_tos(acl_tos
** head
)
995 acl_tos
**tail
= head
; /* sane name below */
998 char *token
= strtok(NULL
, w_space
);
1003 if (sscanf(token
, "0x%x%c", &tos
, &junk
) != 1)
1006 if (tos
< 0 || tos
> 255)
1009 CBDATA_INIT_TYPE_FREECB(acl_tos
, freed_acl_tos
);
1011 l
= cbdataAlloc(acl_tos
);
1015 aclParseAclList(LegacyParser
, &l
->aclList
);
1018 tail
= &(*tail
)->next
;
1024 free_acl_tos(acl_tos
** head
)
1034 CBDATA_TYPE(acl_size_t
);
1037 dump_acl_b_size_t(StoreEntry
* entry
, const char *name
, acl_size_t
* head
)
1041 for (l
= head
; l
; l
= l
->next
) {
1042 if (l
->size
!= static_cast<size_t>(-1))
1043 storeAppendPrintf(entry
, "%s %d %s\n", name
, (int) l
->size
, B_BYTES_STR
);
1045 storeAppendPrintf(entry
, "%s none", name
);
1047 dump_acl_list(entry
, l
->aclList
);
1049 storeAppendPrintf(entry
, "\n");
1054 freed_acl_b_size_t(void *data
)
1056 acl_size_t
*l
= static_cast<acl_size_t
*>(data
);
1057 aclDestroyAclList(&l
->aclList
);
1061 parse_acl_b_size_t(acl_size_t
** head
)
1064 acl_size_t
**tail
= head
; /* sane name below */
1066 CBDATA_INIT_TYPE_FREECB(acl_size_t
, freed_acl_b_size_t
);
1068 l
= cbdataAlloc(acl_size_t
);
1070 parse_b_int64_t(&l
->size
);
1072 aclParseAclList(LegacyParser
, &l
->aclList
);
1075 tail
= &(*tail
)->next
;
1081 free_acl_b_size_t(acl_size_t
** head
)
1084 acl_size_t
*l
= *head
;
1093 #include "DelayPools.h"
1094 #include "DelayConfig.h"
1095 /* do nothing - free_delay_pool_count is the magic free function.
1096 * this is why delay_pool_count isn't just marked TYPE: ushort
1098 #define free_delay_pool_class(X)
1099 #define free_delay_pool_access(X)
1100 #define free_delay_pool_rates(X)
1101 #define dump_delay_pool_class(X, Y, Z)
1102 #define dump_delay_pool_access(X, Y, Z)
1103 #define dump_delay_pool_rates(X, Y, Z)
1106 free_delay_pool_count(DelayConfig
* cfg
)
1108 cfg
->freePoolCount();
1112 dump_delay_pool_count(StoreEntry
* entry
, const char *name
, DelayConfig
&cfg
)
1114 cfg
.dumpPoolCount (entry
, name
);
1118 parse_delay_pool_count(DelayConfig
* cfg
)
1120 cfg
->parsePoolCount();
1124 parse_delay_pool_class(DelayConfig
* cfg
)
1126 cfg
->parsePoolClass();
1130 parse_delay_pool_rates(DelayConfig
* cfg
)
1132 cfg
->parsePoolRates();
1136 parse_delay_pool_access(DelayConfig
* cfg
)
1138 cfg
->parsePoolAccess(LegacyParser
);
1145 dump_http_header_access(StoreEntry
* entry
, const char *name
, header_mangler header
[])
1149 for (i
= 0; i
< HDR_ENUM_END
; i
++) {
1150 if (header
[i
].access_list
!= NULL
) {
1151 storeAppendPrintf(entry
, "%s ", name
);
1152 dump_acl_access(entry
, httpHeaderNameById(i
),
1153 header
[i
].access_list
);
1159 parse_http_header_access(header_mangler header
[])
1164 if ((t
= strtok(NULL
, w_space
)) == NULL
) {
1165 debugs(3, 0, "" << cfg_filename
<< " line " << config_lineno
<< ": " << config_input_line
);
1166 debugs(3, 0, "parse_http_header_access: missing header name.");
1170 /* Now lookup index of header. */
1171 id
= httpHeaderIdByNameDef(t
, strlen(t
));
1173 if (strcmp(t
, "All") == 0)
1175 else if (strcmp(t
, "Other") == 0)
1177 else if (id
== -1) {
1178 debugs(3, 0, "" << cfg_filename
<< " line " << config_lineno
<< ": " << config_input_line
);
1179 debugs(3, 0, "parse_http_header_access: unknown header name '" << t
<< "'");
1183 if (id
!= HDR_ENUM_END
) {
1184 parse_acl_access(&header
[id
].access_list
);
1186 char *next_string
= t
+ strlen(t
) - 1;
1188 *(next_string
+ 1) = ' ';
1190 for (i
= 0; i
< HDR_ENUM_END
; i
++) {
1191 char *new_string
= xstrdup(next_string
);
1192 strtok(new_string
, w_space
);
1193 parse_acl_access(&header
[i
].access_list
);
1194 safe_free(new_string
);
1200 free_http_header_access(header_mangler header
[])
1204 for (i
= 0; i
< HDR_ENUM_END
; i
++) {
1205 free_acl_access(&header
[i
].access_list
);
1210 dump_http_header_replace(StoreEntry
* entry
, const char *name
, header_mangler
1215 for (i
= 0; i
< HDR_ENUM_END
; i
++) {
1216 if (NULL
== header
[i
].replacement
)
1219 storeAppendPrintf(entry
, "%s %s %s\n", name
, httpHeaderNameById(i
),
1220 header
[i
].replacement
);
1225 parse_http_header_replace(header_mangler header
[])
1230 if ((t
= strtok(NULL
, w_space
)) == NULL
) {
1231 debugs(3, 0, "" << cfg_filename
<< " line " << config_lineno
<< ": " << config_input_line
);
1232 debugs(3, 0, "parse_http_header_replace: missing header name.");
1236 /* Now lookup index of header. */
1237 id
= httpHeaderIdByNameDef(t
, strlen(t
));
1239 if (strcmp(t
, "All") == 0)
1241 else if (strcmp(t
, "Other") == 0)
1243 else if (id
== -1) {
1244 debugs(3, 0, "" << cfg_filename
<< " line " << config_lineno
<< ": " << config_input_line
);
1245 debugs(3, 0, "parse_http_header_replace: unknown header name " << t
<< ".");
1250 if (id
!= HDR_ENUM_END
) {
1251 if (header
[id
].replacement
!= NULL
)
1252 safe_free(header
[id
].replacement
);
1254 header
[id
].replacement
= xstrdup(t
+ strlen(t
) + 1);
1256 for (i
= 0; i
< HDR_ENUM_END
; i
++) {
1257 if (header
[i
].replacement
!= NULL
)
1258 safe_free(header
[i
].replacement
);
1260 header
[i
].replacement
= xstrdup(t
+ strlen(t
) + 1);
1266 free_http_header_replace(header_mangler header
[])
1270 for (i
= 0; i
< HDR_ENUM_END
; i
++) {
1271 if (header
[i
].replacement
!= NULL
)
1272 safe_free(header
[i
].replacement
);
1279 dump_cachedir(StoreEntry
* entry
, const char *name
, _SquidConfig::_cacheSwap swap
)
1285 for (i
= 0; i
< swap
.n_configured
; i
++) {
1286 s
= dynamic_cast<SwapDir
*>(swap
.swapDirs
[i
].getRaw());
1288 storeAppendPrintf(entry
, "%s %s %s", name
, s
->type(), s
->path
);
1290 storeAppendPrintf(entry
, "\n");
1295 check_null_cachedir(_SquidConfig::_cacheSwap swap
)
1297 return swap
.swapDirs
== NULL
;
1301 check_null_string(char *s
)
1307 parse_authparam(authConfig
* config
)
1312 if ((type_str
= strtok(NULL
, w_space
)) == NULL
)
1315 if ((param_str
= strtok(NULL
, w_space
)) == NULL
)
1318 /* find a configuration for the scheme */
1319 AuthConfig
*scheme
= AuthConfig::Find (type_str
);
1321 if (scheme
== NULL
) {
1322 /* Create a configuration */
1323 AuthScheme
*theScheme
;
1325 if ((theScheme
= AuthScheme::Find(type_str
)) == NULL
) {
1326 debugs(3, 0, "Parsing Config File: Unknown authentication scheme '" << type_str
<< "'.");
1330 config
->push_back(theScheme
->createConfig());
1331 scheme
= config
->back();
1335 scheme
->parse(scheme
, config
->size(), param_str
);
1339 free_authparam(authConfig
* cfg
)
1342 /* DON'T FREE THESE FOR RECONFIGURE */
1347 while (cfg
->size()) {
1348 scheme
= cfg
->pop_back();
1354 dump_authparam(StoreEntry
* entry
, const char *name
, authConfig cfg
)
1356 for (authConfig::iterator i
= cfg
.begin(); i
!= cfg
.end(); ++i
)
1357 (*i
)->dump(entry
, name
, (*i
));
1360 /* TODO: just return the object, the # is irrelevant */
1362 find_fstype(char *type
)
1364 for (size_t i
= 0; i
< StoreFileSystem::FileSystems().size(); ++i
)
1365 if (strcasecmp(type
, StoreFileSystem::FileSystems().items
[i
]->type()) == 0)
1372 parse_cachedir(_SquidConfig::_cacheSwap
* swap
)
1376 RefCount
<SwapDir
> sd
;
1380 if ((type_str
= strtok(NULL
, w_space
)) == NULL
)
1383 if ((path_str
= strtok(NULL
, w_space
)) == NULL
)
1386 fs
= find_fstype(type_str
);
1391 /* reconfigure existing dir */
1393 for (i
= 0; i
< swap
->n_configured
; i
++) {
1394 assert (swap
->swapDirs
[i
].getRaw());
1396 if ((strcasecmp(path_str
, dynamic_cast<SwapDir
*>(swap
->swapDirs
[i
].getRaw())->path
)
1398 /* this is specific to on-fs Stores. The right
1399 * way to handle this is probably to have a mapping
1400 * from paths to stores, and have on-fs stores
1401 * register with that, and lookip in that in their
1402 * own setup logic. RBC 20041225. TODO.
1405 sd
= dynamic_cast<SwapDir
*>(swap
->swapDirs
[i
].getRaw());
1407 if (sd
->type() != StoreFileSystem::FileSystems().items
[fs
]->type()) {
1408 debugs(3, 0, "ERROR: Can't change type of existing cache_dir " <<
1409 sd
->type() << " " << sd
->path
<< " to " << type_str
<< ". Restart required");
1413 sd
->reconfigure (i
, path_str
);
1415 update_maxobjsize();
1422 assert(swap
->n_configured
< 63); /* 7 bits, signed */
1424 allocate_new_swapdir(swap
);
1426 swap
->swapDirs
[swap
->n_configured
] = StoreFileSystem::FileSystems().items
[fs
]->createSwapDir();
1428 sd
= dynamic_cast<SwapDir
*>(swap
->swapDirs
[swap
->n_configured
].getRaw());
1430 /* parse the FS parameters and options */
1431 sd
->parse(swap
->n_configured
, path_str
);
1433 ++swap
->n_configured
;
1435 /* Update the max object size */
1436 update_maxobjsize();
1440 peer_type_str(const peer_t type
)
1442 const char * result
;
1454 case PEER_MULTICAST
:
1455 result
= "multicast";
1467 dump_peer(StoreEntry
* entry
, const char *name
, peer
* p
)
1471 LOCAL_ARRAY(char, xname
, 128);
1474 storeAppendPrintf(entry
, "%s %s %s %d %d",
1480 dump_peer_options(entry
, p
);
1482 for (d
= p
->peer_domain
; d
; d
= d
->next
) {
1483 storeAppendPrintf(entry
, "cache_peer_domain %s %s%s\n",
1485 d
->do_ping
? null_string
: "!",
1490 snprintf(xname
, 128, "cache_peer_access %s", p
->name
);
1491 dump_acl_access(entry
, xname
, p
->access
);
1494 for (t
= p
->typelist
; t
; t
= t
->next
) {
1495 storeAppendPrintf(entry
, "neighbor_type_domain %s %s %s\n",
1497 peer_type_str(t
->type
),
1506 parse_peer(peer
** head
)
1510 CBDATA_INIT_TYPE_FREECB(peer
, peerDestroy
);
1511 p
= cbdataAlloc(peer
);
1512 p
->http_port
= CACHE_HTTP_PORT
;
1513 p
->icp
.port
= CACHE_ICP_PORT
;
1516 p
->stats
.logged_state
= PEER_ALIVE
;
1518 if ((token
= strtok(NULL
, w_space
)) == NULL
)
1521 p
->host
= xstrdup(token
);
1523 p
->name
= xstrdup(token
);
1525 if ((token
= strtok(NULL
, w_space
)) == NULL
)
1528 p
->type
= parseNeighborType(token
);
1530 if (p
->type
== PEER_MULTICAST
) {
1531 p
->options
.no_digest
= 1;
1532 p
->options
.no_netdb_exchange
= 1;
1535 p
->http_port
= GetShort();
1540 p
->icp
.port
= GetShort();
1542 while ((token
= strtok(NULL
, w_space
))) {
1543 if (!strcasecmp(token
, "proxy-only")) {
1544 p
->options
.proxy_only
= 1;
1545 } else if (!strcasecmp(token
, "no-query")) {
1546 p
->options
.no_query
= 1;
1547 } else if (!strcasecmp(token
, "background-ping")) {
1548 p
->options
.background_ping
= 1;
1549 } else if (!strcasecmp(token
, "no-digest")) {
1550 p
->options
.no_digest
= 1;
1551 } else if (!strcasecmp(token
, "multicast-responder")) {
1552 p
->options
.mcast_responder
= 1;
1553 } else if (!strncasecmp(token
, "weight=", 7)) {
1554 p
->weight
= xatoi(token
+ 7);
1555 } else if (!strncasecmp(token
, "basetime=", 9)) {
1556 p
->basetime
= xatoi(token
+ 9);
1557 } else if (!strcasecmp(token
, "closest-only")) {
1558 p
->options
.closest_only
= 1;
1559 } else if (!strncasecmp(token
, "ttl=", 4)) {
1560 p
->mcast
.ttl
= xatoi(token
+ 4);
1562 if (p
->mcast
.ttl
< 0)
1565 if (p
->mcast
.ttl
> 128)
1567 } else if (!strcasecmp(token
, "default")) {
1568 p
->options
.default_parent
= 1;
1569 } else if (!strcasecmp(token
, "round-robin")) {
1570 p
->options
.roundrobin
= 1;
1571 } else if (!strcasecmp(token
, "weighted-round-robin")) {
1572 p
->options
.weighted_roundrobin
= 1;
1575 } else if (!strcasecmp(token
, "htcp")) {
1576 p
->options
.htcp
= 1;
1577 } else if (!strcasecmp(token
, "htcp-oldsquid")) {
1578 p
->options
.htcp
= 1;
1579 p
->options
.htcp_oldsquid
= 1;
1582 } else if (!strcasecmp(token
, "no-netdb-exchange")) {
1583 p
->options
.no_netdb_exchange
= 1;
1586 } else if (!strcasecmp(token
, "carp")) {
1587 if (p
->type
!= PEER_PARENT
)
1588 fatalf("parse_peer: non-parent carp peer %s/%d\n", p
->host
, p
->http_port
);
1590 p
->options
.carp
= 1;
1595 } else if (!strcasecmp(token
, "no-delay")) {
1596 p
->options
.no_delay
= 1;
1599 } else if (!strncasecmp(token
, "login=", 6)) {
1600 p
->login
= xstrdup(token
+ 6);
1601 rfc1738_unescape(p
->login
);
1602 } else if (!strncasecmp(token
, "connect-timeout=", 16)) {
1603 p
->connect_timeout
= xatoi(token
+ 16);
1604 #if USE_CACHE_DIGESTS
1606 } else if (!strncasecmp(token
, "digest-url=", 11)) {
1607 p
->digest_url
= xstrdup(token
+ 11);
1610 } else if (!strcasecmp(token
, "allow-miss")) {
1611 p
->options
.allow_miss
= 1;
1612 } else if (!strncasecmp(token
, "max-conn=", 9)) {
1613 p
->max_conn
= xatoi(token
+ 9);
1614 } else if (!strcasecmp(token
, "originserver")) {
1615 p
->options
.originserver
= 1;
1616 } else if (!strncasecmp(token
, "name=", 5)) {
1620 p
->name
= xstrdup(token
+ 5);
1621 } else if (!strncasecmp(token
, "forceddomain=", 13)) {
1622 safe_free(p
->domain
);
1625 p
->domain
= xstrdup(token
+ 13);
1629 } else if (strcmp(token
, "ssl") == 0) {
1631 } else if (strncmp(token
, "sslcert=", 8) == 0) {
1632 safe_free(p
->sslcert
);
1633 p
->sslcert
= xstrdup(token
+ 8);
1634 } else if (strncmp(token
, "sslkey=", 7) == 0) {
1635 safe_free(p
->sslkey
);
1636 p
->sslkey
= xstrdup(token
+ 7);
1637 } else if (strncmp(token
, "sslversion=", 11) == 0) {
1638 p
->sslversion
= atoi(token
+ 11);
1639 } else if (strncmp(token
, "ssloptions=", 11) == 0) {
1640 safe_free(p
->ssloptions
);
1641 p
->ssloptions
= xstrdup(token
+ 11);
1642 } else if (strncmp(token
, "sslcipher=", 10) == 0) {
1643 safe_free(p
->sslcipher
);
1644 p
->sslcipher
= xstrdup(token
+ 10);
1645 } else if (strncmp(token
, "sslcafile=", 10) == 0) {
1646 safe_free(p
->sslcafile
);
1647 p
->sslcafile
= xstrdup(token
+ 10);
1648 } else if (strncmp(token
, "sslcapath=", 10) == 0) {
1649 safe_free(p
->sslcapath
);
1650 p
->sslcapath
= xstrdup(token
+ 10);
1651 } else if (strncmp(token
, "sslcrlfile=", 11) == 0) {
1652 safe_free(p
->sslcrlfile
);
1653 p
->sslcapath
= xstrdup(token
+ 10);
1654 } else if (strncmp(token
, "sslflags=", 9) == 0) {
1655 safe_free(p
->sslflags
);
1656 p
->sslflags
= xstrdup(token
+ 9);
1657 } else if (strncmp(token
, "ssldomain=", 10) == 0) {
1658 safe_free(p
->ssldomain
);
1659 p
->ssldomain
= xstrdup(token
+ 10);
1662 } else if (strcmp(token
, "front-end-https") == 0) {
1663 p
->front_end_https
= 1;
1664 } else if (strcmp(token
, "front-end-https=on") == 0) {
1665 p
->front_end_https
= 1;
1666 } else if (strcmp(token
, "front-end-https=auto") == 0) {
1667 p
->front_end_https
= 2;
1669 debugs(3, 0, "parse_peer: token='" << token
<< "'");
1674 if (peerFindByName(p
->name
))
1675 fatalf("ERROR: cache_peer %s specified twice\n", p
->name
);
1680 p
->icp
.version
= ICP_VERSION_CURRENT
;
1684 #if USE_CACHE_DIGESTS
1686 if (!p
->options
.no_digest
) {
1687 /* XXX This looks odd.. who has the original pointer
1690 PeerDigest
*pd
= peerDigestCreate(p
);
1691 p
->digest
= cbdataReference(pd
);
1695 while (*head
!= NULL
)
1696 head
= &(*head
)->next
;
1706 free_peer(peer
** P
)
1710 while ((p
= *P
) != NULL
) {
1712 #if USE_CACHE_DIGESTS
1714 cbdataReferenceDone(p
->digest
);
1724 dump_cachemgrpasswd(StoreEntry
* entry
, const char *name
, cachemgr_passwd
* list
)
1728 while (list
!= NULL
) {
1729 if (strcmp(list
->passwd
, "none") && strcmp(list
->passwd
, "disable"))
1730 storeAppendPrintf(entry
, "%s XXXXXXXXXX", name
);
1732 storeAppendPrintf(entry
, "%s %s", name
, list
->passwd
);
1734 for (w
= list
->actions
; w
!= NULL
; w
= w
->next
) {
1735 storeAppendPrintf(entry
, " %s", w
->key
);
1738 storeAppendPrintf(entry
, "\n");
1744 parse_cachemgrpasswd(cachemgr_passwd
** head
)
1746 char *passwd
= NULL
;
1747 wordlist
*actions
= NULL
;
1749 cachemgr_passwd
**P
;
1750 parse_string(&passwd
);
1751 parse_wordlist(&actions
);
1752 p
= static_cast<cachemgr_passwd
*>(xcalloc(1, sizeof(cachemgr_passwd
)));
1754 p
->actions
= actions
;
1756 for (P
= head
; *P
; P
= &(*P
)->next
) {
1758 * See if any of the actions from this line already have a
1759 * password from previous lines. The password checking
1760 * routines in cache_manager.c take the the password from
1761 * the first cachemgr_passwd struct that contains the
1762 * requested action. Thus, we should warn users who might
1763 * think they can have two passwords for the same action.
1768 for (w
= (*P
)->actions
; w
; w
= w
->next
) {
1769 for (u
= actions
; u
; u
= u
->next
) {
1770 if (strcmp(w
->key
, u
->key
))
1773 debugs(0, 0, "WARNING: action '" << u
->key
<< "' (line " << config_lineno
<< ") already has a password");
1782 free_cachemgrpasswd(cachemgr_passwd
** head
)
1786 while ((p
= *head
) != NULL
) {
1789 wordlistDestroy(&p
->actions
);
1795 dump_denyinfo(StoreEntry
* entry
, const char *name
, acl_deny_info_list
* var
)
1799 while (var
!= NULL
) {
1800 storeAppendPrintf(entry
, "%s %s", name
, var
->err_page_name
);
1802 for (a
= var
->acl_list
; a
!= NULL
; a
= a
->next
)
1803 storeAppendPrintf(entry
, " %s", a
->name
);
1805 storeAppendPrintf(entry
, "\n");
1812 parse_denyinfo(acl_deny_info_list
** var
)
1814 aclParseDenyInfoLine(var
);
1818 free_denyinfo(acl_deny_info_list
** list
)
1820 acl_deny_info_list
*a
= NULL
;
1821 acl_deny_info_list
*a_next
= NULL
;
1822 acl_name_list
*l
= NULL
;
1823 acl_name_list
*l_next
= NULL
;
1825 for (a
= *list
; a
; a
= a_next
) {
1826 for (l
= a
->acl_list
; l
; l
= l_next
) {
1828 memFree(l
, MEM_ACL_NAME_LIST
);
1833 memFree(a
, MEM_ACL_DENY_INFO_LIST
);
1841 parse_peer_access(void)
1846 if (!(host
= strtok(NULL
, w_space
)))
1849 if ((p
= peerFindByName(host
)) == NULL
) {
1850 debugs(15, 0, "" << cfg_filename
<< ", line " << config_lineno
<< ": No cache_peer '" << host
<< "'");
1854 aclParseAccessLine(LegacyParser
, &p
->access
);
1858 parse_hostdomain(void)
1861 char *domain
= NULL
;
1863 if (!(host
= strtok(NULL
, w_space
)))
1866 while ((domain
= strtok(NULL
, list_sep
))) {
1867 domain_ping
*l
= NULL
;
1868 domain_ping
**L
= NULL
;
1871 if ((p
= peerFindByName(host
)) == NULL
) {
1872 debugs(15, 0, "" << cfg_filename
<< ", line " << config_lineno
<< ": No cache_peer '" << host
<< "'");
1876 l
= static_cast<domain_ping
*>(xcalloc(1, sizeof(domain_ping
)));
1879 if (*domain
== '!') { /* check for !.edu */
1884 l
->domain
= xstrdup(domain
);
1886 for (L
= &(p
->peer_domain
); *L
; L
= &((*L
)->next
))
1894 parse_hostdomaintype(void)
1898 char *domain
= NULL
;
1900 if (!(host
= strtok(NULL
, w_space
)))
1903 if (!(type
= strtok(NULL
, w_space
)))
1906 while ((domain
= strtok(NULL
, list_sep
))) {
1907 domain_type
*l
= NULL
;
1908 domain_type
**L
= NULL
;
1911 if ((p
= peerFindByName(host
)) == NULL
) {
1912 debugs(15, 0, "" << cfg_filename
<< ", line " << config_lineno
<< ": No cache_peer '" << host
<< "'");
1916 l
= static_cast<domain_type
*>(xcalloc(1, sizeof(domain_type
)));
1917 l
->type
= parseNeighborType(type
);
1918 l
->domain
= xstrdup(domain
);
1920 for (L
= &(p
->typelist
); *L
; L
= &((*L
)->next
))
1928 dump_int(StoreEntry
* entry
, const char *name
, int var
)
1930 storeAppendPrintf(entry
, "%s %d\n", name
, var
);
1948 dump_onoff(StoreEntry
* entry
, const char *name
, int var
)
1950 storeAppendPrintf(entry
, "%s %s\n", name
, var
? "on" : "off");
1954 parse_onoff(int *var
)
1956 char *token
= strtok(NULL
, w_space
);
1961 if (!strcasecmp(token
, "on") || !strcasecmp(token
, "enable"))
1967 #define free_onoff free_int
1970 dump_tristate(StoreEntry
* entry
, const char *name
, int var
)
1981 storeAppendPrintf(entry
, "%s %s\n", name
, state
);
1985 parse_tristate(int *var
)
1987 char *token
= strtok(NULL
, w_space
);
1992 if (!strcasecmp(token
, "on") || !strcasecmp(token
, "enable"))
1994 else if (!strcasecmp(token
, "warn"))
2000 #define free_tristate free_int
2003 dump_refreshpattern(StoreEntry
* entry
, const char *name
, refresh_t
* head
)
2005 while (head
!= NULL
) {
2006 storeAppendPrintf(entry
, "%s%s %s %d %d%% %d\n",
2008 head
->flags
.icase
? " -i" : null_string
,
2010 (int) head
->min
/ 60,
2011 (int) (100.0 * head
->pct
+ 0.5),
2012 (int) head
->max
/ 60);
2014 if (head
->flags
.refresh_ims
)
2015 storeAppendPrintf(entry
, " refresh-ims");
2019 if (head
->flags
.override_expire
)
2020 storeAppendPrintf(entry
, " override-expire");
2022 if (head
->flags
.override_lastmod
)
2023 storeAppendPrintf(entry
, " override-lastmod");
2025 if (head
->flags
.reload_into_ims
)
2026 storeAppendPrintf(entry
, " reload-into-ims");
2028 if (head
->flags
.ignore_reload
)
2029 storeAppendPrintf(entry
, " ignore-reload");
2031 if (head
->flags
.ignore_no_cache
)
2032 storeAppendPrintf(entry
, " ignore-no-cache");
2034 if (head
->flags
.ignore_no_store
)
2035 storeAppendPrintf(entry
, " ignore-no-store");
2037 if (head
->flags
.ignore_private
)
2038 storeAppendPrintf(entry
, " ignore-private");
2040 if (head
->flags
.ignore_auth
)
2041 storeAppendPrintf(entry
, " ignore-auth");
2045 storeAppendPrintf(entry
, "\n");
2052 parse_refreshpattern(refresh_t
** head
)
2059 int refresh_ims
= 0;
2062 int override_expire
= 0;
2063 int override_lastmod
= 0;
2064 int reload_into_ims
= 0;
2065 int ignore_reload
= 0;
2066 int ignore_no_cache
= 0;
2067 int ignore_no_store
= 0;
2068 int ignore_private
= 0;
2069 int ignore_auth
= 0;
2076 int flags
= REG_EXTENDED
| REG_NOSUB
;
2078 if ((token
= strtok(NULL
, w_space
)) == NULL
)
2081 if (strcmp(token
, "-i") == 0) {
2083 token
= strtok(NULL
, w_space
);
2084 } else if (strcmp(token
, "+i") == 0) {
2085 flags
&= ~REG_ICASE
;
2086 token
= strtok(NULL
, w_space
);
2092 pattern
= xstrdup(token
);
2094 i
= GetInteger(); /* token: min */
2096 min
= (time_t) (i
* 60); /* convert minutes to seconds */
2098 i
= GetInteger(); /* token: pct */
2100 pct
= (double) i
/ 100.0;
2102 i
= GetInteger(); /* token: max */
2104 max
= (time_t) (i
* 60); /* convert minutes to seconds */
2107 while ((token
= strtok(NULL
, w_space
)) != NULL
) {
2108 if (!strcmp(token
, "refresh-ims")) {
2112 } else if (!strcmp(token
, "override-expire"))
2113 override_expire
= 1;
2114 else if (!strcmp(token
, "override-lastmod"))
2115 override_lastmod
= 1;
2116 else if (!strcmp(token
, "ignore-no-cache"))
2117 ignore_no_cache
= 1;
2118 else if (!strcmp(token
, "ignore-no-store"))
2119 ignore_no_store
= 1;
2120 else if (!strcmp(token
, "ignore-private"))
2122 else if (!strcmp(token
, "ignore-auth"))
2124 else if (!strcmp(token
, "reload-into-ims")) {
2125 reload_into_ims
= 1;
2126 refresh_nocache_hack
= 1;
2127 /* tell client_side.c that this is used */
2128 } else if (!strcmp(token
, "ignore-reload")) {
2130 refresh_nocache_hack
= 1;
2131 /* tell client_side.c that this is used */
2135 debugs(22, 0, "redreshAddToList: Unknown option '" << pattern
<< "': " << token
);
2138 if ((errcode
= regcomp(&comp
, pattern
, flags
)) != 0) {
2140 regerror(errcode
, &comp
, errbuf
, sizeof errbuf
);
2141 debugs(22, 0, "" << cfg_filename
<< " line " << config_lineno
<< ": " << config_input_line
);
2142 debugs(22, 0, "refreshAddToList: Invalid regular expression '" << pattern
<< "': " << errbuf
);
2146 pct
= pct
< 0.0 ? 0.0 : pct
;
2147 max
= max
< 0 ? 0 : max
;
2148 t
= static_cast<refresh_t
*>(xcalloc(1, sizeof(refresh_t
)));
2149 t
->pattern
= (char *) xstrdup(pattern
);
2150 t
->compiled_pattern
= comp
;
2155 if (flags
& REG_ICASE
)
2159 t
->flags
.refresh_ims
= 1;
2163 if (override_expire
)
2164 t
->flags
.override_expire
= 1;
2166 if (override_lastmod
)
2167 t
->flags
.override_lastmod
= 1;
2169 if (reload_into_ims
)
2170 t
->flags
.reload_into_ims
= 1;
2173 t
->flags
.ignore_reload
= 1;
2175 if (ignore_no_cache
)
2176 t
->flags
.ignore_no_cache
= 1;
2178 if (ignore_no_store
)
2179 t
->flags
.ignore_no_store
= 1;
2182 t
->flags
.ignore_private
= 1;
2185 t
->flags
.ignore_auth
= 1;
2192 head
= &(*head
)->next
;
2200 free_refreshpattern(refresh_t
** head
)
2204 while ((t
= *head
) != NULL
) {
2206 safe_free(t
->pattern
);
2207 regfree(&t
->compiled_pattern
);
2212 refresh_nocache_hack
= 0;
2218 dump_string(StoreEntry
* entry
, const char *name
, char *var
)
2221 storeAppendPrintf(entry
, "%s %s\n", name
, var
);
2225 parse_string(char **var
)
2227 char *token
= strtok(NULL
, w_space
);
2233 *var
= xstrdup(token
);
2237 ConfigParser::ParseString(char **var
)
2243 ConfigParser::ParseString(String
*var
)
2245 char *token
= strtok(NULL
, w_space
);
2254 free_string(char **var
)
2260 parse_eol(char *volatile *var
)
2262 unsigned char *token
= (unsigned char *) strtok(NULL
, null_string
);
2268 while (*token
&& xisspace(*token
))
2274 *var
= xstrdup((char *) token
);
2277 #define dump_eol dump_string
2278 #define free_eol free_string
2281 parse_debug(char *volatile *var
)
2284 safe_free(debug_options
)
2285 debug_options
= xstrdup(Config
.debugOptions
);
2286 Debug::parseOptions(Config
.debugOptions
);
2289 #define dump_debug dump_string
2290 #define free_debug free_string
2293 dump_time_t(StoreEntry
* entry
, const char *name
, time_t var
)
2295 storeAppendPrintf(entry
, "%s %d seconds\n", name
, (int) var
);
2299 parse_time_t(time_t * var
)
2301 parseTimeLine(var
, T_SECOND_STR
);
2305 free_time_t(time_t * var
)
2311 dump_size_t(StoreEntry
* entry
, const char *name
, size_t var
)
2313 storeAppendPrintf(entry
, "%s %d\n", name
, (int) var
);
2317 dump_b_size_t(StoreEntry
* entry
, const char *name
, size_t var
)
2319 storeAppendPrintf(entry
, "%s %d %s\n", name
, (int) var
, B_BYTES_STR
);
2323 dump_kb_size_t(StoreEntry
* entry
, const char *name
, size_t var
)
2325 storeAppendPrintf(entry
, "%s %d %s\n", name
, (int) var
, B_KBYTES_STR
);
2329 dump_b_int64_t(StoreEntry
* entry
, const char *name
, int64_t var
)
2331 storeAppendPrintf(entry
, "%s %"PRId64
" %s\n", name
, var
, B_BYTES_STR
);
2335 dump_kb_int64_t(StoreEntry
* entry
, const char *name
, int64_t var
)
2337 storeAppendPrintf(entry
, "%s %"PRId64
" %s\n", name
, var
, B_KBYTES_STR
);
2341 parse_size_t(size_t * var
)
2349 parse_b_size_t(size_t * var
)
2351 parseBytesLine(var
, B_BYTES_STR
);
2355 parse_kb_size_t(size_t * var
)
2357 parseBytesLine(var
, B_KBYTES_STR
);
2361 parse_b_int64_t(int64_t * var
)
2363 parseBytesLine64(var
, B_BYTES_STR
);
2367 parse_kb_int64_t(int64_t * var
)
2369 parseBytesLine64(var
, B_KBYTES_STR
);
2373 free_size_t(size_t * var
)
2379 free_b_int64_t(int64_t * var
)
2384 #define free_b_size_t free_size_t
2385 #define free_kb_size_t free_size_t
2386 #define free_mb_size_t free_size_t
2387 #define free_gb_size_t free_size_t
2388 #define free_kb_int64_t free_b_int64_t
2391 dump_ushort(StoreEntry
* entry
, const char *name
, u_short var
)
2393 storeAppendPrintf(entry
, "%s %d\n", name
, var
);
2397 free_ushort(u_short
* u
)
2403 parse_ushort(u_short
* var
)
2405 ConfigParser::ParseUShort(var
);
2409 ConfigParser::ParseUShort(u_short
*var
)
2415 ConfigParser::ParseBool(bool *var
)
2417 int i
= GetInteger();
2428 dump_wordlist(StoreEntry
* entry
, const char *name
, wordlist
* list
)
2430 while (list
!= NULL
) {
2431 storeAppendPrintf(entry
, "%s %s\n", name
, list
->key
);
2437 ConfigParser::ParseWordList(wordlist
** list
)
2439 parse_wordlist(list
);
2443 parse_wordlist(wordlist
** list
)
2446 char *t
= strtok(NULL
, "");
2448 while ((token
= strwordtok(NULL
, &t
)))
2449 wordlistAdd(list
, token
);
2453 check_null_wordlist(wordlist
* w
)
2459 check_null_acl_access(acl_access
* a
)
2464 #define free_wordlist wordlistDestroy
2466 #define free_uri_whitespace free_int
2469 parse_uri_whitespace(int *var
)
2471 char *token
= strtok(NULL
, w_space
);
2476 if (!strcasecmp(token
, "strip"))
2477 *var
= URI_WHITESPACE_STRIP
;
2478 else if (!strcasecmp(token
, "deny"))
2479 *var
= URI_WHITESPACE_DENY
;
2480 else if (!strcasecmp(token
, "allow"))
2481 *var
= URI_WHITESPACE_ALLOW
;
2482 else if (!strcasecmp(token
, "encode"))
2483 *var
= URI_WHITESPACE_ENCODE
;
2484 else if (!strcasecmp(token
, "chop"))
2485 *var
= URI_WHITESPACE_CHOP
;
2491 dump_uri_whitespace(StoreEntry
* entry
, const char *name
, int var
)
2495 if (var
== URI_WHITESPACE_ALLOW
)
2497 else if (var
== URI_WHITESPACE_ENCODE
)
2499 else if (var
== URI_WHITESPACE_CHOP
)
2501 else if (var
== URI_WHITESPACE_DENY
)
2506 storeAppendPrintf(entry
, "%s %s\n", name
, s
);
2510 free_removalpolicy(RemovalPolicySettings
** settings
)
2515 free_string(&(*settings
)->type
);
2517 free_wordlist(&(*settings
)->args
);
2525 parse_removalpolicy(RemovalPolicySettings
** settings
)
2528 free_removalpolicy(settings
);
2530 *settings
= new RemovalPolicySettings
;
2532 parse_string(&(*settings
)->type
);
2534 parse_wordlist(&(*settings
)->args
);
2538 dump_removalpolicy(StoreEntry
* entry
, const char *name
, RemovalPolicySettings
* settings
)
2541 storeAppendPrintf(entry
, "%s %s", name
, settings
->type
);
2542 args
= settings
->args
;
2545 storeAppendPrintf(entry
, " %s", args
->key
);
2549 storeAppendPrintf(entry
, "\n");
2552 #include "cf_parser.h"
2555 parseNeighborType(const char *s
)
2557 if (!strcasecmp(s
, "parent"))
2560 if (!strcasecmp(s
, "neighbor"))
2561 return PEER_SIBLING
;
2563 if (!strcasecmp(s
, "neighbour"))
2564 return PEER_SIBLING
;
2566 if (!strcasecmp(s
, "sibling"))
2567 return PEER_SIBLING
;
2569 if (!strcasecmp(s
, "multicast"))
2570 return PEER_MULTICAST
;
2572 debugs(15, 0, "WARNING: Unknown neighbor type: " << s
);
2574 return PEER_SIBLING
;
2579 parse_sockaddr_in_list_token(sockaddr_in_list
** head
, char *token
)
2585 const struct hostent
*hp
;
2586 unsigned short port
;
2587 sockaddr_in_list
*s
;
2592 if ((t
= strchr(token
, ':'))) {
2596 port
= xatos(t
+ 1);
2600 } else if ((port
= strtol(token
, &tmp
, 10)), !*tmp
) {
2607 s
= static_cast<sockaddr_in_list
*>(xcalloc(1, sizeof(*s
)));
2608 s
->s
.sin_port
= htons(port
);
2611 s
->s
.sin_addr
= any_addr
;
2612 else if (1 == safe_inet_addr(host
, &s
->s
.sin_addr
))
2614 else if ((hp
= gethostbyname(host
))) /* dont use ipcache */
2615 s
->s
.sin_addr
= inaddrFromHostent(hp
);
2620 head
= &(*head
)->next
;
2626 parse_sockaddr_in_list(sockaddr_in_list
** head
)
2630 while ((token
= strtok(NULL
, w_space
))) {
2631 parse_sockaddr_in_list_token(head
, token
);
2636 dump_sockaddr_in_list(StoreEntry
* e
, const char *n
, const sockaddr_in_list
* s
)
2639 storeAppendPrintf(e
, "%s %s:%d\n",
2641 inet_ntoa(s
->s
.sin_addr
),
2642 ntohs(s
->s
.sin_port
));
2648 free_sockaddr_in_list(sockaddr_in_list
** head
)
2650 sockaddr_in_list
*s
;
2652 while ((s
= *head
) != NULL
) {
2658 #if CURRENTLY_UNUSED
2659 /* This code was previously used by http_port. Left as it really should
2660 * be used by icp_port and htcp_port
2663 check_null_sockaddr_in_list(const sockaddr_in_list
* s
)
2668 #endif /* CURRENTLY_UNUSED */
2669 #endif /* USE_WCCPv2 */
2672 parse_http_port_specification(http_port_list
* s
, char *token
)
2676 const struct hostent
*hp
;
2677 unsigned short port
= 0;
2680 s
->disable_pmtu_discovery
= DISABLE_PMTU_OFF
;
2682 if ((t
= strchr(token
, ':'))) {
2686 port
= xatos(t
+ 1);
2689 port
= xatos(token
);
2695 s
->s
.sin_port
= htons(port
);
2698 s
->s
.sin_addr
= any_addr
;
2699 else if (1 == safe_inet_addr(host
, &s
->s
.sin_addr
))
2701 else if ((hp
= gethostbyname(host
))) {
2702 /* dont use ipcache */
2703 s
->s
.sin_addr
= inaddrFromHostent(hp
);
2704 s
->defaultsite
= xstrdup(host
);
2710 parse_http_port_option(http_port_list
* s
, char *token
)
2712 if (strncmp(token
, "defaultsite=", 12) == 0) {
2713 safe_free(s
->defaultsite
);
2714 s
->defaultsite
= xstrdup(token
+ 12);
2716 } else if (strncmp(token
, "name=", 5) == 0) {
2718 s
->name
= xstrdup(token
+ 5);
2719 } else if (strcmp(token
, "transparent") == 0) {
2721 } else if (strcmp(token
, "vhost") == 0) {
2724 } else if (strcmp(token
, "vport") == 0) {
2727 } else if (strncmp(token
, "vport=", 6) == 0) {
2728 s
->vport
= xatos(token
+ 6);
2730 } else if (strncmp(token
, "protocol=", 9) == 0) {
2731 s
->protocol
= xstrdup(token
+ 9);
2733 } else if (strcmp(token
, "accel") == 0) {
2735 } else if (strncmp(token
, "disable-pmtu-discovery=", 23) == 0) {
2736 if (!strcasecmp(token
+ 23, "off"))
2737 s
->disable_pmtu_discovery
= DISABLE_PMTU_OFF
;
2738 else if (!strcasecmp(token
+ 23, "transparent"))
2739 s
->disable_pmtu_discovery
= DISABLE_PMTU_TRANSPARENT
;
2740 else if (!strcasecmp(token
+ 23, "always"))
2741 s
->disable_pmtu_discovery
= DISABLE_PMTU_ALWAYS
;
2747 } else if (strcmp(token
, "tproxy") == 0) {
2749 need_linux_tproxy
= 1;
2758 free_generic_http_port_data(http_port_list
* s
)
2761 safe_free(s
->defaultsite
);
2762 safe_free(s
->protocol
);
2766 cbdataFree_http_port(void *data
)
2768 free_generic_http_port_data((http_port_list
*)data
);
2771 static http_port_list
*
2772 create_http_port(char *portspec
)
2774 CBDATA_TYPE(http_port_list
);
2775 CBDATA_INIT_TYPE_FREECB(http_port_list
, cbdataFree_http_port
);
2777 http_port_list
*s
= cbdataAlloc(http_port_list
);
2778 s
->protocol
= xstrdup("http");
2779 parse_http_port_specification(s
, portspec
);
2784 add_http_port(char *portspec
)
2786 http_port_list
*s
= create_http_port(portspec
);
2787 s
->next
= Config
.Sockaddr
.http
;
2788 Config
.Sockaddr
.http
= s
;
2792 parse_http_port_list(http_port_list
** head
)
2794 char *token
= strtok(NULL
, w_space
);
2799 http_port_list
*s
= create_http_port(token
);
2801 /* parse options ... */
2802 while ((token
= strtok(NULL
, w_space
))) {
2803 parse_http_port_option(s
, token
);
2807 head
= &(*head
)->next
;
2813 dump_generic_http_port(StoreEntry
* e
, const char *n
, const http_port_list
* s
)
2815 storeAppendPrintf(e
, "%s %s:%d",
2817 inet_ntoa(s
->s
.sin_addr
),
2818 ntohs(s
->s
.sin_port
));
2821 storeAppendPrintf(e
, " defaultsite=%s", s
->defaultsite
);
2824 storeAppendPrintf(e
, " transparent");
2827 storeAppendPrintf(e
, " vhost");
2830 storeAppendPrintf(e
, " vport");
2832 if (s
->disable_pmtu_discovery
!= DISABLE_PMTU_OFF
) {
2835 if (s
->disable_pmtu_discovery
== DISABLE_PMTU_ALWAYS
)
2838 pmtu
= "transparent";
2840 storeAppendPrintf(e
, " disable-pmtu-discovery=%s", pmtu
);
2845 dump_http_port_list(StoreEntry
* e
, const char *n
, const http_port_list
* s
)
2848 dump_generic_http_port(e
, n
, s
);
2849 storeAppendPrintf(e
, "\n");
2855 free_http_port_list(http_port_list
** head
)
2859 while ((s
= *head
) != NULL
) {
2867 cbdataFree_https_port(void *data
)
2869 https_port_list
*s
= (https_port_list
*)data
;
2870 free_generic_http_port_data(&s
->http
);
2873 safe_free(s
->options
);
2874 safe_free(s
->cipher
);
2875 safe_free(s
->cafile
);
2876 safe_free(s
->capath
);
2877 safe_free(s
->dhfile
);
2878 safe_free(s
->sslflags
);
2882 parse_https_port_list(https_port_list
** head
)
2884 CBDATA_TYPE(https_port_list
);
2887 CBDATA_INIT_TYPE_FREECB(https_port_list
, cbdataFree_https_port
);
2888 token
= strtok(NULL
, w_space
);
2893 s
= cbdataAlloc(https_port_list
);
2895 s
->http
.protocol
= xstrdup("https");
2897 parse_http_port_specification(&s
->http
, token
);
2899 /* parse options ... */
2900 while ((token
= strtok(NULL
, w_space
))) {
2901 if (strncmp(token
, "cert=", 5) == 0) {
2903 s
->cert
= xstrdup(token
+ 5);
2904 } else if (strncmp(token
, "key=", 4) == 0) {
2906 s
->key
= xstrdup(token
+ 4);
2907 } else if (strncmp(token
, "version=", 8) == 0) {
2908 s
->version
= xatoi(token
+ 8);
2910 if (s
->version
< 1 || s
->version
> 4)
2912 } else if (strncmp(token
, "options=", 8) == 0) {
2913 safe_free(s
->options
);
2914 s
->options
= xstrdup(token
+ 8);
2915 } else if (strncmp(token
, "cipher=", 7) == 0) {
2916 safe_free(s
->cipher
);
2917 s
->cipher
= xstrdup(token
+ 7);
2918 } else if (strncmp(token
, "clientca=", 9) == 0) {
2919 safe_free(s
->clientca
);
2920 s
->clientca
= xstrdup(token
+ 9);
2921 } else if (strncmp(token
, "cafile=", 7) == 0) {
2922 safe_free(s
->cafile
);
2923 s
->cafile
= xstrdup(token
+ 7);
2924 } else if (strncmp(token
, "capath=", 7) == 0) {
2925 safe_free(s
->capath
);
2926 s
->capath
= xstrdup(token
+ 7);
2927 } else if (strncmp(token
, "crlfile=", 8) == 0) {
2928 safe_free(s
->crlfile
);
2929 s
->crlfile
= xstrdup(token
+ 8);
2930 } else if (strncmp(token
, "dhparams=", 9) == 0) {
2931 safe_free(s
->dhfile
);
2932 s
->dhfile
= xstrdup(token
+ 9);
2933 } else if (strncmp(token
, "sslflags=", 9) == 0) {
2934 safe_free(s
->sslflags
);
2935 s
->sslflags
= xstrdup(token
+ 9);
2936 } else if (strncmp(token
, "sslcontext=", 11) == 0) {
2937 safe_free(s
->sslcontext
);
2938 s
->sslcontext
= xstrdup(token
+ 11);
2940 parse_http_port_option(&s
->http
, token
);
2945 http_port_list
** headTmp
= &(*head
)->http
.next
;
2946 head
= (https_port_list
**)headTmp
;
2953 dump_https_port_list(StoreEntry
* e
, const char *n
, const https_port_list
* s
)
2956 dump_generic_http_port(e
, n
, &s
->http
);
2959 storeAppendPrintf(e
, " cert=%s", s
->cert
);
2962 storeAppendPrintf(e
, " key=%s", s
->key
);
2965 storeAppendPrintf(e
, " version=%d", s
->version
);
2968 storeAppendPrintf(e
, " options=%s", s
->options
);
2971 storeAppendPrintf(e
, " cipher=%s", s
->cipher
);
2974 storeAppendPrintf(e
, " cafile=%s", s
->cafile
);
2977 storeAppendPrintf(e
, " capath=%s", s
->capath
);
2980 storeAppendPrintf(e
, " crlfile=%s", s
->crlfile
);
2983 storeAppendPrintf(e
, " dhparams=%s", s
->dhfile
);
2986 storeAppendPrintf(e
, " sslflags=%s", s
->sslflags
);
2989 storeAppendPrintf(e
, " sslcontext=%s", s
->sslcontext
);
2991 storeAppendPrintf(e
, "\n");
2993 s
= (https_port_list
*) s
->http
.next
;
2998 free_https_port_list(https_port_list
** head
)
3002 while ((s
= *head
) != NULL
) {
3003 *head
= (https_port_list
*) s
->http
.next
;
3010 check_null_https_port_list(const https_port_list
* s
)
3017 #endif /* USE_SSL */
3020 configFreeMemory(void)
3026 requirePathnameExists(const char *name
, const char *path
)
3030 char pathbuf
[BUFSIZ
];
3031 assert(path
!= NULL
);
3033 if (Config
.chroot_dir
&& (geteuid() == 0)) {
3034 snprintf(pathbuf
, BUFSIZ
, "%s/%s", Config
.chroot_dir
, path
);
3038 if (stat(path
, &sb
) < 0) {
3039 if (opt_send_signal
== -1 || opt_send_signal
== SIGHUP
)
3040 fatalf("%s %s: %s", name
, path
, xstrerror());
3042 fprintf(stderr
, "WARNING: %s %s: %s\n", name
, path
, xstrerror());
3049 return ConfigParser::strtokFile();
3052 #include "AccessLogEntry.h"
3053 /* TODO: split out parsing somehow ...*/
3055 parse_logformat(logformat
** logformat_definitions
)
3060 if ((name
= strtok(NULL
, w_space
)) == NULL
)
3063 if ((def
= strtok(NULL
, "\r\n")) == NULL
)
3066 debugs(3, 2, "Logformat for '" << name
<< "' is '" << def
<< "'");
3068 nlf
= (logformat
*)xcalloc(1, sizeof(logformat
));
3070 nlf
->name
= xstrdup(name
);
3072 if (!accessLogParseLogFormat(&nlf
->format
, def
))
3075 nlf
->next
= *logformat_definitions
;
3077 *logformat_definitions
= nlf
;
3081 parse_access_log(customlog
** logs
)
3083 const char *filename
, *logdef_name
;
3087 cl
= (customlog
*)xcalloc(1, sizeof(*cl
));
3089 if ((filename
= strtok(NULL
, w_space
)) == NULL
)
3092 if (strcmp(filename
, "none") == 0) {
3093 cl
->type
= CLF_NONE
;
3097 if ((logdef_name
= strtok(NULL
, w_space
)) == NULL
)
3098 logdef_name
= "auto";
3100 debugs(3, 9, "Log definition name '" << logdef_name
<< "' file '" << filename
<< "'");
3102 cl
->filename
= xstrdup(filename
);
3104 /* look for the definition pointer corresponding to this name */
3105 lf
= Config
.Log
.logformats
;
3107 while (lf
!= NULL
) {
3108 debugs(3, 9, "Comparing against '" << lf
->name
<< "'");
3110 if (strcmp(lf
->name
, logdef_name
) == 0)
3117 cl
->type
= CLF_CUSTOM
;
3119 } else if (strcmp(logdef_name
, "auto") == 0) {
3120 cl
->type
= CLF_AUTO
;
3121 } else if (strcmp(logdef_name
, "squid") == 0) {
3122 cl
->type
= CLF_SQUID
;
3123 } else if (strcmp(logdef_name
, "common") == 0) {
3124 cl
->type
= CLF_COMMON
;
3126 debugs(3, 0, "Log format '" << logdef_name
<< "' is not defined");
3131 aclParseAclList(LegacyParser
, &cl
->aclList
);
3134 logs
= &(*logs
)->next
;
3140 check_null_access_log(customlog
*customlog_definitions
)
3142 return customlog_definitions
== NULL
;
3146 dump_logformat(StoreEntry
* entry
, const char *name
, logformat
* definitions
)
3148 accessLogDumpLogFormat(entry
, name
, definitions
);
3152 dump_access_log(StoreEntry
* entry
, const char *name
, customlog
* logs
)
3156 for (log
= logs
; log
; log
= log
->next
) {
3157 storeAppendPrintf(entry
, "%s ", name
);
3159 switch (log
->type
) {
3162 storeAppendPrintf(entry
, "%s %s", log
->filename
, log
->logFormat
->name
);
3166 storeAppendPrintf(entry
, "none");
3170 storeAppendPrintf(entry
, "%s squid", log
->filename
);
3174 storeAppendPrintf(entry
, "%s squid", log
->filename
);
3180 storeAppendPrintf(entry
, "%s auto", log
->filename
);
3182 storeAppendPrintf(entry
, "%s", log
->filename
);
3191 dump_acl_list(entry
, log
->aclList
);
3193 storeAppendPrintf(entry
, "\n");
3198 free_logformat(logformat
** definitions
)
3200 while (*definitions
) {
3201 logformat
*format
= *definitions
;
3202 *definitions
= format
->next
;
3203 accessLogFreeLogFormat(&format
->format
);
3209 free_access_log(customlog
** definitions
)
3211 while (*definitions
) {
3212 customlog
*log
= *definitions
;
3213 *definitions
= log
->next
;
3215 log
->logFormat
= NULL
;
3216 log
->type
= CLF_UNKNOWN
;
3219 aclDestroyAclList(&log
->aclList
);
3221 safe_free(log
->filename
);
3230 parse_icap_service_type(ICAPConfig
* cfg
)
3232 cfg
->parseICAPService();
3236 free_icap_service_type(ICAPConfig
* cfg
)
3238 cfg
->freeICAPService();
3242 dump_icap_service_type(StoreEntry
* entry
, const char *name
, const ICAPConfig
&cfg
)
3244 cfg
.dumpICAPService(entry
, name
);
3248 parse_icap_class_type(ICAPConfig
* cfg
)
3250 cfg
->parseICAPClass();
3254 free_icap_class_type(ICAPConfig
* cfg
)
3256 cfg
->freeICAPClass();
3260 dump_icap_class_type(StoreEntry
* entry
, const char *name
, const ICAPConfig
&cfg
)
3262 cfg
.dumpICAPClass(entry
, name
);
3266 parse_icap_access_type(ICAPConfig
* cfg
)
3268 cfg
->parseICAPAccess(LegacyParser
);
3272 free_icap_access_type(ICAPConfig
* cfg
)
3274 cfg
->freeICAPAccess();
3278 dump_icap_access_type(StoreEntry
* entry
, const char *name
, const ICAPConfig
&cfg
)
3280 cfg
.dumpICAPAccess(entry
, name
);