xref: /freebsd/usr.sbin/nscd/parser.c (revision 28f805cece978c1041c648b0b968094506bcc1e6)
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>
2906a99fe3SHajimu UMEMOTO __FBSDID("$FreeBSD$");
3006a99fe3SHajimu UMEMOTO 
3128f805ceSDag-Erling Smørgrav #include <sys/time.h>
3228f805ceSDag-Erling Smørgrav 
3306a99fe3SHajimu UMEMOTO #include <assert.h>
3406a99fe3SHajimu UMEMOTO #include <stdio.h>
3528f805ceSDag-Erling Smørgrav #include <stdlib.h>
3606a99fe3SHajimu UMEMOTO #include <string.h>
3728f805ceSDag-Erling Smørgrav 
3806a99fe3SHajimu UMEMOTO #include "config.h"
3906a99fe3SHajimu UMEMOTO #include "debug.h"
4006a99fe3SHajimu UMEMOTO #include "log.h"
4106a99fe3SHajimu UMEMOTO #include "parser.h"
4206a99fe3SHajimu UMEMOTO 
4306a99fe3SHajimu UMEMOTO static void enable_cache(struct configuration *,const char *, int);
4406a99fe3SHajimu UMEMOTO static struct configuration_entry *find_create_entry(struct configuration *,
4506a99fe3SHajimu UMEMOTO 	const char *);
4606a99fe3SHajimu UMEMOTO static int get_number(const char *, int, int);
4706a99fe3SHajimu UMEMOTO static enum cache_policy_t get_policy(const char *);
4806a99fe3SHajimu UMEMOTO static int get_yesno(const char *);
4906a99fe3SHajimu UMEMOTO static int check_cachename(const char *);
5006a99fe3SHajimu UMEMOTO static void check_files(struct configuration *, const char *, int);
5106a99fe3SHajimu UMEMOTO static void set_keep_hot_count(struct configuration *, const char *, int);
5206a99fe3SHajimu UMEMOTO static void set_negative_policy(struct configuration *, const char *,
5306a99fe3SHajimu UMEMOTO 	enum cache_policy_t);
5406a99fe3SHajimu UMEMOTO static void set_negative_time_to_live(struct configuration *,
5506a99fe3SHajimu UMEMOTO 	const char *, int);
5606a99fe3SHajimu UMEMOTO static void set_positive_policy(struct configuration *, const char *,
5706a99fe3SHajimu UMEMOTO 	enum cache_policy_t);
5806a99fe3SHajimu UMEMOTO static void set_perform_actual_lookups(struct configuration *, const char *,
5906a99fe3SHajimu UMEMOTO 	int);
6006a99fe3SHajimu UMEMOTO static void set_positive_time_to_live(struct configuration *,
6106a99fe3SHajimu UMEMOTO 	const char *, int);
6206a99fe3SHajimu UMEMOTO static void set_suggested_size(struct configuration *, const char *,
6306a99fe3SHajimu UMEMOTO 	int size);
6406a99fe3SHajimu UMEMOTO static void set_threads_num(struct configuration *, int);
6506a99fe3SHajimu UMEMOTO static int strbreak(char *, char **, int);
6606a99fe3SHajimu UMEMOTO 
6706a99fe3SHajimu UMEMOTO static int
6806a99fe3SHajimu UMEMOTO strbreak(char *str, char **fields, int fields_size)
6906a99fe3SHajimu UMEMOTO {
7006a99fe3SHajimu UMEMOTO 	char	*c = str;
7106a99fe3SHajimu UMEMOTO 	int	i, num;
7206a99fe3SHajimu UMEMOTO 
7306a99fe3SHajimu UMEMOTO 	TRACE_IN(strbreak);
7406a99fe3SHajimu UMEMOTO 	num = 0;
7506a99fe3SHajimu UMEMOTO 	for (i = 0;
7606a99fe3SHajimu UMEMOTO 	     ((*fields =
7706a99fe3SHajimu UMEMOTO 	     	strsep(i < fields_size ? &c : NULL, "\n\t ")) != NULL);
7806a99fe3SHajimu UMEMOTO 	     ++i)
7906a99fe3SHajimu UMEMOTO 		if ((*(*fields)) != '\0') {
8006a99fe3SHajimu UMEMOTO 			++fields;
8106a99fe3SHajimu UMEMOTO 			++num;
8206a99fe3SHajimu UMEMOTO 		}
8306a99fe3SHajimu UMEMOTO 
8406a99fe3SHajimu UMEMOTO 	TRACE_OUT(strbreak);
8506a99fe3SHajimu UMEMOTO 	return (num);
8606a99fe3SHajimu UMEMOTO }
8706a99fe3SHajimu UMEMOTO 
8806a99fe3SHajimu UMEMOTO /*
8906a99fe3SHajimu UMEMOTO  * Tries to find the configuration entry with the specified name. If search
9006a99fe3SHajimu UMEMOTO  * fails, the new entry with the default parameters will be created.
9106a99fe3SHajimu UMEMOTO  */
9206a99fe3SHajimu UMEMOTO static struct configuration_entry *
9306a99fe3SHajimu UMEMOTO find_create_entry(struct configuration *config,
9406a99fe3SHajimu UMEMOTO 	const char *entry_name)
9506a99fe3SHajimu UMEMOTO {
9606a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry = NULL;
9706a99fe3SHajimu UMEMOTO 	int res;
9806a99fe3SHajimu UMEMOTO 
9906a99fe3SHajimu UMEMOTO 	TRACE_IN(find_create_entry);
10006a99fe3SHajimu UMEMOTO 	entry = configuration_find_entry(config, entry_name);
10106a99fe3SHajimu UMEMOTO 	if (entry == NULL) {
10206a99fe3SHajimu UMEMOTO 		entry = create_def_configuration_entry(entry_name);
10306a99fe3SHajimu UMEMOTO 		assert( entry != NULL);
10406a99fe3SHajimu UMEMOTO 		res = add_configuration_entry(config, entry);
10506a99fe3SHajimu UMEMOTO 		assert(res == 0);
10606a99fe3SHajimu UMEMOTO 	}
10706a99fe3SHajimu UMEMOTO 
10806a99fe3SHajimu UMEMOTO 	TRACE_OUT(find_create_entry);
10906a99fe3SHajimu UMEMOTO 	return (entry);
11006a99fe3SHajimu UMEMOTO }
11106a99fe3SHajimu UMEMOTO 
11206a99fe3SHajimu UMEMOTO /*
11306a99fe3SHajimu UMEMOTO  * The vast majority of the functions below corresponds to the particular
11406a99fe3SHajimu UMEMOTO  * keywords in the configuration file.
11506a99fe3SHajimu UMEMOTO  */
11606a99fe3SHajimu UMEMOTO static void
11706a99fe3SHajimu UMEMOTO enable_cache(struct configuration *config, const char *entry_name, int flag)
11806a99fe3SHajimu UMEMOTO {
11906a99fe3SHajimu UMEMOTO 	struct configuration_entry	*entry;
12006a99fe3SHajimu UMEMOTO 
12106a99fe3SHajimu UMEMOTO 	TRACE_IN(enable_cache);
12206a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
12306a99fe3SHajimu UMEMOTO 	entry->enabled = flag;
12406a99fe3SHajimu UMEMOTO 	TRACE_OUT(enable_cache);
12506a99fe3SHajimu UMEMOTO }
12606a99fe3SHajimu UMEMOTO 
12706a99fe3SHajimu UMEMOTO static void
12806a99fe3SHajimu UMEMOTO set_positive_time_to_live(struct configuration *config,
12906a99fe3SHajimu UMEMOTO 	const char *entry_name, int ttl)
13006a99fe3SHajimu UMEMOTO {
13106a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry;
13206a99fe3SHajimu UMEMOTO 	struct timeval lifetime;
13306a99fe3SHajimu UMEMOTO 
13406a99fe3SHajimu UMEMOTO 	TRACE_IN(set_positive_time_to_live);
13506a99fe3SHajimu UMEMOTO 	assert(ttl >= 0);
13606a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
13706a99fe3SHajimu UMEMOTO 	memset(&lifetime, 0, sizeof(struct timeval));
13806a99fe3SHajimu UMEMOTO 	lifetime.tv_sec = ttl;
13906a99fe3SHajimu UMEMOTO 
14006a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
14106a99fe3SHajimu UMEMOTO 	memcpy(&entry->positive_cache_params.max_lifetime,
14206a99fe3SHajimu UMEMOTO 		&lifetime, sizeof(struct timeval));
14306a99fe3SHajimu UMEMOTO 	memcpy(&entry->mp_cache_params.max_lifetime,
14406a99fe3SHajimu UMEMOTO 		&lifetime, sizeof(struct timeval));
14506a99fe3SHajimu UMEMOTO 
14606a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_positive_time_to_live);
14706a99fe3SHajimu UMEMOTO }
14806a99fe3SHajimu UMEMOTO 
14906a99fe3SHajimu UMEMOTO static void
15006a99fe3SHajimu UMEMOTO set_negative_time_to_live(struct configuration *config,
15106a99fe3SHajimu UMEMOTO 	const char *entry_name, int nttl)
15206a99fe3SHajimu UMEMOTO {
15306a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry;
15406a99fe3SHajimu UMEMOTO 	struct timeval lifetime;
15506a99fe3SHajimu UMEMOTO 
15606a99fe3SHajimu UMEMOTO 	TRACE_IN(set_negative_time_to_live);
15706a99fe3SHajimu UMEMOTO 	assert(nttl > 0);
15806a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
15906a99fe3SHajimu UMEMOTO 	memset(&lifetime, 0, sizeof(struct timeval));
16006a99fe3SHajimu UMEMOTO 	lifetime.tv_sec = nttl;
16106a99fe3SHajimu UMEMOTO 
16206a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
16306a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
16406a99fe3SHajimu UMEMOTO 	memcpy(&entry->negative_cache_params.max_lifetime,
16506a99fe3SHajimu UMEMOTO 		&lifetime, sizeof(struct timeval));
16606a99fe3SHajimu UMEMOTO 
16706a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_negative_time_to_live);
16806a99fe3SHajimu UMEMOTO }
16906a99fe3SHajimu UMEMOTO 
17006a99fe3SHajimu UMEMOTO /*
17106a99fe3SHajimu UMEMOTO  * Hot count is actually the elements size limit.
17206a99fe3SHajimu UMEMOTO  */
17306a99fe3SHajimu UMEMOTO static void
17406a99fe3SHajimu UMEMOTO set_keep_hot_count(struct configuration *config,
17506a99fe3SHajimu UMEMOTO 	const char *entry_name, int count)
17606a99fe3SHajimu UMEMOTO {
17706a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry;
17806a99fe3SHajimu UMEMOTO 
17906a99fe3SHajimu UMEMOTO 	TRACE_IN(set_keep_hot_count);
18006a99fe3SHajimu UMEMOTO 	assert(count >= 0);
18106a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
18206a99fe3SHajimu UMEMOTO 
18306a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
18406a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
18506a99fe3SHajimu UMEMOTO 	entry->positive_cache_params.max_elemsize = count;
18606a99fe3SHajimu UMEMOTO 
18706a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
18806a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
18906a99fe3SHajimu UMEMOTO 	entry->negative_cache_params.max_elemsize = count;
19006a99fe3SHajimu UMEMOTO 
19106a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_keep_hot_count);
19206a99fe3SHajimu UMEMOTO }
19306a99fe3SHajimu UMEMOTO 
19406a99fe3SHajimu UMEMOTO static void
19506a99fe3SHajimu UMEMOTO set_positive_policy(struct configuration *config,
19606a99fe3SHajimu UMEMOTO 	const char *entry_name, enum cache_policy_t policy)
19706a99fe3SHajimu UMEMOTO {
19806a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry;
19906a99fe3SHajimu UMEMOTO 
20006a99fe3SHajimu UMEMOTO 	TRACE_IN(set_positive_policy);
20106a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
20206a99fe3SHajimu UMEMOTO 
20306a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
20406a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
20506a99fe3SHajimu UMEMOTO 	entry->positive_cache_params.policy = policy;
20606a99fe3SHajimu UMEMOTO 
20706a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_positive_policy);
20806a99fe3SHajimu UMEMOTO }
20906a99fe3SHajimu UMEMOTO 
21006a99fe3SHajimu UMEMOTO static void
21106a99fe3SHajimu UMEMOTO set_negative_policy(struct configuration *config,
21206a99fe3SHajimu UMEMOTO 	const char *entry_name, enum cache_policy_t policy)
21306a99fe3SHajimu UMEMOTO {
21406a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry;
21506a99fe3SHajimu UMEMOTO 
21606a99fe3SHajimu UMEMOTO 	TRACE_IN(set_negative_policy);
21706a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
21806a99fe3SHajimu UMEMOTO 
21906a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
22006a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
22106a99fe3SHajimu UMEMOTO 	entry->negative_cache_params.policy = policy;
22206a99fe3SHajimu UMEMOTO 
22306a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_negative_policy);
22406a99fe3SHajimu UMEMOTO }
22506a99fe3SHajimu UMEMOTO 
22606a99fe3SHajimu UMEMOTO static void
22706a99fe3SHajimu UMEMOTO set_perform_actual_lookups(struct configuration *config,
22806a99fe3SHajimu UMEMOTO 	const char *entry_name, int flag)
22906a99fe3SHajimu UMEMOTO {
23006a99fe3SHajimu UMEMOTO 	struct configuration_entry *entry;
23106a99fe3SHajimu UMEMOTO 
23206a99fe3SHajimu UMEMOTO 	TRACE_IN(set_perform_actual_lookups);
23306a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
23406a99fe3SHajimu UMEMOTO 
23506a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
23606a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
23706a99fe3SHajimu UMEMOTO 	entry->perform_actual_lookups = flag;
23806a99fe3SHajimu UMEMOTO 
23906a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_perform_actual_lookups);
24006a99fe3SHajimu UMEMOTO }
24106a99fe3SHajimu UMEMOTO 
24206a99fe3SHajimu UMEMOTO static void
24306a99fe3SHajimu UMEMOTO set_suggested_size(struct configuration *config,
24406a99fe3SHajimu UMEMOTO 	const char *entry_name, int size)
24506a99fe3SHajimu UMEMOTO {
24606a99fe3SHajimu UMEMOTO 	struct configuration_entry	*entry;
24706a99fe3SHajimu UMEMOTO 
24806a99fe3SHajimu UMEMOTO 	TRACE_IN(set_suggested_size);
24906a99fe3SHajimu UMEMOTO 	assert(config != NULL);
25006a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
25106a99fe3SHajimu UMEMOTO 	assert(size > 0);
25206a99fe3SHajimu UMEMOTO 
25306a99fe3SHajimu UMEMOTO 	entry = find_create_entry(config, entry_name);
25406a99fe3SHajimu UMEMOTO 	assert(entry != NULL);
25506a99fe3SHajimu UMEMOTO 	entry->positive_cache_params.cache_entries_size = size;
25606a99fe3SHajimu UMEMOTO 	entry->negative_cache_params.cache_entries_size = size;
25706a99fe3SHajimu UMEMOTO 
25806a99fe3SHajimu UMEMOTO 	TRACE_OUT(set_suggested_size);
25906a99fe3SHajimu UMEMOTO }
26006a99fe3SHajimu UMEMOTO 
26106a99fe3SHajimu UMEMOTO static void
26206a99fe3SHajimu UMEMOTO check_files(struct configuration *config, const char *entry_name, int flag)
26306a99fe3SHajimu UMEMOTO {
26406a99fe3SHajimu UMEMOTO 
26506a99fe3SHajimu UMEMOTO 	TRACE_IN(check_files);
26606a99fe3SHajimu UMEMOTO 	assert(entry_name != NULL);
26706a99fe3SHajimu UMEMOTO 	TRACE_OUT(check_files);
26806a99fe3SHajimu UMEMOTO }
26906a99fe3SHajimu UMEMOTO 
27006a99fe3SHajimu UMEMOTO static int
27106a99fe3SHajimu UMEMOTO get_yesno(const char *str)
27206a99fe3SHajimu UMEMOTO {
27306a99fe3SHajimu UMEMOTO 
27406a99fe3SHajimu UMEMOTO 	if (strcmp(str, "yes") == 0)
27506a99fe3SHajimu UMEMOTO 		return (1);
27606a99fe3SHajimu UMEMOTO 	else if (strcmp(str, "no") == 0)
27706a99fe3SHajimu UMEMOTO 		return (0);
27806a99fe3SHajimu UMEMOTO 	else
27906a99fe3SHajimu UMEMOTO 		return (-1);
28006a99fe3SHajimu UMEMOTO }
28106a99fe3SHajimu UMEMOTO 
28206a99fe3SHajimu UMEMOTO static int
28306a99fe3SHajimu UMEMOTO get_number(const char *str, int low, int max)
28406a99fe3SHajimu UMEMOTO {
28506a99fe3SHajimu UMEMOTO 
28606a99fe3SHajimu UMEMOTO 	char *end = NULL;
28706a99fe3SHajimu UMEMOTO 	int res = 0;
28806a99fe3SHajimu UMEMOTO 
28906a99fe3SHajimu UMEMOTO 	if (str[0] == '\0')
29006a99fe3SHajimu UMEMOTO 		return (-1);
29106a99fe3SHajimu UMEMOTO 
29206a99fe3SHajimu UMEMOTO 	res = strtol(str, &end, 10);
29306a99fe3SHajimu UMEMOTO 	if (*end != '\0')
29406a99fe3SHajimu UMEMOTO 		return (-1);
29506a99fe3SHajimu UMEMOTO 	else
29606a99fe3SHajimu UMEMOTO 		if (((res >= low) || (low == -1)) &&
29706a99fe3SHajimu UMEMOTO 			((res <= max) || (max == -1)))
29806a99fe3SHajimu UMEMOTO 			return (res);
29906a99fe3SHajimu UMEMOTO 		else
30006a99fe3SHajimu UMEMOTO 			return (-2);
30106a99fe3SHajimu UMEMOTO }
30206a99fe3SHajimu UMEMOTO 
30306a99fe3SHajimu UMEMOTO static enum cache_policy_t
30406a99fe3SHajimu UMEMOTO get_policy(const char *str)
30506a99fe3SHajimu UMEMOTO {
30606a99fe3SHajimu UMEMOTO 
30706a99fe3SHajimu UMEMOTO 	if (strcmp(str, "fifo") == 0)
30806a99fe3SHajimu UMEMOTO 		return (CPT_FIFO);
30906a99fe3SHajimu UMEMOTO 	else if (strcmp(str, "lru") == 0)
31006a99fe3SHajimu UMEMOTO 		return (CPT_LRU);
31106a99fe3SHajimu UMEMOTO 	else if (strcmp(str, "lfu") == 0)
31206a99fe3SHajimu UMEMOTO 		return (CPT_LFU);
31306a99fe3SHajimu UMEMOTO 
31406a99fe3SHajimu UMEMOTO 	return (-1);
31506a99fe3SHajimu UMEMOTO }
31606a99fe3SHajimu UMEMOTO 
31706a99fe3SHajimu UMEMOTO static int
31806a99fe3SHajimu UMEMOTO check_cachename(const char *str)
31906a99fe3SHajimu UMEMOTO {
32006a99fe3SHajimu UMEMOTO 
32106a99fe3SHajimu UMEMOTO 	assert(str != NULL);
32206a99fe3SHajimu UMEMOTO 	return ((strlen(str) > 0) ? 0 : -1);
32306a99fe3SHajimu UMEMOTO }
32406a99fe3SHajimu UMEMOTO 
32506a99fe3SHajimu UMEMOTO static void
32606a99fe3SHajimu UMEMOTO set_threads_num(struct configuration *config, int value)
32706a99fe3SHajimu UMEMOTO {
32806a99fe3SHajimu UMEMOTO 
32906a99fe3SHajimu UMEMOTO 	assert(config != NULL);
33006a99fe3SHajimu UMEMOTO 	config->threads_num = value;
33106a99fe3SHajimu UMEMOTO }
33206a99fe3SHajimu UMEMOTO 
33306a99fe3SHajimu UMEMOTO /*
33406a99fe3SHajimu UMEMOTO  * The main configuration routine. Its implementation is hugely inspired by the
33506a99fe3SHajimu UMEMOTO  * the same routine implementation in Solaris NSCD.
33606a99fe3SHajimu UMEMOTO  */
33706a99fe3SHajimu UMEMOTO int
33806a99fe3SHajimu UMEMOTO parse_config_file(struct configuration *config,
33906a99fe3SHajimu UMEMOTO 	const char *fname, char const **error_str, int *error_line)
34006a99fe3SHajimu UMEMOTO {
34106a99fe3SHajimu UMEMOTO 	FILE	*fin;
34206a99fe3SHajimu UMEMOTO 	char	buffer[255];
34306a99fe3SHajimu UMEMOTO 	char	*fields[128];
34406a99fe3SHajimu UMEMOTO 	int	field_count, line_num, value;
34506a99fe3SHajimu UMEMOTO 	int	res;
34606a99fe3SHajimu UMEMOTO 
34706a99fe3SHajimu UMEMOTO 	TRACE_IN(parse_config_file);
34806a99fe3SHajimu UMEMOTO 	assert(config != NULL);
34906a99fe3SHajimu UMEMOTO 	assert(fname != NULL);
35006a99fe3SHajimu UMEMOTO 
35106a99fe3SHajimu UMEMOTO 	fin = fopen(fname, "r");
35206a99fe3SHajimu UMEMOTO 	if (fin == NULL) {
35306a99fe3SHajimu UMEMOTO 		TRACE_OUT(parse_config_file);
35406a99fe3SHajimu UMEMOTO 		return (-1);
35506a99fe3SHajimu UMEMOTO 	}
35606a99fe3SHajimu UMEMOTO 
35706a99fe3SHajimu UMEMOTO 	res = 0;
35806a99fe3SHajimu UMEMOTO 	line_num = 0;
35906a99fe3SHajimu UMEMOTO 	memset(buffer, 0, sizeof(buffer));
36006a99fe3SHajimu UMEMOTO 	while ((res == 0) && (fgets(buffer, sizeof(buffer) - 1, fin) != NULL)) {
36106a99fe3SHajimu UMEMOTO 		field_count = strbreak(buffer, fields, sizeof(fields));
36206a99fe3SHajimu UMEMOTO 		++line_num;
36306a99fe3SHajimu UMEMOTO 
36406a99fe3SHajimu UMEMOTO 		if (field_count == 0)
36506a99fe3SHajimu UMEMOTO 			continue;
36606a99fe3SHajimu UMEMOTO 
36706a99fe3SHajimu UMEMOTO 		switch (fields[0][0]) {
36806a99fe3SHajimu UMEMOTO 		case '#':
36906a99fe3SHajimu UMEMOTO 		case '\0':
37006a99fe3SHajimu UMEMOTO 			continue;
37106a99fe3SHajimu UMEMOTO 		case 'e':
37206a99fe3SHajimu UMEMOTO 			if ((field_count == 3) &&
37306a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "enable-cache") == 0) &&
37406a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
37506a99fe3SHajimu UMEMOTO 			((value = get_yesno(fields[2])) != -1)) {
37606a99fe3SHajimu UMEMOTO 				enable_cache(config, fields[1], value);
37706a99fe3SHajimu UMEMOTO 				continue;
37806a99fe3SHajimu UMEMOTO 			}
37906a99fe3SHajimu UMEMOTO 			break;
38006a99fe3SHajimu UMEMOTO 		case 'd':
38106a99fe3SHajimu UMEMOTO 			if ((field_count == 2) &&
38206a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "debug-level") == 0) &&
38306a99fe3SHajimu UMEMOTO 			((value = get_number(fields[1], 0, 10)) != -1)) {
38406a99fe3SHajimu UMEMOTO 				continue;
38506a99fe3SHajimu UMEMOTO 			}
38606a99fe3SHajimu UMEMOTO 			break;
38706a99fe3SHajimu UMEMOTO 		case 'p':
38806a99fe3SHajimu UMEMOTO 			if ((field_count == 3) &&
38906a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "positive-time-to-live") == 0) &&
39006a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
39106a99fe3SHajimu UMEMOTO 			((value = get_number(fields[2], 0, -1)) != -1)) {
39206a99fe3SHajimu UMEMOTO 				set_positive_time_to_live(config,
39306a99fe3SHajimu UMEMOTO 					fields[1], value);
39406a99fe3SHajimu UMEMOTO 				continue;
39506a99fe3SHajimu UMEMOTO 			} else if ((field_count == 3) &&
39606a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "positive-policy") == 0) &&
39706a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
39806a99fe3SHajimu UMEMOTO 			((value = get_policy(fields[2])) != -1)) {
39906a99fe3SHajimu UMEMOTO 				set_positive_policy(config, fields[1], value);
40006a99fe3SHajimu UMEMOTO 				continue;
40106a99fe3SHajimu UMEMOTO 			} else if ((field_count == 3) &&
40206a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "perform-actual-lookups") == 0) &&
40306a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
40406a99fe3SHajimu UMEMOTO 			((value = get_yesno(fields[2])) != -1)) {
40506a99fe3SHajimu UMEMOTO 				set_perform_actual_lookups(config, fields[1],
40606a99fe3SHajimu UMEMOTO 					value);
40706a99fe3SHajimu UMEMOTO 				continue;
40806a99fe3SHajimu UMEMOTO 			}
40906a99fe3SHajimu UMEMOTO 			break;
41006a99fe3SHajimu UMEMOTO 		case 'n':
41106a99fe3SHajimu UMEMOTO 			if ((field_count == 3) &&
41206a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "negative-time-to-live") == 0) &&
41306a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
41406a99fe3SHajimu UMEMOTO 			((value = get_number(fields[2], 0, -1)) != -1)) {
41506a99fe3SHajimu UMEMOTO 				set_negative_time_to_live(config,
41606a99fe3SHajimu UMEMOTO 					fields[1], value);
41706a99fe3SHajimu UMEMOTO 				continue;
41806a99fe3SHajimu UMEMOTO 			} else if ((field_count == 3) &&
41906a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "negative-policy") == 0) &&
42006a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
42106a99fe3SHajimu UMEMOTO 			((value = get_policy(fields[2])) != -1)) {
42206a99fe3SHajimu UMEMOTO 				set_negative_policy(config,
42306a99fe3SHajimu UMEMOTO 					fields[1], value);
42406a99fe3SHajimu UMEMOTO 				continue;
42506a99fe3SHajimu UMEMOTO 			}
42606a99fe3SHajimu UMEMOTO 			break;
42706a99fe3SHajimu UMEMOTO 		case 's':
42806a99fe3SHajimu UMEMOTO 			if ((field_count == 3) &&
42906a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "suggested-size") == 0) &&
43006a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
43106a99fe3SHajimu UMEMOTO 			((value = get_number(fields[2], 1, -1)) != -1)) {
43206a99fe3SHajimu UMEMOTO 				set_suggested_size(config, fields[1], value);
43306a99fe3SHajimu UMEMOTO 				continue;
43406a99fe3SHajimu UMEMOTO 			}
43506a99fe3SHajimu UMEMOTO 			break;
43606a99fe3SHajimu UMEMOTO 		case 't':
43706a99fe3SHajimu UMEMOTO 			if ((field_count == 2) &&
43806a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "threads") == 0) &&
43906a99fe3SHajimu UMEMOTO 			((value = get_number(fields[1], 1, -1)) != -1)) {
44006a99fe3SHajimu UMEMOTO 				set_threads_num(config, value);
44106a99fe3SHajimu UMEMOTO 				continue;
44206a99fe3SHajimu UMEMOTO 			}
44306a99fe3SHajimu UMEMOTO 			break;
44406a99fe3SHajimu UMEMOTO 		case 'k':
44506a99fe3SHajimu UMEMOTO 			if ((field_count == 3) &&
44606a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "keep-hot-count") == 0) &&
44706a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
44806a99fe3SHajimu UMEMOTO 			((value = get_number(fields[2], 0, -1)) != -1)) {
44906a99fe3SHajimu UMEMOTO 				set_keep_hot_count(config,
45006a99fe3SHajimu UMEMOTO 					fields[1], value);
45106a99fe3SHajimu UMEMOTO 				continue;
45206a99fe3SHajimu UMEMOTO 			}
45306a99fe3SHajimu UMEMOTO 			break;
45406a99fe3SHajimu UMEMOTO 		case 'c':
45506a99fe3SHajimu UMEMOTO 			if ((field_count == 3) &&
45606a99fe3SHajimu UMEMOTO 			(strcmp(fields[0], "check-files") == 0) &&
45706a99fe3SHajimu UMEMOTO 			(check_cachename(fields[1]) == 0) &&
45806a99fe3SHajimu UMEMOTO 			((value = get_yesno(fields[2])) != -1)) {
45906a99fe3SHajimu UMEMOTO 				check_files(config,
46006a99fe3SHajimu UMEMOTO 					fields[1], value);
46106a99fe3SHajimu UMEMOTO 				continue;
46206a99fe3SHajimu UMEMOTO 			}
46306a99fe3SHajimu UMEMOTO 			break;
46406a99fe3SHajimu UMEMOTO 		default:
46506a99fe3SHajimu UMEMOTO 			break;
46606a99fe3SHajimu UMEMOTO 		}
46706a99fe3SHajimu UMEMOTO 
46806a99fe3SHajimu UMEMOTO 		LOG_ERR_2("config file parser", "error in file "
46906a99fe3SHajimu UMEMOTO 			"%s on line %d", fname, line_num);
47006a99fe3SHajimu UMEMOTO 		*error_str = "syntax error";
47106a99fe3SHajimu UMEMOTO 		*error_line = line_num;
47206a99fe3SHajimu UMEMOTO 		res = -1;
47306a99fe3SHajimu UMEMOTO 	}
47406a99fe3SHajimu UMEMOTO 	fclose(fin);
47506a99fe3SHajimu UMEMOTO 
47606a99fe3SHajimu UMEMOTO 	TRACE_OUT(parse_config_file);
47706a99fe3SHajimu UMEMOTO 	return (res);
47806a99fe3SHajimu UMEMOTO }
479