Support for generating separate sub files and bugfixes in the reader
authorMichael Matz <matz@suse.de>
Sun, 10 Feb 2008 06:09:37 +0000 (06:09 +0000)
committerMichael Matz <matz@suse.de>
Sun, 10 Feb 2008 06:09:37 +0000 (06:09 +0000)
side.  Try "susetags2solv -as" to play (e.g. with dumpsolv).

16 files changed:
src/pool.h
src/repo.c
src/repo_solv.c
src/repodata.c
src/repodata.h
tools/content2solv.c
tools/dumpsolv.c
tools/helix2solv.c
tools/mergesolv.c
tools/patchxml2solv.c
tools/repo_susetags.c
tools/repo_write.c
tools/repo_write.h
tools/rpmdb2solv.c
tools/rpmmd2solv.c
tools/susetags2solv.c

index 7b6a11a..7c702c6 100644 (file)
@@ -69,6 +69,7 @@ extern "C" {
 //-----------------------------------------------
 
 struct _Repo;
+struct _Repodata;
 
 struct _Pool {
   struct _Stringpool ss;
@@ -113,6 +114,10 @@ struct _Pool {
   int  debugmask;
   void (*debugcallback)(struct _Pool *, void *data, int type, const char *str);
   void *debugcallbackdata;
+
+  /* load callback */
+  FILE * (*loadcallback)(struct _Pool *, struct _Repodata *, void *);
+  void *loadcallbackdata;
 };
 
 #define SAT_FATAL                      (1<<0)
@@ -253,6 +258,12 @@ static inline void pool_setdebugmask(Pool *pool, int mask)
   pool->debugmask = mask;
 }
 
+static inline void pool_setloadcallback(Pool *pool, FILE *(*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata)
+{
+  pool->loadcallback = cb;
+  pool->loadcallbackdata = loadcbdata;
+}
+
 /* loop over all providers of d */
 #define FOR_PROVIDES(v, vp, d)                                                 \
   for (vp = pool_whatprovides(pool, d) ; (v = *vp++) != 0; )
index 2a2eb4c..58fed3c 100644 (file)
@@ -818,7 +818,8 @@ repo_add_repodata(Repo *repo)
   return data;
 }
 
-static Repodata *findrepodata(Repo *repo, Id p, Id keyname)
+static Repodata *
+findrepodata(Repo *repo, Id p, Id keyname)
 {
   int i;
   Repodata *data;
index 2c61340..8fae8dc 100644 (file)
@@ -371,8 +371,9 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned
              skip_item(maindata, TYPE_IDVALUEARRAY, numid, numrel);
              break;
            }
-         ida = sat_calloc(keys[key].size, sizeof(Id));
-         ide = read_idarray(maindata, 0, 0, ida, ida + keys[key].size, 0);
+         /* read_idarray writes a terminating 0, that's why the + 1 */
+         ida = sat_calloc(keys[key].size + 1, sizeof(Id));
+         ide = read_idarray(maindata, 0, 0, ida, ida + keys[key].size + 1, 0);
          n = ide - ida - 1;
          if (n & 1)
            {
@@ -409,9 +410,7 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned
              unsigned len = sizeof (buf);
              char *filename = buf;
              read_str(maindata, &filename, &len);
-#if 0
              data->location = strdup(filename);
-#endif
              if (filename != buf)
                free(filename);
            }
@@ -608,9 +607,9 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
          pool_debug(pool, SAT_ERROR, "relations are forbidden in a store\n");
          return SOLV_ERROR_CORRUPT;
        }
-      if (numsolv)
+      if (parent->end - parent->start != numsolv)
        {
-         pool_debug(pool, SAT_ERROR, "solvables are forbidden in a store\n");
+         pool_debug(pool, SAT_ERROR, "unequal number of solvables in a store\n");
          return SOLV_ERROR_CORRUPT;
        }
       if (numinfo)
