X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b50b2c97b3a8cf71aaecdcea6321433d576852a9..281daf46d178d4fb6f43e8b13b9b51736db84d74:/apt-pkg/packagemanager.cc?ds=inline diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index e3504f8bf..8556687ad 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.2 1998/07/09 05:41:12 jgg Exp $ +// $Id: packagemanager.cc,v 1.15 1999/07/03 03:10:35 jgg Exp $ /* ###################################################################### Package Manager - Abstacts the package manager @@ -14,13 +14,16 @@ /*}}}*/ // Include Files /*{{{*/ #ifdef __GNUG__ -#pragma implementation "pkglib/packagemanager.h" +#pragma implementation "apt-pkg/packagemanager.h" #endif -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include /*}}}*/ // PM::PackageManager - Constructor /*{{{*/ @@ -30,6 +33,7 @@ pkgPackageManager::pkgPackageManager(pkgDepCache &Cache) : Cache(Cache) { FileNames = new string[Cache.Head().PackageCount]; List = 0; + Debug = _config->FindB("Debug::pkgPackageManager",false); } /*}}}*/ // PM::PackageManager - Destructor /*{{{*/ @@ -41,36 +45,134 @@ pkgPackageManager::~pkgPackageManager() delete [] FileNames; } /*}}}*/ +// PM::GetArchives - Queue the archives for download /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, + pkgRecords *Recs) +{ + if (CreateOrderList() == false) + return false; + + if (List->OrderUnpack() == false) + return _error->Error("Internal ordering error"); + + 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; + + // Skip Packages that need configure only. + 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]); + } + + return true; +} + /*}}}*/ // PM::FixMissing - Keep all missing packages /*{{{*/ // --------------------------------------------------------------------- /* This is called to correct the installation when packages could not be downloaded. */ bool pkgPackageManager::FixMissing() { - unsigned char *Touch = new unsigned char[Cache.Head().PackageCount]; + pkgProblemResolver Resolve(Cache); + + bool Bad = false; for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { - // Create the status list that ResolveConflicts needs - if ((Cache[I].DepState & pkgDepCache::DepNowMin) == pkgDepCache::DepNowMin) - Touch[I->ID] = (1 << 0) | (1 << 1); - else - Touch[I->ID] = 1 << 1; - + // These don't need files if (Cache[I].Keep() == true) continue; - if (FileNames[I->ID].empty() == false || Cache[I].Delete() == true) + 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) continue; + + // Okay, this file is missing and we need it. Mark it for keep + Bad = true; Cache.MarkKeep(I); } + if (Bad == false) + return true; + // Now downgrade everything that is broken - Cache.ResolveConflicts(Touch); - delete [] Touch; - - return Cache.BrokenCount() == 0; + return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0; } /*}}}*/ +// PM::CreateOrderList - Create the ordering class /*{{{*/ +// --------------------------------------------------------------------- +/* This populates the ordering list with all the packages that are + going to change. */ +bool pkgPackageManager::CreateOrderList() +{ + if (List != 0) + return true; + + delete List; + List = new pkgOrderList(Cache); + + bool NoImmConfigure = _config->FindB("APT::Immediate-Configure",false); + + // Generate the list of affected packages and sort it + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + // Mark the package and its dependends for immediate configuration + if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) && + NoImmConfigure == false) + { + List->Flag(I,pkgOrderList::Immediate); + + // Look for other packages to make immediate configurea + if (Cache[I].InstallVer != 0) + for (DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); + D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + List->Flag(D.TargetPkg(),pkgOrderList::Immediate); + + // And again with the current version. + if (I->CurrentVer != 0) + for (DepIterator D = I.CurrentVer().DependsList(); + D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + List->Flag(D.TargetPkg(),pkgOrderList::Immediate); + } + + // Not interesting + if ((Cache[I].Keep() == true || + Cache[I].InstVerIter(Cache) == I.CurrentVer()) && + I.State() == pkgCache::PkgIterator::NeedsNothing) + continue; + + // Append it to the list + List->push_back(I); + } + + return true; +} + /*}}}*/ // PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/ // --------------------------------------------------------------------- /* The restriction on provides is to eliminate the case when provides @@ -302,7 +404,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) return _error->Error("Internal Error, Could not perform immediate configuraton"); return true; } - + /* See if this packages install version has any predependencies that are not met by 'now' packages. */ for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); @@ -393,84 +495,96 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) // PM::OrderInstall - Installation ordering routine /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgPackageManager::OrderInstall() +pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() { - delete List; - List = new pkgOrderList(Cache); + if (CreateOrderList() == false) + return Failed; + + Reset(); - // Generate the list of affected packages and sort it - for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + if (Debug == true) + clog << "Begining to order" << endl; + + if (List->OrderUnpack(FileNames) == false) { - // Consider all depends - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - { - List->Flag(I,pkgOrderList::Immediate); - if (Cache[I].InstallVer != 0) - for (DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); - D.end() == false; D++) - if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) - List->Flag(D.TargetPkg(),pkgOrderList::Immediate); - if (I->CurrentVer != 0) - for (DepIterator D = I.CurrentVer().DependsList(); - D.end() == false; D++) - if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) - List->Flag(D.TargetPkg(),pkgOrderList::Immediate); - } - - // Not interesting - if ((Cache[I].Keep() == true || - Cache[I].InstVerIter(Cache) == I.CurrentVer()) && - I.State() == pkgCache::PkgIterator::NeedsNothing) - continue; - - // Append it to the list - List->push_back(I); - - if ((I->Flags & pkgCache::Flag::ImmediateConf) == pkgCache::Flag::ImmediateConf) - List->Flag(I,pkgOrderList::Immediate); + _error->Error("Internal ordering error"); + return Failed; } - if (List->OrderUnpack() == false) - return _error->Error("Internal ordering error"); + 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 (Cache[Pkg].Delete() == false && FileNames[Pkg->ID].empty() == 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"); + { + _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; } /*}}}*/