When setting attributes with %attr or %defattr we want to be explicit
about the mode and not just use - to pick up the mode from the file
on disk.

Change the generation of build-id files to a file list using ARGV_t.
First go through the current package list and generate a files list.
Then add those files using the defaults mode/attr settings as if they
were part of the original package file list.

https://bugzilla.redhat.com/show_bug.cgi?id=1452893
https://bugzilla.redhat.com/show_bug.cgi?id=1458839

Signed-off-by: Mark Wielaard <m...@klomp.org>
---
 build/files.c | 310 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 167 insertions(+), 143 deletions(-)

diff --git a/build/files.c b/build/files.c
index 4911162..be72f0e 100644
--- a/build/files.c
+++ b/build/files.c
@@ -207,9 +207,9 @@ static char *mkattr(const char *fn)
 {
     char *s = NULL;
     if (fn)
-       rasprintf(&s, "%s(-,%s,%s) %s", "%attr", UID_0_USER, GID_0_GROUP, fn);
+       rasprintf(&s, "%s(755,%s,%s) %s", "%attr", UID_0_USER, GID_0_GROUP, fn);
     else
-       rasprintf(&s, "%s(-,%s,%s)", "%defattr", UID_0_USER, GID_0_GROUP);
+       rasprintf(&s, "%s(644,%s,%s,755)", "%defattr", UID_0_USER, GID_0_GROUP);
     return s;
 }
 
@@ -1614,6 +1614,15 @@ exit:
     return rc;
 }
 
+/* add a directory to the file list */
+static void argvAddDir(ARGV_t *filesp, const char *dir)
+{
+    char *line = NULL;
+    rasprintf(&line, "%%dir %s", dir);
+    argvAdd(filesp, line);
+    _free(line);
+}
+
 #if HAVE_LIBDW
 /* How build id links are generated.  See macros.in for description.  */
 #define BUILD_IDS_NONE     0
@@ -1621,7 +1630,7 @@ exit:
 #define BUILD_IDS_SEPARATE 2
 #define BUILD_IDS_COMPAT   3
 
