From 5a2baeeeef9fd4818340d8d4894325d1dd0f6e23 Mon Sep 17 00:00:00 2001 From: Klaus Kaempf Date: Fri, 15 Aug 2008 12:28:43 +0000 Subject: [PATCH] rpmdb2solv: - add usage() - call repo_add_products differently repo_products: - fallback to parsing /etc/*-release if not products.d directory found --- package/libsatsolver.changes | 6 ++ tools/repo_products.c | 173 ++++++++++++++++++++++++------------------- tools/repo_products.h | 2 +- tools/rpmdb2solv.c | 32 +++++--- 4 files changed, 125 insertions(+), 88 deletions(-) diff --git a/package/libsatsolver.changes b/package/libsatsolver.changes index 4b3b6c9..696d7d5 100644 --- a/package/libsatsolver.changes +++ b/package/libsatsolver.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Fri Aug 15 14:26:29 CEST 2008 - kkaempf@suse.de + +- Implement pre-code11 fallback for products, parse /etc/*-release + if /etc/products.d is not available. + +------------------------------------------------------------------- Wed Aug 13 18:06:41 CEST 2008 - kkaempf@suse.de - provide installtime for installed products. diff --git a/tools/repo_products.c b/tools/repo_products.c index 1c9757d..2312958 100644 --- a/tools/repo_products.c +++ b/tools/repo_products.c @@ -25,6 +25,7 @@ #include "pool.h" #include "repo.h" #include "util.h" +#include "tools_util.h" #include "repo_content.h" struct parsedata { @@ -36,60 +37,6 @@ struct parsedata { /* - * join up to three strings into one - */ - -static char * -join(struct parsedata *pd, const char *s1, const char *s2, const char *s3) -{ - int l = 1; - char *p; - - if (s1) - l += strlen(s1); - if (s2) - l += strlen(s2); - if (s3) - l += strlen(s3); - if (l > pd->tmpl) - { - pd->tmpl = l + 256; - pd->tmp = sat_realloc(pd->tmp, pd->tmpl); - } - p = pd->tmp; - if (s1) - { - strcpy(p, s1); - p += strlen(s1); - } - if (s2) - { - strcpy(p, s2); - p += strlen(s2); - } - if (s3) - { - strcpy(p, s3); - p += strlen(s3); - } - return pd->tmp; -} - - -/* - * create epoch:version-release as Id - */ - -static Id -makeevr(Pool *pool, char *s) -{ - if (!strncmp(s, "0:", 2) && s[2]) - s += 2; - return str2id(pool, s, 1); -} - - -/* * create localized tag */ @@ -124,7 +71,7 @@ enum sections */ static void -repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp) +repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp, int code11) { Repo *repo = pd->repo; Pool *pool = repo->pool; @@ -159,6 +106,42 @@ repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp) *--linep = 0; linep = line; + if (!code11) + { + /* non-code11, assume /etc/xyz-release + * just parse first line + * as " ()" + */ + char *sp[3]; + + if (split(linep, sp, 3) == 3) + { + if (!s) + { + struct stat st; + + s = pool_id2solvable(pool, repo_add_solvable(repo)); + repodata_extend(data, s - pool->solvables); + handle = repodata_get_handle(data, s - pool->solvables - repo->start); + if (!fstat(fileno(fp), &st)) + { + repodata_set_num(data, handle, SOLVABLE_INSTALLTIME, st.st_ctime); + } + else + { + perror("Can't stat()"); + } + } + s->name = str2id(pool, join2("product", ":", sp[0]), 1); + s->evr = makeevr(pool, sp[1]); + } + else + { + fprintf(stderr, "Can't recognize -release line '%s'\n", linep); + } + break; /* just parse single line */ + } + /* * Very trivial .ini parser */ @@ -249,7 +232,7 @@ repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp) } } if (!strcmp(key, "name")) - s->name = str2id(pool, join(pd, "product", ":", value), 1); + s->name = str2id(pool, join2("product", ":", value), 1); else if (!strcmp(key, "version")) s->evr = makeevr(pool, value); else if (!strcmp(key, "vendor")) @@ -300,44 +283,82 @@ repo_add_product(struct parsedata *pd, Repodata *data, FILE *fp) /* - * read all .prod files from directory - * parse each one as a product + * parse dir looking for files ending in suffix */ -void -repo_add_products(Repo *repo, Repodata *repodata, const char *proddir) +static void +parse_dir(DIR *dir, const char *path, struct parsedata *pd, Repodata *repodata, int code11) { - DIR *dir = opendir(proddir); struct dirent *entry; - struct parsedata pd; - - memset(&pd, 0, sizeof(pd)); - pd.repo = repo; - - if (!dir) - { - perror(proddir); - return; - } + char *suffix = code11 ? ".prod" : "-release"; + int slen = code11 ? 5 : 8; /* strlen(".prod") : strlen("-release") */ while ((entry = readdir(dir))) { - const char *dot; - dot = strrchr( entry->d_name, '.' ); - if (dot && strcmp(dot, ".prod") == 0) + int len; + len = strlen(entry->d_name); + + /* skip /etc/lsb-release, thats not a product per-se */ + if (!code11 + && strcmp(entry->d_name, "lsb-release") == 0) { - char *fullpath = join(&pd, proddir, "/", entry->d_name); + continue; + } + + if (len > slen + && strcmp(entry->d_name+len-slen, suffix) == 0) + { + char *fullpath = join2(path, "/", entry->d_name); FILE *fp = fopen(fullpath, "r"); if (!fp) { perror(fullpath); break; } - repo_add_product(&pd, repodata, fp); + repo_add_product(pd, repodata, fp, code11); fclose(fp); } } +} + + +/* + * read all installed products + * + * try proddir (reading all .prod files from this directory) first + * if not available, assume non-code11 layout and parse /etc/xyz-release + * + * parse each one as a product + */ + +void +repo_add_products(Repo *repo, Repodata *repodata, const char *proddir, const char *root) +{ + const char *fullpath = proddir; + int code11 = 1; + DIR *dir = opendir(fullpath); + struct parsedata pd; + + memset(&pd, 0, sizeof(pd)); + pd.repo = repo; + + if (!dir) + { + fullpath = root ? join2(root, "", "/etc") : "/etc"; + dir = opendir(fullpath); + code11 = 0; + } + if (!dir) + { + perror(fullpath); + } + else + { + parse_dir(dir, fullpath, &pd, repodata, code11); + } + if (pd.tmp) sat_free(pd.tmp); + join_freemem(); closedir(dir); } diff --git a/tools/repo_products.h b/tools/repo_products.h index 2c2114b..9739096 100644 --- a/tools/repo_products.h +++ b/tools/repo_products.h @@ -5,4 +5,4 @@ * for further information */ -void repo_add_products(Repo *repo, Repodata *repodata, const char *proddir); +void repo_add_products(Repo *repo, Repodata *repodata, const char *proddir, const char *root); diff --git a/tools/rpmdb2solv.c b/tools/rpmdb2solv.c index 29d6f7e..7cbc214 100644 --- a/tools/rpmdb2solv.c +++ b/tools/rpmdb2solv.c @@ -12,14 +12,6 @@ * a .solv file of 'installed' solvables. * Writes .solv to stdout * - * Usage: - * rpmdb2solv [-n] [-x] [-b ] [-p ] [-r ] - * -n : No packages, do not read rpmdb, useful to only parse products - * -x : use extrapool - * -b : Write .solv to .solv instead of stdout - * -p : Scan for .prod files, representing installed products - * -r : Prefix rpmdb path and with - * */ #include @@ -37,6 +29,21 @@ #include "repo_solv.h" #include "common_write.h" +static void +usage(int status) +{ + fprintf(stderr, "\nUsage:\n" + "rpmdb2solv [-n] [-x] [-b ] [-p ] [-r ]\n" + " -n : No packages, do not read rpmdb, useful to only parse products\n" + " -x : use extrapool\n" + " -b : Write .solv to .solv instead of stdout\n" + " -p : Scan for .prod files, representing installed products\n" + " -r : Prefix rpmdb path and with \n" + ); + exit(status); +} + + int main(int argc, char **argv) { @@ -56,9 +63,12 @@ main(int argc, char **argv) * parse arguments */ - while ((c = getopt (argc, argv, "nxb:r:p:")) >= 0) + while ((c = getopt (argc, argv, "hnxb:r:p:")) >= 0) switch (c) { + case 'h': + usage(0); + break; case 'r': root = optarg; break; @@ -75,7 +85,7 @@ main(int argc, char **argv) extrapool = 1; break; default: - exit(1); + usage(1); } /* @@ -134,7 +144,7 @@ main(int argc, char **argv) } } - repo_add_products(repo, repodata, proddir); + repo_add_products(repo, repodata, proddir, root); } if (repodata) -- 2.7.4