summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/pool_fileconflicts.c95
-rw-r--r--ext/pool_fileconflicts.h4
-rw-r--r--tools/findfileconflicts.c2
3 files changed, 91 insertions, 10 deletions
diff --git a/ext/pool_fileconflicts.c b/ext/pool_fileconflicts.c
index 37364ba..b35ace5 100644
--- a/ext/pool_fileconflicts.c
+++ b/ext/pool_fileconflicts.c
@@ -260,7 +260,7 @@ findfileconflicts2_cb(void *cbdatav, const char *fn, struct filelistinfo *info)
}
static int
-lookat_cmp(const void *ap, const void *bp, void *dp)
+lookat_hx_cmp(const void *ap, const void *bp, void *dp)
{
const Id *a = ap;
const Id *b = bp;
@@ -286,13 +286,79 @@ conflicts_cmp(const void *ap, const void *bp, void *dp)
return 0;
}
+static void
+iterate_solvable_dirs(Pool *pool, Id p, void (*cb)(void *, const char *, struct filelistinfo *), void *cbdata)
+{
+ Repodata *lastdata = 0;
+ Id lastdirid = -1;
+ Dataiterator di;
+
+ dataiterator_init(&di, pool, 0, p, SOLVABLE_FILELIST, 0, SEARCH_COMPLETE_FILELIST);
+ while (dataiterator_step(&di))
+ {
+ if (di.data == lastdata && di.kv.id == lastdirid)
+ continue;
+ lastdata = di.data;
+ lastdirid = di.kv.id;
+ cb(cbdata, repodata_dir2str(di.data, di.kv.id, ""), 0);
+ }
+ dataiterator_free(&di);
+}
+
+#if 0
+static void
+iterate_solvable_files(Pool *pool, Id p, void (*cb)(void *, const char *, struct filelistinfo *), void *cbdata)
+{
+ Dataiterator di;
+ char *space = 0;
+ int spacen = 0;
+ Repodata *lastdata = 0;
+ Id lastdirid = -1;
+ int dirl = 0, l;
+ struct filelistinfo info;
+ const char *tmpdir = 0;
+ unsigned int diridx;
+
+ dataiterator_init(&di, pool, 0, p, SOLVABLE_FILELIST, 0, SEARCH_COMPLETE_FILELIST);
+ memset(&info, 0, sizeof(info));
+ while (dataiterator_step(&di))
+ {
+ if (di.data != lastdata || di.kv.id != lastdirid)
+ {
+ lastdata = di.data;
+ lastdirid = di.kv.id;
+ tmpdir = repodata_dir2str(di.data, di.kv.id, "");
+ dirl = strlen(tmpdir);
+ info.diridx++;
+ info.dirlen = dirl;
+ }
+ l = dirl + strlen(di.kv.str) + 1;
+ if (l > spacen)
+ {
+ spacen = l + 16;
+ space = solv_realloc(space, spacen);
+ }
+ if (tmpdir)
+ {
+ strcpy(space, tmpdir);
+ tmpdir = 0;
+ }
+ strcpy(space + dirl, di.kv.str);
+ cb(cbdata, space, &info);
+ }
+ dataiterator_free(&di);
+ solv_free(space);
+}
+#endif
+
int
-pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, void *(*handle_cb)(Pool *, Id, void *) , void *handle_cbdata)
+pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, int flags, void *(*handle_cb)(Pool *, Id, void *) , void *handle_cbdata)
{
int i, j, cflmapn, idxmapset;
struct cbdata cbdata;
unsigned int now, start;
void *handle;
+ Repo *installed = pool->installed;
Id p;
int obsoleteusescolors = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESCOLORS);
@@ -331,9 +397,20 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
cbdata.idx = i;
if (i == cutoff)
cbdata.create = 0;
+ if ((flags & FINDFILECONFLICTS_USESOLVABLEFILELIST) != 0 && installed)
+ {
+ if (p >= installed->start && p < installed->end && pool->solvables[p].repo == installed)
+ {
+ iterate_solvable_dirs(pool, p, finddirs_cb, &cbdata);
+ if (MAPTST(&cbdata.idxmap, i))
+ idxmapset++;
+ continue;
+ }
+ }
handle = (*handle_cb)(pool, p, handle_cbdata);
- if (handle)
- rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_ONLYDIRS, finddirs_cb, &cbdata);
+ if (!handle)
+ continue;
+ rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_ONLYDIRS, finddirs_cb, &cbdata);
if (MAPTST(&cbdata.idxmap, i))
idxmapset++;
}
@@ -359,6 +436,8 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
cbdata.idx = i;
if (i == cutoff)
cbdata.create = 0;
+ /* can't use FINDFILECONFLICTS_USESOLVABLEFILELIST because we have to know if
+ * the file is a directory or not */
handle = (*handle_cb)(pool, p, handle_cbdata);
if (!handle)
continue;
@@ -383,7 +462,7 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
queue_free(&cbdata.lookat_dir);
/* sort and unify */
- solv_sort(cbdata.lookat.elements, cbdata.lookat.count / 2, sizeof(Id) * 2, &lookat_cmp, pool);
+ solv_sort(cbdata.lookat.elements, cbdata.lookat.count / 2, sizeof(Id) * 2, &lookat_hx_cmp, pool);
for (i = j = 0; i < cbdata.lookat.count; i += 2)
{
Id hx = cbdata.lookat.elements[i];
@@ -407,13 +486,13 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
iterflags = RPM_ITERATE_FILELIST_WITHMD5 | RPM_ITERATE_FILELIST_NOGHOSTS;
if (obsoleteusescolors)
iterflags |= RPM_ITERATE_FILELIST_WITHCOL;
- p = pkgs->elements[pidx];
if (cbdata.lookat.elements[i + 2] != hx)
continue; /* no package left */
queue_empty(&cbdata.files);
cbdata.filesspace = solv_free(cbdata.filesspace);
cbdata.filesspacen = 0;
+ p = pkgs->elements[pidx];
cbdata.idx = p;
cbdata.hx = cbdata.lookat.elements[i];
handle = (*handle_cb)(pool, p, handle_cbdata);
@@ -425,10 +504,10 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
pend = cbdata.files.count;
for (j = i + 2; j < cbdata.lookat.count && cbdata.lookat.elements[j] == hx; j += 2)
{
- Id qidx = cbdata.lookat.elements[j + 1];
- Id q = pkgs->elements[qidx];
+ Id q, qidx = cbdata.lookat.elements[j + 1];
if (pidx >= cutoff && qidx >= cutoff)
continue; /* no conflicts between packages with idx >= cutoff */
+ q = pkgs->elements[qidx];
cbdata.idx = q;
handle = (*handle_cb)(pool, q, handle_cbdata);
if (!handle)
diff --git a/ext/pool_fileconflicts.h b/ext/pool_fileconflicts.h
index f8be98d..8666fc6 100644
--- a/ext/pool_fileconflicts.h
+++ b/ext/pool_fileconflicts.h
@@ -10,6 +10,8 @@
#include "pool.h"
-extern int pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, void *(*handle_cb)(Pool *, Id, void *) , void *handle_cbdata);
+extern int pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, int flags, void *(*handle_cb)(Pool *, Id, void *) , void *handle_cbdata);
+
+#define FINDFILECONFLICTS_USESOLVABLEFILELIST (1 << 0)
#endif
diff --git a/tools/findfileconflicts.c b/tools/findfileconflicts.c
index 23151c5..64f55dd 100644
--- a/tools/findfileconflicts.c
+++ b/tools/findfileconflicts.c
@@ -50,7 +50,7 @@ int main(int argc, char **argv)
FOR_REPO_SOLVABLES(installed, p, s)
queue_push(&todo, p);
state = rpm_state_create(0);
- pool_findfileconflicts(pool, &todo, 0, &conflicts, &iterate_handle, state);
+ pool_findfileconflicts(pool, &todo, 0, &conflicts, FINDFILECONFLICTS_USESOLVABLEFILELIST, &iterate_handle, state);
rpm_state_free(state);
queue_free(&todo);
for (i = 0; i < conflicts.count; i += 6)