@@ -638,6 +637,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
     spool = &pool->ss;
   else
     {
+      data.localpool = 1;
       spool = &data.spool;
       spool->stringspace = sat_malloc(7);
       strcpy(spool->stringspace, "<NULL>");
@@ -703,12 +703,12 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
     {
       /* no shared pool, thus no idmap and no unification */
       idmap = 0;
-      sp += 7;
-      if (*sp)
+      if (0 && *sp)
        {
          pool_debug(pool, SAT_ERROR, "store strings don't start with ''\n");
          return SOLV_ERROR_CORRUPT;
        }
+      spool->nstrings = numid;
       str[0] = 0;
       for (i = 1; i < spool->nstrings; i++)
        {
@@ -717,9 +717,10 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
              pool_debug(pool, SAT_ERROR, "not enough strings\n");
              return SOLV_ERROR_OVERFLOW;
            }
-         str[i] = sp - strsp;
+         str[i] = sp - spool->stringspace;
          sp += strlen(sp) + 1;
        }
+      spool->sstrings = sp - spool->stringspace;
     }
   else
     {
@@ -905,9 +906,15 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
       id = read_id(&data, numid);
       if (idmap)
        id = idmap[id];
+      else if (parent)
+        id = str2id(pool, stringpool_id2str(spool, id), 1);
       keys[i].name = id;
       keys[i].type = read_id(&data, 0);
       keys[i].size = read_id(&data, 0);
+#if 0
+      fprintf (stderr, "key %d %s %d %d\n", i, id2str(pool,id), keys[i].type,
+               keys[i].size);
+#endif
       if (solvversion >= SOLV_VERSION_5)
        {
          keys[i].storage = read_id(&data, 0);
@@ -979,6 +986,13 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
     {
       schemata[i] = schemadatap - schemadata;
       schemadatap = read_idarray(&data, numid, 0, schemadatap, schemadataend, 0);
+#if 0
+      Id *sp = schemadata + schemata[i];
+      fprintf (stderr, "schema %d:", i);
+      for (; *sp; sp++)
+        fprintf (stderr, " %d", *sp);
+      fprintf (stderr, "\n");
+#endif
     }
   data.schemata = schemata;
   data.nschemata = numschemata;
@@ -1046,12 +1060,25 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
     }
 
   /* read solvables */
-  if (numsolv)
+  if (parent)
+    {
+      data.start = parent->start;
+      data.end = parent->end;
+      s = pool_id2solvable(pool, data.start);
+    }
+  else if (numsolv)
     {
       s = pool_id2solvable(pool, repo_add_solvable_block(repo, numsolv));
       /* store start and end of our id block */
       data.start = s - pool->solvables;
       data.end = data.start + numsolv;
+      /* In case we have subfiles, make them refer to our part of the 
+        repository now.  */
+      for (i = 0; i < repo->nrepodata; i++)
+        {
+         repo->repodata[i].start = data.start;
+         repo->repodata[i].end = data.end;
+       }
     }
   else
     s = 0;
@@ -1365,14 +1392,14 @@ static void
 repodata_load_solv(Repodata *data)
 {
   FILE *fp;
-#if 0
+#if 1
   Pool *pool = data->repo->pool;
   if (!pool->loadcallback)
     {   
       data->state = REPODATA_ERROR;
       return;
     }   
-  fp = pool->loadcallback(pool->loadcallback_data, pool, data);
+  fp = pool->loadcallback(pool, data, pool->loadcallbackdata);
 #else
   fp = 0;
 #endif
index a777bb6..6fb9459 100644 (file)
@@ -399,6 +399,21 @@ get_data(Repodata *data, Repokey *key, unsigned char **dpp)
   return 0;
 }
 
+static inline int
+maybe_load_repodata(Repodata *data)
+{
+  if (data->state == REPODATA_STUB)
+    {
+      if (data->loadcallback)
+       data->loadcallback(data);
+      else
+       data->state = REPODATA_ERROR;
+    }
+  if (data->state == REPODATA_AVAILABLE)
+    return 1;
+  data->state = REPODATA_ERROR;
+  return 0;
+}
 
 const char *
 repodata_lookup_str(Repodata *data, Id entry, Id keyid)
@@ -408,6 +423,9 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid)
   Id id, *keyp;
   unsigned char *dp;
 
