Imported Upstream version 0.6.35
[platform/upstream/libsolv.git] / ext / repo_rpmdb.c
index ee226e7..75bb678 100644 (file)
@@ -446,13 +446,24 @@ headstringarray(RpmHead *h, int tag, int *cnt)
 static unsigned char *
 headbinary(RpmHead *h, int tag, unsigned int *sizep)
 {
-  return headget(h, tag, (int *)sizep, 0);
+  unsigned char *b = headget(h, tag, (int *)sizep, 0);
+  if (b && sizep && (tag == TAG_SIGMD5 || tag == SIGTAG_MD5) && *sizep > 16) {
+    /* due to a bug in rpm the count may be bigger if HEADERIMPORT_FAST is used */
+    *sizep = 16;
+  }
+  return b;
 }
 
 static int
 headissourceheuristic(RpmHead *h)
 {
-  return headerIsSource(h);
+  struct rpmtd_s td;
+  int issource;
+  if (!headerGet(h, TAG_DIRNAMES, &td, HEADERGET_MINMEM))
+    return 0;
+  issource = td.count == 1 && td.data && ((char **)td.data)[0] && !((char **)td.data)[0][0];
+  rpmtdFreeData(&td);
+  return issource;
 }
 
 static inline void
@@ -475,10 +486,7 @@ static char *headtoevr(RpmHead *h)
   release  = headstring(h, TAG_RELEASE);
   epoch = headint32(h, TAG_EPOCH);
   if (!version || !release)
-    {
-      fprintf(stderr, "headtoevr: bad rpm header\n");
-      return 0;
-    }
+    return 0;
   for (v = version; *v >= '0' && *v <= '9'; v++)
     ;
   if (epoch || (v != version && *v == ':'))
@@ -1084,7 +1092,7 @@ rpmhead2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhe
       pool_error(pool, 0, "package has no name");
       return 0;
     }
-  if (!strcmp(name, "gpg-pubkey"))
+  if (!(flags & RPMDB_KEEP_GPG_PUBKEY) && !strcmp(name, "gpg-pubkey"))
     return 0;
   s->name = pool_str2id(pool, name, 1);
   sourcerpm = headstring(rpmhead, TAG_SOURCERPM);
@@ -1101,6 +1109,7 @@ rpmhead2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhe
     s->arch = ARCH_NOARCH;
   evr = headtoevr(rpmhead);
   s->evr = pool_str2id(pool, evr, 1);
+  solv_free(evr);
   s->vendor = pool_str2id(pool, headstring(rpmhead, TAG_VENDOR), 1);
 
   queue_init_buffer(&ignq, ignqbuf, sizeof(ignqbuf)/sizeof(*ignqbuf));
@@ -1198,7 +1207,6 @@ rpmhead2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhe
       if ((flags & RPM_ADD_WITH_CHANGELOG) != 0)
        addchangelog(data, handle, rpmhead);
     }
-  solv_free(evr);
   return 1;
 }
 
@@ -1252,10 +1260,7 @@ headfromfp(struct rpmdbstate *state, const char *name, FILE *fp, unsigned char *
     }
   rpmhead = state->rpmhead;
   if (fread(rpmhead->data, len, 1, fp) != 1)
-    {
-      fclose(fp);
-      return pool_error(state->pool, 0, "%s: unexpected EOF", name);
-    }
+    return pool_error(state->pool, 0, "%s: unexpected EOF", name);
   if (chk1)
     solv_chksum_add(chk1, rpmhead->data, len);
   if (chk2)
@@ -1382,18 +1387,18 @@ copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo)
 
 #define COPYDIR_DIRCACHE_SIZE 512
 
-static Id copydir_complex(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache);
+static Id copydir_complex(Repodata *data, Repodata *fromdata, Id did, Id *cache);
 
 static inline Id
-copydir(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache)
+copydir(Repodata *data, Repodata *fromdata, Id did, Id *cache)
 {
   if (cache && did && cache[did & 255] == did)
     return cache[(did & 255) + 256];
-  return copydir_complex(pool, data, fromdata, did, cache);
+  return copydir_complex(data, fromdata, did, cache);
 }
 
 static Id
