Skip to content

Commit

Permalink
Add support for %preuntrans and %postuntrans scriptlets
Browse files Browse the repository at this point in the history
These are obviously the long lost uninstall-time counterparts of
%pretrans and %posttrans.

%preuntrans is easy but %postuntrans is the reason this hasn't been
implemented so far: by the time it's supposed to execute, the header will
be gone. Work around this by allowing the rpmte to hold on to its header
if it has a %postuntrans scriptlet.

Cheapskate on transaction flags and reuse pre/posttrans flags for these
uninstall counterparts too, adding separate flags and disablers just
doesn't seem worth it, especially as we're quite short of free bits.

Fixes: rpm-software-management#2119
  • Loading branch information
pmatilai authored and ffesti committed Sep 26, 2022
1 parent 9478961 commit db46bd8
Show file tree
Hide file tree
Showing 29 changed files with 234 additions and 29 deletions.
2 changes: 2 additions & 0 deletions build/pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions build/parsePreamble.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
};

Expand Down
20 changes: 20 additions & 0 deletions build/parseScript.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions build/parseSpec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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")},
Expand Down Expand Up @@ -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:
Expand Down
6 changes: 5 additions & 1 deletion build/rpmbuild_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;


Expand Down
6 changes: 6 additions & 0 deletions build/rpmfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
7 changes: 4 additions & 3 deletions docs/man/rpm.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**

Expand Down
14 changes: 13 additions & 1 deletion docs/manual/tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions docs/manual/triggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ package upgrade:

```
all-%pretrans
all-%preuntrans
...
any-%triggerprein (%triggerprein from other packages set off by new install)
new-%triggerprein
Expand All @@ -165,4 +166,5 @@ package upgrade:
install)
...
all-%posttrans
all-%postuntrans
```
10 changes: 7 additions & 3 deletions include/rpm/rpmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -74,6 +76,8 @@ typedef rpmFlags rpmsenseFlags;
RPMSENSE_KEYRING | \
RPMSENSE_PRETRANS | \
RPMSENSE_POSTTRANS | \
RPMSENSE_PREUNTRANS | \
RPMSENSE_POSTUNTRANS | \
RPMSENSE_PREREQ | \
RPMSENSE_META | \
RPMSENSE_MISSINGOK)
Expand All @@ -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)

Expand Down
6 changes: 6 additions & 0 deletions include/rpm/rpmtag.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions include/rpm/rpmts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 \
Expand Down
8 changes: 4 additions & 4 deletions lib/depends.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand 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++)
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions lib/formats.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions lib/poptI.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
14 changes: 14 additions & 0 deletions lib/psm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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";
}
}
Expand All @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions lib/rpmscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, },
Expand Down
2 changes: 2 additions & 0 deletions lib/rpmscript.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
Expand Down
Loading

0 comments on commit db46bd8

Please sign in to comment.