+  if (!maybe_load_repodata (data))
+    return 0;
+
   dp = data->incoredata + data->incoreoffset[entry];
   dp = data_read_id(dp, &schema);
   /* make sure the schema of this solvable contains the key */
@@ -440,6 +458,10 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
   unsigned char *dp;
 
   *value = 0;
+
+  if (!maybe_load_repodata (data))
+    return 0;
+
   dp = data->incoredata + data->incoreoffset[entry];
   dp = data_read_id(dp, &schema);
   /* make sure the schema of this solvable contains the key */
@@ -473,6 +495,9 @@ repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbda
   int stop;
   KeyValue kv;
 
+  if (!maybe_load_repodata (data))
+    return;
+
   dp = data->incoredata + data->incoreoffset[entry];
   dp = data_read_id(dp, &schema);
   keyp = data->schemadata + data->schemata[schema];
index c695d78..c9de915 100644 (file)
@@ -39,9 +39,17 @@ typedef struct _Attrblobpage
 typedef struct _Repodata {
   struct _Repo *repo;          /* back pointer to repo */
 
+#define REPODATA_AVAILABLE     0
+#define REPODATA_STUB          1
+#define REPODATA_ERROR         2
+#define REPODATA_STORE         3
   int state;                   /* available, stub or error */
 
   void (*loadcallback)(struct _Repodata *);
+  char *location;              /* E.g. filename or the like */
+  char *checksum;              /* Checksum of the file */
+  unsigned nchecksum;          /* Length of the checksum */
+  unsigned checksumtype;       /* Type of checksum */
 
   int start;                   /* start of solvables this repodata is valid for */
   int end;                     /* last solvable + 1 of this repodata */
@@ -94,10 +102,6 @@ typedef struct _Repodata {
 
 } Repodata;
 
-#define REPODATA_AVAILABLE     0
-#define REPODATA_STUB          1
-#define REPODATA_ERROR         2
-#define REPODATA_STORE         3
 
 void repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
 const char *repodata_lookup_str(Repodata *data, Id entry, Id keyid);
index 5c5af58..c29958f 100644 (file)
@@ -23,7 +23,7 @@ main(int argc, char **argv)
   Pool *pool = pool_create();
   Repo *repo = repo_create(pool, "<stdin>");
   repo_add_content(repo, stdin);
-  repo_write(repo, stdout, 0, 0);
+  repo_write(repo, stdout, 0, 0, 0, 0);
   pool_free(pool);
   return 0;
 }
index 100f3cb..631e529 100644 (file)
@@ -86,6 +86,7 @@ dump_attrs (Repo *repo, unsigned int entry)
         dump_attrs_1 (s, entry);
     }
 }
+#endif
 
 static void
 dump_repodata (Repo *repo)
@@ -94,18 +95,17 @@ dump_repodata (Repo *repo)
   Repodata *data;
   if (repo->nrepodata == 0)
     return;
-  printf("repo refers to %d attribute stores:\n", repo->nrepodata);
+  printf("repo refers to %d subfiles:\n", repo->nrepodata);
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
     {
       unsigned int j;
       printf("%s has %d keys", data->location ? data->location : "**EMBED**", data->nkeys);
-      for (j = 0; j < data->nkeys; j++)
+      for (j = 1; j < data->nkeys; j++)
         printf("\n  %s", id2str(repo->pool, data->keys[j].name));
       printf("\n");
     }
   printf("\n");
 }
-#endif
 
 static void
 printids(Repo *repo, char *kind, Offset ido)
@@ -189,6 +189,34 @@ dump_repoattrs(Repo *repo, Id p)
     }
 }
 
