From 09cfe2a4c061a4b2c08d93c1d99f60c8879f5cf2 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sat, 26 Apr 2014 12:31:33 -0400 Subject: ini.c: move Include parsing to conf.c Reduces the number of errors the ini parser must handle to make it more suitable for sharing with the backend. Signed-off-by: Andrew Gregory --- src/pacman/conf.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/ini.c | 67 +++-------------------------------------------------- 2 files changed, 72 insertions(+), 64 deletions(-) diff --git a/src/pacman/conf.c b/src/pacman/conf.c index fbf7bb3c..64c83198 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -22,6 +22,7 @@ #include #include /* setlocale */ #include /* open */ +#include #include #include #include /* strdup */ @@ -813,6 +814,7 @@ static int setup_libalpm(void) struct section_t { const char *name; config_repo_t *repo; + int depth; }; static int process_usage(alpm_list_t *values, alpm_db_usage_t *usage, @@ -895,6 +897,69 @@ static int _parse_repo(const char *key, char *value, const char *file, return ret; } +static int _parse_directive(const char *file, int linenum, const char *name, + char *key, char *value, void *data); + +static int process_include(const char *value, void *data, + const char *file, int linenum) +{ + glob_t globbuf; + int globret, ret = 0; + size_t gindex; + struct section_t *section = data; + static const int config_max_recursion = 10; + + if(value == NULL) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"), + file, linenum, "Include"); + return 1; + } + + if(section->depth >= config_max_recursion) { + pm_printf(ALPM_LOG_ERROR, + _("config parsing exceeded max recursion depth of %d.\n"), + config_max_recursion); + return 1; + } + + section->depth++; + + /* Ignore include failures... assume non-critical */ + globret = glob(value, GLOB_NOCHECK, NULL, &globbuf); + switch(globret) { + case GLOB_NOSPACE: + pm_printf(ALPM_LOG_DEBUG, + "config file %s, line %d: include globbing out of space\n", + file, linenum); + break; + case GLOB_ABORTED: + pm_printf(ALPM_LOG_DEBUG, + "config file %s, line %d: include globbing read error for %s\n", + file, linenum, value); + break; + case GLOB_NOMATCH: + pm_printf(ALPM_LOG_DEBUG, + "config file %s, line %d: no include found for %s\n", + file, linenum, value); + break; + default: + for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) { + pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: including %s\n", + file, linenum, globbuf.gl_pathv[gindex]); + ret = parse_ini(globbuf.gl_pathv[gindex], _parse_directive, data); + if(ret) { + goto cleanup; + } + } + break; + } + +cleanup: + section->depth--; + globfree(&globbuf); + return ret; +} + static int _parse_directive(const char *file, int linenum, const char *name, char *key, char *value, void *data) { @@ -914,6 +979,10 @@ static int _parse_directive(const char *file, int linenum, const char *name, return 0; } + if(strcmp(key, "Include") == 0) { + return process_include(value, data, file, linenum); + } + if(section->name == NULL) { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"), file, linenum); diff --git a/src/pacman/ini.c b/src/pacman/ini.c index 7b35c243..048c3d9b 100644 --- a/src/pacman/ini.c +++ b/src/pacman/ini.c @@ -18,7 +18,6 @@ */ #include -#include #include #include /* strdup */ @@ -27,8 +26,6 @@ #include "ini.h" #include "util.h" -static const int ini_max_recursion = 10; - /** * @brief INI parser backend. * @@ -37,26 +34,17 @@ static const int ini_max_recursion = 10; * @param data caller defined data to be passed to the callback * @param section_name the name of the current section * @param line buffer to read into, must be at least PATH_MAX long - * @param depth recursion depth, should initially be 0 * * @return 0 on success, 1 on parsing errors, the callback return value * otherwise */ static int _parse_ini(const char *file, ini_parser_fn cb, void *data, - char **section_name, char *line, int depth) + char **section_name, char *line) { FILE *fp = NULL; int linenum = 0; int ret = 0; - if(depth >= ini_max_recursion) { - pm_printf(ALPM_LOG_ERROR, - _("config parsing exceeded max recursion depth of %d.\n"), - ini_max_recursion); - ret = 1; - goto cleanup; - } - pm_printf(ALPM_LOG_DEBUG, "config: attempting to read file %s\n", file); fp = fopen(file, "r"); if(fp == NULL) { @@ -121,52 +109,6 @@ static int _parse_ini(const char *file, ini_parser_fn cb, void *data, ret = 1; goto cleanup; } - /* Include is allowed in both options and repo sections */ - if(strcmp(key, "Include") == 0) { - glob_t globbuf; - int globret; - size_t gindex; - - if(value == NULL) { - pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"), - file, linenum, key); - ret = 1; - goto cleanup; - } - /* Ignore include failures... assume non-critical */ - globret = glob(value, GLOB_NOCHECK, NULL, &globbuf); - switch(globret) { - case GLOB_NOSPACE: - pm_printf(ALPM_LOG_DEBUG, - "config file %s, line %d: include globbing out of space\n", - file, linenum); - break; - case GLOB_ABORTED: - pm_printf(ALPM_LOG_DEBUG, - "config file %s, line %d: include globbing read error for %s\n", - file, linenum, value); - break; - case GLOB_NOMATCH: - pm_printf(ALPM_LOG_DEBUG, - "config file %s, line %d: no include found for %s\n", - file, linenum, value); - break; - default: - for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) { - pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: including %s\n", - file, linenum, globbuf.gl_pathv[gindex]); - ret =_parse_ini(globbuf.gl_pathv[gindex], cb, data, - section_name, line, depth + 1); - if(ret) { - globfree(&globbuf); - goto cleanup; - } - } - break; - } - globfree(&globbuf); - continue; - } if((ret = cb(file, linenum, *section_name, key, value, data)) != 0) { goto cleanup; } @@ -176,10 +118,7 @@ cleanup: if(fp) { fclose(fp); } - if(depth == 0) { - free(*section_name); - *section_name = NULL; - } + free(*section_name); pm_printf(ALPM_LOG_DEBUG, "config: finished parsing %s\n", file); return ret; } @@ -206,7 +145,7 @@ cleanup: int parse_ini(const char *file, ini_parser_fn cb, void *data) { char *section_name = NULL, line[PATH_MAX]; - return _parse_ini(file, cb, data, §ion_name, line, 0); + return _parse_ini(file, cb, data, §ion_name, line); } /* vim: set noet: */ -- cgit v1.2.3-70-g09d2