From 3bb2d8fd96618c11f499c8dddb97a62015b1ea53 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 8 Jun 2019 11:25:19 +0200 Subject: Implement configuration file parsing --- config.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 15 deletions(-) (limited to 'config.c') diff --git a/config.c b/config.c index 7da08eb..0b57714 100644 --- a/config.c +++ b/config.c @@ -1,5 +1,6 @@ #include #include +#include #include "websocksy.h" #include "config.h" @@ -10,8 +11,98 @@ static enum /*_config_file_section*/ { cfg_backend } config_section = cfg_main; +static int config_file_line(ws_config* config, char* key, char* value, size_t line_no){ + if(!strcmp(key, "port")){ + free(config->port); + config->port = strdup(value); + } + else if(!strcmp(key, "listen")){ + free(config->host); + config->host = strdup(value); + } + else if(!strcmp(key, "backend")){ + //clean up the previously registered backend + if(config->backend.cleanup){ + config->backend.cleanup(); + } + //load the backend plugin + if(plugin_backend_load(PLUGINS, value, &(config->backend))){ + return 1; + } + if(config->backend.init() != WEBSOCKSY_API_VERSION){ + fprintf(stderr, "Loaded backend %s was built for a different API version\n", value); + return 1; + } + } + return 0; +} + int config_parse_file(ws_config* config, char* filename){ - return 1; + ssize_t line_current; + size_t line_alloc = 0, line_no = 1, key_len; + char* line = NULL, *key, *value; + FILE* input = fopen(filename, "r"); + if(!input){ + fprintf(stderr, "Failed to open %s as configuration file\n", filename); + return 1; + } + + for(line_current = getline(&line, &line_alloc, input); line_current >= 0; line_current = getline(&line, &line_alloc, input)){ + if(!strncmp(line, "[core]", 6)){ + config_section = cfg_main; + } + else if(!strncmp(line, "[backend]", 9)){ + config_section = cfg_backend; + } + else if(line_current > 0){ + //right-trim newlines & spaces from value + for(line_current--; line_current && isspace(line[line_current]); line_current--){ + line[line_current] = 0; + } + + if(line_current > 0){ + //left-trim key + for(key = line; *key && isspace(key[0]); key++){ + } + + value = strchr(key, '='); + if(value){ + *value = 0; + //left-trim value + for(value++; *value && isspace(value[0]); value++){ + } + + //right-trim key + for(key_len = strlen(key) - 1; *key && key_len && isspace(key[key_len]); key_len--){ + key[key_len] = 0; + } + + switch(config_section){ + case cfg_main: + if(config_file_line(config, key, value, line_no)){ + free(line); + fclose(input); + return 1; + } + break; + case cfg_backend: + if(config->backend.config(key, value)){ + fprintf(stderr, "Backend configuration failed in %s line %lu\n", filename, line_no); + free(line); + fclose(input); + return 1; + } + break; + } + } + } + } + line_no++; + } + + free(line); + fclose(input); + return 0; } int config_parse_arguments(ws_config* config, int argc, char** argv){ @@ -33,24 +124,13 @@ int config_parse_arguments(ws_config* config, int argc, char** argv){ } switch(argv[u][1]){ case 'p': - config->port = argv[u + 1]; + config_file_line(config, "port", argv[u + 1], 0); break; case 'l': - config->host = argv[u + 1]; + config_file_line(config, "listen", argv[u + 1], 0); break; case 'b': - //clean up the previously registered backend - if(config->backend.cleanup){ - config->backend.cleanup(); - } - //load the backend plugin - if(plugin_backend_load(PLUGINS, argv[u + 1], &(config->backend))){ - return 1; - } - if(config->backend.init() != WEBSOCKSY_API_VERSION){ - fprintf(stderr, "Loaded backend %s was built for a different API version\n", argv[u + 1]); - return 1; - } + config_file_line(config, "backend", argv[u + 1], 0); break; case 'c': if(!strchr(argv[u + 1], '=')){ -- cgit v1.2.3