/* confparser.h - Configuration file parser for ck ---------------------*- C -*- * * This file is part of ck, the config keeper * * ----------------------------------------------------------------------------- * * Copyright (C) 2018 Anastasis Grammenos * GPLv3 (see LICENCE for the full notice) * * -------------------------------------------------------------------------- */ #include "ckutil.h" #include "confparser.h" #include "ckerrlog.h" ERRLOG(configfile); const char * const CONFIG_NAME = "/ckrc"; void initialize_conf(Conf *c) { #define X(var, str, name) \ c->var = NULL; CONFIG_VARIABLES_TABLE #undef X } int read_next_line(char *line, FILE *f) { char nextLine[STR_L] = ""; if (fgets(nextLine, STR_L, f) == NULL) { return -1; } strcpy(line, nextLine); return 0; } ConfVar match_variables(char *line, char matched[]) { if (line[0] == '#' || str_is_empty(line)) { return CV_NO_VAL_OR_COMMENT; } #define X(var, str, name) \ if (sscanf(line, str, matched) == 1) { \ return CV_##var; \ } CONFIG_VARIABLES_TABLE #undef X return CV_WRONG_VAL; } void make_config_name(char * ret, const char *confPath) { char tmp[STR_L] = ""; strcpy(tmp, confPath); strcat(tmp, CONFIG_NAME); strcpy(ret, tmp); } int config_file_parse(Conf *conf, UserOpt *opt) { LOG("Using '%s' for ck configuration directory", opt->confDir); FILE *confPtr; char confName[STR_L] = ""; char line[STR_L] = ""; char matched[STR_L] = ""; make_config_name(confName, opt->confDir); if ((confPtr = fopen(confName, "r")) == NULL) { ERR("%s is not readable, check the permissions.", confName) return -1; } while (read_next_line(line, confPtr) == 0) { if (strlen(line) > STR_L) { return -1; } switch(match_variables(line, matched)) { #define X(var, str, name) \ case CV_##var: \ conf->var = malloc(strlen(matched)+1); \ strcpy(conf->var, matched); \ if (!util_is_dir(matched)) { \ ERR("%s %s defined in config doesn't exist", \ name, conf->var); \ return -1; \ } \ LOG("Found %s: %s", name, conf->var); \ break; CONFIG_VARIABLES_TABLE #undef X case CV_NO_VAL_OR_COMMENT: break; default: ERR("In line: %s", line); return -1; } } /* Could add an optional row that would make the config var * optional. */ #define X(var, str, name) \ if (!conf->var) { \ ERR("Missing %s", name); \ return -1; \ } CONFIG_VARIABLES_TABLE #undef X return 0; } void free_conf(Conf *conf) { #define X(var,str,name) \ if (conf->var) { \ free(conf->var); \ } CONFIG_VARIABLES_TABLE #undef X }