void check_conflict(struct dependency *dep, struct pkginfo *pkg, const char *pfilename) { struct pkginfo *fixbyrm; struct deppossi *pdep, flagdeppossi; struct varbuf conflictwhy = VARBUF_INIT, removalwhy = VARBUF_INIT; struct dependency *providecheck; fixbyrm = NULL; if (depisok(dep, &conflictwhy, &fixbyrm, false)) { varbuf_destroy(&conflictwhy); varbuf_destroy(&removalwhy); return; } if (fixbyrm) { ensure_package_clientdata(fixbyrm); if (fixbyrm->clientdata->istobe == itb_installnew) { fixbyrm= dep->up; ensure_package_clientdata(fixbyrm); } if (((pkg->available.essential && fixbyrm->installed.essential) || (((fixbyrm->want != want_install && fixbyrm->want != want_hold) || does_replace(pkg, &pkg->available, fixbyrm, &fixbyrm->installed)) && (!fixbyrm->installed.essential || fc_removeessential)))) { assert(fixbyrm->clientdata->istobe == itb_normal || fixbyrm->clientdata->istobe == itb_deconfigure); fixbyrm->clientdata->istobe= itb_remove; fprintf(stderr, _("dpkg: considering removing %s in favour of %s ...\n"), fixbyrm->name, pkg->name); if (!(fixbyrm->status == stat_installed || fixbyrm->status == stat_triggerspending || fixbyrm->status == stat_triggersawaited)) { fprintf(stderr, _("%s is not properly installed - ignoring any dependencies on it.\n"), fixbyrm->name); pdep = NULL; } else { for (pdep= fixbyrm->installed.depended; pdep; pdep = pdep->rev_next) { if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends) continue; if (depisok(pdep->up, &removalwhy, NULL, false)) continue; varbufaddc(&removalwhy,0); if (!try_remove_can(pdep,fixbyrm,removalwhy.buf)) break; } if (!pdep) { /* If we haven't found a reason not to yet, let's look some more. */ for (providecheck= fixbyrm->installed.depends; providecheck; providecheck= providecheck->next) { if (providecheck->type != dep_provides) continue; for (pdep= providecheck->list->ed->installed.depended; pdep; pdep = pdep->rev_next) { if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends) continue; if (depisok(pdep->up, &removalwhy, NULL, false)) continue; varbufaddc(&removalwhy,0); fprintf(stderr, _("dpkg" ": may have trouble removing %s, as it provides %s ...\n"), fixbyrm->name, providecheck->list->ed->name); if (!try_remove_can(pdep,fixbyrm,removalwhy.buf)) goto break_from_both_loops_at_once; } } break_from_both_loops_at_once:; } } if (!pdep && skip_due_to_hold(fixbyrm)) { pdep= &flagdeppossi; } if (!pdep && (fixbyrm->eflag & eflag_reinstreq)) { if (fc_removereinstreq) { fprintf(stderr, _("dpkg: package %s requires reinstallation, but will" " remove anyway as you requested.\n"), fixbyrm->name); } else { fprintf(stderr, _("dpkg: package %s requires reinstallation, " "will not remove.\n"), fixbyrm->name); pdep= &flagdeppossi; } } if (!pdep) { if (cflict_index >= MAXCONFLICTORS) ohshit(_("package %s has too many Conflicts/Replaces pairs"), pkg->name); /* This conflict is OK - we'll remove the conflictor. */ conflictor[cflict_index++]= fixbyrm; varbuf_destroy(&conflictwhy); varbuf_destroy(&removalwhy); fprintf(stderr, _("dpkg: yes, will remove %s in favour of %s.\n"), fixbyrm->name, pkg->name); return; } /* Put it back. */ fixbyrm->clientdata->istobe = itb_normal; } } varbufaddc(&conflictwhy,0); fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"), pfilename, pkg->name, conflictwhy.buf); if (!force_conflicts(dep->list)) ohshit(_("conflicting packages - not installing %.250s"),pkg->name); warning(_("ignoring conflict, may proceed anyway!")); varbuf_destroy(&conflictwhy); return; }
/* * Return values: * 0: cannot be satisfied. * 1: defer: may be satisfied later, when other packages are better or * at higher dependtry due to --force * will set *fixbytrig to package whose trigger processing would help * if applicable (and leave it alone otherwise). * 2: not satisfied but forcing * (*interestingwarnings >= 0 on exit? caller is to print oemsgs). * 3: satisfied now. */ static enum found_status deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, struct pkginfo *removing, struct deppossi *provider, struct pkginfo **fixbytrig, bool *matched, struct deppossi *checkversion, int *interestingwarnings, struct varbuf *oemsgs) { enum found_status thisf; if (ignore_depends(possdependee)) { debug(dbg_depcondetail," ignoring depended package so ok and found"); return FOUND_OK; } thisf = FOUND_NONE; if (possdependee == removing) { if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig)); } *matched = true; debug(dbg_depcondetail," removing possdependee, returning %d",thisf); return thisf; } switch (possdependee->status) { case PKG_STAT_UNPACKED: case PKG_STAT_HALFCONFIGURED: case PKG_STAT_TRIGGERSAWAITED: case PKG_STAT_TRIGGERSPENDING: case PKG_STAT_INSTALLED: if (checkversion) { if (provider) { debug(dbg_depcondetail, " checking package %s provided by pkg %s", checkversion->ed->name, pkg_name(possdependee, pnaw_always)); if (!pkg_virtual_deppossi_satisfied(checkversion, provider)) { varbuf_printf(oemsgs, _(" Version of %s on system, provided by %s, is %s.\n"), checkversion->ed->name, pkg_name(possdependee, pnaw_always), versiondescribe(&provider->version, vdew_nonambig)); if (in_force(FORCE_DEPENDS_VERSION)) thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION); debug(dbg_depcondetail, " bad version"); goto unsuitable; } } else { debug(dbg_depcondetail, " checking non-provided pkg %s", pkg_name(possdependee, pnaw_always)); if (!versionsatisfied(&possdependee->installed, checkversion)) { varbuf_printf(oemsgs, _(" Version of %s on system is %s.\n"), pkg_name(possdependee, pnaw_nonambig), versiondescribe(&possdependee->installed.version, vdew_nonambig)); if (in_force(FORCE_DEPENDS_VERSION)) thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION); debug(dbg_depcondetail, " bad version"); goto unsuitable; } } } if (possdependee->status == PKG_STAT_INSTALLED || possdependee->status == PKG_STAT_TRIGGERSPENDING) { debug(dbg_depcondetail," is installed, ok and found"); return FOUND_OK; } if (possdependee->status == PKG_STAT_TRIGGERSAWAITED) { if (possdependee->trigaw.head == NULL) internerr("package %s in state %s, has no awaited triggers", pkg_name(possdependee, pnaw_always), pkg_status_name(possdependee)); if (removing || !(f_triggers || (possdependee->clientdata && possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW))) { if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " triggers-awaited, no fixbytrig"); goto unsuitable; } /* We don't check the status of trigaw.head->pend here, just in case * we get into the pathological situation where Triggers-Awaited but * the named package doesn't actually have any pending triggers. In * that case we queue the non-pending package for trigger processing * anyway, and that trigger processing will be a noop except for * sorting out all of the packages which name it in Triggers-Awaited. * * (This situation can only arise if modstatdb_note success in * clearing the triggers-pending status of the pending package * but then fails to go on to update the awaiters.) */ *fixbytrig = possdependee->trigaw.head->pend; debug(dbg_depcondetail, " triggers-awaited, fixbytrig '%s', defer", pkg_name(*fixbytrig, pnaw_always)); return FOUND_DEFER; } if (possdependee->clientdata && possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) { debug(dbg_depcondetail," unpacked/halfconfigured, defer"); return FOUND_DEFER; } else if (!removing && in_force(FORCE_CONFIGURE_ANY) && !skip_due_to_hold(possdependee) && !(possdependee->status == PKG_STAT_HALFCONFIGURED)) { notice(_("also configuring '%s' (required by '%s')"), pkg_name(possdependee, pnaw_nonambig), pkg_name(requiredby, pnaw_nonambig)); enqueue_package(possdependee); sincenothing = 0; return FOUND_DEFER; } else { if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not configured/able"); goto unsuitable; } default: if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not installed"); goto unsuitable; } unsuitable: debug(dbg_depcondetail, " returning %d", thisf); (*interestingwarnings)++; return thisf; }
/* * Return values: * 0: cannot be satisfied. * 1: defer: may be satisfied later, when other packages are better or * at higher dependtry due to --force * will set *fixbytrig to package whose trigger processing would help * if applicable (and leave it alone otherwise). * 2: not satisfied but forcing * (*interestingwarnings >= 0 on exit? caller is to print oemsgs). * 3: satisfied now. */ static enum found_status deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, struct pkginfo *removing, struct pkgset *providing, struct pkginfo **fixbytrig, bool *matched, struct deppossi *checkversion, int *interestingwarnings, struct varbuf *oemsgs) { enum found_status thisf; if (ignore_depends(possdependee)) { debug(dbg_depcondetail," ignoring depended package so ok and found"); return found_ok; } thisf = found_none; if (possdependee == removing) { if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig)); } *matched = true; debug(dbg_depcondetail," removing possdependee, returning %d",thisf); return thisf; } switch (possdependee->status) { case stat_unpacked: case stat_halfconfigured: case stat_triggersawaited: case stat_triggerspending: case stat_installed: if (checkversion && !versionsatisfied(&possdependee->installed,checkversion)) { varbuf_printf(oemsgs, _(" Version of %s on system is %s.\n"), pkg_name(possdependee, pnaw_nonambig), versiondescribe(&possdependee->installed.version, vdew_nonambig)); assert(checkversion->verrel != dpkg_relation_none); if (fc_dependsversion) thisf = (dependtry >= 3) ? found_forced : found_defer; debug(dbg_depcondetail," bad version, returning %d",thisf); (*interestingwarnings)++; return thisf; } if (possdependee->status == stat_installed || possdependee->status == stat_triggerspending) { debug(dbg_depcondetail," is installed, ok and found"); return found_ok; } if (possdependee->status == stat_triggersawaited) { assert(possdependee->trigaw.head); if (removing || !(f_triggers || possdependee->clientdata->istobe == itb_installnew)) { if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " triggers-awaited, no fixbytrig"); goto unsuitable; } /* We don't check the status of trigaw.head->pend here, just in case * we get into the pathological situation where Triggers-Awaited but * the named package doesn't actually have any pending triggers. In * that case we queue the non-pending package for trigger processing * anyway, and that trigger processing will be a noop except for * sorting out all of the packages which name it in Triggers-Awaited. * * (This situation can only arise if modstatdb_note success in * clearing the triggers-pending status of the pending package * but then fails to go on to update the awaiters.) */ *fixbytrig = possdependee->trigaw.head->pend; debug(dbg_depcondetail, " triggers-awaited, fixbytrig '%s', defer", pkg_name(*fixbytrig, pnaw_always)); return found_defer; } if (possdependee->clientdata && possdependee->clientdata->istobe == itb_installnew) { debug(dbg_depcondetail," unpacked/halfconfigured, defer"); return found_defer; } else if (!removing && fc_configureany && !skip_due_to_hold(possdependee) && !(possdependee->status == stat_halfconfigured)) { notice(_("also configuring '%s' (required by '%s')"), pkg_name(possdependee, pnaw_nonambig), pkg_name(requiredby, pnaw_nonambig)); enqueue_package(possdependee); sincenothing = 0; return found_defer; } else { if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not configured/able"); goto unsuitable; } default: if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not installed"); goto unsuitable; } unsuitable: debug(dbg_depcondetail, " returning %d", thisf); (*interestingwarnings)++; return thisf; }