+void
+dump_some_attrs(Repo *repo, Solvable *s)
+{
+  Id name = str2id (repo->pool, "summary", 0);
+  const char *summary = 0;
+  unsigned int medianr = -1, downloadsize = -1;
+  unsigned int time = -1;
+  if (name)
+    summary = repo_lookup_str (s, name);
+  if ((name = str2id (repo->pool, "medianr", 0)))
+    medianr = repo_lookup_num (s, name);
+  if ((name = str2id (repo->pool, "downloadsize", 0)))
+    downloadsize = repo_lookup_num (s, name);
+  if ((name = str2id (repo->pool, "time", 0)))
+    time = repo_lookup_num (s, name);
+
+  printf ("  XXX %d %d %u %s\n", medianr, downloadsize, time, summary);
+}
+
+static FILE *
+loadcallback (Pool *pool, Repodata *data, void *vdata)
+{
+  FILE *fp;
+  fprintf (stderr, "Loading SOLV file %s\n", data->location);
+  fp = fopen ("test.attr", "r");
+  return fp;
+}
+
 int main(int argc, char **argv)
 {
   Repo *repo;
@@ -206,13 +234,12 @@ int main(int argc, char **argv)
     }
   pool = pool_create();
   pool_setdebuglevel(pool, 1);
+  pool_setloadcallback(pool, loadcallback, 0);
 
   repo = repo_create(pool, argc != 1 ? argv[1] : "<stdin>");
   if (repo_add_solv(repo, stdin))
     printf("could not read repository\n");
-#if 0
   dump_repodata (repo);
-#endif
   printf("repo contains %d solvables\n", repo->nsolvables);
   for (i = repo->start, n = 1; i < repo->end; i++)
     {
@@ -238,6 +265,9 @@ int main(int argc, char **argv)
       dump_attrs (repo, n - 1);
 #endif
       dump_repoattrs(repo, i);
+#if 1
+      dump_some_attrs(repo, s);
+#endif
       n++;
     }
   pool_free(pool);
index 9c3a618..764f195 100644 (file)
@@ -31,7 +31,7 @@ main(int argc, char **argv)
   Pool *pool = pool_create();
   Repo *repo = repo_create(pool, "<stdin>");
   repo_add_helix(repo, stdin);
-  repo_write(repo, stdout, 0, 0);
+  repo_write(repo, stdout, 0, 0, 0, 0);
   pool_free(pool);
   exit(0);
 }
index b3a1795..c8d6f62 100644 (file)
@@ -82,7 +82,7 @@ main(int argc, char **argv)
     }
 
   create_filter(pool);
-  repo_write(repo, stdout, keyfilter, 0);
+  repo_write(repo, stdout, keyfilter, 0, 0, 0);
   pool_free(pool);
 
   return 0;
index 30a359d..68b478e 100644 (file)
@@ -23,7 +23,7 @@ main(int argc, char **argv)
   Pool *pool = pool_create();
   Repo *repo = repo_create(pool, "<stdin>");
   repo_add_patchxml(repo, stdin);
-  repo_write(repo, stdout, 0, 0);
+  repo_write(repo, stdout, 0, 0, 0, 0);
   pool_free(pool);
   exit(0);
 }
index 4dd2021..27adcc1 100644 (file)
@@ -643,6 +643,10 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
           case CTAG('=', 'P', 's', 'g'):
            s->suggests = adddep(pool, &pd, s->suggests, line, 0, 0);
            continue;
+          case CTAG('=', 'V', 'e', 'r'):
+           last_found_pack = 0;
+           indesc++;
+           continue;
        }
       if (!with_attr)
         continue;
@@ -716,10 +720,6 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr)
          case CTAG('=', 'D', 'i', 'r'):
            add_dirline (&pd, line + 6);
            continue;
-          case CTAG('=', 'V', 'e', 'r'):
-           last_found_pack = 0;
-           indesc++;
-           continue;
        }
     }
   if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
index 2af7828..f44ffa3 100644 (file)
@@ -172,6 +172,8 @@ write_blob(FILE *fp, void *data, int len)
     }
 }
 
+static unsigned id_bytes;
+
 /*
  * Id
  */
@@ -196,7 +198,7 @@ write_id(FILE *fp, Id x)
     }
 }
 
-#if 0
+#if 1
 static void
 write_str(FILE *fp, const char *str)
 {
@@ -668,6 +670,7 @@ traverse_dirs(Dirpool *dp, Id *dirmap, Id n, Id dir, Id *used)
        continue;
       if (sib == 1 && parent == 1)
        continue;       /* already did that one above */
+assert (sib < dp->ndirs);
       dirmap[n++] = sib;
     }
   lastn = n;
@@ -713,7 +716,7 @@ write_compressed_page(FILE *fp, unsigned char *page, int len)
  */
 
 void
-repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata)
+repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodatafile *fileinfo, int nsubfiles)
 {
   Pool *pool = repo->pool;
   int i, j, k, n;
@@ -744,6 +747,15 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void
   Stringpool ownspool, *spool;
   Dirpool owndirpool, *dirpool;
 
+  int setfileinfo = 0;
+  Id repodataschema = 0;
+  Id repodataschema_internal = 0;
+
+  /* If we're given a fileinfo structure, but have no subfiles, then we're
+     writing a subfile and our callers wants info about it.  */
+  if (fileinfo && nsubfiles == 0)
+    setfileinfo = 1;
+
   memset(&cbdata, 0, sizeof(cbdata));
 
   /* go through all repodata and find the keys we need */
@@ -791,6 +803,34 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void
     }
   cbdata.nmykeys = i;
 
+  /* If we store subfile info, generate the three necessary keys.  */
+  if (nsubfiles)
+    {
+      key = cbdata.mykeys + cbdata.nmykeys;
+      key->name = REPODATA_EXTERNAL;
+      key->type = TYPE_VOID;
+      key->size = 0;
+      key->storage = KEY_STORAGE_SOLVABLE;
+      cbdata.keymap[key->name] = key - cbdata.mykeys;
+      key++;
+
+      key->name = REPODATA_KEYS;
+      key->type = TYPE_IDVALUEARRAY;
+      key->size = 0;
+      key->storage = KEY_STORAGE_SOLVABLE;
+      cbdata.keymap[key->name] = key - cbdata.mykeys;
+      key++;
+
+      key->name = REPODATA_LOCATION;
+      key->type = TYPE_STR;
+      key->size = 0;
+      key->storage = KEY_STORAGE_SOLVABLE;
+      cbdata.keymap[key->name] = key - cbdata.mykeys;
+      key++;
+
+      cbdata.nmykeys = key - cbdata.mykeys;
+    }
+
   dirpoolusage = 0;
 
   spool = 0;
@@ -1053,6 +1093,46 @@ for (i = 1; i < cbdata.nmykeys; i++)
 
   reloff = needid[0].map;
 
+  /* If we have fileinfos to write, setup schemas and increment needid[]
+     of the right strings.  */
+  for (i = 0; i < nsubfiles; i++)
+    {
+      int j;
+
+      if (fileinfo[i].location && !repodataschema)
+        {
+         Id schema[4];
+         schema[0] = cbdata.keymap[REPODATA_EXTERNAL];
+         schema[1] = cbdata.keymap[REPODATA_KEYS];
+         schema[2] = cbdata.keymap[REPODATA_LOCATION];
+         schema[3] = 0;
+         repodataschema = addschema(&cbdata, schema);
+       }
+      else if (!repodataschema_internal)
+        {
+         Id schema[3];
+         schema[0] = cbdata.keymap[REPODATA_EXTERNAL];
+         schema[1] = cbdata.keymap[REPODATA_KEYS];
+         schema[2] = 0;
+         repodataschema_internal = addschema(&cbdata, schema);
+       }
+      if (2 * fileinfo[i].nkeys > cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size)
+       cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size = 2 * fileinfo[i].nkeys;
+      for (j = 1; j < fileinfo[i].nkeys; j++)
+       needid[fileinfo[i].keys[j].name].need++;
+#if 0
+      fprintf (stderr, " %d nkeys: %d:", i, fileinfo[i].nkeys);
+      for (j = 1; j < fileinfo[i].nkeys; j++)
+        {
+         needid[fileinfo[i].keys[j].name].need++;
+         fprintf (stderr, " %s(%d,%d)", id2str(pool, fileinfo[i].keys[j].name),
+                  fileinfo[i].keys[j].name, fileinfo[i].keys[j].type);
+       }
+      fprintf (stderr, "\n");
+#endif
+    }
+  if (nsubfiles)
+    cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size -= 2;
 
 /********************************************************************/
 
@@ -1222,7 +1302,7 @@ if (cbdata.dirused)
   write_u32(fp, repo->nsolvables);
   write_u32(fp, cbdata.nmykeys);
   write_u32(fp, cbdata.nmyschemata);
