summaryrefslogtreecommitdiff
path: root/apt-pkg/algorithms.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/algorithms.cc')
-rw-r--r--apt-pkg/algorithms.cc105
1 files changed, 39 insertions, 66 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index bbe315ef7..6f1f82d50 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -104,9 +104,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
DepIterator Start;
DepIterator End;
D.GlobOr(Start,End);
- if (Start->Type == pkgCache::Dep::Conflicts ||
- Start->Type == pkgCache::Dep::DpkgBreaks ||
- Start->Type == pkgCache::Dep::Obsoletes ||
+ if (Start.IsNegative() == true ||
End->Type == pkgCache::Dep::PreDepends)
{
if ((Sim[End] & pkgDepCache::DepGInstall) == 0)
@@ -332,6 +330,12 @@ bool pkgFixBroken(pkgDepCache &Cache)
*/
bool pkgDistUpgrade(pkgDepCache &Cache)
{
+ std::string const solver = _config->Find("APT::Solver::Name", "internal");
+ if (solver != "internal") {
+ OpTextProgress Prog(*_config);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog);
+ }
+
pkgDepCache::ActionGroup group(Cache);
/* Upgrade all installed packages first without autoinst to help the resolver
@@ -384,6 +388,12 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
to install packages not marked for install */
bool pkgAllUpgrade(pkgDepCache &Cache)
{
+ std::string const solver = _config->Find("APT::Solver::Name", "internal");
+ if (solver != "internal") {
+ OpTextProgress Prog(*_config);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+ }
+
pkgDepCache::ActionGroup group(Cache);
pkgProblemResolver Fix(&Cache);
@@ -650,12 +660,10 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
// Compute a single dependency element (glob or)
pkgCache::DepIterator Start = D;
pkgCache::DepIterator End = D;
- unsigned char State = 0;
for (bool LastOR = true; D.end() == false && LastOR == true;)
{
- State |= Cache[D];
LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
- D++;
+ ++D;
if (LastOR == true)
End = D;
}
@@ -700,9 +708,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
{
/* We let the algorithm deal with conflicts on its next iteration,
it is much smarter than us */
- if (Start->Type == pkgCache::Dep::Conflicts ||
- Start->Type == pkgCache::Dep::DpkgBreaks ||
- Start->Type == pkgCache::Dep::Obsoletes)
+ if (Start.IsNegative() == true)
break;
if (Debug == true)
@@ -740,46 +746,9 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
bool pkgProblemResolver::Resolve(bool BrokenFix)
{
std::string const solver = _config->Find("APT::Solver::Name", "internal");
-
- if (solver != "internal")
- {
-// std::string const file = _config->FindDir("Dir::Bin::Solvers") + solver;
- std::string const file = solver;
- if (RealFileExists(file.c_str()) == false)
- return _error->Error("Can't call external solver '%s' as it is not available: %s", solver.c_str(), file.c_str());
- int external[4] = {-1, -1, -1, -1};
- if (pipe(external) != 0 || pipe(external + 2) != 0)
- return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP");
- for (int i = 0; i < 4; ++i)
- SetCloseExec(external[i], true);
-
- pid_t Solver = ExecFork();
- if (Solver == 0)
- {
- dup2(external[0], STDIN_FILENO);
- dup2(external[3], STDOUT_FILENO);
- const char* calling[2] = { file.c_str(), 0 };
- execv(calling[0], (char**) calling);
- std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl;
- _exit(100);
- }
- close(external[0]);
- close(external[3]);
-
- if (WaitFd(external[1], true, 5) == false)
- return _error->Errno("Resolve", "Waiting on availability of solver stdin timed out");
-
- FILE* output = fdopen(external[1], "w");
- if (output == NULL)
- return _error->Errno("Resolve", "fdopen on solver stdin failed");
- EDSP::WriteRequest(Cache, output);
- EDSP::WriteScenario(Cache, output);
- fclose(output);
-
- if (EDSP::ReadResponse(external[2], Cache) == false)
- return _error->Error("Reading solver response failed");
-
- return ExecWait(Solver, solver.c_str(), false);
+ if (solver != "internal") {
+ OpTextProgress Prog(*_config);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog);
}
return ResolveInternal(BrokenFix);
}
@@ -981,9 +950,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
if a package has a dep on another package that cant be found */
SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
- Start->Type != pkgCache::Dep::Conflicts &&
- Start->Type != pkgCache::Dep::DpkgBreaks &&
- Start->Type != pkgCache::Dep::Obsoletes &&
+ Start.IsNegative() == false &&
Cache[I].NowBroken() == false)
{
if (InOr == true)
@@ -1008,10 +975,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
at is not the currently selected version of the
package, which means it is not necessary to
remove/keep */
- if (Cache[Pkg].InstallVer != Ver &&
- (Start->Type == pkgCache::Dep::Conflicts ||
- Start->Type == pkgCache::Dep::DpkgBreaks ||
- Start->Type == pkgCache::Dep::Obsoletes))
+ if (Cache[Pkg].InstallVer != Ver && Start.IsNegative() == true)
{
if (Debug)
clog << " Conflicts//Breaks against version "
@@ -1029,9 +993,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
fiddle with the VList package */
if (Scores[I->ID] <= Scores[Pkg->ID] ||
((Cache[Start] & pkgDepCache::DepNow) == 0 &&
- End->Type != pkgCache::Dep::Conflicts &&
- End->Type != pkgCache::Dep::DpkgBreaks &&
- End->Type != pkgCache::Dep::Obsoletes))
+ End.IsNegative() == false))
{
// Try a little harder to fix protected packages..
if ((Flags[I->ID] & Protected) == Protected)
@@ -1138,10 +1100,8 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
}
// Hm, nothing can possibly satisify this dep. Nuke it.
- if (VList[0] == 0 &&
- Start->Type != pkgCache::Dep::Conflicts &&
- Start->Type != pkgCache::Dep::DpkgBreaks &&
- Start->Type != pkgCache::Dep::Obsoletes &&
+ if (VList[0] == 0 &&
+ Start.IsNegative() == false &&
(Flags[I->ID] & Protected) != Protected)
{
bool Installed = Cache[I].Install();
@@ -1187,9 +1147,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
Change = true;
if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0)
{
- if (J->Dep->Type == pkgCache::Dep::Conflicts ||
- J->Dep->Type == pkgCache::Dep::DpkgBreaks ||
- J->Dep->Type == pkgCache::Dep::Obsoletes)
+ if (J->Dep.IsNegative() == true)
{
if (Debug == true)
clog << " Fixing " << I.FullName(false) << " via remove of " << J->Pkg.FullName(false) << endl;
@@ -1253,6 +1211,21 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
system was non-broken previously. */
bool pkgProblemResolver::ResolveByKeep()
{
+ std::string const solver = _config->Find("APT::Solver::Name", "internal");
+ if (solver != "internal") {
+ OpTextProgress Prog(*_config);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+ }
+ return ResolveByKeepInternal();
+}
+ /*}}}*/
+// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/
+// ---------------------------------------------------------------------
+/* This is the work horse of the soft upgrade routine. It is very gental
+ in that it does not install or remove any packages. It is assumed that the
+ system was non-broken previously. */
+bool pkgProblemResolver::ResolveByKeepInternal()
+{
pkgDepCache::ActionGroup group(Cache);
unsigned long Size = Cache.Head().PackageCount;