diff --git a/src/backend-test.c b/src/backend-test.c index 59472f2..342f6b6 100644 --- a/src/backend-test.c +++ b/src/backend-test.c @@ -10,8 +10,8 @@ void usage() { int main(int argc, char *argv[]) { const char *ip = "127.0.0.17"; - f2b_config_section_t *config = NULL; - f2b_config_section_t *b_conf = NULL; + f2b_config_t *config = NULL; + f2b_config_section_t *section = NULL; f2b_backend_t *backend = NULL; if (argc < 3) @@ -22,12 +22,12 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - if ((b_conf = f2b_config_find_section(config, t_backend, "test")) == NULL) { + if ((section = f2b_config_section_find(config->backends, "test")) == NULL) { f2b_log_msg(log_error, "can't find config section for backend '%s'", "test"); return EXIT_FAILURE; } - if ((backend = f2b_backend_create(config, argv[2])) == NULL) { + if ((backend = f2b_backend_create(section, argv[2])) == NULL) { f2b_log_msg(log_error, "can't create backend"); return EXIT_FAILURE; } diff --git a/src/backend.c b/src/backend.c index 0c82412..4fcb68b 100644 --- a/src/backend.c +++ b/src/backend.c @@ -13,7 +13,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) { assert(config != NULL); assert(config->type == t_backend); - param = f2b_config_find_param(config->param, BACKEND_LIBRARY_PARAM); + param = f2b_config_param_find(config->param, BACKEND_LIBRARY_PARAM); if (!param) { f2b_log_msg(log_error, "can't find '%s' param in backend config", BACKEND_LIBRARY_PARAM); return NULL; diff --git a/src/config.c b/src/config.c index 1de06d3..d2c8d94 100644 --- a/src/config.c +++ b/src/config.c @@ -3,7 +3,7 @@ #include "log.h" f2b_config_param_t * -f2b_config_parse_kv_pair(const char *src) { +f2b_config_param_create(const char *src) { f2b_config_param_t *param = NULL; char line[CONFIG_LINE_MAX] = ""; char *p, *key, *value; @@ -63,12 +63,26 @@ f2b_config_parse_kv_pair(const char *src) { return NULL; } +f2b_config_param_t * +f2b_config_param_find(f2b_config_param_t *param, const char *name) { + for (; param != NULL; param = param->next) { + if (strcmp(name, param->name) == 0) + return param; + } + + return NULL; +} + f2b_config_section_t * -f2b_config_parse_section(const char *src) { +f2b_config_section_create(const char *src) { f2b_config_section_t *section = NULL; char line[CONFIG_LINE_MAX] = ""; char *name, *end; + assert(src != NULL); + assert(*src == '['); + + src++; strncpy(line, src, sizeof(line)); line[CONFIG_LINE_MAX] = '\0'; @@ -79,20 +93,26 @@ f2b_config_parse_section(const char *src) { if ((section = calloc(1, sizeof(f2b_config_section_t))) == NULL) return NULL; - name = "[defaults]"; + name = "main"; + if (strncmp(line, name, strlen(name)) == 0) { + section->type = t_main; + return section; + } + + name = "defaults"; if (strncmp(line, name, strlen(name)) == 0) { section->type = t_defaults; return section; } - name = "[backend:"; + name = "backend:"; if (strncmp(line, name, strlen(name)) == 0) { section->type = t_backend; strncpy(section->name, line + strlen(name), sizeof(section->name)); return section; } - name = "[jail:"; + name = "jail:"; if (strncmp(line, name, strlen(name)) == 0) { section->type = t_jail; strncpy(section->name, line + strlen(name), sizeof(section->name)); @@ -104,27 +124,17 @@ f2b_config_parse_section(const char *src) { } f2b_config_section_t * -f2b_config_find_section(f2b_config_section_t *section, f2b_section_type type, const char *name) { +f2b_config_section_find(f2b_config_section_t *section, const char *name) { for (; section != NULL; section = section->next) { - if (section->type == type && strcmp(section->name, name) == 0) + if (strcmp(section->name, name) == 0) return section; } return NULL; } -f2b_config_param_t * -f2b_config_find_param(f2b_config_param_t *param, const char *name) { - for (; param != NULL; param = param->next) { - if (strcmp(name, param->name) == 0) - return param; - } - - return NULL; -} - f2b_config_section_t * -f2b_config_append_param(f2b_config_section_t *section, f2b_config_param_t *param) { +f2b_config_section_append(f2b_config_section_t *section, f2b_config_param_t *param) { if (section->param) { section->last->next = param; section->last = section->last->next; @@ -135,15 +145,15 @@ f2b_config_append_param(f2b_config_section_t *section, f2b_config_param_t *param return section; } -f2b_config_section_t * +f2b_config_t * f2b_config_load(const char *path) { - f2b_config_section_t *config = NULL; /* always points to current section */ - f2b_config_section_t *section = NULL; /* temp pointer */ + f2b_config_t *config = NULL; + f2b_config_section_t *section = NULL; /* always points to current section */ f2b_config_param_t *param = NULL; /* temp pointer */ FILE *f = NULL; /* config file fd */ char *p; /* temp pointer */ char line[CONFIG_LINE_MAX] = ""; /* last read line */ - bool skip_section = false; /* if set - skip parameters unless next section */ + bool skip_section = true; /* if set - skip parameters unless next section */ size_t linenum = 0; /* current line number in config */ if ((f = fopen(path, "r")) == NULL) { @@ -151,14 +161,18 @@ f2b_config_load(const char *path) { return NULL; } - if ((config = calloc(1, sizeof(f2b_config_section_t))) == NULL) + if ((config = calloc(1, sizeof(f2b_config_t))) == NULL) return NULL; - config->type = t_main; while (1) { p = fgets(line, sizeof(line), f); if (!p && (feof(f) || ferror(f))) break; + if ((p = strchr(line, '\r')) != NULL) + *p = '\0'; + if ((p = strchr(line, '\n')) != NULL) + *p = '\0'; + p = line; while (isblank(*p)) p++; linenum++; @@ -174,11 +188,10 @@ f2b_config_load(const char *path) { break; case '[': /* section header */ - section = f2b_config_parse_section(p); + section = f2b_config_section_create(p); if (section) { skip_section = false; - section->next = config; - config = section; + f2b_config_append(config, section); } else { skip_section = true; f2b_log_msg(log_error, "unknown section at line %d: %s", linenum, p); @@ -190,12 +203,12 @@ f2b_config_load(const char *path) { continue; } /* key/value pair */ - param = f2b_config_parse_kv_pair(p); - if (param) { - f2b_config_append_param(config, param); - } else { + param = f2b_config_param_create(p); + if (!param) { f2b_log_msg(log_error, "can't parse key/value at line %d: %s", linenum, p); + continue; } + f2b_config_section_append(section, param); break; } /* switch */ } /* while */ @@ -204,17 +217,45 @@ f2b_config_load(const char *path) { return config; } +#define FREE_SECTIONS(SECTION) \ + for (; SECTION != NULL; SECTION = ns) { \ + ns = SECTION->next; \ + for (; SECTION->param != NULL; \ + SECTION->param = np) { \ + np = SECTION->param->next; \ + FREE(SECTION->param); \ + } \ + } + +void +f2b_config_free(f2b_config_t *config) { + f2b_config_section_t *ns = NULL; /* next section */ + f2b_config_param_t *np = NULL; /* next param */ + + FREE_SECTIONS(config->main); + FREE_SECTIONS(config->defaults); + FREE_SECTIONS(config->backends); + FREE_SECTIONS(config->jails); + + FREE(config); +} + void -f2b_config_free(f2b_config_section_t *config) { - f2b_config_section_t *next_section = NULL; - f2b_config_param_t *next_param = NULL; - - for (; config != NULL; config = next_section) { - next_section = config->next; - for (; config->param != NULL; config->param = next_param) { - next_param = config->param->next; - FREE(config->param); - } - FREE(config); +f2b_config_append(f2b_config_t *config, f2b_config_section_t *section) { + f2b_config_section_t **s = NULL; + assert(config != NULL); + assert(section != NULL); + + switch (section->type) { + case t_main: s = &config->main; break; + case t_defaults: s = &config->defaults; break; + case t_backend: s = &config->backends; break; + case t_jail: s = &config->jails; break; + default: + f2b_log_msg(log_error, "unknown section type"); + abort(); + break; } + section->next = *s; + *s = section; } diff --git a/src/config.h b/src/config.h index ecfec25..6663f0f 100644 --- a/src/config.h +++ b/src/config.h @@ -28,13 +28,21 @@ typedef struct f2b_config_section_t { f2b_config_param_t *last; } f2b_config_section_t; -f2b_config_param_t * f2b_config_parse_kv_pair(const char *line); -f2b_config_param_t * f2b_config_find_param(f2b_config_param_t *param, const char *name); - -f2b_config_section_t * f2b_config_parse_section(const char *line); -f2b_config_section_t * f2b_config_find_section(f2b_config_section_t *section, f2b_section_type type, const char *name); -f2b_config_section_t * f2b_config_append_param(f2b_config_section_t *section, f2b_config_param_t *param); - -f2b_config_section_t * f2b_config_load(const char *path); -void f2b_config_free(f2b_config_section_t *config); +typedef struct f2b_config_t { + f2b_config_section_t *main; + f2b_config_section_t *defaults; + f2b_config_section_t *backends; + f2b_config_section_t *jails; +} f2b_config_t; + +f2b_config_param_t * f2b_config_param_create(const char *line); +f2b_config_param_t * f2b_config_param_find (f2b_config_param_t *param, const char *name); + +f2b_config_section_t * f2b_config_section_create(const char *line); +f2b_config_section_t * f2b_config_section_find (f2b_config_section_t *s, const char *name); +f2b_config_section_t * f2b_config_section_append(f2b_config_section_t *s, f2b_config_param_t *p); + +f2b_config_t * f2b_config_load (const char *path); +void f2b_config_free (f2b_config_t *c); +void f2b_config_append(f2b_config_t *c, f2b_config_section_t *s); #endif /* CONFIG_H_ */ diff --git a/t/t_config_param.c b/t/t_config_param.c index 0b7f264..7a841af 100644 --- a/t/t_config_param.c +++ b/t/t_config_param.c @@ -4,32 +4,32 @@ int main() { f2b_config_param_t *param = NULL; - assert(f2b_config_parse_kv_pair("") == NULL); - assert(f2b_config_parse_kv_pair("#") == NULL); - assert(f2b_config_parse_kv_pair("=") == NULL); - assert(f2b_config_parse_kv_pair("key=") == NULL); - assert(f2b_config_parse_kv_pair("key =") == NULL); - assert(f2b_config_parse_kv_pair("key = ") == NULL); - assert(f2b_config_parse_kv_pair( "=value") == NULL); - assert(f2b_config_parse_kv_pair( "= value") == NULL); - assert(f2b_config_parse_kv_pair(" = value") == NULL); + assert(f2b_config_param_create("") == NULL); + assert(f2b_config_param_create("#") == NULL); + assert(f2b_config_param_create("=") == NULL); + assert(f2b_config_param_create("key=") == NULL); + assert(f2b_config_param_create("key =") == NULL); + assert(f2b_config_param_create("key = ") == NULL); + assert(f2b_config_param_create( "=value") == NULL); + assert(f2b_config_param_create( "= value") == NULL); + assert(f2b_config_param_create(" = value") == NULL); - assert((param = f2b_config_parse_kv_pair("key=value")) != NULL); + assert((param = f2b_config_param_create("key=value")) != NULL); assert(strcmp(param->name, "key") == 0); assert(strcmp(param->value, "value") == 0); free(param); - assert((param = f2b_config_parse_kv_pair("key = value")) != NULL); + assert((param = f2b_config_param_create("key = value")) != NULL); assert(strcmp(param->name, "key") == 0); assert(strcmp(param->value, "value") == 0); free(param); - assert((param = f2b_config_parse_kv_pair("key=value #comment")) != NULL); + assert((param = f2b_config_param_create("key=value #comment")) != NULL); assert(strcmp(param->name, "key") == 0); assert(strcmp(param->value, "value") == 0); free(param); - assert((param = f2b_config_parse_kv_pair("key=value#compose")) != NULL); + assert((param = f2b_config_param_create("key=value#compose")) != NULL); assert(strcmp(param->name, "key") == 0); assert(strcmp(param->value, "value#compose") == 0); free(param);