From 0a5fdc05f0d01e810270f75c52492837415e9fe3 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 19 Jun 2009 18:52:23 +0200 Subject: [PATCH] - add support for REL_FILECONFLICT - add findfileconflicts.c demo app --- src/pool.c | 56 ++++++++++++++++++++++++++++++++++++- src/pool.h | 4 +++ src/poolid.c | 7 +++++ tools/findfileconflicts.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 tools/findfileconflicts.c diff --git a/src/pool.c b/src/pool.c index 73fc1c2..4fa4e25 100644 --- a/src/pool.c +++ b/src/pool.c @@ -620,10 +620,27 @@ pool_addrelproviders(Pool *pool, Id d) } if (wp) { + /* all solvables match, no need to create a new list */ pool->whatprovides_rel[d] = wp; return wp; } break; + case REL_FILECONFLICT: + pp = pool_whatprovides_ptr(pool, name); + while ((p = *pp++) != 0) + { + Id origd = MAKERELDEP(d); + Solvable *s = pool->solvables + p; + if (!s->provides) + continue; + pidp = s->repo->idarraydata + s->provides; + while ((pid = *pidp++) != 0) + if (pid == origd) + break; + if (pid) + queue_push(&plist, p); + } + break; default: break; } @@ -810,6 +827,11 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct sea } dep = rd->evr; } + else if (rd->flags == REL_FILECONFLICT) + { + dep = 0; + break; + } else { Id ids[2]; @@ -1709,4 +1731,36 @@ pool_lookup_checksum(Pool *pool, Id entry, Id keyname, Id *typep) return solvable_lookup_checksum(pool->solvables + entry, keyname, typep); } -// EOF +void +pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts) +{ + int hadhashes = pool->relhashtbl ? 1 : 0; + Solvable *s; + Id fn, p, q, md5; + Id id; + int i; + + if (!conflicts->count) + return; + pool_freewhatprovides(pool); + for (i = 0; i < conflicts->count; i += 5) + { + fn = conflicts->elements[i]; + p = conflicts->elements[i + 1]; + md5 = conflicts->elements[i + 2]; + q = conflicts->elements[i + 3]; + id = rel2id(pool, fn, md5, REL_FILECONFLICT, 1); + s = pool->solvables + p; + if (!s->repo) + continue; + s->provides = repo_addid_dep(s->repo, s->provides, id, SOLVABLE_FILEMARKER); + s = pool->solvables + q; + if (!s->repo) + continue; + s->conflicts = repo_addid_dep(s->repo, s->conflicts, id, 0); + } + if (!hadhashes) + pool_freeidhashes(pool); +} + +/* EOF */ diff --git a/src/pool.h b/src/pool.h index 2e657ad..e985211 100644 --- a/src/pool.h +++ b/src/pool.h @@ -154,6 +154,7 @@ struct _Pool { #define REL_WITH 18 #define REL_NAMESPACE 19 #define REL_ARCH 20 +#define REL_FILECONFLICT 21 #if !defined(__GNUC__) && !defined(__attribute__) # define __attribute__(x) @@ -316,6 +317,9 @@ int pool_lookup_void(Pool *pool, Id entry, Id keyname); const unsigned char *pool_lookup_bin_checksum(Pool *pool, Id entry, Id keyname, Id *typep); const char *pool_lookup_checksum(Pool *pool, Id entry, Id keyname, Id *typep); +void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts); + + /* loop over all providers of d */ #define FOR_PROVIDES(v, vp, d) \ diff --git a/src/poolid.c b/src/poolid.c index cd5f4d7..a0059e2 100644 --- a/src/poolid.c +++ b/src/poolid.c @@ -168,6 +168,8 @@ id2rel(Pool *pool, Id id) return " NAMESPACE "; /* actually not used in dep2str */ case REL_ARCH: return "."; + case REL_FILECONFLICT: + return " FILECONFLICT "; default: break; } @@ -232,6 +234,11 @@ dep2strcpy(Pool *pool, char *p, Id id, int oldrel) strcat(p, ")"); return; } + if (rd->flags == REL_FILECONFLICT) + { + *p = 0; + return; + } strcpy(p, id2rel(pool, id)); p += strlen(p); id = rd->evr; diff --git a/tools/findfileconflicts.c b/tools/findfileconflicts.c new file mode 100644 index 0000000..88833d5 --- /dev/null +++ b/tools/findfileconflicts.c @@ -0,0 +1,71 @@ +#include +#include + +#include "pool.h" +#include "repo.h" +#include "solver.h" +#include "solverdebug.h" +#include "hash.h" +#include "repo_rpmdb.h" +#include "pool_fileconflicts.h" + +static void * +iterate_handle(Pool *pool, Id p, void *cbdata) +{ + Solvable *s = pool->solvables + p; + Id rpmdbid; + + if (!p) + { + rpm_byrpmdbid(0, 0, (void **)cbdata); + return 0; + } + if (!s->repo->rpmdbid) + return 0; + rpmdbid = s->repo->rpmdbid[p - s->repo->start]; + if (!rpmdbid) + return 0; + return rpm_byrpmdbid(rpmdbid, 0, (void **)cbdata); +} + +int main() +{ + Pool *pool; + Repo *installed; + Solvable *s; + Id p; + int i; + Queue todo, conflicts; + void *state = 0; + + pool = pool_create(); + installed = repo_create(pool, "@System"); + pool_set_installed(pool, installed); + repo_add_rpmdb(installed, 0, 0, 0); + queue_init(&todo); + queue_init(&conflicts); + FOR_REPO_SOLVABLES(installed, p, s) + queue_push(&todo, p); + pool_findfileconflicts(pool, &todo, &conflicts, &iterate_handle, (void *)&state); + queue_free(&todo); + for (i = 0; i < conflicts.count; i += 5) + printf("%s: %s[%s] %s[%s]\n", id2str(pool, conflicts.elements[i]), solvid2str(pool, conflicts.elements[i + 1]), id2str(pool, conflicts.elements[i + 2]), solvid2str(pool, conflicts.elements[i + 3]), id2str(pool, conflicts.elements[i + 4])); + if (conflicts.count) + { + Queue job; + queue_init(&job); + pool_add_fileconflicts_deps(pool, &conflicts); + pool_addfileprovides(pool); + pool_createwhatprovides(pool); + pool_setdebuglevel(pool, 0); + Solver *solv = solver_create(pool); + solv->fixsystem = 1; + solver_solve(solv, &job); + if (solv->problems.count) + solver_printallsolutions(solv); + queue_free(&job); + solver_free(solv); + } + queue_free(&conflicts); + exit(0); +} -- 2.7.4