X-Git-Url: https://git.hcoop.net/ntk/apt.git/blobdiff_plain/bdae53f1bf6710404235bbbd071c55f4ec1a9330..5af32db6607ca018936285fd19a776bd10a418f0:/apt-pkg/packagemanager.cc diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 68827f53..772ad4a5 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: packagemanager.cc,v 1.19 1999/08/03 05:19:41 jgg Exp $ +// $Id: packagemanager.cc,v 1.24 1999/12/24 21:10:56 jgg Exp $ /* ###################################################################### Package Manager - Abstacts the package manager @@ -157,6 +157,7 @@ bool pkgPackageManager::CreateOrderList() if ((Cache[I].Keep() == true || Cache[I].InstVerIter(Cache) == I.CurrentVer()) && I.State() == pkgCache::PkgIterator::NeedsNothing && + (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall && (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete || (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge)) continue; @@ -194,19 +195,22 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, { if (D->Type != pkgCache::Dep::Conflicts) continue; + + // The package hasnt been changed + if (List->IsNow(Pkg) == false) + continue; - if (D.ParentPkg() == Pkg) + // Ignore self conflicts, ignore conflicts from irrelevent versions + if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer()) continue; if (pkgCheckDep(D.TargetVer(),Ver,D->CompareOp) == false) continue; - - if (List->IsNow(Pkg) == false) - continue; if (EarlyRemove(D.ParentPkg()) == false) - return false; - } + return _error->Error("Reverse conflicts early remove for package '%s' failed", + Pkg.Name()); + } return true; } /*}}}*/ @@ -364,6 +368,32 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) // Woops, it will not be re-installed! if (List->IsFlag(Pkg,pkgOrderList::InList) == false) return false; + + // Essential packages get special treatment + bool IsEssential = false; + if ((Pkg->Flags & pkgCache::Flag::Essential) != 0) + IsEssential = true; + + /* Check for packages that are the dependents of essential packages and + promote them too */ + if (Pkg->CurrentVer != 0) + { + for (DepIterator D = Pkg.RevDependsList(); D.end() == false && + IsEssential == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0) + IsEssential = true; + } + + if (IsEssential == true) + { + if (_config->FindB("APT::Force-LoopBreak",false) == false) + return _error->Error("This installation run will require temporarily " + "removing the essential package %s due to a " + "Conflicts/Pre-Depends loop. This is often bad, " + "but if you really want to do it, activate the " + "APT::Force-LoopBreak option.",Pkg.Name()); + } bool Res = SmartRemove(Pkg); if (Cache[Pkg].Delete() == false) @@ -403,12 +433,17 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) /* See if this packages install version has any predependencies that are not met by 'now' packages. */ for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); - D.end() == false; D++) + D.end() == false; ) { - if (D->Type == pkgCache::Dep::PreDepends) + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + + while (End->Type == pkgCache::Dep::PreDepends) { // Look for possible ok targets. - Version **VList = D.AllTargets(); + Version **VList = Start.AllTargets(); bool Bad = true; for (Version **I = VList; *I != 0 && Bad == true; I++) { @@ -439,18 +474,24 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) } delete [] VList; - - if (Bad == true) - return _error->Error("Internal Error, Couldn't configure a pre-depend"); - continue; + /* If this or element did not match then continue on to the + next or element until a matching element is found*/ + if (Bad == true) + { + if (Start == End) + return _error->Error("Internal Error, Couldn't configure a pre-depend"); + Start++; + } + else + break; } - if (D->Type == pkgCache::Dep::Conflicts) + if (End->Type == pkgCache::Dep::Conflicts) { /* Look for conflicts. Two packages that are both in the install state cannot conflict so we don't check.. */ - Version **VList = D.AllTargets(); + Version **VList = End.AllTargets(); for (Version **I = VList; *I != 0; I++) { VerIterator Ver(Cache,*I); @@ -468,8 +509,10 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) } // Check for reverse conflicts. - CheckRConflicts(Pkg,Pkg.RevDependsList(), - Cache[Pkg].InstVerIter(Cache).VerStr()); + if (CheckRConflicts(Pkg,Pkg.RevDependsList(), + Cache[Pkg].InstVerIter(Cache).VerStr()) == false) + return false; + for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList(); P.end() == false; P++) CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); @@ -524,7 +567,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() if (List->IsMissing(Pkg) == true) { if (Debug == true) - clog << "Sequence completed at" << Pkg.Name() << endl; + clog << "Sequence completed at " << Pkg.Name() << endl; if (DoneSomething == false) { _error->Error("Internal Error, ordering was unable to handle the media swap"); @@ -534,7 +577,9 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() } // Sanity check - if (Cache[Pkg].Keep() == true && Pkg.State() == pkgCache::PkgIterator::NeedsNothing) + if (Cache[Pkg].Keep() == true && + Pkg.State() == pkgCache::PkgIterator::NeedsNothing && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall) { _error->Error("Internal Error, trying to manipulate a kept package"); return Failed;