106a99fe3SHajimu UMEMOTO /*-
206a99fe3SHajimu UMEMOTO * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
306a99fe3SHajimu UMEMOTO * All rights reserved.
406a99fe3SHajimu UMEMOTO *
506a99fe3SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without
606a99fe3SHajimu UMEMOTO * modification, are permitted provided that the following conditions
706a99fe3SHajimu UMEMOTO * are met:
806a99fe3SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright
906a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer.
1006a99fe3SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright
1106a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the
1206a99fe3SHajimu UMEMOTO * documentation and/or other materials provided with the distribution.
1306a99fe3SHajimu UMEMOTO *
1406a99fe3SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1506a99fe3SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1606a99fe3SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1706a99fe3SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1806a99fe3SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1906a99fe3SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2006a99fe3SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2106a99fe3SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2206a99fe3SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2306a99fe3SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2406a99fe3SHajimu UMEMOTO * SUCH DAMAGE.
2506a99fe3SHajimu UMEMOTO *
2606a99fe3SHajimu UMEMOTO */
2706a99fe3SHajimu UMEMOTO
2806a99fe3SHajimu UMEMOTO #include <sys/cdefs.h>
2928f805ceSDag-Erling Smørgrav #include <sys/time.h>
3028f805ceSDag-Erling Smørgrav
3106a99fe3SHajimu UMEMOTO #include <assert.h>
3206a99fe3SHajimu UMEMOTO #include <stdio.h>
3328f805ceSDag-Erling Smørgrav #include <stdlib.h>
3406a99fe3SHajimu UMEMOTO #include <string.h>
3528f805ceSDag-Erling Smørgrav
3606a99fe3SHajimu UMEMOTO #include "config.h"
3706a99fe3SHajimu UMEMOTO #include "debug.h"
3806a99fe3SHajimu UMEMOTO #include "log.h"
3906a99fe3SHajimu UMEMOTO #include "parser.h"
4006a99fe3SHajimu UMEMOTO
4106a99fe3SHajimu UMEMOTO static void enable_cache(struct configuration *,const char *, int);
4206a99fe3SHajimu UMEMOTO static struct configuration_entry *find_create_entry(struct configuration *,
4306a99fe3SHajimu UMEMOTO const char *);
4406a99fe3SHajimu UMEMOTO static int get_number(const char *, int, int);
4506a99fe3SHajimu UMEMOTO static enum cache_policy_t get_policy(const char *);
4606a99fe3SHajimu UMEMOTO static int get_yesno(const char *);
4706a99fe3SHajimu UMEMOTO static int check_cachename(const char *);
4806a99fe3SHajimu UMEMOTO static void check_files(struct configuration *, const char *, int);
4906a99fe3SHajimu UMEMOTO static void set_keep_hot_count(struct configuration *, const char *, int);
5006a99fe3SHajimu UMEMOTO static void set_negative_policy(struct configuration *, const char *,
5106a99fe3SHajimu UMEMOTO enum cache_policy_t);
5206a99fe3SHajimu UMEMOTO static void set_negative_time_to_live(struct configuration *,
5306a99fe3SHajimu UMEMOTO const char *, int);
5406a99fe3SHajimu UMEMOTO static void set_positive_policy(struct configuration *, const char *,
5506a99fe3SHajimu UMEMOTO enum cache_policy_t);
5606a99fe3SHajimu UMEMOTO static void set_perform_actual_lookups(struct configuration *, const char *,
5706a99fe3SHajimu UMEMOTO int);
5806a99fe3SHajimu UMEMOTO static void set_positive_time_to_live(struct configuration *,
5906a99fe3SHajimu UMEMOTO const char *, int);
6006a99fe3SHajimu UMEMOTO static void set_suggested_size(struct configuration *, const char *,
6106a99fe3SHajimu UMEMOTO int size);
6206a99fe3SHajimu UMEMOTO static void set_threads_num(struct configuration *, int);
6306a99fe3SHajimu UMEMOTO static int strbreak(char *, char **, int);
6406a99fe3SHajimu UMEMOTO
6506a99fe3SHajimu UMEMOTO static int
strbreak(char * str,char ** fields,int fields_size)6606a99fe3SHajimu UMEMOTO strbreak(char *str, char **fields, int fields_size)
6706a99fe3SHajimu UMEMOTO {
6806a99fe3SHajimu UMEMOTO char *c = str;
6906a99fe3SHajimu UMEMOTO int i, num;
7006a99fe3SHajimu UMEMOTO
7106a99fe3SHajimu UMEMOTO TRACE_IN(strbreak);
7206a99fe3SHajimu UMEMOTO num = 0;
7306a99fe3SHajimu UMEMOTO for (i = 0;
7406a99fe3SHajimu UMEMOTO ((*fields =
7506a99fe3SHajimu UMEMOTO strsep(i < fields_size ? &c : NULL, "\n\t ")) != NULL);
7606a99fe3SHajimu UMEMOTO ++i)
7706a99fe3SHajimu UMEMOTO if ((*(*fields)) != '\0') {
7806a99fe3SHajimu UMEMOTO ++fields;
7906a99fe3SHajimu UMEMOTO ++num;
8006a99fe3SHajimu UMEMOTO }
8106a99fe3SHajimu UMEMOTO
8206a99fe3SHajimu UMEMOTO TRACE_OUT(strbreak);
8306a99fe3SHajimu UMEMOTO return (num);
8406a99fe3SHajimu UMEMOTO }
8506a99fe3SHajimu UMEMOTO
8606a99fe3SHajimu UMEMOTO /*
8706a99fe3SHajimu UMEMOTO * Tries to find the configuration entry with the specified name. If search
8806a99fe3SHajimu UMEMOTO * fails, the new entry with the default parameters will be created.
8906a99fe3SHajimu UMEMOTO */
9006a99fe3SHajimu UMEMOTO static struct configuration_entry *
find_create_entry(struct configuration * config,const char * entry_name)9106a99fe3SHajimu UMEMOTO find_create_entry(struct configuration *config,
9206a99fe3SHajimu UMEMOTO const char *entry_name)
9306a99fe3SHajimu UMEMOTO {
9406a99fe3SHajimu UMEMOTO struct configuration_entry *entry = NULL;
9506a99fe3SHajimu UMEMOTO int res;
9606a99fe3SHajimu UMEMOTO
9706a99fe3SHajimu UMEMOTO TRACE_IN(find_create_entry);
9806a99fe3SHajimu UMEMOTO entry = configuration_find_entry(config, entry_name);
9906a99fe3SHajimu UMEMOTO if (entry == NULL) {
10006a99fe3SHajimu UMEMOTO entry = create_def_configuration_entry(entry_name);
10106a99fe3SHajimu UMEMOTO assert( entry != NULL);
10206a99fe3SHajimu UMEMOTO res = add_configuration_entry(config, entry);
10306a99fe3SHajimu UMEMOTO assert(res == 0);
10406a99fe3SHajimu UMEMOTO }
10506a99fe3SHajimu UMEMOTO
10606a99fe3SHajimu UMEMOTO TRACE_OUT(find_create_entry);
10706a99fe3SHajimu UMEMOTO return (entry);
10806a99fe3SHajimu UMEMOTO }
10906a99fe3SHajimu UMEMOTO
11006a99fe3SHajimu UMEMOTO /*
11106a99fe3SHajimu UMEMOTO * The vast majority of the functions below corresponds to the particular
11206a99fe3SHajimu UMEMOTO * keywords in the configuration file.
11306a99fe3SHajimu UMEMOTO */
11406a99fe3SHajimu UMEMOTO static void
enable_cache(struct configuration * config,const char * entry_name,int flag)11506a99fe3SHajimu UMEMOTO enable_cache(struct configuration *config, const char *entry_name, int flag)
11606a99fe3SHajimu UMEMOTO {
11706a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
11806a99fe3SHajimu UMEMOTO
11906a99fe3SHajimu UMEMOTO TRACE_IN(enable_cache);
12006a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
12106a99fe3SHajimu UMEMOTO entry->enabled = flag;
12206a99fe3SHajimu UMEMOTO TRACE_OUT(enable_cache);
12306a99fe3SHajimu UMEMOTO }
12406a99fe3SHajimu UMEMOTO
12506a99fe3SHajimu UMEMOTO static void
set_positive_time_to_live(struct configuration * config,const char * entry_name,int ttl)12606a99fe3SHajimu UMEMOTO set_positive_time_to_live(struct configuration *config,
12706a99fe3SHajimu UMEMOTO const char *entry_name, int ttl)
12806a99fe3SHajimu UMEMOTO {
12906a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
13006a99fe3SHajimu UMEMOTO struct timeval lifetime;
13106a99fe3SHajimu UMEMOTO
13206a99fe3SHajimu UMEMOTO TRACE_IN(set_positive_time_to_live);
13306a99fe3SHajimu UMEMOTO assert(ttl >= 0);
13406a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
13506a99fe3SHajimu UMEMOTO memset(&lifetime, 0, sizeof(struct timeval));
13606a99fe3SHajimu UMEMOTO lifetime.tv_sec = ttl;
13706a99fe3SHajimu UMEMOTO
13806a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
13906a99fe3SHajimu UMEMOTO memcpy(&entry->positive_cache_params.max_lifetime,
14006a99fe3SHajimu UMEMOTO &lifetime, sizeof(struct timeval));
14106a99fe3SHajimu UMEMOTO memcpy(&entry->mp_cache_params.max_lifetime,
14206a99fe3SHajimu UMEMOTO &lifetime, sizeof(struct timeval));
14306a99fe3SHajimu UMEMOTO
14406a99fe3SHajimu UMEMOTO TRACE_OUT(set_positive_time_to_live);
14506a99fe3SHajimu UMEMOTO }
14606a99fe3SHajimu UMEMOTO
14706a99fe3SHajimu UMEMOTO static void
set_negative_time_to_live(struct configuration * config,const char * entry_name,int nttl)14806a99fe3SHajimu UMEMOTO set_negative_time_to_live(struct configuration *config,
14906a99fe3SHajimu UMEMOTO const char *entry_name, int nttl)
15006a99fe3SHajimu UMEMOTO {
15106a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
15206a99fe3SHajimu UMEMOTO struct timeval lifetime;
15306a99fe3SHajimu UMEMOTO
15406a99fe3SHajimu UMEMOTO TRACE_IN(set_negative_time_to_live);
15506a99fe3SHajimu UMEMOTO assert(nttl > 0);
15606a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
15706a99fe3SHajimu UMEMOTO memset(&lifetime, 0, sizeof(struct timeval));
15806a99fe3SHajimu UMEMOTO lifetime.tv_sec = nttl;
15906a99fe3SHajimu UMEMOTO
16006a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
16106a99fe3SHajimu UMEMOTO assert(entry != NULL);
16206a99fe3SHajimu UMEMOTO memcpy(&entry->negative_cache_params.max_lifetime,
16306a99fe3SHajimu UMEMOTO &lifetime, sizeof(struct timeval));
16406a99fe3SHajimu UMEMOTO
16506a99fe3SHajimu UMEMOTO TRACE_OUT(set_negative_time_to_live);
16606a99fe3SHajimu UMEMOTO }
16706a99fe3SHajimu UMEMOTO
168a397989dSStefan Eßer static void
set_positive_confidence_threshold(struct configuration * config,const char * entry_name,int conf_thresh)169a397989dSStefan Eßer set_positive_confidence_threshold(struct configuration *config,
170a397989dSStefan Eßer const char *entry_name, int conf_thresh)
171a397989dSStefan Eßer {
172a397989dSStefan Eßer struct configuration_entry *entry;
173a397989dSStefan Eßer
174a397989dSStefan Eßer TRACE_IN(set_positive_conf_thresh);
175a397989dSStefan Eßer assert(conf_thresh > 0);
176a397989dSStefan Eßer assert(entry_name != NULL);
177a397989dSStefan Eßer
178a397989dSStefan Eßer entry = find_create_entry(config, entry_name);
179a397989dSStefan Eßer assert(entry != NULL);
180a397989dSStefan Eßer entry->positive_cache_params.confidence_threshold = conf_thresh;
181a397989dSStefan Eßer
182a397989dSStefan Eßer TRACE_OUT(set_positive_conf_thresh);
183a397989dSStefan Eßer }
184a397989dSStefan Eßer
185a397989dSStefan Eßer static void
set_negative_confidence_threshold(struct configuration * config,const char * entry_name,int conf_thresh)186a397989dSStefan Eßer set_negative_confidence_threshold(struct configuration *config,
187a397989dSStefan Eßer const char *entry_name, int conf_thresh)
188a397989dSStefan Eßer {
189a397989dSStefan Eßer struct configuration_entry *entry;
190a397989dSStefan Eßer
191a397989dSStefan Eßer TRACE_IN(set_negative_conf_thresh);
192a397989dSStefan Eßer assert(conf_thresh > 0);
193a397989dSStefan Eßer assert(entry_name != NULL);
194a397989dSStefan Eßer entry = find_create_entry(config, entry_name);
195a397989dSStefan Eßer assert(entry != NULL);
196a397989dSStefan Eßer entry->negative_cache_params.confidence_threshold = conf_thresh;
197a397989dSStefan Eßer TRACE_OUT(set_negative_conf_thresh);
198a397989dSStefan Eßer }
199a397989dSStefan Eßer
20006a99fe3SHajimu UMEMOTO /*
20106a99fe3SHajimu UMEMOTO * Hot count is actually the elements size limit.
20206a99fe3SHajimu UMEMOTO */
20306a99fe3SHajimu UMEMOTO static void
set_keep_hot_count(struct configuration * config,const char * entry_name,int count)20406a99fe3SHajimu UMEMOTO set_keep_hot_count(struct configuration *config,
20506a99fe3SHajimu UMEMOTO const char *entry_name, int count)
20606a99fe3SHajimu UMEMOTO {
20706a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
20806a99fe3SHajimu UMEMOTO
20906a99fe3SHajimu UMEMOTO TRACE_IN(set_keep_hot_count);
21006a99fe3SHajimu UMEMOTO assert(count >= 0);
21106a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
21206a99fe3SHajimu UMEMOTO
21306a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
21406a99fe3SHajimu UMEMOTO assert(entry != NULL);
21506a99fe3SHajimu UMEMOTO entry->positive_cache_params.max_elemsize = count;
21606a99fe3SHajimu UMEMOTO
21706a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
21806a99fe3SHajimu UMEMOTO assert(entry != NULL);
21906a99fe3SHajimu UMEMOTO entry->negative_cache_params.max_elemsize = count;
22006a99fe3SHajimu UMEMOTO
22106a99fe3SHajimu UMEMOTO TRACE_OUT(set_keep_hot_count);
22206a99fe3SHajimu UMEMOTO }
22306a99fe3SHajimu UMEMOTO
22406a99fe3SHajimu UMEMOTO static void
set_positive_policy(struct configuration * config,const char * entry_name,enum cache_policy_t policy)22506a99fe3SHajimu UMEMOTO set_positive_policy(struct configuration *config,
22606a99fe3SHajimu UMEMOTO const char *entry_name, enum cache_policy_t policy)
22706a99fe3SHajimu UMEMOTO {
22806a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
22906a99fe3SHajimu UMEMOTO
23006a99fe3SHajimu UMEMOTO TRACE_IN(set_positive_policy);
23106a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
23206a99fe3SHajimu UMEMOTO
23306a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
23406a99fe3SHajimu UMEMOTO assert(entry != NULL);
23506a99fe3SHajimu UMEMOTO entry->positive_cache_params.policy = policy;
23606a99fe3SHajimu UMEMOTO
23706a99fe3SHajimu UMEMOTO TRACE_OUT(set_positive_policy);
23806a99fe3SHajimu UMEMOTO }
23906a99fe3SHajimu UMEMOTO
24006a99fe3SHajimu UMEMOTO static void
set_negative_policy(struct configuration * config,const char * entry_name,enum cache_policy_t policy)24106a99fe3SHajimu UMEMOTO set_negative_policy(struct configuration *config,
24206a99fe3SHajimu UMEMOTO const char *entry_name, enum cache_policy_t policy)
24306a99fe3SHajimu UMEMOTO {
24406a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
24506a99fe3SHajimu UMEMOTO
24606a99fe3SHajimu UMEMOTO TRACE_IN(set_negative_policy);
24706a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
24806a99fe3SHajimu UMEMOTO
24906a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
25006a99fe3SHajimu UMEMOTO assert(entry != NULL);
25106a99fe3SHajimu UMEMOTO entry->negative_cache_params.policy = policy;
25206a99fe3SHajimu UMEMOTO
25306a99fe3SHajimu UMEMOTO TRACE_OUT(set_negative_policy);
25406a99fe3SHajimu UMEMOTO }
25506a99fe3SHajimu UMEMOTO
25606a99fe3SHajimu UMEMOTO static void
set_perform_actual_lookups(struct configuration * config,const char * entry_name,int flag)25706a99fe3SHajimu UMEMOTO set_perform_actual_lookups(struct configuration *config,
25806a99fe3SHajimu UMEMOTO const char *entry_name, int flag)
25906a99fe3SHajimu UMEMOTO {
26006a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
26106a99fe3SHajimu UMEMOTO
26206a99fe3SHajimu UMEMOTO TRACE_IN(set_perform_actual_lookups);
26306a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
26406a99fe3SHajimu UMEMOTO
26506a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
26606a99fe3SHajimu UMEMOTO assert(entry != NULL);
26706a99fe3SHajimu UMEMOTO entry->perform_actual_lookups = flag;
26806a99fe3SHajimu UMEMOTO
26906a99fe3SHajimu UMEMOTO TRACE_OUT(set_perform_actual_lookups);
27006a99fe3SHajimu UMEMOTO }
27106a99fe3SHajimu UMEMOTO
27206a99fe3SHajimu UMEMOTO static void
set_suggested_size(struct configuration * config,const char * entry_name,int size)27306a99fe3SHajimu UMEMOTO set_suggested_size(struct configuration *config,
27406a99fe3SHajimu UMEMOTO const char *entry_name, int size)
27506a99fe3SHajimu UMEMOTO {
27606a99fe3SHajimu UMEMOTO struct configuration_entry *entry;
27706a99fe3SHajimu UMEMOTO
27806a99fe3SHajimu UMEMOTO TRACE_IN(set_suggested_size);
27906a99fe3SHajimu UMEMOTO assert(config != NULL);
28006a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
28106a99fe3SHajimu UMEMOTO assert(size > 0);
28206a99fe3SHajimu UMEMOTO
28306a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name);
28406a99fe3SHajimu UMEMOTO assert(entry != NULL);
28506a99fe3SHajimu UMEMOTO entry->positive_cache_params.cache_entries_size = size;
28606a99fe3SHajimu UMEMOTO entry->negative_cache_params.cache_entries_size = size;
28706a99fe3SHajimu UMEMOTO
28806a99fe3SHajimu UMEMOTO TRACE_OUT(set_suggested_size);
28906a99fe3SHajimu UMEMOTO }
29006a99fe3SHajimu UMEMOTO
29106a99fe3SHajimu UMEMOTO static void
check_files(struct configuration * config,const char * entry_name,int flag)29206a99fe3SHajimu UMEMOTO check_files(struct configuration *config, const char *entry_name, int flag)
29306a99fe3SHajimu UMEMOTO {
29406a99fe3SHajimu UMEMOTO
29506a99fe3SHajimu UMEMOTO TRACE_IN(check_files);
29606a99fe3SHajimu UMEMOTO assert(entry_name != NULL);
29706a99fe3SHajimu UMEMOTO TRACE_OUT(check_files);
29806a99fe3SHajimu UMEMOTO }
29906a99fe3SHajimu UMEMOTO
30006a99fe3SHajimu UMEMOTO static int
get_yesno(const char * str)30106a99fe3SHajimu UMEMOTO get_yesno(const char *str)
30206a99fe3SHajimu UMEMOTO {
30306a99fe3SHajimu UMEMOTO
30406a99fe3SHajimu UMEMOTO if (strcmp(str, "yes") == 0)
30506a99fe3SHajimu UMEMOTO return (1);
30606a99fe3SHajimu UMEMOTO else if (strcmp(str, "no") == 0)
30706a99fe3SHajimu UMEMOTO return (0);
30806a99fe3SHajimu UMEMOTO else
30906a99fe3SHajimu UMEMOTO return (-1);
31006a99fe3SHajimu UMEMOTO }
31106a99fe3SHajimu UMEMOTO
31206a99fe3SHajimu UMEMOTO static int
get_number(const char * str,int low,int max)31306a99fe3SHajimu UMEMOTO get_number(const char *str, int low, int max)
31406a99fe3SHajimu UMEMOTO {
31506a99fe3SHajimu UMEMOTO
31606a99fe3SHajimu UMEMOTO char *end = NULL;
31706a99fe3SHajimu UMEMOTO int res = 0;
31806a99fe3SHajimu UMEMOTO
31906a99fe3SHajimu UMEMOTO if (str[0] == '\0')
32006a99fe3SHajimu UMEMOTO return (-1);
32106a99fe3SHajimu UMEMOTO
32206a99fe3SHajimu UMEMOTO res = strtol(str, &end, 10);
32306a99fe3SHajimu UMEMOTO if (*end != '\0')
32406a99fe3SHajimu UMEMOTO return (-1);
32506a99fe3SHajimu UMEMOTO else
32606a99fe3SHajimu UMEMOTO if (((res >= low) || (low == -1)) &&
32706a99fe3SHajimu UMEMOTO ((res <= max) || (max == -1)))
32806a99fe3SHajimu UMEMOTO return (res);
32906a99fe3SHajimu UMEMOTO else
33006a99fe3SHajimu UMEMOTO return (-2);
33106a99fe3SHajimu UMEMOTO }
33206a99fe3SHajimu UMEMOTO
33306a99fe3SHajimu UMEMOTO static enum cache_policy_t
get_policy(const char * str)33406a99fe3SHajimu UMEMOTO get_policy(const char *str)
33506a99fe3SHajimu UMEMOTO {
33606a99fe3SHajimu UMEMOTO
33706a99fe3SHajimu UMEMOTO if (strcmp(str, "fifo") == 0)
33806a99fe3SHajimu UMEMOTO return (CPT_FIFO);
33906a99fe3SHajimu UMEMOTO else if (strcmp(str, "lru") == 0)
34006a99fe3SHajimu UMEMOTO return (CPT_LRU);
34106a99fe3SHajimu UMEMOTO else if (strcmp(str, "lfu") == 0)
34206a99fe3SHajimu UMEMOTO return (CPT_LFU);
34306a99fe3SHajimu UMEMOTO
34406a99fe3SHajimu UMEMOTO return (-1);
34506a99fe3SHajimu UMEMOTO }
34606a99fe3SHajimu UMEMOTO
34706a99fe3SHajimu UMEMOTO static int
check_cachename(const char * str)34806a99fe3SHajimu UMEMOTO check_cachename(const char *str)
34906a99fe3SHajimu UMEMOTO {
35006a99fe3SHajimu UMEMOTO
35106a99fe3SHajimu UMEMOTO assert(str != NULL);
35206a99fe3SHajimu UMEMOTO return ((strlen(str) > 0) ? 0 : -1);
35306a99fe3SHajimu UMEMOTO }
35406a99fe3SHajimu UMEMOTO
35506a99fe3SHajimu UMEMOTO static void
set_threads_num(struct configuration * config,int value)35606a99fe3SHajimu UMEMOTO set_threads_num(struct configuration *config, int value)
35706a99fe3SHajimu UMEMOTO {
35806a99fe3SHajimu UMEMOTO
35906a99fe3SHajimu UMEMOTO assert(config != NULL);
36006a99fe3SHajimu UMEMOTO config->threads_num = value;
36106a99fe3SHajimu UMEMOTO }
36206a99fe3SHajimu UMEMOTO
36306a99fe3SHajimu UMEMOTO /*
36406a99fe3SHajimu UMEMOTO * The main configuration routine. Its implementation is hugely inspired by the
365*ec8a394dSElyes Haouas * same routine implementation in Solaris NSCD.
36606a99fe3SHajimu UMEMOTO */
36706a99fe3SHajimu UMEMOTO int
parse_config_file(struct configuration * config,const char * fname,char const ** error_str,int * error_line)36806a99fe3SHajimu UMEMOTO parse_config_file(struct configuration *config,
36906a99fe3SHajimu UMEMOTO const char *fname, char const **error_str, int *error_line)
37006a99fe3SHajimu UMEMOTO {
37106a99fe3SHajimu UMEMOTO FILE *fin;
37206a99fe3SHajimu UMEMOTO char buffer[255];
37306a99fe3SHajimu UMEMOTO char *fields[128];
37406a99fe3SHajimu UMEMOTO int field_count, line_num, value;
37506a99fe3SHajimu UMEMOTO int res;
37686e88c4fSAllan Jude int invalid_value;
37706a99fe3SHajimu UMEMOTO
37806a99fe3SHajimu UMEMOTO TRACE_IN(parse_config_file);
37906a99fe3SHajimu UMEMOTO assert(config != NULL);
38006a99fe3SHajimu UMEMOTO assert(fname != NULL);
38106a99fe3SHajimu UMEMOTO
38206a99fe3SHajimu UMEMOTO fin = fopen(fname, "r");
38306a99fe3SHajimu UMEMOTO if (fin == NULL) {
38406a99fe3SHajimu UMEMOTO TRACE_OUT(parse_config_file);
38506a99fe3SHajimu UMEMOTO return (-1);
38606a99fe3SHajimu UMEMOTO }
38706a99fe3SHajimu UMEMOTO
38806a99fe3SHajimu UMEMOTO res = 0;
38906a99fe3SHajimu UMEMOTO line_num = 0;
39086e88c4fSAllan Jude invalid_value = 0;
39106a99fe3SHajimu UMEMOTO memset(buffer, 0, sizeof(buffer));
39206a99fe3SHajimu UMEMOTO while ((res == 0) && (fgets(buffer, sizeof(buffer) - 1, fin) != NULL)) {
39306a99fe3SHajimu UMEMOTO field_count = strbreak(buffer, fields, sizeof(fields));
39406a99fe3SHajimu UMEMOTO ++line_num;
39506a99fe3SHajimu UMEMOTO
39606a99fe3SHajimu UMEMOTO if (field_count == 0)
39706a99fe3SHajimu UMEMOTO continue;
39806a99fe3SHajimu UMEMOTO
39906a99fe3SHajimu UMEMOTO switch (fields[0][0]) {
40006a99fe3SHajimu UMEMOTO case '#':
40106a99fe3SHajimu UMEMOTO case '\0':
40206a99fe3SHajimu UMEMOTO continue;
40306a99fe3SHajimu UMEMOTO case 'e':
40406a99fe3SHajimu UMEMOTO if ((field_count == 3) &&
40506a99fe3SHajimu UMEMOTO (strcmp(fields[0], "enable-cache") == 0) &&
40606a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
40706a99fe3SHajimu UMEMOTO ((value = get_yesno(fields[2])) != -1)) {
40806a99fe3SHajimu UMEMOTO enable_cache(config, fields[1], value);
40906a99fe3SHajimu UMEMOTO continue;
41006a99fe3SHajimu UMEMOTO }
41106a99fe3SHajimu UMEMOTO break;
41206a99fe3SHajimu UMEMOTO case 'd':
41306a99fe3SHajimu UMEMOTO if ((field_count == 2) &&
41406a99fe3SHajimu UMEMOTO (strcmp(fields[0], "debug-level") == 0) &&
41506a99fe3SHajimu UMEMOTO ((value = get_number(fields[1], 0, 10)) != -1)) {
41606a99fe3SHajimu UMEMOTO continue;
41706a99fe3SHajimu UMEMOTO }
41806a99fe3SHajimu UMEMOTO break;
41906a99fe3SHajimu UMEMOTO case 'p':
42006a99fe3SHajimu UMEMOTO if ((field_count == 3) &&
42106a99fe3SHajimu UMEMOTO (strcmp(fields[0], "positive-time-to-live") == 0) &&
42206a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
42306a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 0, -1)) != -1)) {
42486e88c4fSAllan Jude if (value <= 0) {
42586e88c4fSAllan Jude invalid_value = 1;
42686e88c4fSAllan Jude break;
42786e88c4fSAllan Jude }
42806a99fe3SHajimu UMEMOTO set_positive_time_to_live(config,
42906a99fe3SHajimu UMEMOTO fields[1], value);
43006a99fe3SHajimu UMEMOTO continue;
43106a99fe3SHajimu UMEMOTO } else if ((field_count == 3) &&
432a397989dSStefan Eßer (strcmp(fields[0], "positive-confidence-threshold") == 0) &&
433a397989dSStefan Eßer ((value = get_number(fields[2], 1, -1)) != -1)) {
43486e88c4fSAllan Jude if (value <= 0) {
43586e88c4fSAllan Jude invalid_value = 1;
43686e88c4fSAllan Jude break;
43786e88c4fSAllan Jude }
438a397989dSStefan Eßer set_positive_confidence_threshold(config,
439a397989dSStefan Eßer fields[1], value);
440a397989dSStefan Eßer continue;
441a397989dSStefan Eßer } else if ((field_count == 3) &&
44206a99fe3SHajimu UMEMOTO (strcmp(fields[0], "positive-policy") == 0) &&
44306a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
44406a99fe3SHajimu UMEMOTO ((value = get_policy(fields[2])) != -1)) {
44506a99fe3SHajimu UMEMOTO set_positive_policy(config, fields[1], value);
44606a99fe3SHajimu UMEMOTO continue;
44706a99fe3SHajimu UMEMOTO } else if ((field_count == 3) &&
44806a99fe3SHajimu UMEMOTO (strcmp(fields[0], "perform-actual-lookups") == 0) &&
44906a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
45006a99fe3SHajimu UMEMOTO ((value = get_yesno(fields[2])) != -1)) {
45106a99fe3SHajimu UMEMOTO set_perform_actual_lookups(config, fields[1],
45206a99fe3SHajimu UMEMOTO value);
45306a99fe3SHajimu UMEMOTO continue;
45406a99fe3SHajimu UMEMOTO }
45506a99fe3SHajimu UMEMOTO break;
45606a99fe3SHajimu UMEMOTO case 'n':
45706a99fe3SHajimu UMEMOTO if ((field_count == 3) &&
45806a99fe3SHajimu UMEMOTO (strcmp(fields[0], "negative-time-to-live") == 0) &&
45906a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
46006a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 0, -1)) != -1)) {
46186e88c4fSAllan Jude if (value <= 0) {
46286e88c4fSAllan Jude invalid_value = 1;
46386e88c4fSAllan Jude break;
46486e88c4fSAllan Jude }
46506a99fe3SHajimu UMEMOTO set_negative_time_to_live(config,
46606a99fe3SHajimu UMEMOTO fields[1], value);
46706a99fe3SHajimu UMEMOTO continue;
46806a99fe3SHajimu UMEMOTO } else if ((field_count == 3) &&
469a397989dSStefan Eßer (strcmp(fields[0], "negative-confidence-threshold") == 0) &&
470a397989dSStefan Eßer ((value = get_number(fields[2], 1, -1)) != -1)) {
47186e88c4fSAllan Jude if (value <= 0) {
47286e88c4fSAllan Jude invalid_value = 1;
47386e88c4fSAllan Jude break;
47486e88c4fSAllan Jude }
475a397989dSStefan Eßer set_negative_confidence_threshold(config,
476a397989dSStefan Eßer fields[1], value);
477a397989dSStefan Eßer continue;
478a397989dSStefan Eßer } else if ((field_count == 3) &&
47906a99fe3SHajimu UMEMOTO (strcmp(fields[0], "negative-policy") == 0) &&
48006a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
48106a99fe3SHajimu UMEMOTO ((value = get_policy(fields[2])) != -1)) {
48206a99fe3SHajimu UMEMOTO set_negative_policy(config,
48306a99fe3SHajimu UMEMOTO fields[1], value);
48406a99fe3SHajimu UMEMOTO continue;
48506a99fe3SHajimu UMEMOTO }
48606a99fe3SHajimu UMEMOTO break;
48706a99fe3SHajimu UMEMOTO case 's':
48806a99fe3SHajimu UMEMOTO if ((field_count == 3) &&
48906a99fe3SHajimu UMEMOTO (strcmp(fields[0], "suggested-size") == 0) &&
49006a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
49106a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 1, -1)) != -1)) {
49286e88c4fSAllan Jude if (value <= 0) {
49386e88c4fSAllan Jude invalid_value = 1;
49486e88c4fSAllan Jude break;
49586e88c4fSAllan Jude }
49606a99fe3SHajimu UMEMOTO set_suggested_size(config, fields[1], value);
49706a99fe3SHajimu UMEMOTO continue;
49806a99fe3SHajimu UMEMOTO }
49906a99fe3SHajimu UMEMOTO break;
50006a99fe3SHajimu UMEMOTO case 't':
50106a99fe3SHajimu UMEMOTO if ((field_count == 2) &&
50206a99fe3SHajimu UMEMOTO (strcmp(fields[0], "threads") == 0) &&
50306a99fe3SHajimu UMEMOTO ((value = get_number(fields[1], 1, -1)) != -1)) {
50406a99fe3SHajimu UMEMOTO set_threads_num(config, value);
50506a99fe3SHajimu UMEMOTO continue;
50606a99fe3SHajimu UMEMOTO }
50706a99fe3SHajimu UMEMOTO break;
50806a99fe3SHajimu UMEMOTO case 'k':
50906a99fe3SHajimu UMEMOTO if ((field_count == 3) &&
51006a99fe3SHajimu UMEMOTO (strcmp(fields[0], "keep-hot-count") == 0) &&
51106a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
51206a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 0, -1)) != -1)) {
51386e88c4fSAllan Jude if (value < 0) {
51486e88c4fSAllan Jude invalid_value = 1;
51586e88c4fSAllan Jude break;
51686e88c4fSAllan Jude }
51706a99fe3SHajimu UMEMOTO set_keep_hot_count(config,
51806a99fe3SHajimu UMEMOTO fields[1], value);
51906a99fe3SHajimu UMEMOTO continue;
52006a99fe3SHajimu UMEMOTO }
52106a99fe3SHajimu UMEMOTO break;
52206a99fe3SHajimu UMEMOTO case 'c':
52306a99fe3SHajimu UMEMOTO if ((field_count == 3) &&
52406a99fe3SHajimu UMEMOTO (strcmp(fields[0], "check-files") == 0) &&
52506a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) &&
52606a99fe3SHajimu UMEMOTO ((value = get_yesno(fields[2])) != -1)) {
52706a99fe3SHajimu UMEMOTO check_files(config,
52806a99fe3SHajimu UMEMOTO fields[1], value);
52906a99fe3SHajimu UMEMOTO continue;
53006a99fe3SHajimu UMEMOTO }
53106a99fe3SHajimu UMEMOTO break;
53206a99fe3SHajimu UMEMOTO default:
53306a99fe3SHajimu UMEMOTO break;
53406a99fe3SHajimu UMEMOTO }
53506a99fe3SHajimu UMEMOTO
53686e88c4fSAllan Jude if (invalid_value != 0) {
53786e88c4fSAllan Jude LOG_ERR_2("Invalid value for parameter",
53886e88c4fSAllan Jude "error in file %s on line %d",
53986e88c4fSAllan Jude fname, line_num);
54086e88c4fSAllan Jude *error_str = "invalid value";
54186e88c4fSAllan Jude } else {
54206a99fe3SHajimu UMEMOTO LOG_ERR_2("config file parser", "error in file "
54306a99fe3SHajimu UMEMOTO "%s on line %d", fname, line_num);
54406a99fe3SHajimu UMEMOTO *error_str = "syntax error";
54586e88c4fSAllan Jude }
54606a99fe3SHajimu UMEMOTO *error_line = line_num;
54706a99fe3SHajimu UMEMOTO res = -1;
54806a99fe3SHajimu UMEMOTO }
54906a99fe3SHajimu UMEMOTO fclose(fin);
55006a99fe3SHajimu UMEMOTO
55106a99fe3SHajimu UMEMOTO TRACE_OUT(parse_config_file);
55206a99fe3SHajimu UMEMOTO return (res);
55306a99fe3SHajimu UMEMOTO }
554