From 641ab97226bd2398b71656d80b715255fa1a30d9 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 4 Sep 2017 17:39:16 +0300 Subject: Always execute scriptlet callbacks with owning header (RhBug:1485389) Triggers and file triggers can and do execute scriptlets from installed packages which are not part of the current transaction and thus have no associated transaction element, making the scriptlet callbacks inconsistent and cumbersome for API users. Create a fake transaction element for the poor orphan scriptlets lacking one to make it consistent (of course, creating rpmte's with all their associated data just to pass a header pointer along is ridiculously expensive but *shrug*). Regular triggers used to execute in the context of the triggering transaction element, make them run with the owning trigger header too. (cherry picked from commit 6d610e9b9a906548ce44265d7f36199441ea8bca) --- lib/psm.c | 7 +++---- lib/rpmtriggers.c | 4 ++-- lib/rpmts_internal.h | 2 +- lib/transaction.c | 12 +++++++++++- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/psm.c b/lib/psm.c index 266b14a6f..bf7e572f5 100644 --- a/lib/psm.c +++ b/lib/psm.c @@ -249,7 +249,7 @@ static rpmRC runInstScript(rpmpsm psm, rpmTagVal scriptTag) if (script) { headerGet(h, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV); - rc = runScript(psm->ts, psm->te, pfx.data, script, psm->scriptArg, -1); + rc = runScript(psm->ts, psm->te, h, pfx.data, script, psm->scriptArg, -1); rpmtdFreeData(&pfx); } @@ -312,8 +312,7 @@ static rpmRC handleOneTrigger(rpmts ts, rpmte te, rpmsenseFlags sense, rpmScript script = rpmScriptFromTriggerTag(trigH, triggertag(sense), RPMSCRIPT_NORMALTRIGGER, tix); arg1 += countCorrection; - rc = runScript(ts, te, pfx.data, script, arg1, arg2); - + rc = runScript(ts, te, trigH, pfx.data, script, arg1, arg2); if (triggersAlreadyRun != NULL) triggersAlreadyRun[tix] = 1; @@ -361,7 +360,7 @@ static rpmRC runTriggers(rpmpsm psm, rpmsenseFlags sense) mi = rpmtsInitIterator(ts, RPMDBI_TRIGGERNAME, N, 0); while((triggeredH = rpmdbNextIterator(mi)) != NULL) { - nerrors += handleOneTrigger(ts, psm->te, sense, h, triggeredH, + nerrors += handleOneTrigger(ts, NULL, sense, h, triggeredH, 0, numPackage, NULL); } rpmdbFreeIterator(mi); diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c index cd5d6ff67..ea04b0357 100644 --- a/lib/rpmtriggers.c +++ b/lib/rpmtriggers.c @@ -183,7 +183,7 @@ int runPostUnTransFileTrigs(rpmts ts) headerGet(trigH, RPMTAG_INSTPREFIXES, &installPrefixes, HEADERGET_ALLOC|HEADERGET_ARGV); - nerrors += runScript(ts, NULL, installPrefixes.data, script, 0, 0); + nerrors += runScript(ts, NULL, trigH, installPrefixes.data, script, 0, 0); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); headerFree(trigH); @@ -424,7 +424,7 @@ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h, inputFunc = (char *(*)(void *)) matchFilesNext; rpmScriptSetNextFileFunc(script, inputFunc, mfi); - nerrors += runScript(ts, te, installPrefixes.data, + nerrors += runScript(ts, te, h, installPrefixes.data, script, 0, 0); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); diff --git a/lib/rpmts_internal.h b/lib/rpmts_internal.h index 6a30cc520..90334ba24 100644 --- a/lib/rpmts_internal.h +++ b/lib/rpmts_internal.h @@ -117,7 +117,7 @@ RPM_GNUC_INTERNAL rpmRC rpmtsSetupTransactionPlugins(rpmts ts); RPM_GNUC_INTERNAL -rpmRC runScript(rpmts ts, rpmte te, ARGV_const_t prefixes, +rpmRC runScript(rpmts ts, rpmte te, Header h, ARGV_const_t prefixes, rpmScript script, int arg1, int arg2); #ifdef __cplusplus diff --git a/lib/transaction.c b/lib/transaction.c index 31308d10c..a74e6c4e6 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -1413,9 +1413,10 @@ rpmRC rpmtsSetupTransactionPlugins(rpmts ts) * @param arg2 ditto, but for the target package * @return 0 on success */ -rpmRC runScript(rpmts ts, rpmte te, ARGV_const_t prefixes, +rpmRC runScript(rpmts ts, rpmte te, Header h, ARGV_const_t prefixes, rpmScript script, int arg1, int arg2) { + rpmte xte = te; rpmRC stoprc, rc = RPMRC_OK; rpmTagVal stag = rpmScriptTag(script); FD_t sfd = NULL; @@ -1424,6 +1425,12 @@ rpmRC runScript(rpmts ts, rpmte te, ARGV_const_t prefixes, stag != RPMTAG_PRETRANS && stag != RPMTAG_VERIFYSCRIPT); + /* Fake up a transaction element for triggers from rpmdb */ + if (te == NULL) { + te = rpmteNew(ts, h, TR_REMOVED, NULL, NULL); + rpmteSetHeader(te, h); + } + sfd = rpmtsNotify(ts, te, RPMCALLBACK_SCRIPT_START, stag, 0); if (sfd == NULL) sfd = rpmtsScriptFd(ts); @@ -1449,6 +1456,9 @@ rpmRC runScript(rpmts ts, rpmte te, ARGV_const_t prefixes, rpmtsNotify(ts, te, RPMCALLBACK_SCRIPT_ERROR, stag, rc); } + if (te != xte) + rpmteFree(te); + return rc; } -- cgit v1.2.1