-copydir_complex(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache)
+copydir_complex(Repodata *data, Repodata *fromdata, Id did, Id *cache)
 {
   Id parent, compid;
   if (!did)
@@ -1406,7 +1411,7 @@ copydir_complex(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cach
   parent = dirpool_parent(&fromdata->dirpool, did);
   compid = dirpool_compid(&fromdata->dirpool, did);
   if (parent)
-    parent = copydir(pool, data, fromdata, parent, cache);
+    parent = copydir(data, fromdata, parent, cache);
   if (data->localpool || fromdata->localpool)
     compid = repodata_translate_id(data, fromdata, compid, 1);
   compid = dirpool_add_dir(&data->dirpool, parent, compid, 1);
@@ -1429,50 +1434,20 @@ static int
 solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, KeyValue *kv)
 {
   struct solvable_copy_cbdata *cbdata = vcbdata;
-  Id id, keyname;
   Repodata *data = cbdata->data;
   Id handle = cbdata->handle;
-  Pool *pool = data->repo->pool;
 
-  keyname = key->name;
-  switch(key->type)
+  switch (key->type)
     {
     case REPOKEY_TYPE_ID:
     case REPOKEY_TYPE_CONSTANTID:
     case REPOKEY_TYPE_IDARRAY: /* used for triggers */
-      id = kv->id;
       if (data->localpool || fromdata->localpool)
-       id = repodata_translate_id(data, fromdata, id, 1);
-      if (key->type == REPOKEY_TYPE_ID)
-        repodata_set_id(data, handle, keyname, id);
-      else if (key->type == REPOKEY_TYPE_CONSTANTID)
-        repodata_set_constantid(data, handle, keyname, id);
-      else
-        repodata_add_idarray(data, handle, keyname, id);
-      break;
-    case REPOKEY_TYPE_STR:
-      repodata_set_str(data, handle, keyname, kv->str);
-      break;
-    case REPOKEY_TYPE_VOID:
-      repodata_set_void(data, handle, keyname);
-      break;
-    case REPOKEY_TYPE_NUM:
-      repodata_set_num(data, handle, keyname, SOLV_KV_NUM64(kv));
-      break;
-    case REPOKEY_TYPE_CONSTANT:
-      repodata_set_constant(data, handle, keyname, kv->num);
+       kv->id = repodata_translate_id(data, fromdata, kv->id, 1);
       break;
     case REPOKEY_TYPE_DIRNUMNUMARRAY:
-      id = kv->id;
-      id = copydir(pool, data, fromdata, id, cbdata->dircache);
-      if (id)
-        repodata_add_dirnumnum(data, handle, keyname, id, kv->num, kv->num2);
-      break;
     case REPOKEY_TYPE_DIRSTRARRAY:
-      id = kv->id;
-      id = copydir(pool, data, fromdata, id, cbdata->dircache);
-      if (id)
-        repodata_add_dirstr(data, handle, keyname, id, kv->str);
+      kv->id = copydir(data, fromdata, kv->id, cbdata->dircache);
       break;
     case REPOKEY_TYPE_FLEXARRAY:
       if (kv->eof == 2)
@@ -1488,16 +1463,12 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K
          cbdata->subhandle = cbdata->handle;
        }
       cbdata->handle = repodata_new_handle(data);
-      repodata_add_flexarray(data, cbdata->subhandle, keyname, cbdata->handle);
-      break;
+      repodata_add_flexarray(data, cbdata->subhandle, key->name, cbdata->handle);
+      return 0;
     default:
-      if (solv_chksum_len(key->type))
-       {
-         repodata_set_bin_checksum(data, handle, keyname, key->type, (const unsigned char *)kv->str);
-         break;
-       }
       break;
     }
+  repodata_set_kv(data, handle, key->name, key->type, kv);
   return 0;
 }
 
@@ -1525,13 +1496,20 @@ solvable_copy(Solvable *s, Solvable *r, Repodata *data, Id *dircache)
   s->enhances  = copydeps(pool, repo, r->enhances, fromrepo);
 
   /* copy all attributes */
-  if (!data)
+  if (!data || fromrepo->nrepodata < 2)
     return;
   cbdata.data = data;
   cbdata.handle = s - pool->solvables;
   cbdata.subhandle = 0;
   cbdata.dircache = dircache;
   p = r - fromrepo->pool->solvables;
+  if (fromrepo->nrepodata == 2)
+    {
+      Repodata *fromdata = repo_id2repodata(fromrepo, 1);
+      if (p >= fromdata->start && p < fromdata->end)
+        repodata_search(fromdata, p, 0, SEARCH_SUB | SEARCH_ARRAYSENTINEL, solvable_copy_cb, &cbdata);
+      return;
+    }
 #if 0
   repo_search(fromrepo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE | SEARCH_SUB | SEARCH_ARRAYSENTINEL, solvable_copy_cb, &cbdata);
 #else
@@ -1764,7 +1742,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
       memset(dircache, 0, sizeof(dircache));
 
       /* get ids of installed rpms */
-      entries = getinstalledrpmdbids(&state, "Name", 0, &nentries, &namedata);
+      entries = getinstalledrpmdbids(&state, "Name", 0, &nentries, &namedata, flags & RPMDB_KEEP_GPG_PUBKEY);
       if (!entries)
        {
          freestate(&state);
@@ -2354,7 +2332,7 @@ rpm_query(void *rpmhandle, Id what)
   r = 0;
   switch (what)
     {
-    case 0:
+    case 0:    /* return canonical name of rpm */
       name = headstring(rpmhead, TAG_NAME);
       if (!name)
        name = "";
@@ -2418,7 +2396,7 @@ rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queu
   struct rpmdbentry *entries;
   int nentries, i;
 
-  entries = getinstalledrpmdbids(rpmstate, index ? index : "Name", match, &nentries, 0);
+  entries = getinstalledrpmdbids(rpmstate, index ? index : "Name", match, &nentries, 0, 0);
   if (rpmdbidq)
     {
       queue_empty(rpmdbidq);