X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/e9afbeb9df95b582aac76bb44b5ae2b766ab8fd5..fa321bf3dbf363879cfc799b6c1cc4e5af50ffd8:/apt-pkg/algorithms.cc diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index ac9d3be0b..6e2b97557 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -14,18 +14,17 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/algorithms.h" -#endif #include #include #include #include #include - +#include #include #include +#include +#include #include /*}}}*/ using namespace std; @@ -102,6 +101,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/) DepIterator End; D.GlobOr(Start,End); if (Start->Type == pkgCache::Dep::Conflicts || + Start->Type == pkgCache::Dep::DpkgBreaks || Start->Type == pkgCache::Dep::Obsoletes || End->Type == pkgCache::Dep::PreDepends) { @@ -151,6 +151,8 @@ bool pkgSimulate::Configure(PkgIterator iPkg) cout << " Obsoletes:" << D.TargetPkg().Name(); else if (D->Type == pkgCache::Dep::Conflicts) cout << " Conflicts:" << D.TargetPkg().Name(); + else if (D->Type == pkgCache::Dep::DpkgBreaks) + cout << " Breaks:" << D.TargetPkg().Name(); else cout << " Depends:" << D.TargetPkg().Name(); } @@ -255,6 +257,8 @@ bool pkgApplyStatus(pkgDepCache &Cache) re-unpacked (probably) */ case pkgCache::State::UnPacked: case pkgCache::State::HalfConfigured: + case pkgCache::State::TriggersAwaited: + case pkgCache::State::TriggersPending: if ((I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) || I.State() != pkgCache::PkgIterator::NeedsUnpack) Cache.MarkKeep(I, false, false); @@ -506,8 +510,10 @@ void pkgProblemResolver::MakeScores() Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority]; /* This helps to fix oddball problems with conflicting packages - on the same level. We enhance the score of installed packages */ - if (I->CurrentVer != 0) + on the same level. We enhance the score of installed packages + if those are not obsolete + */ + if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable()) Score += 1; } @@ -651,6 +657,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) /* We let the algorithm deal with conflicts on its next iteration, it is much smarter than us */ if (Start->Type == pkgCache::Dep::Conflicts || + Start->Type == pkgCache::Dep::DpkgBreaks || Start->Type == pkgCache::Dep::Obsoletes) break; @@ -800,7 +807,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) continue; if (Debug == true) - cout << "Investigating " << I.Name() << endl; + clog << "Investigating " << I.Name() << endl; // Isolate the problem dependency PackageKill KillList[100]; @@ -855,7 +862,12 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) OldEnd = LEnd; } else + { Start++; + // We only worry about critical deps. + if (Start.IsCritical() != true) + continue; + } // Dep is ok if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) @@ -873,6 +885,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) SPtrArray VList = Start.AllTargets(); if (*VList == 0 && (Flags[I->ID] & Protected) != Protected && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::DpkgBreaks && Start->Type != pkgCache::Dep::Obsoletes && Cache[I].NowBroken() == false) { @@ -903,6 +916,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (Scores[I->ID] <= Scores[Pkg->ID] || ((Cache[Start] & pkgDepCache::DepNow) == 0 && End->Type != pkgCache::Dep::Conflicts && + End->Type != pkgCache::Dep::DpkgBreaks && End->Type != pkgCache::Dep::Obsoletes)) { // Try a little harder to fix protected packages.. @@ -968,7 +982,22 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) (Start->Type == pkgCache::Dep::Conflicts || Start->Type == pkgCache::Dep::Obsoletes)) continue; - + + if (Start->Type == pkgCache::Dep::DpkgBreaks) + { + /* Would it help if we upgraded? */ + if (Cache[End] & pkgDepCache::DepGCVer) { + if (Debug) + clog << " Upgrading " << Pkg.Name() << " due to Breaks field in " << I.Name() << endl; + Cache.MarkInstall(Pkg, false, 0, false); + continue; + } + if (Debug) + clog << " Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() <ID] & Protected) != 0) continue; @@ -989,6 +1018,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) // Hm, nothing can possibly satisify this dep. Nuke it. if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::DpkgBreaks && Start->Type != pkgCache::Dep::Obsoletes && (Flags[I->ID] & Protected) != Protected) { @@ -1229,8 +1259,13 @@ void pkgProblemResolver::InstallProtect() { if ((Flags[I->ID] & ToRemove) == ToRemove) Cache.MarkDelete(I); - else - Cache.MarkInstall(I, false, 0, false); + else + { + // preserve the information whether the package was auto + // or manually installed + bool autoInst = (Cache[I].Flags & pkgCache::Flag::Auto); + Cache.MarkInstall(I, false, 0, !autoInst); + } } } } @@ -1267,3 +1302,77 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) } /*}}}*/ +// CacheFile::ListUpdate - update the cache files /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple wrapper to update the cache. it will fetch stuff + * from the network (or any other sources defined in sources.list) + */ +bool ListUpdate(pkgAcquireStatus &Stat, + pkgSourceList &List, + int PulseInterval) +{ + pkgAcquire::RunResult res; + pkgAcquire Fetcher(&Stat); + + // Populate it with the source selection + if (List.GetIndexes(&Fetcher) == false) + return false; + + // Run scripts + RunScripts("APT::Update::Pre-Invoke"); + + // check arguments + if(PulseInterval>0) + res = Fetcher.Run(PulseInterval); + else + res = Fetcher.Run(); + + if (res == pkgAcquire::Failed) + return false; + + bool Failed = false; + bool TransientNetworkFailure = false; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); + I != Fetcher.ItemsEnd(); I++) + { + if ((*I)->Status == pkgAcquire::Item::StatDone) + continue; + + (*I)->Finished(); + + _error->Warning(_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(), + (*I)->ErrorText.c_str()); + + if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError) + { + TransientNetworkFailure = true; + continue; + } + + Failed = true; + } + + // Clean out any old list files + // Keep "APT::Get::List-Cleanup" name for compatibility, but + // this is really a global option for the APT library now + if (!TransientNetworkFailure && !Failed && + (_config->FindB("APT::Get::List-Cleanup",true) == true || + _config->FindB("APT::List-Cleanup",true) == true)) + { + if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || + Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) + // something went wrong with the clean + return false; + } + + if (TransientNetworkFailure == true) + _error->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead.")); + else if (Failed == true) + return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead.")); + + + // Run the scripts if all was fine + RunScripts("APT::Update::Post-Invoke"); + return true; +} + /*}}}*/