-static int addNewIDSymlink(FileList fl,
+static int addNewIDSymlink(ARGV_t *files,
                           char *targetpath, char *idlinkpath,
                           int isDbg, int *dups)
 {
@@ -1670,8 +1679,7 @@ static int addNewIDSymlink(FileList fl,
        rpmlog(RPMLOG_ERR, "%s: %s -> %s: %m\n",
               linkerr, linkpath, targetpath);
     } else {
-       fl->cur.isDir = 0;
-       rc = addFile(fl, linkpath, NULL);
+       rc = argvAdd(files, linkpath);
     }
 
     if (nr > 0) {
@@ -1709,7 +1717,7 @@ static int addNewIDSymlink(FileList fl,
     return rc;
 }
 
-static int generateBuildIDs(FileList fl)
+static int generateBuildIDs(FileList fl, ARGV_t *files)
 {
     int rc = 0;
     int i;
@@ -1858,18 +1866,9 @@ static int generateBuildIDs(FileList fl)
            mainiddir = rpmGetPath(fl->buildRoot, BUILD_ID_DIR, NULL);
            debugiddir = rpmGetPath(fl->buildRoot, DEBUG_ID_DIR, NULL);
 
-           /* Make sure to reset all file flags to defaults.
-              Uses parseForAttr to reset ar, arFlags, and specdFlags.
-              Note that parseForAttr pokes at the attrstr, so we cannot
-              just pass a static string. */
-           fl->cur.attrFlags = 0;
-           fl->def.attrFlags = 0;
-           fl->def.verifyFlags = RPMVERIFY_ALL;
-           fl->cur.verifyFlags = RPMVERIFY_ALL;
-           fl->def.specdFlags |= SPECD_VERIFY;
-           fl->cur.specdFlags |= SPECD_VERIFY;
+           /* Make sure to reset all file flags to defaults.  */
            attrstr = mkattr(NULL);
-           parseForAttr(fl->pool, attrstr, 1, &fl->def);
+           argvAdd(files, attrstr);
            free (attrstr);
 
            /* Supported, but questionable.  */
@@ -1881,11 +1880,7 @@ static int generateBuildIDs(FileList fl)
                if ((rc = rpmioMkpath(mainiddir, 0755, -1, -1)) != 0) {
                    rpmlog(RPMLOG_ERR, "%s %s: %m\n", errdir, mainiddir);
                } else {
-                   attrstr = mkattr(mainiddir);
-                   parseForAttr(fl->pool, attrstr, 0, &fl->cur);
-                   fl->cur.isDir = 1;
-                   rc = addFile(fl, mainiddir, NULL);
-                   free (attrstr);
+                   argvAddDir(files, mainiddir);
                }
            }
 
@@ -1893,11 +1888,7 @@ static int generateBuildIDs(FileList fl)
                if ((rc = rpmioMkpath(debugiddir, 0755, -1, -1)) != 0) {
                    rpmlog(RPMLOG_ERR, "%s %s: %m\n", errdir, debugiddir);
                } else {
-                   attrstr = mkattr(debugiddir);
-                   parseForAttr(fl->pool, attrstr, 0, &fl->cur);
-                   fl->cur.isDir = 1;
-                   rc = addFile(fl, debugiddir, NULL);
-                   free (attrstr);
+                   argvAddDir(files, debugiddir);
                }
            }
        }
@@ -1936,114 +1927,113 @@ static int generateBuildIDs(FileList fl)
                    && (rc = rpmioMkpath(buildidsubdir, 0755, -1, -1)) != 0) {
                    rpmlog(RPMLOG_ERR, "%s %s: %m\n", errdir, buildidsubdir);
                } else {
-                   fl->cur.isDir = 1;
-                   if (!addsubdir
-                       || (rc = addFile(fl, buildidsubdir, NULL)) == 0) {
-                       char *linkpattern, *targetpattern;
-                       char *linkpath, *targetpath;
-                       int dups = 0;
-                       if (isDbg) {
-                           linkpattern = "%s/%s";
-                           targetpattern = "../../../../..%s";
-                       } else {
-                           linkpattern = "%s/%s";
-                           targetpattern = "../../../..%s";
-                       }
-                       rasprintf(&linkpath, linkpattern,
+                 if (addsubdir)
+                   argvAddDir (files, buildidsubdir);
+
+                 char *linkpattern, *targetpattern;
+                 char *linkpath, *targetpath;
+                 int dups = 0;
+                 if (isDbg) {
+                   linkpattern = "%s/%s";
+                   targetpattern = "../../../../..%s";
+                 } else {
+                   linkpattern = "%s/%s";
+                   targetpattern = "../../../..%s";
+                 }
+                 rasprintf(&linkpath, linkpattern,
+                           buildidsubdir, &ids[i][2]);
+                 rasprintf(&targetpath, targetpattern, paths[i]);
+                 rc = addNewIDSymlink(files, targetpath, linkpath,
+                                      isDbg, &dups);
+
+                 /* We might want to have a link from the debug
+                    build_ids dir to the main one. We create it
+                    when we are creating compat links or doing
+                    an old style alldebug build-ids package. In
+                    the first case things are simple since we
+                    just link to the main build-id symlink. The
+                    second case is a bit tricky, since we
+                    cannot be 100% sure the file names in the
+                    main and debug package match. Currently
+                    they do, but when creating parallel
+                    installable debuginfo packages they might
+                    not (in that case we might have to also
+                    strip the nvr from the debug name).
+
+                    In general either method is discouraged
+                    since it might create dangling symlinks if
+                    the package versions get out of sync.  */
+                 if (rc == 0 && isDbg
+                     && build_id_links == BUILD_IDS_COMPAT) {
+                   /* buildidsubdir already points to the
+                      debug buildid. We just need to setup
+                      the symlink to the main one. There
+                      might be duplicate IDs, those are found
+                      by the addNewIDSymlink above. Target
+                      the last found duplicate, if any. */
+                   free(linkpath);
+                   free(targetpath);
+                   if (dups == 0)
+                     {
+                       rasprintf(&linkpath, "%s/%s",
                                  buildidsubdir, &ids[i][2]);
-                       rasprintf(&targetpath, targetpattern, paths[i]);
-                       rc = addNewIDSymlink(fl, targetpath, linkpath,
-                                            isDbg, &dups);
-
-                       /* We might want to have a link from the debug
-                          build_ids dir to the main one. We create it
-                          when we are creating compat links or doing
-                          an old style alldebug build-ids package. In
-                          the first case things are simple since we
-                          just link to the main build-id symlink. The
-                          second case is a bit tricky, since we
-                          cannot be 100% sure the file names in the
-                          main and debug package match. Currently
-                          they do, but when creating parallel
-                          installable debuginfo packages they might
-                          not (in that case we might have to also
-                          strip the nvr from the debug name).
-
-                          In general either method is discouraged
-                           since it might create dangling symlinks if
-                           the package versions get out of sync.  */
-                       if (rc == 0 && isDbg
-                           && build_id_links == BUILD_IDS_COMPAT) {
-                           /* buildidsubdir already points to the
-                              debug buildid. We just need to setup
-                              the symlink to the main one. There
-                              might be duplicate IDs, those are found
-                              by the addNewIDSymlink above. Target
-                              the last found duplicate, if any. */
-                           free(linkpath);
-                           free(targetpath);
-                           if (dups == 0)
-                             {
-                               rasprintf(&linkpath, "%s/%s",
-                                         buildidsubdir, &ids[i][2]);
-                               rasprintf(&targetpath,
-                                         "../../../.build-id%s/%s",
-                                         subdir, &ids[i][2]);
-                             }
-                           else
-                             {
-                               rasprintf(&linkpath, "%s/%s.%d",
-                                         buildidsubdir, &ids[i][2], dups);
-                               rasprintf(&targetpath,
-                                         "../../../.build-id%s/%s.%d",
-                                         subdir, &ids[i][2], dups);
-                             }
-                           rc = addNewIDSymlink(fl, targetpath, linkpath,
-                                                0, NULL);
-                       }
-
-                       if (rc == 0 && isDbg
-                           && build_id_links == BUILD_IDS_ALLDEBUG) {
-                           /* buildidsubdir already points to the
-                              debug buildid. We do have to figure out
-                              the main ELF file though (which is most
-                              likely not in this package). Guess we
-                              can find it by stripping the
-                              /usr/lib/debug path and .debug
-                              prefix. Which might not really be
-                              correct if there was a more involved
-                              transformation (for example for
-                              parallel installable debuginfo
-                              packages), but then we shouldn't be
-                              using ALLDEBUG in the first place.
-                              Also ignore things like .dwz multifiles
-                              which don't end in ".debug". */
-                           int pathlen = strlen(paths[i]);
-                           int debuglen = strlen(".debug");
-                           int prefixlen = strlen(DEBUG_LIB_DIR);
-                           int vralen = vra == NULL ? 0 : strlen(vra);
-                           if (pathlen > prefixlen + debuglen + vralen
-                               && strcmp ((paths[i] + pathlen - debuglen),
-                                          ".debug") == 0) {
-                               free(linkpath);
-                               free(targetpath);
-                               char *targetstr = xstrdup (paths[i]
-                                                          + prefixlen);
-                               int targetlen = pathlen - prefixlen;
-                               int targetend = targetlen - debuglen - vralen;
-                               targetstr[targetend] = '\0';
-                               rasprintf(&linkpath, "%s/%s",
-                                         buildidsubdir, &ids[i][2]);
-                               rasprintf(&targetpath, "../../../../..%s",
-                                         targetstr);
-                               rc = addNewIDSymlink(fl, targetpath,
-                                                    linkpath, 0, &dups);
-                               free(targetstr);
-                           }
-                       }
-                       free(linkpath);
-                       free(targetpath);
+                       rasprintf(&targetpath,
+                                 "../../../.build-id%s/%s",
+                                 subdir, &ids[i][2]);
+                     }
+                   else
+                     {
+                       rasprintf(&linkpath, "%s/%s.%d",
+                                 buildidsubdir, &ids[i][2], dups);
+                       rasprintf(&targetpath,
+                                 "../../../.build-id%s/%s.%d",
+                                 subdir, &ids[i][2], dups);
+                     }
+                   rc = addNewIDSymlink(files, targetpath, linkpath,
+                                        0, NULL);
+                 }
+
+                 if (rc == 0 && isDbg
+                     && build_id_links == BUILD_IDS_ALLDEBUG) {
+                   /* buildidsubdir already points to the
+                      debug buildid. We do have to figure out
+                      the main ELF file though (which is most
+                      likely not in this package). Guess we
+                      can find it by stripping the
+                      /usr/lib/debug path and .debug
+                      prefix. Which might not really be
+                      correct if there was a more involved
+                      transformation (for example for
+                      parallel installable debuginfo
+                      packages), but then we shouldn't be
+                      using ALLDEBUG in the first place.
+                      Also ignore things like .dwz multifiles
+                      which don't end in ".debug". */
+                   int pathlen = strlen(paths[i]);
+                   int debuglen = strlen(".debug");
+                   int prefixlen = strlen(DEBUG_LIB_DIR);
+                   int vralen = vra == NULL ? 0 : strlen(vra);
+                   if (pathlen > prefixlen + debuglen + vralen
+                       && strcmp ((paths[i] + pathlen - debuglen),
+                                  ".debug") == 0) {
+                     free(linkpath);
+                     free(targetpath);
+                     char *targetstr = xstrdup (paths[i]
+                                                + prefixlen);
+                     int targetlen = pathlen - prefixlen;
+                     int targetend = targetlen - debuglen - vralen;
+                     targetstr[targetend] = '\0';
+                     rasprintf(&linkpath, "%s/%s",
+                               buildidsubdir, &ids[i][2]);
+                     rasprintf(&targetpath, "../../../../..%s",
+                               targetstr);
+                     rc = addNewIDSymlink(files, targetpath,
+                                          linkpath, 0, &dups);
+                     free(targetstr);
                    }
+                 }
+                 free(linkpath);
+                 free(targetpath);
                }
                free(buildidsubdir);
            }
@@ -2478,11 +2468,54 @@ static rpmRC processPackageFiles(rpmSpec spec, 
rpmBuildPkgFlags pkgFlags,
     /* Check build-ids and add build-ids links for files to package list. */
     const char *arch = headerGetString(pkg->header, RPMTAG_ARCH);
     if (!rstreq(arch, "noarch")) {
-       if (generateBuildIDs (&fl) != 0) {
+       /* Go through the current package list and generate a files list. */
+       ARGV_t idFiles = NULL;
+       if (generateBuildIDs (&fl, &idFiles) != 0) {
            rpmlog(RPMLOG_ERR, _("Generating build-id links failed\n"));
            fl.processingFailed = 1;
            goto exit;
        }
+
+       /* Now add those files, see above, to the package list.
+          We reset the addition loop, slightly simplified since we know
+          the file list is sane, doesn't contain special files and all
+          paths are absolute. */
+       root_ar.ar_user = rpmstrPoolId(fl.pool, UID_0_USER, 1);
+       root_ar.ar_group = rpmstrPoolId(fl.pool, GID_0_GROUP, 1);
+       dupAttrRec(&root_ar, &fl.def.ar);/* XXX assume %defattr(-,root,root) */
+       fl.def.verifyFlags = RPMVERIFY_ALL;
+       for (ARGV_const_t fp = idFiles; fp && *fp != NULL; fp++) {
+           char buf[strlen(*fp) + 1];
+           fileNames = argvFree(fileNames);
+           rstrlcpy(buf, (const char *) *fp, sizeof(buf));
+
+           /* Reset for a new line in %files */
+           FileEntryFree(&fl.cur);
+
+           /* turn explicit flags into %def'd ones (gosh this is hacky...) */
+           fl.cur.specdFlags = ((unsigned)fl.def.specdFlags) >> 8;
+           fl.cur.verifyFlags = fl.def.verifyFlags;
+
+           if (parseForVerify(buf, 0, &fl.cur) ||
+               parseForVerify(buf, 1, &fl.def) ||
+               parseForAttr(fl.pool, buf, 0, &fl.cur) ||
+               parseForAttr(fl.pool, buf, 1, &fl.def) ||
+               parseForDev(buf, &fl.cur) ||
+               parseForConfig(buf, &fl.cur) ||
+               parseForLang(buf, &fl.cur) ||
+               parseForCaps(buf, &fl.cur) ||
+               parseForSimple(buf, &fl.cur, &fileNames))
+           {
+               fl.processingFailed = 1;
+               continue;
+           }
+
+           for (ARGV_const_t fn = fileNames; fn && *fn; fn++) {
+               if (fl.cur.attrFlags & RPMFILE_DIR)
+                   fl.cur.isDir = 1;
+               addFile(&fl, *fn, NULL);
+           }
+       }
     }
 #endif
 
@@ -2741,15 +2774,6 @@ static Package cloneDebuginfoPackage(rpmSpec spec, 
Package pkg, Package maindbg)
     return dbg;
 }
 
-/* add a directory to the file list */
-static void argvAddDir(ARGV_t *filesp, const char *dir)
-{
-    char *line = NULL;
-    rasprintf(&line, "%%dir %s", dir);
-    argvAdd(filesp, line);
-    _free(line);
-}
-
 /* collect the debug files for package pkg and put them into
  * a (possibly new) debuginfo subpackage */
 static void filterDebuginfoPackage(rpmSpec spec, Package pkg,
-- 
2.9.4

_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to