diff options
author | Michael Vogt <mvo@debian.org> | 2013-10-22 16:53:32 +0200 |
---|---|---|
committer | Michael Vogt <mvo@debian.org> | 2013-10-22 16:53:32 +0200 |
commit | f62f17b489405432a3125e51471d8a00e78c5170 (patch) | |
tree | ce2a6e077cb0846e75cbb3d583f4152608100adb /apt-pkg/depcache.cc | |
parent | 9aa9db9c88fca3a9266427b0d5cc9ad53df7207e (diff) | |
parent | c08cf1dc784a98a253296a51433f6de7d16d3125 (diff) |
Merge branch 'debian/sid' into ubuntu/master
Conflicts:
cmdline/apt-key
configure.ac
debian/apt.auto-removal.sh
debian/changelog
debian/control
debian/rules
po/apt-all.pot
po/ar.po
po/ast.po
po/bg.po
po/bs.po
po/ca.po
po/cs.po
po/cy.po
po/da.po
po/de.po
po/dz.po
po/el.po
po/es.po
po/eu.po
po/fi.po
po/fr.po
po/gl.po
po/hu.po
po/it.po
po/ja.po
po/km.po
po/ko.po
po/ku.po
po/lt.po
po/mr.po
po/nb.po
po/ne.po
po/nl.po
po/nn.po
po/pl.po
po/pt.po
po/pt_BR.po
po/ro.po
po/ru.po
po/sk.po
po/sl.po
po/sv.po
po/th.po
po/tl.po
po/uk.po
po/vi.po
po/zh_CN.po
po/zh_TW.po
Diffstat (limited to 'apt-pkg/depcache.cc')
-rw-r--r-- | apt-pkg/depcache.cc | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 08c1bd809..a06789cdf 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -865,6 +865,11 @@ bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge, unsigned long Depth, bool FromUser) { + return IsDeleteOkProtectInstallRequests(Pkg, rPurge, Depth, FromUser); +} +bool pkgDepCache::IsDeleteOkProtectInstallRequests(PkgIterator const &Pkg, + bool const rPurge, unsigned long const Depth, bool const FromUser) +{ if (FromUser == false && Pkg->CurrentVer == 0) { StateCache &P = PkgState[Pkg->ID]; @@ -891,6 +896,7 @@ char const* PrintMode(char const mode) case pkgDepCache::ModeInstall: return "Install"; case pkgDepCache::ModeKeep: return "Keep"; case pkgDepCache::ModeDelete: return "Delete"; + case pkgDepCache::ModeGarbage: return "Garbage"; default: return "UNKNOWN"; } } @@ -1047,9 +1053,10 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, return true; } - // check if we are allowed to install the package - if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false) - return false; + // check if we are allowed to install the package (if we haven't already) + if (P.Mode != ModeInstall || P.InstallVer != P.CandidateVer) + if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false) + return false; ActionGroup group(*this); P.iFlags &= ~AutoKept; @@ -1271,11 +1278,50 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, /*}}}*/ // DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/ // --------------------------------------------------------------------- -/* The default implementation does nothing. +/* The default implementation checks if the installation of an M-A:same + package would lead us into a version-screw and if so forbids it. dpkg holds are enforced by the private IsModeChangeOk */ bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst, unsigned long Depth, bool FromUser) { + return IsInstallOkMultiArchSameVersionSynced(Pkg,AutoInst, Depth, FromUser); +} +bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, + bool const AutoInst, unsigned long const Depth, bool const FromUser) +{ + if (FromUser == true) // as always: user is always right + return true; + + // ignore packages with none-M-A:same candidates + VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this); + if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer() || + (CandVer->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same) + return true; + + GrpIterator const Grp = Pkg.Group(); + for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P)) + { + // not installed or version synced: fine by definition + // (simple string-compare as stuff like '1' == '0:1-0' can't happen here) + if (P->CurrentVer == 0 || strcmp(Pkg.CandVersion(), P.CandVersion()) == 0) + continue; + // packages loosing M-A:same can be out-of-sync + VerIterator CV = PkgState[P->ID].CandidateVerIter(*this); + if (unlikely(CV.end() == true) || + (CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same) + continue; + + // not downloadable means the package is obsolete, so allow out-of-sync + if (CV.Downloadable() == false) + continue; + + PkgState[Pkg->ID].iFlags |= AutoKept; + if (unlikely(DebugMarker == true)) + std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << Pkg + << " as its M-A:same siblings are not version-synced" << std::endl; + return false; + } + return true; } /*}}}*/ @@ -1681,8 +1727,6 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) follow_recommends = MarkFollowsRecommends(); follow_suggests = MarkFollowsSuggests(); - - // do the mark part, this is the core bit of the algorithm for(PkgIterator p = PkgBegin(); !p.end(); ++p) { @@ -1693,7 +1737,9 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) // be nice even then a required package violates the policy (#583517) // and do the full mark process also for required packages (p.CurrentVer().end() != true && - p.CurrentVer()->Priority == pkgCache::State::Required)) + p.CurrentVer()->Priority == pkgCache::State::Required) || + // packages which can't be changed (like holds) can't be garbage + (IsModeChangeOk(ModeGarbage, p, 0, false) == false)) { // the package is installed (and set to keep) if(PkgState[p->ID].Keep() && !p.CurrentVer().end()) |