From 2ccfed450e6acfbcea6ebd7b3688e145e68718a2 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Mon, 3 Mar 2008 19:56:59 +0000 Subject: [PATCH] - fix mem leaks - do not close fd 0 by mistake - add repodata_lookup_void - add solvable_lookup_void - add solvable_get_location --- src/CMakeLists.txt | 2 +- src/pool.c | 55 +------------ src/pool.h | 6 ++ src/repo_solv.c | 3 +- src/repodata.c | 20 ++++- src/repodata.h | 1 + src/solvable.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 261 insertions(+), 57 deletions(-) create mode 100644 src/solvable.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db14219..545a8d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ SET(libsatsolver_SRCS bitmap.c poolarch.c poolvendor.c poolid.c strpool.c dirpool.c -solver.c repo_solv.c repo_helix.c evr.c pool.c queue.c repo.c repodata.c util.c policy.c fastlz.c) +solver.c repo_solv.c repo_helix.c evr.c pool.c queue.c repo.c repodata.c util.c policy.c fastlz.c solvable.c) ADD_LIBRARY(satsolver STATIC ${libsatsolver_SRCS}) diff --git a/src/pool.c b/src/pool.c index a7298b2..d5cac2b 100644 --- a/src/pool.c +++ b/src/pool.c @@ -163,6 +163,7 @@ pool_free(Pool *pool) for (i = 0; i < pool->nlanguages; i++) free((char *)pool->languages[i]); sat_free(pool->languages); + sat_free(pool->languagecache); sat_free(pool); } @@ -932,58 +933,4 @@ pool_set_languages(Pool *pool, const char **languages, int nlanguages) pool->languages[i] = strdup(languages[i]); } -const char * -solvable_lookup_str_lang(Solvable *s, Id keyname) -{ - Pool *pool; - int i, cols; - const char *str; - Id *row; - - if (!s->repo) - return repo_lookup_str(s, keyname); - pool = s->repo->pool; - if (!pool->nlanguages) - return repo_lookup_str(s, keyname); - cols = pool->nlanguages + 1; - if (!pool->languagecache) - { - pool->languagecache = sat_calloc(cols * ID_NUM_INTERNAL, sizeof(Id)); - pool->languagecacheother = 0; - } - if (keyname >= ID_NUM_INTERNAL) - { - row = pool->languagecache + ID_NUM_INTERNAL * cols; - for (i = 0; i < pool->languagecacheother; i++, row += cols) - if (*row == keyname) - break; - if (i >= pool->languagecacheother) - { - pool->languagecache = sat_realloc2(pool->languagecache, pool->languagecacheother + 1, cols * sizeof(Id)); - pool->languagecacheother++; - row = pool->languagecache + cols * (ID_NUM_INTERNAL + pool->languagecacheother++); - } - } - else - row = pool->languagecache + keyname * cols; - row++; /* skip keyname */ - for (i = 0; i < pool->nlanguages; i++, row++) - { - if (!*row) - { - char *p; - const char *kn; - - kn = id2str(pool, keyname); - p = sat_malloc(strlen(kn) + strlen(pool->languages[i]) + 2); - sprintf(p, "%s:%s", kn, pool->languages[i]); - *row = str2id(pool, p, 1); - } - str = repo_lookup_str(s, *row); - if (str) - return str; - } - return repo_lookup_str(s, keyname); -} - // EOF diff --git a/src/pool.h b/src/pool.h index be6e76a..ecc3915 100644 --- a/src/pool.h +++ b/src/pool.h @@ -240,7 +240,13 @@ static inline Solvable *pool_id2solvable(Pool *pool, Id p) extern const char *solvable2str(Pool *pool, Solvable *s); void pool_set_languages(Pool *pool, const char **languages, int nlanguages); + +unsigned int solvable_lookup_num(Solvable *s, Id keyname, unsigned int notfound); +const char *solvable_lookup_str(Solvable *s, Id keyname); const char *solvable_lookup_str_lang(Solvable *s, Id keyname); +int solvable_lookup_bool(Solvable *s, Id keyname); +char * solvable_get_location(Solvable *s, unsigned int *medianrp); + /** diff --git a/src/repo_solv.c b/src/repo_solv.c index 2723465..361097b 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -476,6 +476,7 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned data = repo->repodata + repo->nrepodata++; memset(data, 0, sizeof(*data)); data->repo = repo; + data->pagefd = -1; data->state = REPODATA_STUB; data->loadcallback = repodata_load_solv; @@ -526,7 +527,7 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned else { char buf[1024]; - unsigned len = sizeof (buf); + unsigned len = sizeof(buf); char *filename = buf; read_str(maindata, &filename, &len); data->location = strdup(filename); diff --git a/src/repodata.c b/src/repodata.c index 558a083..333d6bb 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -65,6 +65,8 @@ repodata_free(Repodata *data) sat_free(data->attrdata); sat_free(data->attriddata); + sat_free(data->location); + if (data->pagefd != -1) close(data->pagefd); } @@ -373,7 +375,7 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid) } int -repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value) +repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned int *value) { Id schema; Repokey *key; @@ -408,6 +410,22 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value) return 0; } +int +repodata_lookup_void(Repodata *data, Id entry, Id keyid) +{ + Id schema; + Id *keyp; + unsigned char *dp; + if (!maybe_load_repodata(data, &keyid)) + return 0; + dp = data->incoredata + data->incoreoffset[entry]; + dp = data_read_id(dp, &schema); + for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++) + if (!*keyp) + return 0; + return 1; +} + void repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata) { diff --git a/src/repodata.h b/src/repodata.h index cb81793..8bf79e6 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -118,6 +118,7 @@ const char *repodata_lookup_str(Repodata *data, Id entry, Id keyid); * lookup integer type attribute */ int repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value); +int repodata_lookup_void(Repodata *data, Id entry, Id keyid); void repodata_init(Repodata *data, struct _Repo *repo, int localpool); void repodata_extend(Repodata *data, Id p); diff --git a/src/solvable.c b/src/solvable.c new file mode 100644 index 0000000..77fb427 --- /dev/null +++ b/src/solvable.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2008, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * solvable.c + * + * set/retrieve data from solvables + */ + +#include +#include +#include +#include +#include + +#include "pool.h" +#include "repo.h" +#include "util.h" + +const char * +solvable_lookup_str(Solvable *s, Id keyname) +{ + Repo *repo = s->repo; + Pool *pool; + Repodata *data; + int i, j, n; + const char *str; + + if (!repo) + return 0; + pool = repo->pool; + switch(keyname) + { + case SOLVABLE_NAME: + return id2str(pool, s->name); + case SOLVABLE_ARCH: + return id2str(pool, s->arch); + case SOLVABLE_EVR: + return id2str(pool, s->evr); + case SOLVABLE_VENDOR: + return id2str(pool, s->vendor); + } + n = s - pool->solvables; + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + { + if (n < data->start || n >= data->end) + continue; + for (j = 1; j < data->nkeys; j++) + { + if (data->keys[j].name == keyname && (data->keys[j].type == REPOKEY_TYPE_ID || data->keys[j].type == REPOKEY_TYPE_CONSTANTID || data->keys[j].type == REPOKEY_TYPE_STR)) + { + str = repodata_lookup_str(data, n - data->start, j); + if (str) + return str; + } + } + } + return 0; +} + +const char * +solvable_lookup_str_lang(Solvable *s, Id keyname) +{ + Pool *pool; + int i, cols; + const char *str; + Id *row; + + if (!s->repo) + return repo_lookup_str(s, keyname); + pool = s->repo->pool; + if (!pool->nlanguages) + return repo_lookup_str(s, keyname); + cols = pool->nlanguages + 1; + if (!pool->languagecache) + { + pool->languagecache = sat_calloc(cols * ID_NUM_INTERNAL, sizeof(Id)); + pool->languagecacheother = 0; + } + if (keyname >= ID_NUM_INTERNAL) + { + row = pool->languagecache + ID_NUM_INTERNAL * cols; + for (i = 0; i < pool->languagecacheother; i++, row += cols) + if (*row == keyname) + break; + if (i >= pool->languagecacheother) + { + pool->languagecache = sat_realloc2(pool->languagecache, pool->languagecacheother + 1, cols * sizeof(Id)); + pool->languagecacheother++; + row = pool->languagecache + cols * (ID_NUM_INTERNAL + pool->languagecacheother++); + } + } + else + row = pool->languagecache + keyname * cols; + row++; /* skip keyname */ + for (i = 0; i < pool->nlanguages; i++, row++) + { + if (!*row) + { + char *p; + const char *kn; + + kn = id2str(pool, keyname); + p = sat_malloc(strlen(kn) + strlen(pool->languages[i]) + 2); + sprintf(p, "%s:%s", kn, pool->languages[i]); + *row = str2id(pool, p, 1); + sat_free(p); + } + str = repo_lookup_str(s, *row); + if (str) + return str; + } + return repo_lookup_str(s, keyname); +} + +unsigned int +solvable_lookup_num(Solvable *s, Id keyname, unsigned int notfound) +{ + Repo *repo = s->repo; + Pool *pool; + Repodata *data; + int i, j, n; + + if (!repo) + return 0; + pool = repo->pool; + if (keyname == RPM_RPMDBID) + { + if (repo->rpmdbid) + return repo->rpmdbid[(s - pool->solvables) - repo->start]; + return notfound; + } + n = s - pool->solvables; + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + { + if (n < data->start || n >= data->end) + continue; + for (j = 1; j < data->nkeys; j++) + { + if (data->keys[j].name == keyname + && (data->keys[j].type == REPOKEY_TYPE_U32 + || data->keys[j].type == REPOKEY_TYPE_NUM + || data->keys[j].type == REPOKEY_TYPE_CONSTANT)) + { + unsigned int value; + if (repodata_lookup_num(data, n - data->start, j, &value)) + return value; + } + } + } + return notfound; +} + +int +solvable_lookup_void(Solvable *s, Id keyname) +{ + Repo *repo = s->repo; + Pool *pool; + Repodata *data; + int i, j, n; + + if (!repo) + return 0; + pool = repo->pool; + n = s - pool->solvables; + for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) + { + if (n < data->start || n >= data->end) + continue; + for (j = 1; j < data->nkeys; j++) + { + if (data->keys[j].name == keyname + && (data->keys[j].type == REPOKEY_TYPE_VOID)) + { + if (repodata_lookup_void(data, n - data->start, j)) + return 1; + } + } + } + return 0; +} + +char * +solvable_get_location(Solvable *s, unsigned int *medianrp) +{ + Pool *pool; + int l = 0; + char *loc; + const char *mediadir, *mediafile; + + *medianrp = 0; + if (!s->repo) + return 0; + pool = s->repo->pool; + *medianrp = solvable_lookup_num(s, SOLVABLE_MEDIANR, 1); + if (solvable_lookup_void(s, SOLVABLE_MEDIADIR)) + mediadir = id2str(pool, s->arch); + else + mediadir = solvable_lookup_str(s, SOLVABLE_MEDIADIR); + if (mediadir) + l = strlen(mediadir) + 1; + if (solvable_lookup_void(s, SOLVABLE_MEDIAFILE)) + { + const char *name, *evr, *arch; + name = id2str(pool, s->name); + evr = id2str(pool, s->evr); + arch = id2str(pool, s->arch); + /* name-evr.arch.rpm */ + loc = sat_malloc(l + strlen(name) + strlen(evr) + strlen(arch) + 7); + if (mediadir) + sprintf(loc, "%s/%s-%s.%s.rpm", mediadir, name, evr, arch); + else + sprintf(loc, "%s-%s.%s.rpm", name, evr, arch); + } + else + { + mediafile = solvable_lookup_str(s, SOLVABLE_MEDIAFILE); + if (!mediafile) + return 0; + loc = sat_malloc(l + strlen(mediafile) + 1); + if (mediadir) + sprintf(loc, "%s/%s", mediadir, mediafile); + else + strcpy(loc, mediafile); + } + return loc; +} -- 2.7.4