X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/d41d0e0113208aa1752344a13e8a962a1ad4f76e..c4cca79156ef5651e90772bae5f4aa11f669907d:/apt-pkg/packagemanager.cc?ds=sidebyside diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 53bb507b6..4f9762701 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -13,6 +13,8 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@ -22,10 +24,10 @@ #include #include #include - -#include + +#include #include -#include +#include /*}}}*/ using namespace std; @@ -65,7 +67,7 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, if (ordering == false) return _error->Error("Internal ordering error"); - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) { PkgIterator Pkg(Cache,*I); FileNames[Pkg->ID] = string(); @@ -101,7 +103,7 @@ bool pkgPackageManager::FixMissing() List->SetFileList(FileNames); bool Bad = false; - for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { if (List->IsMissing(I) == false) continue; @@ -142,7 +144,7 @@ void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned D = I.CurrentVer().DependsList(); } - for ( /* nothing */ ; D.end() == false; D++) + for ( /* nothing */ ; D.end() == false; ++D) if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) { if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate)) @@ -175,7 +177,7 @@ bool pkgPackageManager::CreateOrderList() clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl; // Generate the list of affected packages and sort it - for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { // Ignore no-version packages if (I->VersionList == 0) @@ -237,7 +239,7 @@ bool pkgPackageManager::DepAlwaysTrue(DepIterator D) bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, const char *Ver) { - for (;D.end() == false; D++) + for (;D.end() == false; ++D) { if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes) @@ -271,7 +273,7 @@ bool pkgPackageManager::ConfigureAll() pkgOrderList OList(&Cache); // Populate the order list - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) if (List->IsFlag(pkgCache::PkgIterator(Cache,*I), pkgOrderList::UnPacked) == true) OList.push_back(*I); @@ -283,7 +285,7 @@ bool pkgPackageManager::ConfigureAll() bool const ConfigurePkgs = (conf == "all"); // Perform the configuring - for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) + for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); ++I) { PkgIterator Pkg(Cache,*I); @@ -371,18 +373,27 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) // Check if the version that is going to be installed will satisfy the dependancy if (Cache[DepPkg].InstallVer == *I) { if (List->IsFlag(DepPkg,pkgOrderList::UnPacked)) { - if (PkgLoop && List->IsFlag(DepPkg,pkgOrderList::Loop)) { + if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop) { // This dependancy has already been dealt with by another SmartConfigure on Pkg Bad = false; break; + } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) { + /* Check for a loop to prevent one forming + If A depends on B and B depends on A, SmartConfigure will + just hop between them if this is not checked. Dont remove the + loop flag after finishing however as loop is already set. + This means that there is another SmartConfigure call for this + package and it will remove the loop flag */ + Bad = !SmartConfigure(DepPkg, Depth + 1); + } else { + /* Check for a loop to prevent one forming + If A depends on B and B depends on A, SmartConfigure will + just hop between them if this is not checked */ + List->Flag(Pkg,pkgOrderList::Loop); + Bad = !SmartConfigure(DepPkg, Depth + 1); + List->RmFlag(Pkg,pkgOrderList::Loop); } - /* Check for a loop to prevent one forming - If A depends on B and B depends on A, SmartConfigure will - just hop between them if this is not checked */ - List->Flag(Pkg,pkgOrderList::Loop); // If SmartConfigure was succesfull, Bad is false, so break - Bad = !SmartConfigure(DepPkg, Depth + 1); - List->RmFlag(Pkg,pkgOrderList::Loop); if (!Bad) break; } else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) { Bad = false; @@ -393,22 +404,27 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) /* If the dependany is still not satisfied, try, if possible, unpacking a package to satisfy it */ if (InstallVer != 0 && Bad) { - Bad = false; - if (List->IsNow(DepPkg) && !List->IsFlag(DepPkg,pkgOrderList::Loop)) { - List->Flag(Pkg,pkgOrderList::Loop); - if (Debug) - cout << OutputInDepth(Depth) << "Unpacking " << DepPkg.Name() << " to avoid loop" << endl; - SmartUnPack(DepPkg, true, Depth + 1); - List->RmFlag(Pkg,pkgOrderList::Loop); + if (List->IsNow(DepPkg)) { + Bad = false; + if (List->IsFlag(Pkg,pkgOrderList::Loop)) + { + if (Debug) + std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl; + } + else + { + List->Flag(Pkg,pkgOrderList::Loop); + if (Debug) + cout << OutputInDepth(Depth) << "Unpacking " << DepPkg.Name() << " to avoid loop" << endl; + SmartUnPack(DepPkg, true, Depth + 1); + List->RmFlag(Pkg,pkgOrderList::Loop); + } } } if (Start==End) { - if (Bad && Debug) { - if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { - _error->Warning("Could not satisfy dependancies for %s",Pkg.Name()); - } - } + if (Bad && Debug && List->IsFlag(DepPkg,pkgOrderList::Loop) == false) + std::clog << OutputInDepth(Depth) << "Could not satisfy dependancies for " << Pkg.Name() << std::endl; break; } else { Start++; @@ -428,14 +444,14 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) static bool const ConfigurePkgs = (conf == "all" || conf == "smart"); if (List->IsFlag(Pkg,pkgOrderList::Configured)) - return _error->Error("Internal configure error on '%s'. ",Pkg.Name(),1); + return _error->Error("Internal configure error on '%s'.", Pkg.Name()); if (ConfigurePkgs == true && Configure(Pkg) == false) return false; - + List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same) + if ((Cache[Pkg].InstVerIter(Cache)->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same) for (PkgIterator P = Pkg.Group().PackageList(); P.end() == false; P = Pkg.Group().NextPkg(P)) { @@ -479,7 +495,7 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) if (Pkg->CurrentVer != 0) { for (DepIterator D = Pkg.RevDependsList(); D.end() == false && - IsEssential == false; D++) + IsEssential == false; ++D) if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0) IsEssential = true; @@ -540,14 +556,6 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c cout << endl; } - // Check if it is already unpacked - if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && - Cache[Pkg].Keep() == true) - { - cout << OutputInDepth(Depth) << "SmartUnPack called on Package " << Pkg.Name() << " but its unpacked" << endl; - return false; - } - VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked. @@ -618,7 +626,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c return _error->Error("Couldn't configure pre-depend %s for %s, " "probably a dependency cycle.", End.TargetPkg().Name(),Pkg.Name()); - Start++; + ++Start; } else break; @@ -678,18 +686,28 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c // Check if it needs to be unpacked if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false && List->IsNow(BrokenPkg)) { - if (PkgLoop && List->IsFlag(BrokenPkg,pkgOrderList::Loop)) { + if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop) { // This dependancy has already been dealt with by another SmartUnPack on Pkg break; - } - List->Flag(Pkg,pkgOrderList::Loop); - // Found a break, so unpack the package - if (Debug) - cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) { + /* Found a break, so unpack the package, but dont remove loop as already set. + This means that there is another SmartUnPack call for this + package and it will remove the loop flag. */ + if (Debug) + cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + + SmartUnPack(BrokenPkg, false, Depth + 1); + } else { + List->Flag(Pkg,pkgOrderList::Loop); + // Found a break, so unpack the package + if (Debug) + cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; - SmartUnPack(BrokenPkg, false, Depth + 1); - List->RmFlag(Pkg,pkgOrderList::Loop); + SmartUnPack(BrokenPkg, false, Depth + 1); + List->RmFlag(Pkg,pkgOrderList::Loop); + } } + // Check if a package needs to be removed if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) { if (Debug) @@ -706,25 +724,49 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c return false; for (PrvIterator P = instVer.ProvidesList(); - P.end() == false; P++) - CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); + P.end() == false; ++P) + if (Pkg->Group != P.OwnerPkg()->Group) + CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); - if (PkgLoop) return true; + if (PkgLoop) + return true; List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); - if (instVer->MultiArch == pkgCache::Version::Same) + if (Immediate == true && instVer->MultiArch == pkgCache::Version::Same) + { + /* Do lockstep M-A:same unpacking in two phases: + First unpack all installed architectures, then the not installed. + This way we avoid that M-A: enabled packages are installed before + their older non-M-A enabled packages are replaced by newer versions */ + bool const installed = Pkg->CurrentVer != 0; + if (installed == true && Install(Pkg,FileNames[Pkg->ID]) == false) + return false; for (PkgIterator P = Pkg.Group().PackageList(); - P.end() == false; P = Pkg.Group().NextPkg(P)) + P.end() == false; P = Pkg.Group().NextPkg(P)) { - if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true || - Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && - (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) - continue; - SmartUnPack(P, false, Depth + 1); + if (P->CurrentVer == 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true || + Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + continue; + if (SmartUnPack(P, false, Depth + 1) == false) + return false; } - - if(Install(Pkg,FileNames[Pkg->ID]) == false) + if (installed == false && Install(Pkg,FileNames[Pkg->ID]) == false) + return false; + for (PkgIterator P = Pkg.Group().PackageList(); + P.end() == false; P = Pkg.Group().NextPkg(P)) + { + if (P->CurrentVer != 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true || + Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + continue; + if (SmartUnPack(P, false, Depth + 1) == false) + return false; + } + } + // packages which are already unpacked don't need to be unpacked again + else if (Pkg.State() != pkgCache::PkgIterator::NeedsConfigure && Install(Pkg,FileNames[Pkg->ID]) == false) return false; if (Immediate == true) { @@ -763,7 +805,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() clog << "Done ordering" << endl; bool DoneSomething = false; - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) { PkgIterator Pkg(Cache,*I); @@ -826,7 +868,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Failed; // Sanity check - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) { if (List->IsFlag(*I,pkgOrderList::Configured) == false) {