/* Check a given dependency against installed packages */ static void checkInstDeps(rpmts ts, depCache dcache, rpmte te, rpmTag depTag, const char *dep) { Header h; rpmdbMatchIterator mi = rpmtsPrunedIterator(ts, depTag, dep, 1); rpmstrPool pool = rpmtsPool(ts); /* require-problems are unsatisfied, others appear "satisfied" */ int is_problem = (depTag == RPMTAG_REQUIRENAME); while ((h = rpmdbNextIterator(mi)) != NULL) { char * pkgNEVRA; rpmds ds; /* Ignore self-obsoletes and self-conflicts */ if (depTag == RPMTAG_OBSOLETENAME || depTag == RPMTAG_CONFLICTNAME) { unsigned int instance = headerGetInstance(h); if (instance && instance == rpmteDBInstance(te)) continue; } pkgNEVRA = headerGetAsString(h, RPMTAG_NEVRA); ds = rpmdsNewPool(pool, h, depTag, 0); rpmdsSetIx(ds, rpmdbGetIteratorFileNum(mi)); if (unsatisfiedDepend(ts, dcache, ds) == is_problem) rpmteAddDepProblem(te, pkgNEVRA, ds, NULL); rpmdsFree(ds); free(pkgNEVRA); } rpmdbFreeIterator(mi); }
/* * For packages being installed: * - verify package arch/os. * - verify package epoch:version-release is newer. */ static rpmps checkProblems(rpmts ts) { rpm_color_t tscolor = rpmtsColor(ts); rpmprobFilterFlags probFilter = rpmtsFilterFlags(ts); rpmstrPool tspool = rpmtsPool(ts); rpmtsi pi = rpmtsiInit(ts); rpmte p; /* The ordering doesn't matter here */ /* XXX Only added packages need be checked. */ rpmlog(RPMLOG_DEBUG, "sanity checking %d elements\n", rpmtsNElements(ts)); while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) { if (!(probFilter & RPMPROB_FILTER_IGNOREARCH) && badArch(rpmteA(p))) rpmteAddProblem(p, RPMPROB_BADARCH, rpmteA(p), NULL, 0); if (!(probFilter & RPMPROB_FILTER_IGNOREOS) && badOs(rpmteO(p))) rpmteAddProblem(p, RPMPROB_BADOS, rpmteO(p), NULL, 0); if (!(probFilter & RPMPROB_FILTER_OLDPACKAGE)) { Header h; rpmdbMatchIterator mi; mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0); while ((h = rpmdbNextIterator(mi)) != NULL) ensureOlder(tspool, p, h); rpmdbFreeIterator(mi); } if (!(probFilter & RPMPROB_FILTER_REPLACEPKG)) { Header h; rpmdbMatchIterator mi; 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)); if (tscolor) { rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP, rpmteA(p)); rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP, rpmteO(p)); } if ((h = rpmdbNextIterator(mi)) != NULL) { rpmteAddProblem(p, RPMPROB_PKG_INSTALLED, NULL, NULL, headerGetInstance(h)); } rpmdbFreeIterator(mi); } if (!(probFilter & RPMPROB_FILTER_FORCERELOCATE)) rpmteAddRelocProblems(p); } rpmtsiFree(pi); return rpmtsProblems(ts); }
/* Add erase elements for obsoleted packages of same color (if any). */ static int addObsoleteErasures(rpmts ts, rpm_color_t tscolor, rpmte p) { rpmstrPool tspool = rpmtsPool(ts); rpmds obsoletes = rpmdsInit(rpmteDS(p, RPMTAG_OBSOLETENAME)); Header oh; int rc = 0; while (rpmdsNext(obsoletes) >= 0 && rc == 0) { const char * Name; rpmdbMatchIterator mi = NULL; if ((Name = rpmdsN(obsoletes)) == NULL) continue; /* XXX can't happen */ mi = rpmtsPrunedIterator(ts, RPMDBI_NAME, Name, 1); while((oh = rpmdbNextIterator(mi)) != NULL) { const char *oarch = headerGetString(oh, RPMTAG_ARCH); int match; /* avoid self-obsoleting packages */ if (rstreq(rpmteN(p), Name) && rstreq(rpmteA(p), oarch)) { char * ohNEVRA = headerGetAsString(oh, RPMTAG_NEVRA); rpmlog(RPMLOG_DEBUG, " Not obsoleting: %s\n", ohNEVRA); free(ohNEVRA); continue; } /* * Rpm prior to 3.0.3 does not have versioned obsoletes. * If no obsoletes version info is available, match all names. */ match = (rpmdsEVR(obsoletes) == NULL); if (!match) match = rpmdsMatches(tspool, oh, -1, obsoletes, 1, _rpmds_nopromote); if (match) { char * ohNEVRA = headerGetAsString(oh, RPMTAG_NEVRA); rpmlog(RPMLOG_DEBUG, " Obsoletes: %s\t\terases %s\n", rpmdsDNEVR(obsoletes)+2, ohNEVRA); free(ohNEVRA); if (removePackage(ts, oh, p)) { rc = 1; break; } } } rpmdbFreeIterator(mi); } return rc; }
/* Check a given dependency type against installed packages */ static void checkInstDeps(rpmts ts, depCache dcache, rpmte te, rpmTag depTag, const char *dep) { Header h; rpmdbMatchIterator mi = rpmtsPrunedIterator(ts, depTag, dep, 1); rpmstrPool pool = rpmtsPool(ts); while ((h = rpmdbNextIterator(mi)) != NULL) { char * pkgNEVRA = headerGetAsString(h, RPMTAG_NEVRA); rpmds ds = rpmdsNewPool(pool, h, depTag, 0); checkDS(ts, dcache, te, pkgNEVRA, ds, dep, 0); rpmdsFree(ds); free(pkgNEVRA); } rpmdbFreeIterator(mi); }
/* Cached rpmdb provide lookup, returns 0 if satisfied, 1 otherwise */ static int rpmdbProvides(rpmts ts, depCache dcache, rpmds dep) { const char * Name = rpmdsN(dep); const char * DNEVR = rpmdsDNEVR(dep); rpmTagVal deptag = rpmdsTagN(dep); int *cachedrc = NULL; rpmdbMatchIterator mi = NULL; 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; unsigned int keyhash = 0; /* See if we already looked this up */ if (prune) { keyhash = depCacheKeyHash(dcache, DNEVR); if (depCacheGetHEntry(dcache, DNEVR, keyhash, &cachedrc, NULL, NULL)) { rc = *cachedrc; rpmdsNotify(dep, "(cached)", rc); return rc; } } /* * See if a filename dependency is a real file in some package, * taking file state into account: replaced, wrong colored and * not installed files can not satisfy a dependency. */ if (deptag != RPMTAG_OBSOLETENAME && Name[0] == '/') { mi = rpmtsPrunedIterator(ts, RPMDBI_INSTFILENAMES, Name, prune); while ((h = rpmdbNextIterator(mi)) != NULL) { /* Ignore self-conflicts */ if (deptag == RPMTAG_CONFLICTNAME) { unsigned int instance = headerGetInstance(h); if (instance && instance == rpmdsInstance(dep)) continue; } rpmdsNotify(dep, "(db files)", rc); break; } rpmdbFreeIterator(mi); } /* Otherwise look in provides no matter what the dependency looks like */ if (h == NULL) { rpmstrPool tspool = rpmtsPool(ts); /* Obsoletes use just name alone, everything else uses provides */ rpmTagVal dbtag = RPMDBI_PROVIDENAME; int selfevr = 0; if (deptag == RPMTAG_OBSOLETENAME) { dbtag = RPMDBI_NAME; selfevr = 1; } mi = rpmtsPrunedIterator(ts, dbtag, Name, prune); while ((h = rpmdbNextIterator(mi)) != NULL) { /* Provide-indexes can't be used with nevr-only matching */ int prix = (selfevr) ? -1 : rpmdbGetIteratorFileNum(mi); int match = rpmdsMatches(tspool, h, prix, dep, selfevr, _rpmds_nopromote); /* Ignore self-obsoletes and self-conflicts */ if (match && (deptag == RPMTAG_OBSOLETENAME || deptag == RPMTAG_CONFLICTNAME)) { unsigned int instance = headerGetInstance(h); if (instance && instance == rpmdsInstance(dep)) match = 0; } if (match) { rpmdsNotify(dep, "(db provides)", rc); break; } } rpmdbFreeIterator(mi); } rc = (h != NULL) ? 0 : 1; /* Cache the relatively expensive rpmdb lookup results */ /* Caching the oddball non-pruned case would mess up other results */ if (prune) depCacheAddHEntry(dcache, xstrdup(DNEVR), keyhash, rc); return rc; }