Imported Upstream version 0.7.4
[platform/upstream/libsolv.git] / tools / rpmdb2solv.c
index 8bd134a..1a04adf 100644 (file)
 /*
  * rpmdb2solv
  * 
+ * Reads rpm database (and evtl. more, like product metadata) to build
+ * a .solv file of 'installed' solvables.
+ * Writes .solv to stdout
+ * 
  */
 
 #include <sys/types.h>
-#include <limits.h>
-#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "pool.h"
 #include "repo.h"
 #include "repo_rpmdb.h"
+#ifdef ENABLE_PUBKEY
+#include "repo_pubkey.h"
+#endif
+#include "repo_products.h"
 #include "repo_solv.h"
-#include "repo_write.h"
+#include "common_write.h"
+#ifdef ENABLE_APPDATA
+#include "repo_appdata.h"
+#endif
+#ifdef SUSE
+#include "repo_autopattern.h"
+#endif
+
+
+static void
+usage(int status)
+{
+  fprintf(stderr, "\nUsage:\n"
+         "rpmdb2solv [-P] [-C] [-n] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
+         " -n : No packages, do not read rpmdb, useful to only parse products\n"
+         " -p <productsdir> : Scan <productsdir> for .prod files, representing installed products\n"
+         " -r <root> : Prefix rpmdb path and <productsdir> with <root>\n"
+         " -o <solv> : Write .solv to file instead of stdout\n"
+          " -P : print percentage done\n"
+          " -C : include the changelog\n"
+        );
+  exit(status);
+}
+
 
 int
 main(int argc, char **argv)
 {
+  FILE *reffp = 0;
   Pool *pool = pool_create();
-  Repo *repo, *ref = 0;
-  FILE *fp;
+  Repo *repo;
+  Repodata *data;
+  int c, percent = 0;
+  int nopacks = 0;
+  int add_changelog = 0;
+  const char *root = 0;
+  const char *refname = 0;
+#ifdef ENABLE_SUSEREPO
+  char *proddir = 0;
+#endif
+  char *outfile = 0;
+#ifdef ENABLE_PUBKEY
+  int pubkeys = 0;
+#endif
+#ifdef ENABLE_APPDATA
+  int add_appdata = 0;
+#endif
+#ifdef SUSE
+  int add_auto = 0;
+#endif
+
+  /*
+   * parse arguments
+   */
+  
+  while ((c = getopt(argc, argv, "ACPhnkxXr:p:o:")) >= 0)
+    switch (c)
+      {
+      case 'h':
+         usage(0);
+       break;
+      case 'r':
+        root = optarg;
+        break;
+      case 'n':
+       nopacks = 1;
+       break;
+      case 'P':
+       percent = 1;
+       break;
+      case 'p':
+#ifdef ENABLE_SUSEREPO
+       proddir = optarg;
+#endif
+       break;
+      case 'x':
+        break; /* extrapool no longer supported */
+      case 'X':
+#ifdef SUSE
+       add_auto = 1;
+#endif
+       break;
+      case 'A':
+#ifdef ENABLE_APPDATA
+       add_appdata = 1;
+#endif
+       break;
+      case 'o':
+        outfile = optarg;
+        break;
+#ifdef ENABLE_PUBKEY
+      case 'k':
+        nopacks = 1;
+        pubkeys = 1;
+        break;
+#endif
+      case 'C':
+       add_changelog = 1;
+       break;
+      default:
+       usage(1);
+      }
+  
+  if (outfile && !freopen(outfile, "w", stdout))
+    {
+      perror(outfile);
+      exit(1);
+    }
+    
+  /*
+   * optional arg is old version of rpmdb solv file
+   * should make this a real option instead
+   */
+  
+  if (optind < argc)
+    refname = argv[optind];
+
+  if (refname && !nopacks)
+    {
+      if ((reffp = fopen(refname, "r")) == NULL)
+        perror(refname);
+    }
+
+  /*
+   * create 'installed' repository
+   * add products
+   * add rpmdb
+   * write .solv
+   */
+
+  if (root && *root)
+    pool_set_rootdir(pool, root);
+
+  repo = repo_create(pool, "installed");
+  data = repo_add_repodata(repo, 0);
 
-  if (argc != 1)
+  if (!nopacks)
     {
-      Pool *refpool = pool;
-      if ((fp = fopen(argv[1], "r")) == NULL)
+      int flags = REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE;
+      if (percent)
+       flags |= RPMDB_REPORT_PROGRESS;
+      if (add_changelog)
+       flags |= RPM_ADD_WITH_CHANGELOG;
+      if (repo_add_rpmdb_reffp(repo, reffp, flags))
        {
-         perror(argv[1]);
-         exit(0);
+         fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
+         exit(1);
        }
-      ref = repo_create(refpool, "ref");
-      repo_add_solv(ref, fp);
-      fclose(fp);
     }
+#ifdef ENABLE_PUBKEY
+  if (pubkeys)
+    {
+      if (repo_add_rpmdb_pubkeys(repo, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | ADD_WITH_KEYSIGNATURES))
+       {
+         fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
+         exit(1);
+       }
+    }
+#endif
 
-  repo = repo_create(pool, "installed");
-  repo_add_rpmdb(repo, ref, "/");
-  if (ref)
+#ifdef ENABLE_SUSEREPO
+  if (proddir && *proddir)
     {
-      if (ref->pool != pool)
-       pool_free(ref->pool);
-      else
-       repo_free(ref, 1);
-      ref = 0;
+      if (root && *root)
+       {
+         int rootlen = strlen(root);
+         if (!strncmp(root, proddir, rootlen))
+           {
+             proddir += rootlen;
+             if (*proddir != '/' && proddir[-1] == '/')
+               proddir--;
+           }
+       }
+      if (repo_add_products(repo, proddir, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+       {
+         fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
+         exit(1);
+       }
     }
+#endif
 
-  repo_write(repo, stdout, 0, 0, 0, 0);
-  pool_free(pool);
+#ifdef ENABLE_APPDATA
+  if (add_appdata)
+    {
+      repo_add_appdata_dir(repo, "/usr/share/metainfo", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST);
+      repo_add_appdata_dir(repo, "/usr/share/appdata", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST);
+    }
+#endif
+  repodata_internalize(data);
 
+  if (reffp)
+    fclose(reffp);
+
+#ifdef SUSE
+  if (add_auto)
+    repo_add_autopattern(repo, ADD_NO_AUTOPRODUCTS);
+#endif
+
+  tool_write(repo, stdout);
+  pool_free(pool);
   exit(0);
 }