X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=ext%2Frepo_rpmdb.c;h=95756c03aebb1316e94883b71120187797aa461b;hb=f458102388250c8a1cbbfa8f18d27baa204c696c;hp=f6c8f0d2d5028c6fb1f0f9b32a43239ac77f3df5;hpb=6dfec0d0a5a873b7745903de7c530be8faaeee6f;p=platform%2Fupstream%2Flibsolv.git diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index f6c8f0d..95756c0 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -47,11 +47,16 @@ #include "chksum.h" #include "repo_rpmdb.h" #include "repo_solv.h" +#ifdef ENABLE_COMPLEX_DEPS +#include "pool_parserpmrichdep.h" +#endif /* 3: added triggers */ /* 4: fixed triggers */ /* 5: fixed checksum copying */ -#define RPMDB_COOKIE_VERSION 5 +/* 6: add SOLVABLE_PREREQ_IGNOREINST support */ +/* 7: fix bug in ignoreinst logic */ +#define RPMDB_COOKIE_VERSION 7 #define TAG_NAME 1000 #define TAG_VERSION 1001 @@ -404,6 +409,14 @@ setutf8string(Repodata *repodata, Id handle, Id tag, const char *str) repodata_set_str(repodata, handle, tag, str); } +static int +ignq_sortcmp(const void *va, const void *vb, void *dp) +{ + int r = *(Id *)va - *(Id *)vb; + if (!r) + r = ((Id *)va)[1] - ((Id *)vb)[1]; + return r; +} /* * strong: 0: ignore strongness @@ -411,12 +424,12 @@ setutf8string(Repodata *repodata, Id handle, Id tag, const char *str) * 2: filter to weak */ static unsigned int -makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags) +makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags, Queue *ignq) { char **n, **v; unsigned int *f; int i, cc, nc, vc, fc; - int haspre, premask; + int haspre, premask, has_ign; unsigned int olddeps; Id *ida; int strong = 0; @@ -510,8 +523,11 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, cc += haspre; /* add slot for the prereq marker */ olddeps = repo_reserve_ids(repo, 0, cc); ida = repo->idarraydata + olddeps; + + has_ign = 0; for (i = 0; ; i++) { + Id id; if (i == nc) { if (haspre != 1) @@ -532,9 +548,21 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, if ((flags & RPM_ADD_NO_RPMLIBREQS) != 0) if (!strncmp(n[i], "rpmlib(", 7)) continue; +#ifdef ENABLE_COMPLEX_DEPS + if ((f[i] & (DEP_LESS|DEP_EQUAL|DEP_GREATER)) == 0 && n[i][0] == '(') + { + id = pool_parserpmrichdep(pool, n[i]); + if (id) + *ida++ = id; + else + cc--; + continue; + } +#endif + id = pool_str2id(pool, n[i], 1); if (f[i] & (DEP_LESS|DEP_GREATER|DEP_EQUAL)) { - Id name, evr; + Id evr; int fl = 0; if ((f[i] & DEP_LESS) != 0) fl |= REL_LT; @@ -542,21 +570,45 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, fl |= REL_EQ; if ((f[i] & DEP_GREATER) != 0) fl |= REL_GT; - name = pool_str2id(pool, n[i], 1); if (v[i][0] == '0' && v[i][1] == ':' && v[i][2]) evr = pool_str2id(pool, v[i] + 2, 1); else evr = pool_str2id(pool, v[i], 1); - *ida++ = pool_rel2id(pool, name, evr, fl, 1); + id = pool_rel2id(pool, id, evr, fl, 1); + } + *ida++ = id; + if (haspre == 2 && ignq) + { + int is_ign = (f[i] & DEP_PRE_IN) != 0 && (f[i] & DEP_PRE_UN) == 0 ? 1 : 0; + has_ign |= is_ign; + queue_push2(ignq, id, is_ign); } - else - *ida++ = pool_str2id(pool, n[i], 1); } *ida++ = 0; repo->idarraysize += cc + 1; solv_free(n); solv_free(v); solv_free(f); + if (ignq && ignq->count) + { + int j = 0; + if (has_ign && ignq->count == 2) + j = 1; + else if (has_ign) + { + Id id, lastid = 0; + + solv_sort(ignq->elements, ignq->count / 2, sizeof(Id) * 2, ignq_sortcmp, 0); + for (i = j = 0; i < ignq->count; i += 2) + { + id = ignq->elements[i]; + if (id != lastid && ignq->elements[i + 1] > 0) + ignq->elements[j++] = id; + lastid = id; + } + } + queue_truncate(ignq, j); + } return olddeps; } @@ -896,6 +948,8 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, char *name; char *evr; char *sourcerpm; + Queue ignq; + Id ignqbuf[64]; name = headstring(rpmhead, TAG_NAME); if (!name) @@ -922,20 +976,25 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, s->evr = pool_str2id(pool, evr, 1); s->vendor = pool_str2id(pool, headstring(rpmhead, TAG_VENDOR), 1); - s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0); + queue_init_buffer(&ignq, ignqbuf, sizeof(ignqbuf)/sizeof(*ignqbuf)); + + s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0, 0); if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); - s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, flags); - s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0); - s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0); + s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, flags, &ignq); + s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0, 0); + s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0, 0); + + s->recommends = makedeps(pool, repo, rpmhead, TAG_RECOMMENDNAME, TAG_RECOMMENDVERSION, TAG_RECOMMENDFLAGS, 0, 0); + s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0, 0); + s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0, 0); + s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0, 0); - s->recommends = makedeps(pool, repo, rpmhead, TAG_RECOMMENDNAME, TAG_RECOMMENDVERSION, TAG_RECOMMENDFLAGS, 0); - s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0); - s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0); - s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0); + repo_rewrite_suse_deps(s, 0); - s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0); - s->conflicts = repo_fix_conflicts(repo, s->conflicts); + if (data && ignq.count) + repodata_set_idarray(data, s - pool->solvables, SOLVABLE_PREREQ_IGNOREINST, &ignq); + queue_free(&ignq); if (data) { @@ -1001,24 +1060,11 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, repodata_set_sourcepkg(data, handle, sourcerpm); if ((flags & RPM_ADD_TRIGGERS) != 0) { - Id id, lastid; - unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0); - - lastid = 0; - for (; (id = repo->idarraydata[ida]) != 0; ida++) - { - /* we currently do not support rel ids in incore data, so - * strip off versioning information */ - while (ISRELDEP(id)) - { - Reldep *rd = GETRELDEP(pool, id); - id = rd->name; - } - if (id == lastid) - continue; + unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0, 0); + Id id, lastid = 0; + for (lastid = 0; (id = repo->idarraydata[ida]) != 0; ida++, lastid = id) + if (id != lastid) repodata_add_idarray(data, handle, SOLVABLE_TRIGGERS, id); - lastid = id; - } } if ((flags & RPM_ADD_NO_FILELIST) == 0) addfilelist(data, handle, rpmhead, flags); @@ -1045,6 +1091,7 @@ struct rpmdbstate { DB_ENV *dbenv; /* database environment */ DB *db; /* packages database */ int byteswapped; /* endianess of packages database */ + int is_ostree; /* read-only db that lives in /usr/share/rpm */ }; struct rpmdbentry { @@ -1135,6 +1182,10 @@ opendbenv(struct rpmdbstate *state) snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm", rootdir ? rootdir : ""); if (access(dbpath, W_OK) == -1) { + snprintf(dbpath, PATH_MAX, "%s/usr/share/rpm/Packages", rootdir ? rootdir : ""); + if (access(dbpath, R_OK) == 0) + state->is_ostree = 1; + snprintf(dbpath, PATH_MAX, "%s%s", rootdir ? rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0); } else @@ -1409,12 +1460,12 @@ freestate(struct rpmdbstate *state) /* close down */ if (!state) return; - if (state->rootdir) - solv_free(state->rootdir); if (state->db) state->db->close(state->db, 0); if (state->dbenv) closedbenv(state); + if (state->rootdir) + solv_free(state->rootdir); solv_free(state->rpmhead); } @@ -1448,7 +1499,7 @@ count_headers(struct rpmdbstate *state) DBT dbkey; DBT dbdata; - snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Name", state->rootdir ? state->rootdir : ""); + snprintf(dbpath, PATH_MAX, "%s%s/Name", state->rootdir ? state->rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); if (stat(dbpath, &statbuf)) return 0; memset(&dbkey, 0, sizeof(dbkey)); @@ -1600,12 +1651,12 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K cbdata->handle = repodata_new_handle(data); repodata_add_flexarray(data, cbdata->subhandle, keyname, cbdata->handle); break; - case REPOKEY_TYPE_MD5: - case REPOKEY_TYPE_SHA1: - case REPOKEY_TYPE_SHA256: - repodata_set_bin_checksum(data, handle, keyname, key->type, (const unsigned char *)kv->str); - break; default: + if (solv_chksum_len(key->type)) + { + repodata_set_bin_checksum(data, handle, keyname, key->type, (const unsigned char *)kv->str); + break; + } break; } return 0; @@ -1766,7 +1817,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) } /* XXX: should get ro lock of Packages database! */ - snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", state.rootdir ? state.rootdir : ""); + snprintf(dbpath, PATH_MAX, "%s%s/Packages", state.rootdir ? state.rootdir : "", state.is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); if (stat(dbpath, &packagesstat)) { pool_error(pool, -1, "%s: %s", dbpath, strerror(errno)); @@ -2389,7 +2440,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * if ((flags & RPM_ITERATE_FILELIST_WITHCOL) != 0) { co = headint32array(rpmhead, TAG_FILECOLORS, &cnt2); - if (!co || cnt != cnt2) + if (co && cnt != cnt2) { solv_free(co); solv_free(md); @@ -2467,8 +2518,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char * info.digest = md5; } } - if (co) - info.color = co[i]; + info.color = co ? co[i] : 0; (*cb)(cbdata, space, &info); } solv_free(space);