2 * $Id: cache_cf.cc,v 1.230 1997/11/05 05:29:18 wessels Exp $
4 * DEBUG: section 3 Configuration File Parsing
5 * AUTHOR: Harvest Derived
7 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
8 * --------------------------------------------------------
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.
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.
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.
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.
33 static const char *const T_SECOND_STR
= "second";
34 static const char *const T_MINUTE_STR
= "minute";
35 static const char *const T_HOUR_STR
= "hour";
36 static const char *const T_DAY_STR
= "day";
37 static const char *const T_WEEK_STR
= "week";
38 static const char *const T_FORTNIGHT_STR
= "fortnight";
39 static const char *const T_MONTH_STR
= "month";
40 static const char *const T_YEAR_STR
= "year";
41 static const char *const T_DECADE_STR
= "decade";
43 static const char *const B_BYTES_STR
= "bytes";
44 static const char *const B_KBYTES_STR
= "KB";
45 static const char *const B_MBYTES_STR
= "MB";
46 static const char *const B_GBYTES_STR
= "GB";
48 static const char *const list_sep
= ", \t\n\r";
50 static char fatal_str
[BUFSIZ
];
51 static void self_destruct(void);
52 static void wordlistAdd(wordlist
**, const char *);
54 static void configDoConfigure(void);
55 static void parse_refreshpattern(refresh_t
**);
56 static int parseTimeUnits(const char *unit
);
57 static void parseTimeLine(time_t * tptr
, const char *units
);
58 static void parse_string(char **);
59 static void parse_wordlist(wordlist
**);
60 static void default_all(void);
61 static void defaults_if_none(void);
62 static int parse_line(char *);
63 static void parseBytesLine(size_t * bptr
, const char *units
);
64 static size_t parseBytesUnits(const char *unit
);
66 /* These come from cf_gen.c */
67 static void default_all(void);
68 static void free_all(void);
73 snprintf(fatal_str
, BUFSIZ
, "Bungled %s line %d: %s",
74 cfg_filename
, config_lineno
, config_input_line
);
79 wordlistDestroy(wordlist
** list
)
82 while ((w
= *list
) != NULL
) {
91 wordlistAdd(wordlist
** list
, const char *key
)
98 *list
= xcalloc(1, sizeof(wordlist
));
99 (*list
)->key
= xstrdup(key
);
100 (*list
)->next
= NULL
;
105 q
= xcalloc(1, sizeof(wordlist
));
106 q
->key
= xstrdup(key
);
113 intlistDestroy(intlist
** list
)
118 for (w
= *list
; w
; w
= n
) {
127 * Use this #define in all the parse*() functions. Assumes char *token is
131 #define GetInteger(var) \
132 token = strtok(NULL, w_space); \
135 if (sscanf(token, "%d", &var) != 1) \
139 parseConfigFile(const char *file_name
)
146 if ((fp
= fopen(file_name
, "r")) == NULL
) {
147 snprintf(fatal_str
, BUFSIZ
, "Unable to open configuration file: %s: %s",
148 file_name
, xstrerror());
151 cfg_filename
= file_name
;
152 if ((token
= strrchr(cfg_filename
, '/')))
153 cfg_filename
= token
+ 1;
154 memset(config_input_line
, '\0', BUFSIZ
);
156 while (fgets(config_input_line
, BUFSIZ
, fp
)) {
158 if ((token
= strchr(config_input_line
, '\n')))
160 if (config_input_line
[0] == '#')
162 if (config_input_line
[0] == '\0')
164 debug(3, 5) ("Processing: '%s'\n", config_input_line
);
165 tmp_line
= xstrdup(config_input_line
);
166 if (!parse_line(tmp_line
)) {
167 debug(3, 0) ("parseConfigFile: line %d unrecognized: '%s'\n",
175 if (Config
.cacheSwap
.swapDirs
== NULL
)
176 fatal("No cache_dir's specified in config file");
177 if (Config
.Swap
.maxSize
< (Config
.Mem
.maxSize
>> 10)) {
178 printf("WARNING: cache_swap (%d kbytes) is less than cache_mem (%d bytes).\n", Config
.Swap
.maxSize
, Config
.Mem
.maxSize
);
179 printf(" This will cause serious problems with your cache!!!\n");
180 printf(" Change your configuration file.\n");
181 fflush(stdout
); /* print message */
183 if (Config
.Announce
.period
< 1) {
184 Config
.Announce
.period
= 86400 * 365; /* one year */
185 Config
.onoff
.announce
= 0;
187 if (Config
.dnsChildren
< 0)
188 Config
.dnsChildren
= 0;
189 if (Config
.dnsChildren
< 1) {
190 printf("WARNING: dnsservers are disabled!\n");
191 printf("WARNING: Cache performance may be very poor\n");
192 } else if (Config
.dnsChildren
> DefaultDnsChildrenMax
) {
193 printf("WARNING: dns_children was set to a bad value: %d\n",
195 printf("Setting it to the maximum (%d).\n", DefaultDnsChildrenMax
);
196 Config
.dnsChildren
= DefaultDnsChildrenMax
;
198 if (Config
.Program
.redirect
) {
199 if (Config
.redirectChildren
< 1) {
200 Config
.redirectChildren
= 0;
201 safe_free(Config
.Program
.redirect
);
202 } else if (Config
.redirectChildren
> DefaultRedirectChildrenMax
) {
203 printf("WARNING: redirect_children was set to a bad value: %d\n",
204 Config
.redirectChildren
);
205 printf("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax
);
206 Config
.redirectChildren
= DefaultRedirectChildrenMax
;
216 configDoConfigure(void)
218 LOCAL_ARRAY(char, buf
, BUFSIZ
);
219 memset(&Config2
, '\0', sizeof(SquidConfig2
));
220 if (Config
.Accel
.host
) {
221 snprintf(buf
, BUFSIZ
, "http://%s:%d", Config
.Accel
.host
, Config
.Accel
.port
);
222 Config2
.Accel
.prefix
= xstrdup(buf
);
223 Config2
.Accel
.on
= 1;
225 if (Config
.appendDomain
)
226 if (*Config
.appendDomain
!= '.')
227 fatal("append_domain must begin with a '.'");
228 if (Config
.errHtmlText
== NULL
)
229 Config
.errHtmlText
= xstrdup(null_string
);
231 if (Config2
.Accel
.on
&& !strcmp(Config
.Accel
.host
, "virtual"))
233 if (Config
.Port
.http
== NULL
)
234 fatal("No http_port specified!");
235 snprintf(ThisCache
, SQUIDHOSTNAMELEN
<< 1, "%s:%d (Squid/%s)",
237 (int) Config
.Port
.http
->i
,
239 if (!Config
.udpMaxHitObjsz
|| Config
.udpMaxHitObjsz
> SQUID_UDP_SO_SNDBUF
)
240 Config
.udpMaxHitObjsz
= SQUID_UDP_SO_SNDBUF
;
241 if (Config
.appendDomain
)
242 Config
.appendDomainLen
= strlen(Config
.appendDomain
);
244 Config
.appendDomainLen
= 0;
245 safe_free(debug_options
)
246 debug_options
= xstrdup(Config
.debugOptions
);
247 if (Config
.retry
.timeout
< 5)
248 fatal("minimum_retry_timeout must be at least 5 seconds");
249 if (Config
.retry
.maxtries
> 10)
250 fatal("maximum_single_addr_tries cannot be larger than 10");
251 if (Config
.retry
.maxtries
< 1) {
252 debug(3, 0) ("WARNING: resetting 'maximum_single_addr_tries to 1\n");
253 Config
.retry
.maxtries
= 1;
255 if (Config
.referenceAge
< 300) {
256 debug(3, 0) ("WARNING: resetting 'reference_age' to 1 week\n");
257 Config
.referenceAge
= 86400 * 7;
261 /* Parse a time specification from the config file. Store the
262 * result in 'tptr', after converting it to 'units' */
264 parseTimeLine(time_t * tptr
, const char *units
)
270 if ((u
= parseTimeUnits(units
)) == 0)
272 if ((token
= strtok(NULL
, w_space
)) == NULL
)
275 m
= u
; /* default to 'units' if none specified */
276 if ((token
= strtok(NULL
, w_space
)) == NULL
)
277 debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
278 config_input_line
, d
, units
);
279 else if ((m
= parseTimeUnits(token
)) == 0)
285 parseTimeUnits(const char *unit
)
287 if (!strncasecmp(unit
, T_SECOND_STR
, strlen(T_SECOND_STR
)))
289 if (!strncasecmp(unit
, T_MINUTE_STR
, strlen(T_MINUTE_STR
)))
291 if (!strncasecmp(unit
, T_HOUR_STR
, strlen(T_HOUR_STR
)))
293 if (!strncasecmp(unit
, T_DAY_STR
, strlen(T_DAY_STR
)))
295 if (!strncasecmp(unit
, T_WEEK_STR
, strlen(T_WEEK_STR
)))
297 if (!strncasecmp(unit
, T_FORTNIGHT_STR
, strlen(T_FORTNIGHT_STR
)))
299 if (!strncasecmp(unit
, T_MONTH_STR
, strlen(T_MONTH_STR
)))
301 if (!strncasecmp(unit
, T_YEAR_STR
, strlen(T_YEAR_STR
)))
302 return 86400 * 365.2522;
303 if (!strncasecmp(unit
, T_DECADE_STR
, strlen(T_DECADE_STR
)))
304 return 86400 * 365.2522 * 10;
305 debug(3, 1) ("parseTimeUnits: unknown time unit '%s'\n", unit
);
310 parseBytesLine(size_t * bptr
, const char *units
)
316 if ((u
= parseBytesUnits(units
)) == 0)
318 if ((token
= strtok(NULL
, w_space
)) == NULL
)
321 m
= u
; /* default to 'units' if none specified */
322 if ((token
= strtok(NULL
, w_space
)) == NULL
)
323 debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
324 config_input_line
, d
, units
);
325 else if ((m
= parseBytesUnits(token
)) == 0)
331 parseBytesUnits(const char *unit
)
333 if (!strncasecmp(unit
, B_BYTES_STR
, strlen(B_BYTES_STR
)))
335 if (!strncasecmp(unit
, B_KBYTES_STR
, strlen(B_KBYTES_STR
)))
337 if (!strncasecmp(unit
, B_MBYTES_STR
, strlen(B_MBYTES_STR
)))
339 if (!strncasecmp(unit
, B_GBYTES_STR
, strlen(B_GBYTES_STR
)))
341 debug(3, 1) ("parseBytesUnits: unknown bytes unit '%s'\n", unit
);
345 /*****************************************************************************
347 *****************************************************************************/
350 dump_acl(StoreEntry
* entry
, const char *name
, acl
* acl
)
352 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
356 parse_acl(acl
** acl
)
358 aclParseAclLine(acl
);
368 dump_acl_access(StoreEntry
* entry
, const char *name
, struct _acl_access
*head
)
370 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
374 parse_acl_access(struct _acl_access
**head
)
376 aclParseAccessLine(head
);
380 free_acl_access(struct _acl_access
**head
)
382 aclDestroyAccessList(head
);
386 dump_address(StoreEntry
* entry
, const char *name
, struct in_addr addr
)
388 storeAppendPrintf(entry
, "%s %s\n", name
, inet_ntoa(addr
));
392 parse_address(struct in_addr
*addr
)
394 const struct hostent
*hp
;
395 char *token
= strtok(NULL
, w_space
);
399 if (safe_inet_addr(token
, addr
) == 1)
401 else if ((hp
= gethostbyname(token
))) /* dont use ipcache */
402 *addr
= inaddrFromHostent(hp
);
408 free_address(struct in_addr
*addr
)
410 memset(addr
, '\0', sizeof(struct in_addr
));
414 dump_cachedir(StoreEntry
* entry
, const char *name
, struct _cacheSwap swap
)
418 for (i
= 0; i
< swap
.n_configured
; i
++) {
419 s
= swap
.swapDirs
+ i
;
420 storeAppendPrintf(entry
, "%s %s %d %d %d\n",
430 check_null_cachedir(struct _cacheSwap swap
)
432 return swap
.swapDirs
== NULL
;
436 parse_cachedir(struct _cacheSwap
*swap
)
446 if ((path
= strtok(NULL
, w_space
)) == NULL
)
448 if (strlen(path
) > (SQUID_MAXPATHLEN
- 32))
449 fatal_dump("cache_dir pathname is too long");
451 size
= i
<< 10; /* Mbytes to kbytes */
456 if ((token
= strtok(NULL
, w_space
)))
457 if (!strcasecmp(token
, "read-only"))
459 for (i
= 0; i
< swap
->n_configured
; i
++) {
460 tmp
= swap
->swapDirs
+ i
;
461 if (!strcmp(path
, tmp
->path
)) {
462 /* just reconfigure it */
463 tmp
->max_size
= size
;
464 tmp
->read_only
= readonly
;
468 if (swap
->swapDirs
== NULL
) {
469 swap
->n_allocated
= 4;
470 swap
->swapDirs
= xcalloc(swap
->n_allocated
, sizeof(SwapDir
));
472 if (swap
->n_allocated
== swap
->n_configured
) {
473 swap
->n_allocated
<<= 1;
474 tmp
= xcalloc(swap
->n_allocated
, sizeof(SwapDir
));
475 xmemcpy(tmp
, swap
->swapDirs
, swap
->n_configured
* sizeof(SwapDir
));
476 xfree(swap
->swapDirs
);
477 swap
->swapDirs
= tmp
;
479 tmp
= swap
->swapDirs
+ swap
->n_configured
;
480 tmp
->path
= xstrdup(path
);
481 tmp
->max_size
= size
;
484 tmp
->read_only
= readonly
;
485 tmp
->map
= file_map_create(MAX_FILES_PER_DIR
);
486 tmp
->swaplog_fd
= -1;
487 swap
->n_configured
++;
488 Config
.Swap
.maxSize
+= size
;
492 free_cachedir(struct _cacheSwap
*swap
)
496 for (i
= 0; i
< swap
->n_configured
; i
++) {
497 s
= swap
->swapDirs
+ i
;
498 if (s
->swaplog_fd
> -1) {
499 file_close(s
->swaplog_fd
);
503 filemapFreeMemory(s
->map
);
505 safe_free(swap
->swapDirs
);
506 swap
->swapDirs
= NULL
;
507 swap
->n_allocated
= 0;
508 swap
->n_configured
= 0;
512 dump_peer(StoreEntry
* entry
, const char *name
, peer
* p
)
514 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
518 parse_peer(peer
** head
)
524 const char *me
= null_string
; /* XXX */
525 p
= xcalloc(1, sizeof(peer
));
526 p
->http_port
= CACHE_HTTP_PORT
;
527 p
->icp_port
= CACHE_ICP_PORT
;
529 if ((token
= strtok(NULL
, w_space
)) == NULL
)
531 p
->host
= xstrdup(token
);
532 if ((token
= strtok(NULL
, w_space
)) == NULL
)
534 p
->type
= parseNeighborType(token
);
536 p
->http_port
= (u_short
) i
;
538 p
->icp_port
= (u_short
) i
;
539 if (strcmp(p
->host
, me
) == 0) {
540 for (u
= Config
.Port
.http
; u
; u
= u
->next
) {
541 if (p
->http_port
!= u
->i
)
543 debug(15, 0) ("parse_peer: Peer looks like myself: %s %s/%d/%d\n",
544 p
->type
, p
->host
, p
->http_port
, p
->icp_port
);
548 while ((token
= strtok(NULL
, w_space
))) {
549 if (!strcasecmp(token
, "proxy-only")) {
550 p
->options
|= NEIGHBOR_PROXY_ONLY
;
551 } else if (!strcasecmp(token
, "no-query")) {
552 p
->options
|= NEIGHBOR_NO_QUERY
;
553 } else if (!strcasecmp(token
, "multicast-responder")) {
554 p
->options
|= NEIGHBOR_MCAST_RESPONDER
;
555 } else if (!strncasecmp(token
, "weight=", 7)) {
556 p
->weight
= atoi(token
+ 7);
557 } else if (!strncasecmp(token
, "closest-only", 12)) {
558 p
->options
|= NEIGHBOR_CLOSEST_ONLY
;
559 } else if (!strncasecmp(token
, "ttl=", 4)) {
560 p
->mcast
.ttl
= atoi(token
+ 4);
561 if (p
->mcast
.ttl
< 0)
563 if (p
->mcast
.ttl
> 128)
565 } else if (!strncasecmp(token
, "default", 7)) {
566 p
->options
|= NEIGHBOR_DEFAULT_PARENT
;
567 } else if (!strncasecmp(token
, "round-robin", 11)) {
568 p
->options
|= NEIGHBOR_ROUNDROBIN
;
570 debug(3, 0) ("parse_peer: token='%s'\n", token
);
576 p
->icp_version
= ICP_VERSION_CURRENT
;
579 while (*head
!= NULL
)
580 head
= &(*head
)->next
;
589 while ((p
= *P
) != NULL
) {
596 dump_cachemgrpasswd(StoreEntry
* entry
, const char *name
, cachemgr_passwd
* list
)
598 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
602 parse_cachemgrpasswd(cachemgr_passwd
** head
)
605 wordlist
*actions
= NULL
;
606 parse_string(&passwd
);
607 parse_wordlist(&actions
);
608 objcachePasswdAdd(head
, passwd
, actions
);
609 wordlistDestroy(&actions
);
613 free_cachemgrpasswd(cachemgr_passwd
** head
)
616 while ((p
= *head
) != NULL
) {
625 dump_denyinfo(StoreEntry
* entry
, const char *name
, struct _acl_deny_info_list
*var
)
627 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
631 parse_denyinfo(struct _acl_deny_info_list
**var
)
633 aclParseDenyInfoLine(var
);
637 free_denyinfo(acl_deny_info_list
** list
)
639 struct _acl_deny_info_list
*a
= NULL
;
640 struct _acl_deny_info_list
*a_next
= NULL
;
641 struct _acl_name_list
*l
= NULL
;
642 struct _acl_name_list
*l_next
= NULL
;
643 for (a
= *list
; a
; a
= a_next
) {
644 for (l
= a
->acl_list
; l
; l
= l_next
) {
658 char *aclname
= NULL
;
659 if (!(host
= strtok(NULL
, w_space
)))
661 while ((aclname
= strtok(NULL
, list_sep
))) {
664 acl_list
**Tail
= NULL
;
666 if ((p
= peerFindByName(host
)) == NULL
) {
667 debug(15, 0) ("%s, line %d: No cache_peer '%s'\n",
668 cfg_filename
, config_lineno
, host
);
671 L
= xcalloc(1, sizeof(struct _acl_list
));
673 if (*aclname
== '!') {
677 debug(15, 3) ("neighborAddAcl: looking for ACL name '%s'\n", aclname
);
678 a
= aclFindByName(aclname
);
680 debug(15, 0) ("%s line %d: %s\n",
681 cfg_filename
, config_lineno
, config_input_line
);
682 debug(15, 0) ("neighborAddAcl: ACL name '%s' not found.\n", aclname
);
687 for (Tail
= &p
->acls
; *Tail
; Tail
= &(*Tail
)->next
);
693 parse_hostdomain(void)
697 if (!(host
= strtok(NULL
, w_space
)))
699 while ((domain
= strtok(NULL
, list_sep
))) {
700 domain_ping
*l
= NULL
;
701 domain_ping
**L
= NULL
;
703 if ((p
= peerFindByName(host
)) == NULL
) {
704 debug(15, 0) ("%s, line %d: No cache_peer '%s'\n",
705 cfg_filename
, config_lineno
, host
);
708 l
= xcalloc(1, sizeof(struct _domain_ping
));
710 if (*domain
== '!') { /* check for !.edu */
714 l
->domain
= xstrdup(domain
);
715 for (L
= &(p
->pinglist
); *L
; L
= &((*L
)->next
));
721 parse_hostdomaintype(void)
726 if (!(host
= strtok(NULL
, w_space
)))
728 if (!(type
= strtok(NULL
, w_space
)))
730 while ((domain
= strtok(NULL
, list_sep
))) {
731 domain_type
*l
= NULL
;
732 domain_type
**L
= NULL
;
734 if ((p
= peerFindByName(host
)) == NULL
) {
735 debug(15, 0) ("%s, line %d: No cache_peer '%s'\n",
736 cfg_filename
, config_lineno
, host
);
739 l
= xcalloc(1, sizeof(struct _domain_type
));
740 l
->type
= parseNeighborType(type
);
741 l
->domain
= xstrdup(domain
);
742 for (L
= &(p
->typelist
); *L
; L
= &((*L
)->next
));
748 dump_httpanonymizer(StoreEntry
* entry
, const char *name
, int var
)
751 case ANONYMIZER_NONE
:
754 case ANONYMIZER_STANDARD
:
757 case ANONYMIZER_PARANOID
:
764 parse_httpanonymizer(int *var
)
767 token
= strtok(NULL
, w_space
);
770 if (!strcasecmp(token
, "off"))
771 *var
= ANONYMIZER_NONE
;
772 else if (!strcasecmp(token
, "paranoid"))
773 *var
= ANONYMIZER_PARANOID
;
775 *var
= ANONYMIZER_STANDARD
;
780 dump_ushortlist(StoreEntry
* entry
, const char *name
, ushortlist
* u
)
783 storeAppendPrintf(entry
, "%s %d\n", name
, (int) u
->i
);
789 check_null_ushortlist(ushortlist
* u
)
795 parse_ushortlist(ushortlist
** P
)
801 while ((token
= strtok(NULL
, w_space
))) {
802 if (sscanf(token
, "%d", &i
) != 1)
806 u
= xcalloc(1, sizeof(ushortlist
));
808 for (U
= P
; *U
; U
= &(*U
)->next
);
814 free_ushortlist(ushortlist
** P
)
817 while ((u
= *P
) != NULL
) {
824 dump_int(StoreEntry
* entry
, const char *name
, int var
)
826 storeAppendPrintf(entry
, "%s %d\n", name
, var
);
845 dump_onoff(StoreEntry
* entry
, const char *name
, int var
)
847 storeAppendPrintf(entry
, "%s %s\n", name
, var
? "on" : "off");
851 parse_onoff(int *var
)
853 char *token
= strtok(NULL
, w_space
);
857 if (!strcasecmp(token
, "on") || !strcasecmp(token
, "enable"))
863 #define free_onoff free_int
864 #define free_httpanonymizer free_int
865 #define dump_pathname_stat dump_string
866 #define free_pathname_stat free_string
867 #define dump_eol dump_string
868 #define free_eol free_string
871 parse_pathname_stat(char **path
)
875 if (stat(*path
, &sb
) < 0) {
876 debug(50, 1) ("parse_pathname_stat: %s: %s\n", *path
, xstrerror());
882 dump_refreshpattern(StoreEntry
* entry
, const char *name
, refresh_t
* head
)
884 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
888 parse_refreshpattern(refresh_t
** head
)
899 int flags
= REG_EXTENDED
| REG_NOSUB
;
900 if ((token
= strtok(NULL
, w_space
)) == NULL
)
902 if (strcmp(token
, "-i") == 0) {
904 token
= strtok(NULL
, w_space
);
905 } else if (strcmp(token
, "+i") == 0) {
907 token
= strtok(NULL
, w_space
);
911 pattern
= xstrdup(token
);
912 GetInteger(i
); /* token: min */
913 min
= (time_t) (i
* 60); /* convert minutes to seconds */
914 GetInteger(i
); /* token: pct */
916 GetInteger(i
); /* token: max */
917 max
= (time_t) (i
* 60); /* convert minutes to seconds */
918 if ((errcode
= regcomp(&comp
, pattern
, flags
)) != 0) {
920 regerror(errcode
, &comp
, errbuf
, sizeof errbuf
);
921 debug(22, 0) ("%s line %d: %s\n",
922 cfg_filename
, config_lineno
, config_input_line
);
923 debug(22, 0) ("refreshAddToList: Invalid regular expression '%s': %s\n",
927 pct
= pct
< 0 ? 0 : pct
;
928 max
= max
< 0 ? 0 : max
;
929 t
= xcalloc(1, sizeof(refresh_t
));
930 t
->pattern
= (char *) xstrdup(pattern
);
931 t
->compiled_pattern
= comp
;
937 head
= &(*head
)->next
;
943 free_refreshpattern(refresh_t
** head
)
946 while ((t
= *head
) != NULL
) {
948 safe_free(t
->pattern
);
949 regfree(&t
->compiled_pattern
);
955 dump_regexlist(StoreEntry
* entry
, const char *name
, relist
* var
)
957 storeAppendPrintf(entry
, "%s -- UNIMPLEMENTED\n", name
);
961 parse_regexlist(relist
** var
)
963 aclParseRegexList(var
);
967 free_regexlist(relist
** var
)
969 aclDestroyRegexList(*var
);
974 dump_string(StoreEntry
* entry
, const char *name
, char *var
)
977 storeAppendPrintf(entry
, "%s %s\n", name
, var
);
981 parse_string(char **var
)
983 char *token
= strtok(NULL
, w_space
);
987 *var
= xstrdup(token
);
991 free_string(char **var
)
998 parse_eol(char *volatile *var
)
1000 char *token
= strtok(NULL
, null_string
);
1004 *var
= xstrdup(token
);
1008 dump_time_t(StoreEntry
* entry
, const char *name
, time_t var
)
1010 storeAppendPrintf(entry
, "%s %d seconds\n", name
, (int) var
);
1014 parse_time_t(time_t * var
)
1016 parseTimeLine(var
, T_SECOND_STR
);
1020 free_time_t(time_t * var
)
1026 dump_size_t(StoreEntry
* entry
, const char *name
, size_t var
)
1028 storeAppendPrintf(entry
, "%s %d\n", name
, (int) var
);
1032 dump_b_size_t(StoreEntry
* entry
, const char *name
, size_t var
)
1034 storeAppendPrintf(entry
, "%s %d %s\n", name
, (int) var
, B_BYTES_STR
);
1038 dump_kb_size_t(StoreEntry
* entry
, const char *name
, size_t var
)
1040 storeAppendPrintf(entry
, "%s %d %s\n", name
, (int) var
, B_KBYTES_STR
);
1044 parse_size_t(size_t * var
)
1053 parse_b_size_t(size_t * var
)
1055 parseBytesLine(var
, B_BYTES_STR
);
1059 parse_kb_size_t(size_t * var
)
1061 parseBytesLine(var
, B_KBYTES_STR
);
1065 free_size_t(size_t * var
)
1070 #define free_b_size_t free_size_t
1071 #define free_kb_size_t free_size_t
1072 #define free_mb_size_t free_size_t
1073 #define free_gb_size_t free_size_t
1076 dump_ushort(StoreEntry
* entry
, const char *name
, u_short var
)
1078 storeAppendPrintf(entry
, "%s %d\n", name
, var
);
1082 free_ushort(u_short
* u
)
1088 parse_ushort(u_short
* var
)
1100 dump_wordlist(StoreEntry
* entry
, const char *name
, wordlist
* list
)
1102 while (list
!= NULL
) {
1103 storeAppendPrintf(entry
, "%s %s\n", name
, list
->key
);
1109 parse_wordlist(wordlist
** list
)
1113 while ((token
= strtok(NULL
, w_space
)))
1114 wordlistAdd(list
, token
);
1117 #define free_wordlist wordlistDestroy
1119 #include "cf_parser.c"
1122 parseNeighborType(const char *s
)
1124 if (!strcasecmp(s
, "parent"))
1126 if (!strcasecmp(s
, "neighbor"))
1127 return PEER_SIBLING
;
1128 if (!strcasecmp(s
, "neighbour"))
1129 return PEER_SIBLING
;
1130 if (!strcasecmp(s
, "sibling"))
1131 return PEER_SIBLING
;
1132 if (!strcasecmp(s
, "multicast"))
1133 return PEER_MULTICAST
;
1134 debug(15, 0) ("WARNING: Unknown neighbor type: %s\n", s
);
1135 return PEER_SIBLING
;
1139 configFreeMemory(void)