summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2020-11-27 14:44:40 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2020-11-27 14:44:40 +0900
commita997565567d8b30dc3a6f289e72324f8f2085b64 (patch)
tree9d2bddbd4f09ca9ce3cdd906c663e2d7f6412169
parent0de6a1fb83326a7af7c401e706a808da0c042a0f (diff)
downloadlibsolv-a997565567d8b30dc3a6f289e72324f8f2085b64.tar.gz
libsolv-a997565567d8b30dc3a6f289e72324f8f2085b64.tar.bz2
libsolv-a997565567d8b30dc3a6f289e72324f8f2085b64.zip
Imported Upstream version 0.7.10upstream/0.7.10
-rw-r--r--CMakeLists.txt5
-rw-r--r--NEWS5
-rw-r--r--VERSION.cmake2
-rw-r--r--ext/libsolvext.ver2
-rw-r--r--ext/repo_rpmdb.c29
-rw-r--r--ext/repo_rpmdb.h7
-rw-r--r--ext/repo_rpmdb_bdb.h62
-rw-r--r--ext/repo_rpmdb_librpm.h159
-rw-r--r--package/libsolv.changes7
9 files changed, 224 insertions, 54 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b39fd99..b7e5d7a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -238,6 +238,8 @@ IF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM)
ENDIF (NOT ENABLE_RPMDB_LIBRPM)
INCLUDE (CheckLibraryExists)
CHECK_LIBRARY_EXISTS(rpmio pgpDigGetParams "" HAVE_PGPDIGGETPARAMS)
+ CHECK_LIBRARY_EXISTS(rpm rpmdbNextIteratorHeaderBlob "" HAVE_RPMDBNEXTITERATORHEADERBLOB)
+ CHECK_LIBRARY_EXISTS(rpm rpmdbFStat "" HAVE_RPMDBFSTAT)
ENDIF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM)
IF (ENABLE_PUBKEY)
@@ -270,7 +272,8 @@ ENDIF (${CMAKE_MAJOR_VERSION} GREATER 2)
# should create config.h with #cmakedefine instead...
FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN
- HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS WITH_LIBXML2 WITHOUT_COOKIEOPEN)
+ HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS HAVE_RPMDBNEXTITERATORHEADERBLOB HAVE_RPMDBFSTAT
+ WITH_LIBXML2 WITHOUT_COOKIEOPEN)
IF(${VAR})
ADD_DEFINITIONS (-D${VAR}=1)
SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
diff --git a/NEWS b/NEWS
index ace34bd..ed9be3b 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@
This file contains the major changes between
libsolv versions:
+Version 0.7.10
+- new features:
+ * new rpm_stat_database() function
+ * new rpm_hash_database_state() function
+
Version 0.7.9
- new features:
* support conda constrains dependencies
diff --git a/VERSION.cmake b/VERSION.cmake
index 0ec5582..7707dfc 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "1")
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "7")
-SET(LIBSOLV_PATCH "9")
+SET(LIBSOLV_PATCH "10")
diff --git a/ext/libsolvext.ver b/ext/libsolvext.ver
index 02cf6d1..6423837 100644
--- a/ext/libsolvext.ver
+++ b/ext/libsolvext.ver
@@ -47,10 +47,12 @@ SOLV_1.0 {
rpm_byfp;
rpm_byrpmdbid;
rpm_byrpmh;
+ rpm_hash_database_state;
rpm_installedrpmdbids;
rpm_iterate_filelist;
rpm_query;
rpm_query_num;
+ rpm_stat_database;
rpm_state_create;
rpm_state_free;
solv_verify_sig;
diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
index e49188d..67aa97c 100644
--- a/ext/repo_rpmdb.c
+++ b/ext/repo_rpmdb.c
@@ -1329,8 +1329,6 @@ freestate(struct rpmdbstate *state)
{
/* close down */
#ifdef ENABLE_RPMDB
- if (state->pkgdbopened)
- closepkgdb(state);
if (state->dbenvopened)
closedbenv(state);
#endif
@@ -1624,11 +1622,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
repo_empty(ref, 1); /* get it out of the way */
if ((flags & RPMDB_REPORT_PROGRESS) != 0)
count = count_headers(&state);
- if (!openpkgdb(&state))
- {
- freestate(&state);
- return -1;
- }
if (pkgdb_cursor_open(&state))
{
freestate(&state);
@@ -2394,6 +2387,28 @@ rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queu
return nentries;
}
+int
+rpm_hash_database_state(void *rpmstate, Chksum *chk)
+{
+ struct rpmdbstate *state = rpmstate;
+ struct stat stb;
+ if (stat_database(state, &stb))
+ return -1;
+ if (state->dbenvopened != 1 && !opendbenv(state))
+ return -1;
+ solv_chksum_add(chk, &stb.st_mtime, sizeof(stb.st_mtime));
+ solv_chksum_add(chk, &stb.st_size, sizeof(stb.st_size));
+ solv_chksum_add(chk, &stb.st_ino, sizeof(stb.st_ino));
+ hash_name_index(rpmstate, chk);
+ return 0;
+}
+
+int
+rpm_stat_database(void *rpmstate, void *stb)
+{
+ return stat_database((struct rpmdbstate *)rpmstate, (struct stat *)stb) ? -1 : 0;
+}
+
void *
rpm_byrpmdbid(void *rpmstate, Id rpmdbid)
{
diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h
index 554d48a..22aab88 100644
--- a/ext/repo_rpmdb.h
+++ b/ext/repo_rpmdb.h
@@ -7,6 +7,7 @@
#include "queue.h"
#include "repo.h"
+#include "chksum.h"
struct headerToken_s;
@@ -39,7 +40,11 @@ extern void *rpm_state_create(Pool *pool, const char *rootdir);
extern void *rpm_state_free(void *rpmstate);
/* return all matching rpmdbids */
-extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq);
+extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char *match, Queue *rpmdbidq);
+/* stat the package database */
+extern int rpm_stat_database(void *rpmstate, void *stb);
+/* hash the state of the package database */
+extern int rpm_hash_database_state(void *rpmstate, Chksum *chk);
/* return handles to a rpm header */
extern void *rpm_byrpmdbid(void *rpmstate, Id rpmdbid);
diff --git a/ext/repo_rpmdb_bdb.h b/ext/repo_rpmdb_bdb.h
index 574e9a8..a8b8500 100644
--- a/ext/repo_rpmdb_bdb.h
+++ b/ext/repo_rpmdb_bdb.h
@@ -56,11 +56,31 @@ struct rpmdbstate {
};
+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_ostree(struct rpmdbstate *state)
+{
+ state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 &&
+ access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 ? 1 : -1;
+}
+
static int
stat_database_name(struct rpmdbstate *state, char *dbname, struct stat *statbuf, int seterror)
{
char *dbpath;
- dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname);
+ dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname);
if (stat(dbpath, statbuf))
{
if (seterror)
@@ -75,6 +95,8 @@ stat_database_name(struct rpmdbstate *state, char *dbname, struct stat *statbuf,
static int
stat_database(struct rpmdbstate *state, struct stat *statbuf)
{
+ if (!state->is_ostree)
+ detect_ostree(state);
return stat_database_name(state, "Packages", statbuf, 1);
}
@@ -160,6 +182,7 @@ opendbenv(struct rpmdbstate *state)
dbenv->set_thread_count(dbenv, 8);
#endif
dbpath = solv_dupjoin(rootdir, "/var/lib/rpm", 0);
+ state->is_ostree = -1;
if (access(dbpath, W_OK) == -1)
{
free(dbpath);
@@ -167,7 +190,7 @@ opendbenv(struct rpmdbstate *state)
if (access(dbpath, R_OK) == 0)
state->is_ostree = 1;
free(dbpath);
- dbpath = solv_dupjoin(rootdir, state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm", 0);
+ dbpath = solv_dupjoin(rootdir, state->is_ostree > 0 ? "/usr/share/rpm" : "/var/lib/rpm", 0);
r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0);
}
else
@@ -209,6 +232,12 @@ closedbenv(struct rpmdbstate *state)
uint32_t eflags = 0;
#endif
+ if (state->db)
+ {
+ state->db->close(state->db, 0);
+ state->db = 0;
+ }
+ state->pkgdbopened = 0;
if (!state->dbenv)
return;
#if defined(FEDORA) || defined(MAGEIA)
@@ -264,16 +293,6 @@ openpkgdb(struct rpmdbstate *state)
return 1;
}
-static void
-closepkgdb(struct rpmdbstate *state)
-{
- if (!state->db)
- return;
- state->db->close(state->db, 0);
- state->db = 0;
- state->pkgdbopened = 0;
-}
-
/* 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 *
@@ -464,6 +483,8 @@ count_headers(struct rpmdbstate *state)
static int
pkgdb_cursor_open(struct rpmdbstate *state)
{
+ if (state->pkgdbopened != 1 && !openpkgdb(state))
+ return -1;
if (state->db->cursor(state->db, NULL, &state->dbc, 0))
return pool_error(state->pool, -1, "db->cursor failed");
return 0;
@@ -497,3 +518,20 @@ pkgdb_cursor_getrpm(struct rpmdbstate *state)
return 0; /* no more entries */
}
+static int
+hash_name_index(struct rpmdbstate *state, Chksum *chk)
+{
+ char *dbpath;
+ int fd, l;
+ char buf[4096];
+
+ dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", "Name");
+ if ((fd = open(dbpath, O_RDONLY)) < 0)
+ return -1;
+ while ((l = read(fd, buf, sizeof(buf))) > 0)
+ solv_chksum_add(chk, buf, l);
+ close(fd);
+ return 0;
+}
+
+
diff --git a/ext/repo_rpmdb_librpm.h b/ext/repo_rpmdb_librpm.h
index 6fdcfb0..b50a4b5 100644
--- a/ext/repo_rpmdb_librpm.h
+++ b/ext/repo_rpmdb_librpm.h
@@ -23,13 +23,32 @@ struct rpmdbstate {
int rpmheadsize;
int dbenvopened; /* database environment opened */
- int pkgdbopened; /* package database openend */
int is_ostree; /* read-only db that lives in /usr/share/rpm */
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_ostree(struct rpmdbstate *state)
+{
+ state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 &&
+ access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 ? 1 : -1;
+}
+
static int
stat_database(struct rpmdbstate *state, struct stat *statbuf)
{
@@ -43,9 +62,15 @@ stat_database(struct rpmdbstate *state, struct stat *statbuf)
};
int i;
+#ifdef HAVE_RPMDBFSTAT
+ if (state->dbenvopened == 1)
+ return rpmdbFStat(rpmtsGetRdb(state->ts), statbuf);
+#endif
+ if (!state->is_ostree)
+ detect_ostree(state);
for (i = 0; ; i++)
{
- char *dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname[i]);
+ char *dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? "/usr/share/rpm/" : "/var/lib/rpm/", dbname[i]);
if (!stat(dbpath, statbuf))
{
free(dbpath);
@@ -53,8 +78,10 @@ stat_database(struct rpmdbstate *state, struct stat *statbuf)
}
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);
@@ -68,16 +95,8 @@ 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");
- }
+ detect_ostree(state);
+ dbpath = solv_dupjoin("_dbpath ", rootdir, state->is_ostree > 0 ? "/usr/share/rpm" : "/var/lib/rpm");
rpmDefineMacro(NULL, dbpath, 0);
solv_free(dbpath);
ts = rpmtsCreate();
@@ -98,7 +117,6 @@ opendbenv(struct rpmdbstate *state)
rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES | _RPMVSF_NOHEADER);
state->ts = ts;
state->dbenvopened = 1;
- state->pkgdbopened = 1;
return 1;
}
@@ -108,22 +126,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 *
@@ -139,7 +144,6 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma
int nentries = 0;
rpmdbIndexIterator ii;
- int i;
*nentriesp = 0;
if (namedatap)
@@ -154,6 +158,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)
@@ -169,7 +174,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);
@@ -187,17 +193,67 @@ getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *ma
return entries;
}
+#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM)
+static int
+rpm_byrpmhdrblob(struct rpmdbstate *state, const unsigned char *data, unsigned int size)
+{
+ unsigned int dsize, cnt, len;
+ RpmHead *rpmhead;
+ if (size < 8)
+ return pool_error(state->pool, 0, "corrupt rpm database (size)");
+ cnt = getu32(data);
+ dsize = getu32(data + 4);
+ if (cnt >= MAX_HDR_CNT || dsize >= MAX_HDR_DSIZE)
+ return pool_error(state->pool, 0, "corrupt rpm database (cnt/dcnt)");
+ if (8 + cnt * 16 + dsize > size)
+ return pool_error(state->pool, 0, "corrupt rpm database (data size)");
+ len = 16 * cnt + dsize;
+ if (len + 1 > state->rpmheadsize)
+ {
+ state->rpmheadsize = len + 128;
+ state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + state->rpmheadsize);
+ }
+ rpmhead = state->rpmhead;
+ memcpy(rpmhead->data, data + 8, len);
+ rpmhead->data[len] = 0;
+ rpmhead->cnt = cnt;
+ rpmhead->dcnt = dsize;
+ rpmhead->dp = rpmhead->data + cnt * 16;
+ return 1;
+}
+#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 (!rpm_byrpmhdrblob(state, uh, uhlen))
+ {
+ rpmdbFreeIterator(mi);
+ return -1;
+ }
+#else
h = rpmdbNextIterator(mi);
if (!h)
{
@@ -209,8 +265,9 @@ getrpm_dbid(struct rpmdbstate *state, Id rpmdbid)
rpmdbFreeIterator(mi);
return -1;
}
+#endif
mi = rpmdbFreeIterator(mi);
- return 1;
+ return rpmdbid;
}
static int
@@ -221,7 +278,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;
@@ -230,7 +287,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;
}
@@ -244,6 +301,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 (!rpm_byrpmhdrblob(state, uh, uhlen))
+ continue;
+ return dbid;
+ }
+#else
Header h;
while ((h = rpmdbNextIterator(state->mi)))
{
@@ -252,6 +320,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;
}
diff --git a/package/libsolv.changes b/package/libsolv.changes
index 9ae1511..b638864 100644
--- a/package/libsolv.changes
+++ b/package/libsolv.changes
@@ -1,4 +1,11 @@
-------------------------------------------------------------------
+Tue Dec 10 14:18:36 CET 2019 - mls@suse.de
+
+- added two new function to make libzypp independent of the rpm
+ database format
+- bump version to 0.7.10
+
+-------------------------------------------------------------------
Thu Nov 21 16:34:52 CET 2019 - mls@suse.de
- support conda constrains dependencies