diff --git a/build/pack.c b/build/pack.c index e37c4e8993..a36a23a1ac 100644 --- a/build/pack.c +++ b/build/pack.c @@ -169,6 +169,8 @@ static rpmRC processScriptFiles(rpmSpec spec, Package pkg) addFileToTag(spec, pkg->postInFile, h, RPMTAG_POSTIN, 1) || addFileToTag(spec, pkg->postUnFile, h, RPMTAG_POSTUN, 1) || addFileToTag(spec, pkg->postTransFile, h, RPMTAG_POSTTRANS, 1) || + addFileToTag(spec, pkg->preunTransFile, h, RPMTAG_PREUNTRANS, 1) || + addFileToTag(spec, pkg->postunTransFile, h, RPMTAG_POSTUNTRANS, 1) || addFileToTag(spec, pkg->verifyFile, h, RPMTAG_VERIFYSCRIPT, 1)) { goto exit; diff --git a/build/parsePreamble.c b/build/parsePreamble.c index bd3da196d3..119551cf64 100644 --- a/build/parsePreamble.c +++ b/build/parsePreamble.c @@ -349,6 +349,8 @@ static struct tokenBits_s const installScriptBits[] = { { "verify", RPMSENSE_SCRIPT_VERIFY }, { "pretrans", RPMSENSE_PRETRANS }, { "posttrans", RPMSENSE_POSTTRANS }, + { "preuntrans", RPMSENSE_PREUNTRANS }, + { "postuntrans", RPMSENSE_POSTUNTRANS }, { NULL, 0 } }; diff --git a/build/parseScript.c b/build/parseScript.c index 95a9fc5906..df7919238e 100644 --- a/build/parseScript.c +++ b/build/parseScript.c @@ -159,6 +159,20 @@ int parseScript(rpmSpec spec, int parsePart) flagtag = RPMTAG_POSTTRANSFLAGS; partname = "%posttrans"; break; + case PART_PREUNTRANS: + tag = RPMTAG_PREUNTRANS; + tagflags = RPMSENSE_PREUNTRANS; + progtag = RPMTAG_PREUNTRANSPROG; + flagtag = RPMTAG_PREUNTRANSFLAGS; + partname = "%preuntrans"; + break; + case PART_POSTUNTRANS: + tag = RPMTAG_POSTUNTRANS; + tagflags = RPMSENSE_POSTUNTRANS; + progtag = RPMTAG_POSTUNTRANSPROG; + flagtag = RPMTAG_POSTUNTRANSFLAGS; + partname = "%postuntrans"; + break; case PART_VERIFYSCRIPT: tag = RPMTAG_VERIFYSCRIPT; tagflags = RPMSENSE_SCRIPT_VERIFY; @@ -451,6 +465,12 @@ int parseScript(rpmSpec spec, int parsePart) case PART_POSTTRANS: pkg->postTransFile = xstrdup(file); break; + case PART_PREUNTRANS: + pkg->preunTransFile = xstrdup(file); + break; + case PART_POSTUNTRANS: + pkg->postunTransFile = xstrdup(file); + break; case PART_VERIFYSCRIPT: pkg->verifyFile = xstrdup(file); break; diff --git a/build/parseSpec.c b/build/parseSpec.c index 85131d8f98..003568fc41 100644 --- a/build/parseSpec.c +++ b/build/parseSpec.c @@ -55,6 +55,8 @@ static const struct PartRec { { PART_POSTUN, LEN_AND_STR("%postun")}, { PART_PRETRANS, LEN_AND_STR("%pretrans")}, { PART_POSTTRANS, LEN_AND_STR("%posttrans")}, + { PART_PREUNTRANS, LEN_AND_STR("%preuntrans")}, + { PART_POSTUNTRANS, LEN_AND_STR("%postuntrans")}, { PART_PRE, LEN_AND_STR("%pre")}, { PART_POST, LEN_AND_STR("%post")}, { PART_FILES, LEN_AND_STR("%files")}, @@ -972,6 +974,8 @@ static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags, case PART_POSTUN: case PART_PRETRANS: case PART_POSTTRANS: + case PART_PREUNTRANS: + case PART_POSTUNTRANS: case PART_VERIFYSCRIPT: case PART_TRIGGERPREIN: case PART_TRIGGERIN: diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h index a93b339a18..df23e1cd8b 100644 --- a/build/rpmbuild_internal.h +++ b/build/rpmbuild_internal.h @@ -178,6 +178,8 @@ struct Package_s { char * postUnFile; /*!< %postun scriptlet. */ char * preTransFile; /*!< %pretrans scriptlet. */ char * postTransFile; /*!< %posttrans scriptlet. */ + char * preunTransFile; /*!< %preuntrans scriptlet. */ + char * postunTransFile; /*!< %postuntrans scriptlet. */ char * verifyFile; /*!< %verifyscript scriptlet. */ struct TriggerFileEntry * triggerFiles; @@ -242,7 +244,9 @@ typedef enum rpmParseState_e { PART_SOURCELIST = 41+PART_BASE, /*!< */ PART_BUILDREQUIRES = 42+PART_BASE, /*!< */ PART_CONF = 43+PART_BASE, /*!< */ - PART_LAST = 44+PART_BASE /*!< */ + PART_PREUNTRANS = 44+PART_BASE, /*!< */ + PART_POSTUNTRANS = 45+PART_BASE, /*!< */ + PART_LAST = 46+PART_BASE /*!< */ } rpmParseState; diff --git a/build/rpmfc.c b/build/rpmfc.c index be96d66116..d35c148b9a 100644 --- a/build/rpmfc.c +++ b/build/rpmfc.c @@ -1386,6 +1386,12 @@ static struct DepMsg_s depMsgs[] = { { "Requires(posttrans)", { NULL, "posttrans", NULL, NULL }, -1, -1, RPMTAG_REQUIREFLAGS, RPMSENSE_POSTTRANS, 0 }, + { "Requires(preuntrans)", { NULL, "preuntrans", NULL, NULL }, + -1, -1, RPMTAG_REQUIREFLAGS, + RPMSENSE_PREUNTRANS, 0 }, + { "Requires(postuntrans)", { NULL, "postuntrans", NULL, NULL }, + -1, -1, RPMTAG_REQUIREFLAGS, + RPMSENSE_POSTUNTRANS, 0 }, { "Requires", { "%{?__find_requires}", NULL, NULL, NULL }, -1, -1, RPMTAG_REQUIREFLAGS, /* XXX inherit name/version arrays */ RPMSENSE_FIND_REQUIRES|RPMSENSE_TRIGGERIN|RPMSENSE_TRIGGERUN|RPMSENSE_TRIGGERPOSTUN|RPMSENSE_TRIGGERPREIN, 0 }, diff --git a/docs/man/rpm.8.md b/docs/man/rpm.8.md index 088012cb12..450694f17f 100644 --- a/docs/man/rpm.8.md +++ b/docs/man/rpm.8.md @@ -351,16 +351,17 @@ This reinstalls a previously installed package. : Do not load and execute plugins. -**\--noscripts**, **\--nopre**, **\--nopost**, **\--nopreun**, **\--nopostun**, **\--nopretrans**, **\--noposttrans** +**\--noscripts**, **\--nopre**, **\--nopost**, **\--nopreun**, **\--nopostun**, **\--nopretrans**, **\--noposttrans**, **\--nopreuntrans**, **\--nopostuntrans** : Don\'t execute the scriptlet of the same name. The **\--noscripts** option is equivalent to **\--nopre** **\--nopost** **\--nopreun** **\--nopostun** -**\--nopretrans** **\--noposttrans** +**\--nopretrans** **\--noposttrans** **\--nopreuntrans** **\--nopostuntrans** and turns off the execution of the corresponding **%pre**, **%post**, -**%preun**, **%postun** **%pretrans**, and **%posttrans** scriptlet(s). +**%preun**, **%postun** **%pretrans**, **%posttrans**, **%preuntrans** +and **%postuntrans** scriptlet(s). **\--notriggers**, **\--notriggerin**, **\--notriggerun**, **\--notriggerprein**, **\--notriggerpostun** diff --git a/docs/manual/tags.md b/docs/manual/tags.md index 80cb157be3..0b62ccf91e 100644 --- a/docs/manual/tags.md +++ b/docs/manual/tags.md @@ -208,6 +208,12 @@ Posttrans | 1152 | string Posttransflags | 5025 | int32 Posttransprog | 1154 | string array +`%postuntrans` scripts are all executed at the end of the transaction that removes their packages + +Postuntrans | 5104 | string +Postuntransflags | 5108 | int32 +Postuntransprog | 5106 | string array + `%postun` script is executed right after the package was removed Postun | 1026 | string @@ -220,12 +226,18 @@ Prein | 1023 | string Preinflags | 5020 | int32 Preinprog | 1085 | string array -`%pretrans` scripts are executed for to be installed packages before any packages are installed +`%pretrans` scripts are executed for to be installed packages before any packages are installed/removed Pretrans | 1151 | string Pretransflags | 5024 | int32 Pretransprog | 1153 | string array +`%preuntrans` scripts are executed for to be removed packages before any packages are installed/removed + +Preuntrans | 5103 | string +Preuntransflags | 5107 | int32 +Preuntransprog | 5105 | string array + `%preun` script is executed right before the package gets removed Preun | 1025 | string diff --git a/docs/manual/triggers.md b/docs/manual/triggers.md index 75c37f84f0..21be3edb27 100644 --- a/docs/manual/triggers.md +++ b/docs/manual/triggers.md @@ -144,6 +144,7 @@ package upgrade: ``` all-%pretrans + all-%preuntrans ... any-%triggerprein (%triggerprein from other packages set off by new install) new-%triggerprein @@ -165,4 +166,5 @@ package upgrade: install) ... all-%posttrans + all-%postuntrans ``` diff --git a/include/rpm/rpmds.h b/include/rpm/rpmds.h index 5ffe7dc9d6..b9129ad758 100644 --- a/include/rpm/rpmds.h +++ b/include/rpm/rpmds.h @@ -45,7 +45,9 @@ enum rpmsenseFlags_e { RPMSENSE_TRIGGERUN = (1 << 17), /*!< %triggerun dependency. */ RPMSENSE_TRIGGERPOSTUN = (1 << 18), /*!< %triggerpostun dependency. */ RPMSENSE_MISSINGOK = (1 << 19), /*!< suggests/enhances hint. */ - /* bits 20-23 unused */ + RPMSENSE_PREUNTRANS = (1 << 20), /*!< %preuntrans dependency. */ + RPMSENSE_POSTUNTRANS = (1 << 21), /*!< %postuntrans dependency. */ + /* bits 22-23 unused */ RPMSENSE_RPMLIB = (1 << 24), /*!< rpmlib(feature) dependency. */ RPMSENSE_TRIGGERPREIN = (1 << 25), /*!< %triggerprein dependency. */ RPMSENSE_KEYRING = (1 << 26), @@ -74,6 +76,8 @@ typedef rpmFlags rpmsenseFlags; RPMSENSE_KEYRING | \ RPMSENSE_PRETRANS | \ RPMSENSE_POSTTRANS | \ + RPMSENSE_PREUNTRANS | \ + RPMSENSE_POSTUNTRANS | \ RPMSENSE_PREREQ | \ RPMSENSE_META | \ RPMSENSE_MISSINGOK) @@ -82,9 +86,9 @@ typedef rpmFlags rpmsenseFlags; #define _INSTALL_ONLY_MASK \ _notpre(RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POST|RPMSENSE_RPMLIB|RPMSENSE_KEYRING|RPMSENSE_PRETRANS|RPMSENSE_POSTTRANS) #define _ERASE_ONLY_MASK \ - _notpre(RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_POSTUN) + _notpre(RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_POSTUN|RPMSENSE_PREUNTRANS|RPMSENSE_POSTUNTRANS) #define _UNORDERED_ONLY_MASK \ - _notpre(RPMSENSE_RPMLIB|RPMSENSE_CONFIG|RPMSENSE_PRETRANS|RPMSENSE_POSTTRANS|RPMSENSE_SCRIPT_VERIFY|RPMSENSE_META) + _notpre(RPMSENSE_RPMLIB|RPMSENSE_CONFIG|RPMSENSE_PRETRANS|RPMSENSE_POSTTRANS|RPMSENSE_PREUNTRANS|RPMSENSE_POSTUNTRANS|RPMSENSE_SCRIPT_VERIFY|RPMSENSE_META) #define _FORCE_ORDER_ONLY_MASK \ _notpre(RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POST|RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_POSTUN) diff --git a/include/rpm/rpmtag.h b/include/rpm/rpmtag.h index fee21e98ae..9a18443b31 100644 --- a/include/rpm/rpmtag.h +++ b/include/rpm/rpmtag.h @@ -381,6 +381,12 @@ typedef enum rpmTag_e { RPMTAG_TRANSLATIONURL = 5100, /* s */ RPMTAG_UPSTREAMRELEASES = 5101, /* s */ RPMTAG_SOURCELICENSE = 5102, /* internal */ + RPMTAG_PREUNTRANS = 5103, /* s */ + RPMTAG_POSTUNTRANS = 5104, /* s */ + RPMTAG_PREUNTRANSPROG = 5105, /* s[] */ + RPMTAG_POSTUNTRANSPROG = 5106, /* s[] */ + RPMTAG_PREUNTRANSFLAGS = 5107, /* i */ + RPMTAG_POSTUNTRANSFLAGS = 5108, /* i */ RPMTAG_FIRSTFREE_TAG /*!< internal */ } rpmTag; diff --git a/include/rpm/rpmts.h b/include/rpm/rpmts.h index eb09ed61c5..b9eb6daa02 100644 --- a/include/rpm/rpmts.h +++ b/include/rpm/rpmts.h @@ -37,7 +37,9 @@ enum rpmtransFlags_e { RPMTRANS_FLAG_NOCONTEXTS = (1 << 8), /*!< from --nocontexts */ RPMTRANS_FLAG_NOCAPS = (1 << 9), /*!< from --nocaps */ RPMTRANS_FLAG_NODB = (1 << 10), /*!< from --nodb */ - /* bits 11-15 unused */ + /* bits 11-13 unused */ + RPMTRANS_FLAG_NOPREUNTRANS = (1 << 14), /*!< from --nopreuntrans */ + RPMTRANS_FLAG_NOPOSTUNTRANS = (1 << 15), /*!< from --nopostuntrans */ RPMTRANS_FLAG_NOTRIGGERPREIN= (1 << 16), /*!< from --notriggerprein */ RPMTRANS_FLAG_NOPRE = (1 << 17), /*!< from --nopre */ RPMTRANS_FLAG_NOPOST = (1 << 18), /*!< from --nopost */ @@ -65,7 +67,9 @@ typedef rpmFlags rpmtransFlags; RPMTRANS_FLAG_NOPREUN | \ RPMTRANS_FLAG_NOPOSTUN | \ RPMTRANS_FLAG_NOPRETRANS | \ - RPMTRANS_FLAG_NOPOSTTRANS \ + RPMTRANS_FLAG_NOPOSTTRANS | \ + RPMTRANS_FLAG_NOPREUNTRANS |\ + RPMTRANS_FLAG_NOPOSTUNTRANS \ ) #define _noTransTriggers \ diff --git a/lib/depends.c b/lib/depends.c index b690251db6..5076fc5013 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -522,7 +522,7 @@ static int rpmdbProvides(rpmts ts, depCache dcache, rpmds dep, dbiIndexSet *matc Header h = NULL; int rc = 0; /* pretrans deps are provided by current packages, don't prune erasures */ - int prune = (rpmdsFlags(dep) & RPMSENSE_PRETRANS) ? 0 : 1; + int prune = (rpmdsFlags(dep) & (RPMSENSE_PRETRANS|RPMSENSE_PREUNTRANS)) ? 0 : 1; unsigned int keyhash = 0; /* See if we already looked this up */ @@ -657,7 +657,7 @@ static dbiIndexSet unsatisfiedDependSet(rpmts ts, rpmds dep) rpmdbProvides(ts, NULL, dep, &set1); /* Pretrans dependencies can't be satisfied by added packages. */ - if (!(dsflags & RPMSENSE_PRETRANS)) { + if (!(dsflags & (RPMSENSE_PRETRANS|RPMSENSE_PREUNTRANS))) { rpmte *matches = rpmalAllSatisfiesDepend(tsmem->addedPackages, dep); if (matches) { for (rpmte *p = matches; *p; p++) @@ -771,7 +771,7 @@ static int unsatisfiedDepend(rpmts ts, depCache dcache, rpmds dep) } /* Pretrans dependencies can't be satisfied by added packages. */ - if (!(dsflags & RPMSENSE_PRETRANS)) { + if (!(dsflags & (RPMSENSE_PRETRANS|RPMSENSE_PREUNTRANS))) { rpmte *matches = rpmalAllSatisfiesDepend(tsmem->addedPackages, dep); int match = matches && *matches; _free(matches); @@ -784,7 +784,7 @@ static int unsatisfiedDepend(rpmts ts, depCache dcache, rpmds dep) goto exit; /* Search for an unsatisfied dependency. */ - if (adding && !retrying && !(dsflags & RPMSENSE_PRETRANS)) { + if (adding && !retrying && !(dsflags & (RPMSENSE_PRETRANS|RPMSENSE_PREUNTRANS))) { int xx = rpmtsSolve(ts, dep); if (xx == 0) goto exit; diff --git a/lib/formats.c b/lib/formats.c index a80ff330a8..317d3f62a4 100644 --- a/lib/formats.c +++ b/lib/formats.c @@ -187,6 +187,10 @@ static char * deptypeFormat(rpmtd td, char **emsg) argvAdd(&sdeps, "pretrans"); if (item & RPMSENSE_POSTTRANS) argvAdd(&sdeps, "posttrans"); + if (item & RPMSENSE_PREUNTRANS) + argvAdd(&sdeps, "preuntrans"); + if (item & RPMSENSE_POSTUNTRANS) + argvAdd(&sdeps, "postuntrans"); if (item & RPMSENSE_CONFIG) argvAdd(&sdeps, "config"); if (item & RPMSENSE_MISSINGOK) diff --git a/lib/poptI.c b/lib/poptI.c index 78ea2b92d7..c13e83a948 100644 --- a/lib/poptI.c +++ b/lib/poptI.c @@ -224,6 +224,12 @@ struct poptOption rpmInstallPoptTable[] = { { "noposttrans", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPOSTTRANS, N_("do not execute %%posttrans scriptlet (if any)"), NULL }, + { "nopreuntrans", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &rpmIArgs.transFlags, + RPMTRANS_FLAG_NOPREUNTRANS, + N_("do not execute %%preuntrans scriptlet (if any)"), NULL }, + { "nopostuntrans", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &rpmIArgs.transFlags, + RPMTRANS_FLAG_NOPOSTUNTRANS, + N_("do not execute %%postuntrans scriptlet (if any)"), NULL }, { "notriggers", '\0', POPT_BIT_SET, &rpmIArgs.transFlags, _noTransTriggers, N_("do not execute any scriptlet(s) triggered by this package"), NULL}, diff --git a/lib/psm.c b/lib/psm.c index c8849334c6..50ab12a0ad 100644 --- a/lib/psm.c +++ b/lib/psm.c @@ -470,6 +470,16 @@ static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal) psm->scriptArg = npkgs_installed + 1; psm->countCorrection = 0; break; + case PKG_PREUNTRANS: + if (rpmteDependsOn(psm->te)) + psm->scriptArg = npkgs_installed; + else + psm->scriptArg = npkgs_installed - 1; + psm->countCorrection = -1; + break; + case PKG_POSTUNTRANS: + psm->scriptArg = npkgs_installed; + break; case PKG_ERASE: psm->scriptArg = npkgs_installed - 1; psm->countCorrection = -1; @@ -880,6 +890,8 @@ static const char * pkgGoalString(pkgGoal goal) case PKG_VERIFY: return " verify"; case PKG_PRETRANS: return " pretrans"; case PKG_POSTTRANS: return "posttrans"; + case PKG_PREUNTRANS: return " preuntrans"; + case PKG_POSTUNTRANS: return "postuntrans"; default: return "unknown"; } } @@ -899,6 +911,8 @@ static rpmRC runGoal(rpmpsm psm, pkgGoal goal) break; case PKG_PRETRANS: case PKG_POSTTRANS: + case PKG_PREUNTRANS: + case PKG_POSTUNTRANS: case PKG_VERIFY: rc = runInstScript(psm, goal); break; diff --git a/lib/rpmscript.c b/lib/rpmscript.c index 5e785c52bb..fbc48421dd 100644 --- a/lib/rpmscript.c +++ b/lib/rpmscript.c @@ -67,6 +67,12 @@ static const struct scriptInfo_s scriptInfo[] = { { RPMSCRIPT_POSTTRANS, "posttrans", 0, RPMTAG_POSTTRANS, RPMTAG_POSTTRANSPROG, RPMTAG_POSTTRANSFLAGS, 0, }, + { RPMSCRIPT_PREUNTRANS, "preuntrans", 0, + RPMTAG_PREUNTRANS, RPMTAG_PREUNTRANSPROG, RPMTAG_PREUNTRANSFLAGS, + RPMSCRIPT_FLAG_CRITICAL, }, + { RPMSCRIPT_POSTUNTRANS, "postuntrans", 0, + RPMTAG_POSTUNTRANS, RPMTAG_POSTUNTRANSPROG, RPMTAG_POSTUNTRANSFLAGS, + 0, }, { RPMSCRIPT_TRIGGERPREIN, "triggerprein", RPMSENSE_TRIGGERPREIN, RPMTAG_TRIGGERPREIN, 0, 0, 0, }, diff --git a/lib/rpmscript.h b/lib/rpmscript.h index bb90cb0b1d..ad5410828a 100644 --- a/lib/rpmscript.h +++ b/lib/rpmscript.h @@ -17,6 +17,8 @@ enum rpmscriptTypes_e { RPMSCRIPT_TRIGGERPOSTUN = (1 << 7), RPMSCRIPT_PRETRANS = (1 << 8), RPMSCRIPT_POSTTRANS = (1 << 9), + RPMSCRIPT_PREUNTRANS = (1 << 10), + RPMSCRIPT_POSTUNTRANS = (1 << 11), /* ... */ RPMSCRIPT_VERIFY = (1 << 24), }; diff --git a/lib/rpmte.c b/lib/rpmte.c index 9c21c26965..6a62015754 100644 --- a/lib/rpmte.c +++ b/lib/rpmte.c @@ -75,6 +75,8 @@ struct rpmte_s { #define RPMTE_HAVE_PRETRANS (1 << 0) #define RPMTE_HAVE_POSTTRANS (1 << 1) +#define RPMTE_HAVE_PREUNTRANS (1 << 2) +#define RPMTE_HAVE_POSTUNTRANS (1 << 3) int transscripts; /*!< pre/posttrans script existence */ int failed; /*!< (parent) install/erase failed */ @@ -207,6 +209,12 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs) p->transscripts |= (headerIsEntry(h, RPMTAG_POSTTRANS) || headerIsEntry(h, RPMTAG_POSTTRANSPROG)) ? RPMTE_HAVE_POSTTRANS : 0; + p->transscripts |= (headerIsEntry(h, RPMTAG_PREUNTRANS) || + headerIsEntry(h, RPMTAG_PREUNTRANSPROG)) ? + RPMTE_HAVE_PREUNTRANS : 0; + p->transscripts |= (headerIsEntry(h, RPMTAG_POSTUNTRANS) || + headerIsEntry(h, RPMTAG_POSTUNTRANSPROG)) ? + RPMTE_HAVE_POSTUNTRANS : 0; rpmteColorDS(p, RPMTAG_PROVIDENAME); rpmteColorDS(p, RPMTAG_REQUIRENAME); @@ -583,18 +591,21 @@ static int rpmteOpen(rpmte te, int reload_fi) if (te == NULL || te->ts == NULL || rpmteFailed(te)) goto exit; - rpmteSetHeader(te, NULL); - switch (rpmteType(te)) { case TR_ADDED: h = rpmteDBInstance(te) ? rpmteDBHeader(te) : rpmteFDHeader(te); break; case TR_REMOVED: + if (te->h) { + h = headerLink(te->h); + break; + } case TR_RPMDB: case TR_RESTORED: h = rpmteDBHeader(te); break; } + if (h != NULL) { if (reload_fi) { /* This can fail if we get a different, bad header from callback */ @@ -614,6 +625,7 @@ static int rpmteOpen(rpmte te, int reload_fi) static int rpmteClose(rpmte te, int reset_fi) { + int keephdr = 0; if (te == NULL || te->ts == NULL) return 0; @@ -625,12 +637,15 @@ static int rpmteClose(rpmte te, int reset_fi) } break; case TR_REMOVED: + if (te->transscripts & RPMTE_HAVE_POSTUNTRANS) + keephdr = 1; case TR_RPMDB: case TR_RESTORED: /* eventually we'll want notifications for erase open too */ break; } - rpmteSetHeader(te, NULL); + if (!keephdr) + rpmteSetHeader(te, NULL); if (reset_fi) { rpmteCleanFiles(te); } @@ -676,11 +691,16 @@ int rpmteFailed(rpmte te) int rpmteHaveTransScript(rpmte te, rpmTagVal tag) { - int rc = 0; + /* We only filter pre/post transaction scripts */ + int rc = 1; if (tag == RPMTAG_PRETRANS) { rc = (te->transscripts & RPMTE_HAVE_PRETRANS); } else if (tag == RPMTAG_POSTTRANS) { rc = (te->transscripts & RPMTE_HAVE_POSTTRANS); + } else if (tag == RPMTAG_PREUNTRANS) { + rc = (te->transscripts & RPMTE_HAVE_PREUNTRANS); + } else if (tag == RPMTAG_POSTUNTRANS) { + rc = (te->transscripts & RPMTE_HAVE_POSTUNTRANS); } return rc; } @@ -800,11 +820,8 @@ int rpmteProcess(rpmte te, pkgGoal goal, int num) int failed = 1; /* Dont bother opening for elements without pre/posttrans scripts */ - if (goal == PKG_PRETRANS || goal == PKG_POSTTRANS) { - if (!rpmteHaveTransScript(te, goal)) { - return 0; - } - } + if (!rpmteHaveTransScript(te, goal)) + return 0; if (rpmteOpen(te, reset_fi)) { if (!scriptstage) { diff --git a/lib/rpmte_internal.h b/lib/rpmte_internal.h index f4b9860947..dad1f8d336 100644 --- a/lib/rpmte_internal.h +++ b/lib/rpmte_internal.h @@ -16,6 +16,8 @@ typedef enum pkgGoal_e { PKG_VERIFY = RPMTAG_VERIFYSCRIPT, PKG_PRETRANS = RPMTAG_PRETRANS, PKG_POSTTRANS = RPMTAG_POSTTRANS, + PKG_PREUNTRANS = RPMTAG_PREUNTRANS, + PKG_POSTUNTRANS = RPMTAG_POSTUNTRANS, PKG_TRANSFILETRIGGERIN = RPMTAG_TRANSFILETRIGGERIN, PKG_TRANSFILETRIGGERUN = RPMTAG_TRANSFILETRIGGERUN, } pkgGoal; diff --git a/lib/transaction.c b/lib/transaction.c index 7bdc177228..d9ed704b33 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -1436,10 +1436,19 @@ static int runTransScripts(rpmts ts, pkgGoal goal) int rc = 0; rpmte p; rpmtsi pi = rpmtsiInit(ts); - rpmElementTypes types = TR_ADDED; + rpmElementTypes types; int i = 0; - if (goal == PKG_TRANSFILETRIGGERUN) + + switch (goal) { + case PKG_TRANSFILETRIGGERUN: + case PKG_PREUNTRANS: + case PKG_POSTUNTRANS: types = TR_REMOVED; + break; + default: + types = TR_ADDED; + break; + } while ((p = rpmtsiNext(pi, types)) != NULL) { rc += rpmteProcess(p, goal, i++); @@ -1814,7 +1823,7 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet) */ if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRETRANS)) || (rpmpsNumProblems(tsprobs)))) { - rpmlog(RPMLOG_DEBUG, "running pre-transaction scripts\n"); + rpmlog(RPMLOG_DEBUG, "running %%pretrans scripts\n"); runTransScripts(ts, PKG_PRETRANS); } tsprobs = rpmpsFree(tsprobs); @@ -1844,6 +1853,11 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet) if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))) tsmem->pool = rpmstrPoolFree(tsmem->pool); + /* Run %preuntrans scripts unless disabled */ + if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUNTRANS)) { + rpmlog(RPMLOG_DEBUG, "running %%preuntrans scripts\n"); + runTransScripts(ts, PKG_PREUNTRANS); + } /* Run %transfiletriggerun scripts unless disabled */ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPRETRANS|RPMTRANS_FLAG_NOTRIGGERUN))) { runFileTriggers(ts, NULL, RPMSENSE_TRIGGERUN, @@ -1856,9 +1870,14 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet) /* Run %posttrans scripts unless disabled */ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS))) { - rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n"); + rpmlog(RPMLOG_DEBUG, "running %%posttrans scripts\n"); runTransScripts(ts, PKG_POSTTRANS); } + /* Run %postuntrans scripts unless disabled */ + if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUNTRANS)) { + rpmlog(RPMLOG_DEBUG, "running %%postuntrans scripts\n"); + runTransScripts(ts, PKG_POSTUNTRANS); + } /* Run %transfiletriggerpostun scripts unless disabled */ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) { diff --git a/python/rpmmodule.c b/python/rpmmodule.c index 0a9ac59112..4d32cdddc7 100644 --- a/python/rpmmodule.c +++ b/python/rpmmodule.c @@ -414,6 +414,8 @@ static int initModule(PyObject *m) REGISTER_ENUM(RPMSENSE_KEYRING); REGISTER_ENUM(RPMSENSE_CONFIG); REGISTER_ENUM(RPMSENSE_MISSINGOK); + REGISTER_ENUM(RPMSENSE_PREUNTRANS); + REGISTER_ENUM(RPMSENSE_POSTUNTRANS); REGISTER_ENUM(RPMTRANS_FLAG_TEST); REGISTER_ENUM(RPMTRANS_FLAG_BUILD_PROBS); @@ -431,6 +433,8 @@ static int initModule(PyObject *m) REGISTER_ENUM(RPMTRANS_FLAG_REVERSE); REGISTER_ENUM(RPMTRANS_FLAG_NOPRE); REGISTER_ENUM(RPMTRANS_FLAG_NOPOST); + REGISTER_ENUM(RPMTRANS_FLAG_NOPREUNTRANS); + REGISTER_ENUM(RPMTRANS_FLAG_NOPOSTUNTRANS); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERPREIN); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERIN); REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERUN); diff --git a/rpmpopt.in b/rpmpopt.in index 4409a04f6e..175a8f08ae 100644 --- a/rpmpopt.in +++ b/rpmpopt.in @@ -37,6 +37,14 @@ rpm alias --scripts --qf '\ %|POSTTRANSPROG?{ (using[ %{POSTTRANSPROG}])}|:\n%{POSTTRANS}\n}:\ {%|POSTTRANSPROG?{posttrans program:[ %{POSTTRANSPROG}]\n}|}|\ \ +%|PREUNTRANS?{preuntrans scriptlet\ +%|PREUNTRANSPROG?{ (using[ %{PREUNTRANSPROG}])}|:\n%{PREUNTRANS}\n}:\ +{%|PREUNTRANSPROG?{preuntrans program:[ %{PREUNTRANSPROG}]\n}|}|\ +\ +%|POSTUNTRANS?{postuntrans scriptlet\ +%|POSTUNTRANSPROG?{ (using[ %{POSTUNTRANSPROG}])}|:\n%{POSTUNTRANS}\n}:\ +{%|POSTUNTRANSPROG?{postuntrans program:[ %{POSTUNTRANSPROG}]\n}|}|\ +\ %|VERIFYSCRIPT?{verify scriptlet\ %|VERIFYSCRIPTPROG?{ (using[ %{VERIFYSCRIPTPROG}])}|:\n%{VERIFYSCRIPT}\n}:\ {%|VERIFYSCRIPTPROG?{verify program:[ %{VERIFYSCRIPTPROG}]\n}|}|\ diff --git a/tests/data/SPECS/scriptfail.spec b/tests/data/SPECS/scriptfail.spec index 70be3f342c..6101b4fbba 100644 --- a/tests/data/SPECS/scriptfail.spec +++ b/tests/data/SPECS/scriptfail.spec @@ -13,7 +13,7 @@ BuildArch: noarch %{summary} %{lua: -for i, s in ipairs({"pre","preun","pretrans","post","postun","posttrans"}) do +for i, s in ipairs({"pre","preun","pretrans","post","postun","posttrans","preuntrans","postuntrans"}) do print('%'..s..' -e\n') print('%{!?exit'..s..':%global exit'..s..' 0}\n') print('exit %{exit'..s..'}\n\n') diff --git a/tests/data/SPECS/scriptfile.spec b/tests/data/SPECS/scriptfile.spec index 97813a45be..e3a0c28028 100644 --- a/tests/data/SPECS/scriptfile.spec +++ b/tests/data/SPECS/scriptfile.spec @@ -10,7 +10,8 @@ BuildArch: noarch %build -for s in pre pretrans post posttrans preun postun verifyscript \ +for s in verifyscript \ + pre pretrans post posttrans preun preuntrans postun postuntrans \ triggerprein triggerin triggerun triggerpostun \ filetriggerin filetriggerun transfiletriggerin transfiletriggerun; do echo ${s} > ${s}.sh @@ -26,8 +27,12 @@ done %preun -f preun.sh +%preuntrans -f preuntrans.sh + %postun -f postun.sh +%postuntrans -f postuntrans.sh + %verifyscript -f verifyscript.sh %triggerprein -f triggerprein.sh -- %{name} diff --git a/tests/data/SPECS/scripts.spec b/tests/data/SPECS/scripts.spec index 581a56f5c5..09f4539987 100644 --- a/tests/data/SPECS/scripts.spec +++ b/tests/data/SPECS/scripts.spec @@ -15,6 +15,9 @@ BuildArch: noarch %pretrans echo %{name}-%{version}-%{release} PRETRANS $* +%preuntrans +echo %{name}-%{version}-%{release} PREUNTRANS $* + %pre echo %{name}-%{version}-%{release} PRE $* @@ -30,6 +33,9 @@ echo %{name}-%{version}-%{release} POSTUN $* %posttrans echo %{name}-%{version}-%{release} POSTTRANS $* +%postuntrans +echo %{name}-%{version}-%{release} POSTUNTRANS $* + %verifyscript echo %{name}-%{version}-%{release} VERIFY $* diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index 9fde7a1f9c..70cb0a5e6b 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -319,6 +319,12 @@ postun posttrans scriptlet (using /bin/sh): posttrans +preuntrans scriptlet (using /bin/sh): +preuntrans + +postuntrans scriptlet (using /bin/sh): +postuntrans + verify scriptlet (using /bin/sh): verifyscript diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at index 755ebce1b6..ab38d7860f 100644 --- a/tests/rpmgeneral.at +++ b/tests/rpmgeneral.at @@ -227,6 +227,9 @@ POSTTRANSPROG POSTUN POSTUNFLAGS POSTUNPROG +POSTUNTRANS +POSTUNTRANSFLAGS +POSTUNTRANSPROG PREFIXES PREIN PREINFLAGS @@ -237,6 +240,9 @@ PRETRANSPROG PREUN PREUNFLAGS PREUNPROG +PREUNTRANS +PREUNTRANSFLAGS +PREUNTRANSPROG PROVIDEFLAGS PROVIDENAME PROVIDENEVRS diff --git a/tests/rpmscript.at b/tests/rpmscript.at index 46a6207518..8382f8dcbd 100644 --- a/tests/rpmscript.at +++ b/tests/rpmscript.at @@ -36,6 +36,9 @@ runroot rpm -q ${pkgname} 2>&1 echo PREUNFAIL runroot rpm -e --define "exitpreun 1" ${pkgname} 2>&1; echo $? runroot rpm -q ${pkgname} 2>&1 +echo PREUNTRANSFAIL +runroot rpm -e --define "exitpreuntrans 1" ${pkgname} 2>&1; echo $? +runroot rpm -q ${pkgname} 2>&1 echo PREUN runroot rpm -e --define "exitpreun 0" ${pkgname} 2>&1; echo $? runroot rpm -q ${pkgname} 2>&1 @@ -62,11 +65,21 @@ runroot rpm -U ${pkgfile1} 2>&1 runroot rpm -U --define "exitpostun 1" ${pkgfile2} 2>&1; echo $? runroot rpm -q ${pkgname} 2>&1 runroot rpm -e ${pkgname} 2>&1 +echo POSTUNTRANSFAIL +runroot rpm -U ${pkgfile1} 2>&1 +runroot rpm -U --define "exitpostuntrans 1" ${pkgfile2} 2>&1; echo $? +runroot rpm -q ${pkgname} 2>&1 +runroot rpm -e ${pkgname} 2>&1 echo POSTUN runroot rpm -U ${pkgfile1} 2>&1 runroot rpm -U --define "exitpostun 0" ${pkgfile2} 2>&1; echo $? runroot rpm -q ${pkgname} 2>&1 runroot rpm -e ${pkgname} 2>&1 +echo POSTUNTRANS +runroot rpm -U ${pkgfile1} 2>&1 +runroot rpm -U --define "exitpostuntrans 0" ${pkgfile2} 2>&1; echo $? +runroot rpm -q ${pkgname} 2>&1 +runroot rpm -e ${pkgname} 2>&1 exit 0 ], @@ -92,6 +105,11 @@ error: %preun(scriptfail-1.0-1.noarch) scriptlet failed, exit status 1 error: scriptfail-1.0-1.noarch: erase failed 1 scriptfail-1.0-1.noarch +PREUNTRANSFAIL +error: %preuntrans(scriptfail-1.0-1.noarch) scriptlet failed, exit status 1 +error: scriptfail-1.0-1.noarch: erase skipped +1 +scriptfail-1.0-1.noarch PREUN 0 package scriptfail is not installed @@ -113,9 +131,16 @@ POSTUNFAIL warning: %postun(scriptfail-1.0-1.noarch) scriptlet failed, exit status 1 0 scriptfail-2.0-1.noarch +POSTUNTRANSFAIL +warning: %postuntrans(scriptfail-1.0-1.noarch) scriptlet failed, exit status 1 +0 +scriptfail-2.0-1.noarch POSTUN 0 scriptfail-2.0-1.noarch +POSTUNTRANS +0 +scriptfail-2.0-1.noarch ], []) AT_CLEANUP @@ -145,14 +170,18 @@ scripts-1.0-1 PRE 1 scripts-1.0-1 POST 1 scripts-1.0-1 POSTTRANS 1 scripts-1.0-2 PRETRANS 2 +scripts-1.0-1 PREUNTRANS 1 scripts-1.0-2 PRE 2 scripts-1.0-2 POST 2 scripts-1.0-1 PREUN 1 scripts-1.0-1 POSTUN 1 scripts-1.0-2 POSTTRANS 2 +scripts-1.0-1 POSTUNTRANS 1 scripts-1.0-2 VERIFY 1 +scripts-1.0-2 PREUNTRANS 0 scripts-1.0-2 PREUN 0 scripts-1.0-2 POSTUN 0 +scripts-1.0-2 POSTUNTRANS 0 ], []) AT_CLEANUP @@ -191,6 +220,7 @@ triggers-1.0-1 TRIGGERIN 1 1 scripts-1.0-1 POSTTRANS 1 SCRIPTS 2 scripts-1.0-2 PRETRANS 2 +scripts-1.0-1 PREUNTRANS 1 triggers-1.0-1 TRIGGERPREIN 1 1 scripts-1.0-2 PRE 2 scripts-1.0-2 POST 2 @@ -200,15 +230,18 @@ scripts-1.0-1 PREUN 1 scripts-1.0-1 POSTUN 1 triggers-1.0-1 TRIGGERPOSTUN 1 1 scripts-1.0-2 POSTTRANS 2 +scripts-1.0-1 POSTUNTRANS 1 TRIGGERS 2 triggers-1.0-2 TRIGGERPREIN 1 1 triggers-1.0-2 TRIGGERIN 2 1 triggers-1.0-1 TRIGGERUN 1 1 ERASE +scripts-1.0-2 PREUNTRANS 0 triggers-1.0-2 TRIGGERUN 1 0 scripts-1.0-2 PREUN 0 scripts-1.0-2 POSTUN 0 triggers-1.0-2 TRIGGERPOSTUN 1 0 +scripts-1.0-2 POSTUNTRANS 0 ], []) AT_CLEANUP