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