commit:     facaa636947ceeffce0c7a5a5dd52fee8e9175ca
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Wed Jun  3 15:40:42 2015 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Wed Jun  3 15:40:42 2015 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=facaa636

support repos.conf files

Since the system is moving away from PORTDIR/etc... and to a more
flexible repos.conf setup, make sure we support that stuff.

This pulls in an external dependency which is new for us, but the
iniparser library is very small (<20k on x86_64), written in pure
C, and is used by big projects already (like samba).  Doing an NIH
thing here would be a waste of time.

URL: https://bugs.gentoo.org/540620
Reported-by: Elias Probst <mail <AT> eliasprobst.eu>

 Makefile  |  1 +
 main.c    | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 porting.h |  2 ++
 3 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index 7304559..fe6092f 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ DBG_CFLAGS = -O0 -DEBUG -g3 -ggdb -fno-pie $(call check_gcc, 
-fsanitize=address
 #CFLAGS   += -Os -DOPTIMIZE_FOR_SIZE=2 -falign-functions=2 -falign-jumps=2 
-falign-labels=2 -falign-loops=2
 #LDFLAGS  := -pie
 LIBADD    += $(shell echo | $(CC) -dM -E - | grep -q ' __FreeBSD__' && echo 
'-lkvm')
+LIBADD    += -liniparser
 DESTDIR   :=
 PREFIX    := $(DESTDIR)/usr
 STRIP     := strip

diff --git a/main.c b/main.c
index 29a889f..cb180df 100644
--- a/main.c
+++ b/main.c
@@ -421,6 +421,57 @@ contents_entry *contents_parse_line(char *line)
        return &e;
 }
 
+/* Handle a single file in the repos.conf format. */
+static void read_one_repos_conf(const char *repos_conf)
+{
+       char *conf;
+       const char *repo, *path;
+       dictionary *dict;
+
+       dict = iniparser_load(repos_conf);
+
+       repo = iniparser_getstring(dict, "DEFAULT:main-repo", NULL);
+       if (repo) {
+               xasprintf(&conf, "%s:location", repo);
+               path = iniparser_getstring(dict, conf, NULL);
+               if (path) {
+                       free(portdir);
+                       portdir = xstrdup(path);
+               }
+               free(conf);
+       }
+
+       iniparser_freedict(dict);
+}
+
+/* Handle a possible directory of files. */
+static void read_repos_conf(const char *configroot, const char *repos_conf)
+{
+       char *top_conf, *sub_conf;
+       int i, count;
+       struct dirent **confs;
+
+       xasprintf(&top_conf, "%s%s", configroot, repos_conf);
+       count = scandir(top_conf, &confs, NULL, alphasort);
+       if (count == -1) {
+               if (errno == ENOTDIR)
+                       read_one_repos_conf(top_conf);
+       } else {
+               for (i = 0; i < count; ++i) {
+                       const char *name = confs[i]->d_name;
+
+                       if (name[0] == '.' || confs[i]->d_type != DT_REG)
+                               continue;
+
+                       xasprintf(&sub_conf, "%s/%s", top_conf, name);
+                       read_one_repos_conf(sub_conf);
+                       free(sub_conf);
+               }
+               scandir_free(confs, count);
+       }
+       free(top_conf);
+}
+
 static void strincr_var(const char *name, const char *s, char **value, size_t 
*value_len)
 {
        size_t len;
@@ -715,18 +766,18 @@ void initialize_portage_env(void)
        }
 
        /* figure out where to find our config files */
-       s = getenv("PORTAGE_CONFIGROOT");
-       if (!s)
-               s = "/";
+       const char *configroot = getenv("PORTAGE_CONFIGROOT");
+       if (!configroot)
+               configroot = "/";
 
        /* walk all the stacked profiles */
-       read_portage_profile(s, CONFIG_EPREFIX "etc/make.profile", 
vars_to_read);
-       read_portage_profile(s, CONFIG_EPREFIX "etc/portage/make.profile", 
vars_to_read);
+       read_portage_profile(configroot, CONFIG_EPREFIX "etc/make.profile", 
vars_to_read);
+       read_portage_profile(configroot, CONFIG_EPREFIX 
"etc/portage/make.profile", vars_to_read);
 
        /* now read all the config files */
        read_portage_env_file("", CONFIG_EPREFIX 
"usr/share/portage/config/make.globals", vars_to_read);
-       read_portage_env_file(s, CONFIG_EPREFIX "etc/make.conf", vars_to_read);
-       read_portage_env_file(s, CONFIG_EPREFIX "etc/portage/make.conf", 
vars_to_read);
+       read_portage_env_file(configroot, CONFIG_EPREFIX "etc/make.conf", 
vars_to_read);
+       read_portage_env_file(configroot, CONFIG_EPREFIX 
"etc/portage/make.conf", vars_to_read);
 
        /* finally, check the env */
        for (i = 0; vars_to_read[i].name; ++i) {
@@ -826,6 +877,8 @@ void initialize_portage_env(void)
                portroot[var->value_len + 1] = '\0';
        }
 
+       read_repos_conf(configroot, CONFIG_EPREFIX "etc/portage/repos.conf");
+
        if (getenv("PORTAGE_QUIET") != NULL)
                quiet = 1;
 

diff --git a/porting.h b/porting.h
index 3235542..8045813 100644
--- a/porting.h
+++ b/porting.h
@@ -49,6 +49,8 @@
 #include <sys/time.h>
 #include <sys/types.h>
 
+#include <iniparser.h>
+
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*(arr)))
 
 #ifndef BUFSIZE

Reply via email to