diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/algorithms.cc | 49 | ||||
-rw-r--r-- | apt-pkg/contrib/gpgv.cc | 3 | ||||
-rw-r--r-- | apt-pkg/contrib/srvrec.cc | 17 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.cc | 2 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 11 | ||||
-rw-r--r-- | apt-pkg/deb/debsystem.cc | 7 | ||||
-rw-r--r-- | apt-pkg/deb/debsystem.h | 1 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 14 | ||||
-rw-r--r-- | apt-pkg/depcache.cc | 196 | ||||
-rw-r--r-- | apt-pkg/depcache.h | 3 | ||||
-rw-r--r-- | apt-pkg/edsp.cc | 28 | ||||
-rw-r--r-- | apt-pkg/tagfile-keys.list | 1 | ||||
-rw-r--r-- | apt-pkg/tagfile-order.c | 3 |
13 files changed, 216 insertions, 119 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index cba772d41..cd09a6944 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -517,18 +517,37 @@ void pkgProblemResolver::MakeScores() Score += PrioInstalledAndNotObsolete; // propagate score points along dependencies - for (pkgCache::DepIterator D = InstVer.DependsList(); D.end() == false; ++D) + for (pkgCache::DepIterator D = InstVer.DependsList(); not D.end(); ++D) { if (DepMap[D->Type] == 0) continue; pkgCache::PkgIterator const T = D.TargetPkg(); - if (D->Version != 0) + if (not D.IsIgnorable(T)) { - pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache); - if (IV.end() == true || D.IsSatisfied(IV) == false) + if (D->Version != 0) + { + pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache); + if (IV.end() || not D.IsSatisfied(IV)) + continue; + } + Scores[T->ID] += DepMap[D->Type]; + } + + std::vector<map_id_t> providers; + for (auto Prv = T.ProvidesList(); not Prv.end(); ++Prv) + { + if (D.IsIgnorable(Prv)) + continue; + auto const PV = Prv.OwnerVer(); + auto const PP = PV.ParentPkg(); + if (PV != Cache[PP].InstVerIter(Cache) || not D.IsSatisfied(Prv)) continue; + providers.push_back(PP->ID); } - Scores[T->ID] += DepMap[D->Type]; + std::sort(providers.begin(), providers.end()); + providers.erase(std::unique(providers.begin(), providers.end()), providers.end()); + for (auto const prv : providers) + Scores[prv] += DepMap[D->Type]; } } @@ -564,13 +583,25 @@ void pkgProblemResolver::MakeScores() provide important packages extremely important */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { - for (pkgCache::PrvIterator P = I.ProvidesList(); P.end() == false; ++P) + auto const transfer = abs(Scores[I->ID] - OldScores[I->ID]); + if (transfer == 0) + continue; + + std::vector<map_id_t> providers; + for (auto Prv = I.ProvidesList(); not Prv.end(); ++Prv) { - // Only do it once per package - if ((pkgCache::Version *)P.OwnerVer() != Cache[P.OwnerPkg()].InstallVer) + if (Prv.IsMultiArchImplicit()) + continue; + auto const PV = Prv.OwnerVer(); + auto const PP = PV.ParentPkg(); + if (PV != Cache[PP].InstVerIter(Cache)) continue; - Scores[P.OwnerPkg()->ID] += abs(Scores[I->ID] - OldScores[I->ID]); + providers.push_back(PP->ID); } + std::sort(providers.begin(), providers.end()); + providers.erase(std::unique(providers.begin(), providers.end()), providers.end()); + for (auto const prv : providers) + Scores[prv] += transfer; } /* Protected things are pushed really high up. This number should put them diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index d956eaf00..28f3150c3 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -251,6 +251,9 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, setenv("APT_CONFIG", conf.get(), 1); } + // Tell apt-key not to emit warnings + setenv("APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE", "1", 1); + if (releaseSignature == DETACHED) { auto detached = make_unique_FILE(FileGPG, "r"); diff --git a/apt-pkg/contrib/srvrec.cc b/apt-pkg/contrib/srvrec.cc index 7d9bf116e..4ca208273 100644 --- a/apt-pkg/contrib/srvrec.cc +++ b/apt-pkg/contrib/srvrec.cc @@ -137,17 +137,12 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result) // sort them by priority std::stable_sort(Result.begin(), Result.end()); - for(std::vector<SrvRec>::iterator I = Result.begin(); - I != Result.end(); ++I) - { - if (_config->FindB("Debug::Acquire::SrvRecs", false) == true) - { - std::cerr << "SrvRecs: got " << I->target - << " prio: " << I->priority - << " weight: " << I->weight - << std::endl; - } - } + if (_config->FindB("Debug::Acquire::SrvRecs", false)) + for(auto const &R : Result) + std::cerr << "SrvRecs: got " << R.target + << " prio: " << R.priority + << " weight: " << R.weight + << '\n'; return true; } diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 972472986..bd4856526 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1771,7 +1771,7 @@ URI::operator string() { // FIXME: Technically userinfo is permitted even less // characters than these, but this is not conveniently - // expressed with a blacklist. + // expressed with a denylist. Res << QuoteString(User, ":/?#[]@"); if (Password.empty() == false) Res << ":" << QuoteString(Password, ":/?#[]@"); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index ab957a01a..240946529 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -318,6 +318,8 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, return false; if (Section.FindFlag(pkgTagSection::Key::Important,Pkg->Flags,pkgCache::Flag::Important) == false) return false; + if (Section.FindFlag(pkgTagSection::Key::Protected, Pkg->Flags, pkgCache::Flag::Important) == false) + return false; if (std::find(forceEssential.begin(), forceEssential.end(), Pkg.Name()) != forceEssential.end()) { @@ -1018,12 +1020,11 @@ debDebFileParser::debDebFileParser(FileFd *File, std::string const &DebFile) bool debDebFileParser::UsePackage(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver) { - bool res = debListParser::UsePackage(Pkg, Ver); - // we use the full file path as a provides so that the file is found - // by its name - if(NewProvides(Ver, DebFile, Pkg.Cache()->NativeArch(), Ver.VerStr(), 0) == false) + if (not debListParser::UsePackage(Pkg, Ver)) return false; - return res; + // we use the full file path as a provides so that the file is found by its name + // using the MultiArchImplicit flag for this is a bit of a stretch + return NewProvides(Ver, DebFile, Pkg.Cache()->NativeArch(), Ver.VerStr(), pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific); } debListParser::~debListParser() {} diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 7d4bf7213..eac43c3b7 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -466,8 +466,13 @@ pid_t debSystem::ExecDpkg(std::vector<std::string> const &sArgs, int * const inp /*}}}*/ bool debSystem::MultiArchSupported() const /*{{{*/ { + return AssertFeature("multi-arch"); +} + /*}}}*/ +bool debSystem::AssertFeature(std::string const &feature) /*{{{*/ +{ std::vector<std::string> Args = GetDpkgBaseCommand(); - Args.push_back("--assert-multi-arch"); + Args.push_back("--assert-" + feature); pid_t const dpkgAssertMultiArch = ExecDpkg(Args, nullptr, nullptr, true); if (dpkgAssertMultiArch > 0) { diff --git a/apt-pkg/deb/debsystem.h b/apt-pkg/deb/debsystem.h index 2e5a8550c..b3d241512 100644 --- a/apt-pkg/deb/debsystem.h +++ b/apt-pkg/deb/debsystem.h @@ -45,6 +45,7 @@ class debSystem : public pkgSystem APT_HIDDEN static void DpkgChrootDirectory(); APT_HIDDEN static pid_t ExecDpkg(std::vector<std::string> const &sArgs, int * const inputFd, int * const outputFd, bool const DiscardOutput); bool MultiArchSupported() const override; + static bool AssertFeature(std::string const &Feature); std::vector<std::string> ArchitecturesSupported() const override; bool LockInner(OpProgress *const Progress, int timeoutSec) override; diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index ef73881c8..c496538cc 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1416,6 +1416,15 @@ static bool ItemIsEssential(pkgDPkgPM::Item const &I) return true; return (I.Pkg->Flags & pkgCache::Flag::Essential) != 0; } +static bool ItemIsProtected(pkgDPkgPM::Item const &I) +{ + static auto const cachegen = _config->Find("pkgCacheGen::Protected"); + if (cachegen == "none" || cachegen == "native") + return true; + if (unlikely(I.Pkg.end())) + return true; + return (I.Pkg->Flags & pkgCache::Flag::Important) != 0; +} bool pkgDPkgPM::ExpandPendingCalls(std::vector<Item> &List, pkgDepCache &Cache) { { @@ -1712,6 +1721,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) OpenLog(); bool dpkgMultiArch = _system->MultiArchSupported(); + bool dpkgProtectedField = debSystem::AssertFeature("protected-field"); // start pty magic before the loop StartPtyMagic(); @@ -1780,6 +1790,10 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) { ADDARGC("--force-remove-essential"); } + if (dpkgProtectedField && std::any_of(I, J, ItemIsProtected)) + { + ADDARGC("--force-remove-protected"); + } ADDARGC("--remove"); break; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index f90a41e22..c7ef7a400 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -839,13 +839,73 @@ void pkgDepCache::Update(PkgIterator const &Pkg) Update(P.ParentPkg().RevDependsList()); } /*}}}*/ +// DepCache::IsModeChangeOk - check if it is ok to change the mode /*{{{*/ +// --------------------------------------------------------------------- +/* this is used by all Mark methods on the very first line to check sanity + and prevents mode changes for packages on hold for example. + If you want to check Mode specific stuff you can use the virtual public + Is<Mode>Ok methods instead */ +static char const* PrintMode(char const mode) +{ + switch (mode) + { + case pkgDepCache::ModeInstall: return "Install"; + case pkgDepCache::ModeKeep: return "Keep"; + case pkgDepCache::ModeDelete: return "Delete"; + case pkgDepCache::ModeGarbage: return "Garbage"; + default: return "UNKNOWN"; + } +} +static bool IsModeChangeOk(pkgDepCache &Cache, pkgDepCache::ModeList const mode, pkgCache::PkgIterator const &Pkg, + unsigned long const Depth, bool const FromUser, bool const DebugMarker) +{ + // we are not trying to hard… + if (unlikely(Depth > 100)) + return false; + + // general sanity + if (unlikely(Pkg.end() == true || Pkg->VersionList == 0)) + return false; + + // the user is always right + if (FromUser == true) + return true; + + auto &P = Cache[Pkg]; + // not changing the mode is obviously also fine as we might want to call + // e.g. MarkInstall multiple times with different arguments for the same package + if (P.Mode == mode) + return true; + + // if previous state was set by user only user can reset it + if ((P.iFlags & pkgDepCache::Protected) == pkgDepCache::Protected) + { + if (unlikely(DebugMarker == true)) + std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode) + << " of " << APT::PrettyPkg(&Cache, Pkg) << " as its mode (" << PrintMode(P.Mode) + << ") is protected" << std::endl; + return false; + } + // enforce dpkg holds + else if (mode != pkgDepCache::ModeKeep && Pkg->SelectedState == pkgCache::State::Hold && + _config->FindB("APT::Ignore-Hold",false) == false) + { + if (unlikely(DebugMarker == true)) + std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode) + << " of " << APT::PrettyPkg(&Cache, Pkg) << std::endl; + return false; + } + + return true; +} + /*}}}*/ // DepCache::MarkKeep - Put the package in the keep state /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, unsigned long Depth) { - if (IsModeChangeOk(ModeKeep, Pkg, Depth, FromUser) == false) + if (not IsModeChangeOk(*this, ModeKeep, Pkg, Depth, FromUser, DebugMarker)) return false; /* Reject an attempt to keep a non-source broken installed package, those @@ -905,7 +965,7 @@ bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, unsigned long Depth, bool FromUser) { - if (IsModeChangeOk(ModeDelete, Pkg, Depth, FromUser) == false) + if (not IsModeChangeOk(*this, ModeDelete, Pkg, Depth, FromUser, DebugMarker)) return false; StateCache &P = PkgState[Pkg->ID]; @@ -1004,66 +1064,6 @@ bool pkgDepCache::IsDeleteOkProtectInstallRequests(PkgIterator const &Pkg, return true; } /*}}}*/ -// DepCache::IsModeChangeOk - check if it is ok to change the mode /*{{{*/ -// --------------------------------------------------------------------- -/* this is used by all Mark methods on the very first line to check sanity - and prevents mode changes for packages on hold for example. - If you want to check Mode specific stuff you can use the virtual public - Is<Mode>Ok methods instead */ -static char const* PrintMode(char const mode) -{ - switch (mode) - { - case pkgDepCache::ModeInstall: return "Install"; - case pkgDepCache::ModeKeep: return "Keep"; - case pkgDepCache::ModeDelete: return "Delete"; - case pkgDepCache::ModeGarbage: return "Garbage"; - default: return "UNKNOWN"; - } -} -bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg, - unsigned long const Depth, bool const FromUser) -{ - // we are not trying to hard… - if (unlikely(Depth > 100)) - return false; - - // general sanity - if (unlikely(Pkg.end() == true || Pkg->VersionList == 0)) - return false; - - // the user is always right - if (FromUser == true) - return true; - - StateCache &P = PkgState[Pkg->ID]; - // not changing the mode is obviously also fine as we might want to call - // e.g. MarkInstall multiple times with different arguments for the same package - if (P.Mode == mode) - return true; - - // if previous state was set by user only user can reset it - if ((P.iFlags & Protected) == Protected) - { - if (unlikely(DebugMarker == true)) - std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode) - << " of " << APT::PrettyPkg(this, Pkg) << " as its mode (" << PrintMode(P.Mode) - << ") is protected" << std::endl; - return false; - } - // enforce dpkg holds - else if (mode != ModeKeep && Pkg->SelectedState == pkgCache::State::Hold && - _config->FindB("APT::Ignore-Hold",false) == false) - { - if (unlikely(DebugMarker == true)) - std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode) - << " of " << APT::PrettyPkg(this, Pkg) << std::endl; - return false; - } - - return true; -} - /*}}}*/ struct CompareProviders /*{{{*/ { pkgDepCache const &Cache; @@ -1279,32 +1279,55 @@ static APT::VersionVector getAllPossibleSolutions(pkgDepCache &Cache, pkgCache:: toNewInstall.emplace_back(std::move(Ver)); } } while (Start++ != End); - std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade)); + if (toUpgrade.empty()) + toUpgrade = std::move(toNewInstall); + else + std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade)); + if (not sorted) std::sort(toUpgrade.begin(), toUpgrade.end(), [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) { return A->ID < B->ID; }); toUpgrade.erase(std::unique(toUpgrade.begin(), toUpgrade.end()), toUpgrade.end()); + + if (not End.IsNegative()) + toUpgrade.erase(std::remove_if(toUpgrade.begin(), toUpgrade.end(), [&Cache](pkgCache::VerIterator const &V) { + auto const P = V.ParentPkg(); + auto const &State = Cache[P]; + return State.Protect() && (State.Delete() || (State.Keep() && P->CurrentVer == 0)); + }), + toUpgrade.end()); + return toUpgrade; } /*}}}*/ -static bool MarkInstall_MarkDeleteForNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long const Depth, pkgCache::PkgIterator const &Pkg, bool const propagateProctected)/*{{{*/ +static bool MarkInstall_MarkDeleteForNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long const Depth, pkgCache::PkgIterator const &Pkg, bool const propagateProctected, APT::PackageVector &delayedRemove)/*{{{*/ { auto &State = Cache[Pkg]; - if (not State.Delete()) + if (not propagateProctected) { + if (State.Delete()) + return true; if(DebugAutoInstall) - std::clog << OutputInDepth(Depth) << " Removing: " << Pkg.Name() << " as upgrade is not an option for " << PV.ParentPkg().FullName() << " (" << PV.VerStr() << ")\n"; - if (not Cache.MarkDelete(Pkg, false, Depth + 1, false)) + std::clog << OutputInDepth(Depth) << " Delayed Removing: " << Pkg.FullName() << " as upgrade is not an option for " << PV.ParentPkg().FullName() << " (" << PV.VerStr() << ")\n"; + if (not IsModeChangeOk(Cache, pkgDepCache::ModeDelete, Pkg, Depth, false, DebugAutoInstall) || + not Cache.IsDeleteOk(Pkg, false, Depth, false)) return false; + delayedRemove.push_back(Pkg); + return true; } - if (propagateProctected) + + if (not State.Delete()) { - MarkInstall_DiscardCandidate(Cache, Pkg); - Cache.MarkProtected(Pkg); + if(DebugAutoInstall) + std::clog << OutputInDepth(Depth) << " Removing: " << Pkg.FullName() << " as upgrade is not an option for " << PV.ParentPkg().FullName() << " (" << PV.VerStr() << ")\n"; + if (not Cache.MarkDelete(Pkg, false, Depth + 1, false)) + return false; } + MarkInstall_DiscardCandidate(Cache, Pkg); + Cache.MarkProtected(Pkg); return true; } /*}}}*/ -static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long Depth, std::vector<pkgCache::DepIterator> &toRemove, APT::PackageVector &toUpgrade, bool const propagateProctected, bool const FromUser) /*{{{*/ +static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long Depth, std::vector<pkgCache::DepIterator> &toRemove, APT::PackageVector &toUpgrade, APT::PackageVector &delayedRemove, bool const propagateProctected, bool const FromUser) /*{{{*/ { /* Negative dependencies have no or-group If the candidate is effected try to keep current and discard candidate @@ -1336,7 +1359,7 @@ static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool else badCandidate.push_back(Pkg); } - else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected)) + else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected, delayedRemove)) { failedToRemoveSomething = true; if (not propagateProctected && not FromUser) @@ -1352,7 +1375,9 @@ static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool if (State.CandidateVer != Ver && State.CandidateVer != nullptr && std::find(badCandidate.cbegin(), badCandidate.cend(), Pkg) == badCandidate.end()) toUpgrade.push_back(Pkg); - else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected)) + else if (State.CandidateVer == Pkg.CurrentVer()) + ; // already done in the first loop above + else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected, delayedRemove)) { failedToRemoveSomething = true; if (not propagateProctected && not FromUser) @@ -1510,10 +1535,12 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst, unsigned long Depth, bool FromUser, bool ForceImportantDeps) { - if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false) + StateCache &P = PkgState[Pkg->ID]; + if (P.Protect() && P.Keep() && P.CandidateVer != nullptr && P.CandidateVer == Pkg.CurrentVer()) + ; // we are here to mark our dependencies as protected, no state is changed + else if (not IsModeChangeOk(*this, ModeInstall, Pkg, Depth, FromUser, DebugMarker)) return false; - StateCache &P = PkgState[Pkg->ID]; // See if there is even any possible installation candidate if (P.CandidateVer == 0) @@ -1545,7 +1572,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst, bool hasFailed = false; std::vector<pkgCache::DepIterator> toInstall, toRemove; - APT::PackageVector toUpgrade; + APT::PackageVector toUpgrade, delayedRemove; if (AutoSolve) { VerIterator const PV = P.CandidateVerIter(*this); @@ -1554,7 +1581,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst, if (not MarkInstall_CollectDependencies(*this, PV, toInstall, toRemove)) return false; - if (not MarkInstall_RemoveConflictsIfNotUpgradeable(*this, DebugAutoInstall, PV, Depth, toRemove, toUpgrade, P.Protect(), FromUser)) + if (not MarkInstall_RemoveConflictsIfNotUpgradeable(*this, DebugAutoInstall, PV, Depth, toRemove, toUpgrade, delayedRemove, P.Protect(), FromUser)) { if (failEarly) return false; @@ -1628,6 +1655,19 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst, hasFailed = true; } + for (auto const &R : delayedRemove) + { + if (not MarkDelete(R, false, Depth, false)) + { + if (failEarly) + { + MarkInstall_DiscardInstall(Pkg); + return false; + } + hasFailed = true; + } + } + if (MoveAutoBitToDependencies) { if (DebugAutoInstall) @@ -2183,7 +2223,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) reason = "Required"; else if (userFunc.InRootSet(P)) reason = "Blacklisted [APT::NeverAutoRemove]"; - else if (IsModeChangeOk(ModeGarbage, P, 0, false) == false) + else if (not IsModeChangeOk(*this, ModeGarbage, P, 0, false, DebugMarker)) reason = "Hold"; else continue; diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index d9bb69a18..78f88ba2f 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -518,9 +518,6 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace private: void * const d; - APT_HIDDEN bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg, - unsigned long const Depth, bool const FromUser); - APT_HIDDEN bool MarkInstall_StateChange(PkgIterator const &Pkg, bool AutoInst, bool FromUser); APT_HIDDEN bool MarkInstall_DiscardInstall(PkgIterator const &Pkg); diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 3f8534234..7e3993be4 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -29,8 +29,10 @@ #include <sys/stat.h> #include <unistd.h> +#include <algorithm> #include <array> #include <limits> +#include <sstream> #include <string> #include <apti18n.h> @@ -119,19 +121,25 @@ static bool WriteScenarioDependency(FileFd &output, pkgCache::VerIterator const for (size_t i = 1; i < dependencies.size(); ++i) if (dependencies[i].empty() == false) WriteOkay(Okay, output, "\n", DepMap[i], ": ", dependencies[i]); - string provides; - for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv) + std::vector<std::string> provides; + for (auto Prv = Ver.ProvidesList(); not Prv.end(); ++Prv) { - if (Prv.IsMultiArchImplicit() == true) + if (Prv.IsMultiArchImplicit()) continue; - if (provides.empty() == false) - provides.append(", "); - provides.append(Prv.Name()); + std::string provide = Prv.Name(); if (Prv->ProvideVersion != 0) - provides.append(" (= ").append(Prv.ProvideVersion()).append(")"); + provide.append(" (= ").append(Prv.ProvideVersion()).append(")"); + if ((Ver->MultiArch & pkgCache::Version::Foreign) != 0 && std::find(provides.cbegin(), provides.cend(), provide) != provides.cend()) + continue; + provides.emplace_back(std::move(provide)); + } + if (not provides.empty()) + { + std::ostringstream out; + std::copy(provides.begin(), provides.end() - 1, std::ostream_iterator<std::string>(out, ", ")); + out << provides.back(); + WriteOkay(Okay, output, "\nProvides: ", out.str()); } - if (provides.empty() == false) - WriteOkay(Okay, output, "\nProvides: ", provides); return WriteOkay(Okay, output, "\n"); } /*}}}*/ @@ -262,7 +270,7 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progres for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false && likely(Okay); ++Pkg) { std::string const arch = Pkg.Arch(); - if (std::find(archs.begin(), archs.end(), arch) == archs.end()) + if (Pkg->CurrentVer == 0 && std::find(archs.begin(), archs.end(), arch) == archs.end()) continue; for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false && likely(Okay); ++Ver, ++p) { diff --git a/apt-pkg/tagfile-keys.list b/apt-pkg/tagfile-keys.list index a979a404b..a16bc686a 100644 --- a/apt-pkg/tagfile-keys.list +++ b/apt-pkg/tagfile-keys.list @@ -48,6 +48,7 @@ Package-Revision Package-Type Pre-Depends Priority +Protected Provides Recommended Recommends diff --git a/apt-pkg/tagfile-order.c b/apt-pkg/tagfile-order.c index 4c2068c00..bb199b32e 100644 --- a/apt-pkg/tagfile-order.c +++ b/apt-pkg/tagfile-order.c @@ -11,7 +11,7 @@ static const char *iTFRewritePackageOrder[] = { "Architecture", "Subarchitecture", // Used only by d-i "Version", - "Revision", // Obsolete (warning in dpkg) + "Revision", // Obsolete (warning in dpkg) "Package-Revision", // Obsolete (warning in dpkg) "Package_Revision", // Obsolete (warning in dpkg) "Kernel-Version", // Used only by d-i @@ -23,6 +23,7 @@ static const char *iTFRewritePackageOrder[] = { "Priority", "Class", // dpkg nickname for Priority "Build-Essential", + "Protected", "Essential", "Installer-Menu-Item", // Used only by d-i "Section", |