[Rpm-maint] [PATCH] Use a file list to add build-id files to pkgList and explicitly set attrs.

Mark Wielaard mark at klomp.org
Fri Jun 9 12:52:31 UTC 2017


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 <mark at 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



More information about the Rpm-maint mailing list