X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/c5ca2c52a98fcb50de6429cf370ed5b6b7602a00..4c81d32aada5b78fff4724efb1e039dd429c09f3:/apt-pkg/algorithms.cc diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 08d1f8cb7..2f5fcc7ab 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -14,6 +14,8 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@ -21,14 +23,17 @@ #include #include #include +#include +#include +#include -#include #include #include #include #include - #include + +#include /*}}}*/ using namespace std; @@ -53,6 +58,12 @@ pkgSimulate::pkgSimulate(pkgDepCache *Cache) : pkgPackageManager(Cache), FileNames[I] = Jnk; } /*}}}*/ +// Simulate::~Simulate - Destructor /*{{{*/ +pkgSimulate::~pkgSimulate() +{ + delete[] Flags; +} + /*}}}*/ // Simulate::Describe - Describe a package /*{{{*/ // --------------------------------------------------------------------- /* Parameter Current == true displays the current package version, @@ -351,11 +362,36 @@ bool pkgDistUpgrade(pkgDepCache &Cache) if (I->CurrentVer != 0) Cache.MarkInstall(I, true, 0, false); - /* Now, auto upgrade all essential packages - this ensures that - the essential packages are present and working */ - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Cache.MarkInstall(I, true, 0, false); + /* Now, install each essential package which is not installed + (and not provided by another package in the same name group) */ + std::string essential = _config->Find("pkgCacheGen::Essential", "all"); + if (essential == "all") + { + for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G) + { + bool isEssential = false; + bool instEssential = false; + for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P)) + { + if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential) + continue; + isEssential = true; + if (Cache[P].Install() == true) + { + instEssential = true; + break; + } + } + if (isEssential == false || instEssential == true) + continue; + pkgCache::PkgIterator P = G.FindPreferredPkg(); + Cache.MarkInstall(P, true, 0, false); + } + } + else if (essential != "none") + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + Cache.MarkInstall(I, true, 0, false); /* We do it again over all previously installed packages to force conflict resolution on them all. */ @@ -466,11 +502,11 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache) // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : Cache(*pCache) +pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : d(NULL), Cache(*pCache) { // Allocate memory unsigned long Size = Cache.Head().PackageCount; - Scores = new signed short[Size]; + Scores = new int[Size]; Flags = new unsigned char[Size]; memset(Flags,0,sizeof(*Flags)*Size); @@ -510,20 +546,20 @@ void pkgProblemResolver::MakeScores() memset(Scores,0,sizeof(*Scores)*Size); // Important Required Standard Optional Extra - signed short PrioMap[] = { + int PrioMap[] = { 0, - (signed short) _config->FindI("pkgProblemResolver::Scores::Important",3), - (signed short) _config->FindI("pkgProblemResolver::Scores::Required",2), - (signed short) _config->FindI("pkgProblemResolver::Scores::Standard",1), - (signed short) _config->FindI("pkgProblemResolver::Scores::Optional",-1), - (signed short) _config->FindI("pkgProblemResolver::Scores::Extra",-2) + _config->FindI("pkgProblemResolver::Scores::Important",3), + _config->FindI("pkgProblemResolver::Scores::Required",2), + _config->FindI("pkgProblemResolver::Scores::Standard",1), + _config->FindI("pkgProblemResolver::Scores::Optional",-1), + _config->FindI("pkgProblemResolver::Scores::Extra",-2) }; - signed short PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100); - signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1); - signed short PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1); - signed short PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1); - signed short AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000); - signed short AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000); + int PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100); + int PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1); + int PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1); + int PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1); + int AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000); + int AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000); if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl @@ -545,13 +581,14 @@ void pkgProblemResolver::MakeScores() if (Cache[I].InstallVer == 0) continue; - signed short &Score = Scores[I->ID]; + int &Score = Scores[I->ID]; /* This is arbitrary, it should be high enough to elevate an essantial package above most other packages but low enough to allow an obsolete essential packages to be removed by a conflicts on a powerfull normal package (ie libc6) */ - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential + || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) Score += PrioEssentials; // We transform the priority @@ -583,7 +620,7 @@ void pkgProblemResolver::MakeScores() } // Copy the scores to advoid additive looping - SPtrArray OldScores = new signed short[Size]; + SPtrArray OldScores = new int[Size]; memcpy(OldScores,Scores,sizeof(*Scores)*Size); /* Now we cause 1 level of dependency inheritance, that is we add the @@ -626,7 +663,8 @@ void pkgProblemResolver::MakeScores() { if ((Flags[I->ID] & Protected) != 0) Scores[I->ID] += AddProtected; - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) Scores[I->ID] += AddEssential; } } @@ -1030,7 +1068,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) if (BrokenFix == false || DoUpgrade(I) == false) { // Consider other options - if (InOr == false) + if (InOr == false || Cache[I].Garbage == true) { if (Debug == true) clog << " Removing " << I.FullName(false) << " rather than change " << Start.TargetPkg().FullName(false) << endl; @@ -1093,8 +1131,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) LEnd->Dep = End; LEnd++; - if (Start->Type != pkgCache::Dep::Conflicts && - Start->Type != pkgCache::Dep::Obsoletes) + if (Start.IsNegative() == false) break; } } @@ -1204,7 +1241,6 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) return true; } /*}}}*/ - // ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/ // --------------------------------------------------------------------- /* This checks if the given package is broken either by a hard dependency @@ -1216,19 +1252,26 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) */ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I) { - // a broken install is always a problem if (Cache[I].InstBroken() == true) + { + if (Debug == true) + std::clog << " Dependencies are not satisfied for " << I << std::endl; return true; + } // a newly broken policy (recommends/suggests) is a problem if (Cache[I].NowPolicyBroken() == false && Cache[I].InstPolicyBroken() == true) + { + if (Debug == true) + std::clog << " Policy breaks with upgrade of " << I << std::endl; return true; - + } + return false; } - + /*}}}*/ // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/ // --------------------------------------------------------------------- /* This is the work horse of the soft upgrade routine. It is very gental @@ -1420,6 +1463,13 @@ static int PrioComp(const void *A,const void *B) if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential && (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) return -1; + + if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important && + (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important) + return 1; + if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important && + (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) + return -1; if (L->Priority != R->Priority) return R->Priority - L->Priority; @@ -1434,7 +1484,7 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) qsort(List,Count,sizeof(*List),PrioComp); } /*}}}*/ -// CacheFile::ListUpdate - update the cache files /*{{{*/ +// ListUpdate - construct Fetcher and 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) @@ -1443,7 +1493,6 @@ bool ListUpdate(pkgAcquireStatus &Stat, pkgSourceList &List, int PulseInterval) { - pkgAcquire::RunResult res; pkgAcquire Fetcher; if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false) return false; @@ -1452,11 +1501,24 @@ bool ListUpdate(pkgAcquireStatus &Stat, if (List.GetIndexes(&Fetcher) == false) return false; + return AcquireUpdate(Fetcher, PulseInterval, true); +} + /*}}}*/ +// AcquireUpdate - take Fetcher and update the cache files /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple wrapper to update the cache with a provided acquire + * If you only need control over Status and the used SourcesList use + * ListUpdate method instead. + */ +bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval, + bool const RunUpdateScripts, bool const ListCleanup) +{ // Run scripts - RunScripts("APT::Update::Pre-Invoke"); - - // check arguments - if(PulseInterval>0) + if (RunUpdateScripts == true) + RunScripts("APT::Update::Pre-Invoke"); + + pkgAcquire::RunResult res; + if(PulseInterval > 0) res = Fetcher.Run(PulseInterval); else res = Fetcher.Run(); @@ -1493,7 +1555,7 @@ bool ListUpdate(pkgAcquireStatus &Stat, // 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 && + if (!TransientNetworkFailure && !Failed && ListCleanup == true && (_config->FindB("APT::Get::List-Cleanup",true) == true && _config->FindB("APT::List-Cleanup",true) == true)) { @@ -1510,11 +1572,14 @@ bool ListUpdate(pkgAcquireStatus &Stat, // Run the success scripts if all was fine - if(!TransientNetworkFailure && !Failed) - RunScripts("APT::Update::Post-Invoke-Success"); + if (RunUpdateScripts == true) + { + if(!TransientNetworkFailure && !Failed) + RunScripts("APT::Update::Post-Invoke-Success"); - // Run the other scripts - RunScripts("APT::Update::Post-Invoke"); + // Run the other scripts + RunScripts("APT::Update::Post-Invoke"); + } return true; } /*}}}*/