summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/pool.c25
-rw-r--r--src/repodata.c6
-rw-r--r--src/solver.c28
4 files changed, 54 insertions, 6 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f91c9c0..6abb3ad 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -55,7 +55,6 @@ ENDIF (DISABLE_SHARED)
SET_TARGET_PROPERTIES(libsolv PROPERTIES OUTPUT_NAME "solv")
SET_TARGET_PROPERTIES(libsolv PROPERTIES SOVERSION ${LIBSOLV_SOVERSION})
-SET_TARGET_PROPERTIES(libsolv PROPERTIES INSTALL_NAME_DIR ${CMAKE_INSTALL_LIBDIR})
INSTALL (FILES ${libsolv_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/solv")
INSTALL (TARGETS libsolv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/src/pool.c b/src/pool.c
index a554453..4b63727 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -814,6 +814,23 @@ pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, Id evr)
return pool_match_flags_evr(pool, pflags, pevr, flags, evr);
}
+
+static int
+is_interval_dep(Pool *pool, Id d1, Id d2)
+{
+ Reldep *rd1, *rd2;
+ if (!ISRELDEP(d1) || !ISRELDEP(d2))
+ return 0;
+ rd1 = GETRELDEP(pool, d1);
+ rd2 = GETRELDEP(pool, d2);
+ if (rd1->name != rd2->name || rd1->flags >= 8 || rd2->flags >= 8)
+ return 0;
+ if (((rd1->flags ^ rd2->flags) & (REL_LT|REL_GT)) != (REL_LT|REL_GT))
+ return 0;
+ return 1;
+}
+
+
/* match two dependencies (d1 = provider) */
int
@@ -830,6 +847,8 @@ pool_match_dep(Pool *pool, Id d1, Id d2)
rd1 = GETRELDEP(pool, d1);
if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_WITHOUT || rd1->flags == REL_COND || rd1->flags == REL_UNLESS)
{
+ if (rd1->flags == REL_WITH && is_interval_dep(pool, rd1->name, rd1->evr))
+ return pool_match_dep(pool, rd1->name, d2) && pool_match_dep(pool, rd1->evr, d2);
if (pool_match_dep(pool, rd1->name, d2))
return 1;
if ((rd1->flags == REL_COND || rd1->flags == REL_UNLESS) && ISRELDEP(rd1->evr))
@@ -849,6 +868,8 @@ pool_match_dep(Pool *pool, Id d1, Id d2)
rd2 = GETRELDEP(pool, d2);
if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_WITHOUT || rd2->flags == REL_COND || rd2->flags == REL_UNLESS)
{
+ if (rd2->flags == REL_WITH && is_interval_dep(pool, rd2->name, rd2->evr))
+ return pool_match_dep(pool, d1, rd2->name) && pool_match_dep(pool, d1, rd2->evr);
if (pool_match_dep(pool, d1, rd2->name))
return 1;
if ((rd2->flags == REL_COND || rd2->flags == REL_UNLESS) && ISRELDEP(rd2->evr))
@@ -1355,9 +1376,9 @@ pool_addrelproviders(Pool *pool, Id d)
continue;
}
}
- if (!s->provides)
+ if (!s->provides || s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
{
- /* no provides - check nevr */
+ /* no provides or src rpm - check nevr */
if (pool_match_nevr_rel(pool, s, MAKERELDEP(d)))
queue_push(&plist, p);
continue;
diff --git a/src/repodata.c b/src/repodata.c
index 0c7a51f..3cae0fe 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -211,11 +211,13 @@ repodata_schema2id(Repodata *data, Id *schema, int create)
cid = schematahash[h];
if (cid)
{
- if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
+ if ((data->schemata[cid] + len <= data->schemadatalen) &&
+ !memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
return cid;
/* cache conflict, do a slow search */
for (cid = 1; cid < data->nschemata; cid++)
- if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
+ if ((data->schemata[cid] + len <= data->schemadatalen) &&
+ !memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
return cid;
}
/* a new one */
diff --git a/src/solver.c b/src/solver.c
index e7a9dc0..5453b39 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -1720,12 +1720,27 @@ resolve_installed(Solver *solv, int level, int disablerules, Queue *dq)
{
if (specialupdaters && (d = specialupdaters[i - installed->start]) != 0)
{
+ int j;
/* special multiversion handling, make sure best version is chosen */
if (rr->p == i && solv->decisionmap[i] >= 0)
queue_push(dq, i);
while ((p = pool->whatprovidesdata[d++]) != 0)
if (solv->decisionmap[p] >= 0)
queue_push(dq, p);
+ for (j = 0; j < dq->count; j++)
+ {
+ Id p2 = dq->elements[j];
+ if (pool->solvables[p2].repo != installed)
+ continue;
+ d = specialupdaters[i - installed->start];
+ while ((p = pool->whatprovidesdata[d++]) != 0)
+ {
+ if (solv->decisionmap[p] >= 0 || pool->solvables[p].repo == installed)
+ continue;
+ if (solvable_identical(pool->solvables + p, pool->solvables + p2))
+ queue_push(dq, p); /* identical to installed, put it on the list so we have a repo prio */
+ }
+ }
if (dq->count && solv->update_targets && solv->update_targets->elements[i - installed->start])
prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[i - installed->start], dq);
if (dq->count)
@@ -3858,6 +3873,10 @@ solver_solve(Solver *solv, Queue *job)
name_s = s;
}
solver_addjobrule(solv, -p, 0, 0, i, weak);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
+ solver_addjobrule(solv, -solv->instbuddy[p - installed->start], 0, 0, i, weak);
+#endif
}
/* special case for "erase a specific solvable": we also
* erase all other solvables with that name, so that they
@@ -3925,7 +3944,14 @@ solver_solve(Solver *solv, Queue *job)
}
}
FOR_JOB_SELECT(p, pp, select, what)
- solver_addjobrule(solv, installed && pool->solvables[p].repo == installed ? p : -p, 0, 0, i, weak);
+ {
+ s = pool->solvables + p;
+ solver_addjobrule(solv, installed && s->repo == installed ? p : -p, 0, 0, i, weak);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
+ solver_addjobrule(solv, solv->instbuddy[p - installed->start], 0, 0, i, weak);
+#endif
+ }
if (solv->nrules != oldnrules)
haslockjob = 1;
break;