X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/138d4b3d84035f2e0547d7de999d7c7ebb6b7adc..a62f8bb9110edd33cebe3968ab349657a99fa00a:/apt-pkg/packagemanager.cc diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 3b09871e5..fad40c46a 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.14 1999/02/21 08:38:53 jgg Exp $ +// $Id: packagemanager.cc,v 1.22 1999/10/22 05:58:54 jgg Exp $ /* ###################################################################### Package Manager - Abstacts the package manager @@ -60,7 +60,8 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) { PkgIterator Pkg(Cache,*I); - + FileNames[Pkg->ID] = string(); + // Skip packages to erase if (Cache[Pkg].Delete() == true) continue; @@ -69,7 +70,11 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && Cache[Pkg].Keep() == true) continue; - + + // Skip already processed packages + if (List->IsNow(Pkg) == false) + continue; + new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache), FileNames[Pkg->ID]); } @@ -82,31 +87,24 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, /* This is called to correct the installation when packages could not be downloaded. */ bool pkgPackageManager::FixMissing() -{ +{ pkgProblemResolver Resolve(Cache); - + List->SetFileList(FileNames); + bool Bad = false; for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { - // These don't need files - if (Cache[I].Keep() == true) - continue; - if (Cache[I].Delete() == true) - continue; - - // We have a filename - if (FileNames[I->ID].empty() == false) - continue; - - // Skip Packages that need configure only. - if (I.State() == pkgCache::PkgIterator::NeedsConfigure && - Cache[I].Keep() == true) + if (List->IsMissing(I) == false) continue; - + // Okay, this file is missing and we need it. Mark it for keep Bad = true; Cache.MarkKeep(I); } + + // We have to empty the list otherwise it will not have the new changes + delete List; + List = 0; if (Bad == false) return true; @@ -122,6 +120,9 @@ bool pkgPackageManager::FixMissing() going to change. */ bool pkgPackageManager::CreateOrderList() { + if (List != 0) + return true; + delete List; List = new pkgOrderList(Cache); @@ -155,7 +156,10 @@ bool pkgPackageManager::CreateOrderList() // Not interesting if ((Cache[I].Keep() == true || Cache[I].InstVerIter(Cache) == I.CurrentVer()) && - I.State() == pkgCache::PkgIterator::NeedsNothing) + 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; // Append it to the list @@ -361,6 +365,17 @@ 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 + if ((Pkg->Flags & pkgCache::Flag::Essential) != 0) + { + 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) @@ -378,7 +393,7 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) return true; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - return Remove(Pkg); + return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); } /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ @@ -400,12 +415,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++) { @@ -436,18 +456,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); @@ -487,58 +513,98 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) // PM::OrderInstall - Installation ordering routine /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgPackageManager::OrderInstall() +pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() { if (CreateOrderList() == false) - return false; + return Failed; + + Reset(); if (Debug == true) clog << "Begining to order" << endl; - - if (List->OrderUnpack() == false) - return _error->Error("Internal ordering error"); + if (List->OrderUnpack(FileNames) == false) + { + _error->Error("Internal ordering error"); + return Failed; + } + if (Debug == true) clog << "Done ordering" << endl; + bool DoneSomething = false; for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) { PkgIterator Pkg(Cache,*I); + + if (List->IsNow(Pkg) == false) + { + if (Debug == true) + clog << "Skipping already done " << Pkg.Name() << endl; + continue; + } + + if (List->IsMissing(Pkg) == true) + { + if (Debug == true) + clog << "Sequence completed at" << Pkg.Name() << endl; + if (DoneSomething == false) + { + _error->Error("Internal Error, ordering was unable to handle the media swap"); + return Failed; + } + return Incomplete; + } // Sanity check - if (Cache[Pkg].Keep() == true && Pkg.State() == pkgCache::PkgIterator::NeedsNothing) - return _error->Error("Internal Error, trying to manipulate a kept package"); + 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; + } // Perform a delete or an install if (Cache[Pkg].Delete() == true) { if (SmartRemove(Pkg) == false) - return false; + return Failed; } else if (SmartUnPack(Pkg) == false) - return false; + return Failed; + DoneSomething = true; } // Final run through the configure phase if (ConfigureAll() == false) - return false; + return Failed; // Sanity check for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + { if (List->IsFlag(*I,pkgOrderList::Configured) == false) - return _error->Error("Internal error, packages left unconfigured. %s", - PkgIterator(Cache,*I).Name()); - - return true; + { + _error->Error("Internal error, packages left unconfigured. %s", + PkgIterator(Cache,*I).Name()); + return Failed; + } + } + + return Completed; } /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ -bool pkgPackageManager::DoInstall() +pkgPackageManager::OrderResult pkgPackageManager::DoInstall() { - return OrderInstall() && Go(); + OrderResult Res = OrderInstall(); + if (Res != Failed) + if (Go() == false) + return Failed; + return Res; } /*}}}*/