Reimplement state handling in rpm_by functions
authorMichael Schroeder <mls@suse.de>
Wed, 10 Apr 2013 10:52:08 +0000 (12:52 +0200)
committerMichael Schroeder <mls@suse.de>
Wed, 10 Apr 2013 10:52:08 +0000 (12:52 +0200)
We now have rpm_state_create and rpm_state_free to create/free
the state. API change, but should be pretty internal.

examples/solv.c
ext/libsolvext.ver
ext/pool_fileconflicts.c
ext/repo_rpmdb.c
ext/repo_rpmdb.h
tools/findfileconflicts.c

index 6a0bfe2..3f4156d 100644 (file)
@@ -141,21 +141,22 @@ yum_substitute(Pool *pool, char *line)
        {
          if (!releaseevr)
            {
+             void *rpmstate;
              Queue q;
-             const char *rootdir = pool_get_rootdir(pool);
        
              queue_init(&q);
-             rpm_installedrpmdbids(rootdir, "Providename", "redhat-release", &q);
+             rpmstate = rpm_state_create(pool_get_rootdir(pool));
+             rpm_installedrpmdbids(rpmstate, "Providename", "redhat-release", &q);
              if (q.count)
                {
-                 void *handle, *state = 0;
+                 void *handle;
                  char *p;
-                 handle = rpm_byrpmdbid(q.elements[0], rootdir, &state);
-                 releaseevr = rpm_query(handle, SOLVABLE_EVR);
-                 rpm_byrpmdbid(0, 0, &state);
-                 if ((p = strchr(releaseevr, '-')) != 0)
+                 handle = rpm_byrpmdbid(rpmstate, q.elements[0]);
+                 releaseevr = handle ? rpm_query(handle, SOLVABLE_EVR) : 0;
+                 if (releaseevr && (p = strchr(releaseevr, '-')) != 0)
                    *p = 0;
                }
+             rpm_state_free(rpmstate);
              queue_free(&q);
              if (!releaseevr)
                {
@@ -2063,7 +2064,7 @@ struct fcstate {
   FILE **newpkgsfps;
   Queue *checkq;
   int newpkgscnt;
-  void *rpmdbstate;
+  void *rpmstate;
 };
 
 static void *
@@ -2075,11 +2076,6 @@ fileconflict_cb(Pool *pool, Id p, void *cbdata)
   int i;
   FILE *fp;
 
-  if (!p)
-    {
-      rpm_byrpmdbid(0, 0, &fcstate->rpmdbstate);
-      return 0;
-    }
   s = pool_id2solvable(pool, p);
   if (pool->installed && s->repo == pool->installed)
     {
@@ -2088,7 +2084,7 @@ fileconflict_cb(Pool *pool, Id p, void *cbdata)
       rpmdbid = s->repo->rpmdbid[p - s->repo->start];
       if (!rpmdbid)
        return 0;
-       return rpm_byrpmdbid(rpmdbid, 0, &fcstate->rpmdbstate);
+       return rpm_byrpmdbid(fcstate->rpmstate, rpmdbid);
     }
   for (i = 0; i < fcstate->newpkgscnt; i++)
     if (fcstate->checkq->elements[i] == p)
@@ -2099,7 +2095,7 @@ fileconflict_cb(Pool *pool, Id p, void *cbdata)
   if (!fp)
     return 0;
   rewind(fp);
-  return rpm_byfp(fp, pool_solvable2str(pool, s), &fcstate->rpmdbstate);
+  return rpm_byfp(fcstate->rpmstate, fp, pool_solvable2str(pool, s));
 }
 
 
@@ -3175,11 +3171,12 @@ rerunsolver:
 
       printf("Searching for file conflicts\n");
       queue_init(&conflicts);
-      fcstate.rpmdbstate = 0;
+      fcstate.rpmstate = rpm_state_create(rootdir);
       fcstate.newpkgscnt = newpkgs;
       fcstate.checkq = &checkq;
       fcstate.newpkgsfps = newpkgsfps;
       pool_findfileconflicts(pool, &checkq, newpkgs, &conflicts, &fileconflict_cb, &fcstate);
+      fcstate.rpmstate = rpm_state_free(fcstate.rpmstate);
       if (conflicts.count)
        {
          printf("\n");
index 272cac9..953aadf 100644 (file)
@@ -33,6 +33,8 @@ SOLV_1.0 {
                rpm_installedrpmdbids;
                rpm_iterate_filelist;
                rpm_query;
+               rpm_state_create;
+               rpm_state_free;
                solv_xfopen;
                solv_xfopen_buf;
                solv_xfopen_fd;
index 5f56e60..27e7ab8 100644 (file)
@@ -440,7 +440,6 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
   POOL_DEBUG(SOLV_DEBUG_STATS, "candidate check took %d ms\n", solv_timems(now));
   if (conflicts->count > 6)
     solv_sort(conflicts->elements, conflicts->count / 6, 6 * sizeof(Id), conflicts_cmp, pool);
-  (*handle_cb)(pool, 0, handle_cbdata);
   POOL_DEBUG(SOLV_DEBUG_STATS, "found %d file conflicts\n", conflicts->count / 6);
   POOL_DEBUG(SOLV_DEBUG_STATS, "file conflict detection took %d ms\n", solv_timems(start));
   return conflicts->count;
index d03c325..c02e531 100644 (file)
@@ -2357,6 +2357,7 @@ struct rpm_by_state {
   int rpmheadsize;
 
   int dbopened;
+  char *rootdir;
   DB_ENV *dbenv;
   DB *db;
   int byteswapped;
@@ -2389,8 +2390,11 @@ getinstalledrpmdbids(struct rpm_by_state *state, const char *index, const char *
   int nentries = 0;
 
   *nentriesp = 0;
-  *namedatap = 0;
+  if (namedatap)
+    *namedatap = 0;
 
+  if (!state->dbenv && !(state->dbenv = opendbenv(state->rootdir)))
+    return 0;
   dbenv = state->dbenv;
   if (db_create(&db, dbenv, 0))
     {
@@ -2500,6 +2504,8 @@ freestate(struct rpm_by_state *state)
   /* close down */
   if (!state)
     return;
+  if (state->rootdir)
+    solv_free(state->rootdir);
   if (state->db)
     state->db->close(state->db, 0);
   if (state->dbenv)
@@ -2507,55 +2513,52 @@ freestate(struct rpm_by_state *state)
   solv_free(state->rpmhead);
 }
 
+void *
+rpm_state_create(const char *rootdir)
+{
+  struct rpm_by_state *state;
+  state = solv_calloc(1, sizeof(*state));
+  if (rootdir)
+    state->rootdir = solv_strdup(rootdir);
+  return state;
+}
+
+void *
+rpm_state_free(void *state)
+{
+  freestate(state);
+  return solv_free(state);
+}
+
 int
-rpm_installedrpmdbids(const char *rootdir, const char *index, const char *match, Queue *rpmdbidq)
+rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq)
 {
-  struct rpm_by_state state;
+  struct rpm_by_state *state = rpmstate;
   struct rpmdbentry *entries;
   int nentries, i;
-  char *namedata;
 
   if (!index)
     index = "Name";
   if (rpmdbidq)
     queue_empty(rpmdbidq);
-  memset(&state, 0, sizeof(state));
-  if (!(state.dbenv = opendbenv(rootdir)))
-    return 0;
-  entries = getinstalledrpmdbids(&state, index, match, &nentries, &namedata);
+  entries = getinstalledrpmdbids(state, index, match, &nentries, 0);
   if (rpmdbidq)
     for (i = 0; i < nentries; i++)
       queue_push(rpmdbidq, entries[i].rpmdbid);
   solv_free(entries);
-  solv_free(namedata);
-  freestate(&state);
   return nentries;
 }
 
 void *
-rpm_byrpmdbid(Id rpmdbid, const char *rootdir, void **statep)
+rpm_byrpmdbid(void *rpmstate, Id rpmdbid)
 {
-  struct rpm_by_state *state = *statep;
+  struct rpm_by_state *state = rpmstate;
   unsigned char buf[16];
   DBT dbkey;
   DBT dbdata;
   RpmHead *rpmhead;
 
-  if (!rpmdbid)
-    {
-      /* close down */
-      freestate(state);
-      solv_free(state);
-      *statep = (void *)0;
-      return 0;
-    }
-
-  if (!state)
-    {
-      state = solv_calloc(1, sizeof(*state));
-      *statep = state;
-    }
-  if (!state->dbopened && !openpkgdb(state, rootdir))
+  if (!state->dbopened && !openpkgdb(state, state->rootdir))
     return 0;
   rpmdbid2db(buf, rpmdbid, state->byteswapped);
   memset(&dbkey, 0, sizeof(dbkey));
@@ -2595,22 +2598,15 @@ rpm_byrpmdbid(Id rpmdbid, const char *rootdir, void **statep)
 }
 
 void *
-rpm_byfp(FILE *fp, const char *name, void **statep)
+rpm_byfp(void *rpmstate, FILE *fp, const char *name)
 {
-  struct rpm_by_state *state = *statep;
+  struct rpm_by_state *state = rpmstate;
   /* int headerstart, headerend; */
   RpmHead *rpmhead;
   unsigned int sigdsize, sigcnt, l;
   unsigned char lead[4096];
   int forcebinary = 0;
 
-  if (!fp)
-    return rpm_byrpmdbid(0, 0, statep);
-  if (!state)
-    {
-      state = solv_calloc(1, sizeof(*state));
-      *statep = state;
-    }
   if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb)
     {
       fprintf(stderr, "%s: not a rpm\n", name);
@@ -2690,9 +2686,9 @@ rpm_byfp(FILE *fp, const char *name, void **statep)
 #ifdef ENABLE_RPMDB_BYRPMHEADER
 
 void *
-rpm_byrpmh(Header h, void **statep)
+rpm_byrpmh(void *rpmstate, Header h)
 {
-  struct rpm_by_state *state = *statep;
+  struct rpm_by_state *state = rpmstate;
   const unsigned char *uh;
   unsigned int sigdsize, sigcnt, l;
   RpmHead *rpmhead;
@@ -2707,11 +2703,6 @@ rpm_byrpmh(Header h, void **statep)
   sigcnt = getu32(uh);
   sigdsize = getu32(uh + 4);
   l = sigdsize + sigcnt * 16;
-  if (!state)
-    {
-      state = solv_calloc(1, sizeof(*state));
-      *statep = state;
-    }
   if (l > state->rpmheadsize)
     {
       state->rpmheadsize = l + 128;
@@ -3268,7 +3259,7 @@ repo_add_rpmdb_pubkeys(Repo *repo, int flags)
   struct rpm_by_state state;
   struct rpmdbentry *entries;
   int nentries, i;
-  char *namedata, *str;
+  char *str;
   unsigned int u32;
   Repodata *data;
   Solvable *s;
@@ -3281,11 +3272,10 @@ repo_add_rpmdb_pubkeys(Repo *repo, int flags)
   memset(&state, 0, sizeof(state));
   if (!(state.dbenv = opendbenv(rootdir)))
     return 0;
-  entries = getinstalledrpmdbids(&state, "Name", "gpg-pubkey", &nentries, &namedata);
+  entries = getinstalledrpmdbids(&state, "Name", "gpg-pubkey", &nentries, 0);
   for (i = 0 ; i < nentries; i++)
     {
-      void *statep = &state;
-      RpmHead *rpmhead = rpm_byrpmdbid(entries[i].rpmdbid, rootdir, &statep);
+      RpmHead *rpmhead = rpm_byrpmdbid(&state, entries[i].rpmdbid);
       if (!rpmhead)
        continue;
       str = headstring(rpmhead, TAG_DESCRIPTION);
@@ -3301,7 +3291,6 @@ repo_add_rpmdb_pubkeys(Repo *repo, int flags)
       repo->rpmdbid[s - pool->solvables - repo->start] = entries[i].rpmdbid;
     }
   solv_free(entries);
-  solv_free(namedata);
   freestate(&state);
   if (!(flags & REPO_NO_INTERNALIZE))
     repodata_internalize(data);
index fdc6120..79e35c7 100644 (file)
@@ -31,11 +31,19 @@ extern Id repo_add_pubkey(Repo *repo, const char *key, int flags);
 #define RPM_ITERATE_FILELIST_WITHCOL   (1 << 2)
 #define RPM_ITERATE_FILELIST_NOGHOSTS  (1 << 3)
 
-extern void *rpm_byrpmdbid(Id rpmdbid, const char *rootdir, void **statep);
-extern void *rpm_byfp(FILE *fp, const char *name, void **statep);
-extern void *rpm_byrpmh(struct headerToken_s *h, void **statep);
-extern int  rpm_installedrpmdbids(const char *rootdir, const char *index, const char *match, Queue *rpmdbidq);
+/* create and free internal state, rootdir is the rootdir of the rpm database */
+extern void *rpm_state_create(const char *rootdir);
+extern void *rpm_state_free(void *rpmstate);
 
+/* return all matching rpmdbids */
+extern int  rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq);
+
+/* return handles to a rpm header */
+extern void *rpm_byrpmdbid(void *rpmstate, Id rpmdbid);
+extern void *rpm_byfp(void *rpmstate, FILE *fp, const char *name);
+extern void *rpm_byrpmh(void *rpmstate, struct headerToken_s *h);
+
+/* operations on a rpm header handle */
 extern char *rpm_query(void *rpmhandle, Id what);
 extern void rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, int, const char *), void *cbdata);
 extern Id   repo_add_rpm_handle(Repo *repo, void *rpmhandle, int flags);
index ff49e42..23151c5 100644 (file)
@@ -18,17 +18,12 @@ 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);
+  return rpm_byrpmdbid(cbdata, rpmdbid);
 }
 
 int main(int argc, char **argv)
@@ -54,7 +49,9 @@ int main(int argc, char **argv)
   queue_init(&conflicts);
   FOR_REPO_SOLVABLES(installed, p, s)
     queue_push(&todo, p);
-  pool_findfileconflicts(pool, &todo, 0, &conflicts, &iterate_handle, (void *)&state);
+  state = rpm_state_create(0);
+  pool_findfileconflicts(pool, &todo, 0, &conflicts, &iterate_handle, state);
+  rpm_state_free(state);
   queue_free(&todo);
   for (i = 0; i < conflicts.count; i += 6)
     printf("%s: %s[%s] %s[%s]\n", pool_id2str(pool, conflicts.elements[i]), pool_solvid2str(pool, conflicts.elements[i + 1]), pool_id2str(pool, conflicts.elements[i + 2]), pool_solvid2str(pool, conflicts.elements[i + 4]), pool_id2str(pool, conflicts.elements[i + 5]));