xref: /freebsd/usr.sbin/nscd/parser.c (revision ec8a394d9c676b3c4fd2cd721cf554e073736fc1)
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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