ref: refs/heads/master
commit 74b7ef329450d67ddb6bcffd206383deba9fef57
Author: Michael Schroeder
Date: Sat Jun 20 13:04:36 2009 +0200
- clean up ugly products handling
---
tools/CMakeLists.txt | 1 +
tools/repo_products.c | 270 +++++++++++++------------------------
tools/repo_products.h | 3 +-
tools/repo_releasefile_products.c | 156 +++++++++++++++++++++
tools/repo_releasefile_products.h | 8 +
tools/repo_zyppdb.c | 69 +++++-----
tools/repo_zyppdb.h | 2 +-
tools/rpmdb2solv.c | 2 +-
8 files changed, 296 insertions(+), 215 deletions(-)
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 741bb10..576dae4 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -10,6 +10,7 @@ SET(rpmdb2solv_REPOS
repo_rpmdb.c
repo_products.c
repo_zyppdb.c
+ repo_releasefile_products.c
)
ADD_EXECUTABLE( rpmdb2solv ${rpmdb2solv_REPOS} )
diff --git a/tools/repo_products.c b/tools/repo_products.c
index a974f71..5cdcc19 100644
--- a/tools/repo_products.c
+++ b/tools/repo_products.c
@@ -31,6 +31,7 @@
#include "tools_util.h"
#include "repo_content.h"
#include "repo_zyppdb.h"
+#include "repo_releasefile_products.h"
//#define DUMPOUT 0
@@ -385,7 +386,7 @@ characterData(void *userData, const XML_Char *s, int len)
*/
static void
-repo_add_product(struct parsedata *pd, FILE *fp, int code11)
+add_code11_product(struct parsedata *pd, FILE *fp)
{
char buf[BUFF_SIZE];
int l;
@@ -403,162 +404,101 @@ repo_add_product(struct parsedata *pd, FILE *fp, int code11)
pd->ctime = 0;
}
- if (code11)
- {
- XML_Parser parser = XML_ParserCreate(NULL);
- XML_SetUserData(parser, pd);
- XML_SetElementHandler(parser, startElement, endElement);
- XML_SetCharacterDataHandler(parser, characterData);
+ XML_Parser parser = XML_ParserCreate(NULL);
+ XML_SetUserData(parser, pd);
+ XML_SetElementHandler(parser, startElement, endElement);
+ XML_SetCharacterDataHandler(parser, characterData);
- for (;;)
- {
- l = fread(buf, 1, sizeof(buf), fp);
- if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
- {
- pool_debug(pd->pool, SAT_ERROR, "%s: %s at line %u:%u\n", pd->filename, XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
- pool_debug(pd->pool, SAT_ERROR, "Skipping this product\n");
- XML_ParserFree(parser);
- return;
- }
- if (l == 0)
- break;
- }
- XML_ParserFree(parser);
- }
- else
+ for (;;)
{
- Id name = 0;
- Id arch = 0;
- Id version = 0;
- int lnum = 0; /* line number */
- char *ptr, *ptr1;
- /* parse /etc/<xyz>-release file */
- while (fgets(buf, sizeof(buf), fp))
- {
- /* remove trailing \n */
- int l = strlen(buf);
- if (*(buf + l - 1) == '\n')
- {
- --l;
- *(buf + l) = 0;
- }
- ++lnum;
-
- if (lnum == 1)
- {
- /* 1st line, <name> [(<arch>)] */
- ptr = strchr(buf, '(');
- if (ptr)
- {
- ptr1 = ptr - 1;
- *ptr++ = 0;
- }
- else
- ptr1 = buf + l - 1;
-
- /* track back until non-blank, non-digit */
- while (ptr1 > buf
- && (*ptr1 == ' ' || isdigit(*ptr1) || *ptr1 == '.'))
- --ptr1;
- *(++ptr1) = 0;
- name = str2id(pd->pool, join2("product", ":", buf), 1);
-
- if (ptr)
- {
- /* have arch */
- char *ptr1 = strchr(ptr, ')');
- if (ptr1)
- {
- *ptr1 = 0;
- /* downcase arch */
- ptr1 = ptr;
- while (*ptr1)
- {
- if (isupper(*ptr1)) *ptr1 = tolower(*ptr1);
- ++ptr1;
- }
- arch = str2id(pd->pool, ptr, 1);
- }
- }
- }
- else if (strncmp(buf, "VERSION", 7) == 0)
- {
- ptr = strchr(buf+7, '=');
- if (ptr)
- {
- while (*++ptr == ' ');
- version = makeevr(pd->pool, ptr);
- }
- }
- }
- if (name)
+ l = fread(buf, 1, sizeof(buf), fp);
+ if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
{
- Solvable *s = pd->solvable = pool_id2solvable(pd->pool, repo_add_solvable(pd->repo));
- s->name = name;
- if (version)
- s->evr = version;
- if (arch)
- s->arch = arch;
- if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
- s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
+ pool_debug(pd->pool, SAT_ERROR, "%s: %s at line %u:%u\n", pd->filename, XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
+ pool_debug(pd->pool, SAT_ERROR, "skipping this product\n");
+ XML_ParserFree(parser);
+ return;
}
+ if (l == 0)
+ break;
}
+ XML_ParserFree(parser);
}
+void
+repo_add_code11_products(Repo *repo, const char *dirpath, int flags)
+{
+ Repodata *data;
+ struct parsedata pd;
+ struct stateswitch *sw;
+ DIR *dir;
+ int i;
-/*
- * parse dir looking for files ending in suffix
- */
+ if (!(flags & REPO_REUSE_REPODATA))
+ data = repo_add_repodata(repo, 0);
+ else
+ data = repo_last_repodata(repo);
-static void
-parse_dir(DIR *dir, const char *path, struct parsedata *pd, int code11)
-{
- struct dirent *entry;
- char *suffix = code11 ? ".prod" : "-release";
- int slen = code11 ? 5 : 8; /* strlen(".prod") : strlen("-release") */
- struct stat st;
+ memset(&pd, 0, sizeof(pd));
+ pd.repo = repo;
+ pd.pool = repo->pool;
+ pd.data = data;
+
+ pd.content = sat_malloc(256);
+ pd.acontent = 256;
- /* check for <productsdir>/baseproduct on code11 and remember its target inode */
- if (code11
- && stat(join2(path, "/", "baseproduct"), &st) == 0) /* follow symlink */
+ for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
{
- pd->baseproduct = st.st_ino;
+ if (!pd.swtab[sw->from])
+ pd.swtab[sw->from] = sw;
+ pd.sbtab[sw->to] = sw->from;
}
- else
- pd->baseproduct = 0;
- while ((entry = readdir(dir)))
+ dir = opendir(dirpath);
+ if (dir)
{
- int len;
- len = strlen(entry->d_name);
+ struct dirent *entry;
+ struct stat st;
+ char *fullpath;
- /* skip /etc/lsb-release, thats not a product per-se */
- if (!code11
- && strcmp(entry->d_name, "lsb-release") == 0)
- {
- continue;
- }
+ /* check for <productsdir>/baseproduct on code11 and remember its target inode */
+ if (stat(join2(dirpath, "/", "baseproduct"), &st) == 0) /* follow symlink */
+ pd.baseproduct = st.st_ino;
+ else
+ pd.baseproduct = 0;
- if (len > slen
- && strcmp(entry->d_name + len - slen, suffix) == 0)
+ while ((entry = readdir(dir)))
{
- char *fullpath = join2(path, "/", entry->d_name);
+ int len = strlen(entry->d_name);
+ if (len <= 5 || strcmp(entry->d_name + len - 5, ".prod") != 0)
+ continue;
+ fullpath = join2(dirpath, "/", entry->d_name);
FILE *fp = fopen(fullpath, "r");
if (!fp)
{
perror(fullpath);
- break;
+ continue;
}
- pd->filename = fullpath;
- pd->basename = entry->d_name;
- repo_add_product(pd, fp, code11);
+ pd.filename = fullpath;
+ pd.basename = entry->d_name;
+ add_code11_product(&pd, fp);
fclose(fp);
}
+ closedir(dir);
}
+ sat_free((void *)pd.tmplang);
+ sat_free(pd.content);
+ join_freemem();
+
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(data);
}
+/******************************************************************************************/
+
+
/*
* read all installed products
*
@@ -573,70 +513,44 @@ parse_dir(DIR *dir, const char *path, struct parsedata *pd, int code11)
void
repo_add_products(Repo *repo, const char *proddir, const char *root, int flags)
{
- const char *fullpath = proddir;
+ const char *fullpath;
DIR *dir;
- int i;
- struct parsedata pd;
- struct stateswitch *sw;
- Repodata *data;
-
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
- memset(&pd, 0, sizeof(pd));
- pd.repo = repo;
- pd.pool = repo->pool;
- pd.data = data;
-
- pd.content = sat_malloc(256);
- pd.acontent = 256;
-
- for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
+ dir = opendir(proddir);
+ if (dir)
{
- if (!pd.swtab[sw->from])
- pd.swtab[sw->from] = sw;
- pd.sbtab[sw->to] = sw->from;
+ /* assume code11 stype products */
+ closedir(dir);
+ repo_add_code11_products(repo, proddir, flags);
+ return;
}
+ /* code11 didn't work, try old zyppdb */
+ fullpath = root ? join2(root, "", "/var/lib/zypp/db/products") : "/var/lib/zypp/db/products";
dir = opendir(fullpath);
if (dir)
{
- parse_dir(dir, fullpath, &pd, 1); /* assume 'code11' products */
closedir(dir);
+ /* assume code10 style products */
+ repo_add_zyppdb_products(repo, fullpath, flags);
+ join_freemem();
+ return;
}
- else
+
+ /* code11 didn't work, try -release files parsing */
+ fullpath = root ? join2(root, "", "/etc") : "/etc";
+ dir = opendir(fullpath);
+ if (dir)
{
- fullpath = root ? join2(root, "", "/var/lib/zypp/db/products") : "/var/lib/zypp/db/products";
- dir = opendir(fullpath);
- if (dir)
- {
- repo_add_zyppdb_products(repo, data, fullpath, dir); /* assume 'code10' zypp-style products */
- closedir(dir);
- }
- else
- {
- fullpath = root ? join2(root, "", "/etc") : "/etc";
- dir = opendir(fullpath);
- if (dir)
- {
- parse_dir(dir, fullpath, &pd, 0); /* fall back to /etc/<xyz>-release parsing */
- closedir(dir);
- }
- else
- {
- perror(fullpath);
- }
- }
+ closedir(dir);
+ repo_add_releasefile_products(repo, fullpath, flags);
+ join_freemem();
+ return;
}
- sat_free((void *)pd.tmplang);
- sat_free(pd.content);
+ /* no luck. print an error message in case the root argument is wrong */
+ perror(fullpath);
join_freemem();
-
- if (!(flags & REPO_NO_INTERNALIZE))
- repodata_internalize(data);
}
/* EOF */
diff --git a/tools/repo_products.h b/tools/repo_products.h
index aa0c2d9..6f4ce85 100644
--- a/tools/repo_products.h
+++ b/tools/repo_products.h
@@ -1,8 +1,9 @@
/*
- * Copyright (c) 2007, Novell Inc.
+ * Copyright (c) 2007-2009, Novell Inc.
*
* This program is licensed under the BSD license, read LICENSE.BSD
* for further information
*/
+void repo_add_code11_products(Repo *repo, const char *dirpath, int flags);
void repo_add_products(Repo *repo, const char *proddir, const char *root, int flags);
diff --git a/tools/repo_releasefile_products.c b/tools/repo_releasefile_products.c
new file mode 100644
index 0000000..2413d20
--- /dev/null
+++ b/tools/repo_releasefile_products.c
@@ -0,0 +1,156 @@
+/*
+ * repo_products.c
+ *
+ * Parses all files below 'proddir'
+ * See http://en.opensuse.org/Product_Management/Code11
+ *
+ *
+ * Copyright (c) 2008, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "pool.h"
+#include "repo.h"
+#include "util.h"
+#define DISABLE_SPLIT
+#include "tools_util.h"
+#include "repo_releasefile_products.h"
+
+#define BUFF_SIZE 8192
+
+static void
+add_releasefile_product(Repo *repo, FILE *fp)
+{
+ Pool *pool = repo->pool;
+ char buf[BUFF_SIZE];
+ Id name = 0;
+ Id arch = 0;
+ Id version = 0;
+ int lnum = 0; /* line number */
+ char *ptr, *ptr1;
+
+ /* parse /etc/<xyz>-release file */
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ /* remove trailing \n */
+ int l = strlen(buf);
+ if (l && buf[l - 1] == '\n')
+ buf[--l] = 0;
+ ++lnum;
+
+ if (lnum == 1)
+ {
+ /* 1st line, <name> [(<arch>)] */
+ ptr = strchr(buf, '(');
+ if (ptr)
+ {
+ ptr1 = ptr - 1;
+ *ptr++ = 0;
+ }
+ else
+ ptr1 = buf + l - 1;
+
+ /* track back until non-blank, non-digit */
+ while (ptr1 > buf
+ && (*ptr1 == ' ' || isdigit(*ptr1) || *ptr1 == '.'))
+ --ptr1;
+ *(++ptr1) = 0;
+ name = str2id(pool, join2("product", ":", buf), 1);
+
+ if (ptr)
+ {
+ /* have arch */
+ char *ptr1 = strchr(ptr, ')');
+ if (ptr1)
+ {
+ *ptr1 = 0;
+ /* downcase arch */
+ ptr1 = ptr;
+ while (*ptr1)
+ {
+ if (isupper(*ptr1))
+ *ptr1 = tolower(*ptr1);
+ ++ptr1;
+ }
+ arch = str2id(pool, ptr, 1);
+ }
+ }
+ }
+ else if (strncmp(buf, "VERSION", 7) == 0)
+ {
+ ptr = strchr(buf + 7, '=');
+ if (ptr)
+ {
+ while (*++ptr == ' ')
+ ;
+ version = makeevr(pool, ptr);
+ }
+ }
+ }
+ if (name)
+ {
+ Solvable *s = pool_id2solvable(pool, repo_add_solvable(repo));
+ s->name = name;
+ if (version)
+ s->evr = version;
+ if (arch)
+ s->arch = arch;
+ if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
+ s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+ }
+}
+
+
+void
+repo_add_releasefile_products(Repo *repo, const char *dirpath, int flags)
+{
+ DIR *dir;
+ struct dirent *entry;
+ FILE *fp;
+ char *fullpath;
+
+ dir = opendir(dirpath);
+ if (!dir)
+ return;
+
+ while ((entry = readdir(dir)))
+ {
+ int len = strlen(entry->d_name);
+ if (len > 8 && !strcmp(entry->d_name + len - 8, "-release"))
+ {
+ /* skip /etc/lsb-release, thats not a product per-se */
+ if (strcmp(entry->d_name, "lsb-release") == 0)
+ continue;
+ fullpath = join2(dirpath, "/", entry->d_name);
+ if ((fp = fopen(fullpath, "r")) == 0)
+ {
+ perror(fullpath);
+ continue;
+ }
+ add_releasefile_product(repo, fp);
+ }
+ }
+ closedir(dir);
+ join_freemem();
+
+ if (!(flags & REPO_NO_INTERNALIZE))
+ {
+ if (!(flags & REPO_REUSE_REPODATA))
+ {
+ Repodata *data = repo_add_repodata(repo, 0);
+ repodata_internalize(data);
+ }
+ }
+}
+
diff --git a/tools/repo_releasefile_products.h b/tools/repo_releasefile_products.h
new file mode 100644
index 0000000..34311ac
--- /dev/null
+++ b/tools/repo_releasefile_products.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2007, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+void repo_add_releasefile_products(Repo *repo, const char *dirpath, int flags);
diff --git a/tools/repo_zyppdb.c b/tools/repo_zyppdb.c
index dc94281..13086d9 100644
--- a/tools/repo_zyppdb.c
+++ b/tools/repo_zyppdb.c
@@ -1,8 +1,8 @@
/*
* repo_zyppdb.c
*
- * Parses /var/lib/zypp/db/products/...
- * The are old (pre Code11) products. See bnc#429177
+ * Parses legacy /var/lib/zypp/db/products/... files.
+ * They are old (pre Code11) product descriptions. See bnc#429177
*
*
* Copyright (c) 2008, Novell Inc.
@@ -302,7 +302,7 @@ characterData(void *userData, const XML_Char *s, int len)
*/
static void
-repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp)
+add_zyppdb_product(struct parsedata *pd, FILE *fp)
{
char buf[BUFF_SIZE];
int l;
@@ -327,34 +327,6 @@ repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp)
}
-
-/*
- * parse dir for products
- */
-
-static void
-parse_dir(DIR *dir, const char *path, struct parsedata *pd, Repodata *repodata)
-{
- struct dirent *entry;
-
- while ((entry = readdir(dir)))
- {
- int len = strlen(entry->d_name);
- if (len < 3) /* skip '.' and '..' */
- continue;
- char *fullpath = join2(path, "/", entry->d_name);
- FILE *fp = fopen(fullpath, "r");
- if (!fp)
- {
- perror(fullpath);
- break;
- }
- repo_add_product(pd, repodata, fp);
- fclose(fp);
- }
-}
-
-
/*
* read all installed products
*
@@ -362,16 +334,26 @@ parse_dir(DIR *dir, const char *path, struct parsedata *pd, Repodata *repodata)
*/
void
-repo_add_zyppdb_products(Repo *repo, Repodata *repodata, const char *fullpath, DIR *dir)
+repo_add_zyppdb_products(Repo *repo, const char *dirpath, int flags)
{
int i;
struct parsedata pd;
struct stateswitch *sw;
+ struct dirent *entry;
+ char *fullpath;
+ DIR *dir;
+ FILE *fp;
+ Repodata *data;
+
+ if (!(flags & REPO_REUSE_REPODATA))
+ data = repo_add_repodata(repo, 0);
+ else
+ data = repo_last_repodata(repo);
memset(&pd, 0, sizeof(pd));
pd.repo = repo;
pd.pool = repo->pool;
- pd.data = repodata;
+ pd.data = data;
pd.content = malloc(256);
pd.acontent = 256;
@@ -383,11 +365,30 @@ repo_add_zyppdb_products(Repo *repo, Repodata *repodata, const char *fullpath, D
pd.sbtab[sw->to] = sw->from;
}
- parse_dir(dir, fullpath, &pd, repodata);
+ dir = opendir(dirpath);
+ if (dir)
+ {
+ while ((entry = readdir(dir)))
+ {
+ if (strlen(entry->d_name) < 3)
+ continue; /* skip '.' and '..' */
+ fullpath = join2(dirpath, "/", entry->d_name);
+ if ((fp = fopen(fullpath, "r")) == 0)
+ {
+ perror(fullpath);
+ continue;
+ }
+ add_zyppdb_product(&pd, fp);
+ fclose(fp);
+ }
+ }
+ closedir(dir);
sat_free((void *)pd.tmplang);
free(pd.content);
join_freemem();
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(data);
}
/* EOF */
diff --git a/tools/repo_zyppdb.h b/tools/repo_zyppdb.h
index 1e2ac1e..8c4a5da 100644
--- a/tools/repo_zyppdb.h
+++ b/tools/repo_zyppdb.h
@@ -5,4 +5,4 @@
* for further information
*/
-void repo_add_zyppdb_products(Repo *repo, Repodata *repodata, const char *fullpath, DIR *dir);
+void repo_add_zyppdb_products(Repo *repo, const char *dirpath, int flags);
diff --git a/tools/rpmdb2solv.c b/tools/rpmdb2solv.c
index f4bea47..515a8e7 100644
--- a/tools/rpmdb2solv.c
+++ b/tools/rpmdb2solv.c
@@ -159,7 +159,7 @@ main(int argc, char **argv)
strcpy(buf + rootlen, proddir);
}
}
- repo_add_products(repo, proddir, root, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE);
+ repo_add_products(repo, buf, root, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE);
if (buf != proddir)
sat_free(buf);
}
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org