- support repo_add_arch_local to read the installed package database on arch
authorMichael Schroeder <mls@suse.de>
Tue, 3 Apr 2012 09:44:44 +0000 (11:44 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 3 Apr 2012 09:44:44 +0000 (11:44 +0200)
ext/libsolvext.ver
ext/repo_arch.c
ext/repo_arch.h
tools/archrepo2solv.c

index e291f2c..74d2718 100644 (file)
@@ -1,6 +1,7 @@
 SOLV_1.0 {
        global:
                pool_findfileconflicts;
+               repo_add_arch_local;
                repo_add_arch_pkg;
                repo_add_arch_repo;
                repo_add_code11_products;
index b8c88cc..183d13d 100644 (file)
@@ -13,6 +13,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <dirent.h>
 
 #include "pool.h"
 #include "repo.h"
@@ -89,6 +90,18 @@ static char *getsentry(struct tarhead *th, char *s, int size)
            }
        }
       th->off = i;
+      if (!th->path)
+       {
+         /* fake entry */
+         th->end = fread(th->blk, 1, 512, th->fp);
+         if (th->end <= 0)
+           {
+             th->eof = 1;
+             return 0;
+           }
+         th->off = 0;
+         continue;
+       }
       if (th->length <= 0)
        return 0;
       if (readblock(th->fp, th->blk))
@@ -536,21 +549,200 @@ joinhash_lookup(Repo *repo, Hashtable ht, Hashmask hm, const char *fn)
   return 0;
 }
 
