summaryrefslogtreecommitdiff
path: root/lib/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/transaction.c')
-rw-r--r--lib/transaction.c579
1 files changed, 318 insertions, 261 deletions
diff --git a/lib/transaction.c b/lib/transaction.c
index fa17d34b7..6af1d1662 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -4,6 +4,9 @@
#include "system.h"
+#include <inttypes.h>
+#include <libgen.h>
+
#include <rpm/rpmlib.h> /* rpmMachineScore, rpmReadPackageFile */
#include <rpm/rpmmacro.h> /* XXX for rpmExpand */
#include <rpm/rpmlog.h>
@@ -11,6 +14,7 @@
#include <rpm/rpmds.h>
#include <rpm/rpmfileutil.h>
#include <rpm/rpmstring.h>
+#include <rpm/rpmsq.h>
#include "lib/fprint.h"
#include "lib/misc.h"
@@ -21,6 +25,7 @@
#include "lib/rpmte_internal.h" /* only internal apis */
#include "lib/rpmts_internal.h"
#include "rpmio/rpmhook.h"
+#include "lib/rpmtriggers.h"
#include "lib/rpmplugins.h"
@@ -63,6 +68,45 @@ struct diskspaceInfo_s {
#define adj_fs_blocks(_nb) (((_nb) * 21) / 20)
#define BLOCK_ROUND(size, block) (((size) + (block) - 1) / (block))
+static char *getMntPoint(const char *dirName, dev_t dev)
+{
+ char mntPoint[PATH_MAX];
+ char *resolved_path = realpath(dirName, mntPoint);
+ char *end = NULL;
+ struct stat sb;
+ char *res = NULL;
+
+ if (!resolved_path) {
+ strncpy(mntPoint, dirName, PATH_MAX);
+ mntPoint[PATH_MAX-1] = '\0';
+ }
+
+ while (end != mntPoint) {
+ end = strrchr(mntPoint, '/');
+ if (end == mntPoint) { /* reached "/" */
+ stat("/", &sb);
+ if (dev != sb.st_dev) {
+ res = xstrdup(mntPoint);
+ } else {
+ res = xstrdup("/");
+ }
+ break;
+ } else if (end) {
+ *end = '\0';
+ } else { /* dirName doesn't start with / - should not happen */
+ res = xstrdup(dirName);
+ break;
+ }
+ stat(mntPoint, &sb);
+ if (dev != sb.st_dev) {
+ *end = '/';
+ res = xstrdup(mntPoint);
+ break;
+ }
+ }
+ return res;
+}
+
static int rpmtsInitDSI(const rpmts ts)
{
if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_DISKSPACE)
@@ -77,8 +121,6 @@ static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
{
rpmDiskSpaceInfo dsi;
struct stat sb;
- char * resolved_path;
- char mntPoint[PATH_MAX];
int rc;
#if STATFS_IN_SYS_STATVFS
@@ -119,11 +161,7 @@ static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
dsi->bneeded = 0;
dsi->ineeded = 0;
#ifdef STATFS_HAS_F_BAVAIL
-# ifdef ST_RDONLY
dsi->bavail = (sfb.f_flag & ST_RDONLY) ? 0 : sfb.f_bavail;
-# else
- dsi->bavail = sfb.f_bavail;
-# endif
#else
/* FIXME: the statfs struct doesn't have a member to tell how many blocks are
* available for non-superusers. f_blocks - f_bfree is probably too big, but
@@ -137,34 +175,16 @@ static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
? sfb.f_ffree : -1;
/* Find mount point belonging to this device number */
- resolved_path = realpath(dirName, mntPoint);
- if (!resolved_path) {
- strncpy(mntPoint, dirName, PATH_MAX);
- mntPoint[PATH_MAX-1] = '\0';
- }
- char * end = NULL;
- while (end != mntPoint) {
- end = strrchr(mntPoint, '/');
- if (end == mntPoint) { /* reached "/" */
- stat("/", &sb);
- if (dsi->dev != sb.st_dev) {
- dsi->mntPoint = xstrdup(mntPoint);
- } else {
- dsi->mntPoint = xstrdup("/");
- }
- break;
- } else if (end) {
- *end = '\0';
- } else { /* dirName doesn't start with / - should not happen */
- dsi->mntPoint = xstrdup(dirName);
- break;
- }
- stat(mntPoint, &sb);
- if (dsi->dev != sb.st_dev) {
- *end = '/';
- dsi->mntPoint = xstrdup(mntPoint);
- break;
- }
+ dsi->mntPoint = getMntPoint(dirName, dsi->dev);
+
+ /* normalize block size to 4096 bytes if it is too big. */
+ if (dsi->bsize > 4096) {
+ uint64_t old_size = dsi->bavail * dsi->bsize;
+ rpmlog(RPMLOG_DEBUG,
+ "dubious blocksize % " PRId64 " on %s, normalizing to 4096\n",
+ dsi->bsize, dsi->mntPoint);
+ dsi->bsize = 4096; /* Assume 4k block size */
+ dsi->bavail = old_size / dsi->bsize;
}
rpmlog(RPMLOG_DEBUG,
@@ -291,17 +311,21 @@ static uint64_t countFiles(rpmts ts)
uint64_t fc = 0;
rpmtsi pi = rpmtsiInit(ts);
rpmte p;
- while ((p = rpmtsiNext(pi, 0)) != NULL)
- fc += rpmfiFC(rpmteFI(p));
+ rpmfiles files;
+ while ((p = rpmtsiNext(pi, 0)) != NULL) {
+ files = rpmteFiles(p);
+ fc += rpmfilesFC(files);
+ rpmfilesFree(files);
+ }
rpmtsiFree(pi);
return fc;
}
-static int handleRemovalConflict(rpmfi fi, int fx, rpmfi ofi, int ofx)
+static int handleRemovalConflict(rpmfiles fi, int fx, rpmfiles ofi, int ofx)
{
int rConflicts = 0; /* Removed files don't conflict, normally */
- rpmFileTypes ft = rpmfiWhatis(rpmfiFModeIndex(fi, fx));
- rpmFileTypes oft = rpmfiWhatis(rpmfiFModeIndex(ofi, ofx));
+ rpmFileTypes ft = rpmfiWhatis(rpmfilesFMode(fi, fx));
+ rpmFileTypes oft = rpmfiWhatis(rpmfilesFMode(ofi, ofx));
struct stat sb;
char *fn = NULL;
@@ -312,7 +336,7 @@ static int handleRemovalConflict(rpmfi fi, int fx, rpmfi ofi, int ofx)
} else if (oft == LINK) {
/* We can't correctly handle directory symlink changing to directory */
if (ft == XDIR) {
- fn = rpmfiFNIndex(fi, fx);
+ fn = rpmfilesFN(fi, fx);
if (stat(fn, &sb) == 0 && S_ISDIR(sb.st_mode))
rConflicts = 1;
}
@@ -324,7 +348,7 @@ static int handleRemovalConflict(rpmfi fi, int fx, rpmfi ofi, int ofx)
*/
if (rConflicts) {
if (fn == NULL)
- fn = rpmfiFNIndex(fi, fx);
+ fn = rpmfilesFN(fi, fx);
if (lstat(fn, &sb) || rpmfiWhatis(sb.st_mode) == ft)
rConflicts = 0;
}
@@ -342,15 +366,15 @@ static int handleRemovalConflict(rpmfi fi, int fx, rpmfi ofi, int ofx)
* unnecessary with careful packaging.
*/
static int handleColorConflict(rpmts ts,
- rpmfs fs, rpmfi fi, int fx,
- rpmfs ofs, rpmfi ofi, int ofx)
+ rpmfs fs, rpmfiles fi, int fx,
+ rpmfs ofs, rpmfiles ofi, int ofx)
{
int rConflicts = 1;
rpm_color_t tscolor = rpmtsColor(ts);
if (tscolor != 0) {
- rpm_color_t fcolor = rpmfiFColorIndex(fi, fx) & tscolor;
- rpm_color_t ofcolor = rpmfiFColorIndex(ofi, ofx) & tscolor;
+ rpm_color_t fcolor = rpmfilesFColor(fi, fx) & tscolor;
+ rpm_color_t ofcolor = rpmfilesFColor(ofi, ofx) & tscolor;
if (fcolor != 0 && ofcolor != 0 && fcolor != ofcolor) {
rpm_color_t prefcolor = rpmtsPrefColor(ts);
@@ -377,22 +401,24 @@ static int handleColorConflict(rpmts ts,
* @param ts transaction set
* @param p current transaction element
* @param fi file info set
- * @param shared shared file info
- * @param sharedCount no. of shared elements
- * @param reportConflicts
+ * @param fx file index
+ * @param otherHeader header containing the matching file
+ * @param otherFi matching file info set
+ * @param ofx matching file index
+ * @param beingRemoved file being removed (installed otherwise)
*/
/* XXX only ts->{probs,rpmdb} modified */
-static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, int fx,
- Header otherHeader, rpmfi otherFi, int ofx,
+static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx,
+ Header otherHeader, rpmfiles otherFi, int ofx,
int beingRemoved)
{
rpmfs fs = rpmteGetFileStates(p);
- int isCfgFile = ((rpmfiFFlagsIndex(otherFi, ofx) | rpmfiFFlagsIndex(fi, fx)) & RPMFILE_CONFIG);
+ int isCfgFile = ((rpmfilesFFlags(otherFi, ofx) | rpmfilesFFlags(fi, fx)) & RPMFILE_CONFIG);
if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
return;
- if (rpmfiCompareIndex(otherFi, ofx, fi, fx)) {
+ if (rpmfilesCompare(otherFi, ofx, fi, fx)) {
int rConflicts = 1;
char rState = RPMFILE_STATE_REPLACED;
@@ -421,20 +447,22 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, int fx,
rState = RPMFILE_STATE_WRONGCOLOR;
}
+
if (rConflicts) {
- char *path = rpmfiFNIndex(fi, fx);
+ char *path = rpmfilesFN(fi, fx);
/* Call file conflict hook for all plugins */
rpmpluginsCallFileConflict(ts->plugins, ts, path, otherHeader, otherFi, rConflicts);
}
-
+
/* Somebody used The Force, lets shut up... */
if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES) {
rConflicts = 0;
}
+
if (rConflicts) {
char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA);
- char *fn = rpmfiFNIndex(fi, fx);
+ char *fn = rpmfilesFN(fi, fx);
rpmteAddProblem(p, RPMPROB_FILE_CONFLICT, altNEVR, fn,
headerGetInstance(otherHeader));
free(fn);
@@ -449,34 +477,42 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, int fx,
}
}
- /* Determine config file dispostion, skipping missing files (if any). */
+ /* Determine config file disposition, skipping missing files (if any). */
if (isCfgFile) {
int skipMissing = ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1);
rpmFileAction action;
- action = rpmfiDecideFateIndex(otherFi, ofx, fi, fx, skipMissing);
+ action = rpmfilesDecideFate(otherFi, ofx, fi, fx, skipMissing);
rpmfsSetAction(fs, fx, action);
}
- rpmfiSetFReplacedSizeIndex(fi, fx, rpmfiFSizeIndex(otherFi, ofx));
+
+ /* Skip already existing files - if 'minimize_writes' is set. */
+ if ((!isCfgFile) && (rpmfsGetAction(fs, fx) == FA_UNKNOWN) && ts->min_writes) {
+ if (rpmfileContentsEqual(otherFi, ofx, fi, fx)) {
+ rpmfsSetAction(fs, fx, FA_TOUCH);
+ }
+ }
+
+ rpmfilesSetFReplacedSize(fi, fx, rpmfilesFSize(otherFi, ofx));
}
/**
* Update disk space needs on each partition for this package's files.
*/
/* XXX only ts->{probs,di} modified */
-static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi fi)
+static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfiles fi)
{
rpm_loff_t fixupSize = 0;
int i, j;
rpmfs fs = rpmteGetFileStates(p);
rpmfs otherFs;
- rpm_count_t fc = rpmfiFC(fi);
+ rpm_count_t fc = rpmfilesFC(fi);
int reportConflicts = !(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACENEWFILES);
- fingerPrint * fpList = rpmfiFps(fi);
+ fingerPrint * fpList = rpmfilesFps(fi);
for (i = 0; i < fc; i++) {
struct fingerPrint_s * fiFps;
int otherPkgNum, otherFileNum;
- rpmfi otherFi;
+ rpmfiles otherFi;
rpmte otherTe;
rpmfileAttrs FFlags;
struct rpmffi_s * recs;
@@ -485,7 +521,7 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
if (XFA_SKIPPING(rpmfsGetAction(fs, i)))
continue;
- FFlags = rpmfiFFlagsIndex(fi, i);
+ FFlags = rpmfilesFFlags(fi, i);
fixupSize = 0;
@@ -513,7 +549,7 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
* that were just installed.
* If both this and the other package are being removed, then each
* file removal from preceding packages needs to be skipped so that
- * the file removal occurs only on the last occurence of an overlapped
+ * the file removal occurs only on the last occurrence of an overlapped
* file in the transaction set.
*
*/
@@ -535,7 +571,6 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
for (otherPkgNum = j - 1; otherPkgNum >= 0; otherPkgNum--) {
otherTe = recs[otherPkgNum].p;
- otherFi = rpmteFI(otherTe);
otherFileNum = recs[otherPkgNum].fileno;
otherFs = rpmteGetFileStates(otherTe);
@@ -544,8 +579,10 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
continue;
/* XXX Happens iff fingerprint for incomplete package install. */
- if (rpmfsGetAction(otherFs, otherFileNum) != FA_UNKNOWN)
+ if (rpmfsGetAction(otherFs, otherFileNum) != FA_UNKNOWN) {
+ otherFi = rpmteFiles(otherTe);
break;
+ }
}
switch (rpmteType(p)) {
@@ -555,7 +592,7 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
rpmFileAction action;
if (rpmfsGetAction(fs, i) != FA_UNKNOWN)
break;
- if (rpmfiConfigConflictIndex(fi, i)) {
+ if (rpmfilesConfigConflict(fi, i)) {
/* Here is a non-overlapped pre-existing config file. */
action = (FFlags & RPMFILE_NOREPLACE) ?
FA_ALTNAME : FA_BACKUP;
@@ -568,7 +605,7 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
assert(otherFi != NULL);
/* Mark added overlapped non-identical files as a conflict. */
- if (rpmfiCompareIndex(otherFi, otherFileNum, fi, i)) {
+ if (rpmfilesCompare(otherFi, otherFileNum, fi, i)) {
int rConflicts;
/* If enabled, resolve colored conflicts to preferred type */
@@ -576,7 +613,7 @@ assert(otherFi != NULL);
otherFs, otherFi, otherFileNum);
if (rConflicts && reportConflicts) {
- char *fn = rpmfiFNIndex(fi, i);
+ char *fn = rpmfilesFN(fi, i);
rpmteAddProblem(p, RPMPROB_NEW_FILE_CONFLICT,
rpmteNEVRA(otherTe), fn, 0);
free(fn);
@@ -587,10 +624,13 @@ assert(otherFi != NULL);
if (oaction != FA_UNKNOWN && !XFA_SKIPPING(oaction)) {
rpmfileAttrs oflags;
/* ...but ghosts aren't really created so... */
- oflags = rpmfiFFlagsIndex(otherFi, otherFileNum);
+ oflags = rpmfilesFFlags(otherFi, otherFileNum);
if (!(oflags & RPMFILE_GHOST)) {
rpmfsSetAction(fs, i, FA_SKIP);
}
+ /* if the other file is color skipped then skip this file too */
+ } else if (oaction == FA_SKIPCOLOR) {
+ rpmfsSetAction(fs, i, FA_SKIPCOLOR);
}
}
@@ -599,9 +639,9 @@ assert(otherFi != NULL);
break;
/* Try to get the disk accounting correct even if a conflict. */
- fixupSize = rpmfiFSizeIndex(otherFi, otherFileNum);
+ fixupSize = rpmfilesFSize(otherFi, otherFileNum);
- if (rpmfiConfigConflictIndex(fi, i)) {
+ if (rpmfilesConfigConflict(fi, i)) {
/* Here is an overlapped pre-existing config file. */
rpmFileAction action;
action = (FFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SKIP;
@@ -627,12 +667,14 @@ assert(otherFi != NULL);
}
if (XFA_SKIPPING(rpmfsGetAction(fs, i)))
break;
- if (rpmfiFStateIndex(fi, i) != RPMFILE_STATE_NORMAL)
+ if (rpmfilesFState(fi, i) != RPMFILE_STATE_NORMAL) {
+ rpmfsSetAction(fs, i, FA_SKIP);
break;
+ }
/* Pre-existing modified config files need to be saved. */
- if (rpmfiConfigConflictIndex(fi, i)) {
- rpmfsSetAction(fs, i, FA_BACKUP);
+ if (rpmfilesConfigConflict(fi, i)) {
+ rpmfsSetAction(fs, i, FA_SAVE);
break;
}
@@ -640,10 +682,11 @@ assert(otherFi != NULL);
rpmfsSetAction(fs, i, FA_ERASE);
break;
}
+ rpmfilesFree(otherFi);
/* Update disk space info for a file. */
rpmtsUpdateDSI(ts, fpEntryDev(fpc, fiFps), fpEntryDir(fpc, fiFps),
- rpmfiFSizeIndex(fi, i), rpmfiFReplacedSizeIndex(fi, i),
+ rpmfilesFSize(fi, i), rpmfilesFReplacedSize(fi, i),
fixupSize, rpmfsGetAction(fs, i));
}
@@ -654,7 +697,6 @@ assert(otherFi != NULL);
* @param tspool transaction string pool
* @param p current transaction element
* @param h installed header
- * @param ps problem set
*/
static void ensureOlder(rpmstrPool tspool, const rpmte p, const Header h)
{
@@ -677,9 +719,9 @@ static void ensureOlder(rpmstrPool tspool, const rpmte p, const Header h)
* netshardpath and though should be excluded.
* @param ts transaction set
* @param fi file info set
- * @returns pointer to matching path or NULL
+ * @returns 1 if path is net shared path, otherwise 0
*/
-static char ** matchNetsharedpath(const rpmts ts, rpmfi fi)
+static int matchNetsharedpath(const rpmts ts, rpmfi fi)
{
char ** nsp;
const char * dn, * bn;
@@ -717,29 +759,25 @@ static char ** matchNetsharedpath(const rpmts ts, rpmfi fi)
break;
}
- return nsp;
+ return (nsp != NULL && *nsp != NULL);
}
-static void skipEraseFiles(const rpmts ts, rpmte p)
+static void skipEraseFiles(const rpmts ts, rpmfiles files, rpmfs fs)
{
- rpmfi fi = rpmteFI(p);
- rpmfs fs = rpmteGetFileStates(p);
int i;
- char ** nsp;
/*
* Skip net shared paths.
* Net shared paths are not relative to the current root (though
* they do need to take package relocations into account).
*/
if (ts->netsharedPaths) {
- fi = rpmfiInit(fi, 0);
+ rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);
while ((i = rpmfiNext(fi)) >= 0)
{
- nsp = matchNetsharedpath(ts, fi);
- if (nsp && *nsp) {
+ if (matchNetsharedpath(ts, fi))
rpmfsSetAction(fs, i, FA_SKIPNETSHARED);
- }
}
+ rpmfiFree(fi);
}
}
@@ -747,9 +785,10 @@ static void skipEraseFiles(const rpmts ts, rpmte p)
/**
* Skip any files that do not match install policies.
* @param ts transaction set
- * @param fi file info set
+ * @param files file info set
+ * @param fs file states
*/
-static void skipInstallFiles(const rpmts ts, rpmte p)
+static void skipInstallFiles(const rpmts ts, rpmfiles files, rpmfs fs)
{
rpm_color_t tscolor = rpmtsColor(ts);
rpm_color_t FColor;
@@ -759,8 +798,7 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
char * dff;
int dc;
int i, j, ix;
- rpmfi fi = rpmteFI(p);
- rpmfs fs = rpmteGetFileStates(p);
+ rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);
if (!noDocs)
noDocs = rpmExpandNumeric("%{_excludedocs}");
@@ -772,13 +810,13 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
fi = rpmfiInit(fi, 0);
while ((i = rpmfiNext(fi)) >= 0) {
- char ** nsp;
const char *flangs;
ix = rpmfiDX(fi);
drc[ix]++;
/* Don't bother with skipped files */
+ /* XXX FIXME: --excludepath on %license should not be permitted */
if (XFA_SKIPPING(rpmfsGetAction(fs, i))) {
drc[ix]--; dff[ix] = 1;
continue;
@@ -798,8 +836,7 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
* they do need to take package relocations into account).
*/
if (ts->netsharedPaths) {
- nsp = matchNetsharedpath(ts, fi);
- if (nsp && *nsp) {
+ if (matchNetsharedpath(ts, fi)) {
drc[ix]--; dff[ix] = 1;
rpmfsSetAction(fs, i, FA_SKIPNETSHARED);
continue;
@@ -807,6 +844,14 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
}
/*
+ * In general, excluding license files is not permitted. In case
+ * of SKIPNETSHARED and SKIPCOLOR the file is expected to be
+ * there via other means however so that is ok.
+ */
+ if (rpmfiFFlags(fi) & RPMFILE_LICENSE)
+ continue;
+
+ /*
* Skip i18n language specific files.
*/
flangs = (ts->installLangs != NULL) ? rpmfiFLangs(fi) : NULL;
@@ -851,7 +896,8 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
}
/* Skip (now empty) directories that had skipped files. */
- for (j = 0; j < dc; j++) {
+ /* Iterate over dirs in reversed order to solve subdirs at first */
+ for (j = dc - 1; j >= 0; j--) {
const char * dn, * bn;
size_t dnlen, bnlen;
@@ -859,7 +905,7 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
if (!dff[j]) continue; /* dir was not emptied here. */
/* Find parent directory and basename. */
- dn = rpmfiDNIndex(fi, j); dnlen = strlen(dn) - 1;
+ dn = rpmfilesDN(files, j); dnlen = strlen(dn) - 1;
bn = dn + dnlen; bnlen = 0;
while (bn > dn && bn[-1] != '/') {
bnlen++;
@@ -892,12 +938,18 @@ static void skipInstallFiles(const rpmts ts, rpmte p)
continue;
rpmlog(RPMLOG_DEBUG, "excluding directory %s\n", dn);
rpmfsSetAction(fs, i, FA_SKIPNSTATE);
+ ix = rpmfiDX(fi);
+ /* Decrease count of files for parent directory */
+ drc[ix]--;
+ /* Mark directory because something was removed from them */
+ dff[ix] = 1;
break;
}
}
free(drc);
free(dff);
+ rpmfiFree(fi);
}
#undef HASHTYPE
@@ -932,6 +984,7 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts, uint64_t fileCount)
tsMembers tsmem = rpmtsMembers(ts);
rpmstrPool tspool = rpmtsPool(ts);
rpmtsi pi; rpmte p;
+ rpmfiles files;
rpmfi fi;
rpmdbMatchIterator mi;
int oc = 0;
@@ -945,12 +998,13 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts, uint64_t fileCount)
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, 0)) != NULL) {
- (void) rpmdbCheckSignals();
+ (void) rpmsqPoll();
rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_PROGRESS, oc++, tsmem->orderCount);
/* Gather all installed headers with matching basename's. */
- fi = rpmfiInit(rpmteFI(p), 0);
+ files = rpmteFiles(p);
+ fi = rpmfilesIter(files, RPMFI_ITER_FWD);
while (rpmfiNext(fi) >= 0) {
size_t keylen;
@@ -965,7 +1019,9 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts, uint64_t fileCount)
keylen++; /* XXX "/" fixup. */
rpmdbExtendIterator(mi, baseName, keylen);
rpmStringSetAddEntry(baseNames, baseNameId);
- }
+ }
+ rpmfiFree(fi);
+ rpmfilesFree(files);
}
rpmtsiFree(pi);
rpmStringSetFree(baseNames);
@@ -986,7 +1042,7 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
{
tsMembers tsmem = rpmtsMembers(ts);
rpmte p;
- rpmfi fi;
+ rpmfiles fi;
rpmfs fs;
int j;
unsigned int fileNum;
@@ -1015,15 +1071,15 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
fingerPrint *fpp = NULL;
unsigned int installedPkg;
int beingRemoved = 0;
- rpmfi otherFi = NULL;
+ rpmfiles otherFi = NULL;
rpmte *removedPkg = NULL;
/* Is this package being removed? */
installedPkg = rpmdbGetIteratorOffset(mi);
- if (removedHashGetEntry(tsmem->removedPackages, installedPkg,
+ if (packageHashGetEntry(tsmem->removedPackages, installedPkg,
&removedPkg, NULL, NULL)) {
beingRemoved = 1;
- otherFi = rpmfiLink(rpmteFI(removedPkg[0]));
+ otherFi = rpmteFiles(removedPkg[0]);
}
h = headerLink(h);
@@ -1057,7 +1113,7 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
fpLookup(fpc, dirName, baseName, &fpp);
fpIx = 0;
} else {
- fpp = rpmfiFps(otherFi);
+ fpp = rpmfilesFps(otherFi);
fpIx = fileNum;
}
@@ -1066,7 +1122,7 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
for (j = 0; j < numRecs; j++) {
p = recs[j].p;
- fi = rpmteFI(p);
+ fi = rpmteFiles(p);
fs = rpmteGetFileStates(p);
/* Determine the fate of each file. */
@@ -1074,7 +1130,7 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
case TR_ADDED:
if (!otherFi) {
/* XXX What to do if this fails? */
- otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER);
+ otherFi = rpmfilesNew(NULL, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER);
}
handleInstInstalledFile(ts, p, fi, recs[j].fileno,
h, otherFi, fileNum, beingRemoved);
@@ -1086,13 +1142,14 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
}
break;
}
+ rpmfilesFree(fi);
}
newheader = rpmdbNextIterator(mi);
} while (newheader==h);
- otherFi = rpmfiFree(otherFi);
+ otherFi = rpmfilesFree(otherFi);
if (!beingRemoved) {
rpmtdFreeData(&ostates);
rpmtdFreeData(&bnames);
@@ -1146,7 +1203,7 @@ static rpmps checkProblems(rpmts ts)
if (!(probFilter & RPMPROB_FILTER_REPLACEPKG)) {
Header h;
rpmdbMatchIterator mi;
- mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0);
+ mi = rpmtsPrunedIterator(ts, RPMDBI_NAME, rpmteN(p), 1);
rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP, rpmteE(p));
rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP, rpmteV(p));
rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP, rpmteR(p));
@@ -1180,92 +1237,16 @@ static int runTransScripts(rpmts ts, pkgGoal goal)
int rc = 0;
rpmte p;
rpmtsi pi = rpmtsiInit(ts);
- while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
- rc += rpmteProcess(p, goal);
- }
- rpmtsiFree(pi);
- return rc;
-}
-
-static int rpmtsSetupCollections(rpmts ts)
-{
- /* seenCollectionsPost and TEs are basically a key-value pair. each item in
- * seenCollectionsPost is a collection that has been seen from any package,
- * and the associated index in the TEs is the last transaction element
- * where that collection was seen. */
- ARGV_t seenCollectionsPost = NULL;
- rpmte *TEs = NULL;
- int numSeenPost = 0;
-
- /* seenCollectionsPre is a list of collections that have been seen from
- * only removed packages */
- ARGV_t seenCollectionsPre = NULL;
- int numSeenPre = 0;
-
- ARGV_const_t collname;
- int installing = 1;
- int i;
-
- rpmte p;
- rpmtsi pi = rpmtsiInit(ts);
- while ((p = rpmtsiNext(pi, 0)) != NULL) {
- /* detect when we switch from installing to removing packages, and
- * update the lastInCollectionAdd lists */
- if (installing && rpmteType(p) == TR_REMOVED) {
- installing = 0;
- for (i = 0; i < numSeenPost; i++) {
- rpmteAddToLastInCollectionAdd(TEs[i], seenCollectionsPost[i]);
- }
- }
-
- rpmteSetupCollectionPlugins(p);
-
- for (collname = rpmteCollections(p); collname && *collname; collname++) {
- /* figure out if we've seen this collection in post before */
- for (i = 0; i < numSeenPost && strcmp(*collname, seenCollectionsPost[i]); i++) {
- }
- if (i < numSeenPost) {
- /* we've seen the collection, update the index */
- TEs[i] = p;
- } else {
- /* haven't seen the collection yet, add it */
- argvAdd(&seenCollectionsPost, *collname);
- TEs = xrealloc(TEs, sizeof(*TEs) * (numSeenPost + 1));
- TEs[numSeenPost] = p;
- numSeenPost++;
- }
+ rpmElementTypes types = TR_ADDED;
+ int i = 0;
+ if (goal == PKG_TRANSFILETRIGGERUN)
+ types = TR_REMOVED;
- /* figure out if we've seen this collection in pre remove before */
- if (installing == 0) {
- for (i = 0; i < numSeenPre && strcmp(*collname, seenCollectionsPre[i]); i++) {
- }
- if (i >= numSeenPre) {
- /* haven't seen this collection, add it */
- rpmteAddToFirstInCollectionRemove(p, *collname);
- argvAdd(&seenCollectionsPre, *collname);
- numSeenPre++;
- }
- }
- }
+ while ((p = rpmtsiNext(pi, types)) != NULL) {
+ rc += rpmteProcess(p, goal, i++);
}
rpmtsiFree(pi);
-
- /* we've looked at all the rpmte's, update the lastInCollectionAny lists */
- for (i = 0; i < numSeenPost; i++) {
- rpmteAddToLastInCollectionAny(TEs[i], seenCollectionsPost[i]);
- if (installing == 1) {
- /* lastInCollectionAdd is only updated above if packages were
- * removed. if nothing is removed in the transaction, we need to
- * update that list here */
- rpmteAddToLastInCollectionAdd(TEs[i], seenCollectionsPost[i]);
- }
- }
-
- argvFree(seenCollectionsPost);
- argvFree(seenCollectionsPre);
- _free(TEs);
-
- return 0;
+ return rc;
}
static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
@@ -1279,21 +1260,7 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));
if (rpmtsFlags(ts) & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_TEST))
- (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers | RPMTRANS_FLAG_NOCOLLECTIONS));
-
- /* if SELinux isn't enabled or it is a test run, don't bother... */
- if (!is_selinux_enabled() || (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
- rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
- }
-
- if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS) {
- rpmlog(RPMLOG_DEBUG, "Selinux disabled.\n");
- } else {
- if (rpmtsSELabelInit(ts, 1)) {
- rpmlog(RPMLOG_WARNING, "Failed to open SELinux handle.\n");
- rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
- }
- }
+ (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
/*
* Make sure the database is open RDWR for package install/erase.
@@ -1315,9 +1282,6 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
static int rpmtsFinish(rpmts ts)
{
- if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
- rpmtsSELabelFini(ts, 1);
- }
return rpmChrootSet(NULL);
}
@@ -1326,7 +1290,6 @@ static int rpmtsPrepare(rpmts ts)
tsMembers tsmem = rpmtsMembers(ts);
rpmtsi pi;
rpmte p;
- rpmfi fi;
int rc = 0;
uint64_t fileCount = countFiles(ts);
const char *dbhome = NULL;
@@ -1336,16 +1299,21 @@ static int rpmtsPrepare(rpmts ts)
rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount);
- /* Skip netshared paths, not our i18n files, and excluded docs */
+ /* Reset actions, set skip for netshared paths and excluded files */
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, 0)) != NULL) {
- if (rpmfiFC(rpmteFI(p)) == 0)
- continue;
- if (rpmteType(p) == TR_ADDED) {
- skipInstallFiles(ts, p);
- } else {
- skipEraseFiles(ts, p);
+ rpmfiles files = rpmteFiles(p);
+ if (rpmfilesFC(files) > 0) {
+ rpmfs fs = rpmteGetFileStates(p);
+ /* Ensure clean state, this could get called more than once. */
+ rpmfsResetActions(fs);
+ if (rpmteType(p) == TR_ADDED) {
+ skipInstallFiles(ts, files, fs);
+ } else {
+ skipEraseFiles(ts, files, fs);
+ }
}
+ rpmfilesFree(files);
}
rpmtsiFree(pi);
@@ -1368,13 +1336,14 @@ static int rpmtsPrepare(rpmts ts)
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, 0)) != NULL) {
- if ((fi = rpmteFI(p)) == NULL)
+ rpmfiles files = rpmteFiles(p);;
+ if (files == NULL)
continue; /* XXX can't happen */
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
/* check files in ts against each other and update disk space
needs on each partition for this package. */
- handleOverlappedFiles(ts, fpc, p, fi);
+ handleOverlappedFiles(ts, fpc, p, files);
/* Check added package has sufficient space on each partition used. */
if (rpmteType(p) == TR_ADDED) {
@@ -1391,6 +1360,7 @@ static int rpmtsPrepare(rpmts ts)
rpmtsCheckDSIProblems(ts, p);
}
(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
+ rpmfilesFree(files);
}
rpmtsiFree(pi);
rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, tsmem->orderCount);
@@ -1403,7 +1373,7 @@ static int rpmtsPrepare(rpmts ts)
if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))) {
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, 0)) != NULL) {
- rpmteSetFI(p, NULL);
+ rpmteCleanFiles(p);
}
rpmtsiFree(pi);
}
@@ -1421,6 +1391,7 @@ static int rpmtsProcess(rpmts ts)
{
rpmtsi pi; rpmte p;
int rc = 0;
+ int i = 0;
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, 0)) != NULL) {
@@ -1429,49 +1400,114 @@ static int rpmtsProcess(rpmts ts)
rpmlog(RPMLOG_DEBUG, "========== +++ %s %s-%s 0x%x\n",
rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
- if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
- rpmtsSELabelInit(ts, 0);
- }
-
- failed = rpmteProcess(p, rpmteType(p));
+ failed = rpmteProcess(p, rpmteType(p), i++);
if (failed) {
rpmlog(RPMLOG_ERR, "%s: %s %s\n", rpmteNEVRA(p),
rpmteTypeString(p), failed > 1 ? _("skipped") : _("failed"));
rc++;
}
- (void) rpmdbSync(rpmtsGetRdb(ts));
}
rpmtsiFree(pi);
return rc;
}
-static rpmRC rpmtsSetupTransactionPlugins(rpmts ts)
+rpmRC rpmtsSetupTransactionPlugins(rpmts ts)
{
rpmRC rc = RPMRC_OK;
- char *plugins = NULL, *plugin = NULL;
- const char *delims = ",";
-
- plugins = rpmExpand("%{?__transaction_plugins}", NULL);
- if (!plugins || rstreq(plugins, "")) {
- goto exit;
- }
+ ARGV_t files = NULL;
+ int nfiles = 0;
+ char *dsoPath = NULL;
- plugin = strtok(plugins, delims);
- while(plugin != NULL) {
- rpmlog(RPMLOG_DEBUG, "plugin is %s\n", plugin);
- if (!rpmpluginsPluginAdded(ts->plugins, (const char*)plugin)) {
- if (rpmpluginsAddPlugin(ts->plugins, "transaction",
- (const char*)plugin) == RPMRC_FAIL) {
- /* any configured plugin failing to load is a failure */
+ /*
+ * Assume allocated equals initialized. There are some oddball cases
+ * (verification of non-installed package) where this is not true
+ * currently but that's not a new issue.
+ */
+ if ((rpmtsFlags(ts) & RPMTRANS_FLAG_NOPLUGINS) || rpmPluginsGetCount(rpmtsPlugins(ts)) != 0)
+ return RPMRC_OK;
+
+ dsoPath = rpmExpand("%{__plugindir}/*.so", NULL);
+ if (rpmGlob(dsoPath, &nfiles, &files) == 0) {
+ rpmPlugins tsplugins = rpmtsPlugins(ts);
+ for (int i = 0; i < nfiles; i++) {
+ char *bn = basename(files[i]);
+ bn[strlen(bn)-strlen(".so")] = '\0';
+ if (rpmpluginsAddPlugin(tsplugins, "transaction", bn) == RPMRC_FAIL)
+ {
+ /* any configured plugin failing to load is a failure */
// temporally make the loading policy relaxed: no failures
+ //refer to commit id: 3959da1846227711d97c17495aa4779e653a1b3a
//rc = RPMRC_FAIL;
}
}
- plugin = strtok(NULL, delims);
+ files = argvFree(files);
}
+ free(dsoPath);
+
+ return rc;
+}
+/**
+ * Run a scriptlet with args.
+ *
+ * Run a script with an interpreter. If the interpreter is not specified,
+ * /bin/sh will be used. If the interpreter is /bin/sh, then the args from
+ * the header will be ignored, passing instead arg1 and arg2.
+ *
+ * @param ts transaction set
+ * @param te transaction element
+ * @param prefixes install prefixes
+ * @param script scriptlet from header
+ * @param arg1 no. instances of package installed after scriptlet exec
+ * (-1 is no arg)
+ * @param arg2 ditto, but for the target package
+ * @return 0 on success
+ */
+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;
+ int warn_only = (stag != RPMTAG_PREIN &&
+ stag != RPMTAG_PREUN &&
+ 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);
+
+ rpmswEnter(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), 0);
+ rc = rpmScriptRun(script, arg1, arg2, sfd,
+ prefixes, warn_only, rpmtsPlugins(ts));
+ rpmswExit(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), 0);
+
+ /* Map warn-only errors to "notfound" for script stop callback */
+ stoprc = (rc != RPMRC_OK && warn_only) ? RPMRC_NOTFOUND : rc;
+ rpmtsNotify(ts, te, RPMCALLBACK_SCRIPT_STOP, stag, stoprc);
+
+ /*
+ * Notify callback for all errors. "total" abused for warning/error,
+ * rc only reflects whether the condition prevented install/erase
+ * (which is only happens with %prein and %preun scriptlets) or not.
+ */
+ if (rc != RPMRC_OK) {
+ if (warn_only) {
+ rc = RPMRC_OK;
+ }
+ rpmtsNotify(ts, te, RPMCALLBACK_SCRIPT_ERROR, stag, rc);
+ }
+
+ if (te != xte)
+ rpmteFree(te);
-exit:
- free(plugins);
return rc;
}
@@ -1479,9 +1515,11 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
{
int rc = -1; /* assume failure */
tsMembers tsmem = rpmtsMembers(ts);
- rpmlock lock = NULL;
+ rpmtxn txn = NULL;
rpmps tsprobs = NULL;
int TsmPreDone = 0; /* TsmPre hook hasn't been called */
+ /* Ignore SIGPIPE for the duration of transaction */
+ rpmsqAction_t oact = rpmsqSetAction(SIGPIPE, RPMSQ_IGN);
/* Force default 022 umask during transaction for consistent results */
mode_t oldmask = umask(022);
@@ -1494,7 +1532,7 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
/* If we are in test mode, then there's no need for transaction lock. */
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
- if (!(lock = rpmtsAcquireLock(ts))) {
+ if (!(txn = rpmtxnBegin(ts, RPMTXN_WRITE))) {
goto exit;
}
}
@@ -1504,24 +1542,20 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
goto exit;
}
- if (rpmtsSetupTransactionPlugins(ts) == RPMRC_FAIL) {
- goto exit;
- }
-
- rpmtsSetupCollections(ts);
-
/* Check package set for problems */
tsprobs = checkProblems(ts);
/* Run pre transaction hook for all plugins */
TsmPreDone = 1;
- if (rpmpluginsCallTsmPre(ts->plugins, ts) == RPMRC_FAIL) {
+ if (rpmpluginsCallTsmPre(rpmtsPlugins(ts), ts) == RPMRC_FAIL) {
goto exit;
}
- /* Run pre-transaction scripts, but only if there are no known
- * problems up to this point and not disabled otherwise. */
- if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRE))
+ /* Run %pretrans scripts, but only if there are no known problems up to
+ * this point and not disabled otherwise. This is evil as it runs before
+ * fingerprinting and problem checking and is best avoided.
+ */
+ if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRETRANS))
|| (rpmpsNumProblems(tsprobs)))) {
rpmlog(RPMLOG_DEBUG, "running pre-transaction scripts\n");
runTransScripts(ts, PKG_PRETRANS);
@@ -1553,24 +1587,47 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS)))
tsmem->pool = rpmstrPoolFree(tsmem->pool);
+ /* Run %transfiletriggerun scripts unless disabled */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRETRANS|
+ RPMTRANS_FLAG_NOTRIGGERUN))) {
+
+ runFileTriggers(ts, NULL, RPMSENSE_TRIGGERUN,
+ RPMSCRIPT_TRANSFILETRIGGER, 0);
+ runTransScripts(ts, PKG_TRANSFILETRIGGERUN);
+ }
+
/* Actually install and remove packages, get final exit code */
rc = rpmtsProcess(ts) ? -1 : 0;
- /* Run post-transaction scripts unless disabled */
- if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOST))) {
+ /* Run %posttrans scripts unless disabled */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS))) {
rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
runTransScripts(ts, PKG_POSTTRANS);
}
+ /* Run %transfiletriggerpostun scripts unless disabled */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
+ runFileTriggers(ts, NULL, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0);
+ }
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
+ runPostUnTransFileTrigs(ts);
+ }
+
+ /* Run %transfiletriggerin scripts unless disabled */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERIN))) {
+ runTransScripts(ts, PKG_TRANSFILETRIGGERIN);
+ }
exit:
/* Run post transaction hook for all plugins */
if (TsmPreDone) /* If TsmPre hook has been called, call the TsmPost hook */
- rpmpluginsCallTsmPost(ts->plugins, ts, rc);
+ rpmpluginsCallTsmPost(rpmtsPlugins(ts), ts, rc);
/* Finish up... */
(void) umask(oldmask);
(void) rpmtsFinish(ts);
rpmpsFree(tsprobs);
- rpmlockFree(lock);
+ rpmtxnEnd(txn);
+ /* Restore SIGPIPE *after* unblocking signals in rpmtxnEnd() */
+ rpmsqSetAction(SIGPIPE, oact);
return rc;
}