/* * Checks [Pre]-Depends only. */ enum dep_check dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing, struct varbuf *aemsgs) { /* Valid values: 2 = ok, 1 = defer, 0 = halt. */ enum dep_check ok; /* Valid values: 0 = none, 1 = defer, 2 = withwarning, 3 = ok. */ enum found_status found, thisf; int interestingwarnings; bool matched, anycannotfixbytrig; struct varbuf oemsgs = VARBUF_INIT; struct dependency *dep; struct deppossi *possi, *provider; struct pkginfo *possfixbytrig, *canfixbytrig; interestingwarnings= 0; ok = DEP_CHECK_OK; debug(dbg_depcon,"checking dependencies of %s (- %s)", pkg_name(pkg, pnaw_always), removing ? pkg_name(removing, pnaw_always) : "<none>"); anycannotfixbytrig = false; canfixbytrig = NULL; for (dep= pkg->installed.depends; dep; dep= dep->next) { if (dep->type != dep_depends && dep->type != dep_predepends) continue; debug(dbg_depcondetail," checking group ..."); matched = false; varbuf_reset(&oemsgs); found = FOUND_NONE; possfixbytrig = NULL; for (possi = dep->list; found != FOUND_OK && possi; possi = possi->next) { struct deppossi_pkg_iterator *possi_iter; struct pkginfo *pkg_pos; debug(dbg_depcondetail," checking possibility -> %s",possi->ed->name); if (possi->cyclebreak) { debug(dbg_depcondetail," break cycle so ok and found"); found = FOUND_OK; break; } thisf = FOUND_NONE; possi_iter = deppossi_pkg_iter_new(possi, wpb_installed); while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) { thisf = deppossi_ok_found(pkg_pos, pkg, removing, NULL, &possfixbytrig, &matched, possi, &interestingwarnings, &oemsgs); if (thisf > found) found = thisf; if (found == FOUND_OK) break; } deppossi_pkg_iter_free(possi_iter); if (found != FOUND_OK) { for (provider = possi->ed->depended.installed; found != FOUND_OK && provider; provider = provider->rev_next) { if (provider->up->type != dep_provides) continue; debug(dbg_depcondetail, " checking provider %s", pkg_name(provider->up->up, pnaw_always)); if (!deparchsatisfied(&provider->up->up->installed, provider->arch, possi)) { debug(dbg_depcondetail, " provider does not satisfy arch"); continue; } thisf = deppossi_ok_found(provider->up->up, pkg, removing, provider, &possfixbytrig, &matched, possi, &interestingwarnings, &oemsgs); if (thisf == FOUND_DEFER && provider->up->up == pkg && !removing) { /* IOW, if the pkg satisfies its own dep (via a provide), then * we let it pass, even if it isn't configured yet (as we're * installing it). */ thisf = FOUND_OK; } if (thisf > found) found = thisf; } } debug(dbg_depcondetail," found %d",found); if (thisf > found) found= thisf; } if (in_force(FORCE_DEPENDS)) { thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS); if (thisf > found) { found = thisf; debug(dbg_depcondetail, " rescued by force-depends, found %d", found); } } debug(dbg_depcondetail, " found %d matched %d possfixbytrig %s", found, matched, possfixbytrig ? pkg_name(possfixbytrig, pnaw_always) : "-"); if (removing && !matched) continue; switch (found) { case FOUND_NONE: anycannotfixbytrig = true; ok = DEP_CHECK_HALT; /* Fall through. */ case FOUND_FORCED: varbuf_add_str(aemsgs, " "); varbuf_add_pkgbin_name(aemsgs, pkg, &pkg->installed, pnaw_nonambig); varbuf_add_str(aemsgs, _(" depends on ")); varbufdependency(aemsgs, dep); if (interestingwarnings) { /* Don't print the line about the package to be removed if * that's the only line. */ varbuf_end_str(&oemsgs); varbuf_add_str(aemsgs, _("; however:\n")); varbuf_add_str(aemsgs, oemsgs.buf); } else { varbuf_add_str(aemsgs, ".\n"); } break; case FOUND_DEFER: if (possfixbytrig) canfixbytrig = possfixbytrig; else anycannotfixbytrig = true; if (ok > DEP_CHECK_DEFER) ok = DEP_CHECK_DEFER; break; case FOUND_OK: break; default: internerr("unknown value for found '%d'", found); } } if (ok == DEP_CHECK_HALT && (pkg->clientdata && pkg->clientdata->istobe == PKG_ISTOBE_REMOVE)) ok = DEP_CHECK_DEFER; if (!anycannotfixbytrig && canfixbytrig) progress_bytrigproc = canfixbytrig; varbuf_destroy(&oemsgs); debug(dbg_depcon,"ok %d msgs >>%.*s<<", ok, (int)aemsgs->used, aemsgs->buf); return ok; }
bool archsatisfied(struct pkgbin *it, struct deppossi *against) { return deparchsatisfied(it, it->arch, against); }
/* * Checks [Pre]-Depends only. */ enum dep_check dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing, struct varbuf *aemsgs) { /* Valid values: 2 = ok, 1 = defer, 0 = halt. */ enum dep_check ok; /* Valid values: 0 = none, 1 = defer, 2 = withwarning, 3 = ok. */ enum found_status found, thisf; int interestingwarnings; bool matched, anycannotfixbytrig; struct varbuf oemsgs = VARBUF_INIT; struct dependency *dep; struct deppossi *possi, *provider; struct pkginfo *possfixbytrig, *canfixbytrig; interestingwarnings= 0; ok = dep_check_ok; debug(dbg_depcon,"checking dependencies of %s (- %s)", pkg_name(pkg, pnaw_always), removing ? pkg_name(removing, pnaw_always) : "<none>"); anycannotfixbytrig = false; canfixbytrig = NULL; for (dep= pkg->installed.depends; dep; dep= dep->next) { if (dep->type != dep_depends && dep->type != dep_predepends) continue; debug(dbg_depcondetail," checking group ..."); matched = false; varbuf_reset(&oemsgs); found = found_none; possfixbytrig = NULL; for (possi = dep->list; found != found_ok && possi; possi = possi->next) { struct deppossi_pkg_iterator *possi_iter; struct pkginfo *pkg_pos; debug(dbg_depcondetail," checking possibility -> %s",possi->ed->name); if (possi->cyclebreak) { debug(dbg_depcondetail," break cycle so ok and found"); found = found_ok; break; } thisf = found_none; possi_iter = deppossi_pkg_iter_new(possi, wpb_installed); while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) { thisf = deppossi_ok_found(pkg_pos, pkg, removing, NULL, &possfixbytrig, &matched, possi, &interestingwarnings, &oemsgs); if (thisf > found) found = thisf; if (found == found_ok) break; } deppossi_pkg_iter_free(possi_iter); if (found != found_ok && possi->verrel == dpkg_relation_none) { for (provider = possi->ed->depended.installed; found != found_ok && provider; provider = provider->rev_next) { if (provider->up->type != dep_provides) continue; debug(dbg_depcondetail, " checking provider %s", pkg_name(provider->up->up, pnaw_always)); if (!deparchsatisfied(&provider->up->up->installed, provider->arch, possi)) { debug(dbg_depcondetail, " provider does not satisfy arch"); continue; } thisf = deppossi_ok_found(provider->up->up, pkg, removing, possi->ed, &possfixbytrig, &matched, NULL, &interestingwarnings, &oemsgs); if (thisf > found) found = thisf; } } debug(dbg_depcondetail," found %d",found); if (thisf > found) found= thisf; } if (fc_depends) { thisf = (dependtry >= 4) ? found_forced : found_defer; if (thisf > found) { found = thisf; debug(dbg_depcondetail, " rescued by force-depends, found %d", found); } } debug(dbg_depcondetail, " found %d matched %d possfixbytrig %s", found, matched, possfixbytrig ? pkg_name(possfixbytrig, pnaw_always) : "-"); if (removing && !matched) continue; switch (found) { case found_none: anycannotfixbytrig = true; ok = dep_check_halt; case found_forced: varbuf_add_str(aemsgs, " "); varbuf_add_pkgbin_name(aemsgs, pkg, &pkg->installed, pnaw_nonambig); varbuf_add_str(aemsgs, _(" depends on ")); varbufdependency(aemsgs, dep); if (interestingwarnings) { /* Don't print the line about the package to be removed if * that's the only line. */ varbuf_end_str(&oemsgs); varbuf_add_str(aemsgs, _("; however:\n")); varbuf_add_str(aemsgs, oemsgs.buf); } else { varbuf_add_str(aemsgs, ".\n"); } break; case found_defer: if (possfixbytrig) canfixbytrig = possfixbytrig; else anycannotfixbytrig = true; if (ok > dep_check_defer) ok = dep_check_defer; break; case found_ok: break; default: internerr("unknown value for found '%d'", found); } } if (ok == dep_check_halt && (pkg->clientdata && pkg->clientdata->istobe == itb_remove)) ok = dep_check_defer; if (!anycannotfixbytrig && canfixbytrig) progress_bytrigproc = canfixbytrig; varbuf_destroy(&oemsgs); debug(dbg_depcon,"ok %d msgs >>%.*s<<", ok, (int)aemsgs->used, aemsgs->buf); return ok; }