As part of multiarch, we enforce architecture affinity of package relationships: - unqualified Depends/Pre-Depends/Recommends/Suggests are only satisfied by a package of a different architecture if the target package is Multi-Arch: foreign - Depends/Pre-Depends/Recommends/Suggests on pkg:any are satisfied by a package of a different architecture if the target package is Multi-Arch: allowed - all other Depends/Pre-Depends/Recommends/Suggests are only satisfied by packages of the same architecture - Architecture: all packages are treated the same as packages of the native architecture - Conflicts/Replaces/Breaks are assumed to apply to packages of any arch --- lib/dpkg/dpkg-db.h | 2 ++ lib/dpkg/vercmp.c | 24 ++++++++++++++++++++++++ src/archives.c | 1 + src/depcon.c | 37 +++++++++++++++++++++++++++++-------- src/enquiry.c | 4 +++- src/packages.c | 11 +++++++++++ 6 files changed, 70 insertions(+), 9 deletions(-) diff --git a/lib/dpkg/dpkg-db.h b/lib/dpkg/dpkg-db.h index 3f31512..93b7061 100644 --- a/lib/dpkg/dpkg-db.h +++ b/lib/dpkg/dpkg-db.h @@ -443,6 +443,8 @@ void varbufdependency(struct varbuf *vb, struct dependency *dep); /*** from vercmp.c ***/ +int archsatisfied(struct pkginfoperfile *it, struct deppossi *against, + const char *architecture); int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against); int versionsatisfied3(const struct versionrevision *it, const struct versionrevision *ref, diff --git a/lib/dpkg/vercmp.c b/lib/dpkg/vercmp.c index da8fb3e..67076ba 100644 --- a/lib/dpkg/vercmp.c +++ b/lib/dpkg/vercmp.c @@ -3,6 +3,7 @@ * vercmp.c - comparison of version numbers * * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk> + * Copyright © 2009 Canonical Ltd. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -97,3 +98,26 @@ int versionsatisfied3(const struct versionrevision *it, int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) { return versionsatisfied3(&it->version,&against->version,against->verrel); } + +int +archsatisfied(struct pkginfoperfile *it, struct deppossi *against, + const char *architecture) +{ + const char *srcarch, *tgtarch; + + if (it->multiarch == multiarch_foreign) + return 1; + + srcarch = against->arch; + if (strcmp(srcarch, "any") == 0 && it->multiarch == multiarch_allowed) + return 1; + + if (strcmp(srcarch, "all") == 0) + srcarch = architecture; + + tgtarch = it->architecture; + if (strcmp(tgtarch, "all") == 0) + tgtarch = architecture; + + return (strcmp(srcarch, tgtarch) == 0); +} diff --git a/src/archives.c b/src/archives.c index 2a5765b..3957f05 100644 --- a/src/archives.c +++ b/src/archives.c @@ -282,6 +282,7 @@ static int does_replace(struct pkginfo *newpigp, debug(dbg_depcondetail,"does_replace ... found old, version %s", versiondescribe(&dep->list->version,vdew_always)); if (!versionsatisfied(&oldpigp->installed,dep->list)) continue; + if (!archsatisfied(&oldpigp->installed, dep->list, architecture)) continue; debug(dbg_depcon,"does_replace ... yes"); return 1; } diff --git a/src/depcon.c b/src/depcon.c index f109384..26520b3 100644 --- a/src/depcon.c +++ b/src/depcon.c @@ -281,19 +281,33 @@ int depisok(struct dependency *dep, struct varbuf *whynot, sprintf(linebuf,_(" %.250s is to be deconfigured.\n"),possi->ed->name); break; case itb_installnew: - if (versionsatisfied(&possi->ed->available,possi)) return 1; - sprintf(linebuf,_(" %.250s is to be installed, but is version %.250s.\n"), - possi->ed->name, - versiondescribe(&possi->ed->available.version,vdew_nonambig)); + if (versionsatisfied(&possi->ed->available,possi)) { + if (archsatisfied(&possi->ed->available, possi, architecture)) + return 1; + sprintf(linebuf,_(" %.250s is to be installed, but is architecture %.250s.\n"), + possi->ed->name, + possi->ed->available.architecture); + } else { + sprintf(linebuf,_(" %.250s is to be installed, but is version %.250s.\n"), + possi->ed->name, + versiondescribe(&possi->ed->available.version,vdew_nonambig)); + } break; case itb_normal: case itb_preinstall: switch (possi->ed->status) { case stat_installed: case stat_triggerspending: - if (versionsatisfied(&possi->ed->installed,possi)) return 1; - sprintf(linebuf,_(" %.250s is installed, but is version %.250s.\n"), - possi->ed->name, - versiondescribe(&possi->ed->installed.version,vdew_nonambig)); + if (versionsatisfied(&possi->ed->installed,possi)) { + if (archsatisfied(&possi->ed->installed, possi, architecture)) + return 1; + sprintf(linebuf,_(" %.250s is installed, but is architecture %.250s.\n"), + possi->ed->name, + possi->ed->installed.architecture); + } else { + sprintf(linebuf,_(" %.250s is installed, but is version %.250s.\n"), + possi->ed->name, + versiondescribe(&possi->ed->installed.version,vdew_nonambig)); + } break; case stat_notinstalled: /* Don't say anything about this yet - it might be a virtual package. @@ -315,6 +329,13 @@ int depisok(struct dependency *dep, struct varbuf *whynot, possi->ed->name, versiondescribe(&possi->ed->available.version,vdew_nonambig)); break; + } else if (!archsatisfied(&possi->ed->installed, possi, + architecture)) + { + sprintf(linebuf,_(" %.250s is unpacked, but is architecture %.250s.\n"), + possi->ed->name, + possi->ed->installed.architecture); + break; } else if (!versionsatisfied3(&possi->ed->configversion, &possi->version,possi->verrel)) { sprintf(linebuf, _(" %.250s latest configured version is %.250s.\n"), diff --git a/src/enquiry.c b/src/enquiry.c index 02ede15..f5b359f 100644 --- a/src/enquiry.c +++ b/src/enquiry.c @@ -344,7 +344,9 @@ void predeppackage(const char *const *argv) { possi=possi->next) { trypkg= possi->ed; if (!trypkg->available.valid) continue; - if (trypkg->files && versionsatisfied(&trypkg->available,possi)) { + if (trypkg->files && versionsatisfied(&trypkg->available, possi) && + archsatisfied(&trypkg->available, possi, architecture)) + { if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; } } if (possi->verrel != dvr_none) continue; diff --git a/src/packages.c b/src/packages.c index b176581..c677b60 100644 --- a/src/packages.c +++ b/src/packages.c @@ -369,6 +369,16 @@ static int deppossi_ok_found(struct pkginfo *possdependee, (*interestingwarnings)++; return thisf; } + if (checkversion && !archsatisfied(&possdependee->installed, checkversion, + architecture)) + { + varbufprintf(oemsgs, _(" Architecture of %s on system is %s.\n"), + possdependee->name, checkversion->arch); + if (fc_depends || fc_dependsversion) thisf= (dependtry >= 3) ? 2 : 1; + debug(dbg_depcondetail," bad architecture, returning %d",thisf); + (*interestingwarnings)++; + return thisf; + } if (possdependee->status == stat_installed || possdependee->status == stat_triggerspending) { debug(dbg_depcondetail," is installed, ok and found"); @@ -470,6 +480,7 @@ static void breaks_check_one(struct varbuf *aemsgs, int *ok, breaker->status == stat_configfiles) return; if (broken == breaker) return; if (!versionsatisfied(&broken->installed, breaks)) return; + if (!archsatisfied(&broken->installed, breaks, architecture)) return; if (ignore_depends(breaker)) return; if (virtbroken && ignore_depends(virtbroken)) return; -- 1.6.3.3 -- Steve Langasek Give me a lever long enough and a Free OS Debian Developer to set it on, and I can move the world. Ubuntu Developer http://www.debian.org/ slangasek@ubuntu.com vorlon@debian.org
Attachment:
signature.asc
Description: Digital signature