Blame posttrans.diff

ef05fe
--- ./lib/poptI.c.orig	2021-04-09 11:28:12.359647290 +0000
ef05fe
+++ ./lib/poptI.c	2021-04-09 11:28:15.523640983 +0000
ef05fe
@@ -265,6 +265,10 @@ struct poptOption rpmInstallPoptTable[]
ef05fe
 	&rpmIArgs.installInterfaceFlags, (INSTALL_REINSTALL|INSTALL_INSTALL),
ef05fe
 	N_("reinstall package(s)"),
ef05fe
 	N_("<packagefile>+") },
ef05fe
+ { "runposttrans", '\0', POPT_BIT_SET,
ef05fe
+	&rpmIArgs.installInterfaceFlags, INSTALL_RUNPOSTTRANS,
ef05fe
+	N_("run posttrans scriptlet"),
ef05fe
+	N_("<posttransmanifest>") },
ef05fe
 
ef05fe
    POPT_TABLEEND
ef05fe
 };
ef05fe
--- ./lib/psm.c.orig	2021-04-09 11:28:12.359647290 +0000
ef05fe
+++ ./lib/psm.c	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -810,7 +810,7 @@ static rpmRC rpmPackageErase(rpmts ts, r
ef05fe
 	}
ef05fe
 	if (rc) break;
ef05fe
 
ef05fe
-	if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
ef05fe
+	if (ts->dump_posttrans || !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
ef05fe
 	    /* Prepare post transaction uninstall triggers */
ef05fe
 	    rpmtriggersPrepPostUnTransFileTrigs(psm->ts, psm->te);
ef05fe
 	}
ef05fe
--- ./lib/rpmcli.h.orig	2021-04-09 11:28:12.359647290 +0000
ef05fe
+++ ./lib/rpmcli.h	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -304,6 +304,7 @@ enum rpmInstallFlags_e {
ef05fe
     INSTALL_ERASE	= (1 << 8),	/*!< from --erase */
ef05fe
     INSTALL_ALLMATCHES	= (1 << 9),	/*!< from --allmatches */
ef05fe
     INSTALL_REINSTALL	= (1 << 10),	/*!< from --reinstall */
ef05fe
+    INSTALL_RUNPOSTTRANS = (1 << 11),	/*!< from --runposttrans */
ef05fe
 };
ef05fe
 
ef05fe
 typedef rpmFlags rpmInstallFlags;
ef05fe
@@ -385,6 +386,15 @@ int rpmInstall(rpmts ts, struct rpmInsta
ef05fe
 int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv);
ef05fe
 
ef05fe
 /** \ingroup rpmcli
ef05fe
+ * Run posttrans scriptlets
ef05fe
+ * @param ts		transaction set
ef05fe
+ * @param ia		control args/bits
ef05fe
+ * @param argv		array of trigger manifest file names (NULL terminated)
ef05fe
+ * @return		0 on success
ef05fe
+ */
ef05fe
+int rpmRunPostTrans(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv);
ef05fe
+
ef05fe
+/** \ingroup rpmcli
ef05fe
  */
ef05fe
 extern struct rpmInstallArguments_s rpmIArgs;
ef05fe
 
ef05fe
--- ./lib/rpminstall.c.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./lib/rpminstall.c	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -4,6 +4,8 @@
ef05fe
 
ef05fe
 #include "system.h"
ef05fe
 
ef05fe
+#include <errno.h>
ef05fe
+
ef05fe
 #include <rpm/rpmcli.h>
ef05fe
 #include <rpm/rpmtag.h>
ef05fe
 #include <rpm/rpmlib.h>		/* rpmReadPackageFile, vercmp etc */
ef05fe
@@ -772,3 +774,32 @@ int rpmInstallSource(rpmts ts, const cha
ef05fe
     return rc;
ef05fe
 }
ef05fe
 
