#include <rpm/rpmfi.h>
#include "lib/rpmts_internal.h"
+#include "lib/rpmte_internal.h"
#include "debug.h"
/**
* Check added requires/conflicts against against installed+added packages.
* @param ts transaction set
+ * @param te related transaction element
* @param pkgNEVRA package name-version-release.arch
* @param requires Requires: dependencies (or NULL)
* @param conflicts Conflicts: dependencies (or NULL)
* @param tscolor color bits for transaction set (0 disables)
* @param adding dependency is from added package set?
*/
-static void checkPackageDeps(rpmts ts, depCache dcache, const char * pkgNEVRA,
- rpmds requires, rpmds conflicts,
+static void checkPackageDeps(rpmts ts, depCache dcache, rpmte te,
+ const char * pkgNEVRA, rpmds requires, rpmds conflicts,
const char * depName, rpm_color_t tscolor, int adding)
{
rpm_color_t dscolor;
continue;
if (unsatisfiedDepend(ts, dcache, requires, adding) == 1)
- rpmdsProblem(ts->probs, pkgNEVRA, requires, NULL, adding);
+ rpmteAddDepProblem(te, pkgNEVRA, requires, NULL, adding);
}
conflicts = rpmdsInit(conflicts);
continue;
if (unsatisfiedDepend(ts, dcache, conflicts, adding) == 0)
- rpmdsProblem(ts->probs, pkgNEVRA, conflicts, NULL, adding);
+ rpmteAddDepProblem(te, pkgNEVRA, conflicts, NULL, adding);
}
}
* @param mi rpm database iterator
* @param adding dependency is from added package set?
*/
-static void checkPackageSet(rpmts ts, depCache dcache, const char * dep,
- rpmdbMatchIterator mi, int adding)
+static void checkPackageSet(rpmts ts, depCache dcache, rpmte te,
+ const char * dep, rpmdbMatchIterator mi, int adding)
{
tsMembers tsmem = rpmtsMembers(ts);
Header h;
(void) rpmdsSetNoPromote(requires, _rpmds_nopromote);
(void) rpmdsSetNoPromote(conflicts, _rpmds_nopromote);
- checkPackageDeps(ts, dcache, pkgNEVRA, requires, conflicts, dep, 0, adding);
+ checkPackageDeps(ts, dcache, te, pkgNEVRA, requires, conflicts, dep, 0, adding);
conflicts = rpmdsFree(conflicts);
requires = rpmdsFree(requires);
pkgNEVRA = _free(pkgNEVRA);
* @param ts transaction set
* @param dep requires name
*/
-static void checkDependentPackages(rpmts ts, depCache dcache, const char * dep)
+static void checkDependentPackages(rpmts ts, depCache dcache,
+ rpmte te, const char * dep)
{
rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMTAG_REQUIRENAME, dep, 0);
- checkPackageSet(ts, dcache, dep, mi, 0);
+ checkPackageSet(ts, dcache, te, dep, mi, 0);
rpmdbFreeIterator(mi);
}
* @param ts transaction set
* @param dep conflicts name
*/
-static void checkDependentConflicts(rpmts ts, depCache dcache, const char * dep)
+static void checkDependentConflicts(rpmts ts, depCache dcache,
+ rpmte te, const char * dep)
{
rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMTAG_CONFLICTNAME, dep, 0);
- checkPackageSet(ts, dcache, dep, mi, 1);
+ checkPackageSet(ts, dcache, te, dep, mi, 1);
rpmdbFreeIterator(mi);
}
closeatexit = 1;
}
- ts->probs = rpmpsFree(ts->probs);
- ts->probs = rpmpsCreate();
-
rpmalMakeIndex(tsmem->addedPackages);
/* XXX FIXME: figure some kind of heuristic for the cache size */
rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n",
rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
- checkPackageDeps(ts, dcache, rpmteNEVRA(p),
+ checkPackageDeps(ts, dcache, p, rpmteNEVRA(p),
rpmteDS(p, RPMTAG_REQUIRENAME),
rpmteDS(p, RPMTAG_CONFLICTNAME),
NULL,
/* Adding: check provides key against conflicts matches. */
while (rpmdsNext(provides) >= 0) {
- checkDependentConflicts(ts, dcache, rpmdsN(provides));
+ checkDependentConflicts(ts, dcache, p, rpmdsN(provides));
}
}
pi = rpmtsiFree(pi);
/* Erasing: check provides against requiredby matches. */
while (rpmdsNext(provides) >= 0) {
- checkDependentPackages(ts, dcache, rpmdsN(provides));
+ checkDependentPackages(ts, dcache, p, rpmdsN(provides));
}
/* Erasing: check filename against requiredby matches. */
while (rpmfiNext(fi) >= 0) {
- checkDependentPackages(ts, dcache, rpmfiFN(fi));
+ checkDependentPackages(ts, dcache, p, rpmfiFN(fi));
}
}
pi = rpmtsiFree(pi);
return result;
}
-void rpmdsProblem(rpmps ps, const char * pkgNEVR, const rpmds ds,
- const fnpyKey * suggestedKeys, int adding)
-{
- const char * DNEVR = rpmdsDNEVR(ds);
- const char * EVR = rpmdsEVR(ds);
- rpmProblemType type;
- fnpyKey key;
-
- if (ps == NULL) return;
-
- if (EVR == NULL) EVR = "?EVR?";
- if (DNEVR == NULL) DNEVR = "? ?N? ?OP? ?EVR?";
-
- rpmlog(RPMLOG_DEBUG, "package %s has unsatisfied %s: %s\n",
- pkgNEVR, ds->Type, DNEVR+2);
-
- switch ((unsigned)DNEVR[0]) {
- case 'C': type = RPMPROB_CONFLICT; break;
- default:
- case 'R': type = RPMPROB_REQUIRES; break;
- }
-
- key = (suggestedKeys ? suggestedKeys[0] : NULL);
- rpmpsAppend(ps, type, pkgNEVR, key, NULL, NULL, DNEVR, adding);
-}
-
int rpmdsAnyMatchesDep (const Header h, const rpmds req, int nopromote)
{
rpmds provides = NULL;
**/
int rpmdsSearch(rpmds ds, rpmds ods);
-
/** \ingroup rpmds
* Compare two versioned dependency ranges, looking for overlap.
* @param A 1st dependency
int rpmdsCompare(const rpmds A, const rpmds B);
/** \ingroup rpmds
- * Report a Requires: or Conflicts: dependency problem.
- * @param ps transaction set problems
- * @param pkgNEVR package name/epoch/version/release
- * @param ds dependency set
- * @param suggestedKeys filename or python object address
- * @param adding dependency problem is from added package set?
- */
-void rpmdsProblem(rpmps ps, const char * pkgNEVR, const rpmds ds,
- const fnpyKey * suggestedKeys,
- int adding);
-
-/** \ingroup rpmds
* Compare package provides dependencies from header with a single dependency.
* @param h header
* @param req dependency set
rpmps rpmtsProblems(rpmts ts)
{
- rpmps ps = NULL;
- if (ts) {
- if (ts->probs)
- ps = rpmpsLink(ts->probs, RPMDBG_M("rpmtsProblems"));
+ rpmps ps = rpmpsCreate();
+ rpmtsi pi = rpmtsiInit(ts);
+ rpmte p;
+
+ /* XXX TODO this cries for rpmpsMerge() */
+ while ((p = rpmtsiNext(pi, 0)) != NULL) {
+ rpmps teprobs = rpmteProblems(p);
+ if (teprobs) {
+ rpmpsi psi = rpmpsInitIterator(teprobs);
+ while (rpmpsNextIterator(psi) >= 0) {
+ rpmProblem prob = rpmpsGetProblem(psi);
+ rpmpsAppendProblem(ps, prob);
+ }
+ rpmpsFreeIterator(psi);
+ rpmpsFree(teprobs);
+ }
}
+ pi = rpmtsiFree(pi);
return ps;
}
void rpmtsCleanProblems(rpmts ts)
{
- if (ts && ts->probs) {
- ts->probs = rpmpsFree(ts->probs);
- }
+ rpmte p;
+ rpmtsi pi = rpmtsiInit(ts);
+ while ((p = rpmtsiNext(pi, 0)) != NULL)
+ rpmteCleanProblems(p);
+ pi = rpmtsiFree(pi);
}
void rpmtsClean(rpmts ts)
ts->selinuxEnabled = is_selinux_enabled();
- ts->probs = NULL;
-
ts->keyring = NULL;
ts->nrefs = 0;
rpmCallbackFunction notify; /*!< Callback function. */
rpmCallbackData notifyData; /*!< Callback private data. */
- rpmps probs; /*!< Current problems in transaction. */
rpmprobFilterFlags ignoreSet;
/*!< Bits to filter current problems. */
static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
{
rpmDiskSpaceInfo dsi = ts->dsi;
- rpmps ps;
if (dsi == NULL || !dsi->bsize)
return;
if (rpmfiFC(rpmteFI(te)) <= 0)
return;
- ps = rpmtsProblems(ts);
for (; dsi->bsize; dsi++) {
if (dsi->bavail >= 0 && adj_fs_blocks(dsi->bneeded) > dsi->bavail) {
if (dsi->bneeded > dsi->obneeded) {
- rpmpsAppend(ps, RPMPROB_DISKSPACE,
- rpmteNEVRA(te), rpmteKey(te),
+ rpmteAddProblem(te, RPMPROB_DISKSPACE,
dsi->mntPoint, NULL, NULL,
(adj_fs_blocks(dsi->bneeded) - dsi->bavail) * dsi->bsize);
dsi->obneeded = dsi->bneeded;
if (dsi->iavail >= 0 && adj_fs_blocks(dsi->ineeded) > dsi->iavail) {
if (dsi->ineeded > dsi->oineeded) {
- rpmpsAppend(ps, RPMPROB_DISKNODES,
- rpmteNEVRA(te), rpmteKey(te),
+ rpmteAddProblem(te, RPMPROB_DISKNODES,
dsi->mntPoint, NULL, NULL,
(adj_fs_blocks(dsi->ineeded) - dsi->iavail));
dsi->oineeded = dsi->ineeded;
}
}
}
- ps = rpmpsFree(ps);
}
static void rpmtsFreeDSI(rpmts ts){
if (rConflicts) {
char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA);
- rpmps ps = rpmtsProblems(ts);
- rpmpsAppend(ps, RPMPROB_FILE_CONFLICT,
- rpmteNEVRA(p), rpmteKey(p),
- rpmfiDN(fi), rpmfiBN(fi),
- altNEVR,
- 0);
+ rpmteAddProblem(p, RPMPROB_FILE_CONFLICT,
+ rpmfiDN(fi), rpmfiBN(fi), altNEVR, 0);
free(altNEVR);
- rpmpsFree(ps);
}
/* Save file identifier to mark as state REPLACED. */
static void handleOverlappedFiles(rpmts ts, rpmFpHash ht, rpmte p, rpmfi fi)
{
rpm_loff_t fixupSize = 0;
- rpmps ps;
const char * fn;
int i, j;
rpm_color_t tscolor = rpmtsColor(ts);
rpmfs fs = rpmteGetFileStates(p);
rpmfs otherFs;
- ps = rpmtsProblems(ts);
fi = rpmfiInit(fi, 0);
while ((i = rpmfiNext(fi)) >= 0) {
rpm_color_t oFColor, FColor;
done = 1;
}
if (rConflicts) {
- rpmpsAppend(ps, RPMPROB_NEW_FILE_CONFLICT,
- rpmteNEVRA(p), rpmteKey(p),
- fn, NULL,
- rpmteNEVRA(otherTe),
- 0);
+ rpmteAddProblem(p, RPMPROB_NEW_FILE_CONFLICT,
+ fn, NULL, rpmteNEVRA(otherTe), 0);
}
}
fixupSize, rpmfsGetAction(fs, i));
}
- ps = rpmpsFree(ps);
}
/**
* @param h installed header
* @param ps problem set
*/
-static void ensureOlder(const rpmte p, const Header h, rpmps ps)
+static void ensureOlder(const rpmte p, const Header h)
{
rpmsenseFlags reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL);
rpmds req;
req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), rpmteEVR(p), reqFlags);
if (rpmdsNVRMatchesDep(h, req, _rpmds_nopromote) == 0) {
char * altNEVR = headerGetAsString(h, RPMTAG_NEVRA);
- rpmpsAppend(ps, RPMPROB_OLDPACKAGE, rpmteNEVRA(p), rpmteKey(p),
- NULL, NULL, altNEVR, 0);
+ rpmteAddProblem(p, RPMPROB_OLDPACKAGE, NULL, NULL, altNEVR, 0);
free(altNEVR);
}
rpmdsFree(req);
{
rpm_color_t tscolor = rpmtsColor(ts);
rpmprobFilterFlags probFilter = rpmtsFilterFlags(ts);
- rpmps ps = rpmpsCreate();
rpmtsi pi = rpmtsiInit(ts);
rpmte p;
rpmlog(RPMLOG_DEBUG, "sanity checking %d elements\n", rpmtsNElements(ts));
while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
rpmdbMatchIterator mi;
- rpmpsi psi;
if (!(probFilter & RPMPROB_FILTER_IGNOREARCH) && badArch(rpmteA(p)))
- rpmpsAppend(ps, RPMPROB_BADARCH, rpmteNEVRA(p), rpmteKey(p),
- rpmteA(p), NULL, NULL, 0);
+ rpmteAddProblem(p, RPMPROB_BADARCH, rpmteA(p), NULL, NULL, 0);
if (!(probFilter & RPMPROB_FILTER_IGNOREOS) && badOs(rpmteO(p)))
- rpmpsAppend(ps, RPMPROB_BADOS, rpmteNEVRA(p), rpmteKey(p),
- rpmteO(p), NULL, NULL, 0);
+ rpmteAddProblem(p, RPMPROB_BADOS, rpmteO(p), NULL, NULL, 0);
if (!(probFilter & RPMPROB_FILTER_OLDPACKAGE)) {
Header h;
mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
while ((h = rpmdbNextIterator(mi)) != NULL)
- ensureOlder(p, h, ps);
+ ensureOlder(p, h);
mi = rpmdbFreeIterator(mi);
}
rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP, rpmteO(p));
}
- while (rpmdbNextIterator(mi) != NULL) {
- rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
- rpmteNEVRA(p), rpmteKey(p),
- NULL, NULL,
- NULL, 0);
- break;
+ if (rpmdbNextIterator(mi) != NULL) {
+ rpmteAddProblem(p, RPMPROB_PKG_INSTALLED, NULL, NULL, NULL, 0);
}
mi = rpmdbFreeIterator(mi);
}
-
- /* XXX rpmte problems can only be relocation problems atm */
- if (!(probFilter & RPMPROB_FILTER_FORCERELOCATE)) {
- psi = rpmpsInitIterator(rpmteProblems(p));
- while (rpmpsNextIterator(psi) >= 0) {
- rpmpsAppendProblem(ps, rpmpsGetProblem(psi));
- }
- rpmpsFreeIterator(psi);
- }
}
pi = rpmtsiFree(pi);
- return ps;
+ return rpmtsProblems(ts);
}
/*
}
ts->ignoreSet = ignoreSet;
- ts->probs = rpmpsFree(ts->probs);
{ char * currDir = rpmGetCwd();
rpmtsSetCurrDir(ts, currDir);
{
int rc = -1; /* assume failure */
void * lock = NULL;
+ rpmps tsprobs = NULL;
/* XXX programmer error segfault avoidance. */
if (rpmtsNElements(ts) <= 0) {
}
/* Check package set for problems */
- ts->probs = checkProblems(ts);
+ tsprobs = checkProblems(ts);
/* 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_TEST|RPMTRANS_FLAG_NOPRE))
- || (rpmpsNumProblems(ts->probs) &&
- (okProbs == NULL || rpmpsTrim(ts->probs, okProbs))))) {
+ || (rpmpsNumProblems(tsprobs) &&
+ (okProbs == NULL || rpmpsTrim(tsprobs, okProbs))))) {
rpmlog(RPMLOG_DEBUG, "running pre-transaction scripts\n");
runTransScripts(ts, RPMTAG_PRETRANS);
}
+ tsprobs = rpmpsFree(tsprobs);
/* Compute file disposition for each package in transaction set. */
if (rpmtsPrepare(ts)) {
goto exit;
}
+ /* Check again for problems (now including file conflicts, duh */
+ tsprobs = rpmtsProblems(ts);
/* If unfiltered problems exist, free memory and return. */
if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS) ||
- (rpmpsNumProblems(ts->probs) &&
- (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))) {
+ (rpmpsNumProblems(tsprobs) &&
+ (okProbs == NULL || rpmpsTrim(tsprobs, okProbs)))) {
tsMembers tsmem = rpmtsMembers(ts);
rc = tsmem->orderCount;
goto exit;
}
+ /* Free up memory taken by problem sets */
+ tsprobs = rpmpsFree(tsprobs);
+ rpmtsCleanProblems(ts);
+
/* Actually install and remove packages, get final exit code */
rc = rpmtsProcess(ts) ? -1 : 0;
(void) rpmtsFinish(ts);
exit:
+ tsprobs = rpmpsFree(tsprobs);
rpmtsFreeLock(lock);
return rc;
}