+static void
+adddata(Repodata *data, Solvable *s, struct tarhead *th)
+{
+  Repo *repo = data->repo;
+  Pool *pool = repo->pool;
+  char line[4096];
+  int l;
+  int havesha256 = 0;
+
+  while (getsentry(th, line, sizeof(line)))
+    {
+      l = strlen(line);
+      if (l == 0 || line[l - 1] != '\n')
+       continue;
+      line[--l] = 0;
+      if (l <= 2 || line[0] != '%' || line[l - 1] != '%')
+       continue;
+      if (!strcmp(line, "%FILENAME%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_location(data, s - pool->solvables, 0, 0, line);
+       }
+      else if (!strcmp(line, "%NAME%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           s->name = pool_str2id(pool, line, 1);
+       }
+      else if (!strcmp(line, "%VERSION%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           s->evr = pool_str2id(pool, line, 1);
+       }
+      else if (!strcmp(line, "%DESC%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           {
+             repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line);
+             repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line);
+           }
+       }
+      else if (!strcmp(line, "%GROUPS%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line);
+       }
+      else if (!strcmp(line, "%CSIZE%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, strtoull(line, 0, 10));
+       }
+      else if (!strcmp(line, "%ISIZE%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line, 0, 10));
+       }
+      else if (!strcmp(line, "%MD5SUM%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)) && !havesha256)
+           repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, REPOKEY_TYPE_MD5, line);
+       }
+      else if (!strcmp(line, "%SHA256SUM%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           {
+             repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, REPOKEY_TYPE_SHA256, line);
+             havesha256 = 1;
+           }
+       }
+      else if (!strcmp(line, "%URL%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line);
+       }
+      else if (!strcmp(line, "%LICENSE%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_str(data, s - pool->solvables, SOLVABLE_LICENSE, line);
+       }
+      else if (!strcmp(line, "%ARCH%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           s->arch = pool_str2id(pool, line, 1);
+       }
+      else if (!strcmp(line, "%BUILDDATE%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line, 0, 10));
+       }
+      else if (!strcmp(line, "%PACKAGER%"))
+       {
+         if (getsentrynl(th, line, sizeof(line)))
+           repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line);
+       }
+      else if (!strcmp(line, "%REPLACES%"))
+       {
+         while (getsentrynl(th, line, sizeof(line)) && *line)
+           s->obsoletes = adddep(repo, s->obsoletes, line);
+       }
+      else if (!strcmp(line, "%DEPENDS%"))
+       {
+         while (getsentrynl(th, line, sizeof(line)) && *line)
+           s->requires = adddep(repo, s->requires, line);
+       }
+      else if (!strcmp(line, "%CONFLICTS%"))
+       {
+         while (getsentrynl(th, line, sizeof(line)) && *line)
+           s->conflicts = adddep(repo, s->conflicts, line);
+       }
+      else if (!strcmp(line, "%PROVIDES%"))
+       {
+         while (getsentrynl(th, line, sizeof(line)) && *line)
+           s->provides = adddep(repo, s->provides, line);
+       }
+      else if (!strcmp(line, "%OPTDEPENDS%"))
+       {
+         while (getsentrynl(th, line, sizeof(line)) && *line)
+           {
+             char *p = strchr(line, ':');
+             if (p && p > line)
+               *p = 0;
+             s->suggests = adddep(repo, s->suggests, line);
+           }
+       }
+      else if (!strcmp(line, "%FILES%"))
+       {
+         while (getsentrynl(th, line, sizeof(line)) && *line)
+           {
+             char *p;
+             Id id;
+             l = strlen(line);
+             if (l > 1 && line[l - 1] == '/')
+               line[--l] = 0;  /* remove trailing slashes */
+             if ((p = strrchr(line , '/')) != 0)
+               {
+                 *p++ = 0;
+                 if (line[0] != '/')   /* anchor */
+                   {
+                     char tmp = *p;
+                     memmove(line + 1, line, p - 1 - line);
+                     *line = '/';
+                     *p = 0;
+                     id = repodata_str2dir(data, line, 1);
+                     *p = tmp;
+                   }
+                 else
+                   id = repodata_str2dir(data, line, 1);
+               }
+             else
+               {
+                 p = line;
+                 id = 0;
+               }
+             if (!id)
+               id = repodata_str2dir(data, "/", 1);
+             repodata_add_dirstr(data, s - pool->solvables, SOLVABLE_FILELIST, id, p);
+           }
+       }
+      while (*line)
+       getsentrynl(th, line, sizeof(line));
+    }
+}
+
+static void
+finishsolvable(Repo *repo, Solvable *s)
+{
+  Pool *pool = repo->pool;
+  if (!s)
+    return;
+  if (!s->name)
+    {
+      repo_free_solvable_block(repo, s - pool->solvables, 1, 1);
+      return;
+    }
+  if (!s->arch)
+    s->arch = ARCH_ANY;
+  if (!s->evr)
+    s->evr = ID_EMPTY;
+  s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+}
+
 int
 repo_add_arch_repo(Repo *repo, FILE *fp, int flags)
 {
   Pool *pool = repo->pool;
   Repodata *data;
-  data = repo_add_repodata(repo, flags);
   struct tarhead th;
   char *lastdn = 0;
-  int l, lastdnlen = 0;
-  char line[4096];
+  int lastdnlen = 0;
   Solvable *s = 0;
-  int havesha256 = 0;
   Hashtable joinhash = 0;
   Hashmask joinhashmask = 0;
 
+  data = repo_add_repodata(repo, flags);
+
   if (flags & REPO_EXTEND_SOLVABLES)
     joinhash = joinhash_init(repo, &joinhashmask);
 
@@ -576,22 +768,7 @@ repo_add_arch_repo(Repo *repo, FILE *fp, int flags)
        }
       if (!lastdn || (bn - th.path) != lastdnlen || strncmp(lastdn, th.path, lastdnlen) != 0)
        {
-         if (s)
-           {
-             if (s && !s->name)
-               {
-                 repo_free_solvable_block(repo, s - pool->solvables, 1, 1);
-                 s = 0;
-               }
-             if (s)
-               {
-                 if (!s->arch)
-                   s->arch = ARCH_ANY;
-                 if (!s->evr)
-                   s->evr = ID_EMPTY;
-                 s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
-               }
-           }
+         finishsolvable(repo, s);
          solv_free(lastdn);
          lastdn = solv_strdup(th.path);
          lastdnlen = bn - th.path;
@@ -607,178 +784,61 @@ repo_add_arch_repo(Repo *repo, FILE *fp, int flags)
            }
          else
            s = pool_id2solvable(pool, repo_add_solvable(repo));
-         havesha256 = 0;
        }
-      while (getsentry(&th, line, sizeof(line)))
+      adddata(data, s, &th);
+    }
+  finishsolvable(repo, s);
+  solv_free(joinhash);
+  solv_free(lastdn);
+  if (!(flags & REPO_NO_INTERNALIZE))
+    repodata_internalize(data);
+  return 0;
+}
+
+int
+repo_add_arch_local(Repo *repo, const char *dir, int flags)
+{
+  Pool *pool = repo->pool;
+  Repodata *data;
+  DIR *dp;
+  struct dirent *de;
+  char *entrydir, *file;
+  FILE *fp;
+  Solvable *s;
+
+  data = repo_add_repodata(repo, flags);
+
+  dp = opendir(dir);
+  if (dp)
+    {
+      while ((de = readdir(dp)) != 0)
        {
-         l = strlen(line);
-         if (l == 0 || line[l - 1] != '\n')
-           continue;
-         line[--l] = 0;
-         if (l <= 2 || line[0] != '%' || line[l - 1] != '%')
+         if (!de->d_name[0] || de->d_name[0] == '.')
            continue;
-         if (!strcmp(line, "%FILENAME%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_location(data, s - pool->solvables, 0, 0, line);
-           }
-         else if (!strcmp(line, "%NAME%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               s->name = pool_str2id(pool, line, 1);
-           }
-         else if (!strcmp(line, "%VERSION%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               s->evr = pool_str2id(pool, line, 1);
-           }
-         else if (!strcmp(line, "%DESC%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               {
-                 repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line);
-                 repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line);
-               }
-           }
-         else if (!strcmp(line, "%GROUPS%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line);
-           }
-         else if (!strcmp(line, "%CSIZE%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, strtoull(line, 0, 10));
-           }
-         else if (!strcmp(line, "%ISIZE%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line, 0, 10));
-           }
-         else if (!strcmp(line, "%MD5SUM%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)) && !havesha256)
-               repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, REPOKEY_TYPE_MD5, line);
-           }
-         else if (!strcmp(line, "%SHA256SUM%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               {
-                 repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, REPOKEY_TYPE_SHA256, line);
-                 havesha256 = 1;
-               }
-           }
-         else if (!strcmp(line, "%URL%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line);
-           }
-         else if (!strcmp(line, "%LICENSE%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_str(data, s - pool->solvables, SOLVABLE_LICENSE, line);
-           }
-         else if (!strcmp(line, "%ARCH%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               s->arch = pool_str2id(pool, line, 1);
-           }
-         else if (!strcmp(line, "%BUILDDATE%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line, 0, 10));
-           }
-         else if (!strcmp(line, "%PACKAGER%"))
-           {
-             if (getsentrynl(&th, line, sizeof(line)))
-               repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line);
-           }
-         else if (!strcmp(line, "%REPLACES%"))
-           {
-             while (getsentrynl(&th, line, sizeof(line)) && *line)
-               s->obsoletes = adddep(repo, s->obsoletes, line);
-           }
-         else if (!strcmp(line, "%DEPENDS%"))
-           {
-             while (getsentrynl(&th, line, sizeof(line)) && *line)
-               s->requires = adddep(repo, s->requires, line);
-           }
-         else if (!strcmp(line, "%CONFLICTS%"))
-           {
-             while (getsentrynl(&th, line, sizeof(line)) && *line)
-               s->conflicts = adddep(repo, s->conflicts, line);
-           }
-         else if (!strcmp(line, "%PROVIDES%"))
-           {
-             while (getsentrynl(&th, line, sizeof(line)) && *line)
-               s->provides = adddep(repo, s->provides, line);
-           }
-         else if (!strcmp(line, "%OPTDEPENDS%"))
-           {
-             while (getsentrynl(&th, line, sizeof(line)) && *line)
-               {
-                 char *p = strchr(line, ':');
-                 if (p && p > line)
-                   *p = 0;
-                 s->suggests = adddep(repo, s->suggests, line);
-               }
-           }
-         else if (!strcmp(line, "%FILES%"))
+         entrydir = solv_dupjoin(dir, "/", de->d_name);
+         file = pool_tmpjoin(repo->pool, entrydir, "/desc", 0);
+         s = 0;
+         if ((fp = fopen(file, "r")) != 0)
            {
-             while (getsentrynl(&th, line, sizeof(line)) && *line)
+             struct tarhead th;
+             inittarhead(&th, fp);
+             s = pool_id2solvable(pool, repo_add_solvable(repo));
+             adddata(data, s, &th);
+             freetarhead(&th);
+             fclose(fp);
+             file = pool_tmpjoin(repo->pool, entrydir, "/files", 0);
+             if ((fp = fopen(file, "r")) != 0)
                {
-                 char *p;
-                 Id id;
-                 l = strlen(line);
-                 if (l > 1 && line[l - 1] == '/')
-                   line[--l] = 0;      /* remove trailing slashes */
-                 if ((p = strrchr(line , '/')) != 0)
-                   {
-                     *p++ = 0;
-                     if (line[0] != '/')       /* anchor */
-                       {
-                         char tmp = *p;
-                         memmove(line + 1, line, p - 1 - line);
-                         *line = '/';
-                         *p = 0;
-                         id = repodata_str2dir(data, line, 1);
-                         *p = tmp;
-                       }
-                     else
-                       id = repodata_str2dir(data, line, 1);
-                   }
-                 else
-                   {
-                     p = line;
-                     id = 0;
-                   }
-                 if (!id)
-                   id = repodata_str2dir(data, "/", 1);
-                 repodata_add_dirstr(data, s - pool->solvables, SOLVABLE_FILELIST, id, p);
+                 inittarhead(&th, fp);
+                 adddata(data, s, &th);
+                 freetarhead(&th);
+                 fclose(fp);
                }
            }
-         while (*line)
-           getsentrynl(&th, line, sizeof(line));
+         solv_free(entrydir);
        }
+      closedir(dp);
     }
-  if (s)
-    {
-      if (s && !s->name)
-       {
-         repo_free_solvable_block(repo, s - pool->solvables, 1, 1);
-         s = 0;
-       }
-      if (s)
-       {
-         if (!s->arch)
-           s->arch = ARCH_ANY;
-         if (!s->evr)
-           s->evr = ID_EMPTY;
-         s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
-       }
-    }
-  solv_free(joinhash);
-  solv_free(lastdn);
   if (!(flags & REPO_NO_INTERNALIZE))
     repodata_internalize(data);
   return 0;
index 65be8fe..78a2f32 100644 (file)
@@ -9,4 +9,5 @@
 
 extern Id repo_add_arch_pkg(Repo *repo, const char *fn, int flags);
 extern Id repo_add_arch_repo(Repo *repo, FILE *fp, int flags);
+extern Id repo_add_arch_local(Repo *repo, const char *dir, int flags);
 
index e671c49..3bb7179 100644 (file)
@@ -35,6 +35,7 @@ usage(int status)
   fprintf(stderr, "\nUsage:\n"
           "archrepo2solv\n"
           "  reads a repository from <stdin> and writes a .solv file to <stdout>\n"
+          "  -l <dbdir> : read local database\n"
           "  -h : print help & exit\n"
          );
    exit(status);
@@ -46,14 +47,18 @@ main(int argc, char **argv)
   Pool *pool;
   Repo *repo;
   int c;
+  const char *localdb = 0;
 
-  while ((c = getopt(argc, argv, "h")) >= 0)
+  while ((c = getopt(argc, argv, "hl:")) >= 0)
     {
       switch(c)
        {
        case 'h':
          usage(0);
          break;
+       case 'l':
+         localdb = optarg;
+         break;
        default:
          usage(1);
          break;
@@ -61,7 +66,10 @@ main(int argc, char **argv)
     }
   pool = pool_create();
   repo = repo_create(pool, "<stdin>");
-  repo_add_arch_repo(repo, stdin, 0);
+  if (localdb)
+    repo_add_arch_local(repo, localdb, 0);
+  else
+    repo_add_arch_repo(repo, stdin, 0);
   tool_write(repo, 0, 0);
   pool_free(pool);
   exit(0);