ef05fe
+int rpmRunPostTrans(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t fileArgv)
ef05fe
+{
ef05fe
+    ARGV_t manifest = NULL;
ef05fe
+    FILE *f;
ef05fe
+    char line[BUFSIZ], *s, *p;
ef05fe
+    int rc = 1;
ef05fe
+
ef05fe
+    if (fileArgv == NULL) return 0;
ef05fe
+    if (!fileArgv[0] || fileArgv[1] != NULL) {
ef05fe
+	rpmlog(RPMLOG_ERR, _("runposttrans needs exactly one manifest file\n"));
ef05fe
+	goto exit;
ef05fe
+    }
ef05fe
+    if (!(f = fopen(fileArgv[0], "r"))) {
ef05fe
+	rpmlog(RPMLOG_ERR, _("cannot open %s: %s\n"), fileArgv[0], strerror(errno));
ef05fe
+	goto exit;
ef05fe
+    }
ef05fe
+    while ((s = fgets(line, sizeof(line) - 1, f)) != 0) {
ef05fe
+	if (p = strrchr(s, '\n'))
ef05fe
+	    *p = 0;
ef05fe
+	argvAdd(&manifest, s);
ef05fe
+    }
ef05fe
+    fclose(f);
ef05fe
+    rpmlog(RPMLOG_DEBUG, "running posttrans scriptlets\n");
ef05fe
+    rpmtsClean(ts);
ef05fe
+    rc = rpmtsRunPostTrans(ts, manifest);
ef05fe
+exit:
ef05fe
+    argvFree(manifest);
ef05fe
+    return rc;
ef05fe
+}
ef05fe
--- ./lib/rpmtriggers.c.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./lib/rpmtriggers.c	2021-04-09 11:31:46.999219563 +0000
ef05fe
@@ -1,5 +1,6 @@
ef05fe
 #include "system.h"
ef05fe
 
ef05fe
+#include <rpm/rpmlog.h>
ef05fe
 #include <rpm/rpmts.h>
ef05fe
 #include <rpm/rpmdb.h>
ef05fe
 #include <rpm/rpmds.h>
ef05fe
@@ -34,7 +35,7 @@ rpmtriggers rpmtriggersFree(rpmtriggers
ef05fe
     return NULL;
ef05fe
 }
ef05fe
 
