summaryrefslogtreecommitdiff
path: root/src/pacman/conf.c
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2014-04-26 12:31:33 -0400
committerAllan McRae <allan@archlinux.org>2015-01-21 14:27:46 +1000
commit09cfe2a4c061a4b2c08d93c1d99f60c8879f5cf2 (patch)
treeeab0970d48e21ebd184e513b7c750bbfaa55bd5a /src/pacman/conf.c
parent9eb07a81fa359f323bfa540f8fbefa4c11e2260c (diff)
downloadpacman-09cfe2a4c061a4b2c08d93c1d99f60c8879f5cf2.tar.xz
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 <andrew.gregory.8@gmail.com>
Diffstat (limited to 'src/pacman/conf.c')
-rw-r--r--src/pacman/conf.c69
1 files changed, 69 insertions, 0 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 <limits.h>
#include <locale.h> /* setlocale */
#include <fcntl.h> /* open */
+#include <glob.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* 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,
@@ -896,6 +898,69 @@ static int _parse_repo(const char *key, char *value, const char *file,
}
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)
{
struct section_t *section = 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);