rpmte rpmalSatisfiesDepend(const rpmal al, const rpmds ds) { rpmte *providers = rpmalAllSatisfiesDepend(al, ds); rpmte best = NULL; if (providers) { if (al->tscolor) { /* * For colored dependencies, try to find a matching provider. * Otherwise prefer provider of ts preferred color. */ rpm_color_t dscolor = rpmdsColor(ds); for (rpmte *p = providers; *p; p++) { rpm_color_t tecolor = rpmteColor(*p); if (dscolor) { if (dscolor == tecolor) best = *p; } else if (al->prefcolor) { if (al->prefcolor == tecolor) best = *p; } if (best) break; } } /* if not decided by now, just pick first match */ if (!best) best = providers[0]; free(providers); } return best; }
/* * Filtered rpmal lookup: on colored transactions there can be more * than one identical NEVR but different arch, this must be allowed. * Only a single element needs to be considred as there can only ever * be one previous element to be replaced. */ static rpmte checkAdded(rpmal addedPackages, rpm_color_t tscolor, rpmte te, rpmds ds) { rpmte p = NULL; rpmte *matches = NULL; matches = rpmalAllSatisfiesDepend(addedPackages, ds); if (matches) { const char * arch = rpmteA(te); const char * os = rpmteO(te); for (rpmte *m = matches; m && *m; m++) { if (tscolor) { const char * parch = rpmteA(*m); const char * pos = rpmteO(*m); if (arch == NULL || parch == NULL || os == NULL || pos == NULL) continue; if (!rstreq(arch, parch) || !rstreq(os, pos)) continue; } p = *m; break; } free(matches); } return p; }
rpmte rpmalSatisfiesDepend(const rpmal al, const rpmte te, const rpmds ds) { rpmte *providers = rpmalAllSatisfiesDepend(al, ds); rpmte best = NULL; int bestscore = 0; if (providers) { rpm_color_t dscolor = rpmdsColor(ds); for (rpmte *p = providers; *p; p++) { int score = 0; /* * For colored dependencies, prefer a matching colored provider. * Otherwise prefer provider of ts preferred color. */ if (al->tscolor) { rpm_color_t tecolor = rpmteColor(*p); if (dscolor) { if (dscolor == tecolor) score += 2; } else if (al->prefcolor) { if (al->prefcolor == tecolor) score += 2; } } /* Being self-provided is a bonus */ if (*p == te) score += 1; if (score > bestscore) { bestscore = score; best = *p; } } /* if not decided by now, just pick first match */ if (!best) best = providers[0]; free(providers); } return best; }
/** * Check dep for an unsatisfied dependency. * @param ts transaction set * @param dcache dependency cache * @param dep dependency * @return 0 if satisfied, 1 if not satisfied */ static int unsatisfiedDepend(rpmts ts, depCache dcache, rpmds dep) { tsMembers tsmem = rpmtsMembers(ts); int rc; int retrying = 0; int adding = (rpmdsInstance(dep) == 0); rpmsenseFlags dsflags = rpmdsFlags(dep); retry: rc = 0; /* assume dependency is satisfied */ /* * New features in rpm packaging implicitly add versioned dependencies * on rpmlib provides. The dependencies look like "rpmlib(YaddaYadda)". * Check those dependencies now. */ if (dsflags & RPMSENSE_RPMLIB) { if (tsmem->rpmlib == NULL) rpmdsRpmlibPool(rpmtsPool(ts), &(tsmem->rpmlib), NULL); if (tsmem->rpmlib != NULL && rpmdsSearch(tsmem->rpmlib, dep) >= 0) { rpmdsNotify(dep, "(rpmlib provides)", rc); goto exit; } goto unsatisfied; } /* Dont look at pre-requisites of already installed packages */ if (!adding && isInstallPreReq(dsflags) && !isErasePreReq(dsflags)) goto exit; /* Handle rich dependencies */ if (rpmdsIsRich(dep)) { rpmds ds1, ds2; rpmrichOp op; char *emsg = 0; if (rpmdsParseRichDep(dep, &ds1, &ds2, &op, &emsg) != RPMRC_OK) { rc = rpmdsTagN(dep) == RPMTAG_CONFLICTNAME ? 0 : 1; if (rpmdsInstance(dep) != 0) rc = !rc; /* ignore errors for installed packages */ rpmdsNotify(dep, emsg ? emsg : "(parse error)", rc); _free(emsg); goto exit; } if (op == RPMRICHOP_IF) { if (rpmdsIsRich(ds2)) { /* check if this is a IF...ELSE combination */ rpmds ds21 = NULL, ds22 = NULL; rpmrichOp op2; if (rpmdsParseRichDep(ds2, &ds21, &ds22, &op2, NULL) == RPMRC_OK && op2 == RPMRICHOP_ELSE) { rc = unsatisfiedDepend(ts, dcache, ds21); if (rc) { rpmdsFree(ds1); ds1 = ds22; ds22 = NULL; } rc = 1; } rpmdsFree(ds21); rpmdsFree(ds22); } if (!rc) rc = !unsatisfiedDepend(ts, dcache, ds2); } if (op != RPMRICHOP_IF || rc) rc = unsatisfiedDepend(ts, dcache, ds1); if ((rc && op == RPMRICHOP_OR) || (!rc && op == RPMRICHOP_AND)) rc = unsatisfiedDepend(ts, dcache, ds2); ds1 = rpmdsFree(ds1); ds2 = rpmdsFree(ds2); rpmdsNotify(dep, "(rich)", rc); goto exit; } /* Pretrans dependencies can't be satisfied by added packages. */ if (!(dsflags & RPMSENSE_PRETRANS)) { rpmte *matches = rpmalAllSatisfiesDepend(tsmem->addedPackages, dep); int match = matches && *matches; _free(matches); if (match) goto exit; } /* See if the rpmdb provides it */ if (rpmdbProvides(ts, dcache, dep) == 0) goto exit; /* Search for an unsatisfied dependency. */ if (adding && !retrying && !(dsflags & RPMSENSE_PRETRANS)) { int xx = rpmtsSolve(ts, dep); if (xx == 0) goto exit; if (xx == -1) { retrying = 1; goto retry; } } unsatisfied: if (dsflags & RPMSENSE_MISSINGOK) { /* note the result, but missingok deps are never unsatisfied */ rpmdsNotify(dep, "(missingok)", 1); } else { /* dependency is unsatisfied */ rc = 1; rpmdsNotify(dep, NULL, rc); } exit: return rc; }
/** * Check dep for an unsatisfied dependency. * @param ts transaction set * @param dep dependency * @return 0 if satisfied, 1 if not satisfied */ static int unsatisfiedDepend(rpmts ts, depCache dcache, rpmds dep) { tsMembers tsmem = rpmtsMembers(ts); int rc; int retrying = 0; int adding = (rpmdsInstance(dep) == 0); rpmsenseFlags dsflags = rpmdsFlags(dep); retry: rc = 0; /* assume dependency is satisfied */ /* * New features in rpm packaging implicitly add versioned dependencies * on rpmlib provides. The dependencies look like "rpmlib(YaddaYadda)". * Check those dependencies now. */ if (dsflags & RPMSENSE_RPMLIB) { if (tsmem->rpmlib == NULL) rpmdsRpmlibPool(rpmtsPool(ts), &(tsmem->rpmlib), NULL); if (tsmem->rpmlib != NULL && rpmdsSearch(tsmem->rpmlib, dep) >= 0) { rpmdsNotify(dep, "(rpmlib provides)", rc); goto exit; } goto unsatisfied; } /* Dont look at pre-requisites of already installed packages */ if (!adding && isInstallPreReq(dsflags) && !isErasePreReq(dsflags)) goto exit; /* Pretrans dependencies can't be satisfied by added packages. */ if (!(dsflags & RPMSENSE_PRETRANS)) { rpmte *matches = rpmalAllSatisfiesDepend(tsmem->addedPackages, dep); int match = 0; /* * Handle definitive matches within the added package set. * Self-obsoletes and -conflicts fall through here as we need to * check for possible other matches in the rpmdb. */ for (rpmte *m = matches; m && *m; m++) { rpmTagVal dtag = rpmdsTagN(dep); /* Requires match, look no further */ if (dtag == RPMTAG_REQUIRENAME) { match = 1; break; } /* Conflicts/obsoletes match on another package, look no further */ if (rpmteDS(*m, dtag) != dep) { match = 1; break; } } free(matches); if (match) goto exit; } /* See if the rpmdb provides it */ if (rpmdbProvides(ts, dcache, dep) == 0) goto exit; /* Search for an unsatisfied dependency. */ if (adding && !retrying && !(dsflags & RPMSENSE_PRETRANS)) { int xx = rpmtsSolve(ts, dep); if (xx == 0) goto exit; if (xx == -1) { retrying = 1; goto retry; } } unsatisfied: if (dsflags & RPMSENSE_MISSINGOK) { /* note the result, but missingok deps are never unsatisfied */ rpmdsNotify(dep, "(missingok)", 1); } else { /* dependency is unsatisfied */ rc = 1; rpmdsNotify(dep, NULL, rc); } exit: return rc; }