commit:     1610679b5ad27ec4dcab56e2eb598edfeda4f8aa
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon Jun 10 15:27:36 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon Jun 10 15:27:36 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=1610679b

qmerge: rework config_protected

faccessat does not support AT_SYMLINK_NOFOLLOW according to the
specification, hopefully this is the problem Travis runs into

try to clear up the EPREFIX mess somewhat by calling config_protected
with a non-Prefixed path, and doing the existance checking in merge
itself only

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 qmerge.c | 49 ++++++++++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/qmerge.c b/qmerge.c
index 8644ddc..c48ecd2 100644
--- a/qmerge.c
+++ b/qmerge.c
@@ -355,12 +355,6 @@ config_protected(const char *buf, int cp_argc, char 
**cp_argv,
                  int cpm_argc, char **cpm_argv)
 {
        int i;
-       char dest[_Q_PATH_MAX];
-       snprintf(dest, sizeof(dest), "%s%s", portroot, buf);
-
-       /* config protect paths don't carry EPREFIX */
-       if (strncmp(buf, CONFIG_EPREFIX, strlen(CONFIG_EPREFIX) - 1) == 0)
-               buf += strlen(CONFIG_EPREFIX) - 1;
 
        /* Check CONFIG_PROTECT_MASK */
        for (i = 1; i < cpm_argc; ++i)
@@ -370,8 +364,7 @@ config_protected(const char *buf, int cp_argc, char 
**cp_argv,
        /* Check CONFIG_PROTECT */
        for (i = 1; i < cp_argc; ++i)
                if (strncmp(cp_argv[i], buf, strlen(cp_argv[i])) == 0)
-                       if (access(dest, R_OK) == 0)
-                               return 1;
+                       return 1;
 
        /* this would probably be bad */
        if (strcmp(CONFIG_EPREFIX "bin/sh", buf) == 0)
@@ -777,7 +770,7 @@ pkg_run_func_at(int dirfd, const char *vdb_path, const char 
*phases, const char
 /* Copy one tree (the single package) to another tree (ROOT) */
 static int
 merge_tree_at(int fd_src, const char *src, int fd_dst, const char *dst,
-              FILE *contents, set **objs, char **cpathp,
+              FILE *contents, size_t eprefix_len, set **objs, char **cpathp,
               int cp_argc, char **cp_argv, int cpm_argc, char **cpm_argv)
 {
        int i, ret, subfd_src, subfd_dst;
@@ -847,8 +840,9 @@ merge_tree_at(int fd_src, const char *src, int fd_dst, 
const char *dst,
                        qprintf("%s>>>%s %s%s%s/\n", GREEN, NORM, DKBLUE, 
cpath, NORM);
 
                        /* Copy all of these contents */
-                       merge_tree_at(subfd_src, name, subfd_dst, name, 
contents, objs,
-                                       cpathp, cp_argc, cp_argv, cpm_argc, 
cpm_argv);
+                       merge_tree_at(subfd_src, name,
+                                       subfd_dst, name, contents, eprefix_len,
+                                       objs, cpathp, cp_argc, cp_argv, 
cpm_argc, cpm_argv);
                        cpath = *cpathp;
                        mnlen = 0;
 
@@ -862,6 +856,7 @@ merge_tree_at(int fd_src, const char *src, int fd_dst, 
const char *dst,
                        unsigned char *hash;
                        const char *tmpname, *dname;
                        char buf[_Q_PATH_MAX * 2];
+                       struct stat ignore;
 
                        /* syntax: obj filename hash mtime */
                        hash = hash_file_at(subfd_src, name, HASH_MD5);
@@ -871,7 +866,10 @@ merge_tree_at(int fd_src, const char *src, int fd_dst, 
const char *dst,
                        free(hash);
 
                        /* Check CONFIG_PROTECT */
-                       if (config_protected(cpath, cp_argc, cp_argv, cpm_argc, 
cpm_argv)) {
+                       if (config_protected(cpath + eprefix_len,
+                                               cp_argc, cp_argv, cpm_argc, 
cpm_argv) &&
+                                       fstatat(subfd_dst, name, &ignore, 
AT_SYMLINK_NOFOLLOW) == 0)
+                       {
                                /* ._cfg####_ */
                                char *num;
                                dname = buf;
@@ -880,7 +878,7 @@ merge_tree_at(int fd_src, const char *src, int fd_dst, 
const char *dst,
                                for (i = 0; i < 10000; ++i) {
                                        sprintf(num, "%04i", i);
                                        num[4] = '_';
-                                       if (faccessat(subfd_dst, dname, F_OK, 
AT_SYMLINK_NOFOLLOW))
+                                       if (fstatat(subfd_dst, dname, &ignore, 
AT_SYMLINK_NOFOLLOW))
                                                break;
                                }
                                qprintf("%s>>>%s %s (%s)\n", GREEN, NORM, 
cpath, dname);
@@ -1288,7 +1286,7 @@ pkg_merge(int level, const depend_atom *atom, const 
struct pkg_t *pkg)
        pkg_run_func("vdb", phases, "pkg_preinst", D, T);
 
        if (!eat_file("vdb/EPREFIX", &eprefix, &eprefix_len))
-               eprefix = NULL;
+               eprefix_len = 0;
 
        {
                int imagefd = open("image", O_RDONLY);
@@ -1300,7 +1298,7 @@ pkg_merge(int level, const depend_atom *atom, const 
struct pkg_t *pkg)
                if (fstat(imagefd, &st) == -1) {
                        close(imagefd);
                        err("Cannot stat image dirfd");
-               } else if (eprefix != NULL) {
+               } else if (eprefix_len > 0) {
                        int imagepfx = openat(imagefd, eprefix + 1, O_RDONLY);
                        if (imagepfx != -1) {
                                close(imagefd);
@@ -1333,7 +1331,6 @@ pkg_merge(int level, const depend_atom *atom, const 
struct pkg_t *pkg)
                close(imagefd);
        }
 
-       /* TODO: merge_tree_at should use this, and use chpathtool code? */
        if (eprefix != NULL)
                free(eprefix);
 
@@ -1350,8 +1347,9 @@ pkg_merge(int level, const depend_atom *atom, const 
struct pkg_t *pkg)
 
                cpath = xstrdup("");  /* xrealloced in merge_tree_at */
 
-               ret = merge_tree_at(AT_FDCWD, "image", AT_FDCWD, portroot, 
contents,
-                                       &objs, &cpath, cp_argc, cp_argv, 
cpm_argc, cpm_argv);
+               ret = merge_tree_at(AT_FDCWD, "image",
+                               AT_FDCWD, portroot, contents, eprefix_len,
+                               &objs, &cpath, cp_argc, cp_argv, cpm_argc, 
cpm_argv);
 
                free(cpath);
 
@@ -1450,11 +1448,11 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep,
                int cp_argc, char **cp_argv, int cpm_argc, char **cpm_argv)
 {
        tree_cat_ctx *cat_ctx = pkg_ctx->cat_ctx;
-       const char *cat = cat_ctx->name;
-       const char *pkgname = pkg_ctx->name;
        size_t buflen;
        static char *phases;
        static size_t phases_len;
+       char *eprefix = NULL;
+       size_t eprefix_len = 0;
        const char *T;
        char *buf;
        FILE *fp;
@@ -1466,8 +1464,8 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep,
        buf = phases = NULL;
        T = "${PWD}/temp";
 
-       printf("%s<<<%s %s%s%s/%s%s%s\n",
-                       YELLOW, NORM, WHITE, cat, NORM, CYAN, pkgname, NORM);
+       printf("%s<<<%s %s\n", YELLOW, NORM,
+                       atom_format("%[CATEGORY]%[PF]", tree_get_atom(pkg_ctx, 
false), 0));
 
        if (pretend == 100)
                return 0;
@@ -1486,6 +1484,11 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep,
                pkg_run_func_at(pkg_ctx->fd, ".", phases, "pkg_prerm", T, T);
        }
 
+       if (!tree_pkg_vdb_eat(pkg_ctx, "EPREFIX", &eprefix, &eprefix_len))
+               eprefix_len = 0;
+       if (eprefix != NULL)
+               free(eprefix);
+
        unmerge_config_protected =
                strstr(features, "config-protect-if-modified") != NULL;
 
@@ -1500,7 +1503,7 @@ pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep,
                if (!e)
                        continue;
 
-               protected = config_protected(e->name,
+               protected = config_protected(e->name + eprefix_len,
                                cp_argc, cp_argv, cpm_argc, cpm_argv);
 
                /* This should never happen ... */

Reply via email to