-  write_u32(fp, 0);    /* info blocks.  */
+  write_u32(fp, nsubfiles);    /* info blocks.  */
   solv_flags = 0;
   solv_flags |= SOLV_FLAG_PREFIX_POOL;
 #if 0
@@ -1294,6 +1374,11 @@ if (cbdata.dirused)
   /*
    * write keys
    */
+  if (setfileinfo)
+    {
+      fileinfo->nkeys = cbdata.nmykeys;
+      fileinfo->keys = sat_calloc (fileinfo->nkeys, sizeof (*fileinfo->keys));
+    }
   for (i = 1; i < cbdata.nmykeys; i++)
     {
       write_id(fp, needid[cbdata.mykeys[i].name].need);
@@ -1303,6 +1388,8 @@ if (cbdata.dirused)
       else
         write_id(fp, cbdata.extdata[i].len);
       write_id(fp, cbdata.mykeys[i].storage);
+      if (setfileinfo)
+        fileinfo->keys[i] = cbdata.mykeys[i];
     }
 
   /*
@@ -1315,28 +1402,32 @@ if (cbdata.dirused)
        write_idarray(fp, pool, 0, cbdata.myschemadata + cbdata.myschemata[i]);
     }
 
-#if 0
   /*
    * write info block
    */
-  for (i = 0; i < repo->nrepodata; i++)
+  for (i = 0; i < nsubfiles; i++)
     {
       int j;
 
-      if (repo->repodata[i].location)
+      if (fileinfo[i].location)
         write_id(fp, repodataschema);
       else
         write_id(fp, repodataschema_internal);
       /* keys + location, write idarray */
-      for (j = 0; j < repo->repodata[i].nkeys; j++)
+      for (j = 1; j < fileinfo[i].nkeys; j++)
         {
-         Id id = needid[repo->repodata[i].keys[j].name].need;
-         write_id_value(fp, id, repo->repodata[i].keys[j].type, j == repo->repodata[i].nkeys - 1);
+                  
+         Id id = needid[fileinfo[i].keys[j].name].need;
+#if 0
+         fprintf (stderr, "writing %d(%s) %d\n", id,
+                  id2str(pool, needid[id].map),
+                  fileinfo[i].keys[j].type);
+#endif
+         write_id_value(fp, id, fileinfo[i].keys[j].type, j == fileinfo[i].nkeys - 1);
         }
-      if (repo->repodata[i].location)
-        write_str(fp, repo->repodata[i].location);
+      if (fileinfo[i].location)
+        write_str(fp, fileinfo[i].location);
     }
-#endif
 
 
 /********************************************************************/
@@ -1350,6 +1441,7 @@ if (cbdata.dirused)
     {
       if (s->repo != repo)
        continue;
+      id_bytes = 0;
       /* keep in sync with schema generation! */
       write_id(fp, cbdata.solvschemata[n]);
 #if 0
@@ -1389,11 +1481,12 @@ if (cbdata.dirused)
       if (s->freshens && cbdata.keymap[SOLVABLE_FRESHENS])
         write_idarray_sort(fp, pool, needid, idarraydata + s->freshens);
       if (repo->rpmdbid && cbdata.keymap[RPM_RPMDBID])
-        write_u32(fp, repo->rpmdbid[i - repo->start]);
+        write_u32(fp, repo->rpmdbid[i - repo->start]),id_bytes+=4;
       if (cbdata.incorelen[n])
        {
          write_blob(fp, incoredata, cbdata.incorelen[n]);
          incoredata += cbdata.incorelen[n];
+         id_bytes += cbdata.incorelen[n];
        }
       n++;
     }
@@ -1443,6 +1536,15 @@ if (cbdata.dirused)
       write_blob(fp, cbdata.extdata[i].buf, cbdata.extdata[i].len);
 #endif
 
+  /* Fill fileinfo for our caller.  */
+  if (setfileinfo)
+    {
+      fileinfo->checksum = 0;
+      fileinfo->nchecksum = 0;
+      fileinfo->checksumtype = 0;
+      fileinfo->location = 0;
+    }
+
   for (i = 1; i < cbdata.nmykeys; i++)
     sat_free(cbdata.extdata[i].buf);
 
