summaryrefslogtreecommitdiff
path: root/src/pacman/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/conf.c')
-rw-r--r--src/pacman/conf.c403
1 files changed, 249 insertions, 154 deletions
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 370ec510..a5bc1485 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -34,6 +34,7 @@
#include "conf.h"
#include "util.h"
#include "pacman.h"
+#include "callback.h"
/* global config variable */
config_t *config = NULL;
@@ -50,8 +51,8 @@ config_t *config_new(void)
/* defaults which may get overridden later */
newconfig->op = PM_OP_MAIN;
newconfig->logmask = PM_LOG_ERROR | PM_LOG_WARNING;
- /* CONFFILE is defined at compile-time */
newconfig->configfile = strdup(CONFFILE);
+ newconfig->sigverify = PM_PGP_VERIFY_UNKNOWN;
return newconfig;
}
@@ -64,12 +65,19 @@ int config_free(config_t *oldconfig)
FREELIST(oldconfig->holdpkg);
FREELIST(oldconfig->syncfirst);
+ FREELIST(oldconfig->ignorepkg);
+ FREELIST(oldconfig->ignoregrp);
+ FREELIST(oldconfig->noupgrade);
+ FREELIST(oldconfig->noextract);
free(oldconfig->configfile);
free(oldconfig->rootdir);
free(oldconfig->dbpath);
free(oldconfig->logfile);
+ free(oldconfig->gpgdir);
+ FREELIST(oldconfig->cachedirs);
free(oldconfig->xfercommand);
free(oldconfig->print_format);
+ free(oldconfig->arch);
free(oldconfig);
oldconfig = NULL;
@@ -206,12 +214,12 @@ int config_set_arch(const char *arch)
if(strcmp(arch, "auto") == 0) {
struct utsname un;
uname(&un);
- pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", un.machine);
- return alpm_option_set_arch(un.machine);
+ config->arch = strdup(un.machine);
} else {
- pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", arch);
- return alpm_option_set_arch(arch);
+ config->arch = strdup(arch);
}
+ pm_printf(PM_LOG_DEBUG, "config: arch: %s\n", config->arch);
+ return 0;
}
static pgp_verify_t option_verifysig(const char *value)
@@ -230,27 +238,19 @@ static pgp_verify_t option_verifysig(const char *value)
return level;
}
-/* helper for being used with setrepeatingoption */
-static int option_add_holdpkg(const char *name) {
- config->holdpkg = alpm_list_add(config->holdpkg, strdup(name));
- return 0;
-}
-
-/* helper for being used with setrepeatingoption */
-static int option_add_syncfirst(const char *name) {
- config->syncfirst = alpm_list_add(config->syncfirst, strdup(name));
- return 0;
-}
-
-/* helper for being used with setrepeatingoption */
-static int option_add_cleanmethod(const char *value) {
- if(strcmp(value, "KeepInstalled") == 0) {
- config->cleanmethod |= PM_CLEAN_KEEPINST;
- } else if(strcmp(value, "KeepCurrent") == 0) {
- config->cleanmethod |= PM_CLEAN_KEEPCUR;
- } else {
- pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"),
- value);
+static int process_cleanmethods(alpm_list_t *values) {
+ alpm_list_t *i;
+ for(i = values; i; i = alpm_list_next(i)) {
+ const char *value = i->data;
+ if(strcmp(value, "KeepInstalled") == 0) {
+ config->cleanmethod |= PM_CLEAN_KEEPINST;
+ } else if(strcmp(value, "KeepCurrent") == 0) {
+ config->cleanmethod |= PM_CLEAN_KEEPCUR;
+ } else {
+ pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"),
+ value);
+ return 1;
+ }
}
return 0;
}
@@ -260,21 +260,21 @@ static int option_add_cleanmethod(const char *value) {
* the exact same thing and duplicated code.
* @param ptr a pointer to the start of the multiple options
* @param option the string (friendly) name of the option, used for messages
- * @param optionfunc a function pointer to an alpm_option_add_* function
+ * @param list the list to add the option to
*/
static void setrepeatingoption(char *ptr, const char *option,
- int (*optionfunc)(const char *))
+ alpm_list_t **list)
{
char *q;
while((q = strchr(ptr, ' '))) {
*q = '\0';
- (*optionfunc)(ptr);
+ *list = alpm_list_add(*list, strdup(ptr));
pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr);
ptr = q;
ptr++;
}
- (*optionfunc)(ptr);
+ *list = alpm_list_add(*list, strdup(ptr));
pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr);
}
@@ -284,7 +284,7 @@ static int _parse_options(const char *key, char *value,
if(value == NULL) {
/* options without settings */
if(strcmp(key, "UseSyslog") == 0) {
- alpm_option_set_usesyslog(1);
+ config->usesyslog = 1;
pm_printf(PM_LOG_DEBUG, "config: usesyslog\n");
} else if(strcmp(key, "ILoveCandy") == 0) {
config->chomp = 1;
@@ -293,13 +293,13 @@ static int _parse_options(const char *key, char *value,
config->verbosepkglists = 1;
pm_printf(PM_LOG_DEBUG, "config: verbosepkglists\n");
} else if(strcmp(key, "UseDelta") == 0) {
- alpm_option_set_usedelta(1);
+ config->usedelta = 1;
pm_printf(PM_LOG_DEBUG, "config: usedelta\n");
} else if(strcmp(key, "TotalDownload") == 0) {
config->totaldownload = 1;
pm_printf(PM_LOG_DEBUG, "config: totaldownload\n");
} else if(strcmp(key, "CheckSpace") == 0) {
- alpm_option_set_checkspace(1);
+ config->checkspace = 1;
} else {
pm_printf(PM_LOG_WARNING,
_("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
@@ -308,19 +308,21 @@ static int _parse_options(const char *key, char *value,
} else {
/* options with settings */
if(strcmp(key, "NoUpgrade") == 0) {
- setrepeatingoption(value, "NoUpgrade", alpm_option_add_noupgrade);
+ setrepeatingoption(value, "NoUpgrade", &(config->noupgrade));
} else if(strcmp(key, "NoExtract") == 0) {
- setrepeatingoption(value, "NoExtract", alpm_option_add_noextract);
+ setrepeatingoption(value, "NoExtract", &(config->noextract));
} else if(strcmp(key, "IgnorePkg") == 0) {
- setrepeatingoption(value, "IgnorePkg", alpm_option_add_ignorepkg);
+ setrepeatingoption(value, "IgnorePkg", &(config->ignorepkg));
} else if(strcmp(key, "IgnoreGroup") == 0) {
- setrepeatingoption(value, "IgnoreGroup", alpm_option_add_ignoregrp);
+ setrepeatingoption(value, "IgnoreGroup", &(config->ignoregrp));
} else if(strcmp(key, "HoldPkg") == 0) {
- setrepeatingoption(value, "HoldPkg", option_add_holdpkg);
+ setrepeatingoption(value, "HoldPkg", &(config->holdpkg));
} else if(strcmp(key, "SyncFirst") == 0) {
- setrepeatingoption(value, "SyncFirst", option_add_syncfirst);
+ setrepeatingoption(value, "SyncFirst", &(config->syncfirst));
+ } else if(strcmp(key, "CacheDir") == 0) {
+ setrepeatingoption(value, "CacheDir", &(config->cachedirs));
} else if(strcmp(key, "Architecture") == 0) {
- if(!alpm_option_get_arch()) {
+ if(!config->arch) {
config_set_arch(value);
}
} else if(strcmp(key, "DBPath") == 0) {
@@ -329,13 +331,6 @@ static int _parse_options(const char *key, char *value,
config->dbpath = strdup(value);
pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", value);
}
- } else if(strcmp(key, "CacheDir") == 0) {
- if(alpm_option_add_cachedir(value) != 0) {
- pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"),
- value, alpm_strerrorlast());
- return 1;
- }
- pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", value);
} else if(strcmp(key, "RootDir") == 0) {
/* don't overwrite a path specified on the command line */
if(!config->rootdir) {
@@ -354,14 +349,19 @@ static int _parse_options(const char *key, char *value,
}
} else if(strcmp(key, "XferCommand") == 0) {
config->xfercommand = strdup(value);
- alpm_option_set_fetchcb(download_with_xfercommand);
pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value);
} else if(strcmp(key, "CleanMethod") == 0) {
- setrepeatingoption(value, "CleanMethod", option_add_cleanmethod);
+ alpm_list_t *methods = NULL;
+ setrepeatingoption(value, "CleanMethod", &methods);
+ if(process_cleanmethods(methods)) {
+ FREELIST(methods);
+ return 1;
+ }
+ FREELIST(methods);
} else if(strcmp(key, "VerifySig") == 0) {
pgp_verify_t level = option_verifysig(value);
if(level != PM_PGP_VERIFY_UNKNOWN) {
- alpm_option_set_default_sigverify(level);
+ config->sigverify = level;
} else {
pm_printf(PM_LOG_ERROR,
_("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
@@ -384,7 +384,7 @@ static int _add_mirror(pmdb_t *db, char *value)
/* let's attempt a replacement for the current repo */
char *temp = strreplace(value, "$repo", dbname);
/* let's attempt a replacement for the arch */
- const char *arch = alpm_option_get_arch();
+ const char *arch = config->arch;
char *server;
if(arch) {
server = strreplace(temp, "$arch", arch);
@@ -402,7 +402,7 @@ static int _add_mirror(pmdb_t *db, char *value)
if(alpm_db_add_server(db, server) != 0) {
/* pm_errno is set by alpm_db_setserver */
pm_printf(PM_LOG_ERROR, _("could not add server URL to database '%s': %s (%s)\n"),
- dbname, server, alpm_strerrorlast());
+ dbname, server, alpm_strerror(alpm_errno(config->handle)));
free(server);
return 1;
}
@@ -411,145 +411,248 @@ static int _add_mirror(pmdb_t *db, char *value)
return 0;
}
-/** Sets all libalpm required paths in one go. Called after the command line
+/** Sets up libalpm global stuff in one go. Called after the command line
* and inital config file parsing. Once this is complete, we can see if any
* paths were defined. If a rootdir was defined and nothing else, we want all
* of our paths to live under the rootdir that was specified. Safe to call
* multiple times (will only do anything the first time).
*/
-static int setlibpaths(void)
+static int setup_libalpm(void)
{
int ret = 0;
+ enum _pmerrno_t err;
+ pmhandle_t *handle;
+
+ pm_printf(PM_LOG_DEBUG, "setup_libalpm called\n");
- pm_printf(PM_LOG_DEBUG, "setlibpaths() called\n");
/* Configure root path first. If it is set and dbpath/logfile were not
* set, then set those as well to reside under the root. */
if(config->rootdir) {
char path[PATH_MAX];
- ret = alpm_option_set_root(config->rootdir);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting rootdir '%s' (%s)\n"),
- config->rootdir, alpm_strerrorlast());
- return ret;
- }
if(!config->dbpath) {
- /* omit leading slash from our static DBPATH, root handles it */
- snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), DBPATH + 1);
+ snprintf(path, PATH_MAX, "%s/%s", config->rootdir, DBPATH + 1);
config->dbpath = strdup(path);
}
if(!config->logfile) {
- /* omit leading slash from our static LOGFILE path, root handles it */
- snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), LOGFILE + 1);
+ snprintf(path, PATH_MAX, "%s/%s", config->rootdir, LOGFILE + 1);
config->logfile = strdup(path);
}
- }
- /* Set other paths if they were configured. Note that unless rootdir
- * was left undefined, these two paths (dbpath and logfile) will have
- * been set locally above, so the if cases below will now trigger. */
- if(config->dbpath) {
- ret = alpm_option_set_dbpath(config->dbpath);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting dbpath '%s' (%s)\n"),
- config->dbpath, alpm_strerrorlast());
- return ret;
+ } else {
+ config->rootdir = strdup(ROOTDIR);
+ if(!config->dbpath) {
+ config->dbpath = strdup(DBPATH);
}
}
- if(config->logfile) {
- ret = alpm_option_set_logfile(config->logfile);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"),
- config->logfile, alpm_strerrorlast());
- return ret;
- }
+
+ /* initialize library */
+ handle = alpm_initialize(config->rootdir, config->dbpath, &err);
+ if(!handle) {
+ pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"),
+ alpm_strerror(err));
+ return -1;
+ }
+ config->handle = handle;
+
+ alpm_option_set_logcb(handle, cb_log);
+ alpm_option_set_dlcb(handle, cb_dl_progress);
+
+ config->logfile = config->logfile ? config->logfile : strdup(LOGFILE);
+ ret = alpm_option_set_logfile(handle, config->logfile);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"),
+ config->logfile, alpm_strerror(alpm_errno(config->handle)));
+ return ret;
}
/* Set GnuPG's home directory. This is not relative to rootdir, even if
* rootdir is defined. Reasoning: gpgdir contains configuration data. */
- if(config->gpgdir) {
- ret = alpm_option_set_signaturedir(config->gpgdir);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"),
- config->gpgdir, alpm_strerrorlast());
- return ret;
- }
+ config->gpgdir = config->gpgdir ? config->gpgdir : strdup(GPGDIR);
+ ret = alpm_option_set_signaturedir(handle, config->gpgdir);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"),
+ config->gpgdir, alpm_strerror(alpm_errno(config->handle)));
+ return ret;
}
/* add a default cachedir if one wasn't specified */
- if(alpm_option_get_cachedirs() == NULL) {
- alpm_option_add_cachedir(CACHEDIR);
+ if(config->cachedirs == NULL) {
+ alpm_option_add_cachedir(handle, CACHEDIR);
+ } else {
+ alpm_option_set_cachedirs(handle, config->cachedirs);
+ }
+
+ if(config->sigverify != PM_PGP_VERIFY_UNKNOWN) {
+ alpm_option_set_default_sigverify(handle, config->sigverify);
+ }
+
+ if(config->xfercommand) {
+ alpm_option_set_fetchcb(handle, download_with_xfercommand);
}
+
+ if(config->totaldownload) {
+ alpm_option_set_totaldlcb(handle, cb_dl_total);
+ }
+
+ alpm_option_set_arch(handle, config->arch);
+ alpm_option_set_checkspace(handle, config->checkspace);
+ alpm_option_set_usesyslog(handle, config->usesyslog);
+ alpm_option_set_usedelta(handle, config->usedelta);
+ alpm_option_set_default_sigverify(handle, config->sigverify);
+
+ alpm_option_set_ignorepkgs(handle, config->ignorepkg);
+ alpm_option_set_ignoregrps(handle, config->ignoregrp);
+ alpm_option_set_noupgrades(handle, config->noupgrade);
+ alpm_option_set_noextracts(handle, config->noextract);
+
return 0;
}
+/**
+ * Allows parsing in advance of an entire config section before we start
+ * calling library methods.
+ */
+struct section_t {
+ /* useful for all sections */
+ char *name;
+ int is_options;
+ /* db section option gathering */
+ pgp_verify_t sigverify;
+ alpm_list_t *servers;
+};
+
+/**
+ * Wrap up a section once we have reached the end of it. This should be called
+ * when a subsequent section is encountered, or when we have reached the end of
+ * the root config file. Once called, all existing saved config pieces on the
+ * section struct are freed.
+ * @param section the current parsed and saved section data
+ * @param parse_options whether we are parsing options or repo data
+ * @return 0 on success, 1 on failure
+ */
+static int finish_section(struct section_t *section, int parse_options)
+{
+ int ret = 0;
+ alpm_list_t *i;
+ pmdb_t *db;
-/* The real parseconfig. Called with a null section argument by the publicly
- * visible parseconfig so we can recall from within ourself on an include */
-static int _parseconfig(const char *file, int parse_options,
- char **section, pmdb_t *db)
+ pm_printf(PM_LOG_DEBUG, "config: finish section '%s'\n", section->name);
+
+ /* parsing options (or nothing)- nothing to do except free the pieces */
+ if(!section->name || parse_options || section->is_options) {
+ goto cleanup;
+ }
+
+ /* if we are not looking at options sections only, register a db */
+ db = alpm_db_register_sync(config->handle, section->name);
+ if(db == NULL) {
+ pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
+ section->name, alpm_strerror(alpm_errno(config->handle)));
+ ret = 1;
+ goto cleanup;
+ }
+
+ if(section->sigverify) {
+ if(alpm_db_set_pgp_verify(db, section->sigverify)) {
+ pm_printf(PM_LOG_ERROR,
+ _("could not set verify option for database '%s' (%s)\n"),
+ section->name, alpm_strerror(alpm_errno(config->handle)));
+ ret = 1;
+ goto cleanup;
+ }
+ }
+
+ for(i = section->servers; i; i = alpm_list_next(i)) {
+ char *value = alpm_list_getdata(i);
+ if(_add_mirror(db, value) != 0) {
+ pm_printf(PM_LOG_ERROR,
+ _("could not add mirror '%s' to database '%s' (%s)\n"),
+ value, section->name, alpm_strerror(alpm_errno(config->handle)));
+ ret = 1;
+ goto cleanup;
+ }
+ free(value);
+ }
+
+cleanup:
+ alpm_list_free(section->servers);
+ section->servers = NULL;
+ section->sigverify = 0;
+ free(section->name);
+ section->name = NULL;
+ return ret;
+}
+
+/** The "real" parseconfig. Each "Include" directive will recall this method so
+ * recursion and stack depth are limited to 10 levels. The publicly visible
+ * parseconfig calls this with a NULL section argument so we can recall from
+ * within ourself on an include.
+ * @param file path to the config file
+ * @param section the current active section
+ * @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
+ * @return 0 on success, 1 on failure
+ */
+static int _parseconfig(const char *file, struct section_t *section,
+ int parse_options, int depth)
{
FILE *fp = NULL;
- char line[PATH_MAX+1];
+ char line[PATH_MAX];
int linenum = 0;
- char *ptr;
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);
fp = fopen(file, "r");
if(fp == NULL) {
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)) {
- char *key, *value;
+ char *key, *value, *ptr;
+ size_t line_len;
linenum++;
strtrim(line);
+ line_len = strlen(line);
/* ignore whole line and end of line comments */
- if(strlen(line) == 0 || line[0] == '#') {
+ if(line_len == 0 || line[0] == '#') {
continue;
}
if((ptr = strchr(line, '#'))) {
*ptr = '\0';
}
- /* sanity check */
- if(parse_options && db) {
- pm_printf(PM_LOG_ERROR, _("config file %s, line %d: parsing options but have a database.\n"),
- file, linenum);
- ret = 1;
- goto cleanup;
- }
-
- if(line[0] == '[' && line[strlen(line)-1] == ']') {
+ if(line[0] == '[' && line[line_len - 1] == ']') {
char *name;
- /* new config section, skip the '[' */
- ptr = line;
- ptr++;
- name = strdup(ptr);
- name[strlen(name)-1] = '\0';
- if(!strlen(name)) {
+ /* only possibility here is a line == '[]' */
+ if(line_len <= 2) {
pm_printf(PM_LOG_ERROR, _("config file %s, line %d: bad section name.\n"),
file, linenum);
ret = 1;
goto cleanup;
}
- pm_printf(PM_LOG_DEBUG, "config: new section '%s'\n", name);
- /* if we are not looking at the options section, register a db */
- if(!parse_options && strcmp(name, "options") != 0) {
- db = alpm_db_register_sync(name);
- if(db == NULL) {
- pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
- name, alpm_strerrorlast());
- ret = 1;
- goto cleanup;
- }
- }
- if(*section) {
- free(*section);
+ /* new config section, skip the '[' */
+ name = strdup(line + 1);
+ name[line_len - 2] = '\0';
+ /* we're at a new section; perform any post-actions for the prior */
+ if(finish_section(section, parse_options)) {
+ ret = 1;
+ goto cleanup;
}
- *section = name;
+ pm_printf(PM_LOG_DEBUG, "config: new section '%s'\n", name);
+ section->name = name;
+ section->is_options = (strcmp(name, "options") == 0);
continue;
}
@@ -568,7 +671,7 @@ static int _parseconfig(const char *file, int parse_options,
goto cleanup;
}
/* For each directive, compare to the camelcase string. */
- if(*section == NULL) {
+ if(section->name == NULL) {
pm_printf(PM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"),
file, linenum);
ret = 1;
@@ -608,19 +711,19 @@ static int _parseconfig(const char *file, int parse_options,
for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) {
pm_printf(PM_LOG_DEBUG, "config file %s, line %d: including %s\n",
file, linenum, globbuf.gl_pathv[gindex]);
- _parseconfig(globbuf.gl_pathv[gindex], parse_options, section, db);
+ _parseconfig(globbuf.gl_pathv[gindex], section, parse_options, depth + 1);
}
break;
}
globfree(&globbuf);
continue;
}
- if(parse_options && strcmp(*section, "options") == 0) {
+ if(parse_options && section->is_options) {
/* we are either in options ... */
if((ret = _parse_options(key, value, file, linenum)) != 0) {
goto cleanup;
}
- } else if (!parse_options && strcmp(*section, "options") != 0) {
+ } else if (!parse_options && !section->is_options) {
/* ... or in a repo section */
if(strcmp(key, "Server") == 0) {
if(value == NULL) {
@@ -629,19 +732,11 @@ static int _parseconfig(const char *file, int parse_options,
ret = 1;
goto cleanup;
}
- if(_add_mirror(db, value) != 0) {
- ret = 1;
- goto cleanup;
- }
+ section->servers = alpm_list_add(section->servers, strdup(value));
} else if(strcmp(key, "VerifySig") == 0) {
pgp_verify_t level = option_verifysig(value);
if(level != PM_PGP_VERIFY_UNKNOWN) {
- ret = alpm_db_set_pgp_verify(db, level);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("could not add set verify option for database '%s': %s (%s)\n"),
- alpm_db_get_name(db), value, alpm_strerrorlast());
- goto cleanup;
- }
+ section->sigverify = level;
} else {
pm_printf(PM_LOG_ERROR,
_("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
@@ -652,11 +747,15 @@ static int _parseconfig(const char *file, int parse_options,
} else {
pm_printf(PM_LOG_WARNING,
_("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
- file, linenum, key, *section);
+ file, linenum, key, section->name);
}
}
}
+ if(depth == 0) {
+ ret = finish_section(section, parse_options);
+ }
+
cleanup:
fclose(fp);
pm_printf(PM_LOG_DEBUG, "config: finished parsing %s\n", file);
@@ -664,33 +763,29 @@ cleanup:
}
/** 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
*/
int parseconfig(const char *file)
{
int ret;
- char *section = NULL;
+ struct section_t section;
+ memset(&section, 0, sizeof(struct section_t));
/* the config parse is a two-pass affair. We first parse the entire thing for
* the [options] section so we can get all default and path options set.
* Next, we go back and parse everything but [options]. */
/* call the real parseconfig function with a null section & db argument */
pm_printf(PM_LOG_DEBUG, "parseconfig: options pass\n");
- if((ret = _parseconfig(file, 1, &section, NULL))) {
- free(section);
+ if((ret = _parseconfig(file, &section, 1, 0))) {
return ret;
}
- free(section);
- /* call setlibpaths here to ensure we have called it at least once */
- if((ret = setlibpaths())) {
+ if((ret = setup_libalpm())) {
return ret;
}
/* second pass, repo section parsing */
- section = NULL;
pm_printf(PM_LOG_DEBUG, "parseconfig: repo pass\n");
- return _parseconfig(file, 0, &section, NULL);
- free(section);
+ return _parseconfig(file, &section, 0, 0);
}
/* vim: set ts=2 sw=2 noet: */