-/********************************************************************
- *
- * dependency check helpers
- *
- */
-
-/*-------------------------------------------------------------------
- * handle split provides
- *
- * a splitprovides dep looks like
- * namespace:splitprovides(pkg REL_WITH path)
- * and is only true if pkg is installed and contains the specified path.
- * we also make sure that pkg is selected for an update, otherwise the
- * update would always be forced onto the user.
- */
-int
-solver_splitprovides(Solver *solv, Id dep)
-{
- Pool *pool = solv->pool;
- Id p, pp;
- Reldep *rd;
- Solvable *s;
-
- if (!solv->dosplitprovides || !solv->installed || (!solv->updatemap_all && !solv->updatemap.size))
- return 0;
- if (!ISRELDEP(dep))
- return 0;
- rd = GETRELDEP(pool, dep);
- if (rd->flags != REL_WITH)
- return 0;
- /*
- * things are a bit tricky here if pool->addedprovides == 1, because most split-provides are in
- * a non-standard location. If we simply call pool_whatprovides, we'll drag in the complete
- * file list. Instead we rely on pool_addfileprovides ignoring the addfileprovidesfiltered flag
- * for installed packages and check the lazywhatprovidesq (ignoring the REL_WITH part, but
- * we filter the package name further down anyway).
- */
- if (pool->addedfileprovides == 1 && !ISRELDEP(rd->evr) && !pool->whatprovides[rd->evr])
- pp = pool_searchlazywhatprovidesq(pool, rd->evr);
- else
- pp = pool_whatprovides(pool, dep);
- while ((p = pool->whatprovidesdata[pp++]) != 0)
- {
- /* here we have packages that provide the correct name and contain the path,
- * now do extra filtering */
- s = pool->solvables + p;
- if (s->repo == solv->installed && s->name == rd->name &&
- (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, p - solv->installed->start))))
- return 1;
- }
- return 0;
-}
-
-
-/*-------------------------------------------------------------------
- * solver_dep_installed
- */
-
-int
-solver_dep_installed(Solver *solv, Id dep)
-{
-#if 0
- Pool *pool = solv->pool;
- Id p, pp;
-
- if (ISRELDEP(dep))
- {
- Reldep *rd = GETRELDEP(pool, dep);
- if (rd->flags == REL_AND)
- {
- if (!solver_dep_installed(solv, rd->name))
- return 0;
- return solver_dep_installed(solv, rd->evr);
- }
- if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
- return solver_dep_installed(solv, rd->evr);
- }
- FOR_PROVIDES(p, pp, dep)
- {
- if (p == SYSTEMSOLVABLE || (solv->installed && pool->solvables[p].repo == solv->installed))
- return 1;
- }
-#endif
- return 0;
-}
-
-/* mirrors solver_dep_installed, but returns 2 if a
- * dependency listed in solv->installsuppdepq was involved */
-static int
-solver_check_installsuppdepq_dep(Solver *solv, Id dep)
-{
- Pool *pool = solv->pool;
- Id p, pp;
- Queue *q;
-
- if (ISRELDEP(dep))
- {
- Reldep *rd = GETRELDEP(pool, dep);
- if (rd->flags == REL_AND)
- {
- int r2, r1 = solver_check_installsuppdepq_dep(solv, rd->name);
- if (!r1)
- return 0;
- r2 = solver_check_installsuppdepq_dep(solv, rd->evr);
- if (!r2)
- return 0;
- return r1 == 2 || r2 == 2 ? 2 : 1;
- }
- if (rd->flags == REL_OR)
- {
- int r2, r1 = solver_check_installsuppdepq_dep(solv, rd->name);
- r2 = solver_check_installsuppdepq_dep(solv, rd->evr);
- if (!r1 && !r2)
- return 0;
- return r1 == 2 || r2 == 2 ? 2 : 1;
- }
- if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
- return solver_splitprovides(solv, rd->evr);
- if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
- return solver_dep_installed(solv, rd->evr);
- if (rd->flags == REL_NAMESPACE && (q = solv->installsuppdepq) != 0)
- {
- int i;
- for (i = 0; i < q->count; i++)
- if (q->elements[i] == dep || q->elements[i] == rd->name)
- return 2;
- }
- }
- FOR_PROVIDES(p, pp, dep)
- if (solv->decisionmap[p] > 0)
- return 1;
- return 0;
-}
-
-static int
-solver_check_installsuppdepq(Solver *solv, Solvable *s)
-{
- Id sup, *supp;
- supp = s->repo->idarraydata + s->supplements;
- while ((sup = *supp++) != 0)
- if (solver_check_installsuppdepq_dep(solv, sup) == 2)
- return 1;
- return 0;
-}
-
-static Id
-autouninstall(Solver *solv, Id *problem)
-{
- Pool *pool = solv->pool;
- int i;
- int lastfeature = 0, lastupdate = 0;
- Id v;
- Id extraflags = -1;
-
- for (i = 0; (v = problem[i]) != 0; i++)
- {
- if (v < 0)
- extraflags &= solv->job.elements[-v - 1];
- if (v >= solv->featurerules && v < solv->featurerules_end)
- if (v > lastfeature)
- lastfeature = v;
- if (v >= solv->updaterules && v < solv->updaterules_end)
- {
- /* check if identical to feature rule */
- Id p = solv->rules[v].p;
- Rule *r;
- if (p <= 0)
- continue;
- r = solv->rules + solv->featurerules + (p - solv->installed->start);
- if (!r->p)
- {
- /* update rule == feature rule */
- if (v > lastfeature)
- lastfeature = v;
- continue;
- }
- if (v > lastupdate)
- lastupdate = v;
- }
- }
- if (!lastupdate && !lastfeature)
- return 0;
- v = lastupdate ? lastupdate : lastfeature;
- POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "allowuninstall disabling ");
- solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + v);
- solver_disableproblem(solv, v);
- if (extraflags != -1 && (extraflags & SOLVER_CLEANDEPS) != 0 && solv->cleandepsmap.size)
- {
- /* add the package to the updatepkgs list, this will automatically turn
- * on cleandeps mode */
- Id p = solv->rules[v].p;
- if (!solv->cleandeps_updatepkgs)
- {
- solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue));
- queue_init(solv->cleandeps_updatepkgs);
- }
- if (p > 0)
- {
- int oldupdatepkgscnt = solv->cleandeps_updatepkgs->count;
- queue_pushunique(solv->cleandeps_updatepkgs, p);
- if (solv->cleandeps_updatepkgs->count != oldupdatepkgscnt)
- solver_disablepolicyrules(solv);
- }
- }
- return v;
-}