X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/1db7d3928e37662a6f29fe1cff8dcec38ad93319..6e7c6c3f58193fd5db3d9d598ac65a1571522a58:/apt-pkg/packagemanager.cc diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 99710469b..304d1c653 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.25 2000/05/12 04:26:42 jgg Exp $ +// $Id: packagemanager.cc,v 1.30 2003/04/27 03:04:15 doogie Exp $ /* ###################################################################### Package Manager - Abstacts the package manager @@ -13,9 +13,6 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/packagemanager.h" -#endif #include #include #include @@ -24,12 +21,18 @@ #include #include #include - /*}}}*/ +#include + +#include +#include +#include + +using namespace std; // PM::PackageManager - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgPackageManager::pkgPackageManager(pkgDepCache &Cache) : Cache(Cache) +pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache) { FileNames = new string[Cache.Head().PackageCount]; List = 0; @@ -88,9 +91,10 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, be downloaded. */ bool pkgPackageManager::FixMissing() { - pkgProblemResolver Resolve(Cache); + pkgDepCache::ActionGroup group(Cache); + pkgProblemResolver Resolve(&Cache); List->SetFileList(FileNames); - + bool Bad = false; for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { @@ -99,7 +103,7 @@ bool pkgPackageManager::FixMissing() // Okay, this file is missing and we need it. Mark it for keep Bad = true; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } // We have to empty the list otherwise it will not have the new changes @@ -114,6 +118,41 @@ bool pkgPackageManager::FixMissing() } /*}}}*/ +// PM::ImmediateAdd - Add the immediate flag recursivly /*{{{*/ +// --------------------------------------------------------------------- +/* This adds the immediate flag to the pkg and recursively to the + dependendies + */ +void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer) +{ + DepIterator D; + + if(UseInstallVer) + { + if(Cache[I].InstallVer == 0) + return; + D = Cache[I].InstVerIter(Cache).DependsList(); + } else { + if (I->CurrentVer == 0) + return; + D = I.CurrentVer().DependsList(); + } + + for ( /* nothing */ ; D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + { + if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate)) + { + if(Debug) + clog << "ImmediateAdd(): Adding Immediate flag to " << I.Name() << endl; + List->Flag(D.TargetPkg(),pkgOrderList::Immediate); + ImmediateAdd(D.TargetPkg(), UseInstallVer); + } + } + return; +} + /*}}}*/ + // PM::CreateOrderList - Create the ordering class /*{{{*/ // --------------------------------------------------------------------- /* This populates the ordering list with all the packages that are @@ -124,33 +163,31 @@ bool pkgPackageManager::CreateOrderList() return true; delete List; - List = new pkgOrderList(Cache); + List = new pkgOrderList(&Cache); - bool NoImmConfigure = _config->FindB("APT::Immediate-Configure",false); + bool NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); // Generate the list of affected packages and sort it for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { + // Ignore no-version packages + if (I->VersionList == 0) + continue; + // 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) { + if(Debug) + clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl; 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); + + // Look for other install packages to make immediate configurea + ImmediateAdd(I, true); // 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); + ImmediateAdd(I, false); } // Not interesting @@ -193,7 +230,8 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, { for (;D.end() == false; D++) { - if (D->Type != pkgCache::Dep::Conflicts) + if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::Obsoletes) continue; // The package hasnt been changed @@ -204,9 +242,9 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer()) continue; - if (pkgCheckDep(D.TargetVer(),Ver,D->CompareOp) == false) + if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false) continue; - + if (EarlyRemove(D.ParentPkg()) == false) return _error->Error("Reverse conflicts early remove for package '%s' failed", Pkg.Name()); @@ -220,7 +258,7 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, that the final configuration is valid. */ bool pkgPackageManager::ConfigureAll() { - pkgOrderList OList(Cache); + pkgOrderList OList(&Cache); // Populate the order list for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) @@ -251,14 +289,14 @@ bool pkgPackageManager::ConfigureAll() of it's dependents. */ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) { - pkgOrderList OList(Cache); + pkgOrderList OList(&Cache); if (DepAdd(OList,Pkg) == false) return false; if (OList.OrderConfigure() == false) return false; - + // Perform the configuring for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) { @@ -288,8 +326,7 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) return true; if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false) return false; - - + // Put the package on the list OList.push_back(Pkg); OList.Flag(Pkg,pkgOrderList::Added); @@ -314,7 +351,7 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) if (Bad == false) continue; - Version **VList = D.AllTargets(); + SPtrArray VList = D.AllTargets(); for (Version **I = VList; *I != 0 && Bad == true; I++) { VerIterator Ver(Cache,*I); @@ -332,12 +369,12 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) if (Cache[Pkg].InstallVer != *I || (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) continue; + if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true) Bad = !DepAdd(OList,Pkg,Depth); if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) Bad = false; } - delete [] VList; } if (Bad == true) @@ -388,11 +425,11 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) 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()); + 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); @@ -426,7 +463,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true) if (SmartConfigure(Pkg) == false) - return _error->Error("Internal Error, Could not perform immediate configuration"); + return _error->Error("Internal Error, Could not perform immediate configuration (1) on %s",Pkg.Name()); return true; } @@ -443,7 +480,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) while (End->Type == pkgCache::Dep::PreDepends) { // Look for possible ok targets. - Version **VList = Start.AllTargets(); + SPtrArray VList = Start.AllTargets(); bool Bad = true; for (Version **I = VList; *I != 0 && Bad == true; I++) { @@ -472,26 +509,28 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) Bad = !SmartConfigure(Pkg); } - - delete [] VList; /* If this or element did not match then continue on to the - next or element until a matching element is found*/ + next or element until a matching element is found */ if (Bad == true) - { + { + // This triggers if someone make a pre-depends/depend loop. if (Start == End) - return _error->Error("Internal Error, Couldn't configure a pre-depend"); + return _error->Error("Couldn't configure pre-depend %s for %s, " + "probably a dependency cycle.", + End.TargetPkg().Name(),Pkg.Name()); Start++; } else break; } - if (End->Type == pkgCache::Dep::Conflicts) + if (End->Type == pkgCache::Dep::Conflicts || + End->Type == pkgCache::Dep::Obsoletes) { /* Look for conflicts. Two packages that are both in the install state cannot conflict so we don't check.. */ - Version **VList = End.AllTargets(); + SPtrArray VList = End.AllTargets(); for (Version **I = VList; *I != 0; I++) { VerIterator Ver(Cache,*I); @@ -504,7 +543,6 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) return _error->Error("Internal Error, Could not early remove %s",Pkg.Name()); } } - delete [] VList; } } @@ -525,7 +563,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) // Perform immedate configuration of the package. if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true) if (SmartConfigure(Pkg) == false) - return _error->Error("Internal Error, Could not perform immediate configuration"); + return _error->Error("Internal Error, Could not perform immediate configuration (2) on %s",Pkg.Name()); return true; } @@ -581,7 +619,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() Pkg.State() == pkgCache::PkgIterator::NeedsNothing && (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall) { - _error->Error("Internal Error, trying to manipulate a kept package"); + _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name()); return Failed; } @@ -615,16 +653,31 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Completed; } /*}}}*/ +// PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/ +// --------------------------------------------------------------------- +pkgPackageManager::OrderResult +pkgPackageManager::DoInstallPostFork(int statusFd) +{ + if(statusFd > 0) + // FIXME: use SetCloseExec here once it taught about throwing + // exceptions instead of doing _exit(100) on failure + fcntl(statusFd,F_SETFD,FD_CLOEXEC); + bool goResult = Go(statusFd); + if(goResult == false) + return Failed; + + return Res; +}; + // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall() +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) { - OrderResult Res = OrderInstall(); - if (Res != Failed) - if (Go() == false) - return Failed; - return Res; + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(statusFd); } /*}}}*/