@@ -1451,5 +1553,3 @@ if (cbdata.dirused)
   sat_free(cbdata.myschemadata);
   sat_free(cbdata.myschemata);
 }
-
-// EOF
index eb3b7e7..149eb3e 100644 (file)
 #include "pool.h"
 #include "repo.h"
 
-void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata);
+/* Describes a repodata file */
+typedef struct _Repodatafile
+{
+  /* These have the same meaning as the equally named fields in
+     Repodata.  */
+  char *location;
+  char *checksum;
+  unsigned nchecksum;
+  unsigned checksumtype;
+  struct _Repokey *keys;
+  unsigned int nkeys;
+} Repodatafile;
+
+void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodatafile *fileinfo, int nsubfiles);
 
 #endif
index ba23da6..8bd134a 100644 (file)
@@ -54,7 +54,7 @@ main(int argc, char **argv)
       ref = 0;
     }
 
-  repo_write(repo, stdout, 0, 0);
+  repo_write(repo, stdout, 0, 0, 0, 0);
   pool_free(pool);
 
   exit(0);
index b035ac6..1351c47 100644 (file)
@@ -23,7 +23,7 @@ main(int argc, char **argv)
   Pool *pool = pool_create();
   Repo *repo = repo_create(pool, "<stdin>");
   repo_add_rpmmd(repo, stdin);
-  repo_write(repo, stdout, 0, 0);
+  repo_write(repo, stdout, 0, 0, 0, 0);
   pool_free(pool);
   exit(0);
 }
index 234a57d..a7a8b81 100644 (file)
@@ -53,9 +53,23 @@ create_filter(Pool *pool)
     }
 }
 
+static int test_separate = 0;
+
 static int
-keyfilter(Repo *data, Repokey *key, void *kfdata)
+keyfilter_solv(Repo *data, Repokey *key, void *kfdata)
 {
+  if (test_separate && key->storage != KEY_STORAGE_SOLVABLE)
+    return KEY_STORAGE_DROPPED;
+  if (key->name < nfilter && filter[key->name])
+    return KEY_STORAGE_VERTICAL_OFFSET;
+  return KEY_STORAGE_INCORE;
+}
+
+static int
+keyfilter_attr(Repo *data, Repokey *key, void *kfdata)
+{
+  if (key->storage == KEY_STORAGE_SOLVABLE)
+    return KEY_STORAGE_DROPPED;
   if (key->name < nfilter && filter[key->name])
     return KEY_STORAGE_VERTICAL_OFFSET;
   return KEY_STORAGE_INCORE;
@@ -64,6 +78,9 @@ keyfilter(Repo *data, Repokey *key, void *kfdata)
 int
 main(int argc, char **argv)
 {
+  Repodatafile fileinfoa[1];
+  Repodatafile *fileinfo = 0;
+  int nsubfiles = 0;
   int with_attr = 0;
   argv++;
   argc--;
@@ -75,6 +92,7 @@ main(int argc, char **argv)
           switch (*s++)
            {
              case 'a': with_attr = 1; break;
+             case 's': test_separate = 1; break;
              default : break;
            }
       argv++;
@@ -83,7 +101,20 @@ main(int argc, char **argv)
   Repo *repo = repo_create(pool, "<stdin>");
   repo_add_susetags(repo, stdin, 0, with_attr);
   create_filter(pool);
-  repo_write(repo, stdout, keyfilter, 0);
+  memset (fileinfoa, 0, sizeof fileinfoa);
+  if (with_attr && test_separate)
+    {
+      fileinfo = fileinfoa;
+      FILE *fp = fopen ("test.attr", "w");
+      repo_write(repo, fp, keyfilter_attr, 0, fileinfo, 0);
+      fclose (fp);
+      fileinfo->location = strdup ("test.attr");
+      fileinfo++;
+
+      nsubfiles = fileinfo - fileinfoa;
+      fileinfo = fileinfoa;
+    }
+  repo_write(repo, stdout, keyfilter_solv, 0, fileinfo, nsubfiles);
 #if 0
   if (with_attr && attr)
     {