X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/be2033f9563d148c1ebf1b70c46a1aba6501c031..634985f8:/apt-pkg/packagemanager.cc diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 7aef49718..874472a47 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -80,7 +80,7 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, // Skip already processed packages if (List->IsNow(Pkg) == false) continue; - + new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache), FileNames[Pkg->ID]); } @@ -167,6 +167,10 @@ bool pkgPackageManager::CreateOrderList() List = new pkgOrderList(&Cache); static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); + ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false); + + if (Debug && ImmConfigureAll) + 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++) @@ -176,19 +180,21 @@ bool pkgPackageManager::CreateOrderList() continue; // Mark the package and its dependends for immediate configuration - if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) && - NoImmConfigure == false) + NoImmConfigure == false) || ImmConfigureAll) { - if(Debug) + if(Debug && !ImmConfigureAll) clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl; List->Flag(I,pkgOrderList::Immediate); - - // Look for other install packages to make immediate configurea - ImmediateAdd(I, true); - // And again with the current version. - ImmediateAdd(I, false); + if (!ImmConfigureAll) { + // Look for other install packages to make immediate configurea + ImmediateAdd(I, true); + + // And again with the current version. + ImmediateAdd(I, false); + } } // Not interesting @@ -277,9 +283,11 @@ bool pkgPackageManager::ConfigureAll() for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) { PkgIterator Pkg(Cache,*I); - - if (ConfigurePkgs == true && Configure(Pkg) == false) + + if (ConfigurePkgs == true && VerifyAndConfigure(Pkg,OList) == false) { + _error->Error("Internal error, packages left unconfigured. %s",Pkg.Name()); return false; + } List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); } @@ -313,17 +321,114 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) { PkgIterator Pkg(Cache,*I); - if (ConfigurePkgs == true && Configure(Pkg) == false) + if (ConfigurePkgs == true && VerifyAndConfigure(Pkg,OList) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); } + if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same) + for (PkgIterator P = Pkg.Group().PackageList(); + P.end() == false; P = Pkg.Group().NextPkg(P)) + { + if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true || + Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + continue; + SmartConfigure(P); + } + // Sanity Check - if (List->IsFlag(Pkg,pkgOrderList::Configured) == false) - return _error->Error("Internal error, could not immediate configure %s",Pkg.Name()); - + if (List->IsFlag(Pkg,pkgOrderList::Configured) == false && Debug) + _error->Error(_("Could not perform immediate configuration on '%s'. " + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); + + return true; +} + +// PM::VerifyConfigure - Check configuration of dependancies /*{{{*/ +// --------------------------------------------------------------------- +/* This routine checks that all a packages dependancies have been + configured, before it is going to be configured. If this gives a warning + on a virtual package, it means that the package thats providing it is not + configured*/ +bool pkgPackageManager::VerifyConfigure(PkgIterator Pkg, pkgOrderList &OList) +{ + // If this is true at the end, then the package should not be configured + bool error=true; + // This holds the the OR status of the previous dependancy + bool previousOr=false; + + // First iterate through the dependancies of Pkg + for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false; D++) + { + + /* If the dependancy is of type Depends or PreDepends, we need to check it, but only if it is going to be + configured at some point */ + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) { + + /* If the previous package and this package are OR dependancies, and the previous package satisfied the dependancy + then skip this dependancy as it is not relevent, this will repeat for the next package if the situation is the + same */ + if (previousOr && !error) { // As error has not been reset, this refers to the previous dependancy + previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + continue; + } + + // Reset error + error = true; + + // Check thorugh all possible versions of this dependancy (D) + SPtrArray VList = D.AllTargets(); + for (Version **I = VList; *I != 0; I++) + { + VerIterator DepVer(Cache,*I); + PkgIterator DepPkg = DepVer.ParentPkg(); + VerIterator DepInstallVer(Cache,Cache[DepPkg].InstallVer); + + if (DepPkg.CurrentVer() == DepVer && !List->IsFlag(DepPkg,pkgOrderList::UnPacked)) { + error=false; + break; + } + + if (Cache[DepPkg].InstallVer == DepVer && + (List->IsFlag(DepPkg,pkgOrderList::Configured) || OList.IsFlag(DepPkg,pkgOrderList::InList))) { + error=false; + break; + } + } + + /* Only worry here if this package is a OR with the next, as even though this package does not satisfy the OR + the next one might */ + if (error && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) { + _error->Error("Package %s should not be configured because package %s is not configured",Pkg.Name(),D.TargetPkg().Name()); + return false; + /* If the previous package is a OR but not this package, but there is still an error then fail as it will not + be satisfied */ + } else if (error && previousOr && !((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)) { + _error->Error("Package %s should not be configured because package %s (or any alternatives) are not configured",Pkg.Name(),D.TargetPkg().Name()); + return false; + } + + previousOr = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + } else { + previousOr=false; + } + } return true; +} + +// PM::VerifyAndConfigure - Check configuration of dependancies /*{{{*/ +// --------------------------------------------------------------------- +/* This routine verifies if a package can be configured and if so + configures it */ +bool pkgPackageManager::VerifyAndConfigure(PkgIterator Pkg, pkgOrderList &OList) +{ + if (VerifyConfigure(Pkg, OList)) + return Configure(Pkg); + else + return false; + } /*}}}*/ // PM::DepAdd - Add all dependents to the oder list /*{{{*/ @@ -337,6 +442,9 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) return true; if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false) return false; + + if (Debug) + std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl; // Put the package on the list OList.push_back(Pkg); @@ -367,7 +475,33 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) { VerIterator Ver(Cache,*I); PkgIterator Pkg = Ver.ParentPkg(); + VerIterator InstallVer(Cache,Cache[Pkg].InstallVer); + VerIterator CandVer(Cache,Cache[Pkg].CandidateVer); + + if (Debug && false) { + if (Ver==0) { + cout << OutputInDepth(Depth) << "Checking if " << Ver << " of " << Pkg.Name() << " satisfies this dependancy" << endl; + } else { + cout << OutputInDepth(Depth) << "Checking if " << Ver.VerStr() << " of " << Pkg.Name() << " satisfies this dependancy" << endl; + } + + if (Pkg.CurrentVer()==0) { + cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl; + } else { + cout << OutputInDepth(Depth) << " CurrentVer " << Pkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(Pkg) << " NeedsNothing " << (Pkg.State() == PkgIterator::NeedsNothing) << endl; + } + if (InstallVer==0) { + cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer << endl; + } else { + cout << OutputInDepth(Depth )<< " InstallVer " << InstallVer.VerStr() << endl; + } + if (CandVer != 0) + cout << OutputInDepth(Depth ) << " CandVer " << CandVer.VerStr() << endl; + + cout << OutputInDepth(Depth) << " Keep " << Cache[Pkg].Keep() << " Unpacked " << List->IsFlag(Pkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(Pkg,pkgOrderList::Configured) << endl; + + } // See if the current version is ok if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && Pkg.State() == PkgIterator::NeedsNothing) @@ -377,8 +511,9 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) } // Not the install version - if (Cache[Pkg].InstallVer != *I || - (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) + if ((Cache[Pkg].InstallVer != *I && Cache[Pkg].CandidateVer != *I) || + (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) continue; if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true) @@ -390,6 +525,8 @@ bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) if (Bad == true) { + if (Debug) + std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl; OList.Flag(Pkg,0,pkgOrderList::Added); OList.pop_back(); Depth--; @@ -459,7 +596,9 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) return true; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); + return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); + return true; } /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ @@ -467,21 +606,31 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) /* This performs the task of handling pre-depends. */ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) { + return SmartUnPack(Pkg, true); +} +bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) +{ + if (Debug == true) + clog << "SmartUnPack " << Pkg.Name() << endl; + // Check if it is already unpacked if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && Cache[Pkg].Keep() == true) { List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); - if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true) + if (Immediate == true && + List->IsFlag(Pkg,pkgOrderList::Immediate) == true) if (SmartConfigure(Pkg) == false) - return _error->Error(_("Could not perform immediate configuration for on already unpacked %s." + _error->Warning(_("Could not perform immediate configuration on already unpacked '%s'. " "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name()); return true; } + + VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); /* See if this packages install version has any predependencies that are not met by 'now' packages. */ - for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); + for (DepIterator D = instVer.DependsList(); D.end() == false; ) { // Compute a single dependency element (glob or) @@ -491,7 +640,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) while (End->Type == pkgCache::Dep::PreDepends) { - if (Debug == true) + if (Debug) clog << "PreDepends order for " << Pkg.Name() << std::endl; // Look for possible ok targets. @@ -507,7 +656,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) Pkg.State() == PkgIterator::NeedsNothing) { Bad = false; - if (Debug == true) + if (Debug) clog << "Found ok package " << Pkg.Name() << endl; continue; } @@ -524,7 +673,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) continue; - if (Debug == true) + if (Debug) clog << "Trying to SmartConfigure " << Pkg.Name() << endl; Bad = !SmartConfigure(Pkg); } @@ -540,7 +689,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) End.TargetPkg().Name(),Pkg.Name()); Start++; } - else + else break; } @@ -553,37 +702,250 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) for (Version **I = VList; *I != 0; I++) { VerIterator Ver(Cache,*I); - PkgIterator Pkg = Ver.ParentPkg(); + PkgIterator ConflictPkg = Ver.ParentPkg(); + VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer); // See if the current version is conflicting - if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true) + if (ConflictPkg.CurrentVer() == Ver && !List->IsFlag(ConflictPkg,pkgOrderList::UnPacked)) { - if (EarlyRemove(Pkg) == false) - return _error->Error("Internal Error, Could not early remove %s",Pkg.Name()); + if (Debug && false) + cout << " " << Pkg.Name() << " conflicts with " << ConflictPkg.Name() << endl; + + if (Debug && false) { + if (Ver==0) { + cout << " Checking if " << Ver << " of " << ConflictPkg.Name() << " satisfies this dependancy" << endl; + } else { + cout << " Checking if " << Ver.VerStr() << " of " << ConflictPkg.Name() << " satisfies this dependancy" << endl; + } + + if (ConflictPkg.CurrentVer()==0) { + cout << " CurrentVer " << ConflictPkg.CurrentVer() << " IsNow " << List->IsNow(ConflictPkg) << " NeedsNothing " << (ConflictPkg.State() == PkgIterator::NeedsNothing) << endl; + } else { + cout << " CurrentVer " << ConflictPkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(ConflictPkg) << " NeedsNothing " << (ConflictPkg.State() == PkgIterator::NeedsNothing) << endl; + } + + if (InstallVer==0) { + cout << " InstallVer " << InstallVer << endl; + } else { + cout << " InstallVer " << InstallVer.VerStr() << endl; + } + + cout << " Keep " << Cache[ConflictPkg].Keep() << " Unpacked " << List->IsFlag(ConflictPkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(ConflictPkg,pkgOrderList::Configured) << " Removed " << List->IsFlag(ConflictPkg,pkgOrderList::Removed) << " Loop " << List->IsFlag(ConflictPkg,pkgOrderList::Loop) << endl; + cout << " Delete " << Cache[ConflictPkg].Delete() << endl; + } + + if (!List->IsFlag(ConflictPkg,pkgOrderList::Loop)) { + if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0) { + cout << "Unpacking " << ConflictPkg.Name() << " to prevent conflict" << endl; + List->Flag(Pkg,pkgOrderList::Loop); + SmartUnPack(ConflictPkg,false); + } else { + if (EarlyRemove(ConflictPkg) == false) + return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); + } + } else { + if (!List->IsFlag(ConflictPkg,pkgOrderList::Removed)) { + cout << "Because of conficts knot, removing " << ConflictPkg.Name() << " to conflict violation" << endl; + if (EarlyRemove(ConflictPkg) == false) + return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); + } + } } } } - } + + // Check for breaks + if (End->Type == pkgCache::Dep::DpkgBreaks) { + SPtrArray VList = End.AllTargets(); + for (Version **I = VList; *I != 0; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator BrokenPkg = Ver.ParentPkg(); + VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer); + + cout << " " << Pkg.Name() << " breaks " << BrokenPkg.Name() << endl; + if (Debug && false) { + if (Ver==0) { + cout << " Checking if " << Ver << " of " << BrokenPkg.Name() << " satisfies this dependancy" << endl; + } else { + cout << " Checking if " << Ver.VerStr() << " of " << BrokenPkg.Name() << " satisfies this dependancy" << endl; + } + + if (BrokenPkg.CurrentVer()==0) { + cout << " CurrentVer " << BrokenPkg.CurrentVer() << " IsNow " << List->IsNow(BrokenPkg) << " NeedsNothing " << (BrokenPkg.State() == PkgIterator::NeedsNothing) << endl; + } else { + cout << " CurrentVer " << BrokenPkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(BrokenPkg) << " NeedsNothing " << (BrokenPkg.State() == PkgIterator::NeedsNothing) << endl; + } + + if (InstallVer==0) { + cout << " InstallVer " << InstallVer << endl; + } else { + cout << " InstallVer " << InstallVer.VerStr() << endl; + } - // Check for reverse conflicts. - if (CheckRConflicts(Pkg,Pkg.RevDependsList(), - Cache[Pkg].InstVerIter(Cache).VerStr()) == false) - return false; + cout << " Keep " << Cache[BrokenPkg].Keep() << " Unpacked " << List->IsFlag(BrokenPkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(BrokenPkg,pkgOrderList::Configured) << " Removed " << List->IsFlag(BrokenPkg,pkgOrderList::Removed) << " Loop " << List->IsFlag(BrokenPkg,pkgOrderList::Loop) << " InList " << List->IsFlag(BrokenPkg,pkgOrderList::InList) << endl; + cout << " Delete " << Cache[BrokenPkg].Delete() << endl; + } + // Check if it needs to be unpacked + if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false && + !List->IsFlag(BrokenPkg,pkgOrderList::Loop) && List->IsNow(BrokenPkg)) { + List->Flag(Pkg,pkgOrderList::Loop); + // Found a break, so unpack the package + if (Debug) + cout << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + SmartUnPack(BrokenPkg, false); + } + // Check if a package needs to be removed + if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) { + if (Debug) + cout << " Removing " << BrokenPkg.Name() << " to avoid break" << endl; + SmartRemove(BrokenPkg); + } + } + } + } - for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList(); - P.end() == false; P++) - CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); + // FIXME: Crude but effective fix, allows the SmartUnPack method to be used for packages that new to the system + if (instVer != 0) { + //cout << "Check for reverse conflicts on " << Pkg.Name() << " " << instVer.VerStr() << endl; - if (Install(Pkg,FileNames[Pkg->ID]) == false) - return false; + // Check for reverse conflicts. + if (CheckRConflicts(Pkg,Pkg.RevDependsList(), + instVer.VerStr()) == false) + return false; - List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); + for (PrvIterator P = instVer.ProvidesList(); + P.end() == false; P++) + CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); + + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); + + if (instVer->MultiArch == pkgCache::Version::Same) + for (PkgIterator P = Pkg.Group().PackageList(); + 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); + } + + } else { + VerIterator InstallVer(Cache,Cache[Pkg].InstallVer); + //cout << "Check for reverse conflicts on " << Pkg.Name() << " " << InstallVer.VerStr() << endl; + + // Check for reverse conflicts. + if (CheckRConflicts(Pkg,Pkg.RevDependsList(), + InstallVer.VerStr()) == false) + return false; + + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); + } + + if(Install(Pkg,FileNames[Pkg->ID]) == false) + return false; + + /* Because of the ordered list, most dependancies should be unpacked, + however if there is a loop this is not the case, so check for dependancies before configuring. + This is done after the package installation as it makes it easier to deal with conflicts problems */ + bool Bad = true; + for (DepIterator D = instVer.DependsList(); + D.end() == false; ) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + + if (End->Type == pkgCache::Dep::Depends) + Bad = true; + + // Check for dependanices that have not been unpacked, probably due to loops. + while (End->Type == pkgCache::Dep::Depends) { + PkgIterator DepPkg; + VerIterator InstallVer; + SPtrArray VList = Start.AllTargets(); + + for (Version **I = VList; *I != 0; I++) { + VerIterator Ver(Cache,*I); + DepPkg = Ver.ParentPkg(); + + if (!Bad) continue; + + InstallVer = VerIterator(Cache,Cache[DepPkg].InstallVer); + VerIterator CandVer(Cache,Cache[DepPkg].CandidateVer); + + if (Debug && false) { + if (Ver==0) { + cout << " Checking if " << Ver << " of " << DepPkg.Name() << " satisfies this dependancy" << endl; + } else { + cout << " Checking if " << Ver.VerStr() << " of " << DepPkg.Name() << " satisfies this dependancy" << endl; + } + + if (DepPkg.CurrentVer()==0) { + cout << " CurrentVer " << DepPkg.CurrentVer() << " IsNow " << List->IsNow(DepPkg) << " NeedsNothing " << (DepPkg.State() == PkgIterator::NeedsNothing) << endl; + } else { + cout << " CurrentVer " << DepPkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(DepPkg) << " NeedsNothing " << (DepPkg.State() == PkgIterator::NeedsNothing) << endl; + } + + if (InstallVer==0) { + cout << " InstallVer " << InstallVer << endl; + } else { + cout << " InstallVer " << InstallVer.VerStr() << endl; + } + if (CandVer != 0) + cout << " CandVer " << CandVer.VerStr() << endl; + + cout << " Keep " << Cache[DepPkg].Keep() << " Unpacked " << List->IsFlag(DepPkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(DepPkg,pkgOrderList::Configured) << endl; + + } + + // Check if it satisfies this dependancy + if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && + DepPkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + continue; + } + + if (Cache[DepPkg].InstallVer == *I && !List->IsNow(DepPkg)) { + Bad = false; + continue; + } + } + + if (InstallVer != 0 && Bad) { + Bad = false; + // Found a break, so unpack the package + List->Flag(Pkg,pkgOrderList::Loop); + if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { + if (Debug) + cout << " Unpacking " << DepPkg.Name() << " to avoid loop" << endl; + SmartUnPack(DepPkg, false); + } + } + + if (Start==End) { + if (Bad && Debug) { + if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { + _error->Warning("Could not satisfy dependancies for %s",Pkg.Name()); + } + } + break; + + } else { + Start++; + } + } + } // Perform immedate configuration of the package. - if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true) + if (Immediate == true && + List->IsFlag(Pkg,pkgOrderList::Immediate) == true && !Bad) if (SmartConfigure(Pkg) == false) - return _error->Error(_("Could not perform immediate configuration on %s." - "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name()); + _error->Warning(_("Could not perform immediate configuration on '%s'. " + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); return true; } @@ -617,12 +979,19 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() 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; + if (!List->IsFlag(Pkg,pkgOrderList::Configured)) { + if (SmartConfigure(Pkg) == false && Debug) + _error->Warning("Internal Error, Could not configure %s",Pkg.Name()); + // FIXME: The above warning message might need changing + } else { + if (Debug == true) + clog << "Skipping already done " << Pkg.Name() << endl; + } continue; + } if (List->IsMissing(Pkg) == true) @@ -671,7 +1040,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() PkgIterator(Cache,*I).Name()); return Failed; } - } + } return Completed; } @@ -703,4 +1072,4 @@ pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) return DoInstallPostFork(statusFd); } - /*}}}*/ + /*}}}*/