ef05fe
-static void rpmtriggersAdd(rpmtriggers trigs, unsigned int hdrNum,
ef05fe
+void rpmtriggersAdd(rpmtriggers trigs, unsigned int hdrNum,
ef05fe
 			    unsigned int tix, unsigned int priority)
ef05fe
 {
ef05fe
     if (trigs->count == trigs->alloced) {
ef05fe
@@ -177,6 +178,14 @@ int runPostUnTransFileTrigs(rpmts ts)
ef05fe
 	if (trigH == NULL)
ef05fe
 	    continue;
ef05fe
 
ef05fe
+	if (ts->dump_posttrans) {
ef05fe
+	    char *trigNEVRA = headerGetAsString(trigH, RPMTAG_NEVRA);
ef05fe
+	    rpmlog(RPMLOG_NOTICE, "dump_posttrans: transfiletriggerpostun %u %u %s\n", trigs->triggerInfo[i].tix, trigs->triggerInfo[i].hdrNum, trigNEVRA);
ef05fe
+	    free(trigNEVRA);
ef05fe
+	    headerFree(trigH);
ef05fe
+	    continue;
ef05fe
+	}
ef05fe
+
ef05fe
 	/* Prepare and run script */
ef05fe
 	script = rpmScriptFromTriggerTag(trigH,
ef05fe
 		triggertag(RPMSENSE_TRIGGERPOSTUN),
ef05fe
@@ -583,6 +592,16 @@ rpmRC runImmedFileTriggers(rpmts ts, rpm
ef05fe
     rpmTagVal priorityTag;
ef05fe
     rpmtriggers triggers;
ef05fe
 
ef05fe
+    if (sense == RPMSENSE_TRIGGERIN && tm == RPMSCRIPT_TRANSFILETRIGGER && ts->dump_posttrans) {
ef05fe
+	unsigned int hdrNum = headerGetInstance(trigH);
ef05fe
+	if (hdrNum) {
ef05fe
+	    char *trigNEVRA = headerGetAsString(trigH, RPMTAG_NEVRA);
ef05fe
+	    rpmlog(RPMLOG_NOTICE, "dump_posttrans: install %u %s\n", hdrNum, trigNEVRA);
ef05fe
+	    free(trigNEVRA);
ef05fe
+	}
ef05fe
+	headerFree(trigH);
ef05fe
+	return RPMRC_OK;
ef05fe
+    }
ef05fe
     if (tm == RPMSCRIPT_FILETRIGGER) {
ef05fe
 	priorityTag = RPMTAG_FILETRIGGERPRIORITIES;
ef05fe
     } else {
ef05fe
--- ./lib/rpmtriggers.h.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./lib/rpmtriggers.h	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -27,6 +27,10 @@ rpmtriggers rpmtriggersCreate(unsigned i
ef05fe
 RPM_GNUC_INTERNAL
ef05fe
 rpmtriggers rpmtriggersFree(rpmtriggers triggers);
ef05fe
 
ef05fe
+RPM_GNUC_INTERNAL
ef05fe
+void rpmtriggersAdd(rpmtriggers trigs, unsigned int hdrNum,
ef05fe
+			unsigned int tix, unsigned int priority);
ef05fe
+
ef05fe
 /*
ef05fe
  * Prepare post trans uninstall file triggers. After transcation uninstalled
ef05fe
  * files are not saved anywhere. So we need during uninstalation of every
ef05fe
--- ./lib/rpmts.h.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./lib/rpmts.h	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -229,6 +229,15 @@ int rpmtsOrder(rpmts ts);
ef05fe
 int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet);
ef05fe
 
ef05fe
 /** \ingroup rpmts
ef05fe
+ * Run all posttrans scriptlets described in the manifest data.
ef05fe
+ *       
ef05fe
+ * @param ts		transaction set
ef05fe
+ * @param manifest	the manifest data
ef05fe
+ * @return		0 on success, -1 on error
ef05fe
+ */
ef05fe
+int rpmtsRunPostTrans(rpmts ts, ARGV_const_t manifest);
ef05fe
+
ef05fe
+/** \ingroup rpmts
ef05fe
  * Reference a transaction set instance.
ef05fe
  * @param ts		transaction set
ef05fe
  * @return		new transaction set reference
ef05fe
--- ./lib/rpmts_internal.h.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./lib/rpmts_internal.h	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -87,6 +87,7 @@ struct rpmts_s {
ef05fe
     rpmtriggers trigs2run;   /*!< Transaction file triggers */
ef05fe
 
ef05fe
     int min_writes;             /*!< macro minimize_writes used */
ef05fe
+    int dump_posttrans;		/*!< macro dump_posttrans used */
ef05fe
 };
ef05fe
 
ef05fe
 #ifdef __cplusplus
ef05fe
--- ./lib/transaction.c.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./lib/transaction.c	2021-04-09 11:33:22.247029757 +0000
ef05fe
@@ -1468,6 +1468,8 @@ static int rpmtsSetup(rpmts ts, rpmprobF
ef05fe
     /* Get available space on mounted file systems. */
ef05fe
     (void) rpmtsInitDSI(ts);
ef05fe
 
ef05fe
+    /* Initialize the dump_posttrans flag */
ef05fe
+    ts->dump_posttrans = (rpmExpandNumeric("%{?_dump_posttrans}") > 0);
ef05fe
     return 0;
ef05fe
 }
ef05fe
 
ef05fe
@@ -1846,22 +1848,26 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rp
ef05fe
     /* Actually install and remove packages */
ef05fe
     nfailed = rpmtsProcess(ts);
ef05fe
 
ef05fe
+    if (ts->dump_posttrans) {
ef05fe
+	rpmlog(RPMLOG_NOTICE, "dump_posttrans: enabled\n");
ef05fe
+    }
ef05fe
+
ef05fe
     /* Run %posttrans scripts unless disabled */
ef05fe
-    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS))) {
ef05fe
+    if (!ts->dump_posttrans && !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS))) {
ef05fe
 	rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
ef05fe
 	runTransScripts(ts, PKG_POSTTRANS);
ef05fe
     }
ef05fe
 
ef05fe
     /* Run %transfiletriggerpostun scripts unless disabled */
ef05fe
-    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
ef05fe
+    if (!ts->dump_posttrans && !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
ef05fe
 	runFileTriggers(ts, NULL, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0);
ef05fe
     }
ef05fe
-    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
ef05fe
+    if (ts->dump_posttrans || !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
ef05fe
 	runPostUnTransFileTrigs(ts);
ef05fe
     }
ef05fe
 
ef05fe
     /* Run %transfiletriggerin scripts unless disabled */
ef05fe
-    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
ef05fe
+    if (ts->dump_posttrans || !(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
ef05fe
 	runTransScripts(ts, PKG_TRANSFILETRIGGERIN);
ef05fe
     }
ef05fe
     /* Final exit code */
ef05fe
@@ -1884,3 +1890,110 @@ exit:
ef05fe
     rpmsqSetAction(SIGPIPE, oact);
ef05fe
     return rc;
ef05fe
 }
ef05fe
+
ef05fe
+static unsigned int runPostTransFindPkgNum(const char **lpp)
ef05fe
+{
ef05fe
+    const char *lp = *lpp;
ef05fe
+    unsigned int num = strtoul(lp, 0, 10);
ef05fe
+    while (*lp >= '0' && *lp <= '9')
ef05fe
+	lp++;
ef05fe
+    while (*lp == ' ')
ef05fe
+	lp++;
ef05fe
+    *lpp = lp;
ef05fe
+    return num;
ef05fe
+}
ef05fe
+
ef05fe
+static Header runPostTransFindPkg(rpmts ts, const char *lp)
ef05fe
+{
ef05fe
+    rpmdbMatchIterator mi;
ef05fe
+    Header h = NULL;
ef05fe
+    unsigned int hdrnum = runPostTransFindPkgNum(&lp);
ef05fe
+    if (!*lp)
ef05fe
+	return NULL;
ef05fe
+    if (hdrnum) {
ef05fe
+	mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &hdrnum, sizeof(hdrnum));
ef05fe
+	h = headerLink(rpmdbNextIterator(mi));
ef05fe
+	rpmdbFreeIterator(mi);
ef05fe
+    }
ef05fe
+    if (h) {
ef05fe
+	char *NEVRA = headerGetAsString(h, RPMTAG_NEVRA);
ef05fe
+	if (!NEVRA || strcmp(NEVRA, lp) != 0)
ef05fe
+	    h = headerFree(h);
ef05fe
+	_free(NEVRA);
ef05fe
+    }
ef05fe
+    if (!h) {
ef05fe
+	mi = rpmtsInitIterator(ts, RPMDBI_LABEL, lp, strlen(lp));
ef05fe
+	h = headerLink(rpmdbNextIterator(mi));
ef05fe
+	rpmdbFreeIterator(mi);
ef05fe
+    }
ef05fe
+    if (!h)
ef05fe
+	rpmlog(RPMLOG_WARNING, "package %s is not installed\n", lp);
ef05fe
+    return h;
ef05fe
+}
ef05fe
+
ef05fe
+int rpmtsRunPostTrans(rpmts ts, ARGV_const_t manifest)
ef05fe
+{
ef05fe
+    int rc = -1; /* assume failure */
ef05fe
+    /* setup */
ef05fe
+    tsMembers tsmem = rpmtsMembers(ts);
ef05fe
+    rpmtxn txn = NULL;
ef05fe
+    /* Ignore SIGPIPE for the duration of transaction */
ef05fe
+    rpmsqAction_t oact = rpmsqSetAction(SIGPIPE, RPMSQ_IGN);
ef05fe
+    /* Force default 022 umask during transaction for consistent results */
ef05fe
+    mode_t oldmask = umask(022);
ef05fe
+    
ef05fe
+    if (tsmem->orderCount)
ef05fe
+	goto exit;
ef05fe
+    char *line;
ef05fe
+    while ((line = *manifest++) != 0) {
ef05fe
+	if (!strncmp(line, "dump_posttrans: install ", 24)) {
ef05fe
+	    const char *lp = line + 24;
ef05fe
+	    Header h = runPostTransFindPkg(ts, lp);
ef05fe
+	    if (!h)
ef05fe
+		continue;
ef05fe
+	    rpmte p = rpmteNew(ts, h, TR_ADDED, line + 45, NULL, RPMTE_INSTALL);
ef05fe
+	    if (tsmem->orderCount >= tsmem->orderAlloced) {
ef05fe
+		tsmem->orderAlloced += (tsmem->orderCount - tsmem->orderAlloced) + tsmem->delta;
ef05fe
+		tsmem->order = xrealloc(tsmem->order, tsmem->orderAlloced * sizeof(*tsmem->order));
ef05fe
+	    }
ef05fe
+	    tsmem->order[tsmem->orderCount++] = p; 
ef05fe
+
ef05fe
+	    if (tsmem->addedPackages == NULL)
ef05fe
+		tsmem->addedPackages = rpmalCreate(ts, 5);
ef05fe
+	    rpmalAdd(tsmem->addedPackages, p);
ef05fe
+	    packageHashAddEntry(tsmem->installedPackages, headerGetInstance(h), p);
ef05fe
+	} else if (!strncmp(line, "dump_posttrans: transfiletriggerpostun ", 39)) {
ef05fe
+	    const char *lp = line + 39;
ef05fe
+	    unsigned int tix = runPostTransFindPkgNum(&lp);
ef05fe
+	    Header h = runPostTransFindPkg(ts, lp);
ef05fe
+	    struct rpmtd_s priorities;
ef05fe
+	    if (!h)
ef05fe
+		continue;
ef05fe
+	    headerGet(h, RPMTAG_TRANSFILETRIGGERPRIORITIES, &priorities, HEADERGET_MINMEM);
ef05fe
+	    if (rpmtdSetIndex(&priorities, tix) >= 0)
ef05fe
+		rpmtriggersAdd(ts->trigs2run, headerGetInstance(h), tix, *rpmtdGetUint32(&priorities));
ef05fe
+	    headerFree(h);
ef05fe
+	}
ef05fe
+    }
ef05fe
+
ef05fe
+    if (!(txn = rpmtxnBegin(ts, RPMTXN_WRITE)))
ef05fe
+	goto exit;
ef05fe
+
ef05fe
+    /* run posttrans scripts */
ef05fe
+    rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
ef05fe
+    runTransScripts(ts, PKG_POSTTRANS);
ef05fe
+    /* run %transfiletriggerin scripts */
ef05fe
+    runFileTriggers(ts, NULL, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0);
ef05fe
+    /* run %transfiletriggerpostun scrips */
ef05fe
+    runPostUnTransFileTrigs(ts);
ef05fe
+    /* Run immed %transfiletriggerin scripts */
ef05fe
+    runTransScripts(ts, PKG_TRANSFILETRIGGERIN);
ef05fe
+    rc = 0;
ef05fe
+
ef05fe
+exit:
ef05fe
+    (void) umask(oldmask);
ef05fe
+    rpmtxnEnd(txn);
ef05fe
+    rpmsqSetAction(SIGPIPE, oact);
ef05fe
+    rpmtsEmpty(ts);
ef05fe
+    return rc;
ef05fe
+}
ef05fe
--- ./rpm.c.orig	2021-04-09 11:28:12.363647282 +0000
ef05fe
+++ ./rpm.c	2021-04-09 11:28:15.527640975 +0000
ef05fe
@@ -19,6 +19,7 @@ enum modes {
ef05fe
     MODE_INSTALL	= (1 <<  1),
ef05fe
     MODE_ERASE		= (1 <<  2),
ef05fe
 #define	MODES_IE (MODE_INSTALL | MODE_ERASE)
ef05fe
+    MODE_RUNPOSTTRANS	= (1 <<  4),
ef05fe
 
ef05fe
     MODE_UNKNOWN	= 0
ef05fe
 };
ef05fe
@@ -114,6 +115,11 @@ int main(int argc, char *argv[])
ef05fe
 			 INSTALL_INSTALL|INSTALL_REINSTALL));
ef05fe
 	int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
ef05fe
 
ef05fe
+	if (ia->installInterfaceFlags & INSTALL_RUNPOSTTRANS) {
ef05fe
+	    if (iflags || eflags)
ef05fe
+		argerror(_("only one major mode may be specified"));
ef05fe
+	    bigMode = MODE_RUNPOSTTRANS;
ef05fe
+	}
ef05fe
 	if (iflags & eflags)
ef05fe
 	    argerror(_("only one major mode may be specified"));
ef05fe
 	else if (iflags)
ef05fe
@@ -286,6 +292,14 @@ int main(int argc, char *argv[])
ef05fe
 	ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
ef05fe
     }	break;
ef05fe
 
ef05fe
+    case MODE_RUNPOSTTRANS:
ef05fe
+	if (!poptPeekArg(optCon)) {
ef05fe
+	    argerror(_("need posttrans manifest for --runposttrans"));
ef05fe
+	} else {
ef05fe
+	    ec += rpmRunPostTrans(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
ef05fe
+	}
ef05fe
+	break;
ef05fe
+
ef05fe
     case MODE_UNKNOWN:
ef05fe
 	if (poptPeekArg(optCon) != NULL || argc <= 1) {
ef05fe
 	    printUsage(optCon, stderr, 0);