}
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;
}
}
dep = rd->evr;
}
+ else if (rd->flags == REL_FILECONFLICT)
+ {
+ dep = 0;
+ break;
+ }
else
{
Id ids[2];
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 */
#define REL_WITH 18
#define REL_NAMESPACE 19
#define REL_ARCH 20
+#define REL_FILECONFLICT 21
#if !defined(__GNUC__) && !defined(__attribute__)
# define __attribute__(x)
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) \
return " NAMESPACE "; /* actually not used in dep2str */
case REL_ARCH:
return ".";
+ case REL_FILECONFLICT:
+ return " FILECONFLICT ";
default:
break;
}
strcat(p, ")");
return;
}
+ if (rd->flags == REL_FILECONFLICT)
+ {
+ *p = 0;
+ return;
+ }
strcpy(p, id2rel(pool, id));
p += strlen(p);
id = rd->evr;
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#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);
+}