#include #include #include #include #include #include "config.h" #include "macros.h" #include "misc.h" void cleanup_config(config *conf) { for (int i = 0; config_keywords[i] != NULL; ++i) { /* Get the pointer to the config option. */ void *cfg = get_keyword_offset_ptr(config_keywords[i], conf); /* Is this config option's type a string, and is the string of that config option in conf not NULL? */ if (config_keywords[i]->type == TYPE_STRING && *(void **)cfg != NULL) { free(*(void **)cfg); } } free(conf); } int check_port(void *ctx, void *ret, const keyword *key, keyword_val val) { if (key->type == TYPE_STRING) { int port = strtol(val.str, NULL, 0); if (port > 0 || port <= 65535) { return 0; } else { log(LOG_ERR, "Invalid port %d. (Valid port must be between 1, and 65535.)", port); } } else { log(LOG_ERR, "Keyword \"%s\" doesn't return a string.", key->key); } return -1; } config *parse_config(const char *filename) { /* Size of the file, in bytes. */ long filesize = 0; /* Config settings. */ config *cfg; /* Buffer of the file contents. */ char *buf = read_file(filename, &filesize); char *tmp = buf; /* Return NULL, if the buffer wasn't allocated */ if (buf == NULL) { return NULL; } cfg = calloc(1, sizeof(config)); /* Return NULL, if cfg wasn't allocated. */ if (cfg == NULL) { free(buf); return NULL; } while (*tmp != '\0') { char *line = get_line(&tmp); char *value; char *name = strtok_r(line, "=", &value); int error; /* Did we fail to parse the config option? */ if (error = parse_keywords(config_keywords, name, value, cfg, NULL)) { if (error == 5) { cleanup_config(cfg); free(line); free(buf); return NULL; } else { log(LOG_WARNING, "Failed to parse config option \"%s\". Error code: %i", name, error); } } free(line); } free(buf); return cfg; }