conf: _parseconfig() cleanups and documentation

* Function doxygen documentation
* Reuse a single strlen() call
* Prevent infinite recursion (limit to 10 levels)
* Other small cleanups

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-06-07 17:56:57 -05:00
parent 29ea0fa09f
commit c730ca5997

View file

@ -508,32 +508,52 @@ static int setup_libalpm(void)
} }
/* The real parseconfig. Called with a null section argument by the publicly /** The "real" parseconfig. Each "Include" directive will recall this method so
* visible parseconfig so we can recall from within ourself on an include */ * recursion and stack depth are limited to 10 levels. The publicly visible
static int _parseconfig(const char *file, int parse_options, * parseconfig calls this with a NULL section argument so we can recall from
char **section, pmdb_t *db) * within ourself on an include.
* @param file path to the config file
* @param section the current active section name; should be freed after all
* parsing is complete
* @param db the current active alpm database object
* @param parse_options whether to parse and call methods for the options
* section; if 0, parse and call methods for the repos sections
* @param depth the current recursion depth
**/
static int _parseconfig(const char *file, char **section, pmdb_t *db,
int parse_options, int depth)
{ {
FILE *fp = NULL; FILE *fp = NULL;
char line[PATH_MAX]; char line[PATH_MAX];
int linenum = 0; int linenum = 0;
char *ptr;
int ret = 0; int ret = 0;
const int max_depth = 10;
if(depth >= max_depth) {
pm_printf(PM_LOG_ERROR,
_("config parsing exceeded max recursion depth of %d.\n"), max_depth);
ret = 1;
goto cleanup;
}
pm_printf(PM_LOG_DEBUG, "config: attempting to read file %s\n", file); pm_printf(PM_LOG_DEBUG, "config: attempting to read file %s\n", file);
fp = fopen(file, "r"); fp = fopen(file, "r");
if(fp == NULL) { if(fp == NULL) {
pm_printf(PM_LOG_ERROR, _("config file %s could not be read.\n"), file); pm_printf(PM_LOG_ERROR, _("config file %s could not be read.\n"), file);
return 1; ret = 1;
goto cleanup;
} }
while(fgets(line, PATH_MAX, fp)) { while(fgets(line, PATH_MAX, fp)) {
char *key, *value; char *key, *value, *ptr;
size_t line_len;
linenum++; linenum++;
strtrim(line); strtrim(line);
line_len = strlen(line);
/* ignore whole line and end of line comments */ /* ignore whole line and end of line comments */
if(strlen(line) == 0 || line[0] == '#') { if(line_len == 0 || line[0] == '#') {
continue; continue;
} }
if((ptr = strchr(line, '#'))) { if((ptr = strchr(line, '#'))) {
@ -548,19 +568,18 @@ static int _parseconfig(const char *file, int parse_options,
goto cleanup; goto cleanup;
} }
if(line[0] == '[' && line[strlen(line)-1] == ']') { if(line[0] == '[' && line[line_len - 1] == ']') {
char *name; char *name;
/* new config section, skip the '[' */ /* only possibility here is a line == '[]' */
ptr = line; if(line_len <= 2) {
ptr++;
name = strdup(ptr);
name[strlen(name)-1] = '\0';
if(!strlen(name)) {
pm_printf(PM_LOG_ERROR, _("config file %s, line %d: bad section name.\n"), pm_printf(PM_LOG_ERROR, _("config file %s, line %d: bad section name.\n"),
file, linenum); file, linenum);
ret = 1; ret = 1;
goto cleanup; goto cleanup;
} }
/* new config section, skip the '[' */
name = strdup(line + 1);
name[line_len - 2] = '\0';
pm_printf(PM_LOG_DEBUG, "config: new section '%s'\n", name); pm_printf(PM_LOG_DEBUG, "config: new section '%s'\n", name);
/* if we are not looking at the options section, register a db */ /* if we are not looking at the options section, register a db */
if(!parse_options && strcmp(name, "options") != 0) { if(!parse_options && strcmp(name, "options") != 0) {
@ -634,7 +653,7 @@ static int _parseconfig(const char *file, int parse_options,
for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) { for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) {
pm_printf(PM_LOG_DEBUG, "config file %s, line %d: including %s\n", pm_printf(PM_LOG_DEBUG, "config file %s, line %d: including %s\n",
file, linenum, globbuf.gl_pathv[gindex]); file, linenum, globbuf.gl_pathv[gindex]);
_parseconfig(globbuf.gl_pathv[gindex], parse_options, section, db); _parseconfig(globbuf.gl_pathv[gindex], section, db, parse_options, depth++);
} }
break; break;
} }
@ -690,7 +709,7 @@ cleanup:
} }
/** Parse a configuration file. /** Parse a configuration file.
* @param file path to the config file. * @param file path to the config file
* @return 0 on success, non-zero on error * @return 0 on success, non-zero on error
*/ */
int parseconfig(const char *file) int parseconfig(const char *file)
@ -703,7 +722,7 @@ int parseconfig(const char *file)
/* call the real parseconfig function with a null section & db argument */ /* call the real parseconfig function with a null section & db argument */
pm_printf(PM_LOG_DEBUG, "parseconfig: options pass\n"); pm_printf(PM_LOG_DEBUG, "parseconfig: options pass\n");
if((ret = _parseconfig(file, 1, &section, NULL))) { if((ret = _parseconfig(file, &section, NULL, 1, 0))) {
free(section); free(section);
return ret; return ret;
} }
@ -714,7 +733,7 @@ int parseconfig(const char *file)
/* second pass, repo section parsing */ /* second pass, repo section parsing */
section = NULL; section = NULL;
pm_printf(PM_LOG_DEBUG, "parseconfig: repo pass\n"); pm_printf(PM_LOG_DEBUG, "parseconfig: repo pass\n");
return _parseconfig(file, 0, &section, NULL); return _parseconfig(file, &section, NULL, 0, 0);
free(section); free(section);
} }