- add support for REL_FILECONFLICT
authorMichael Schroeder <mls@suse.de>
Fri, 19 Jun 2009 16:52:23 +0000 (18:52 +0200)
committerMichael Schroeder <mls@suse.de>
Fri, 19 Jun 2009 16:52:23 +0000 (18:52 +0200)
- add findfileconflicts.c demo app

src/pool.c
src/pool.h
src/poolid.c
tools/findfileconflicts.c [new file with mode: 0644]

index 73fc1c2..4fa4e25 100644 (file)
@@ -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 */
index 2e657ad..e985211 100644 (file)
@@ -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)                                                 \
index cd5f4d7..a0059e2 100644 (file)
@@ -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 (file)
index 0000000..88833d5
--- /dev/null
@@ -0,0 +1,71 @@
+#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);
+}