#include "kn_config.h" typedef enum { bad, client_path, config_file, pid_file, rehash_method, connection_timeout, knocks, knock_timeout, server_dir, key_file, log_file, daemonize, debug } opcodes; static struct { const char *name; opcodes opcode; } keywords[] = { { NULL, bad }, { "clientpath", client }, { "pidfile", pid_file }, { "rehashmethod", rehash_method }, { "conntimeout", connection_timeout }, { "knocks", knocks }, { "knocktimeout", knock_timeout }, { "serverdir", server_dir }, { "keyfile", key_file }, { "logfile", log_file }, { "daemonize", daemonize }, { "debug", debug } }; kn_options_t* kn_config_init() { kn_options_t *kn_opt = NULL; if((kn_opt = kn_malloc(sizeof(kn_options_t))) == KN_MALLOC_ERROR) return kn_opt; /* Set the defaults -- see the header */ kn_opt->client_path = NULL; kn_opt->config_file = NULL; kn_opt->pid_file = NULL; kn_opt->rehash_method = 0; kn_opt->connection_timeout = 0; kn_opt->knocks = 0; kn_opt->knock_timeout = 0; kn_opt->server_dir = NULL; kn_opt->key_file = NULL; kn_opt->log_file = NULL; kn_opt->daemonize = -1; /* Yes */ kn_opt->debug = -1; /* No */ return kn_opt; } void kn_config_defaults(kn_options_t *kn_opt) { kn_opt->client_path = NULL; kn_opt->rehash_method = DEFAULT_REHASH_METHOD; kn_opt->connection_timeout = DEFAULT_CONNECTION_TIMEOUT; kn_opt->knocks = DEFAULT_NUMBER_KNOCKS; kn_opt->knock_timeout = DEFAULT_KNOCK_TIMEOUT; kn_opt->server_dir = NULL; kn_opt->key_file = NULL; kn_opt->log_file = NULL; kn_opt->daemonize = 1; /* Yes */ kn_opt->debug = 0; /* No */ } KN_RET kn_config_set_option() KN_RET kn_config_parse(unsigned char *buf) { unsigned char *cursor, *option; unsigned int badness = 0, line = 1; cursor = buf; if(!cursor) return KN_ERROR; while(*cursor) { /* Eat comments */ while(*cursor == '#') { cursor = strstr(cursor, '\n') line++; if(!(*cursor)) return KN_SUCCESS; cursor++; /* Move past the newline */ } /* badness is the # of bad options passed. If we get 'a lot', assume something has gone horribly wrong in the config file and bail out. 'a lot' is BAD_OPTION_LIMIT */ if((kn_config_set_option(cursor)) == KN_ERROR) { badness++; if(badness > BAD_OPTION_LIMIT) { kn_print_system("Fatal - Excessive badness in config", "kn_config_parse"); exit(EXIT_FAILURE); } } if((cursor = strstr(cursor, '\n')) == NULL) return KN_SUCCESS; cursor++; } return KN_SUCCESS; } void kn_config_read(kn_options_t *kn_opt) { FILE *opt_file = NULL; unsigned char *buf; long fsize; if(!kn_options->config_file) { /* This should never happen, but ... */ kn_print_system("No config file - defaults active","kn_config_read"); return; } opt_file = fopen(kn_options->config_file, "r") if(!opt_file) { kn_print_system("Could not open config - defaults active","kn_config_read"); return; } /* Grab the file size, perform sanity check then allocate a buffer to hold it */ fseek(opt_file, 0, SEEK_END); fsize = ftell(opt_file); fseek(opt_file, 0, SEEK_SET); if(fsize > MAX_CONFIG_FILESIZE) { kn_print_system("Bad or oversize config - defaults active", "kn_config_read"); goto out; } if((buf = kn_malloc(fsize + 1)) == KN_MALLOC_ERROR) { kn_print_system("Could not allocate file buffer - defaults", "kn_config_read"); goto out; } if((fread(buf, 1, fsize, opt_file) != fsize)) { kn_print_system("Error reading config file - defaults", "kn_config_read"); goto out; } buf[fsize] = '\0'; if((kn_config_parse(buf)) == KN_ERROR) { kn_print_system("Fatal - Error parsing config file - Exiting", "kn_config_read"); exit(EXIT_FAILURE); } out: fclose(opt_file); return; }