X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=ext%2Frepo_rpmdb_librpm.h;h=34e66989d0f28a37c66ebe67824f8ac857c46c06;hb=6a68988035ea989055076d81b7ab53c7015c8c32;hp=79983d3a640d63b2dbe826c70799093c130891ad;hpb=e679b515eddb3dd340fb25620de0160211f40fdc;p=platform%2Fupstream%2Flibsolv.git diff --git a/ext/repo_rpmdb_librpm.h b/ext/repo_rpmdb_librpm.h index 79983d3..34e6698 100644 --- a/ext/repo_rpmdb_librpm.h +++ b/ext/repo_rpmdb_librpm.h @@ -20,48 +20,85 @@ struct rpmdbstate { char *rootdir; RpmHead *rpmhead; /* header storage space */ - int rpmheadsize; + unsigned int rpmheadsize; int dbenvopened; /* database environment opened */ - int pkgdbopened; /* package database openend */ - int is_ostree; /* read-only db that lives in /usr/share/rpm */ + const char *dbpath; /* path to the database */ rpmts ts; rpmdbMatchIterator mi; /* iterator over packages database */ }; +static inline int +access_rootdir(struct rpmdbstate *state, const char *dir, int mode) +{ + if (state->rootdir) + { + char *path = solv_dupjoin(state->rootdir, dir, 0); + int r = access(path, mode); + free(path); + return r; + } + return access(dir, mode); +} + +static void +detect_dbpath(struct rpmdbstate *state) +{ + state->dbpath = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 + && access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 + ? "/usr/share/rpm" : "/var/lib/rpm"; +} + static int -stat_database(struct rpmdbstate *state, char *dbname, struct stat *statbuf, int seterror) +stat_database(struct rpmdbstate *state, struct stat *statbuf) { - char *dbpath; - dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname); - if (stat(dbpath, statbuf)) + static const char *dbname[] = { + "/Packages", + "/Packages.db", + "/rpmdb.sqlite", + "/data.mdb", + "/Packages", /* for error reporting */ + 0, + }; + int i; + +#ifdef HAVE_RPMDBFSTAT + if (state->dbenvopened == 1) + return rpmdbFStat(rpmtsGetRdb(state->ts), statbuf); +#endif + if (!state->dbpath) + detect_dbpath(state); + for (i = 0; ; i++) { - if (seterror) - pool_error(state->pool, -1, "%s: %s", dbpath, strerror(errno)); - free(dbpath); - return -1; + char *dbpath = solv_dupjoin(state->rootdir, state->dbpath, dbname[i]); + if (!stat(dbpath, statbuf)) + { + free(dbpath); + return 0; + } + if (errno != ENOENT || !dbname[i + 1]) + { + int saved_errno = errno; + pool_error(state->pool, -1, "%s: %s", dbpath, strerror(errno)); + solv_free(dbpath); + errno = saved_errno; + return -1; + } + solv_free(dbpath); } - free(dbpath); return 0; } static int opendbenv(struct rpmdbstate *state) { - const char *rootdir = state->rootdir; rpmts ts; char *dbpath; - dbpath = solv_dupjoin("_dbpath ", rootdir, "/var/lib/rpm"); - if (access(dbpath + 8, W_OK) == -1) - { - free(dbpath); - dbpath = solv_dupjoin(rootdir, "/usr/share/rpm/Packages", 0); - if (access(dbpath, R_OK) == 0) - state->is_ostree = 1; - free(dbpath); - dbpath = solv_dupjoin("_dbpath ", rootdir, state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); - } + + if (!state->dbpath) + detect_dbpath(state); + dbpath = solv_dupjoin("_dbpath ", state->rootdir, state->dbpath); rpmDefineMacro(NULL, dbpath, 0); solv_free(dbpath); ts = rpmtsCreate(); @@ -82,7 +119,6 @@ opendbenv(struct rpmdbstate *state) rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES | _RPMVSF_NOHEADER); state->ts = ts; state->dbenvopened = 1; - state->pkgdbopened = 1; return 1; } @@ -92,22 +128,9 @@ closedbenv(struct rpmdbstate *state) if (state->ts) rpmtsFree(state->ts); state->ts = 0; - state->pkgdbopened = 0; state->dbenvopened = 0; } -static int -openpkgdb(struct rpmdbstate *state) -{ - /* already done in opendbenv */ - return 1; -} - -static void -closepkgdb(struct rpmdbstate *state) -{ -} - /* get the rpmdbids of all installed packages from the Name index database. * This is much faster then querying the big Packages database */ static struct rpmdbentry * @@ -123,7 +146,6 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma int nentries = 0; rpmdbIndexIterator ii; - int i; *nentriesp = 0; if (namedatap) @@ -138,6 +160,7 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma while (rpmdbIndexIteratorNext(ii, &key, &keylen) == 0) { + unsigned int i, npkgs; if (match) { if (keylen != matchl || memcmp(key, match, keylen) != 0) @@ -153,7 +176,8 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma namedata[namedatal + keylen] = 0; namedatal += keylen + 1; } - for (i = 0; i < rpmdbIndexIteratorNumPkgs(ii); i++) + npkgs = rpmdbIndexIteratorNumPkgs(ii); + for (i = 0; i < npkgs; i++) { entries = solv_extend(entries, nentries, 1, sizeof(*entries), ENTRIES_BLOCK); entries[nentries].rpmdbid = rpmdbIndexIteratorPkgOffset(ii, i); @@ -171,17 +195,41 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma return entries; } +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) +static int headfromhdrblob(struct rpmdbstate *state, const unsigned char *data, unsigned int size); +#endif + /* retrive header by rpmdbid, returns 0 if not found, -1 on error */ static int getrpm_dbid(struct rpmdbstate *state, Id rpmdbid) { +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) + const unsigned char *uh; + unsigned int uhlen; +#else Header h; +#endif rpmdbMatchIterator mi; unsigned int offset = rpmdbid; + if (rpmdbid <= 0) + return pool_error(state->pool, -1, "illegal rpmdbid %d", rpmdbid); if (state->dbenvopened != 1 && !opendbenv(state)) return -1; - mi = rpmtsInitIterator(state->ts, RPMDBI_PACKAGES, &offset, sizeof(offset)); + mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_PACKAGES, &offset, sizeof(offset)); +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) + uh = rpmdbNextIteratorHeaderBlob(mi, &uhlen); + if (!uh) + { + rpmdbFreeIterator(mi); + return 0; + } + if (!headfromhdrblob(state, uh, uhlen)) + { + rpmdbFreeIterator(mi); + return -1; + } +#else h = rpmdbNextIterator(mi); if (!h) { @@ -193,8 +241,9 @@ getrpm_dbid(struct rpmdbstate *state, Id rpmdbid) rpmdbFreeIterator(mi); return -1; } +#endif mi = rpmdbFreeIterator(mi); - return 1; + return rpmdbid; } static int @@ -205,7 +254,7 @@ count_headers(struct rpmdbstate *state) if (state->dbenvopened != 1 && !opendbenv(state)) return 0; - mi = rpmtsInitIterator(state->ts, RPMDBI_NAME, NULL, 0); + mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_NAME, NULL, 0); count = rpmdbGetIteratorCount(mi); rpmdbFreeIterator(mi); return count; @@ -214,7 +263,7 @@ count_headers(struct rpmdbstate *state) static int pkgdb_cursor_open(struct rpmdbstate *state) { - state->mi = rpmtsInitIterator(state->ts, RPMDBI_PACKAGES, NULL, 0); + state->mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_PACKAGES, NULL, 0); return 0; } @@ -228,6 +277,17 @@ pkgdb_cursor_close(struct rpmdbstate *state) static Id pkgdb_cursor_getrpm(struct rpmdbstate *state) { +#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM) + const unsigned char *uh; + unsigned int uhlen; + while ((uh = rpmdbNextIteratorHeaderBlob(state->mi, &uhlen)) != 0) + { + Id dbid = rpmdbGetIteratorOffset(state->mi); + if (!headfromhdrblob(state, uh, uhlen)) + continue; + return dbid; + } +#else Header h; while ((h = rpmdbNextIterator(state->mi))) { @@ -236,6 +296,33 @@ pkgdb_cursor_getrpm(struct rpmdbstate *state) continue; return dbid; } +#endif + return 0; +} + +static int +hash_name_index(struct rpmdbstate *state, Chksum *chk) +{ + rpmdbIndexIterator ii; + const void *key; + size_t keylen; + + if (state->dbenvopened != 1 && !opendbenv(state)) + return -1; + ii = rpmdbIndexIteratorInit(rpmtsGetRdb(state->ts), RPMDBI_NAME); + if (!ii) + return -1; + while (rpmdbIndexIteratorNext(ii, &key, &keylen) == 0) + { + unsigned int i, npkgs = rpmdbIndexIteratorNumPkgs(ii); + solv_chksum_add(chk, key, (int)keylen); + for (i = 0; i < npkgs; i++) + { + unsigned int offset = rpmdbIndexIteratorPkgOffset(ii, i); + solv_chksum_add(chk, &offset, sizeof(offset)); + } + } + rpmdbIndexIteratorFree(ii); return 0; }