summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/depcon.c15
-rw-r--r--src/enquiry.c12
-rw-r--r--src/main.c3
-rw-r--r--src/main.h2
-rw-r--r--src/packages.c97
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;
}