diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/depcon.c | 15 | ||||
-rw-r--r-- | src/enquiry.c | 12 | ||||
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/packages.c | 97 |
5 files changed, 85 insertions, 44 deletions
diff --git a/src/depcon.c b/src/depcon.c index deedd5cbf..1f17c84d0 100644 --- a/src/depcon.c +++ b/src/depcon.c @@ -460,13 +460,13 @@ depisok(struct dependency *dep, struct varbuf *whynot, } deppossi_pkg_iter_free(possi_iter); - /* If there was no version specified we try looking for Providers. */ - if (possi->verrel == DPKG_RELATION_NONE) { /* See if the package we're about to install Provides it. */ for (provider = possi->ed->depended.available; provider; provider = provider->rev_next) { if (provider->up->type != dep_provides) continue; + if (!pkg_virtual_deppossi_satisfied(possi, provider)) + continue; if (provider->up->up->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) return true; } @@ -476,6 +476,8 @@ depisok(struct dependency *dep, struct varbuf *whynot, provider; provider = provider->rev_next) { if (provider->up->type != dep_provides) continue; + if (!pkg_virtual_deppossi_satisfied(possi, provider)) + continue; switch (provider->up->up->clientdata->istobe) { case PKG_ISTOBE_INSTALLNEW: @@ -519,7 +521,6 @@ depisok(struct dependency *dep, struct varbuf *whynot, sprintf(linebuf, _(" %.250s is not installed.\n"), possi->ed->name); varbuf_add_str(whynot, linebuf); } - } } return false; @@ -600,8 +601,6 @@ depisok(struct dependency *dep, struct varbuf *whynot, deppossi_pkg_iter_free(possi_iter); } - /* If there was no version specified we try looking for Providers. */ - if (possi->verrel == DPKG_RELATION_NONE) { /* See if the package we're about to install Provides it. */ for (provider = possi->ed->depended.available; provider; @@ -611,6 +610,8 @@ depisok(struct dependency *dep, struct varbuf *whynot, continue; if (provider->up->up->set == dep->up->set) continue; /* Conflicts and provides the same. */ + if (!pkg_virtual_deppossi_satisfied(possi, provider)) + continue; sprintf(linebuf, _(" %.250s provides %.250s and is to be installed.\n"), pkgbin_name(provider->up->up, &provider->up->up->available, pnaw_nonambig), possi->ed->name); @@ -630,6 +631,9 @@ depisok(struct dependency *dep, struct varbuf *whynot, if (provider->up->up->set == dep->up->set) continue; /* Conflicts and provides the same. */ + if (!pkg_virtual_deppossi_satisfied(possi, provider)) + continue; + switch (provider->up->up->clientdata->istobe) { case PKG_ISTOBE_INSTALLNEW: /* Don't pay any attention to the Provides field of the @@ -673,7 +677,6 @@ depisok(struct dependency *dep, struct varbuf *whynot, provider->up->up->clientdata->istobe); } } - } if (!nconflicts) return true; diff --git a/src/enquiry.c b/src/enquiry.c index f1597b002..e3f49cfbb 100644 --- a/src/enquiry.c +++ b/src/enquiry.c @@ -432,6 +432,14 @@ assertmultiarch(const char *const *argv) return assert_version_support(argv, &version, _("multi-arch")); } +int +assertverprovides(const char *const *argv) +{ + struct dpkg_version version = { 0, "1.17.11", NULL }; + + return assert_version_support(argv, &version, _("versioned Provides")); +} + /** * Print a single package which: * (a) is the target of one or more relevant predependencies. @@ -508,13 +516,13 @@ predeppackage(const char *const *argv) pkg = trypkg; break; } - if (possi->verrel != DPKG_RELATION_NONE) - continue; for (provider = possi->ed->depended.available; !pkg && provider; provider = provider->next) { if (provider->up->type != dep_provides) continue; + if (!pkg_virtual_deppossi_satisfied(possi, provider)) + continue; trypkg = provider->up->up; if (!trypkg->files) continue; diff --git a/src/main.c b/src/main.c index 73e746003..6e15f3fd3 100644 --- a/src/main.c +++ b/src/main.c @@ -126,7 +126,7 @@ usage(const struct cmdinfo *ci, const char *value) printf(_( "For internal use: dpkg --assert-support-predepends | --predep-package |\n" " --assert-working-epoch | --assert-long-filenames | --assert-multi-conrep |\n" -" --assert-multi-arch.\n" +" --assert-multi-arch | --assert-versioned-provides.\n" "\n")); printf(_( @@ -672,6 +672,7 @@ static const struct cmdinfo cmdinfos[]= { ACTION( "assert-long-filenames", 0, act_assertlongfilenames, assertlongfilenames ), ACTION( "assert-multi-conrep", 0, act_assertmulticonrep, assertmulticonrep ), ACTION( "assert-multi-arch", 0, act_assertmultiarch, assertmultiarch ), + ACTION( "assert-versioned-provides", 0, act_assertverprovides, assertverprovides ), ACTION( "add-architecture", 0, act_arch_add, arch_add ), ACTION( "remove-architecture", 0, act_arch_remove, arch_remove ), ACTION( "print-architecture", 0, act_printarch, printarch ), diff --git a/src/main.h b/src/main.h index 10014ef0e..5a35808ab 100644 --- a/src/main.h +++ b/src/main.h @@ -101,6 +101,7 @@ enum action { act_assertlongfilenames, act_assertmulticonrep, act_assertmultiarch, + act_assertverprovides, act_audit, act_unpackchk, @@ -165,6 +166,7 @@ int assertpredep(const char *const *argv); int assertlongfilenames(const char *const *argv); int assertmulticonrep(const char *const *argv); int assertmultiarch(const char *const *argv); +int assertverprovides(const char *const *argv); int predeppackage(const char *const *argv); int printarch(const char *const *argv); int printinstarch(const char *const *argv); diff --git a/src/packages.c b/src/packages.c index fed0a4893..597c0c572 100644 --- a/src/packages.c +++ b/src/packages.c @@ -328,7 +328,7 @@ enum found_status { */ static enum found_status deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, - struct pkginfo *removing, struct pkgset *providing, + struct pkginfo *removing, struct deppossi *provider, struct pkginfo **fixbytrig, bool *matched, struct deppossi *checkversion, int *interestingwarnings, struct varbuf *oemsgs) @@ -341,10 +341,11 @@ deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, } thisf = FOUND_NONE; if (possdependee == removing) { - if (providing) { + if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is to be removed.\n"), - pkg_name(possdependee, pnaw_nonambig), providing->name); + pkg_name(possdependee, pnaw_nonambig), + provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig)); @@ -360,17 +361,35 @@ deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, case PKG_STAT_TRIGGERSAWAITED: case PKG_STAT_TRIGGERSPENDING: case PKG_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 (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 (fc_dependsversion) + thisf = (dependtry >= 3) ? FOUND_FORCED : FOUND_DEFER; + 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 (fc_dependsversion) + thisf = (dependtry >= 3) ? FOUND_FORCED : FOUND_DEFER; + debug(dbg_depcondetail, " bad version"); + goto unsuitable; + } + } } if (possdependee->status == PKG_STAT_INSTALLED || possdependee->status == PKG_STAT_TRIGGERSPENDING) { @@ -382,10 +401,11 @@ deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, if (removing || !(f_triggers || possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW)) { - if (providing) { + if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s awaits trigger processing.\n"), - pkg_name(possdependee, pnaw_nonambig), providing->name); + pkg_name(possdependee, pnaw_nonambig), + provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s awaits trigger processing.\n"), @@ -424,10 +444,11 @@ deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, sincenothing = 0; return FOUND_DEFER; } else { - if (providing) { + if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not configured yet.\n"), - pkg_name(possdependee, pnaw_nonambig), providing->name); + pkg_name(possdependee, pnaw_nonambig), + provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig)); @@ -438,10 +459,11 @@ deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, } default: - if (providing) { + if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not installed.\n"), - pkg_name(possdependee, pnaw_nonambig), providing->name); + pkg_name(possdependee, pnaw_nonambig), + provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig)); @@ -461,13 +483,13 @@ unsuitable: static void breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok, struct deppossi *breaks, struct pkginfo *broken, - struct pkginfo *breaker, struct pkgset *virtbroken) + struct pkginfo *breaker, struct deppossi *virtbroken) { struct varbuf depmsg = VARBUF_INIT; debug(dbg_depcondetail, " checking breaker %s virtbroken %s", pkg_name(breaker, pnaw_always), - virtbroken ? virtbroken->name : "<none>"); + virtbroken ? virtbroken->ed->name : "<none>"); if (breaker->status == PKG_STAT_NOTINSTALLED || breaker->status == PKG_STAT_CONFIGFILES) @@ -479,7 +501,9 @@ breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok, if (!archsatisfied(&broken->installed, breaks)) return; if (ignore_depends(breaker)) return; - if (virtbroken && ignore_depends(&virtbroken->pkg)) + if (virtbroken && ignore_depends(&virtbroken->ed->pkg)) + return; + if (virtbroken && !pkg_virtual_deppossi_satisfied(breaks, virtbroken)) return; varbufdependency(&depmsg, breaks->up); @@ -494,7 +518,7 @@ breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok, varbuf_printf(aemsgs, _(" %s (%s) provides %s.\n"), pkg_name(broken, pnaw_nonambig), versiondescribe(&broken->installed.version, vdew_nonambig), - virtbroken->name); + virtbroken->ed->name); } else if (breaks->verrel != DPKG_RELATION_NONE) { varbuf_printf(aemsgs, _(" Version of %s to be configured is %s.\n"), pkg_name(broken, pnaw_nonambig), @@ -508,14 +532,12 @@ breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok, static void breaks_check_target(struct varbuf *aemsgs, enum dep_check *ok, struct pkginfo *broken, struct pkgset *target, - struct pkgset *virtbroken) + struct deppossi *virtbroken) { struct deppossi *possi; for (possi = target->depended.installed; possi; possi = possi->rev_next) { if (possi->up->type != dep_breaks) continue; - if (virtbroken && possi->verrel != DPKG_RELATION_NONE) - continue; breaks_check_one(aemsgs, ok, possi, broken, possi->up->up, virtbroken); } } @@ -524,7 +546,7 @@ enum dep_check breakses_ok(struct pkginfo *pkg, struct varbuf *aemsgs) { struct dependency *dep; - struct pkgset *virtbroken; + struct deppossi *virtbroken; enum dep_check ok = DEP_CHECK_OK; debug(dbg_depcon, " checking Breaks"); @@ -533,9 +555,9 @@ breakses_ok(struct pkginfo *pkg, struct varbuf *aemsgs) for (dep= pkg->installed.depends; dep; dep= dep->next) { if (dep->type != dep_provides) continue; - virtbroken = dep->list->ed; - debug(dbg_depcondetail, " checking virtbroken %s", virtbroken->name); - breaks_check_target(aemsgs, &ok, pkg, virtbroken, virtbroken); + virtbroken = dep->list; + debug(dbg_depcondetail, " checking virtbroken %s", virtbroken->ed->name); + breaks_check_target(aemsgs, &ok, pkg, virtbroken->ed, virtbroken); } return ok; } @@ -597,7 +619,7 @@ dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing, } deppossi_pkg_iter_free(possi_iter); - if (found != FOUND_OK && possi->verrel == DPKG_RELATION_NONE) { + if (found != FOUND_OK) { for (provider = possi->ed->depended.installed; found != FOUND_OK && provider; provider = provider->rev_next) { @@ -610,10 +632,15 @@ dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing, debug(dbg_depcondetail, " provider does not satisfy arch"); continue; } - thisf = deppossi_ok_found(provider->up->up, pkg, removing, - possi->ed, - &possfixbytrig, &matched, NULL, + 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; } |