Hi

The attached patch adds support for scriptlet deps in generated deps.
Eg on Mageia, there's a file trigger for automatically
installing/removing info pages from /usr/share/info index

Having manual or auto generated "Requires: ..." mean some strong
deploops in base packages which rpmlib can break at random places,
sometimes borking scriptlets.

What we want in such a case is "Requires(posttrans): ..;" as
filetriggers will be run late anyway.

This patch enables to do that (but only in internal deps generators)

Example:
%__info_requires        %{_rpmconfigdir}/mageia/info-file.req
%__info_scriptlet       posttrans
%__info_path    ^%{_datadir}/info/.*\\.info.*$

See you
From c70b34df68cedc93c2a77fd92ceed3e78cc06651 Mon Sep 17 00:00:00 2001
From: Thierry Vignaud <tvign...@redhat.com>
Date: Sat, 8 Sep 2018 08:30:45 +0200
Subject: [PATCH] add support for scriptlet deps in generated deps

only in internal deps generators
---
 build/rpmfc.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/build/rpmfc.c b/build/rpmfc.c
index 2fbfc69ab..9fb7945e5 100644
--- a/build/rpmfc.c
+++ b/build/rpmfc.c
@@ -7,6 +7,7 @@
 #include <signal.h>
 #include <magic.h>
 #include <regex.h>
+#include <ctype.h>
 
 #include <rpm/header.h>
 #include <rpm/argv.h>
@@ -504,6 +505,7 @@ static ARGV_t runCmd(const char *nsdep, const char *depname,
 struct addReqProvDataFc {
     rpmfc fc;
     const char *namespace;
+    const char *scriptlet;
     regex_t *exclude;
 };
 
@@ -524,6 +526,61 @@ static rpmRC addReqProvFc(void *cbdata, rpmTagVal tagN,
     return RPMRC_OK;
 }
 
+// Stolen from build/parsePreamble.c
+typedef const struct tokenBits_s {
+    const char * name;
+    rpmsenseFlags bits;
+} * tokenBits;
+
+static struct tokenBits_s const installScriptBits[] = {
+    { "interp",         RPMSENSE_INTERP },
+    { "preun",          RPMSENSE_SCRIPT_PREUN },
+    { "pre",            RPMSENSE_SCRIPT_PRE },
+    { "postun",         RPMSENSE_SCRIPT_POSTUN },
+    { "post",           RPMSENSE_SCRIPT_POST },
+    //{ "rpmlib",         RPMSENSE_RPMLIB },
+    { "verify",         RPMSENSE_SCRIPT_VERIFY },
+    { "pretrans",       RPMSENSE_PRETRANS },
+    { "posttrans",      RPMSENSE_POSTTRANS },
+    { NULL, 0 }
+};
+
+static int parseBits(const char * s, const tokenBits tokbits,
+                rpmsenseFlags * bp)
+{
+    tokenBits tb;
+    const char * se;
+    rpmsenseFlags bits = RPMSENSE_ANY;
+    int c = 0;
+    int rc = RPMRC_OK;
+
+    if (s) {
+        while (*s != '\0') {
+            while ((c = *s) && risspace(c)) s++;
+            se = s;
+            while ((c = *se) && risalpha(c)) se++;
+            if (s == se)
+                break;
+            for (tb = tokbits; tb->name; tb++) {
+                if (tb->name != NULL &&
+                    strlen(tb->name) == (se-s) && rstreqn(tb->name, s, (se-s)))
+                    break;
+            }
+            if (tb->name == NULL) {
+                rc = RPMRC_FAIL;
+                break;
+            }
+            bits |= tb->bits;
+            while ((c = *se) && risspace(c)) se++;
+            if (c != ',')
+                break;
+            s = ++se;
+        }
+    }
+    *bp |= bits;
+    return rc;
+}
+
 /**
  * Run per-interpreter dependency helper.
  * @param fc		file classifier
@@ -541,6 +598,7 @@ static int rpmfcHelper(rpmfc fc, int ix,
     ARGV_t pav = NULL;
     const char * fn = fc->fn[ix];
     char *namespace = NULL;
+    char *scriptlet = NULL;
     int pac;
     int rc = 0;
     regex_t *exclude = NULL;
@@ -563,11 +621,19 @@ static int rpmfcHelper(rpmfc fc, int ix,
     pac = argvCount(pav);
     namespace = rpmfcAttrMacro(nsdep, "namespace", NULL);
     exclude = rpmfcAttrReg(depname, "exclude", NULL);
+    scriptlet = rpmfcAttrMacro(nsdep, "scriptlet", NULL);
+    rpmsenseFlags tagflags = RPMSENSE_ANY;
+    if (scriptlet && parseBits(scriptlet, installScriptBits, &tagflags)) {
+        rpmlog(RPMLOG_ERR, _("Bad scriptlet: %s\n"), scriptlet);
+        goto exit;
+    }
+    dsContext |= tagflags;
 
     struct addReqProvDataFc data;
     data.fc = fc;
     data.namespace = namespace;
     data.exclude = exclude;
+    data.scriptlet = scriptlet;
 
     for (int i = 0; i < pac; i++) {
 	if (parseRCPOT(NULL, fc->pkg, pav[i], tagN, ix, dsContext, addReqProvFc, &data))
@@ -577,6 +643,7 @@ static int rpmfcHelper(rpmfc fc, int ix,
     argvFree(pav);
     regFree(exclude);
     free(namespace);
+    free(scriptlet);
 
 exit:
     regFree(exclude_from);
-- 
2.18.0

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

Reply via email to