summaryrefslogtreecommitdiff
path: root/libsolv-0.4.0/tools/susetags2solv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsolv-0.4.0/tools/susetags2solv.c')
-rw-r--r--libsolv-0.4.0/tools/susetags2solv.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/libsolv-0.4.0/tools/susetags2solv.c b/libsolv-0.4.0/tools/susetags2solv.c
new file mode 100644
index 0000000..f94e517
--- /dev/null
+++ b/libsolv-0.4.0/tools/susetags2solv.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2007, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <zlib.h>
+#include <getopt.h>
+
+#include "pool.h"
+#include "repo.h"
+#include "repo_susetags.h"
+#include "repo_content.h"
+#include "common_write.h"
+#include "solv_xfopen.h"
+
+static void
+usage(int status)
+{
+ fprintf(stderr, "\nUsage:\n"
+ "susetags2solv [-b <base>][-c <content>][-d <descrdir>][-h][-n <name>]\n"
+ " reads a 'susetags' repository from <stdin> and writes a .solv file to <stdout>\n"
+ " -b <base>: save as multiple files starting with <base>\n"
+ " -c <contentfile> : parse given contentfile (for product information)\n"
+ " -d <descrdir> : do not read from stdin, but use data in descrdir\n"
+ " -h : print help & exit\n"
+ " -n <name>: save attributes as <name>.attr\n"
+ );
+ exit(status);
+}
+
+/* content file query */
+static void
+doquery(Pool *pool, Repo *repo, const char *arg)
+{
+ char qbuf[256];
+ const char *str;
+ Id id;
+
+ snprintf(qbuf, sizeof(qbuf), "susetags:%s", arg);
+ id = pool_str2id(pool, qbuf, 0);
+ if (!id)
+ return;
+ str = repo_lookup_str(repo, SOLVID_META, id);
+ if (str)
+ printf("%s\n", str);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *contentfile = 0;
+ const char *attrname = 0;
+ const char *descrdir = 0;
+ const char *basefile = 0;
+ const char *query = 0;
+ Id defvendor = 0;
+ int flags = 0;
+ int c;
+ Pool *pool;
+ Repo *repo;
+
+ while ((c = getopt(argc, argv, "hn:c:d:b:q:")) >= 0)
+ {
+ switch (c)
+ {
+ case 'h':
+ usage(0);
+ break;
+ case 'n':
+ attrname = optarg;
+ break;
+ case 'c':
+ contentfile = optarg;
+ break;
+ case 'd':
+ descrdir = optarg;
+ break;
+ case 'b':
+ basefile = optarg;
+ break;
+ case 'q':
+ query = optarg;
+ break;
+ default:
+ usage(1);
+ break;
+ }
+ }
+ pool = pool_create();
+ repo = repo_create(pool, "<susetags>");
+
+ repo_add_repodata(repo, 0);
+
+ if (contentfile)
+ {
+ FILE *fp = fopen(contentfile, "r");
+ if (!fp)
+ {
+ perror(contentfile);
+ exit(1);
+ }
+ if (repo_add_content(repo, fp, REPO_REUSE_REPODATA))
+ {
+ fprintf(stderr, "susetags2solv: %s: %s\n", contentfile, pool_errstr(pool));
+ exit(1);
+ }
+ defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR);
+ fclose(fp);
+ }
+
+ if (attrname)
+ {
+ /* ensure '.attr' suffix */
+ const char *dot = strrchr(attrname, '.');
+ if (!dot || strcmp(dot, ".attr"))
+ {
+ int len = strlen (attrname);
+ char *newname = (char *)malloc(len + 6); /* alloc for <attrname>+'.attr'+'\0' */
+ strcpy (newname, attrname);
+ strcpy (newname+len, ".attr");
+ attrname = newname;
+ }
+ }
+
+ /*
+ * descrdir path given, open files and read from there
+ */
+
+ if (descrdir)
+ {
+ char *fnp;
+ int ndirs, i;
+ struct dirent **files;
+
+ ndirs = scandir(descrdir, &files, 0, alphasort);
+ if (ndirs < 0)
+ {
+ perror(descrdir);
+ exit(1);
+ }
+
+ /* bring packages to front */
+ for (i = 0; i < ndirs; i++)
+ {
+ char *fn = files[i]->d_name;
+ if (!strcmp(fn, "packages") || !strcmp(fn, "packages.gz"))
+ break;
+ }
+ if (i == ndirs)
+ {
+ fprintf(stderr, "found no packages file\n");
+ exit(1);
+ }
+ if (i)
+ {
+ struct dirent *de = files[i];
+ memmove(files + 1, files, i * sizeof(de));
+ files[0] = de;
+ }
+
+ fnp = solv_malloc(strlen(descrdir) + 128);
+ for (i = 0; i < ndirs; i++)
+ {
+ char *fn = files[i]->d_name;
+
+ if (!strcmp(fn, "packages") || !strcmp(fn, "packages.gz"))
+ {
+ FILE *fp;
+ sprintf(fnp, "%s/%s", descrdir, fn);
+ fp = solv_xfopen(fnp, 0);
+ if (!fp)
+ {
+ perror(fn);
+ exit(1);
+ }
+ if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ {
+ fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+ exit(1);
+ }
+ fclose(fp);
+ }
+ else if (!strcmp(fn, "packages.DU") || !strcmp(fn, "packages.DU.gz"))
+ {
+ FILE *fp;
+ sprintf(fnp, "%s/%s", descrdir, fn);
+ fp = solv_xfopen(fnp, 0);
+ if (!fp)
+ {
+ perror(fn);
+ exit(1);
+ }
+ if (repo_add_susetags(repo, fp, defvendor, 0, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ {
+ fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+ exit(1);
+ }
+ fclose(fp);
+ }
+ else if (!strcmp(fn, "packages.FL") || !strcmp(fn, "packages.FL.gz"))
+ {
+#if 0
+ sprintf(fnp, "%s/%s", descrdir, fn);
+ FILE *fp = solv_xfopen(fnp, 0);
+ if (!fp)
+ {
+ perror(fn);
+ exit(1);
+ }
+ if (repo_add_susetags(repo, fp, defvendor, 0, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ {
+ fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+ exit(1);
+ }
+ fclose(fp);
+#else
+ /* ignore for now. reactivate when filters work */
+ continue;
+#endif
+ }
+ else if (!strncmp(fn, "packages.", 9))
+ {
+ char lang[6];
+ char *p;
+ FILE *fp;
+ sprintf(fnp, "%s/%s", descrdir, fn);
+ p = strrchr(fnp, '.');
+ if (p && !strcmp(p, ".gz"))
+ {
+ *p = 0;
+ p = strrchr(fnp, '.');
+ }
+ if (!p || !p[1] || strlen(p + 1) > 5)
+ continue;
+ strcpy(lang, p + 1);
+ sprintf(fnp, "%s/%s", descrdir, fn);
+ fp = solv_xfopen(fnp, 0);
+ if (!fp)
+ {
+ perror(fn);
+ exit(1);
+ }
+ if (repo_add_susetags(repo, fp, defvendor, lang, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ {
+ fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
+ exit(1);
+ }
+ fclose(fp);
+ }
+ }
+ for (i = 0; i < ndirs; i++)
+ free(files[i]);
+ free(files);
+ free(fnp);
+ repo_internalize(repo);
+ }
+ else
+ {
+ /* read data from stdin */
+ if (repo_add_susetags(repo, stdin, defvendor, 0, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ {
+ fprintf(stderr, "susetags2solv: %s\n", pool_errstr(pool));
+ exit(1);
+ }
+ }
+ repo_internalize(repo);
+
+ if (query)
+ doquery(pool, repo, query);
+ else
+ tool_write(repo, basefile, attrname);
+ pool_free(pool);
+ exit(0);
+}