From 9993670bc496a11b86f74c26a6887eab0c9e5321 Mon Sep 17 00:00:00 2001 From: Renbo Date: Thu, 18 Jul 2024 14:30:10 +0800 Subject: [PATCH 01/15] update to rpm-4.14.3-31.src.rpm Signed-off-by: Renbo --- 0001-debugedit-add-loongarch-support.patch | 28 - ...te-help-description-of-whatconflicts.patch | 41 - 0001-support-sqlite-backend-rpmdb.patch | 2094 ----------------- 1000-rpm-anolis-support-loongarch.patch | 117 - 2002-rpm-anolis-support-sw_64.patch | 53 - 2004-rpm-anolis-support-sw_64.patch | 53 - ...in-db3_dbiOpen-when-db_create-failed.patch | 26 - ...ompile-compatibility-with-newer-pyth.patch | 46 + ...y-of-debugedit-tool-on-sw_64-platfor.patch | 42 - ...ty-between-sw-and-other-architecture.patch | 31 - rpm-4.14.3-sw.patch | 119 - rpm.spec | 102 +- 12 files changed, 58 insertions(+), 2694 deletions(-) delete mode 100644 0001-debugedit-add-loongarch-support.patch delete mode 100644 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch delete mode 100644 0001-support-sqlite-backend-rpmdb.patch delete mode 100644 1000-rpm-anolis-support-loongarch.patch delete mode 100644 2002-rpm-anolis-support-sw_64.patch delete mode 100644 2004-rpm-anolis-support-sw_64.patch delete mode 100644 3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch create mode 100644 brp-python-bytecompile-compatibility-with-newer-pyth.patch delete mode 100644 rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch delete mode 100644 rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch delete mode 100644 rpm-4.14.3-sw.patch diff --git a/0001-debugedit-add-loongarch-support.patch b/0001-debugedit-add-loongarch-support.patch deleted file mode 100644 index f75846c..0000000 --- a/0001-debugedit-add-loongarch-support.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f5449c5534d9bfb526541d49b3caec4f76e12d1d Mon Sep 17 00:00:00 2001 -From: Huang Yang -Date: Mon, 20 Feb 2023 20:03:41 -0500 -Subject: [PATCH] debugedit add loongarch support - ---- - tools/debugedit.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/tools/debugedit.c b/tools/debugedit.c -index 4ec431f..fb0325b 100644 ---- a/tools/debugedit.c -+++ b/tools/debugedit.c -@@ -597,6 +597,12 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype) - goto fail; - break; - #endif -+#if defined(EM_LOONGARCH) -+ case EM_LOONGARCH: -+ if ((rtype != R_LARCH_32) && (rtype != R_LARCH_64)) -+ goto fail; -+ break; -+#endif - default: - fail: - error (1, 0, "%s: Unhandled relocation %d in %s section", --- -2.27.0 diff --git a/0001-fix-a-copy-paste-help-description-of-whatconflicts.patch b/0001-fix-a-copy-paste-help-description-of-whatconflicts.patch deleted file mode 100644 index f02f4f7..0000000 --- a/0001-fix-a-copy-paste-help-description-of-whatconflicts.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a5d0255696890889b73e27a0ad4a57368aef8220 Mon Sep 17 00:00:00 2001 -From: wangkaiqiang -Date: Wed, 24 Jan 2024 23:59:16 +0800 -Subject: [PATCH] fix a copy-paste --help description of --whatconflicts - ---- - lib/poptQV.c | 2 +- - po/zh_CN.po | 4 ++++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/lib/poptQV.c b/lib/poptQV.c -index f752d8b..73d38b4 100644 ---- a/lib/poptQV.c -+++ b/lib/poptQV.c -@@ -106,7 +106,7 @@ struct poptOption rpmQVSourcePoptTable[] = { - { "verify", 'V', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'V', - N_("rpm verify mode"), NULL }, - { "whatconflicts", '\0', 0, 0, POPT_WHATCONFLICTS, -- N_("query/verify the package(s) which require a dependency"), "CAPABILITY" }, -+ N_("query/verify the package(s) which conflict with a dependency"), "CAPABILITY" }, - { "whatrequires", '\0', 0, 0, POPT_WHATREQUIRES, - N_("query/verify the package(s) which require a dependency"), "CAPABILITY" }, - { "whatobsoletes", '\0', 0, 0, POPT_WHATOBSOLETES, -diff --git a/po/zh_CN.po b/po/zh_CN.po -index bf8cb53..7bfceb0 100644 ---- a/po/zh_CN.po -+++ b/po/zh_CN.po -@@ -2505,6 +2505,10 @@ msgstr "查找由软件包所触发的软件包" - msgid "rpm verify mode" - msgstr "rpm 校验模式" - -+#: lib/poptQV.c:108 lib/poptQV.c:109 -+msgid "query/verify the package(s) which conflict with a dependency" -+msgstr "查询/校验与依赖项冲突的软件包" -+ - #: lib/poptQV.c:105 lib/poptQV.c:107 - msgid "query/verify the package(s) which require a dependency" - msgstr "查找/校验需要某个依赖对象的软件包" --- -2.31.1 - diff --git a/0001-support-sqlite-backend-rpmdb.patch b/0001-support-sqlite-backend-rpmdb.patch deleted file mode 100644 index 395badd..0000000 --- a/0001-support-sqlite-backend-rpmdb.patch +++ /dev/null @@ -1,2094 +0,0 @@ -From 955c0f001792deaa95913f5cd7ccaca2d8b0298e Mon Sep 17 00:00:00 2001 -From: forrest_ly -Date: Wed, 28 Jun 2023 16:50:14 +0800 -Subject: [PATCH] support sqlite backend rpmdb - ---- - configure.ac | 14 + - lib/Makefile.am | 4 + - lib/backend/bdb_ro.c | 816 +++++++++++++++++++++++++++++++++++++++++++ - lib/backend/db3.c | 69 ++-- - lib/backend/dbi.c | 139 ++++---- - lib/backend/dbi.h | 47 ++- - lib/backend/sqlite.c | 105 ++++-- - lib/rpmdb.c | 150 +++++--- - lib/rpmdb.h | 33 ++ - lib/rpmdb_internal.h | 10 +- - lib/rpmts.c | 8 +- - macros.in | 2 +- - rpmdb.c | 6 + - 13 files changed, 1212 insertions(+), 191 deletions(-) - create mode 100644 lib/backend/bdb_ro.c - -diff --git a/configure.ac b/configure.ac -index 3bd6382..a47aa46 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -610,6 +610,20 @@ AS_IF([test "$enable_ndb" = yes],[ - ]) - AM_CONDITIONAL([NDB], [test "$enable_ndb" = yes]) - -+#================= -+# Process --enable-bdb-ro -+AC_ARG_ENABLE([bdb-ro], [AS_HELP_STRING([--enable-bdb-ro (EXPERIMENTAL)],[enable the read-only Berkeley DB code])], -+[case "$enable_bdb_ro" in -+yes|no) ;; -+*) AC_MSG_ERROR([invalid argument to --enable-bdb-ro]) -+ ;; -+esac], -+[enable_bdb_ro=no]) -+AS_IF([test "$enable_bdb_ro" = yes],[ -+ AC_DEFINE(WITH_BDB_RO, 1, [Build with read-only Berkeley DB]) -+]) -+AM_CONDITIONAL([BDB_RO], [test "$enable_bdb_ro" = yes]) -+ - # Check for SQLITE support - AC_ARG_ENABLE([sqlite], - [AS_HELP_STRING([--enable-sqlite=@<:@yes/no/auto@:>@)], -diff --git a/lib/Makefile.am b/lib/Makefile.am -index 07c681e..b121f3d 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -66,6 +66,10 @@ else - librpm_la_LIBADD += @WITH_DB_LIB@ - endif - -+if BDB_RO -+librpm_la_SOURCES += backend/bdb_ro.c -+endif -+ - if NDB - librpm_la_SOURCES += \ - backend/ndb/glue.c \ -diff --git a/lib/backend/bdb_ro.c b/lib/backend/bdb_ro.c -new file mode 100644 -index 0000000..2667ec8 ---- /dev/null -+++ b/lib/backend/bdb_ro.c -@@ -0,0 +1,816 @@ -+#include "system.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "lib/rpmdb_internal.h" -+#include -+#include -+ -+#define BDB_HASH 0 -+#define BDB_BTREE 1 -+ -+struct dbiCursor_s; -+ -+struct bdb_kv { -+ unsigned char *kv; -+ unsigned int len; -+}; -+ -+struct bdb_db { -+ int fd; /* file descriptor of database */ -+ int type; /* BDB_HASH / BDB_BTREE */ -+ unsigned int pagesize; -+ unsigned int lastpage; -+ int swapped; /* different endianess? */ -+ /* btree */ -+ unsigned int root; /* root page of the b-tree */ -+ /* hash */ -+ unsigned int maxbucket; -+ unsigned int highmask; -+ unsigned int lowmask; -+ unsigned int spares[32]; /* spare pages for each splitpoint */ -+}; -+ -+struct bdb_cur { -+ struct bdb_db *db; -+ -+ struct bdb_kv key; /* key and value from the db entry */ -+ struct bdb_kv val; -+ -+ unsigned char *page; /* the page we're looking at */ -+ -+ unsigned char *ovpage; -+ struct bdb_kv keyov; /* space to store oversized keys/values */ -+ struct bdb_kv valov; -+ -+ int state; /* 1: onpage, -1: error */ -+ int idx; /* entry index */ -+ int numidx; /* number of entries on the page */ -+ int islookup; /* we're doing a lookup operation */ -+ -+ /* hash */ -+ unsigned int bucket; /* current bucket */ -+}; -+ -+ -+static void swap16(unsigned char *p) -+{ -+ int a = p[0]; -+ p[0] = p[1]; -+ p[1] = a; -+} -+ -+static void swap32(unsigned char *p) -+{ -+ int a = p[0]; -+ p[0] = p[3]; -+ p[3] = a; -+ a = p[1]; -+ p[1] = p[2]; -+ p[2] = a; -+} -+ -+static void swap32_2(unsigned char *p) -+{ -+ swap32(p); -+ swap32(p + 4); -+} -+ -+static void bdb_swapmetapage(struct bdb_db *db, unsigned char *page) -+{ -+ int i, maxi = db->type == BDB_HASH ? 224 : 92; -+ for (i = 8; i < maxi; i += 4) -+ swap32((unsigned char *)(page + i)); -+ swap32((unsigned char *)(page + 24)); -+} -+ -+static void bdb_swappage(struct bdb_db *db, unsigned char *page) -+{ -+ unsigned int pagesize = db->pagesize; -+ int type, i, nent, off; -+ swap32(page + 8); /* page number */ -+ swap32_2(page + 12); /* prev/next page */ -+ swap16(page + 20); /* nitems */ -+ swap16(page + 22); /* highfree */ -+ -+ type = page[25]; -+ if (type != 2 && type != 13 && type != 3 && type != 5) -+ return; -+ nent = *(uint16_t *)(page + 20); -+ if (nent > (pagesize - 26) / 2) -+ nent = (pagesize - 26) / 2; -+ for (i = 0; i < nent; i++) { -+ int minoff = 26 + nent * 2; -+ swap16(page + 26 + i * 2); /* offset */ -+ off = *(uint16_t *)(page + 26 + i * 2); -+ if (off < minoff || off >= pagesize) -+ continue; -+ if (type == 2 || type == 13) { /* hash */ -+ if (page[off] == 3 && off + 12 <= pagesize) -+ swap32_2(page + off + 4); /* page no/length */ -+ } else if (type == 3) { /* btree internal */ -+ if (off + 12 > pagesize) -+ continue; -+ swap16(page + off); /* length */ -+ swap32_2(page + off + 4); /* page no/num recs */ -+ if (page[off + 2] == 3 && off + 24 <= pagesize) -+ swap32_2(page + off + 16); /* with overflow page/length */ -+ } else if (type == 5) { /* btree leaf */ -+ if (off + 3 <= pagesize && page[off + 2] == 1) -+ swap16(page + off); /* length */ -+ else if (off + 12 <= pagesize && page[off + 2] == 3) -+ swap32_2(page + off + 4); /* overflow page/length */ -+ } -+ } -+} -+ -+static int bdb_getpage(struct bdb_db *db, unsigned char *page, unsigned int pageno) -+{ -+ if (!pageno || pageno > db->lastpage) -+ return -1; -+ if (pread(db->fd, page, db->pagesize, (off_t)pageno * db->pagesize) != db->pagesize) { -+ rpmlog(RPMLOG_ERR, "pread: %s\n", strerror(errno)); -+ return -1; -+ } -+ if (db->swapped) -+ bdb_swappage(db, page); -+ if (pageno != *(uint32_t *)(page + 8)) -+ return -1; -+ return 0; -+} -+ -+static void bdb_close(struct bdb_db *db) -+{ -+ if (db->fd >= 0) -+ close(db->fd); -+ free(db); -+} -+ -+static struct bdb_db *bdb_open(const char *name) -+{ -+ uint32_t meta[512 / 4]; -+ int i, fd; -+ struct bdb_db *db; -+ -+ fd = open(name, O_RDONLY); -+ if (fd == -1) { -+ return NULL; -+ } -+ db = xcalloc(1, sizeof(*db)); -+ db->fd = fd; -+ if (pread(fd, meta, 512, 0) != 512) { -+ rpmlog(RPMLOG_ERR, "%s: pread: %s\n", name, strerror(errno)); -+ bdb_close(db); -+ return NULL; -+ } -+ if (meta[3] == 0x00061561 || meta[3] == 0x61150600) { -+ db->type = BDB_HASH; -+ db->swapped = meta[3] == 0x61150600; -+ } else if (meta[3] == 0x00053162 || meta[3] == 0x62310500) { -+ db->type = BDB_BTREE; -+ db->swapped = meta[3] == 0x62310500; -+ } else { -+ rpmlog(RPMLOG_ERR, "%s: not a berkeley db hash/btree database\n", name); -+ bdb_close(db); -+ return NULL; -+ } -+ if (db->swapped) -+ bdb_swapmetapage(db, (unsigned char *)meta); -+ db->pagesize = meta[5]; -+ db->lastpage = meta[8]; -+ if (db->type == BDB_HASH) { -+ if (meta[4] < 8 || meta[4] > 10) { -+ rpmlog(RPMLOG_ERR, "%s: unsupported hash version %d\n", name, meta[4]); -+ bdb_close(db); -+ return NULL; -+ } -+ db->maxbucket = meta[18]; -+ db->highmask = meta[19]; -+ db->lowmask = meta[20]; -+ for (i = 0; i < 32; i++) -+ db->spares[i] = meta[24 + i]; -+ } -+ if (db->type == BDB_BTREE) { -+ if (meta[4] < 9 || meta[4] > 10) { -+ rpmlog(RPMLOG_ERR, "%s: unsupported btree version %d\n", name, meta[4]); -+ bdb_close(db); -+ return NULL; -+ } -+ db->root = meta[22]; -+ } -+ return db; -+} -+ -+ -+/****** overflow handling ******/ -+ -+static int ovfl_get(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, uint32_t *pagenolen) -+{ -+ unsigned int pageno = pagenolen[0]; -+ unsigned int len = pagenolen[1]; -+ unsigned int plen; -+ unsigned char *p; -+ -+ if (len == 0) -+ return -1; -+ if (len > ov->len) { -+ if (ov->kv) -+ ov->kv = xrealloc(ov->kv, len); -+ else -+ ov->kv = xmalloc(len); -+ ov->len = len; -+ } -+ if (!cur->ovpage) -+ cur->ovpage = xmalloc(cur->db->pagesize); -+ p = ov->kv; -+ while (len > 0) { -+ if (bdb_getpage(cur->db, cur->ovpage, pageno)) -+ return -1; -+ if (cur->ovpage[25] != 7) -+ return -1; -+ plen = *(uint16_t *)(cur->ovpage + 22); -+ if (plen + 26 > cur->db->pagesize || plen > len) -+ return -1; -+ memcpy(p, cur->ovpage + 26, plen); -+ p += plen; -+ len -= plen; -+ pageno = *(uint32_t *)(cur->ovpage + 16); -+ } -+ if (kv) { -+ kv->kv = ov->kv; -+ kv->len = pagenolen[1]; -+ } -+ return 0; -+} -+ -+ -+/****** hash implementation ******/ -+ -+static int hash_bucket_to_page(struct bdb_db *db, unsigned int bucket) -+{ -+ unsigned int b; -+ int i = 0; -+ for (b = bucket; b; b >>= 1) -+ i++; -+ return bucket + db->spares[i]; -+} -+ -+static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ uint32_t bucket; -+ unsigned int pg, i; -+ cur->state = -1; -+ for (bucket = 0, i = 0; i < keyl; i++) -+ bucket = (bucket * 16777619) ^ key[i]; -+ bucket &= cur->db->highmask; -+ if (bucket > cur->db->maxbucket) -+ bucket &= cur->db->lowmask; -+ cur->bucket = bucket; -+ pg = hash_bucket_to_page(cur->db, bucket); -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] != 8 && cur->page[25] != 13) -+ return -1; -+ cur->idx = (unsigned int)-2; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ cur->state = 1; -+ return 0; -+} -+ -+static int hash_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off, int len) -+{ -+ if (len <= 0 || off + len > cur->db->pagesize) -+ return -1; -+ if (cur->page[off] == 1) { -+ kv->kv = cur->page + off + 1; -+ kv->len = len - 1; -+ } else if (cur->page[off] == 3) { -+ uint32_t ovlpage[2]; -+ if (len != 12) -+ return -1; -+ memcpy(ovlpage, cur->page + off + 4, 8); /* off is unaligned */ -+ if (ovfl_get(cur, kv, ov, ovlpage)) -+ return -1; -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+static int hash_next(struct bdb_cur *cur) -+{ -+ int pagesize = cur->db->pagesize; -+ int koff, klen, voff, vlen; -+ if (!cur->state && hash_lookup(cur, 0, 0)) -+ return -1; -+ cur->idx += 2; -+ for (;;) { -+ if (cur->idx + 1 >= cur->numidx) { -+ unsigned int pg; -+ cur->idx = cur->numidx = 0; -+ pg = *(uint32_t *)(cur->page + 16); -+ if (!pg) { -+ if (cur->islookup || cur->bucket >= cur->db->maxbucket) -+ return 1; -+ pg = hash_bucket_to_page(cur->db, ++cur->bucket); -+ } -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] != 8 && cur->page[25] != 13) -+ return -1; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ continue; -+ } -+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ if (koff >= pagesize || voff >= pagesize) -+ return -1; -+ if (cur->idx == 0) -+ klen = pagesize - koff; -+ else -+ klen = *(uint16_t *)(cur->page + 24 + 2 * cur->idx) - koff; -+ vlen = koff - voff; -+ if (hash_getkv(cur, &cur->key, &cur->keyov, koff, klen)) -+ return -1; -+ if (!cur->islookup && hash_getkv(cur, &cur->val, &cur->valov, voff, vlen)) -+ return -1; -+ return 0; -+ } -+} -+ -+static int hash_getval(struct bdb_cur *cur) -+{ -+ int koff, voff; -+ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) -+ return -1; -+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ return hash_getkv(cur, &cur->val, &cur->valov, voff, koff - voff); -+} -+ -+ -+/****** btree implementation ******/ -+ -+static int btree_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keylen) -+{ -+ int pagesize = cur->db->pagesize; -+ int off, lastoff, idx, numidx; -+ unsigned int pg; -+ unsigned char *ekey; -+ unsigned int ekeylen; -+ int cmp; -+ -+ cur->state = -1; -+ pg = cur->db->root; -+ for (;;) { -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] == 5) -+ break; /* found leaf page */ -+ if (cur->page[25] != 3) -+ return -1; -+ numidx = *(uint16_t *)(cur->page + 20); -+ if (!numidx) -+ return -1; -+ for (lastoff = 0, idx = 0; idx < numidx; idx++, lastoff = off) { -+ off = *(uint16_t *)(cur->page + 26 + 2 * idx); -+ if ((off & 3) != 0 || off + 3 > pagesize) -+ return -1; -+ ekeylen = *(uint16_t *)(cur->page + off); -+ if (off + 12 + ekeylen > pagesize) -+ return -1; -+ if (!keylen) { -+ lastoff = off; -+ break; -+ } -+ if (idx == 0) -+ continue; -+ ekey = cur->page + off + 12; -+ if ((cur->page[off + 2] & 0x7f) == 3) { -+ if (ekeylen != 12) -+ return -1; -+ if (ovfl_get(cur, 0, &cur->keyov, (uint32_t *)(ekey + 4))) -+ return -1; -+ ekeylen = *(uint32_t *)(ekey + 8); -+ ekey = cur->keyov.kv; -+ } else if ((cur->page[off + 2] & 0x7f) != 1) { -+ return -1; -+ } -+ cmp = memcmp(ekey, key, keylen < ekeylen ? keylen : ekeylen); -+ if (cmp > 0 || (cmp == 0 && ekeylen > keylen)) -+ break; -+ } -+ pg = *(uint32_t *)(cur->page + lastoff + 4); -+ } -+ cur->idx = (unsigned int)-2; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ cur->state = 1; -+ return 0; -+} -+ -+static int btree_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off) -+{ -+ if ((off & 3) != 0) -+ return -1; -+ if (cur->page[off + 2] == 1) { -+ int len = *(uint16_t *)(cur->page + off); -+ if (off + 3 + len > cur->db->pagesize) -+ return -1; -+ kv->kv = cur->page + off + 3; -+ kv->len = len; -+ } else if (cur->page[off + 2] == 3) { -+ if (off + 12 > cur->db->pagesize) -+ return -1; -+ if (ovfl_get(cur, kv, ov, (uint32_t *)(cur->page + off + 4))) -+ return -1; -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+static int btree_next(struct bdb_cur *cur) -+{ -+ int pagesize = cur->db->pagesize; -+ int koff, voff; -+ if (!cur->state && btree_lookup(cur, 0, 0)) -+ return -1; -+ cur->idx += 2; -+ for (;;) { -+ if (cur->idx + 1 >= cur->numidx) { -+ unsigned int pg; -+ cur->idx = cur->numidx = 0; -+ pg = *(uint32_t *)(cur->page + 16); -+ if (cur->islookup || !pg) -+ return 1; -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] != 5) -+ return -1; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ continue; -+ } -+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ if (koff + 3 > pagesize || voff + 3 > pagesize) -+ return -1; -+ if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0) -+ continue; /* ignore deleted */ -+ if (btree_getkv(cur, &cur->key, &cur->keyov, koff)) -+ return -1; -+ if (!cur->islookup && btree_getkv(cur, &cur->val, &cur->valov, voff)) -+ return -1; -+ return 0; -+ } -+} -+ -+static int btree_getval(struct bdb_cur *cur) -+{ -+ int voff; -+ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) -+ return -1; -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ return btree_getkv(cur, &cur->val, &cur->valov, voff); -+} -+ -+ -+/****** cursor functions ******/ -+ -+static struct bdb_cur *cur_open(struct bdb_db *db) -+{ -+ struct bdb_cur *cur = xcalloc(1, sizeof(*cur)); -+ cur->db = db; -+ cur->page = xmalloc(db->pagesize); -+ return cur; -+} -+ -+static void cur_close(struct bdb_cur *cur) -+{ -+ if (cur->page) -+ free(cur->page); -+ if (cur->ovpage) -+ free(cur->ovpage); -+ if (cur->keyov.kv) -+ free(cur->keyov.kv); -+ if (cur->valov.kv) -+ free(cur->valov.kv); -+ free(cur); -+} -+ -+static int cur_next(struct bdb_cur *cur) -+{ -+ if (cur->state < 0) -+ return -1; -+ if (cur->db->type == BDB_HASH) -+ return hash_next(cur); -+ if (cur->db->type == BDB_BTREE) -+ return btree_next(cur); -+ return -1; -+} -+ -+static int cur_getval(struct bdb_cur *cur) -+{ -+ if (cur->state < 0) -+ return -1; -+ if (cur->db->type == BDB_HASH) -+ return hash_getval(cur); -+ if (cur->db->type == BDB_BTREE) -+ return btree_getval(cur); -+ return -1; -+} -+ -+static int cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ int r = -1; -+ if (cur->db->type == BDB_HASH) -+ r = hash_lookup(cur, key, keyl); -+ if (cur->db->type == BDB_BTREE) -+ r = btree_lookup(cur, key, keyl); -+ if (r != 0) -+ return r; -+ cur->islookup = 1; -+ while ((r = cur_next(cur)) == 0) -+ if (keyl == cur->key.len && !memcmp(key, cur->key.kv, keyl)) -+ break; -+ cur->islookup = 0; -+ if (r == 0) -+ r = cur_getval(cur); -+ return r; -+} -+ -+static int cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ int r = -1; -+ if (cur->db->type == BDB_BTREE) -+ r = btree_lookup(cur, key, keyl); -+ if (r != 0) -+ return r; -+ cur->islookup = 1; -+ while ((r = cur_next(cur)) == 0) { -+ unsigned int ekeyl = cur->key.len; -+ int cmp = memcmp(cur->key.kv, key, keyl < ekeyl ? keyl : ekeyl); -+ if (cmp > 0 || (cmp == 0 && ekeyl >= keyl)) -+ break; -+ } -+ cur->islookup = 0; -+ if (r == 0) -+ r = cur_getval(cur); -+ else if (r == 1) -+ r = cur_next(cur); -+ return r; -+} -+ -+/****** glue code ******/ -+ -+static unsigned int getui32(unsigned char *x, int swapped) -+{ -+ union _dbswap bs; -+ memcpy(bs.uc, x, 4); -+ if (swapped) -+ _DBSWAP(bs); -+ return bs.ui; -+} -+ -+static void setui32(unsigned char *x, uint32_t v, int swapped) -+{ -+ union _dbswap bs; -+ bs.ui = v; -+ if (swapped) -+ _DBSWAP(bs); -+ memcpy(x, bs.uc, 4); -+} -+ -+static void log_error(dbiIndex dbi) -+{ -+ rpmlog(RPMLOG_ERR, "bdb_ro error reading %s database\n", dbi->dbi_file); -+} -+ -+static int bdbro_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags) -+{ -+ const char *dbhome = rpmdbHome(rdb); -+ dbiIndex dbi = NULL; -+ char *path; -+ -+ if (dbip) -+ *dbip = NULL; -+ if ((rdb->db_mode & O_ACCMODE) != O_RDONLY) -+ return EPERM; -+ if ((dbi = dbiNew(rdb, rpmtag)) == NULL) -+ return 1; -+ path = rstrscat(NULL, dbhome, "/", dbi->dbi_file, NULL); -+ rpmlog(RPMLOG_DEBUG, "opening db index %s\n", path); -+ dbi->dbi_db = bdb_open(path); -+ if (!dbi->dbi_db) { -+ int lvl = (dbi->dbi_type == DBI_PRIMARY) ? RPMLOG_ERR : RPMLOG_WARNING; -+ rpmlog(lvl, "could not open %s: %s\n", path, strerror(errno)); -+ if (dbi->dbi_type == DBI_PRIMARY) { -+ free(path); -+ dbiFree(dbi); -+ return 1; -+ } -+ } -+ free(path); -+ dbi->dbi_flags |= DBI_RDONLY; -+ if (dbip) -+ *dbip = dbi; -+ else -+ (void) dbiClose(dbi, 0); -+ return 0; -+} -+ -+static int bdbro_Close(dbiIndex dbi, unsigned int flags) -+{ -+ if (dbi->dbi_db) -+ bdb_close(dbi->dbi_db); -+ dbiFree(dbi); -+ return 0; -+} -+ -+static int bdbro_Verify(dbiIndex dbi, unsigned int flags) -+{ -+ return 0; -+} -+ -+static void bdbro_SetFSync(rpmdb rdb, int enable) -+{ -+} -+ -+static int bdbro_Ctrl(rpmdb rdb, dbCtrlOp ctrl) -+{ -+ return 0; -+} -+ -+static dbiCursor bdbro_CursorInit(dbiIndex dbi, unsigned int flags) -+{ -+ /* Secondary indexes may be missing */ -+ return (dbi && dbi->dbi_db) ? (void *)cur_open(dbi->dbi_db) : NULL; -+} -+ -+static dbiCursor bdbro_CursorFree(dbiIndex dbi, dbiCursor dbc) -+{ -+ if (dbc) -+ cur_close((void *)dbc); -+ return NULL; -+} -+ -+static void appenddbt(dbiCursor dbc, unsigned char *val, unsigned int vallen, dbiIndexSet *setp) -+{ -+ struct bdb_cur *cur = (void *)dbc; -+ dbiIndexSet set; -+ unsigned int i; -+ -+ set = dbiIndexSetNew(vallen / (2 * sizeof(uint32_t))); -+ set->count = vallen / (2 * sizeof(uint32_t)); -+ -+ for (i = 0; i < set->count; i++, val += 8) { -+ set->recs[i].hdrNum = getui32(val, cur->db->swapped); -+ set->recs[i].tagNum = getui32(val + 4, cur->db->swapped); -+ } -+ if (*setp == NULL) { -+ *setp = set; -+ } else { -+ dbiIndexSetAppendSet(*setp, set, 0); -+ dbiIndexSetFree(set); -+ } -+} -+ -+static rpmRC bdbro_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) -+{ -+ return RPMRC_FAIL; -+} -+ -+static rpmRC bdbro_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) -+{ -+ return RPMRC_FAIL; -+} -+ -+static rpmRC bdbro_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, -+ dbiIndexSet *set, int searchType) -+{ -+ struct bdb_cur *cur = (void *)dbc; -+ int r; -+ -+ if (!cur) -+ return RPMRC_FAIL; -+ if (searchType == DBC_PREFIX_SEARCH) { -+ rpmRC rc = RPMRC_NOTFOUND; -+ if (!keyp) -+ return RPMRC_FAIL; -+ r = cur_lookup_ge(cur, (const unsigned char *)keyp, keylen); -+ for (; r == 0; r = cur_next(cur)) { -+ if (cur->key.len < keylen || memcmp(cur->key.kv, keyp, keylen) != 0) -+ break; -+ if (set) -+ appenddbt(dbc, cur->val.kv, cur->val.len, set); -+ rc = RPMRC_OK; -+ } -+ if (r == -1) -+ log_error(dbi); -+ cur->key.kv = 0; -+ return r == -1 ? RPMRC_FAIL : rc; -+ } -+ if (keyp) { -+ if (keylen == 0) { -+ keyp = ""; -+ keylen = 1; -+ } -+ r = cur_lookup(cur, (const unsigned char *)keyp, keylen); -+ } else { -+ r = cur_next(cur); -+ } -+ if (r == 0) { -+ if (set) -+ appenddbt(dbc, cur->val.kv, cur->val.len, set); -+ return RPMRC_OK; -+ } -+ if (r == -1) -+ log_error(dbi); -+ cur->key.kv = 0; -+ return r == 1 ? RPMRC_NOTFOUND : RPMRC_FAIL; -+} -+ -+static const void *bdbro_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) -+{ -+ struct bdb_cur *cur = (void *)dbc; -+ if (!cur || !cur->key.kv) -+ return 0; -+ if (keylen) -+ *keylen = cur->key.len; -+ return cur->key.kv; -+} -+ -+static rpmRC bdbro_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, -+ unsigned char *hdrBlob, unsigned int hdrLen) -+{ -+ return RPMRC_FAIL; -+} -+ -+static rpmRC bdbro_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) -+{ -+ return RPMRC_FAIL; -+} -+ -+static rpmRC bdbro_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, -+ unsigned char **hdrBlob, unsigned int *hdrLen) -+{ -+ struct bdb_cur *cur = (void *)dbc; -+ int r; -+ if (hdrNum) { -+ unsigned char hdrkey[4]; -+ setui32(hdrkey, hdrNum, cur->db->swapped); -+ r = cur_lookup(cur, hdrkey, 4); -+ } else { -+ r = cur_next(cur); -+ } -+ if (r == 0) { -+ if (hdrBlob) -+ *hdrBlob = cur->val.kv; -+ if (hdrLen) -+ *hdrLen = cur->val.len; -+ return RPMRC_OK; -+ } -+ if (r == -1) -+ log_error(dbi); -+ cur->key.kv = 0; -+ return r == 1 ? RPMRC_NOTFOUND : RPMRC_FAIL; -+} -+ -+static unsigned int bdbro_pkgdbKey(dbiIndex dbi, dbiCursor dbc) -+{ -+ struct bdb_cur *cur = (void *)dbc; -+ if (!cur || !cur->key.kv || cur->key.len != 4) -+ return 0; -+ return getui32(cur->key.kv, cur->db->swapped); -+} -+ -+struct rpmdbOps_s bdbro_dbops = { -+ .name = "bdb_ro", -+ .path = "Packages", -+ -+ .open = bdbro_Open, -+ .close = bdbro_Close, -+ .verify = bdbro_Verify, -+ .setFSync = bdbro_SetFSync, -+ .ctrl = bdbro_Ctrl, -+ -+ .cursorInit = bdbro_CursorInit, -+ .cursorFree = bdbro_CursorFree, -+ -+ .pkgdbPut = bdbro_pkgdbPut, -+ .pkgdbDel = bdbro_pkgdbDel, -+ .pkgdbGet = bdbro_pkgdbGet, -+ .pkgdbKey = bdbro_pkgdbKey, -+ -+ .idxdbGet = bdbro_idxdbGet, -+ .idxdbPut = bdbro_idxdbPut, -+ .idxdbDel = bdbro_idxdbDel, -+ .idxdbKey = bdbro_idxdbKey -+}; -+ -diff --git a/lib/backend/db3.c b/lib/backend/db3.c -index da50dfd..68cfa6f 100644 ---- a/lib/backend/db3.c -+++ b/lib/backend/db3.c -@@ -11,6 +11,7 @@ static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */ - #include - #include - #include -+#include - - #include - #include -@@ -415,10 +416,6 @@ static int db_init(rpmdb rdb, const char * dbhome) - if (rdb->db_dbenv != NULL) { - rdb->db_opens++; - return 0; -- } else { -- /* On first call, set backend description to something... */ -- free(rdb->db_descr); -- rasprintf(&rdb->db_descr, "db%u", DB_VERSION_MAJOR); - } - - /* -@@ -1012,7 +1009,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t - dbiIndexSet *set, int searchType) - { - rpmRC rc = RPMRC_FAIL; /* assume failure */ -- if (dbi != NULL && dbc != NULL && set != NULL) { -+ if (dbi != NULL && dbc != NULL) { - int cflags = DB_NEXT; - int dbrc; - DBT data, key; -@@ -1037,12 +1034,14 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t - if (searchType == DBC_PREFIX_SEARCH && - (key.size < keylen || memcmp(key.data, keyp, keylen) != 0)) - break; -- dbt2set(dbi, &data, &newset); -- if (*set == NULL) { -- *set = newset; -- } else { -- dbiIndexSetAppendSet(*set, newset, 0); -- dbiIndexSetFree(newset); -+ if (set) { -+ dbt2set(dbi, &data, &newset); -+ if (*set == NULL) { -+ *set = newset; -+ } else { -+ dbiIndexSetAppendSet(*set, newset, 0); -+ dbiIndexSetFree(newset); -+ } - } - if (searchType != DBC_PREFIX_SEARCH) - break; -@@ -1052,7 +1051,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t - } - - /* fixup result status for prefix search */ -- if (searchType == DBC_PREFIX_SEARCH) { -+ if (searchType == DBC_PREFIX_SEARCH && set) { - if (dbrc == DB_NOTFOUND && *set != NULL && (*set)->count > 0) - dbrc = 0; - else if (dbrc == 0 && (*set == NULL || (*set)->count == 0)) -@@ -1115,7 +1114,7 @@ static rpmRC updateIndex(dbiCursor dbc, const char *keyp, unsigned int keylen, - return rc; - } - --static rpmRC db3_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, -+static rpmRC db3_idxdbPutOne(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, - dbiIndexItem rec) - { - dbiIndexSet set = NULL; -@@ -1141,7 +1140,12 @@ static rpmRC db3_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t - return rc; - } - --static rpmRC db3_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, -+static rpmRC db3_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) -+{ -+ return tag2index(dbi, rpmtag, hdrNum, h, db3_idxdbPutOne); -+} -+ -+static rpmRC db3_idxdbDelOne(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, - dbiIndexItem rec) - { - dbiIndexSet set = NULL; -@@ -1171,6 +1175,11 @@ static rpmRC db3_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t - return rc; - } - -+static rpmRC db3_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) -+{ -+ return tag2index(dbi, rpmtag, hdrNum, h, db3_idxdbDelOne); -+} -+ - static const void * db3_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) - { - const void *key = NULL; -@@ -1278,14 +1287,26 @@ static unsigned int pkgInstance(dbiIndex dbi, int alloc) - return hdrNum; - } - --static rpmRC db3_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, -+static rpmRC db3_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, - unsigned char *hdrBlob, unsigned int hdrLen) - { -+ rpmRC rc = RPMRC_FAIL; -+ unsigned int hnum = *hdrNum; - DBT hdr; - memset(&hdr, 0, sizeof(hdr)); - hdr.data = hdrBlob; - hdr.size = hdrLen; -- return updatePackages(dbc, hdrNum, &hdr); -+ -+ if (hnum == 0) -+ hnum = pkgInstance(dbi, 1); -+ -+ if (hnum) -+ rc = updatePackages(dbc, hnum, &hdr); -+ -+ if (rc == RPMRC_OK) -+ *hdrNum = hnum; -+ -+ return rc; - } - - static rpmRC db3_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) -@@ -1342,19 +1363,10 @@ static unsigned int db3_pkgdbKey(dbiIndex dbi, dbiCursor dbc) - return mi_offset.ui; - } - --static rpmRC db3_pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum) --{ -- unsigned int num; -- if (dbc == NULL) -- return RPMRC_FAIL; -- num = pkgInstance(dbc->dbi, 1); -- if (!num) -- return RPMRC_FAIL; -- *hdrNum = num; -- return RPMRC_OK; --} -- - struct rpmdbOps_s db3_dbops = { -+ .name = "bdb", -+ .path = "Packages", -+ - .open = db3_dbiOpen, - .close = db3_dbiClose, - .verify = db3_dbiVerify, -@@ -1368,7 +1380,6 @@ struct rpmdbOps_s db3_dbops = { - .pkgdbGet = db3_pkgdbGet, - .pkgdbPut = db3_pkgdbPut, - .pkgdbDel = db3_pkgdbDel, -- .pkgdbNew = db3_pkgdbNew, - .pkgdbKey = db3_pkgdbKey, - - .idxdbGet = db3_idxdbGet, -diff --git a/lib/backend/dbi.c b/lib/backend/dbi.c -index dc3587f..9e714d7 100644 ---- a/lib/backend/dbi.c -+++ b/lib/backend/dbi.c -@@ -5,6 +5,7 @@ - #include "system.h" - - #include -+#include - #include - #include - #include -@@ -12,6 +13,21 @@ - #include "lib/rpmdb_internal.h" - #include "debug.h" - -+const struct rpmdbOps_s *backends[] = { -+#if defined(WITH_SQLITE) -+ &sqlite_dbops, -+#endif -+#ifdef ENABLE_NDB -+ &ndb_dbops, -+#endif -+#if defined(WITH_BDB) -+ &db3_dbops, -+#endif -+#if defined(WITH_BDB_RO) -+ &bdbro_dbops, -+#endif -+ NULL -+}; - - dbiIndex dbiFree(dbiIndex dbi) - { -@@ -32,69 +48,77 @@ dbiIndex dbiNew(rpmdb rdb, rpmDbiTagVal rpmtag) - return dbi; - } - -+/* Test whether there's a database for this backend, return true/false */ -+static int tryBackend(const char *dbhome, const struct rpmdbOps_s *be) -+{ -+ int rc = 0; -+ if (be && be->path) { -+ char *path = rstrscat(NULL, dbhome, "/", be->path, NULL); -+ rc = (access(path, F_OK) == 0); -+ free(path); -+ } -+ return rc; -+} -+ - static void - dbDetectBackend(rpmdb rdb) - { - const char *dbhome = rpmdbHome(rdb); - char *db_backend = rpmExpand("%{?_db_backend}", NULL); -- char *path = NULL; -- --#if defined(WITH_LMDB) -- if (!strcmp(db_backend, "lmdb")) { -- rdb->db_ops = &lmdb_dbops; -- } else --#endif --#ifdef ENABLE_NDB -- if (!strcmp(db_backend, "ndb")) { -- rdb->db_ops = &ndb_dbops; -- } else --#endif --#ifdef WITH_SQLITE -- if (!strcmp(db_backend, "sqlite")) { -- rdb->db_ops = &sqlite_dbops; -- } else --#endif -- { -- rdb->db_ops = &db3_dbops; -- if (*db_backend == '\0') { -- free(db_backend); -- db_backend = xstrdup("bdb"); -+ const struct rpmdbOps_s **ops; -+ const struct rpmdbOps_s *cfg = NULL; -+ const struct rpmdbOps_s *ondisk = NULL; -+ -+ /* Find configured backend */ -+ for (ops = backends; ops && *ops; ops++) { -+ if (rstreq(db_backend, (*ops)->name)) { -+ cfg = *ops; -+ break; - } - } - --#if defined(WITH_LMDB) -- path = rstrscat(NULL, dbhome, "/data.mdb", NULL); -- if (access(path, F_OK) == 0 && rdb->db_ops != &lmdb_dbops) { -- rdb->db_ops = &lmdb_dbops; -- rpmlog(RPMLOG_WARNING, _("Found LMDB data.mdb database while attempting %s backend: using lmdb backend.\n"), db_backend); -+ if (!cfg && ((rdb->db_mode & O_ACCMODE) != O_RDONLY || (rdb->db_flags & RPMDB_FLAG_REBUILD) != 0)) { -+ rpmlog(RPMLOG_WARNING, _("invalid %%_db_backend: %s\n"), db_backend); -+ goto exit; - } -- free(path); --#endif - --#ifdef ENABLE_NDB -- path = rstrscat(NULL, dbhome, "/Packages.db", NULL); -- if (access(path, F_OK) == 0 && rdb->db_ops != &ndb_dbops) { -- rdb->db_ops = &ndb_dbops; -- rpmlog(RPMLOG_WARNING, _("Found NDB Packages.db database while attempting %s backend: using ndb backend.\n"), db_backend); -- } -- free(path); --#endif -+ /* If configured database doesn't exist, try autodetection */ -+ if (!tryBackend(dbhome, cfg)) { -+ for (ops = backends; ops && *ops; ops++) { -+ if (tryBackend(dbhome, *ops)) { -+ ondisk = *ops; -+ break; -+ } -+ } - --#ifdef WITH_SQLITE -- path = rstrscat(NULL, dbhome, "/rpmdb.sqlite", NULL); -- if (access(path, F_OK) == 0 && rdb->db_ops != &sqlite_dbops) { -- rdb->db_ops = &sqlite_dbops; -- rpmlog(RPMLOG_WARNING, _("Found SQLITE rpmdb.sqlite database while attempting %s backend: using sqlite backend.\n"), db_backend); -+ /* On-disk database differs from configuration */ -+ if (ondisk && ondisk != cfg) { -+ if (*db_backend) { -+ if (rdb->db_flags & RPMDB_FLAG_REBUILD) { -+ rpmlog(RPMLOG_WARNING, -+ _("Converting database from %s to %s backend\n"), -+ ondisk->name, db_backend); -+ } else { -+ rpmlog(RPMLOG_WARNING, -+ _("Found %s %s database while attempting %s backend: " -+ "using %s backend.\n"), -+ ondisk->name, ondisk->path, db_backend, ondisk->name); -+ } -+ } else { -+ rpmlog(RPMLOG_DEBUG, "Found %s %s database: using %s backend.\n", -+ ondisk->name, ondisk->path, ondisk->name); -+ } -+ rdb->db_ops = ondisk; -+ } - } -- free(path); --#endif - -- path = rstrscat(NULL, dbhome, "/Packages", NULL); -- if (access(path, F_OK) == 0 && rdb->db_ops != &db3_dbops) { -- rdb->db_ops = &db3_dbops; -- rpmlog(RPMLOG_WARNING, _("Found BDB Packages database while attempting %s backend: using bdb backend.\n"), db_backend); -- } -- free(path); -+ /* Newly created database, use configured backend */ -+ if (rdb->db_ops == NULL && cfg) -+ rdb->db_ops = cfg; -+ -+exit: -+ -+ rdb->db_descr = rdb->db_ops->name; - - if (db_backend) - free(db_backend); -@@ -151,7 +175,7 @@ dbiCursor dbiCursorFree(dbiIndex dbi, dbiCursor dbc) - return dbi->dbi_rpmdb->db_ops->cursorFree(dbi, dbc); - } - --rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) -+rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) - { - return dbi->dbi_rpmdb->db_ops->pkgdbPut(dbi, dbc, hdrNum, hdrBlob, hdrLen); - } -@@ -166,11 +190,6 @@ rpmRC pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char * - return dbi->dbi_rpmdb->db_ops->pkgdbGet(dbi, dbc, hdrNum, hdrBlob, hdrLen); - } - --rpmRC pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum) --{ -- return dbi->dbi_rpmdb->db_ops->pkgdbNew(dbi, dbc, hdrNum); --} -- - unsigned int pkgdbKey(dbiIndex dbi, dbiCursor dbc) - { - return dbi->dbi_rpmdb->db_ops->pkgdbKey(dbi, dbc); -@@ -181,14 +200,14 @@ rpmRC idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbi - return dbi->dbi_rpmdb->db_ops->idxdbGet(dbi, dbc, keyp, keylen, set, curFlags); - } - --rpmRC idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) -+rpmRC idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) - { -- return dbi->dbi_rpmdb->db_ops->idxdbPut(dbi, dbc, keyp, keylen, rec); -+ return dbi->dbi_rpmdb->db_ops->idxdbPut(dbi, rpmtag, hdrNum, h); - } - --rpmRC idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) -+rpmRC idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) - { -- return dbi->dbi_rpmdb->db_ops->idxdbDel(dbi, dbc, keyp, keylen, rec); -+ return dbi->dbi_rpmdb->db_ops->idxdbDel(dbi, rpmtag, hdrNum, h); - } - - const void * idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) -diff --git a/lib/backend/dbi.h b/lib/backend/dbi.h -index ff2b4f9..fba2f04 100644 ---- a/lib/backend/dbi.h -+++ b/lib/backend/dbi.h -@@ -10,6 +10,7 @@ enum rpmdbFlags { - RPMDB_FLAG_JUSTCHECK = (1 << 0), - RPMDB_FLAG_REBUILD = (1 << 1), - RPMDB_FLAG_VERIFYONLY = (1 << 2), -+ RPMDB_FLAG_SALVAGE = (1 << 3), - }; - - typedef enum dbCtrlOp_e { -@@ -49,7 +50,7 @@ struct rpmdb_s { - int db_flags; - int db_mode; /*!< open mode */ - int db_perms; /*!< open permissions */ -- char * db_descr; /*!< db backend description (for error msgs) */ -+ const char * db_descr; /*!< db backend description (for error msgs) */ - struct dbChk_s * db_checked;/*!< headerCheck()'ed package instances */ - rpmdb db_next; - int db_opens; -@@ -59,10 +60,11 @@ struct rpmdb_s { - dbiIndex * db_indexes; /*!< Tag indices. */ - int db_buildindex; /*!< Index rebuild indicator */ - -- struct rpmdbOps_s * db_ops; /*!< backend ops */ -+ const struct rpmdbOps_s * db_ops; /*!< backend ops */ - - /* dbenv and related parameters */ - void * db_dbenv; /*!< Backend private handle */ -+ void * db_cache; /*!< Backend private cache handle */ - struct dbConfig_s cfg; - int db_remove_env; - -@@ -123,10 +125,16 @@ union _dbswap { - \ - } - -+typedef rpmRC (*idxfunc)(dbiIndex dbi, dbiCursor dbc, -+ const char *keyp, size_t keylen, dbiIndexItem rec); -+ - #ifdef __cplusplus - extern "C" { - #endif - -+RPM_GNUC_INTERNAL -+rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h, -+ idxfunc idxupdate); - - RPM_GNUC_INTERNAL - /* Globally enable/disable fsync in the backend */ -@@ -216,7 +224,7 @@ dbiCursor dbiCursorFree(dbiIndex dbi, dbiCursor dbc); - - - RPM_GNUC_INTERNAL --rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, -+rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, - unsigned char *hdrBlob, unsigned int hdrLen); - RPM_GNUC_INTERNAL - rpmRC pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum); -@@ -224,23 +232,24 @@ RPM_GNUC_INTERNAL - rpmRC pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, - unsigned char **hdrBlob, unsigned int *hdrLen); - RPM_GNUC_INTERNAL --rpmRC pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum); --RPM_GNUC_INTERNAL - unsigned int pkgdbKey(dbiIndex dbi, dbiCursor dbc); - - RPM_GNUC_INTERNAL - rpmRC idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, - dbiIndexSet *set, int curFlags); - RPM_GNUC_INTERNAL --rpmRC idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, -- dbiIndexItem rec); -+rpmRC idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); -+ - RPM_GNUC_INTERNAL --rpmRC idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, -- dbiIndexItem rec); -+rpmRC idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); -+ - RPM_GNUC_INTERNAL - const void * idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen); - - struct rpmdbOps_s { -+ const char *name; /* backend name */ -+ const char *path; /* main database name */ -+ - int (*open)(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags); - int (*close)(dbiIndex dbi, unsigned int flags); - int (*verify)(dbiIndex dbi, unsigned int flags); -@@ -251,28 +260,29 @@ struct rpmdbOps_s { - dbiCursor (*cursorFree)(dbiIndex dbi, dbiCursor dbc); - - rpmRC (*pkgdbGet)(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char **hdrBlob, unsigned int *hdrLen); -- rpmRC (*pkgdbPut)(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen); -+ rpmRC (*pkgdbPut)(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen); - rpmRC (*pkgdbDel)(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum); -- rpmRC (*pkgdbNew)(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum); - unsigned int (*pkgdbKey)(dbiIndex dbi, dbiCursor dbc); - - rpmRC (*idxdbGet)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexSet *set, int curFlags); -- rpmRC (*idxdbPut)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec); -- rpmRC (*idxdbDel)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec); -+ rpmRC (*idxdbPut)(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); -+ rpmRC (*idxdbDel)(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); - const void * (*idxdbKey)(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen); - }; - -+#if defined(WITH_BDB) - RPM_GNUC_INTERNAL - extern struct rpmdbOps_s db3_dbops; -+#endif - --#ifdef ENABLE_NDB -+#if defined(WITH_BDB_RO) - RPM_GNUC_INTERNAL --extern struct rpmdbOps_s ndb_dbops; -+extern struct rpmdbOps_s bdbro_dbops; - #endif - --#if defined(WITH_LMDB) -+#ifdef ENABLE_NDB - RPM_GNUC_INTERNAL --extern struct rpmdbOps_s lmdb_dbops; -+extern struct rpmdbOps_s ndb_dbops; - #endif - - #if defined(WITH_SQLITE) -@@ -280,6 +290,9 @@ RPM_GNUC_INTERNAL - extern struct rpmdbOps_s sqlite_dbops; - #endif - -+RPM_GNUC_INTERNAL -+extern struct rpmdbOps_s dummydb_dbops; -+ - #ifdef __cplusplus - } - #endif -diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c -index 297f97f..7c2de45 100644 ---- a/lib/backend/sqlite.c -+++ b/lib/backend/sqlite.c -@@ -132,22 +132,14 @@ static int sqlite_init(rpmdb rdb, const char * dbhome) - char *dbfile = NULL; - - if (rdb->db_dbenv == NULL) { -- dbfile = rpmGenPath(dbhome, "rpmdb.sqlite", NULL); -+ dbfile = rpmGenPath(dbhome, rdb->db_ops->path, NULL); - sqlite3 *sdb = NULL; - int xx, flags = 0; - int retry_open = 1; -- -- free(rdb->db_descr); -- rdb->db_descr = xstrdup("sqlite"); -- - if ((rdb->db_mode & O_ACCMODE) == O_RDONLY) - flags |= SQLITE_OPEN_READONLY; -- else { -- rpmlog(RPMLOG_ERR, -- _("unable to open sqlite database %s for writing, sqlite support is read-only\n"), dbfile); -- rc = RPMRC_FAIL; -- goto exit; -- } -+ else -+ flags |= (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); - - while (retry_open--) { - xx = sqlite3_open_v2(dbfile, &sdb, flags, NULL); -@@ -241,7 +233,6 @@ static int sqlexec(sqlite3 *sdb, const char *fmt, ...) - rpmlog(RPMLOG_DEBUG, "%s: %d\n", cmd, rc); - - sqlite3_free(cmd); -- sqlite3_free(err); - - return rc ? RPMRC_FAIL : RPMRC_OK; - } -@@ -395,10 +386,8 @@ exit: - - static void sqlite_SetFSync(rpmdb rdb, int enable) - { -- if (rdb->db_dbenv) { -- sqlexec(rdb->db_dbenv, -+ sqlexec(rdb->db_dbenv, - "PRAGMA synchronous = %s", enable ? "FULL" : "OFF"); -- } - } - - static int sqlite_Ctrl(rpmdb rdb, dbCtrlOp ctrl) -@@ -448,19 +437,52 @@ static dbiCursor sqlite_CursorFree(dbiIndex dbi, dbiCursor dbc) - return NULL; - } - --static rpmRC sqlite_pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum) -+static rpmRC sqlite_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) - { -- return RPMRC_FAIL; --} -+ int rc = 0; -+ dbiCursor dbwc = NULL; - --static rpmRC sqlite_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) --{ -- return RPMRC_FAIL; -+ /* Avoid trashing existing query cursor on header rewrite */ -+ if (hdrNum && *hdrNum) { -+ dbwc = dbiCursorInit(dbi, DBC_WRITE); -+ dbc = dbwc; -+ } -+ -+ if (!rc) { -+ rc = dbiCursorPrep(dbc, "INSERT OR REPLACE INTO '%q' VALUES(?, ?)", -+ dbi->dbi_file); -+ } -+ -+ if (!rc) -+ rc = dbiCursorBindPkg(dbc, *hdrNum, hdrBlob, hdrLen); -+ -+ if (!rc) -+ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; -+ -+ /* XXX rowid is a 64bit integer and could overflow hdrnum */ -+ if (rc == SQLITE_DONE && *hdrNum == 0) -+ *hdrNum = sqlite3_last_insert_rowid(dbc->sdb); -+ -+ rc = dbiCursorResult(dbc); -+ -+ if (dbwc) -+ dbiCursorFree(dbi, dbwc); -+ -+ return rc; - } - - static rpmRC sqlite_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) - { -- return RPMRC_FAIL; -+ int rc = dbiCursorPrep(dbc, "DELETE FROM '%q' WHERE hnum=?;", -+ dbi->dbi_file); -+ -+ if (!rc) -+ rc = dbiCursorBindPkg(dbc, hdrNum, NULL, 0); -+ -+ if (!rc) -+ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; -+ -+ return dbiCursorResult(dbc); - } - - static rpmRC sqlite_stepPkg(dbiCursor dbc, unsigned char **hdrBlob, unsigned int *hdrLen) -@@ -615,14 +637,39 @@ static rpmRC sqlite_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size - return rc; - } - --static rpmRC sqlite_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) -+static rpmRC sqlite_idxdbPutOne(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) -+{ -+ int rc = dbiCursorPrep(dbc, "INSERT INTO '%q' VALUES(?, ?, ?)", -+ dbi->dbi_file); -+ -+ if (!rc) -+ rc = dbiCursorBindIdx(dbc, keyp, keylen, rec); -+ -+ if (!rc) -+ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; -+ -+ return dbiCursorResult(dbc); -+} -+ -+static rpmRC sqlite_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) - { -- return RPMRC_FAIL; -+ return tag2index(dbi, rpmtag, hdrNum, h, sqlite_idxdbPutOne); - } - --static rpmRC sqlite_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) -+static rpmRC sqlite_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) - { -- return RPMRC_FAIL; -+ dbiCursor dbc = dbiCursorInit(dbi, DBC_WRITE); -+ int rc = dbiCursorPrep(dbc, "DELETE FROM '%q' WHERE hnum=?", dbi->dbi_file); -+ -+ if (!rc) -+ rc = dbiCursorBindPkg(dbc, hdrNum, NULL, 0); -+ -+ if (!rc) -+ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; -+ -+ rc = dbiCursorResult(dbc); -+ dbiCursorFree(dbi, dbc); -+ return rc; - } - - static const void * sqlite_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) -@@ -636,7 +683,12 @@ static const void * sqlite_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *k - return key; - } - -+ -+ - struct rpmdbOps_s sqlite_dbops = { -+ .name = "sqlite", -+ .path = "rpmdb.sqlite", -+ - .open = sqlite_Open, - .close = sqlite_Close, - .verify = sqlite_Verify, -@@ -650,7 +702,6 @@ struct rpmdbOps_s sqlite_dbops = { - .pkgdbDel = sqlite_pkgdbDel, - .pkgdbGet = sqlite_pkgdbGet, - .pkgdbKey = sqlite_pkgdbKey, -- .pkgdbNew = sqlite_pkgdbNew, - - .idxdbGet = sqlite_idxdbGet, - .idxdbPut = sqlite_idxdbPut, -diff --git a/lib/rpmdb.c b/lib/rpmdb.c -index 355cb08..cf5e6a7 100644 ---- a/lib/rpmdb.c -+++ b/lib/rpmdb.c -@@ -7,6 +7,8 @@ - #include - #include - #include -+#include -+#include - - #ifndef DYING /* XXX already in "system.h" */ - #include -@@ -32,6 +34,7 @@ - #include "lib/rpmdb_internal.h" - #include "lib/fprint.h" - #include "lib/header_internal.h" /* XXX for headerSetInstance() */ -+#include "lib/backend/dbi.h" - #include "lib/backend/dbiset.h" - #include "lib/misc.h" - #include "debug.h" -@@ -48,14 +51,6 @@ - #undef HTKEYTYPE - #undef HTDATATYPE - --typedef rpmRC (*idxfunc)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, -- dbiIndexItem rec); -- --static rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, -- unsigned int hdrNum, Header h, -- idxfunc idxupdate); -- --static rpmRC indexPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); - static rpmdb rpmdbUnlink(rpmdb db); - - static int buildIndexes(rpmdb db) -@@ -87,7 +82,7 @@ static int buildIndexes(rpmdb db) - for (int dbix = 0; dbix < db->db_ndbi; dbix++) { - dbiIndex dbi = db->db_indexes[dbix]; - if (dbi && (dbiFlags(dbi) & DBI_CREATED)) { -- rc += indexPut(dbi, db->db_tags[dbix], hdrNum, h); -+ rc += idxdbPut(dbi, db->db_tags[dbix], hdrNum, h); - } - } - } -@@ -305,6 +300,7 @@ struct rpmdbIndexIterator_s { - dbiCursor ii_dbc; - dbiIndexSet ii_set; - unsigned int *ii_hdrNums; -+ int ii_skipdata; - }; - - static rpmdb rpmdbRock; -@@ -355,17 +351,22 @@ const char *rpmdbHome(rpmdb db) - return dbdir; - } - --int rpmdbOpenAll(rpmdb db) -+static int doOpen(rpmdb db, int justPkgs) - { -- int rc = 0; -+ int rc = pkgdbOpen(db, db->db_flags, NULL); -+ if (!justPkgs) { -+ for (int dbix = 0; rc == 0 && dbix < db->db_ndbi; dbix++) { -+ rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL); -+ } -+ } -+ return rc; -+} - -+int rpmdbOpenAll(rpmdb db) -+{ - if (db == NULL) return -2; - -- rc = pkgdbOpen(db, db->db_flags, NULL); -- for (int dbix = 0; dbix < db->db_ndbi; dbix++) { -- rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL); -- } -- return rc; -+ return doOpen(db, 0); - } - - static int dbiForeach(dbiIndex *dbis, int ndbi, -@@ -415,7 +416,6 @@ int rpmdbClose(rpmdb db) - db->db_fullpath = _free(db->db_fullpath); - db->db_checked = dbChkFree(db->db_checked); - db->db_indexes = _free(db->db_indexes); -- db->db_descr = _free(db->db_descr); - - if (next) { - *prev = next->db_next; -@@ -480,7 +480,6 @@ static rpmdb newRpmdb(const char * root, const char * home, - db->db_tags = dbiTags; - db->db_ndbi = sizeof(dbiTags) / sizeof(rpmDbiTag); - db->db_indexes = xcalloc(db->db_ndbi, sizeof(*db->db_indexes)); -- db->db_descr = xstrdup("unknown db"); - db->nrefs = 0; - return rpmdbLink(db); - } -@@ -508,13 +507,18 @@ static int openDatabase(const char * prefix, - /* Try to ensure db home exists, error out if we can't even create */ - rc = rpmioMkpath(rpmdbHome(db), 0755, getuid(), getgid()); - if (rc == 0) { -+ /* Open just bare minimum when rebuilding a potentially damaged db */ -+ int justPkgs = (db->db_flags & RPMDB_FLAG_REBUILD) && -+ ((db->db_mode & O_ACCMODE) == O_RDONLY); - /* Enable signal queue on the first db open */ - if (db->db_next == NULL) { - rpmsqActivate(1); - } - -- /* Just the primary Packages database opened here */ -- rc = pkgdbOpen(db, db->db_flags, NULL); -+ rc = doOpen(db, justPkgs); -+ -+ if (!db->db_descr) -+ db->db_descr = "unknown db"; - } - - if (rc || justCheck || dbp == NULL) -@@ -552,10 +556,7 @@ int rpmdbInit (const char * prefix, int perms) - - rc = openDatabase(prefix, NULL, &db, (O_CREAT | O_RDWR), perms, 0); - if (db != NULL) { -- int xx; -- xx = rpmdbOpenAll(db); -- if (xx && rc == 0) rc = xx; -- xx = rpmdbClose(db); -+ int xx = rpmdbClose(db); - if (xx && rc == 0) rc = xx; - db = NULL; - } -@@ -571,8 +572,6 @@ int rpmdbVerify(const char * prefix) - - if (db != NULL) { - int xx; -- rc = rpmdbOpenAll(db); -- - - if (db->db_pkgs) - rc += dbiVerify(db->db_pkgs, 0); -@@ -979,7 +978,7 @@ static int miFreeHeader(rpmdbMatchIterator mi, dbiIndex dbi) - if (hdrBlob != NULL && rpmrc != RPMRC_FAIL) { - rpmsqBlock(SIG_BLOCK); - dbCtrl(mi->mi_db, DB_CTRL_LOCK_RW); -- rc = pkgdbPut(dbi, mi->mi_dbc, mi->mi_prevoffset, -+ rc = pkgdbPut(dbi, mi->mi_dbc, &mi->mi_prevoffset, - hdrBlob, hdrLen); - dbCtrl(mi->mi_db, DB_CTRL_INDEXSYNC); - dbCtrl(mi->mi_db, DB_CTRL_UNLOCK_RW); -@@ -1588,6 +1587,7 @@ int rpmdbExtendIterator(rpmdbMatchIterator mi, - dbiIndexSetAppendSet(mi->mi_set, set, 0); - dbiIndexSetFree(set); - } -+ mi->mi_sorted = 0; - rc = 0; - } - -@@ -1649,6 +1649,7 @@ int rpmdbAppendIterator(rpmdbMatchIterator mi, - - for (unsigned int i = 0; i < nHdrNums; i++) - dbiIndexSetAppendOne(mi->mi_set, hdrNums[i], 0, 0); -+ mi->mi_sorted = 0; - return 0; - } - -@@ -1891,6 +1892,13 @@ rpmdbIndexIterator rpmdbIndexIteratorInit(rpmdb db, rpmDbiTag rpmtag) - return ii; - } - -+rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag) -+{ -+ rpmdbIndexIterator ki = rpmdbIndexIteratorInit(db, rpmtag); -+ ki->ii_skipdata = 1; -+ return ki; -+} -+ - int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * keylen) - { - int rc; -@@ -1905,7 +1913,8 @@ int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * ke - /* free old data */ - ii->ii_set = dbiIndexSetFree(ii->ii_set); - -- rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0, &ii->ii_set, DBC_NORMAL_SEARCH); -+ rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0, -+ ii->ii_skipdata ? NULL : &ii->ii_set, DBC_NORMAL_SEARCH); - - *key = idxdbKey(ii->ii_dbi, ii->ii_dbc, &iikeylen); - *keylen = iikeylen; -@@ -1973,7 +1982,7 @@ unsigned int rpmdbIndexIteratorPkgOffset(rpmdbIndexIterator ii, unsigned int nr) - return dbiIndexRecordOffset(ii->ii_set, nr); - } - --unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii) -+const unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii) - { - int i; - -@@ -2042,11 +2051,6 @@ static void logAddRemove(const char *dbiname, int removing, rpmtd tagdata) - } - } - --static rpmRC indexDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) --{ -- return tag2index(dbi, rpmtag, hdrNum, h, idxdbDel); --} -- - int rpmdbRemove(rpmdb db, unsigned int hdrNum) - { - dbiIndex dbi = NULL; -@@ -2088,7 +2092,7 @@ int rpmdbRemove(rpmdb db, unsigned int hdrNum) - if (indexOpen(db, rpmtag, 0, &dbi)) - continue; - -- ret += indexDel(dbi, rpmtag, hdrNum, h); -+ ret += idxdbDel(dbi, rpmtag, hdrNum, h); - } - } - -@@ -2185,7 +2189,7 @@ static rpmRC updateRichDep(dbiIndex dbi, dbiCursor dbc, const char *str, - return rc; - } - --static rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, -+rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, - unsigned int hdrNum, Header h, - idxfunc idxupdate) - { -@@ -2244,8 +2248,8 @@ static rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, - case RPMTAG_REQUIRENAME: { - /* Filter out install prerequisites. */ - rpm_flag_t *rflag = rpmtdNextUint32(&reqflags); -- if (rflag && isInstallPreReq(*rflag) && -- !isErasePreReq(*rflag)) -+ if (rflag && isInstallPreReq(*rflag) && -+ !isErasePreReq(*rflag)) - continue; - break; - } -@@ -2295,11 +2299,6 @@ exit: - return (rc == 0) ? RPMRC_OK : RPMRC_FAIL; - } - --static rpmRC indexPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) --{ -- return tag2index(dbi, rpmtag, hdrNum, h, idxdbPut); --} -- - int rpmdbAdd(rpmdb db, Header h) - { - dbiIndex dbi = NULL; -@@ -2327,9 +2326,7 @@ int rpmdbAdd(rpmdb db, Header h) - - /* Add header to primary index */ - dbc = dbiCursorInit(dbi, DBC_WRITE); -- ret = pkgdbNew(dbi, dbc, &hdrNum); -- if (ret == 0) -- ret = pkgdbPut(dbi, dbc, hdrNum, hdrBlob, hdrLen); -+ ret = pkgdbPut(dbi, dbc, &hdrNum, hdrBlob, hdrLen); - dbiCursorFree(dbi, dbc); - - /* Add associated data to secondary indexes */ -@@ -2340,7 +2337,7 @@ int rpmdbAdd(rpmdb db, Header h) - if (indexOpen(db, rpmtag, 0, &dbi)) - continue; - -- ret += indexPut(dbi, rpmtag, hdrNum, h); -+ ret += idxdbPut(dbi, rpmtag, hdrNum, h); - } - } - -@@ -2487,7 +2484,8 @@ static int rpmdbSetPermissions(char * src, char * dest) - } - - int rpmdbRebuild(const char * prefix, rpmts ts, -- rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg)) -+ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg), -+ int rebuildflags) - { - rpmdb olddb; - char * dbpath = NULL; -@@ -2527,7 +2525,9 @@ int rpmdbRebuild(const char * prefix, rpmts ts, - } - - if (openDatabase(prefix, dbpath, &olddb, -- O_RDONLY, 0644, RPMDB_FLAG_REBUILD)) { -+ O_RDONLY, 0644, RPMDB_FLAG_REBUILD | -+ (rebuildflags & RPMDB_REBUILD_FLAG_SALVAGE ? -+ RPMDB_FLAG_SALVAGE : 0))) { - rc = 1; - goto exit; - } -@@ -2536,10 +2536,6 @@ int rpmdbRebuild(const char * prefix, rpmts ts, - rc = 1; - goto exit; - } -- if (rpmdbOpenAll(newdb)) { -- rc = 1; -- goto exit; -- } - - { Header h = NULL; - rpmdbMatchIterator mi; -@@ -2584,6 +2580,7 @@ int rpmdbRebuild(const char * prefix, rpmts ts, - } - - rpmdbClose(olddb); -+ dbCtrl(newdb, DB_CTRL_INDEXSYNC); - rpmdbClose(newdb); - - if (failed) { -@@ -2644,3 +2641,50 @@ int rpmdbCtrl(rpmdb db, rpmdbCtrlOp ctrl) - return dbctrl ? dbCtrl(db, dbctrl) : 1; - } - -+char *rpmdbCookie(rpmdb db) -+{ -+ void *cookie = NULL; -+ rpmdbIndexIterator ii = rpmdbIndexIteratorInit(db, RPMDBI_NAME); -+ -+ if (ii) { -+ DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); -+ const void *key = 0; -+ size_t keylen = 0; -+ while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) { -+ const unsigned int *offsets = rpmdbIndexIteratorPkgOffsets(ii); -+ unsigned int npkgs = rpmdbIndexIteratorNumPkgs(ii); -+ rpmDigestUpdate(ctx, key, keylen); -+ rpmDigestUpdate(ctx, offsets, sizeof(*offsets) * npkgs); -+ } -+ rpmDigestFinal(ctx, &cookie, NULL, 1); -+ } -+ rpmdbIndexIteratorFree(ii); -+ return cookie; -+} -+ -+int rpmdbFStat(rpmdb db, struct stat *statbuf) -+{ -+ int rc = -1; -+ if (db) { -+ const char *dbfile = db->db_ops->path; -+ if (dbfile) { -+ char *path = rpmGenPath(rpmdbHome(db), dbfile, NULL); -+ rc = stat(path, statbuf); -+ free(path); -+ } -+ } -+ return rc; -+} -+ -+int rpmdbStat(const char *prefix, struct stat *statbuf) -+{ -+ rpmdb db = NULL; -+ int flags = RPMDB_FLAG_VERIFYONLY; -+ int rc = -1; -+ -+ if (openDatabase(prefix, NULL, &db, O_RDONLY, 0644, flags) == 0) { -+ rc = rpmdbFStat(db, statbuf); -+ rpmdbClose(db); -+ } -+ return rc; -+} -diff --git a/lib/rpmdb.h b/lib/rpmdb.h -index 78765bb..8e3ab5a 100644 ---- a/lib/rpmdb.h -+++ b/lib/rpmdb.h -@@ -8,6 +8,7 @@ - - #include - #include -+#include - - #ifdef __cplusplus - extern "C" { -@@ -152,6 +153,14 @@ Header rpmdbNextIterator(rpmdbMatchIterator mi); - */ - rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); - -+/** \ingroup rpmdb -+ * Get an iterator for index keys -+ * @param db rpm database -+ * @param rpmtag the index to iterate over -+ * @return the index iterator -+ */ -+rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag); -+ - /** \ingroup rpmdb - * Get an iterator for an index - * @param db rpm database -@@ -218,6 +227,30 @@ rpmdbIndexIterator rpmdbIndexIteratorFree(rpmdbIndexIterator ii); - */ - int rpmdbCtrl(rpmdb db, rpmdbCtrlOp ctrl); - -+/** \ingroup rpmdb -+ * Retrieve rpm database changed-cookie. -+ * Useful for eg. determining cache validity. -+ * @param db rpm database -+ * @return cookie string (malloced), or NULL on error -+ */ -+char *rpmdbCookie(rpmdb db); -+ -+/** \ingroup rpmdb -+ * Perform stat() on rpm database -+ * @param prefix prefix or NULL for / -+ * @retval statbuf returned data from stat() -+ * @return 0 on success, -1 on error -+ */ -+int rpmdbStat(const char *prefix, struct stat *statbuf); -+ -+/** \ingroup rpmdb -+ * Perform stat() on an open rpm database -+ * @param db rpm database -+ * @retval statbuf returned data from stat() -+ * @return 0 on success, -1 on error -+ */ -+int rpmdbFStat(rpmdb db, struct stat *statbuf); -+ - #ifdef __cplusplus - } - #endif -diff --git a/lib/rpmdb_internal.h b/lib/rpmdb_internal.h -index 92848ab..d7446e5 100644 ---- a/lib/rpmdb_internal.h -+++ b/lib/rpmdb_internal.h -@@ -23,6 +23,10 @@ extern "C" { - #undef HTKEYTYPE - #undef HTDATATYPE - -+enum rpmdbRebuildFlags_e { -+ RPMDB_REBUILD_FLAG_SALVAGE = (1 << 0), -+}; -+ - /** \ingroup rpmdb - * Reference a database instance. - * @param db rpm database -@@ -63,11 +67,13 @@ int rpmdbClose (rpmdb db); - * @param prefix path to top of install tree - * @param ts transaction set (or NULL) - * @param (*hdrchk) headerCheck() vector (or NULL) -+ * @param rebuildflags flags - * @return 0 on success - */ - RPM_GNUC_INTERNAL - int rpmdbRebuild(const char * prefix, rpmts ts, -- rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg)); -+ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg), -+ int rebuildflags); - - /** \ingroup rpmdb - * Verify database components. -@@ -175,7 +181,7 @@ rpmdbMatchIterator rpmdbInitPrefixIterator(rpmdb db, rpmDbiTagVal rpmtag, - * @return db offsets of pkgs - */ - RPM_GNUC_INTERNAL --unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii); -+const unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii); - - /** \ingroup rpmdb - * Return current index (position) in iterator. -diff --git a/lib/rpmts.c b/lib/rpmts.c -index 7131b7b..122a2ff 100644 ---- a/lib/rpmts.c -+++ b/lib/rpmts.c -@@ -135,17 +135,21 @@ int rpmtsRebuildDB(rpmts ts) - { - int rc = -1; - rpmtxn txn = NULL; -+ int rebuildflags = 0; - - /* Cannot do this on a populated transaction set */ - if (rpmtsNElements(ts) > 0) - return -1; - -+ if (rpmExpandNumeric("%{?_rebuilddb_salvage}")) -+ rebuildflags |= RPMDB_REBUILD_FLAG_SALVAGE; -+ - txn = rpmtxnBegin(ts, RPMTXN_WRITE); - if (txn) { - if (!(ts->vsflags & RPMVSF_NOHDRCHK)) -- rc = rpmdbRebuild(ts->rootDir, ts, headerCheck); -+ rc = rpmdbRebuild(ts->rootDir, ts, headerCheck, rebuildflags); - else -- rc = rpmdbRebuild(ts->rootDir, NULL, NULL); -+ rc = rpmdbRebuild(ts->rootDir, NULL, NULL, rebuildflags); - rpmtxnEnd(txn); - } - return rc; -diff --git a/macros.in b/macros.in -index fa2c29b..a0f7b13 100644 ---- a/macros.in -+++ b/macros.in -@@ -629,7 +629,7 @@ package or when debugging this package.\ - # ndb new data base format - # sqlite Sqlite database (read-only in this version!) - # --%_db_backend bdb -+%_db_backend sqlite - - # - # Macros used to configure Berkley db parameters. -diff --git a/rpmdb.c b/rpmdb.c -index 25c088d..b72f0a5 100644 ---- a/rpmdb.c -+++ b/rpmdb.c -@@ -12,6 +12,7 @@ enum modes { - MODE_VERIFYDB = (1 << 2), - MODE_EXPORTDB = (1 << 3), - MODE_IMPORTDB = (1 << 4), -+ MODE_SALVAGEDB = (1 << 5), - }; - - static int mode = 0; -@@ -24,6 +25,8 @@ static struct poptOption dbOptsTable[] = { - NULL}, - { "verifydb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN), - &mode, MODE_VERIFYDB, N_("verify database files"), NULL}, -+ { "salvagedb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN), -+ &mode, MODE_SALVAGEDB, N_("salvage database"), NULL}, - { "exportdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_EXPORTDB, - N_("export database to stdout header list"), - NULL}, -@@ -108,8 +111,11 @@ int main(int argc, char *argv[]) - ec = rpmtsInitDB(ts, 0644); - break; - case MODE_REBUILDDB: -+ case MODE_SALVAGEDB: - { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}"); - rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags); -+ if (mode == MODE_SALVAGEDB) -+ rpmDefineMacro(NULL, "_rebuilddb_salvage 1", 0); - ec = rpmtsRebuildDB(ts); - rpmtsSetVSFlags(ts, ovsflags); - } break; --- -2.39.3 - diff --git a/1000-rpm-anolis-support-loongarch.patch b/1000-rpm-anolis-support-loongarch.patch deleted file mode 100644 index 350516e..0000000 --- a/1000-rpm-anolis-support-loongarch.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 0ff0feb65aa56ae673e0ec0554996a7ce2ff6a38 Mon Sep 17 00:00:00 2001 -From: chenguoqi -Date: Tue, 3 Aug 2021 07:35:19 +0000 -Subject: [PATCH] support loongarch for rpm - ---- - installplatform | 12 ++++++++++++ - lib/rpmrc.c | 6 ++++++ - rpmrc.in | 17 +++++++++++++++++ - 3 files changed, 35 insertions(+) - -diff --git a/installplatform b/installplatform -index 12339fc..74c50a2 100755 ---- a/installplatform -+++ b/installplatform -@@ -168,6 +168,18 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do - CANONARCH=mips64r6el - CANONCOLOR=3 - ;; -+ loongarch32) -+ ISANAME=loongarch -+ ISABITS=32 -+ CANONARCH=loongarch32 -+ CANONCOLOR=0 -+ ;; -+ loongarch64) -+ ISANAME=loongarch -+ ISABITS=64 -+ CANONARCH=loongarch64 -+ CANONCOLOR=3 -+ ;; - m68k) - ISANAME=m68k - ISABITS=32 -diff --git a/lib/rpmrc.c b/lib/rpmrc.c -index cada3f7..c4b13cc 100644 ---- a/lib/rpmrc.c -+++ b/lib/rpmrc.c -@@ -1241,6 +1241,12 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os) - } - # endif /* riscv */ - -+# if defined(__linux__) && defined(__loongarch64) -+ strcpy(un.machine, "loongarch64"); -+# elif defined(__linux__) && defined(__loongarch32) -+ strcpy(un.machine, "loongarch32"); -+# endif /* __loongarch64 */ -+ - # if defined(__GNUC__) && defined(__alpha__) - { - unsigned long amask, implver; -diff --git a/rpmrc.in b/rpmrc.in -index 3a5b1e6..425bb97 100644 ---- a/rpmrc.in -+++ b/rpmrc.in -@@ -67,6 +67,8 @@ optflags: mipsr6el -O2 -g - optflags: mips64r6 -O2 -g - optflags: mips64r6el -O2 -g - -+optflags: loongarch64 -O2 -g -+ - optflags: armv3l -O2 -g -march=armv3 - optflags: armv4b -O2 -g -march=armv4 - optflags: armv4l -O2 -g -march=armv4 -@@ -134,6 +136,9 @@ archcolor: mipsr6el 1 - archcolor: mips64r6 2 - archcolor: mips64r6el 2 - -+archcolor: loongarch32 1 -+archcolor: loongarch64 2 -+ - archcolor: m68k 1 - - archcolor: m68kmint 1 -@@ -252,6 +257,9 @@ arch_canon: mips64r6el: mips64r6el 21 - arch_canon: riscv: riscv64 22 - arch_canon: riscv64: riscv64 22 - -+arch_canon: loongarch32: loongarch32 25 -+arch_canon: loongarch64: loongarch64 26 -+ - ############################################################# - # Canonical OS names and numbers - -@@ -353,6 +361,9 @@ buildarchtranslate: mipsr6el: mipsr6el - buildarchtranslate: mips64r6: mips64r6 - buildarchtranslate: mips64r6el: mips64r6el - -+buildarchtranslate: loongarch32: loongarch32 -+buildarchtranslate: loongarch64: loongarch64 -+ - buildarchtranslate: m68k: m68k - - buildarchtranslate: atarist: m68kmint -@@ -442,6 +453,9 @@ arch_compat: mipsr6el: noarch - arch_compat: mips64r6: mipsr6 - arch_compat: mips64r6el: mipsr6el - -+arch_compat: loongarch32: noarch -+arch_compat: loongarch64: loongarch32 -+ - arch_compat: hppa2.0: hppa1.2 - arch_compat: hppa1.2: hppa1.1 - arch_compat: hppa1.1: hppa1.0 -@@ -577,6 +591,9 @@ buildarch_compat: mipsr6el: noarch - buildarch_compat: mips64r6: noarch - buildarch_compat: mips64r6el: noarch - -+buildarch_compat: loongarch32: noarch -+buildarch_compat: loongarch64: noarch -+ - buildarch_compat: armv4b: noarch - buildarch_compat: armv7l: armv6l - buildarch_compat: armv6l: armv5tejl --- -2.27.0 - diff --git a/2002-rpm-anolis-support-sw_64.patch b/2002-rpm-anolis-support-sw_64.patch deleted file mode 100644 index 0fdee40..0000000 --- a/2002-rpm-anolis-support-sw_64.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 8f1f102e29093740b8d0ebde97dbec84a2e36b73 Mon Sep 17 00:00:00 2001 -From: Weisson -Date: Thu, 18 Jan 2024 16:28:07 +0800 -Subject: [PATCH] update config utils to support sw. - -Signed-off-by: Weisson ---- - config.guess | 8 ++++++++ - config.sub | 2 ++ - 2 files changed, 10 insertions(+) - -diff --git a/config.guess b/config.guess -index f32079a..5fa922c 100755 ---- a/config.guess -+++ b/config.guess -@@ -921,6 +921,14 @@ EOF - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; -+ sw_64:Linux:*:*) -+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in -+ sw) UNAME_MACHINE=sw_64 ;; -+ esac -+ objdump --private-headers /bin/sh | grep -q ld.so.1 -+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi -+ echo ${UNAME_MACHINE}-sunway-linux-${LIBC} -+ exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; -diff --git a/config.sub b/config.sub -index 6759825..8273800 100755 ---- a/config.sub -+++ b/config.sub -@@ -238,6 +238,7 @@ case $basic_machine in - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ -+ | sw_64 \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ -@@ -314,6 +315,7 @@ case $basic_machine in - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ -+ | sw_64-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ --- -2.31.1 - diff --git a/2004-rpm-anolis-support-sw_64.patch b/2004-rpm-anolis-support-sw_64.patch deleted file mode 100644 index 0fdee40..0000000 --- a/2004-rpm-anolis-support-sw_64.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 8f1f102e29093740b8d0ebde97dbec84a2e36b73 Mon Sep 17 00:00:00 2001 -From: Weisson -Date: Thu, 18 Jan 2024 16:28:07 +0800 -Subject: [PATCH] update config utils to support sw. - -Signed-off-by: Weisson ---- - config.guess | 8 ++++++++ - config.sub | 2 ++ - 2 files changed, 10 insertions(+) - -diff --git a/config.guess b/config.guess -index f32079a..5fa922c 100755 ---- a/config.guess -+++ b/config.guess -@@ -921,6 +921,14 @@ EOF - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; -+ sw_64:Linux:*:*) -+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in -+ sw) UNAME_MACHINE=sw_64 ;; -+ esac -+ objdump --private-headers /bin/sh | grep -q ld.so.1 -+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi -+ echo ${UNAME_MACHINE}-sunway-linux-${LIBC} -+ exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; -diff --git a/config.sub b/config.sub -index 6759825..8273800 100755 ---- a/config.sub -+++ b/config.sub -@@ -238,6 +238,7 @@ case $basic_machine in - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ -+ | sw_64 \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ -@@ -314,6 +315,7 @@ case $basic_machine in - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ -+ | sw_64-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ --- -2.31.1 - diff --git a/3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch b/3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch deleted file mode 100644 index a17a373..0000000 --- a/3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b361ad80a41a07c62fc8f21cda534b35c971ace7 Mon Sep 17 00:00:00 2001 -From: Chunmei Xu -Date: Wed, 6 Sep 2023 11:11:11 +0800 -Subject: [PATCH] avoid dead loop in db3_dbiOpen when db_create failed - -Signed-off-by: Chunmei Xu ---- - lib/backend/db3.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/lib/backend/db3.c b/lib/backend/db3.c -index da50dfd..24fbe00 100644 ---- a/lib/backend/db3.c -+++ b/lib/backend/db3.c -@@ -899,6 +899,8 @@ static int db3_dbiOpen(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flag - db->close(db, 0); - db = NULL; - } -+ } else { -+ retry_open--; - } - } - --- -2.39.3 - diff --git a/brp-python-bytecompile-compatibility-with-newer-pyth.patch b/brp-python-bytecompile-compatibility-with-newer-pyth.patch new file mode 100644 index 0000000..ebe7230 --- /dev/null +++ b/brp-python-bytecompile-compatibility-with-newer-pyth.patch @@ -0,0 +1,46 @@ +From acbf558c486ee3518aca74045504f05872da4a58 Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Tue, 26 Sep 2023 13:14:44 +0200 +Subject: [PATCH] brp-python-bytecompile compatibility with newer pythons + +--- + scripts/brp-python-bytecompile | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile +index 4a9b49e..472bf10 100644 +--- a/scripts/brp-python-bytecompile ++++ b/scripts/brp-python-bytecompile +@@ -58,7 +58,7 @@ EOF + # and below /usr/lib/python3.1/, we're targeting /usr/bin/python3.1 + + shopt -s nullglob +-for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]$"`; ++for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]+$"`; + do + python_binary=/usr/bin/$(basename $python_libdir) + if [ "$python_binary" = "/usr/bin/python3.6" ]; then +@@ -97,17 +97,17 @@ fi + + # Figure out if there are files to be bytecompiled with the default_python at all + # this prevents unnecessary default_python invocation +-find "$RPM_BUILD_ROOT" -type f -name "*.py" | grep -Ev "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" || exit 0 ++find "$RPM_BUILD_ROOT" -type f -name "*.py" | grep -Ev "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]+|/usr/share/doc" || exit 0 + + # Generate normal (.pyc) byte-compiled files. +-python_bytecompile "" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" ++python_bytecompile "" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]+|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" + if [ $? -ne 0 -a 0$errors_terminate -ne 0 ]; then + # One or more of the files had a syntax error + exit 1 + fi + + # Generate optimized (.pyo) byte-compiled files. +-python_bytecompile "-O" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" ++python_bytecompile "-O" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]+|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" + if [ $? -ne 0 -a 0$errors_terminate -ne 0 ]; then + # One or more of the files had a syntax error + exit 1 +-- +2.41.0 + diff --git a/rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch b/rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch deleted file mode 100644 index 16f0d82..0000000 --- a/rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4c18e2a55783adc416834c86a6ed8491d8347236 Mon Sep 17 00:00:00 2001 -From: Weisson -Date: Tue, 28 May 2024 15:24:55 +0800 -Subject: [PATCH] Fix compatibility of debugedit tool on sw_64 platform. - -Signed-off-by: Weisson ---- - system.h | 4 ++++ - tools/debugedit.c | 4 ++++ - 2 files changed, 8 insertions(+) - -diff --git a/system.h b/system.h -index a8f3043..666ab5e 100644 ---- a/system.h -+++ b/system.h -@@ -136,4 +136,8 @@ extern int fdatasync(int fildes); - # endif - #endif - -+#ifndef R_SW_64_REFLONG -+# define R_SW_64_REFLONG 1 -+#endif -+ - #endif /* H_SYSTEM */ -diff --git a/tools/debugedit.c b/tools/debugedit.c -index 1d1c808..759ce26 100644 ---- a/tools/debugedit.c -+++ b/tools/debugedit.c -@@ -581,6 +581,10 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype) - if (rtype != R_ALPHA_REFLONG) - goto fail; - break; -+ case EM_SW_64: -+ if (rtype != R_SW_64_REFLONG) -+ goto fail; -+ break; - #if defined(EM_AARCH64) && defined(R_AARCH64_ABS32) - case EM_AARCH64: - if (rtype != R_AARCH64_ABS32) --- -1.8.3.1 - diff --git a/rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch b/rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch deleted file mode 100644 index 8902a97..0000000 --- a/rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 38131090ed022d9e133ccf601004e7ec1745d87c Mon Sep 17 00:00:00 2001 -From: Weisson -Date: Mon, 8 Apr 2024 14:59:22 +0800 -Subject: [PATCH] keep compatibility between sw and other architecture. - -Signed-off-by: Weisson ---- - system.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/system.h b/system.h -index 570cef1..a8f3043 100644 ---- a/system.h -+++ b/system.h -@@ -127,4 +127,13 @@ extern int fdatasync(int fildes); - - #include - -+/* ============= for sw arch compatibility ======== */ -+#ifndef EM_SW_64 -+# ifndef SW_64 -+# define EM_SW_64 0x9916 -+# else -+# define EM_SW_64 0x9906 -+# endif -+#endif -+ - #endif /* H_SYSTEM */ --- -2.39.3 - diff --git a/rpm-4.14.3-sw.patch b/rpm-4.14.3-sw.patch deleted file mode 100644 index e227134..0000000 --- a/rpm-4.14.3-sw.patch +++ /dev/null @@ -1,119 +0,0 @@ -diff -Naur rpm-4.14.3.org/installplatform rpm-4.14.3.sw/installplatform ---- rpm-4.14.3.org/installplatform 2023-05-11 17:16:20.818506688 +0800 -+++ rpm-4.14.3.sw/installplatform 2023-05-12 14:44:13.520745718 +0800 -@@ -114,6 +114,12 @@ - CANONARCH=alpha - CANONCOLOR=0 - ;; -+ sw_64*) -+ ISANAME=sw_64 -+ ISABITS=64 -+ CANONARCH=sw_64 -+ CANONCOLOR=0 -+ ;; - aarch64) - ISANAME=aarch - ISABITS=64 -diff -Naur rpm-4.14.3.org/lib/rpmrc.c rpm-4.14.3.sw/lib/rpmrc.c ---- rpm-4.14.3.org/lib/rpmrc.c 2023-05-11 17:16:20.794506687 +0800 -+++ rpm-4.14.3.sw/lib/rpmrc.c 2023-05-12 17:30:27.072394959 +0800 -@@ -1247,6 +1247,13 @@ - strcpy(un.machine, "loongarch32"); - # endif /* __loongarch64 */ - -+ -+# if defined(__GNUC__) && defined(__alpha__) -+ { -+ strcpy(un.machine, "sw_64sw6b"); -+ } -+# endif -+ - # if defined(__GNUC__) && defined(__alpha__) - { - unsigned long amask, implver; -diff -Naur rpm-4.14.3.org/macros.in rpm-4.14.3.sw/macros.in ---- rpm-4.14.3.org/macros.in 2023-05-11 17:16:20.813506688 +0800 -+++ rpm-4.14.3.sw/macros.in 2023-05-12 14:54:53.461787376 +0800 -@@ -1154,6 +1154,10 @@ - %sparc sparc sparcv8 sparcv9 sparcv9v sparc64 sparc64v - - #------------------------------------------------------------------------------ -+# arch macro for all supported Sw_64 processors -+%sw_64 sw_64 sw_64sw6b -+ -+#------------------------------------------------------------------------------ - # arch macro for all supported Alpha processors - %alpha alpha alphaev56 alphaev6 alphaev67 - -diff -Naur rpm-4.14.3.org/rpmrc.in rpm-4.14.3.sw/rpmrc.in ---- rpm-4.14.3.org/rpmrc.in 2023-05-11 17:16:20.704506681 +0800 -+++ rpm-4.14.3.sw/rpmrc.in 2023-05-11 17:26:48.130547524 +0800 -@@ -25,6 +25,9 @@ - optflags: amd64 -O2 -g - optflags: ia32e -O2 -g - -+optflags: sw_64 -O2 -g -mieee -+optflags: sw_64sw6b -O2 -g -mieee -mtune=sw6b -+ - optflags: alpha -O2 -g -mieee - optflags: alphaev5 -O2 -g -mieee -mtune=ev5 - optflags: alphaev56 -O2 -g -mieee -mtune=ev56 -@@ -110,6 +113,7 @@ - archcolor: noarch 0 - archcolor: i386 1 - archcolor: alpha 2 -+archcolor: sw_64 2 - archcolor: sparc 1 - archcolor: sparc64 2 - archcolor: sparcv9 2 -@@ -173,6 +177,9 @@ - arch_canon: ia32e: ia32e 1 - arch_canon: em64t: em64t 1 - -+arch_canon: sw_64: sw_64 2 -+arch_canon: sw_64sw6b: sw_64sw6b 2 -+ - arch_canon: alpha: alpha 2 - arch_canon: alphaev5: alphaev5 2 - arch_canon: alphaev56: alphaev56 2 -@@ -310,6 +317,9 @@ - buildarchtranslate: i486: i386 - buildarchtranslate: i386: i386 - -+buildarchtranslate: sw_64: sw_64 -+buildarchtranslate: sw_64sw6b: sw_64 -+ - buildarchtranslate: alphaev5: alpha - buildarchtranslate: alphaev56: alpha - buildarchtranslate: alphapca56: alpha -@@ -402,6 +412,9 @@ - arch_compat: alphaev5: alpha - arch_compat: alpha: axp noarch - -+arch_compat: sw_64sw6b: sw_64 -+arch_compat: sw_64: axp noarch -+ - arch_compat: athlon: i686 - arch_compat: geode: i686 - arch_compat: pentium4: pentium3 -@@ -567,6 +580,9 @@ - buildarch_compat: alphaev5: alpha - buildarch_compat: alpha: noarch - -+buildarch_compat: sw_64sw6b: sw_64 -+buildarch_compat: sw_64: noarch -+ - buildarch_compat: m68k: noarch - - buildarch_compat: ppc8260: noarch -diff -Naur rpm-4.14.3.org/tools/elfdeps.c rpm-4.14.3.sw/tools/elfdeps.c ---- rpm-4.14.3.org/tools/elfdeps.c 2023-05-11 17:16:20.820506688 +0800 -+++ rpm-4.14.3.sw/tools/elfdeps.c 2023-05-12 14:45:04.537749039 +0800 -@@ -86,6 +86,7 @@ - if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) { - switch (ehdr->e_machine) { - case EM_ALPHA: -+ case EM_SW_64: - case EM_FAKE_ALPHA: - /* alpha doesn't traditionally have 64bit markers */ - break; diff --git a/rpm.spec b/rpm.spec index d17e0d0..a52c767 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,6 +1,3 @@ -%define anolis_release .0.9 - -%define _legacy_common_support 1 # build against xz? %bcond_without xz # just for giggles, option to build with internal Berkeley DB @@ -23,11 +20,8 @@ %bcond_with lmdb # build with readonly sqlite support? %bcond_without sqlite -# build with bdb_ro support? -# if enabled, rpmdb is switched to sqlite -%bcond_with bdb_ro -%if 0%{?rhel} > 7 || 0%{?anolis} +%if 0%{?rhel} > 7 # Disable python2 build by default %bcond_with python2 %else @@ -38,7 +32,7 @@ %global rpmver 4.14.3 #global snapver rc2 -%global rel 27 +%global rel 31 %global srcver %{version}%{?snapver:-%{snapver}} %global srcdir %{?snapver:testing}%{!?snapver:%{name}-%(echo %{version} | cut -d'.' -f1-2).x} @@ -50,7 +44,7 @@ Summary: The RPM package management system Name: rpm Version: %{rpmver} -Release: %{?snapver:0.%{snapver}.}%{rel}%{anolis_release}%{?dist} +Release: %{?snapver:0.%{snapver}.}%{rel}%{?dist} Group: System Environment/Base Url: http://www.rpm.org/ Source0: http://ftp.rpm.org/releases/%{srcdir}/%{name}-%{srcver}.tar.bz2 @@ -125,28 +119,17 @@ Patch165: rpm-4.16.1.3-rpm2archive-error-handling.patch Patch166: rpm-4.14.3-rpm2archive-nocompression.patch Patch167: rpm-4.14.3-rpm2archive-parse-popt-options.patch Patch168: rpm-4.14.3-rpm2archive-Don-t-print-usage.patch -#https://github.com/rpm-software-management/rpm/commit/ddf56e678676abb436906ada650680c8c13c4a3c +# Backport fsm to fix CVEs Patch169: 0001-Eliminate-code-duplication-from-rpmfiNext.patch -#https://github.com/rpm-software-management/rpm/commit/fb13f7fd9eff012cb7b9dbf94ac5381c69404055 Patch170: 0001-Add-optional-callback-on-directory-changes-during-rp.patch -#https://github.com/rpm-software-management/rpm/commit/35195684d29f495bfd982516044e05deed832b6e Patch171: 0001-Pass-file-descriptor-to-file-prepare-plugin-hook-use.patch -#https://github.com/rpm-software-management/rpm/commit/6dd62720fe84f7e2ad902c915b952fc0b29e3dcd Patch172: 0001-Swap-over-to-dirfd-basename-based-operation-within-t.patch -#https://github.com/rpm-software-management/rpm/commit/2668a2cabfe097d58adb9810da1cc8aa7fe1cc91 -#https://github.com/rpm-software-management/rpm/commit/930650a9377ce72b51d56c94f0d077608d6b839e -#https://github.com/rpm-software-management/rpm/commit/1c98b67911e19a5f92c7fa4492aaa1000a06edad Patch173: 0001-Use-file-state-machine-from-rpm-4.19.patch -#https://github.com/rpm-software-management/rpm/commit/c140768202e271b60910644c1e4bf848a50218d3 Patch174: 0001-Emit-full-paths-for-file-disposition-diagnostics-on-.patch -#https://github.com/rpm-software-management/rpm/commit/89ce4e7ca592f5abafc3f25aeaa07d36a7b43a61 Patch175: 0001-Fix-wrong-return-code-on-O_DIRECTORY-open-of-invalid.patch -#https://github.com/rpm-software-management/rpm/commit/dcf8c5abc64eb0fe3c81482008b8a13bec19eb20 Patch176: 0001-Print-full-path-if-file-removal-fails.patch -#https://github.com/rpm-software-management/rpm/commit/6c66abd34cccbb5b3c063f8f613e0c2faffc415f Patch177: 0001-Don-t-warn-about-missing-user-group-on-skipped-files.patch - # Python 3 string API sanity Patch500: 0001-In-Python-3-return-all-our-string-data-as-surrogate-.patch Patch501: 0001-Return-NULL-string-as-None-from-utf8FromString.patch @@ -177,21 +160,8 @@ Patch1000: disable-python-extra.patch Patch1001: compile-with-Platform-Python-binary-where-relevant.patch # make unversioned %%__python an error unless explicitly overridden Patch1002: rpm-4.14.2-unversioned-python.patch - -Patch2000: 1000-rpm-anolis-support-loongarch.patch -Patch2001: 0001-debugedit-add-loongarch-support.patch - -# bugfix for anolis -Patch3001: 3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch - -Patch3002: 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch - -# defined as source file to seperate with other patches -Source1000: 0001-support-sqlite-backend-rpmdb.patch -Patch2002: rpm-4.14.3-sw.patch -Patch2003: 2004-rpm-anolis-support-sw_64.patch -Patch2004: rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch -Patch2005: rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch +# Make brp-python-bytecompile compatible with Python 3.10+ +Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -266,7 +236,7 @@ BuildRequires: libubsan %endif %if %{with libimaevm} -%if 0%{?fedora} >= 28 || 0%{?rhel} > 7 || 0%{?anolis} +%if 0%{?fedora} >= 28 || 0%{?rhel} > 7 %global imadevname ima-evm-utils-devel %else %global imadevname ima-evm-utils @@ -474,10 +444,6 @@ Obsoletes: fapolicyd-dnf-plugin %prep %autosetup -n %{name}-%{srcver} %{?with_int_bdb:-a 1} -p1 -%if %{with bdb_ro} -patch -p1 < %{SOURCE1000} -%endif - %if %{with int_bdb} ln -s db-%{bdbver} db %endif @@ -522,7 +488,6 @@ done; %{?with_zstd: --enable-zstd} \ %{?with_lmdb: --enable-lmdb} \ %{?with_sqlite: --enable-sqlite} \ - %{?with_bdb_ro: --enable-bdb-ro} \ --with-fapolicyd \ --enable-python \ --with-crypto=openssl \ @@ -601,20 +566,6 @@ chmod a-x $RPM_BUILD_ROOT/%{rpmhome}/python-macro-helper make check || cat tests/rpmtests.log %endif -%if %{with bdb_ro} -%pre -# Only update -if [ $1 == 2 ] -then - [ -e /var/lib/rpm/.rpm.lock ] && rm -f /var/lib/rpm/.rpm.lock - [ `rpm --eval "%_db_backend"` == "bdb" ] && rpmdb --exportdb > /var/lib/rpm_bdb_bak -fi - -%posttrans -[ -e /var/lib/rpm/.rpm.lock ] && rm -f /var/lib/rpm/.rpm.lock -rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb -%endif - %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig @@ -760,44 +711,15 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb %doc doc/librpm/html/* %changelog -* Mon May 27 2024 Weisson - 4.14.4-27.0.9 -- Fix compatibility of debugedit tool on sw_64 platform. - -* Mon Apr 8 2024 Weisson - 4.14.4-27.0.8 -- keep compatibility between sw and other architecture. - -* Wed Mar 20 2024 Weisson - 4.14.4-27.0.7 -- update config to support sw64 Architecture. - -* Wed Mar 20 2024 hpp - 4.14.4-27.0.6 -- Add sw64 Architecture - -* Thu Feb 29 2024 Kaiqiang Wang - 4.14.4-27.0.5 +* Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, CVE-2021-35938 and CVE-2021-35939 -* Wed Jan 24 2024 Kaiqiang Wang - 4.14.4-26.0.5 -- Fix a copy-paste --help description of --whatconflicts -- https://bugzilla.openanolis.cn/show_bug.cgi?id=8035 - -* Thu Sep 07 2023 Chunmei Xu - 4.14.4-26.0.4 -- avoid dead loop in db3_dbiOpen when db_create failed -- do not switch rpmdb to sqlite - -* Tue Jul 25 2023 Liwei Ge - 4.14.4-26.0.3 -- conditional set relbuf for loongarch debugedit - -* Thu Jun 29 2023 forrest_ly - 4.14.4-26.0.2 -- Support and switch rpmdb to sqlite - -* Wed Jun 14 2023 Liwei Ge - 4.14.4-26.0.1 -- Rebrand for Anolis OS -- Fix gcc10 -fno-common compile issue for compatible with gcc10 build -- Support loongarch for rpm -- Add loongarch64 support for debugedit(doupengda@loongson.cn) -- Modify the spec to add debugedit for loongarch64(zhangwenlong@loongson.cn) +* Tue Sep 26 2023 Lumír Balhar - 4.14.3-27 +- Make brp-python-bytecompile script compatible with Python 3.10+ +Resolves: RHEL-6423 -* Mon Dec 19 2022 Florian Festi - 4.14.4-26 +* Mon Dec 19 2022 Florian Festi - 4.14.3-26 - Add --nocompression to rpm2archive (#2129345) * Tue Sep 13 2022 Michal Domonkos - 4.14.3-24 -- Gitee From e77d730f7a4acb6d3c450b1341f6c4a9a415b552 Mon Sep 17 00:00:00 2001 From: songmingliang Date: Wed, 18 May 2022 14:31:33 +0800 Subject: [PATCH 02/15] Rebrand for Anolis OS --- rpm.spec | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rpm.spec b/rpm.spec index a52c767..add5629 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 # build against xz? %bcond_without xz # just for giggles, option to build with internal Berkeley DB @@ -21,7 +22,7 @@ # build with readonly sqlite support? %bcond_without sqlite -%if 0%{?rhel} > 7 +%if 0%{?rhel} > 7 || 0%{?anolis} # Disable python2 build by default %bcond_with python2 %else @@ -44,7 +45,7 @@ Summary: The RPM package management system Name: rpm Version: %{rpmver} -Release: %{?snapver:0.%{snapver}.}%{rel}%{?dist} +Release: %{?snapver:0.%{snapver}.}%{rel}%{anolis_release}%{?dist} Group: System Environment/Base Url: http://www.rpm.org/ Source0: http://ftp.rpm.org/releases/%{srcdir}/%{name}-%{srcver}.tar.bz2 @@ -236,7 +237,7 @@ BuildRequires: libubsan %endif %if %{with libimaevm} -%if 0%{?fedora} >= 28 || 0%{?rhel} > 7 +%if 0%{?fedora} >= 28 || 0%{?rhel} > 7 || 0%{?anolis} %global imadevname ima-evm-utils-devel %else %global imadevname ima-evm-utils @@ -711,6 +712,9 @@ make check || cat tests/rpmtests.log %doc doc/librpm/html/* %changelog +* Thu Jul 18 2024 Liwei Ge - 4.14.4-31.0.1 +- Rebrand for Anolis OS + * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, CVE-2021-35938 and CVE-2021-35939 -- Gitee From 2bd7a01aa7fd97b64a9aa42f0be8b8698d3e4790 Mon Sep 17 00:00:00 2001 From: songmingliang Date: Wed, 18 May 2022 14:39:39 +0800 Subject: [PATCH 03/15] Fix gcc10 -fno-common compile issue until upstream fixes --- rpm.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpm.spec b/rpm.spec index add5629..35b8a84 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,4 +1,5 @@ %define anolis_release .0.1 +%define _legacy_common_support 1 # build against xz? %bcond_without xz # just for giggles, option to build with internal Berkeley DB @@ -714,6 +715,7 @@ make check || cat tests/rpmtests.log %changelog * Thu Jul 18 2024 Liwei Ge - 4.14.4-31.0.1 - Rebrand for Anolis OS +- Fix gcc10 -fno-common compile issue for compatible with gcc10 build * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 278d8dec49d71b19f224306b5adf2323bab6f894 Mon Sep 17 00:00:00 2001 From: songmingliang Date: Wed, 18 May 2022 14:44:37 +0800 Subject: [PATCH 04/15] support loongarch --- 1000-rpm-anolis-support-loongarch.patch | 117 ++++++++++++++++++++++++ rpm.spec | 3 + 2 files changed, 120 insertions(+) create mode 100644 1000-rpm-anolis-support-loongarch.patch diff --git a/1000-rpm-anolis-support-loongarch.patch b/1000-rpm-anolis-support-loongarch.patch new file mode 100644 index 0000000..350516e --- /dev/null +++ b/1000-rpm-anolis-support-loongarch.patch @@ -0,0 +1,117 @@ +From 0ff0feb65aa56ae673e0ec0554996a7ce2ff6a38 Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Tue, 3 Aug 2021 07:35:19 +0000 +Subject: [PATCH] support loongarch for rpm + +--- + installplatform | 12 ++++++++++++ + lib/rpmrc.c | 6 ++++++ + rpmrc.in | 17 +++++++++++++++++ + 3 files changed, 35 insertions(+) + +diff --git a/installplatform b/installplatform +index 12339fc..74c50a2 100755 +--- a/installplatform ++++ b/installplatform +@@ -168,6 +168,18 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do + CANONARCH=mips64r6el + CANONCOLOR=3 + ;; ++ loongarch32) ++ ISANAME=loongarch ++ ISABITS=32 ++ CANONARCH=loongarch32 ++ CANONCOLOR=0 ++ ;; ++ loongarch64) ++ ISANAME=loongarch ++ ISABITS=64 ++ CANONARCH=loongarch64 ++ CANONCOLOR=3 ++ ;; + m68k) + ISANAME=m68k + ISABITS=32 +diff --git a/lib/rpmrc.c b/lib/rpmrc.c +index cada3f7..c4b13cc 100644 +--- a/lib/rpmrc.c ++++ b/lib/rpmrc.c +@@ -1241,6 +1241,12 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os) + } + # endif /* riscv */ + ++# if defined(__linux__) && defined(__loongarch64) ++ strcpy(un.machine, "loongarch64"); ++# elif defined(__linux__) && defined(__loongarch32) ++ strcpy(un.machine, "loongarch32"); ++# endif /* __loongarch64 */ ++ + # if defined(__GNUC__) && defined(__alpha__) + { + unsigned long amask, implver; +diff --git a/rpmrc.in b/rpmrc.in +index 3a5b1e6..425bb97 100644 +--- a/rpmrc.in ++++ b/rpmrc.in +@@ -67,6 +67,8 @@ optflags: mipsr6el -O2 -g + optflags: mips64r6 -O2 -g + optflags: mips64r6el -O2 -g + ++optflags: loongarch64 -O2 -g ++ + optflags: armv3l -O2 -g -march=armv3 + optflags: armv4b -O2 -g -march=armv4 + optflags: armv4l -O2 -g -march=armv4 +@@ -134,6 +136,9 @@ archcolor: mipsr6el 1 + archcolor: mips64r6 2 + archcolor: mips64r6el 2 + ++archcolor: loongarch32 1 ++archcolor: loongarch64 2 ++ + archcolor: m68k 1 + + archcolor: m68kmint 1 +@@ -252,6 +257,9 @@ arch_canon: mips64r6el: mips64r6el 21 + arch_canon: riscv: riscv64 22 + arch_canon: riscv64: riscv64 22 + ++arch_canon: loongarch32: loongarch32 25 ++arch_canon: loongarch64: loongarch64 26 ++ + ############################################################# + # Canonical OS names and numbers + +@@ -353,6 +361,9 @@ buildarchtranslate: mipsr6el: mipsr6el + buildarchtranslate: mips64r6: mips64r6 + buildarchtranslate: mips64r6el: mips64r6el + ++buildarchtranslate: loongarch32: loongarch32 ++buildarchtranslate: loongarch64: loongarch64 ++ + buildarchtranslate: m68k: m68k + + buildarchtranslate: atarist: m68kmint +@@ -442,6 +453,9 @@ arch_compat: mipsr6el: noarch + arch_compat: mips64r6: mipsr6 + arch_compat: mips64r6el: mipsr6el + ++arch_compat: loongarch32: noarch ++arch_compat: loongarch64: loongarch32 ++ + arch_compat: hppa2.0: hppa1.2 + arch_compat: hppa1.2: hppa1.1 + arch_compat: hppa1.1: hppa1.0 +@@ -577,6 +591,9 @@ buildarch_compat: mipsr6el: noarch + buildarch_compat: mips64r6: noarch + buildarch_compat: mips64r6el: noarch + ++buildarch_compat: loongarch32: noarch ++buildarch_compat: loongarch64: noarch ++ + buildarch_compat: armv4b: noarch + buildarch_compat: armv7l: armv6l + buildarch_compat: armv6l: armv5tejl +-- +2.27.0 + diff --git a/rpm.spec b/rpm.spec index 35b8a84..6a6d41d 100644 --- a/rpm.spec +++ b/rpm.spec @@ -165,6 +165,8 @@ Patch1002: rpm-4.14.2-unversioned-python.patch # Make brp-python-bytecompile compatible with Python 3.10+ Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch +Patch2000: 1000-rpm-anolis-support-loongarch.patch + # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD License: GPLv2+ @@ -716,6 +718,7 @@ make check || cat tests/rpmtests.log * Thu Jul 18 2024 Liwei Ge - 4.14.4-31.0.1 - Rebrand for Anolis OS - Fix gcc10 -fno-common compile issue for compatible with gcc10 build +- Support loongarch for rpm * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 45d7e3ee9f4a5543dc5b32bb922cff477c7e2145 Mon Sep 17 00:00:00 2001 From: doupengda Date: Mon, 5 Jun 2023 16:10:58 +0800 Subject: [PATCH 05/15] Add loongarch64 support for debugedit --- 0001-debugedit-add-loongarch-support.patch | 26 ++++++++++++++++++++++ rpm.spec | 1 + 2 files changed, 27 insertions(+) create mode 100644 0001-debugedit-add-loongarch-support.patch diff --git a/0001-debugedit-add-loongarch-support.patch b/0001-debugedit-add-loongarch-support.patch new file mode 100644 index 0000000..363ebfd --- /dev/null +++ b/0001-debugedit-add-loongarch-support.patch @@ -0,0 +1,26 @@ +From f5449c5534d9bfb526541d49b3caec4f76e12d1d Mon Sep 17 00:00:00 2001 +From: Huang Yang +Date: Mon, 20 Feb 2023 20:03:41 -0500 +Subject: [PATCH] debugedit add loongarch support + +--- + tools/debugedit.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/debugedit.c b/tools/debugedit.c +index 4ec431f..fb0325b 100644 +--- a/tools/debugedit.c ++++ b/tools/debugedit.c +@@ -597,6 +597,10 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype) + goto fail; + break; + #endif ++ case EM_LOONGARCH: ++ if ((rtype != R_LARCH_32) && (rtype != R_LARCH_64)) ++ goto fail; ++ break; + default: + fail: + error (1, 0, "%s: Unhandled relocation %d in %s section", +-- +2.27.0 diff --git a/rpm.spec b/rpm.spec index 6a6d41d..d6018e1 100644 --- a/rpm.spec +++ b/rpm.spec @@ -719,6 +719,7 @@ make check || cat tests/rpmtests.log - Rebrand for Anolis OS - Fix gcc10 -fno-common compile issue for compatible with gcc10 build - Support loongarch for rpm +- Add loongarch64 support for debugedit(doupengda@loongson.cn) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 08941824dea2308cdeec37dcf3d60a78c44d5d72 Mon Sep 17 00:00:00 2001 From: Wenlong Zhang Date: Tue, 6 Jun 2023 10:47:24 +0800 Subject: [PATCH 06/15] Modify the spec to add debugedit for loongarch64 Signed-off-by: Wenlong Zhang --- rpm.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpm.spec b/rpm.spec index d6018e1..f156b3d 100644 --- a/rpm.spec +++ b/rpm.spec @@ -166,6 +166,7 @@ Patch1002: rpm-4.14.2-unversioned-python.patch Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch Patch2000: 1000-rpm-anolis-support-loongarch.patch +Patch2001: 0001-debugedit-add-loongarch-support.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -720,6 +721,7 @@ make check || cat tests/rpmtests.log - Fix gcc10 -fno-common compile issue for compatible with gcc10 build - Support loongarch for rpm - Add loongarch64 support for debugedit(doupengda@loongson.cn) +- Modify the spec to add debugedit for loongarch64(zhangwenlong@loongson.cn) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From d6800dcc0d9df5eeba8645d846335fcc5b5a50fb Mon Sep 17 00:00:00 2001 From: forrest_ly Date: Thu, 29 Jun 2023 13:17:31 +0800 Subject: [PATCH 07/15] support and switch to sqlite backend rpmdb --- 0001-support-sqlite-backend-rpmdb.patch | 2094 +++++++++++++++++++++++ rpm.spec | 18 + 2 files changed, 2112 insertions(+) create mode 100644 0001-support-sqlite-backend-rpmdb.patch diff --git a/0001-support-sqlite-backend-rpmdb.patch b/0001-support-sqlite-backend-rpmdb.patch new file mode 100644 index 0000000..395badd --- /dev/null +++ b/0001-support-sqlite-backend-rpmdb.patch @@ -0,0 +1,2094 @@ +From 955c0f001792deaa95913f5cd7ccaca2d8b0298e Mon Sep 17 00:00:00 2001 +From: forrest_ly +Date: Wed, 28 Jun 2023 16:50:14 +0800 +Subject: [PATCH] support sqlite backend rpmdb + +--- + configure.ac | 14 + + lib/Makefile.am | 4 + + lib/backend/bdb_ro.c | 816 +++++++++++++++++++++++++++++++++++++++++++ + lib/backend/db3.c | 69 ++-- + lib/backend/dbi.c | 139 ++++---- + lib/backend/dbi.h | 47 ++- + lib/backend/sqlite.c | 105 ++++-- + lib/rpmdb.c | 150 +++++--- + lib/rpmdb.h | 33 ++ + lib/rpmdb_internal.h | 10 +- + lib/rpmts.c | 8 +- + macros.in | 2 +- + rpmdb.c | 6 + + 13 files changed, 1212 insertions(+), 191 deletions(-) + create mode 100644 lib/backend/bdb_ro.c + +diff --git a/configure.ac b/configure.ac +index 3bd6382..a47aa46 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -610,6 +610,20 @@ AS_IF([test "$enable_ndb" = yes],[ + ]) + AM_CONDITIONAL([NDB], [test "$enable_ndb" = yes]) + ++#================= ++# Process --enable-bdb-ro ++AC_ARG_ENABLE([bdb-ro], [AS_HELP_STRING([--enable-bdb-ro (EXPERIMENTAL)],[enable the read-only Berkeley DB code])], ++[case "$enable_bdb_ro" in ++yes|no) ;; ++*) AC_MSG_ERROR([invalid argument to --enable-bdb-ro]) ++ ;; ++esac], ++[enable_bdb_ro=no]) ++AS_IF([test "$enable_bdb_ro" = yes],[ ++ AC_DEFINE(WITH_BDB_RO, 1, [Build with read-only Berkeley DB]) ++]) ++AM_CONDITIONAL([BDB_RO], [test "$enable_bdb_ro" = yes]) ++ + # Check for SQLITE support + AC_ARG_ENABLE([sqlite], + [AS_HELP_STRING([--enable-sqlite=@<:@yes/no/auto@:>@)], +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 07c681e..b121f3d 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -66,6 +66,10 @@ else + librpm_la_LIBADD += @WITH_DB_LIB@ + endif + ++if BDB_RO ++librpm_la_SOURCES += backend/bdb_ro.c ++endif ++ + if NDB + librpm_la_SOURCES += \ + backend/ndb/glue.c \ +diff --git a/lib/backend/bdb_ro.c b/lib/backend/bdb_ro.c +new file mode 100644 +index 0000000..2667ec8 +--- /dev/null ++++ b/lib/backend/bdb_ro.c +@@ -0,0 +1,816 @@ ++#include "system.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "lib/rpmdb_internal.h" ++#include ++#include ++ ++#define BDB_HASH 0 ++#define BDB_BTREE 1 ++ ++struct dbiCursor_s; ++ ++struct bdb_kv { ++ unsigned char *kv; ++ unsigned int len; ++}; ++ ++struct bdb_db { ++ int fd; /* file descriptor of database */ ++ int type; /* BDB_HASH / BDB_BTREE */ ++ unsigned int pagesize; ++ unsigned int lastpage; ++ int swapped; /* different endianess? */ ++ /* btree */ ++ unsigned int root; /* root page of the b-tree */ ++ /* hash */ ++ unsigned int maxbucket; ++ unsigned int highmask; ++ unsigned int lowmask; ++ unsigned int spares[32]; /* spare pages for each splitpoint */ ++}; ++ ++struct bdb_cur { ++ struct bdb_db *db; ++ ++ struct bdb_kv key; /* key and value from the db entry */ ++ struct bdb_kv val; ++ ++ unsigned char *page; /* the page we're looking at */ ++ ++ unsigned char *ovpage; ++ struct bdb_kv keyov; /* space to store oversized keys/values */ ++ struct bdb_kv valov; ++ ++ int state; /* 1: onpage, -1: error */ ++ int idx; /* entry index */ ++ int numidx; /* number of entries on the page */ ++ int islookup; /* we're doing a lookup operation */ ++ ++ /* hash */ ++ unsigned int bucket; /* current bucket */ ++}; ++ ++ ++static void swap16(unsigned char *p) ++{ ++ int a = p[0]; ++ p[0] = p[1]; ++ p[1] = a; ++} ++ ++static void swap32(unsigned char *p) ++{ ++ int a = p[0]; ++ p[0] = p[3]; ++ p[3] = a; ++ a = p[1]; ++ p[1] = p[2]; ++ p[2] = a; ++} ++ ++static void swap32_2(unsigned char *p) ++{ ++ swap32(p); ++ swap32(p + 4); ++} ++ ++static void bdb_swapmetapage(struct bdb_db *db, unsigned char *page) ++{ ++ int i, maxi = db->type == BDB_HASH ? 224 : 92; ++ for (i = 8; i < maxi; i += 4) ++ swap32((unsigned char *)(page + i)); ++ swap32((unsigned char *)(page + 24)); ++} ++ ++static void bdb_swappage(struct bdb_db *db, unsigned char *page) ++{ ++ unsigned int pagesize = db->pagesize; ++ int type, i, nent, off; ++ swap32(page + 8); /* page number */ ++ swap32_2(page + 12); /* prev/next page */ ++ swap16(page + 20); /* nitems */ ++ swap16(page + 22); /* highfree */ ++ ++ type = page[25]; ++ if (type != 2 && type != 13 && type != 3 && type != 5) ++ return; ++ nent = *(uint16_t *)(page + 20); ++ if (nent > (pagesize - 26) / 2) ++ nent = (pagesize - 26) / 2; ++ for (i = 0; i < nent; i++) { ++ int minoff = 26 + nent * 2; ++ swap16(page + 26 + i * 2); /* offset */ ++ off = *(uint16_t *)(page + 26 + i * 2); ++ if (off < minoff || off >= pagesize) ++ continue; ++ if (type == 2 || type == 13) { /* hash */ ++ if (page[off] == 3 && off + 12 <= pagesize) ++ swap32_2(page + off + 4); /* page no/length */ ++ } else if (type == 3) { /* btree internal */ ++ if (off + 12 > pagesize) ++ continue; ++ swap16(page + off); /* length */ ++ swap32_2(page + off + 4); /* page no/num recs */ ++ if (page[off + 2] == 3 && off + 24 <= pagesize) ++ swap32_2(page + off + 16); /* with overflow page/length */ ++ } else if (type == 5) { /* btree leaf */ ++ if (off + 3 <= pagesize && page[off + 2] == 1) ++ swap16(page + off); /* length */ ++ else if (off + 12 <= pagesize && page[off + 2] == 3) ++ swap32_2(page + off + 4); /* overflow page/length */ ++ } ++ } ++} ++ ++static int bdb_getpage(struct bdb_db *db, unsigned char *page, unsigned int pageno) ++{ ++ if (!pageno || pageno > db->lastpage) ++ return -1; ++ if (pread(db->fd, page, db->pagesize, (off_t)pageno * db->pagesize) != db->pagesize) { ++ rpmlog(RPMLOG_ERR, "pread: %s\n", strerror(errno)); ++ return -1; ++ } ++ if (db->swapped) ++ bdb_swappage(db, page); ++ if (pageno != *(uint32_t *)(page + 8)) ++ return -1; ++ return 0; ++} ++ ++static void bdb_close(struct bdb_db *db) ++{ ++ if (db->fd >= 0) ++ close(db->fd); ++ free(db); ++} ++ ++static struct bdb_db *bdb_open(const char *name) ++{ ++ uint32_t meta[512 / 4]; ++ int i, fd; ++ struct bdb_db *db; ++ ++ fd = open(name, O_RDONLY); ++ if (fd == -1) { ++ return NULL; ++ } ++ db = xcalloc(1, sizeof(*db)); ++ db->fd = fd; ++ if (pread(fd, meta, 512, 0) != 512) { ++ rpmlog(RPMLOG_ERR, "%s: pread: %s\n", name, strerror(errno)); ++ bdb_close(db); ++ return NULL; ++ } ++ if (meta[3] == 0x00061561 || meta[3] == 0x61150600) { ++ db->type = BDB_HASH; ++ db->swapped = meta[3] == 0x61150600; ++ } else if (meta[3] == 0x00053162 || meta[3] == 0x62310500) { ++ db->type = BDB_BTREE; ++ db->swapped = meta[3] == 0x62310500; ++ } else { ++ rpmlog(RPMLOG_ERR, "%s: not a berkeley db hash/btree database\n", name); ++ bdb_close(db); ++ return NULL; ++ } ++ if (db->swapped) ++ bdb_swapmetapage(db, (unsigned char *)meta); ++ db->pagesize = meta[5]; ++ db->lastpage = meta[8]; ++ if (db->type == BDB_HASH) { ++ if (meta[4] < 8 || meta[4] > 10) { ++ rpmlog(RPMLOG_ERR, "%s: unsupported hash version %d\n", name, meta[4]); ++ bdb_close(db); ++ return NULL; ++ } ++ db->maxbucket = meta[18]; ++ db->highmask = meta[19]; ++ db->lowmask = meta[20]; ++ for (i = 0; i < 32; i++) ++ db->spares[i] = meta[24 + i]; ++ } ++ if (db->type == BDB_BTREE) { ++ if (meta[4] < 9 || meta[4] > 10) { ++ rpmlog(RPMLOG_ERR, "%s: unsupported btree version %d\n", name, meta[4]); ++ bdb_close(db); ++ return NULL; ++ } ++ db->root = meta[22]; ++ } ++ return db; ++} ++ ++ ++/****** overflow handling ******/ ++ ++static int ovfl_get(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, uint32_t *pagenolen) ++{ ++ unsigned int pageno = pagenolen[0]; ++ unsigned int len = pagenolen[1]; ++ unsigned int plen; ++ unsigned char *p; ++ ++ if (len == 0) ++ return -1; ++ if (len > ov->len) { ++ if (ov->kv) ++ ov->kv = xrealloc(ov->kv, len); ++ else ++ ov->kv = xmalloc(len); ++ ov->len = len; ++ } ++ if (!cur->ovpage) ++ cur->ovpage = xmalloc(cur->db->pagesize); ++ p = ov->kv; ++ while (len > 0) { ++ if (bdb_getpage(cur->db, cur->ovpage, pageno)) ++ return -1; ++ if (cur->ovpage[25] != 7) ++ return -1; ++ plen = *(uint16_t *)(cur->ovpage + 22); ++ if (plen + 26 > cur->db->pagesize || plen > len) ++ return -1; ++ memcpy(p, cur->ovpage + 26, plen); ++ p += plen; ++ len -= plen; ++ pageno = *(uint32_t *)(cur->ovpage + 16); ++ } ++ if (kv) { ++ kv->kv = ov->kv; ++ kv->len = pagenolen[1]; ++ } ++ return 0; ++} ++ ++ ++/****** hash implementation ******/ ++ ++static int hash_bucket_to_page(struct bdb_db *db, unsigned int bucket) ++{ ++ unsigned int b; ++ int i = 0; ++ for (b = bucket; b; b >>= 1) ++ i++; ++ return bucket + db->spares[i]; ++} ++ ++static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ uint32_t bucket; ++ unsigned int pg, i; ++ cur->state = -1; ++ for (bucket = 0, i = 0; i < keyl; i++) ++ bucket = (bucket * 16777619) ^ key[i]; ++ bucket &= cur->db->highmask; ++ if (bucket > cur->db->maxbucket) ++ bucket &= cur->db->lowmask; ++ cur->bucket = bucket; ++ pg = hash_bucket_to_page(cur->db, bucket); ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] != 8 && cur->page[25] != 13) ++ return -1; ++ cur->idx = (unsigned int)-2; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ cur->state = 1; ++ return 0; ++} ++ ++static int hash_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off, int len) ++{ ++ if (len <= 0 || off + len > cur->db->pagesize) ++ return -1; ++ if (cur->page[off] == 1) { ++ kv->kv = cur->page + off + 1; ++ kv->len = len - 1; ++ } else if (cur->page[off] == 3) { ++ uint32_t ovlpage[2]; ++ if (len != 12) ++ return -1; ++ memcpy(ovlpage, cur->page + off + 4, 8); /* off is unaligned */ ++ if (ovfl_get(cur, kv, ov, ovlpage)) ++ return -1; ++ } else { ++ return -1; ++ } ++ return 0; ++} ++ ++static int hash_next(struct bdb_cur *cur) ++{ ++ int pagesize = cur->db->pagesize; ++ int koff, klen, voff, vlen; ++ if (!cur->state && hash_lookup(cur, 0, 0)) ++ return -1; ++ cur->idx += 2; ++ for (;;) { ++ if (cur->idx + 1 >= cur->numidx) { ++ unsigned int pg; ++ cur->idx = cur->numidx = 0; ++ pg = *(uint32_t *)(cur->page + 16); ++ if (!pg) { ++ if (cur->islookup || cur->bucket >= cur->db->maxbucket) ++ return 1; ++ pg = hash_bucket_to_page(cur->db, ++cur->bucket); ++ } ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] != 8 && cur->page[25] != 13) ++ return -1; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ continue; ++ } ++ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ if (koff >= pagesize || voff >= pagesize) ++ return -1; ++ if (cur->idx == 0) ++ klen = pagesize - koff; ++ else ++ klen = *(uint16_t *)(cur->page + 24 + 2 * cur->idx) - koff; ++ vlen = koff - voff; ++ if (hash_getkv(cur, &cur->key, &cur->keyov, koff, klen)) ++ return -1; ++ if (!cur->islookup && hash_getkv(cur, &cur->val, &cur->valov, voff, vlen)) ++ return -1; ++ return 0; ++ } ++} ++ ++static int hash_getval(struct bdb_cur *cur) ++{ ++ int koff, voff; ++ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) ++ return -1; ++ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ return hash_getkv(cur, &cur->val, &cur->valov, voff, koff - voff); ++} ++ ++ ++/****** btree implementation ******/ ++ ++static int btree_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keylen) ++{ ++ int pagesize = cur->db->pagesize; ++ int off, lastoff, idx, numidx; ++ unsigned int pg; ++ unsigned char *ekey; ++ unsigned int ekeylen; ++ int cmp; ++ ++ cur->state = -1; ++ pg = cur->db->root; ++ for (;;) { ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] == 5) ++ break; /* found leaf page */ ++ if (cur->page[25] != 3) ++ return -1; ++ numidx = *(uint16_t *)(cur->page + 20); ++ if (!numidx) ++ return -1; ++ for (lastoff = 0, idx = 0; idx < numidx; idx++, lastoff = off) { ++ off = *(uint16_t *)(cur->page + 26 + 2 * idx); ++ if ((off & 3) != 0 || off + 3 > pagesize) ++ return -1; ++ ekeylen = *(uint16_t *)(cur->page + off); ++ if (off + 12 + ekeylen > pagesize) ++ return -1; ++ if (!keylen) { ++ lastoff = off; ++ break; ++ } ++ if (idx == 0) ++ continue; ++ ekey = cur->page + off + 12; ++ if ((cur->page[off + 2] & 0x7f) == 3) { ++ if (ekeylen != 12) ++ return -1; ++ if (ovfl_get(cur, 0, &cur->keyov, (uint32_t *)(ekey + 4))) ++ return -1; ++ ekeylen = *(uint32_t *)(ekey + 8); ++ ekey = cur->keyov.kv; ++ } else if ((cur->page[off + 2] & 0x7f) != 1) { ++ return -1; ++ } ++ cmp = memcmp(ekey, key, keylen < ekeylen ? keylen : ekeylen); ++ if (cmp > 0 || (cmp == 0 && ekeylen > keylen)) ++ break; ++ } ++ pg = *(uint32_t *)(cur->page + lastoff + 4); ++ } ++ cur->idx = (unsigned int)-2; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ cur->state = 1; ++ return 0; ++} ++ ++static int btree_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off) ++{ ++ if ((off & 3) != 0) ++ return -1; ++ if (cur->page[off + 2] == 1) { ++ int len = *(uint16_t *)(cur->page + off); ++ if (off + 3 + len > cur->db->pagesize) ++ return -1; ++ kv->kv = cur->page + off + 3; ++ kv->len = len; ++ } else if (cur->page[off + 2] == 3) { ++ if (off + 12 > cur->db->pagesize) ++ return -1; ++ if (ovfl_get(cur, kv, ov, (uint32_t *)(cur->page + off + 4))) ++ return -1; ++ } else { ++ return -1; ++ } ++ return 0; ++} ++ ++static int btree_next(struct bdb_cur *cur) ++{ ++ int pagesize = cur->db->pagesize; ++ int koff, voff; ++ if (!cur->state && btree_lookup(cur, 0, 0)) ++ return -1; ++ cur->idx += 2; ++ for (;;) { ++ if (cur->idx + 1 >= cur->numidx) { ++ unsigned int pg; ++ cur->idx = cur->numidx = 0; ++ pg = *(uint32_t *)(cur->page + 16); ++ if (cur->islookup || !pg) ++ return 1; ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] != 5) ++ return -1; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ continue; ++ } ++ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ if (koff + 3 > pagesize || voff + 3 > pagesize) ++ return -1; ++ if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0) ++ continue; /* ignore deleted */ ++ if (btree_getkv(cur, &cur->key, &cur->keyov, koff)) ++ return -1; ++ if (!cur->islookup && btree_getkv(cur, &cur->val, &cur->valov, voff)) ++ return -1; ++ return 0; ++ } ++} ++ ++static int btree_getval(struct bdb_cur *cur) ++{ ++ int voff; ++ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) ++ return -1; ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ return btree_getkv(cur, &cur->val, &cur->valov, voff); ++} ++ ++ ++/****** cursor functions ******/ ++ ++static struct bdb_cur *cur_open(struct bdb_db *db) ++{ ++ struct bdb_cur *cur = xcalloc(1, sizeof(*cur)); ++ cur->db = db; ++ cur->page = xmalloc(db->pagesize); ++ return cur; ++} ++ ++static void cur_close(struct bdb_cur *cur) ++{ ++ if (cur->page) ++ free(cur->page); ++ if (cur->ovpage) ++ free(cur->ovpage); ++ if (cur->keyov.kv) ++ free(cur->keyov.kv); ++ if (cur->valov.kv) ++ free(cur->valov.kv); ++ free(cur); ++} ++ ++static int cur_next(struct bdb_cur *cur) ++{ ++ if (cur->state < 0) ++ return -1; ++ if (cur->db->type == BDB_HASH) ++ return hash_next(cur); ++ if (cur->db->type == BDB_BTREE) ++ return btree_next(cur); ++ return -1; ++} ++ ++static int cur_getval(struct bdb_cur *cur) ++{ ++ if (cur->state < 0) ++ return -1; ++ if (cur->db->type == BDB_HASH) ++ return hash_getval(cur); ++ if (cur->db->type == BDB_BTREE) ++ return btree_getval(cur); ++ return -1; ++} ++ ++static int cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ int r = -1; ++ if (cur->db->type == BDB_HASH) ++ r = hash_lookup(cur, key, keyl); ++ if (cur->db->type == BDB_BTREE) ++ r = btree_lookup(cur, key, keyl); ++ if (r != 0) ++ return r; ++ cur->islookup = 1; ++ while ((r = cur_next(cur)) == 0) ++ if (keyl == cur->key.len && !memcmp(key, cur->key.kv, keyl)) ++ break; ++ cur->islookup = 0; ++ if (r == 0) ++ r = cur_getval(cur); ++ return r; ++} ++ ++static int cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ int r = -1; ++ if (cur->db->type == BDB_BTREE) ++ r = btree_lookup(cur, key, keyl); ++ if (r != 0) ++ return r; ++ cur->islookup = 1; ++ while ((r = cur_next(cur)) == 0) { ++ unsigned int ekeyl = cur->key.len; ++ int cmp = memcmp(cur->key.kv, key, keyl < ekeyl ? keyl : ekeyl); ++ if (cmp > 0 || (cmp == 0 && ekeyl >= keyl)) ++ break; ++ } ++ cur->islookup = 0; ++ if (r == 0) ++ r = cur_getval(cur); ++ else if (r == 1) ++ r = cur_next(cur); ++ return r; ++} ++ ++/****** glue code ******/ ++ ++static unsigned int getui32(unsigned char *x, int swapped) ++{ ++ union _dbswap bs; ++ memcpy(bs.uc, x, 4); ++ if (swapped) ++ _DBSWAP(bs); ++ return bs.ui; ++} ++ ++static void setui32(unsigned char *x, uint32_t v, int swapped) ++{ ++ union _dbswap bs; ++ bs.ui = v; ++ if (swapped) ++ _DBSWAP(bs); ++ memcpy(x, bs.uc, 4); ++} ++ ++static void log_error(dbiIndex dbi) ++{ ++ rpmlog(RPMLOG_ERR, "bdb_ro error reading %s database\n", dbi->dbi_file); ++} ++ ++static int bdbro_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags) ++{ ++ const char *dbhome = rpmdbHome(rdb); ++ dbiIndex dbi = NULL; ++ char *path; ++ ++ if (dbip) ++ *dbip = NULL; ++ if ((rdb->db_mode & O_ACCMODE) != O_RDONLY) ++ return EPERM; ++ if ((dbi = dbiNew(rdb, rpmtag)) == NULL) ++ return 1; ++ path = rstrscat(NULL, dbhome, "/", dbi->dbi_file, NULL); ++ rpmlog(RPMLOG_DEBUG, "opening db index %s\n", path); ++ dbi->dbi_db = bdb_open(path); ++ if (!dbi->dbi_db) { ++ int lvl = (dbi->dbi_type == DBI_PRIMARY) ? RPMLOG_ERR : RPMLOG_WARNING; ++ rpmlog(lvl, "could not open %s: %s\n", path, strerror(errno)); ++ if (dbi->dbi_type == DBI_PRIMARY) { ++ free(path); ++ dbiFree(dbi); ++ return 1; ++ } ++ } ++ free(path); ++ dbi->dbi_flags |= DBI_RDONLY; ++ if (dbip) ++ *dbip = dbi; ++ else ++ (void) dbiClose(dbi, 0); ++ return 0; ++} ++ ++static int bdbro_Close(dbiIndex dbi, unsigned int flags) ++{ ++ if (dbi->dbi_db) ++ bdb_close(dbi->dbi_db); ++ dbiFree(dbi); ++ return 0; ++} ++ ++static int bdbro_Verify(dbiIndex dbi, unsigned int flags) ++{ ++ return 0; ++} ++ ++static void bdbro_SetFSync(rpmdb rdb, int enable) ++{ ++} ++ ++static int bdbro_Ctrl(rpmdb rdb, dbCtrlOp ctrl) ++{ ++ return 0; ++} ++ ++static dbiCursor bdbro_CursorInit(dbiIndex dbi, unsigned int flags) ++{ ++ /* Secondary indexes may be missing */ ++ return (dbi && dbi->dbi_db) ? (void *)cur_open(dbi->dbi_db) : NULL; ++} ++ ++static dbiCursor bdbro_CursorFree(dbiIndex dbi, dbiCursor dbc) ++{ ++ if (dbc) ++ cur_close((void *)dbc); ++ return NULL; ++} ++ ++static void appenddbt(dbiCursor dbc, unsigned char *val, unsigned int vallen, dbiIndexSet *setp) ++{ ++ struct bdb_cur *cur = (void *)dbc; ++ dbiIndexSet set; ++ unsigned int i; ++ ++ set = dbiIndexSetNew(vallen / (2 * sizeof(uint32_t))); ++ set->count = vallen / (2 * sizeof(uint32_t)); ++ ++ for (i = 0; i < set->count; i++, val += 8) { ++ set->recs[i].hdrNum = getui32(val, cur->db->swapped); ++ set->recs[i].tagNum = getui32(val + 4, cur->db->swapped); ++ } ++ if (*setp == NULL) { ++ *setp = set; ++ } else { ++ dbiIndexSetAppendSet(*setp, set, 0); ++ dbiIndexSetFree(set); ++ } ++} ++ ++static rpmRC bdbro_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) ++{ ++ return RPMRC_FAIL; ++} ++ ++static rpmRC bdbro_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) ++{ ++ return RPMRC_FAIL; ++} ++ ++static rpmRC bdbro_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, ++ dbiIndexSet *set, int searchType) ++{ ++ struct bdb_cur *cur = (void *)dbc; ++ int r; ++ ++ if (!cur) ++ return RPMRC_FAIL; ++ if (searchType == DBC_PREFIX_SEARCH) { ++ rpmRC rc = RPMRC_NOTFOUND; ++ if (!keyp) ++ return RPMRC_FAIL; ++ r = cur_lookup_ge(cur, (const unsigned char *)keyp, keylen); ++ for (; r == 0; r = cur_next(cur)) { ++ if (cur->key.len < keylen || memcmp(cur->key.kv, keyp, keylen) != 0) ++ break; ++ if (set) ++ appenddbt(dbc, cur->val.kv, cur->val.len, set); ++ rc = RPMRC_OK; ++ } ++ if (r == -1) ++ log_error(dbi); ++ cur->key.kv = 0; ++ return r == -1 ? RPMRC_FAIL : rc; ++ } ++ if (keyp) { ++ if (keylen == 0) { ++ keyp = ""; ++ keylen = 1; ++ } ++ r = cur_lookup(cur, (const unsigned char *)keyp, keylen); ++ } else { ++ r = cur_next(cur); ++ } ++ if (r == 0) { ++ if (set) ++ appenddbt(dbc, cur->val.kv, cur->val.len, set); ++ return RPMRC_OK; ++ } ++ if (r == -1) ++ log_error(dbi); ++ cur->key.kv = 0; ++ return r == 1 ? RPMRC_NOTFOUND : RPMRC_FAIL; ++} ++ ++static const void *bdbro_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) ++{ ++ struct bdb_cur *cur = (void *)dbc; ++ if (!cur || !cur->key.kv) ++ return 0; ++ if (keylen) ++ *keylen = cur->key.len; ++ return cur->key.kv; ++} ++ ++static rpmRC bdbro_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, ++ unsigned char *hdrBlob, unsigned int hdrLen) ++{ ++ return RPMRC_FAIL; ++} ++ ++static rpmRC bdbro_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) ++{ ++ return RPMRC_FAIL; ++} ++ ++static rpmRC bdbro_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, ++ unsigned char **hdrBlob, unsigned int *hdrLen) ++{ ++ struct bdb_cur *cur = (void *)dbc; ++ int r; ++ if (hdrNum) { ++ unsigned char hdrkey[4]; ++ setui32(hdrkey, hdrNum, cur->db->swapped); ++ r = cur_lookup(cur, hdrkey, 4); ++ } else { ++ r = cur_next(cur); ++ } ++ if (r == 0) { ++ if (hdrBlob) ++ *hdrBlob = cur->val.kv; ++ if (hdrLen) ++ *hdrLen = cur->val.len; ++ return RPMRC_OK; ++ } ++ if (r == -1) ++ log_error(dbi); ++ cur->key.kv = 0; ++ return r == 1 ? RPMRC_NOTFOUND : RPMRC_FAIL; ++} ++ ++static unsigned int bdbro_pkgdbKey(dbiIndex dbi, dbiCursor dbc) ++{ ++ struct bdb_cur *cur = (void *)dbc; ++ if (!cur || !cur->key.kv || cur->key.len != 4) ++ return 0; ++ return getui32(cur->key.kv, cur->db->swapped); ++} ++ ++struct rpmdbOps_s bdbro_dbops = { ++ .name = "bdb_ro", ++ .path = "Packages", ++ ++ .open = bdbro_Open, ++ .close = bdbro_Close, ++ .verify = bdbro_Verify, ++ .setFSync = bdbro_SetFSync, ++ .ctrl = bdbro_Ctrl, ++ ++ .cursorInit = bdbro_CursorInit, ++ .cursorFree = bdbro_CursorFree, ++ ++ .pkgdbPut = bdbro_pkgdbPut, ++ .pkgdbDel = bdbro_pkgdbDel, ++ .pkgdbGet = bdbro_pkgdbGet, ++ .pkgdbKey = bdbro_pkgdbKey, ++ ++ .idxdbGet = bdbro_idxdbGet, ++ .idxdbPut = bdbro_idxdbPut, ++ .idxdbDel = bdbro_idxdbDel, ++ .idxdbKey = bdbro_idxdbKey ++}; ++ +diff --git a/lib/backend/db3.c b/lib/backend/db3.c +index da50dfd..68cfa6f 100644 +--- a/lib/backend/db3.c ++++ b/lib/backend/db3.c +@@ -11,6 +11,7 @@ static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */ + #include + #include + #include ++#include + + #include + #include +@@ -415,10 +416,6 @@ static int db_init(rpmdb rdb, const char * dbhome) + if (rdb->db_dbenv != NULL) { + rdb->db_opens++; + return 0; +- } else { +- /* On first call, set backend description to something... */ +- free(rdb->db_descr); +- rasprintf(&rdb->db_descr, "db%u", DB_VERSION_MAJOR); + } + + /* +@@ -1012,7 +1009,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t + dbiIndexSet *set, int searchType) + { + rpmRC rc = RPMRC_FAIL; /* assume failure */ +- if (dbi != NULL && dbc != NULL && set != NULL) { ++ if (dbi != NULL && dbc != NULL) { + int cflags = DB_NEXT; + int dbrc; + DBT data, key; +@@ -1037,12 +1034,14 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t + if (searchType == DBC_PREFIX_SEARCH && + (key.size < keylen || memcmp(key.data, keyp, keylen) != 0)) + break; +- dbt2set(dbi, &data, &newset); +- if (*set == NULL) { +- *set = newset; +- } else { +- dbiIndexSetAppendSet(*set, newset, 0); +- dbiIndexSetFree(newset); ++ if (set) { ++ dbt2set(dbi, &data, &newset); ++ if (*set == NULL) { ++ *set = newset; ++ } else { ++ dbiIndexSetAppendSet(*set, newset, 0); ++ dbiIndexSetFree(newset); ++ } + } + if (searchType != DBC_PREFIX_SEARCH) + break; +@@ -1052,7 +1051,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t + } + + /* fixup result status for prefix search */ +- if (searchType == DBC_PREFIX_SEARCH) { ++ if (searchType == DBC_PREFIX_SEARCH && set) { + if (dbrc == DB_NOTFOUND && *set != NULL && (*set)->count > 0) + dbrc = 0; + else if (dbrc == 0 && (*set == NULL || (*set)->count == 0)) +@@ -1115,7 +1114,7 @@ static rpmRC updateIndex(dbiCursor dbc, const char *keyp, unsigned int keylen, + return rc; + } + +-static rpmRC db3_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, ++static rpmRC db3_idxdbPutOne(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, + dbiIndexItem rec) + { + dbiIndexSet set = NULL; +@@ -1141,7 +1140,12 @@ static rpmRC db3_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t + return rc; + } + +-static rpmRC db3_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, ++static rpmRC db3_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) ++{ ++ return tag2index(dbi, rpmtag, hdrNum, h, db3_idxdbPutOne); ++} ++ ++static rpmRC db3_idxdbDelOne(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, + dbiIndexItem rec) + { + dbiIndexSet set = NULL; +@@ -1171,6 +1175,11 @@ static rpmRC db3_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t + return rc; + } + ++static rpmRC db3_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) ++{ ++ return tag2index(dbi, rpmtag, hdrNum, h, db3_idxdbDelOne); ++} ++ + static const void * db3_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) + { + const void *key = NULL; +@@ -1278,14 +1287,26 @@ static unsigned int pkgInstance(dbiIndex dbi, int alloc) + return hdrNum; + } + +-static rpmRC db3_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, ++static rpmRC db3_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, + unsigned char *hdrBlob, unsigned int hdrLen) + { ++ rpmRC rc = RPMRC_FAIL; ++ unsigned int hnum = *hdrNum; + DBT hdr; + memset(&hdr, 0, sizeof(hdr)); + hdr.data = hdrBlob; + hdr.size = hdrLen; +- return updatePackages(dbc, hdrNum, &hdr); ++ ++ if (hnum == 0) ++ hnum = pkgInstance(dbi, 1); ++ ++ if (hnum) ++ rc = updatePackages(dbc, hnum, &hdr); ++ ++ if (rc == RPMRC_OK) ++ *hdrNum = hnum; ++ ++ return rc; + } + + static rpmRC db3_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) +@@ -1342,19 +1363,10 @@ static unsigned int db3_pkgdbKey(dbiIndex dbi, dbiCursor dbc) + return mi_offset.ui; + } + +-static rpmRC db3_pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum) +-{ +- unsigned int num; +- if (dbc == NULL) +- return RPMRC_FAIL; +- num = pkgInstance(dbc->dbi, 1); +- if (!num) +- return RPMRC_FAIL; +- *hdrNum = num; +- return RPMRC_OK; +-} +- + struct rpmdbOps_s db3_dbops = { ++ .name = "bdb", ++ .path = "Packages", ++ + .open = db3_dbiOpen, + .close = db3_dbiClose, + .verify = db3_dbiVerify, +@@ -1368,7 +1380,6 @@ struct rpmdbOps_s db3_dbops = { + .pkgdbGet = db3_pkgdbGet, + .pkgdbPut = db3_pkgdbPut, + .pkgdbDel = db3_pkgdbDel, +- .pkgdbNew = db3_pkgdbNew, + .pkgdbKey = db3_pkgdbKey, + + .idxdbGet = db3_idxdbGet, +diff --git a/lib/backend/dbi.c b/lib/backend/dbi.c +index dc3587f..9e714d7 100644 +--- a/lib/backend/dbi.c ++++ b/lib/backend/dbi.c +@@ -5,6 +5,7 @@ + #include "system.h" + + #include ++#include + #include + #include + #include +@@ -12,6 +13,21 @@ + #include "lib/rpmdb_internal.h" + #include "debug.h" + ++const struct rpmdbOps_s *backends[] = { ++#if defined(WITH_SQLITE) ++ &sqlite_dbops, ++#endif ++#ifdef ENABLE_NDB ++ &ndb_dbops, ++#endif ++#if defined(WITH_BDB) ++ &db3_dbops, ++#endif ++#if defined(WITH_BDB_RO) ++ &bdbro_dbops, ++#endif ++ NULL ++}; + + dbiIndex dbiFree(dbiIndex dbi) + { +@@ -32,69 +48,77 @@ dbiIndex dbiNew(rpmdb rdb, rpmDbiTagVal rpmtag) + return dbi; + } + ++/* Test whether there's a database for this backend, return true/false */ ++static int tryBackend(const char *dbhome, const struct rpmdbOps_s *be) ++{ ++ int rc = 0; ++ if (be && be->path) { ++ char *path = rstrscat(NULL, dbhome, "/", be->path, NULL); ++ rc = (access(path, F_OK) == 0); ++ free(path); ++ } ++ return rc; ++} ++ + static void + dbDetectBackend(rpmdb rdb) + { + const char *dbhome = rpmdbHome(rdb); + char *db_backend = rpmExpand("%{?_db_backend}", NULL); +- char *path = NULL; +- +-#if defined(WITH_LMDB) +- if (!strcmp(db_backend, "lmdb")) { +- rdb->db_ops = &lmdb_dbops; +- } else +-#endif +-#ifdef ENABLE_NDB +- if (!strcmp(db_backend, "ndb")) { +- rdb->db_ops = &ndb_dbops; +- } else +-#endif +-#ifdef WITH_SQLITE +- if (!strcmp(db_backend, "sqlite")) { +- rdb->db_ops = &sqlite_dbops; +- } else +-#endif +- { +- rdb->db_ops = &db3_dbops; +- if (*db_backend == '\0') { +- free(db_backend); +- db_backend = xstrdup("bdb"); ++ const struct rpmdbOps_s **ops; ++ const struct rpmdbOps_s *cfg = NULL; ++ const struct rpmdbOps_s *ondisk = NULL; ++ ++ /* Find configured backend */ ++ for (ops = backends; ops && *ops; ops++) { ++ if (rstreq(db_backend, (*ops)->name)) { ++ cfg = *ops; ++ break; + } + } + +-#if defined(WITH_LMDB) +- path = rstrscat(NULL, dbhome, "/data.mdb", NULL); +- if (access(path, F_OK) == 0 && rdb->db_ops != &lmdb_dbops) { +- rdb->db_ops = &lmdb_dbops; +- rpmlog(RPMLOG_WARNING, _("Found LMDB data.mdb database while attempting %s backend: using lmdb backend.\n"), db_backend); ++ if (!cfg && ((rdb->db_mode & O_ACCMODE) != O_RDONLY || (rdb->db_flags & RPMDB_FLAG_REBUILD) != 0)) { ++ rpmlog(RPMLOG_WARNING, _("invalid %%_db_backend: %s\n"), db_backend); ++ goto exit; + } +- free(path); +-#endif + +-#ifdef ENABLE_NDB +- path = rstrscat(NULL, dbhome, "/Packages.db", NULL); +- if (access(path, F_OK) == 0 && rdb->db_ops != &ndb_dbops) { +- rdb->db_ops = &ndb_dbops; +- rpmlog(RPMLOG_WARNING, _("Found NDB Packages.db database while attempting %s backend: using ndb backend.\n"), db_backend); +- } +- free(path); +-#endif ++ /* If configured database doesn't exist, try autodetection */ ++ if (!tryBackend(dbhome, cfg)) { ++ for (ops = backends; ops && *ops; ops++) { ++ if (tryBackend(dbhome, *ops)) { ++ ondisk = *ops; ++ break; ++ } ++ } + +-#ifdef WITH_SQLITE +- path = rstrscat(NULL, dbhome, "/rpmdb.sqlite", NULL); +- if (access(path, F_OK) == 0 && rdb->db_ops != &sqlite_dbops) { +- rdb->db_ops = &sqlite_dbops; +- rpmlog(RPMLOG_WARNING, _("Found SQLITE rpmdb.sqlite database while attempting %s backend: using sqlite backend.\n"), db_backend); ++ /* On-disk database differs from configuration */ ++ if (ondisk && ondisk != cfg) { ++ if (*db_backend) { ++ if (rdb->db_flags & RPMDB_FLAG_REBUILD) { ++ rpmlog(RPMLOG_WARNING, ++ _("Converting database from %s to %s backend\n"), ++ ondisk->name, db_backend); ++ } else { ++ rpmlog(RPMLOG_WARNING, ++ _("Found %s %s database while attempting %s backend: " ++ "using %s backend.\n"), ++ ondisk->name, ondisk->path, db_backend, ondisk->name); ++ } ++ } else { ++ rpmlog(RPMLOG_DEBUG, "Found %s %s database: using %s backend.\n", ++ ondisk->name, ondisk->path, ondisk->name); ++ } ++ rdb->db_ops = ondisk; ++ } + } +- free(path); +-#endif + +- path = rstrscat(NULL, dbhome, "/Packages", NULL); +- if (access(path, F_OK) == 0 && rdb->db_ops != &db3_dbops) { +- rdb->db_ops = &db3_dbops; +- rpmlog(RPMLOG_WARNING, _("Found BDB Packages database while attempting %s backend: using bdb backend.\n"), db_backend); +- } +- free(path); ++ /* Newly created database, use configured backend */ ++ if (rdb->db_ops == NULL && cfg) ++ rdb->db_ops = cfg; ++ ++exit: ++ ++ rdb->db_descr = rdb->db_ops->name; + + if (db_backend) + free(db_backend); +@@ -151,7 +175,7 @@ dbiCursor dbiCursorFree(dbiIndex dbi, dbiCursor dbc) + return dbi->dbi_rpmdb->db_ops->cursorFree(dbi, dbc); + } + +-rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) ++rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) + { + return dbi->dbi_rpmdb->db_ops->pkgdbPut(dbi, dbc, hdrNum, hdrBlob, hdrLen); + } +@@ -166,11 +190,6 @@ rpmRC pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char * + return dbi->dbi_rpmdb->db_ops->pkgdbGet(dbi, dbc, hdrNum, hdrBlob, hdrLen); + } + +-rpmRC pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum) +-{ +- return dbi->dbi_rpmdb->db_ops->pkgdbNew(dbi, dbc, hdrNum); +-} +- + unsigned int pkgdbKey(dbiIndex dbi, dbiCursor dbc) + { + return dbi->dbi_rpmdb->db_ops->pkgdbKey(dbi, dbc); +@@ -181,14 +200,14 @@ rpmRC idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbi + return dbi->dbi_rpmdb->db_ops->idxdbGet(dbi, dbc, keyp, keylen, set, curFlags); + } + +-rpmRC idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) ++rpmRC idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) + { +- return dbi->dbi_rpmdb->db_ops->idxdbPut(dbi, dbc, keyp, keylen, rec); ++ return dbi->dbi_rpmdb->db_ops->idxdbPut(dbi, rpmtag, hdrNum, h); + } + +-rpmRC idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) ++rpmRC idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) + { +- return dbi->dbi_rpmdb->db_ops->idxdbDel(dbi, dbc, keyp, keylen, rec); ++ return dbi->dbi_rpmdb->db_ops->idxdbDel(dbi, rpmtag, hdrNum, h); + } + + const void * idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) +diff --git a/lib/backend/dbi.h b/lib/backend/dbi.h +index ff2b4f9..fba2f04 100644 +--- a/lib/backend/dbi.h ++++ b/lib/backend/dbi.h +@@ -10,6 +10,7 @@ enum rpmdbFlags { + RPMDB_FLAG_JUSTCHECK = (1 << 0), + RPMDB_FLAG_REBUILD = (1 << 1), + RPMDB_FLAG_VERIFYONLY = (1 << 2), ++ RPMDB_FLAG_SALVAGE = (1 << 3), + }; + + typedef enum dbCtrlOp_e { +@@ -49,7 +50,7 @@ struct rpmdb_s { + int db_flags; + int db_mode; /*!< open mode */ + int db_perms; /*!< open permissions */ +- char * db_descr; /*!< db backend description (for error msgs) */ ++ const char * db_descr; /*!< db backend description (for error msgs) */ + struct dbChk_s * db_checked;/*!< headerCheck()'ed package instances */ + rpmdb db_next; + int db_opens; +@@ -59,10 +60,11 @@ struct rpmdb_s { + dbiIndex * db_indexes; /*!< Tag indices. */ + int db_buildindex; /*!< Index rebuild indicator */ + +- struct rpmdbOps_s * db_ops; /*!< backend ops */ ++ const struct rpmdbOps_s * db_ops; /*!< backend ops */ + + /* dbenv and related parameters */ + void * db_dbenv; /*!< Backend private handle */ ++ void * db_cache; /*!< Backend private cache handle */ + struct dbConfig_s cfg; + int db_remove_env; + +@@ -123,10 +125,16 @@ union _dbswap { + \ + } + ++typedef rpmRC (*idxfunc)(dbiIndex dbi, dbiCursor dbc, ++ const char *keyp, size_t keylen, dbiIndexItem rec); ++ + #ifdef __cplusplus + extern "C" { + #endif + ++RPM_GNUC_INTERNAL ++rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h, ++ idxfunc idxupdate); + + RPM_GNUC_INTERNAL + /* Globally enable/disable fsync in the backend */ +@@ -216,7 +224,7 @@ dbiCursor dbiCursorFree(dbiIndex dbi, dbiCursor dbc); + + + RPM_GNUC_INTERNAL +-rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, ++rpmRC pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, + unsigned char *hdrBlob, unsigned int hdrLen); + RPM_GNUC_INTERNAL + rpmRC pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum); +@@ -224,23 +232,24 @@ RPM_GNUC_INTERNAL + rpmRC pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, + unsigned char **hdrBlob, unsigned int *hdrLen); + RPM_GNUC_INTERNAL +-rpmRC pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum); +-RPM_GNUC_INTERNAL + unsigned int pkgdbKey(dbiIndex dbi, dbiCursor dbc); + + RPM_GNUC_INTERNAL + rpmRC idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, + dbiIndexSet *set, int curFlags); + RPM_GNUC_INTERNAL +-rpmRC idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, +- dbiIndexItem rec); ++rpmRC idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); ++ + RPM_GNUC_INTERNAL +-rpmRC idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, +- dbiIndexItem rec); ++rpmRC idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); ++ + RPM_GNUC_INTERNAL + const void * idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen); + + struct rpmdbOps_s { ++ const char *name; /* backend name */ ++ const char *path; /* main database name */ ++ + int (*open)(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags); + int (*close)(dbiIndex dbi, unsigned int flags); + int (*verify)(dbiIndex dbi, unsigned int flags); +@@ -251,28 +260,29 @@ struct rpmdbOps_s { + dbiCursor (*cursorFree)(dbiIndex dbi, dbiCursor dbc); + + rpmRC (*pkgdbGet)(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char **hdrBlob, unsigned int *hdrLen); +- rpmRC (*pkgdbPut)(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen); ++ rpmRC (*pkgdbPut)(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen); + rpmRC (*pkgdbDel)(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum); +- rpmRC (*pkgdbNew)(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum); + unsigned int (*pkgdbKey)(dbiIndex dbi, dbiCursor dbc); + + rpmRC (*idxdbGet)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexSet *set, int curFlags); +- rpmRC (*idxdbPut)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec); +- rpmRC (*idxdbDel)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec); ++ rpmRC (*idxdbPut)(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); ++ rpmRC (*idxdbDel)(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); + const void * (*idxdbKey)(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen); + }; + ++#if defined(WITH_BDB) + RPM_GNUC_INTERNAL + extern struct rpmdbOps_s db3_dbops; ++#endif + +-#ifdef ENABLE_NDB ++#if defined(WITH_BDB_RO) + RPM_GNUC_INTERNAL +-extern struct rpmdbOps_s ndb_dbops; ++extern struct rpmdbOps_s bdbro_dbops; + #endif + +-#if defined(WITH_LMDB) ++#ifdef ENABLE_NDB + RPM_GNUC_INTERNAL +-extern struct rpmdbOps_s lmdb_dbops; ++extern struct rpmdbOps_s ndb_dbops; + #endif + + #if defined(WITH_SQLITE) +@@ -280,6 +290,9 @@ RPM_GNUC_INTERNAL + extern struct rpmdbOps_s sqlite_dbops; + #endif + ++RPM_GNUC_INTERNAL ++extern struct rpmdbOps_s dummydb_dbops; ++ + #ifdef __cplusplus + } + #endif +diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c +index 297f97f..7c2de45 100644 +--- a/lib/backend/sqlite.c ++++ b/lib/backend/sqlite.c +@@ -132,22 +132,14 @@ static int sqlite_init(rpmdb rdb, const char * dbhome) + char *dbfile = NULL; + + if (rdb->db_dbenv == NULL) { +- dbfile = rpmGenPath(dbhome, "rpmdb.sqlite", NULL); ++ dbfile = rpmGenPath(dbhome, rdb->db_ops->path, NULL); + sqlite3 *sdb = NULL; + int xx, flags = 0; + int retry_open = 1; +- +- free(rdb->db_descr); +- rdb->db_descr = xstrdup("sqlite"); +- + if ((rdb->db_mode & O_ACCMODE) == O_RDONLY) + flags |= SQLITE_OPEN_READONLY; +- else { +- rpmlog(RPMLOG_ERR, +- _("unable to open sqlite database %s for writing, sqlite support is read-only\n"), dbfile); +- rc = RPMRC_FAIL; +- goto exit; +- } ++ else ++ flags |= (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + + while (retry_open--) { + xx = sqlite3_open_v2(dbfile, &sdb, flags, NULL); +@@ -241,7 +233,6 @@ static int sqlexec(sqlite3 *sdb, const char *fmt, ...) + rpmlog(RPMLOG_DEBUG, "%s: %d\n", cmd, rc); + + sqlite3_free(cmd); +- sqlite3_free(err); + + return rc ? RPMRC_FAIL : RPMRC_OK; + } +@@ -395,10 +386,8 @@ exit: + + static void sqlite_SetFSync(rpmdb rdb, int enable) + { +- if (rdb->db_dbenv) { +- sqlexec(rdb->db_dbenv, ++ sqlexec(rdb->db_dbenv, + "PRAGMA synchronous = %s", enable ? "FULL" : "OFF"); +- } + } + + static int sqlite_Ctrl(rpmdb rdb, dbCtrlOp ctrl) +@@ -448,19 +437,52 @@ static dbiCursor sqlite_CursorFree(dbiIndex dbi, dbiCursor dbc) + return NULL; + } + +-static rpmRC sqlite_pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum) ++static rpmRC sqlite_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) + { +- return RPMRC_FAIL; +-} ++ int rc = 0; ++ dbiCursor dbwc = NULL; + +-static rpmRC sqlite_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) +-{ +- return RPMRC_FAIL; ++ /* Avoid trashing existing query cursor on header rewrite */ ++ if (hdrNum && *hdrNum) { ++ dbwc = dbiCursorInit(dbi, DBC_WRITE); ++ dbc = dbwc; ++ } ++ ++ if (!rc) { ++ rc = dbiCursorPrep(dbc, "INSERT OR REPLACE INTO '%q' VALUES(?, ?)", ++ dbi->dbi_file); ++ } ++ ++ if (!rc) ++ rc = dbiCursorBindPkg(dbc, *hdrNum, hdrBlob, hdrLen); ++ ++ if (!rc) ++ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; ++ ++ /* XXX rowid is a 64bit integer and could overflow hdrnum */ ++ if (rc == SQLITE_DONE && *hdrNum == 0) ++ *hdrNum = sqlite3_last_insert_rowid(dbc->sdb); ++ ++ rc = dbiCursorResult(dbc); ++ ++ if (dbwc) ++ dbiCursorFree(dbi, dbwc); ++ ++ return rc; + } + + static rpmRC sqlite_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) + { +- return RPMRC_FAIL; ++ int rc = dbiCursorPrep(dbc, "DELETE FROM '%q' WHERE hnum=?;", ++ dbi->dbi_file); ++ ++ if (!rc) ++ rc = dbiCursorBindPkg(dbc, hdrNum, NULL, 0); ++ ++ if (!rc) ++ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; ++ ++ return dbiCursorResult(dbc); + } + + static rpmRC sqlite_stepPkg(dbiCursor dbc, unsigned char **hdrBlob, unsigned int *hdrLen) +@@ -615,14 +637,39 @@ static rpmRC sqlite_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size + return rc; + } + +-static rpmRC sqlite_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) ++static rpmRC sqlite_idxdbPutOne(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) ++{ ++ int rc = dbiCursorPrep(dbc, "INSERT INTO '%q' VALUES(?, ?, ?)", ++ dbi->dbi_file); ++ ++ if (!rc) ++ rc = dbiCursorBindIdx(dbc, keyp, keylen, rec); ++ ++ if (!rc) ++ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; ++ ++ return dbiCursorResult(dbc); ++} ++ ++static rpmRC sqlite_idxdbPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) + { +- return RPMRC_FAIL; ++ return tag2index(dbi, rpmtag, hdrNum, h, sqlite_idxdbPutOne); + } + +-static rpmRC sqlite_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec) ++static rpmRC sqlite_idxdbDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) + { +- return RPMRC_FAIL; ++ dbiCursor dbc = dbiCursorInit(dbi, DBC_WRITE); ++ int rc = dbiCursorPrep(dbc, "DELETE FROM '%q' WHERE hnum=?", dbi->dbi_file); ++ ++ if (!rc) ++ rc = dbiCursorBindPkg(dbc, hdrNum, NULL, 0); ++ ++ if (!rc) ++ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {}; ++ ++ rc = dbiCursorResult(dbc); ++ dbiCursorFree(dbi, dbc); ++ return rc; + } + + static const void * sqlite_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen) +@@ -636,7 +683,12 @@ static const void * sqlite_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *k + return key; + } + ++ ++ + struct rpmdbOps_s sqlite_dbops = { ++ .name = "sqlite", ++ .path = "rpmdb.sqlite", ++ + .open = sqlite_Open, + .close = sqlite_Close, + .verify = sqlite_Verify, +@@ -650,7 +702,6 @@ struct rpmdbOps_s sqlite_dbops = { + .pkgdbDel = sqlite_pkgdbDel, + .pkgdbGet = sqlite_pkgdbGet, + .pkgdbKey = sqlite_pkgdbKey, +- .pkgdbNew = sqlite_pkgdbNew, + + .idxdbGet = sqlite_idxdbGet, + .idxdbPut = sqlite_idxdbPut, +diff --git a/lib/rpmdb.c b/lib/rpmdb.c +index 355cb08..cf5e6a7 100644 +--- a/lib/rpmdb.c ++++ b/lib/rpmdb.c +@@ -7,6 +7,8 @@ + #include + #include + #include ++#include ++#include + + #ifndef DYING /* XXX already in "system.h" */ + #include +@@ -32,6 +34,7 @@ + #include "lib/rpmdb_internal.h" + #include "lib/fprint.h" + #include "lib/header_internal.h" /* XXX for headerSetInstance() */ ++#include "lib/backend/dbi.h" + #include "lib/backend/dbiset.h" + #include "lib/misc.h" + #include "debug.h" +@@ -48,14 +51,6 @@ + #undef HTKEYTYPE + #undef HTDATATYPE + +-typedef rpmRC (*idxfunc)(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, +- dbiIndexItem rec); +- +-static rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, +- unsigned int hdrNum, Header h, +- idxfunc idxupdate); +- +-static rpmRC indexPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h); + static rpmdb rpmdbUnlink(rpmdb db); + + static int buildIndexes(rpmdb db) +@@ -87,7 +82,7 @@ static int buildIndexes(rpmdb db) + for (int dbix = 0; dbix < db->db_ndbi; dbix++) { + dbiIndex dbi = db->db_indexes[dbix]; + if (dbi && (dbiFlags(dbi) & DBI_CREATED)) { +- rc += indexPut(dbi, db->db_tags[dbix], hdrNum, h); ++ rc += idxdbPut(dbi, db->db_tags[dbix], hdrNum, h); + } + } + } +@@ -305,6 +300,7 @@ struct rpmdbIndexIterator_s { + dbiCursor ii_dbc; + dbiIndexSet ii_set; + unsigned int *ii_hdrNums; ++ int ii_skipdata; + }; + + static rpmdb rpmdbRock; +@@ -355,17 +351,22 @@ const char *rpmdbHome(rpmdb db) + return dbdir; + } + +-int rpmdbOpenAll(rpmdb db) ++static int doOpen(rpmdb db, int justPkgs) + { +- int rc = 0; ++ int rc = pkgdbOpen(db, db->db_flags, NULL); ++ if (!justPkgs) { ++ for (int dbix = 0; rc == 0 && dbix < db->db_ndbi; dbix++) { ++ rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL); ++ } ++ } ++ return rc; ++} + ++int rpmdbOpenAll(rpmdb db) ++{ + if (db == NULL) return -2; + +- rc = pkgdbOpen(db, db->db_flags, NULL); +- for (int dbix = 0; dbix < db->db_ndbi; dbix++) { +- rc += indexOpen(db, db->db_tags[dbix], db->db_flags, NULL); +- } +- return rc; ++ return doOpen(db, 0); + } + + static int dbiForeach(dbiIndex *dbis, int ndbi, +@@ -415,7 +416,6 @@ int rpmdbClose(rpmdb db) + db->db_fullpath = _free(db->db_fullpath); + db->db_checked = dbChkFree(db->db_checked); + db->db_indexes = _free(db->db_indexes); +- db->db_descr = _free(db->db_descr); + + if (next) { + *prev = next->db_next; +@@ -480,7 +480,6 @@ static rpmdb newRpmdb(const char * root, const char * home, + db->db_tags = dbiTags; + db->db_ndbi = sizeof(dbiTags) / sizeof(rpmDbiTag); + db->db_indexes = xcalloc(db->db_ndbi, sizeof(*db->db_indexes)); +- db->db_descr = xstrdup("unknown db"); + db->nrefs = 0; + return rpmdbLink(db); + } +@@ -508,13 +507,18 @@ static int openDatabase(const char * prefix, + /* Try to ensure db home exists, error out if we can't even create */ + rc = rpmioMkpath(rpmdbHome(db), 0755, getuid(), getgid()); + if (rc == 0) { ++ /* Open just bare minimum when rebuilding a potentially damaged db */ ++ int justPkgs = (db->db_flags & RPMDB_FLAG_REBUILD) && ++ ((db->db_mode & O_ACCMODE) == O_RDONLY); + /* Enable signal queue on the first db open */ + if (db->db_next == NULL) { + rpmsqActivate(1); + } + +- /* Just the primary Packages database opened here */ +- rc = pkgdbOpen(db, db->db_flags, NULL); ++ rc = doOpen(db, justPkgs); ++ ++ if (!db->db_descr) ++ db->db_descr = "unknown db"; + } + + if (rc || justCheck || dbp == NULL) +@@ -552,10 +556,7 @@ int rpmdbInit (const char * prefix, int perms) + + rc = openDatabase(prefix, NULL, &db, (O_CREAT | O_RDWR), perms, 0); + if (db != NULL) { +- int xx; +- xx = rpmdbOpenAll(db); +- if (xx && rc == 0) rc = xx; +- xx = rpmdbClose(db); ++ int xx = rpmdbClose(db); + if (xx && rc == 0) rc = xx; + db = NULL; + } +@@ -571,8 +572,6 @@ int rpmdbVerify(const char * prefix) + + if (db != NULL) { + int xx; +- rc = rpmdbOpenAll(db); +- + + if (db->db_pkgs) + rc += dbiVerify(db->db_pkgs, 0); +@@ -979,7 +978,7 @@ static int miFreeHeader(rpmdbMatchIterator mi, dbiIndex dbi) + if (hdrBlob != NULL && rpmrc != RPMRC_FAIL) { + rpmsqBlock(SIG_BLOCK); + dbCtrl(mi->mi_db, DB_CTRL_LOCK_RW); +- rc = pkgdbPut(dbi, mi->mi_dbc, mi->mi_prevoffset, ++ rc = pkgdbPut(dbi, mi->mi_dbc, &mi->mi_prevoffset, + hdrBlob, hdrLen); + dbCtrl(mi->mi_db, DB_CTRL_INDEXSYNC); + dbCtrl(mi->mi_db, DB_CTRL_UNLOCK_RW); +@@ -1588,6 +1587,7 @@ int rpmdbExtendIterator(rpmdbMatchIterator mi, + dbiIndexSetAppendSet(mi->mi_set, set, 0); + dbiIndexSetFree(set); + } ++ mi->mi_sorted = 0; + rc = 0; + } + +@@ -1649,6 +1649,7 @@ int rpmdbAppendIterator(rpmdbMatchIterator mi, + + for (unsigned int i = 0; i < nHdrNums; i++) + dbiIndexSetAppendOne(mi->mi_set, hdrNums[i], 0, 0); ++ mi->mi_sorted = 0; + return 0; + } + +@@ -1891,6 +1892,13 @@ rpmdbIndexIterator rpmdbIndexIteratorInit(rpmdb db, rpmDbiTag rpmtag) + return ii; + } + ++rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag) ++{ ++ rpmdbIndexIterator ki = rpmdbIndexIteratorInit(db, rpmtag); ++ ki->ii_skipdata = 1; ++ return ki; ++} ++ + int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * keylen) + { + int rc; +@@ -1905,7 +1913,8 @@ int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * ke + /* free old data */ + ii->ii_set = dbiIndexSetFree(ii->ii_set); + +- rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0, &ii->ii_set, DBC_NORMAL_SEARCH); ++ rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0, ++ ii->ii_skipdata ? NULL : &ii->ii_set, DBC_NORMAL_SEARCH); + + *key = idxdbKey(ii->ii_dbi, ii->ii_dbc, &iikeylen); + *keylen = iikeylen; +@@ -1973,7 +1982,7 @@ unsigned int rpmdbIndexIteratorPkgOffset(rpmdbIndexIterator ii, unsigned int nr) + return dbiIndexRecordOffset(ii->ii_set, nr); + } + +-unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii) ++const unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii) + { + int i; + +@@ -2042,11 +2051,6 @@ static void logAddRemove(const char *dbiname, int removing, rpmtd tagdata) + } + } + +-static rpmRC indexDel(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) +-{ +- return tag2index(dbi, rpmtag, hdrNum, h, idxdbDel); +-} +- + int rpmdbRemove(rpmdb db, unsigned int hdrNum) + { + dbiIndex dbi = NULL; +@@ -2088,7 +2092,7 @@ int rpmdbRemove(rpmdb db, unsigned int hdrNum) + if (indexOpen(db, rpmtag, 0, &dbi)) + continue; + +- ret += indexDel(dbi, rpmtag, hdrNum, h); ++ ret += idxdbDel(dbi, rpmtag, hdrNum, h); + } + } + +@@ -2185,7 +2189,7 @@ static rpmRC updateRichDep(dbiIndex dbi, dbiCursor dbc, const char *str, + return rc; + } + +-static rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, ++rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, + unsigned int hdrNum, Header h, + idxfunc idxupdate) + { +@@ -2244,8 +2248,8 @@ static rpmRC tag2index(dbiIndex dbi, rpmTagVal rpmtag, + case RPMTAG_REQUIRENAME: { + /* Filter out install prerequisites. */ + rpm_flag_t *rflag = rpmtdNextUint32(&reqflags); +- if (rflag && isInstallPreReq(*rflag) && +- !isErasePreReq(*rflag)) ++ if (rflag && isInstallPreReq(*rflag) && ++ !isErasePreReq(*rflag)) + continue; + break; + } +@@ -2295,11 +2299,6 @@ exit: + return (rc == 0) ? RPMRC_OK : RPMRC_FAIL; + } + +-static rpmRC indexPut(dbiIndex dbi, rpmTagVal rpmtag, unsigned int hdrNum, Header h) +-{ +- return tag2index(dbi, rpmtag, hdrNum, h, idxdbPut); +-} +- + int rpmdbAdd(rpmdb db, Header h) + { + dbiIndex dbi = NULL; +@@ -2327,9 +2326,7 @@ int rpmdbAdd(rpmdb db, Header h) + + /* Add header to primary index */ + dbc = dbiCursorInit(dbi, DBC_WRITE); +- ret = pkgdbNew(dbi, dbc, &hdrNum); +- if (ret == 0) +- ret = pkgdbPut(dbi, dbc, hdrNum, hdrBlob, hdrLen); ++ ret = pkgdbPut(dbi, dbc, &hdrNum, hdrBlob, hdrLen); + dbiCursorFree(dbi, dbc); + + /* Add associated data to secondary indexes */ +@@ -2340,7 +2337,7 @@ int rpmdbAdd(rpmdb db, Header h) + if (indexOpen(db, rpmtag, 0, &dbi)) + continue; + +- ret += indexPut(dbi, rpmtag, hdrNum, h); ++ ret += idxdbPut(dbi, rpmtag, hdrNum, h); + } + } + +@@ -2487,7 +2484,8 @@ static int rpmdbSetPermissions(char * src, char * dest) + } + + int rpmdbRebuild(const char * prefix, rpmts ts, +- rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg)) ++ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg), ++ int rebuildflags) + { + rpmdb olddb; + char * dbpath = NULL; +@@ -2527,7 +2525,9 @@ int rpmdbRebuild(const char * prefix, rpmts ts, + } + + if (openDatabase(prefix, dbpath, &olddb, +- O_RDONLY, 0644, RPMDB_FLAG_REBUILD)) { ++ O_RDONLY, 0644, RPMDB_FLAG_REBUILD | ++ (rebuildflags & RPMDB_REBUILD_FLAG_SALVAGE ? ++ RPMDB_FLAG_SALVAGE : 0))) { + rc = 1; + goto exit; + } +@@ -2536,10 +2536,6 @@ int rpmdbRebuild(const char * prefix, rpmts ts, + rc = 1; + goto exit; + } +- if (rpmdbOpenAll(newdb)) { +- rc = 1; +- goto exit; +- } + + { Header h = NULL; + rpmdbMatchIterator mi; +@@ -2584,6 +2580,7 @@ int rpmdbRebuild(const char * prefix, rpmts ts, + } + + rpmdbClose(olddb); ++ dbCtrl(newdb, DB_CTRL_INDEXSYNC); + rpmdbClose(newdb); + + if (failed) { +@@ -2644,3 +2641,50 @@ int rpmdbCtrl(rpmdb db, rpmdbCtrlOp ctrl) + return dbctrl ? dbCtrl(db, dbctrl) : 1; + } + ++char *rpmdbCookie(rpmdb db) ++{ ++ void *cookie = NULL; ++ rpmdbIndexIterator ii = rpmdbIndexIteratorInit(db, RPMDBI_NAME); ++ ++ if (ii) { ++ DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); ++ const void *key = 0; ++ size_t keylen = 0; ++ while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) { ++ const unsigned int *offsets = rpmdbIndexIteratorPkgOffsets(ii); ++ unsigned int npkgs = rpmdbIndexIteratorNumPkgs(ii); ++ rpmDigestUpdate(ctx, key, keylen); ++ rpmDigestUpdate(ctx, offsets, sizeof(*offsets) * npkgs); ++ } ++ rpmDigestFinal(ctx, &cookie, NULL, 1); ++ } ++ rpmdbIndexIteratorFree(ii); ++ return cookie; ++} ++ ++int rpmdbFStat(rpmdb db, struct stat *statbuf) ++{ ++ int rc = -1; ++ if (db) { ++ const char *dbfile = db->db_ops->path; ++ if (dbfile) { ++ char *path = rpmGenPath(rpmdbHome(db), dbfile, NULL); ++ rc = stat(path, statbuf); ++ free(path); ++ } ++ } ++ return rc; ++} ++ ++int rpmdbStat(const char *prefix, struct stat *statbuf) ++{ ++ rpmdb db = NULL; ++ int flags = RPMDB_FLAG_VERIFYONLY; ++ int rc = -1; ++ ++ if (openDatabase(prefix, NULL, &db, O_RDONLY, 0644, flags) == 0) { ++ rc = rpmdbFStat(db, statbuf); ++ rpmdbClose(db); ++ } ++ return rc; ++} +diff --git a/lib/rpmdb.h b/lib/rpmdb.h +index 78765bb..8e3ab5a 100644 +--- a/lib/rpmdb.h ++++ b/lib/rpmdb.h +@@ -8,6 +8,7 @@ + + #include + #include ++#include + + #ifdef __cplusplus + extern "C" { +@@ -152,6 +153,14 @@ Header rpmdbNextIterator(rpmdbMatchIterator mi); + */ + rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); + ++/** \ingroup rpmdb ++ * Get an iterator for index keys ++ * @param db rpm database ++ * @param rpmtag the index to iterate over ++ * @return the index iterator ++ */ ++rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag); ++ + /** \ingroup rpmdb + * Get an iterator for an index + * @param db rpm database +@@ -218,6 +227,30 @@ rpmdbIndexIterator rpmdbIndexIteratorFree(rpmdbIndexIterator ii); + */ + int rpmdbCtrl(rpmdb db, rpmdbCtrlOp ctrl); + ++/** \ingroup rpmdb ++ * Retrieve rpm database changed-cookie. ++ * Useful for eg. determining cache validity. ++ * @param db rpm database ++ * @return cookie string (malloced), or NULL on error ++ */ ++char *rpmdbCookie(rpmdb db); ++ ++/** \ingroup rpmdb ++ * Perform stat() on rpm database ++ * @param prefix prefix or NULL for / ++ * @retval statbuf returned data from stat() ++ * @return 0 on success, -1 on error ++ */ ++int rpmdbStat(const char *prefix, struct stat *statbuf); ++ ++/** \ingroup rpmdb ++ * Perform stat() on an open rpm database ++ * @param db rpm database ++ * @retval statbuf returned data from stat() ++ * @return 0 on success, -1 on error ++ */ ++int rpmdbFStat(rpmdb db, struct stat *statbuf); ++ + #ifdef __cplusplus + } + #endif +diff --git a/lib/rpmdb_internal.h b/lib/rpmdb_internal.h +index 92848ab..d7446e5 100644 +--- a/lib/rpmdb_internal.h ++++ b/lib/rpmdb_internal.h +@@ -23,6 +23,10 @@ extern "C" { + #undef HTKEYTYPE + #undef HTDATATYPE + ++enum rpmdbRebuildFlags_e { ++ RPMDB_REBUILD_FLAG_SALVAGE = (1 << 0), ++}; ++ + /** \ingroup rpmdb + * Reference a database instance. + * @param db rpm database +@@ -63,11 +67,13 @@ int rpmdbClose (rpmdb db); + * @param prefix path to top of install tree + * @param ts transaction set (or NULL) + * @param (*hdrchk) headerCheck() vector (or NULL) ++ * @param rebuildflags flags + * @return 0 on success + */ + RPM_GNUC_INTERNAL + int rpmdbRebuild(const char * prefix, rpmts ts, +- rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg)); ++ rpmRC (*hdrchk) (rpmts ts, const void *uh, size_t uc, char ** msg), ++ int rebuildflags); + + /** \ingroup rpmdb + * Verify database components. +@@ -175,7 +181,7 @@ rpmdbMatchIterator rpmdbInitPrefixIterator(rpmdb db, rpmDbiTagVal rpmtag, + * @return db offsets of pkgs + */ + RPM_GNUC_INTERNAL +-unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii); ++const unsigned int *rpmdbIndexIteratorPkgOffsets(rpmdbIndexIterator ii); + + /** \ingroup rpmdb + * Return current index (position) in iterator. +diff --git a/lib/rpmts.c b/lib/rpmts.c +index 7131b7b..122a2ff 100644 +--- a/lib/rpmts.c ++++ b/lib/rpmts.c +@@ -135,17 +135,21 @@ int rpmtsRebuildDB(rpmts ts) + { + int rc = -1; + rpmtxn txn = NULL; ++ int rebuildflags = 0; + + /* Cannot do this on a populated transaction set */ + if (rpmtsNElements(ts) > 0) + return -1; + ++ if (rpmExpandNumeric("%{?_rebuilddb_salvage}")) ++ rebuildflags |= RPMDB_REBUILD_FLAG_SALVAGE; ++ + txn = rpmtxnBegin(ts, RPMTXN_WRITE); + if (txn) { + if (!(ts->vsflags & RPMVSF_NOHDRCHK)) +- rc = rpmdbRebuild(ts->rootDir, ts, headerCheck); ++ rc = rpmdbRebuild(ts->rootDir, ts, headerCheck, rebuildflags); + else +- rc = rpmdbRebuild(ts->rootDir, NULL, NULL); ++ rc = rpmdbRebuild(ts->rootDir, NULL, NULL, rebuildflags); + rpmtxnEnd(txn); + } + return rc; +diff --git a/macros.in b/macros.in +index fa2c29b..a0f7b13 100644 +--- a/macros.in ++++ b/macros.in +@@ -629,7 +629,7 @@ package or when debugging this package.\ + # ndb new data base format + # sqlite Sqlite database (read-only in this version!) + # +-%_db_backend bdb ++%_db_backend sqlite + + # + # Macros used to configure Berkley db parameters. +diff --git a/rpmdb.c b/rpmdb.c +index 25c088d..b72f0a5 100644 +--- a/rpmdb.c ++++ b/rpmdb.c +@@ -12,6 +12,7 @@ enum modes { + MODE_VERIFYDB = (1 << 2), + MODE_EXPORTDB = (1 << 3), + MODE_IMPORTDB = (1 << 4), ++ MODE_SALVAGEDB = (1 << 5), + }; + + static int mode = 0; +@@ -24,6 +25,8 @@ static struct poptOption dbOptsTable[] = { + NULL}, + { "verifydb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN), + &mode, MODE_VERIFYDB, N_("verify database files"), NULL}, ++ { "salvagedb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN), ++ &mode, MODE_SALVAGEDB, N_("salvage database"), NULL}, + { "exportdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_EXPORTDB, + N_("export database to stdout header list"), + NULL}, +@@ -108,8 +111,11 @@ int main(int argc, char *argv[]) + ec = rpmtsInitDB(ts, 0644); + break; + case MODE_REBUILDDB: ++ case MODE_SALVAGEDB: + { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}"); + rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags); ++ if (mode == MODE_SALVAGEDB) ++ rpmDefineMacro(NULL, "_rebuilddb_salvage 1", 0); + ec = rpmtsRebuildDB(ts); + rpmtsSetVSFlags(ts, ovsflags); + } break; +-- +2.39.3 + diff --git a/rpm.spec b/rpm.spec index f156b3d..6ba7677 100644 --- a/rpm.spec +++ b/rpm.spec @@ -22,6 +22,8 @@ %bcond_with lmdb # build with readonly sqlite support? %bcond_without sqlite +# build with bdb_ro support? +%bcond_without bdb_ro %if 0%{?rhel} > 7 || 0%{?anolis} # Disable python2 build by default @@ -168,6 +170,8 @@ Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch Patch2000: 1000-rpm-anolis-support-loongarch.patch Patch2001: 0001-debugedit-add-loongarch-support.patch +Patch2002: 0001-support-sqlite-backend-rpmdb.patch + # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD License: GPLv2+ @@ -493,6 +497,7 @@ done; %{?with_zstd: --enable-zstd} \ %{?with_lmdb: --enable-lmdb} \ %{?with_sqlite: --enable-sqlite} \ + %{?with_bdb_ro: --enable-bdb-ro} \ --with-fapolicyd \ --enable-python \ --with-crypto=openssl \ @@ -571,6 +576,18 @@ chmod a-x $RPM_BUILD_ROOT/%{rpmhome}/python-macro-helper make check || cat tests/rpmtests.log %endif +%pre +# Only update +if [ $1 == 2 ] +then + [ -e /var/lib/rpm/.rpm.lock ] && rm -f /var/lib/rpm/.rpm.lock + [ `rpm --eval "%_db_backend"` == "bdb" ] && rpmdb --exportdb > /var/lib/rpm_bdb_bak +fi + +%posttrans +[ -e /var/lib/rpm/.rpm.lock ] && rm -f /var/lib/rpm/.rpm.lock +rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb + %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig @@ -722,6 +739,7 @@ make check || cat tests/rpmtests.log - Support loongarch for rpm - Add loongarch64 support for debugedit(doupengda@loongson.cn) - Modify the spec to add debugedit for loongarch64(zhangwenlong@loongson.cn) +- Support and switch rpmdb to sqlite (flin@linux.alibaba.com) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 055bae12ba3d05a39093eb801495e106acdffbea Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Tue, 25 Jul 2023 13:57:43 +0800 Subject: [PATCH 08/15] conditional set relbuf for loongarch debugedit Signed-off-by: Liwei Ge --- 0001-debugedit-add-loongarch-support.patch | 4 +++- rpm.spec | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/0001-debugedit-add-loongarch-support.patch b/0001-debugedit-add-loongarch-support.patch index 363ebfd..f75846c 100644 --- a/0001-debugedit-add-loongarch-support.patch +++ b/0001-debugedit-add-loongarch-support.patch @@ -11,14 +11,16 @@ diff --git a/tools/debugedit.c b/tools/debugedit.c index 4ec431f..fb0325b 100644 --- a/tools/debugedit.c +++ b/tools/debugedit.c -@@ -597,6 +597,10 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype) +@@ -597,6 +597,12 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype) goto fail; break; #endif ++#if defined(EM_LOONGARCH) + case EM_LOONGARCH: + if ((rtype != R_LARCH_32) && (rtype != R_LARCH_64)) + goto fail; + break; ++#endif default: fail: error (1, 0, "%s: Unhandled relocation %d in %s section", diff --git a/rpm.spec b/rpm.spec index 6ba7677..de8eb29 100644 --- a/rpm.spec +++ b/rpm.spec @@ -740,6 +740,7 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - Add loongarch64 support for debugedit(doupengda@loongson.cn) - Modify the spec to add debugedit for loongarch64(zhangwenlong@loongson.cn) - Support and switch rpmdb to sqlite (flin@linux.alibaba.com) +- conditional set relbuf for loongarch debugedit (geliwei@openanolis.org) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 4fc0ae31a58a63bd2232a24b261ac730f755a557 Mon Sep 17 00:00:00 2001 From: forrest_ly Date: Tue, 25 Jul 2023 06:30:35 +0000 Subject: [PATCH 09/15] =?UTF-8?q?=E9=9A=94=E7=A6=BBloongarch64=E8=A1=A5?= =?UTF-8?q?=E4=B8=81=EF=BC=8C=E5=8F=AA=E5=9C=A8=E7=BC=96=E8=AF=91loongarch?= =?UTF-8?q?64=E6=9E=B6=E6=9E=84=E6=97=B6apply=20=E9=9A=94=E7=A6=BBloongarc?= =?UTF-8?q?h64=E8=A1=A5=E4=B8=81=EF=BC=8C=E5=8F=AA=E5=9C=A8=E7=BC=96?= =?UTF-8?q?=E8=AF=91loongarch64=E6=9E=B6=E6=9E=84=E6=97=B6apply?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: forrest_ly --- rpm.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpm.spec b/rpm.spec index de8eb29..42a9ac2 100644 --- a/rpm.spec +++ b/rpm.spec @@ -167,8 +167,10 @@ Patch1002: rpm-4.14.2-unversioned-python.patch # Make brp-python-bytecompile compatible with Python 3.10+ Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch +%ifarch loongarch64 Patch2000: 1000-rpm-anolis-support-loongarch.patch Patch2001: 0001-debugedit-add-loongarch-support.patch +%endif Patch2002: 0001-support-sqlite-backend-rpmdb.patch -- Gitee From 14b44c83ad208e87dd208c41abaa461e997defed Mon Sep 17 00:00:00 2001 From: Chunmei Xu Date: Thu, 7 Sep 2023 15:09:39 +0800 Subject: [PATCH 10/15] avoid dead loop in db3_dbiOpen when db_create failed Signed-off-by: Chunmei Xu --- ...in-db3_dbiOpen-when-db_create-failed.patch | 26 +++++++++++++++++++ rpm.spec | 19 +++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch diff --git a/3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch b/3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch new file mode 100644 index 0000000..a17a373 --- /dev/null +++ b/3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch @@ -0,0 +1,26 @@ +From b361ad80a41a07c62fc8f21cda534b35c971ace7 Mon Sep 17 00:00:00 2001 +From: Chunmei Xu +Date: Wed, 6 Sep 2023 11:11:11 +0800 +Subject: [PATCH] avoid dead loop in db3_dbiOpen when db_create failed + +Signed-off-by: Chunmei Xu +--- + lib/backend/db3.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/backend/db3.c b/lib/backend/db3.c +index da50dfd..24fbe00 100644 +--- a/lib/backend/db3.c ++++ b/lib/backend/db3.c +@@ -899,6 +899,8 @@ static int db3_dbiOpen(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flag + db->close(db, 0); + db = NULL; + } ++ } else { ++ retry_open--; + } + } + +-- +2.39.3 + diff --git a/rpm.spec b/rpm.spec index 42a9ac2..30b3f81 100644 --- a/rpm.spec +++ b/rpm.spec @@ -23,7 +23,8 @@ # build with readonly sqlite support? %bcond_without sqlite # build with bdb_ro support? -%bcond_without bdb_ro +# if enabled, rpmdb is switched to sqlite +%bcond_with bdb_ro %if 0%{?rhel} > 7 || 0%{?anolis} # Disable python2 build by default @@ -167,12 +168,14 @@ Patch1002: rpm-4.14.2-unversioned-python.patch # Make brp-python-bytecompile compatible with Python 3.10+ Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch -%ifarch loongarch64 Patch2000: 1000-rpm-anolis-support-loongarch.patch Patch2001: 0001-debugedit-add-loongarch-support.patch -%endif -Patch2002: 0001-support-sqlite-backend-rpmdb.patch +# bugfix for anolis +Patch3001: 3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch + +# defined as source file to seperate with other patches +Source1000: 0001-support-sqlite-backend-rpmdb.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -455,6 +458,10 @@ Obsoletes: fapolicyd-dnf-plugin %prep %autosetup -n %{name}-%{srcver} %{?with_int_bdb:-a 1} -p1 +%if %{with bdb_ro} +patch -p1 < %{SOURCE1000} +%endif + %if %{with int_bdb} ln -s db-%{bdbver} db %endif @@ -578,6 +585,7 @@ chmod a-x $RPM_BUILD_ROOT/%{rpmhome}/python-macro-helper make check || cat tests/rpmtests.log %endif +%if %{with bdb_ro} %pre # Only update if [ $1 == 2 ] @@ -589,6 +597,7 @@ fi %posttrans [ -e /var/lib/rpm/.rpm.lock ] && rm -f /var/lib/rpm/.rpm.lock rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb +%endif %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig @@ -743,6 +752,8 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - Modify the spec to add debugedit for loongarch64(zhangwenlong@loongson.cn) - Support and switch rpmdb to sqlite (flin@linux.alibaba.com) - conditional set relbuf for loongarch debugedit (geliwei@openanolis.org) +- avoid dead loop in db3_dbiOpen when db_create failed (xuchunmei@linux.alibaba.com) +- do not switch rpmdb to sqlite (xuchunmei@linux.alibaba.com) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 346d1a5115951891ccb66cfc610ce1ef414d417f Mon Sep 17 00:00:00 2001 From: wangkaiqiang Date: Thu, 25 Jan 2024 00:07:58 +0800 Subject: [PATCH 11/15] Fix a copy-paste --help description of --whatconflicts --- ...te-help-description-of-whatconflicts.patch | 41 +++++++++++++++++++ rpm.spec | 5 +++ 2 files changed, 46 insertions(+) create mode 100644 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch diff --git a/0001-fix-a-copy-paste-help-description-of-whatconflicts.patch b/0001-fix-a-copy-paste-help-description-of-whatconflicts.patch new file mode 100644 index 0000000..f02f4f7 --- /dev/null +++ b/0001-fix-a-copy-paste-help-description-of-whatconflicts.patch @@ -0,0 +1,41 @@ +From a5d0255696890889b73e27a0ad4a57368aef8220 Mon Sep 17 00:00:00 2001 +From: wangkaiqiang +Date: Wed, 24 Jan 2024 23:59:16 +0800 +Subject: [PATCH] fix a copy-paste --help description of --whatconflicts + +--- + lib/poptQV.c | 2 +- + po/zh_CN.po | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lib/poptQV.c b/lib/poptQV.c +index f752d8b..73d38b4 100644 +--- a/lib/poptQV.c ++++ b/lib/poptQV.c +@@ -106,7 +106,7 @@ struct poptOption rpmQVSourcePoptTable[] = { + { "verify", 'V', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'V', + N_("rpm verify mode"), NULL }, + { "whatconflicts", '\0', 0, 0, POPT_WHATCONFLICTS, +- N_("query/verify the package(s) which require a dependency"), "CAPABILITY" }, ++ N_("query/verify the package(s) which conflict with a dependency"), "CAPABILITY" }, + { "whatrequires", '\0', 0, 0, POPT_WHATREQUIRES, + N_("query/verify the package(s) which require a dependency"), "CAPABILITY" }, + { "whatobsoletes", '\0', 0, 0, POPT_WHATOBSOLETES, +diff --git a/po/zh_CN.po b/po/zh_CN.po +index bf8cb53..7bfceb0 100644 +--- a/po/zh_CN.po ++++ b/po/zh_CN.po +@@ -2505,6 +2505,10 @@ msgstr "查找由软件包所触发的软件包" + msgid "rpm verify mode" + msgstr "rpm 校验模式" + ++#: lib/poptQV.c:108 lib/poptQV.c:109 ++msgid "query/verify the package(s) which conflict with a dependency" ++msgstr "查询/校验与依赖项冲突的软件包" ++ + #: lib/poptQV.c:105 lib/poptQV.c:107 + msgid "query/verify the package(s) which require a dependency" + msgstr "查找/校验需要某个依赖对象的软件包" +-- +2.31.1 + diff --git a/rpm.spec b/rpm.spec index 30b3f81..4c1bd12 100644 --- a/rpm.spec +++ b/rpm.spec @@ -174,6 +174,8 @@ Patch2001: 0001-debugedit-add-loongarch-support.patch # bugfix for anolis Patch3001: 3001-avoid-dead-loop-in-db3_dbiOpen-when-db_create-failed.patch +Patch3002: 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch + # defined as source file to seperate with other patches Source1000: 0001-support-sqlite-backend-rpmdb.patch @@ -754,6 +756,9 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - conditional set relbuf for loongarch debugedit (geliwei@openanolis.org) - avoid dead loop in db3_dbiOpen when db_create failed (xuchunmei@linux.alibaba.com) - do not switch rpmdb to sqlite (xuchunmei@linux.alibaba.com) +- Fix a copy-paste --help description of --whatconflicts (wangkaiqiang@inspur.com) +- https://bugzilla.openanolis.cn/show_bug.cgi?id=8035 (wangkaiqiang@inspur.com) + * Tue Dec 12 2023 Florian Festi - 4.14.3-31 - Backport file handling code from rpm-4.19 to fix CVE-2021-35937, -- Gitee From 113f842f90a43a150424745ea3a08e1dfd27d9c5 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 12 May 2023 17:34:04 +0800 Subject: [PATCH 12/15] add sw #0435c1628f2b60925114f847ef84b4a30de1f870 Signed-off-by: Weisson --- rpm-4.14.3-sw.patch | 119 ++++++++++++++++++++++++++++++++++++++++++++ rpm.spec | 2 + 2 files changed, 121 insertions(+) create mode 100644 rpm-4.14.3-sw.patch diff --git a/rpm-4.14.3-sw.patch b/rpm-4.14.3-sw.patch new file mode 100644 index 0000000..e227134 --- /dev/null +++ b/rpm-4.14.3-sw.patch @@ -0,0 +1,119 @@ +diff -Naur rpm-4.14.3.org/installplatform rpm-4.14.3.sw/installplatform +--- rpm-4.14.3.org/installplatform 2023-05-11 17:16:20.818506688 +0800 ++++ rpm-4.14.3.sw/installplatform 2023-05-12 14:44:13.520745718 +0800 +@@ -114,6 +114,12 @@ + CANONARCH=alpha + CANONCOLOR=0 + ;; ++ sw_64*) ++ ISANAME=sw_64 ++ ISABITS=64 ++ CANONARCH=sw_64 ++ CANONCOLOR=0 ++ ;; + aarch64) + ISANAME=aarch + ISABITS=64 +diff -Naur rpm-4.14.3.org/lib/rpmrc.c rpm-4.14.3.sw/lib/rpmrc.c +--- rpm-4.14.3.org/lib/rpmrc.c 2023-05-11 17:16:20.794506687 +0800 ++++ rpm-4.14.3.sw/lib/rpmrc.c 2023-05-12 17:30:27.072394959 +0800 +@@ -1247,6 +1247,13 @@ + strcpy(un.machine, "loongarch32"); + # endif /* __loongarch64 */ + ++ ++# if defined(__GNUC__) && defined(__alpha__) ++ { ++ strcpy(un.machine, "sw_64sw6b"); ++ } ++# endif ++ + # if defined(__GNUC__) && defined(__alpha__) + { + unsigned long amask, implver; +diff -Naur rpm-4.14.3.org/macros.in rpm-4.14.3.sw/macros.in +--- rpm-4.14.3.org/macros.in 2023-05-11 17:16:20.813506688 +0800 ++++ rpm-4.14.3.sw/macros.in 2023-05-12 14:54:53.461787376 +0800 +@@ -1154,6 +1154,10 @@ + %sparc sparc sparcv8 sparcv9 sparcv9v sparc64 sparc64v + + #------------------------------------------------------------------------------ ++# arch macro for all supported Sw_64 processors ++%sw_64 sw_64 sw_64sw6b ++ ++#------------------------------------------------------------------------------ + # arch macro for all supported Alpha processors + %alpha alpha alphaev56 alphaev6 alphaev67 + +diff -Naur rpm-4.14.3.org/rpmrc.in rpm-4.14.3.sw/rpmrc.in +--- rpm-4.14.3.org/rpmrc.in 2023-05-11 17:16:20.704506681 +0800 ++++ rpm-4.14.3.sw/rpmrc.in 2023-05-11 17:26:48.130547524 +0800 +@@ -25,6 +25,9 @@ + optflags: amd64 -O2 -g + optflags: ia32e -O2 -g + ++optflags: sw_64 -O2 -g -mieee ++optflags: sw_64sw6b -O2 -g -mieee -mtune=sw6b ++ + optflags: alpha -O2 -g -mieee + optflags: alphaev5 -O2 -g -mieee -mtune=ev5 + optflags: alphaev56 -O2 -g -mieee -mtune=ev56 +@@ -110,6 +113,7 @@ + archcolor: noarch 0 + archcolor: i386 1 + archcolor: alpha 2 ++archcolor: sw_64 2 + archcolor: sparc 1 + archcolor: sparc64 2 + archcolor: sparcv9 2 +@@ -173,6 +177,9 @@ + arch_canon: ia32e: ia32e 1 + arch_canon: em64t: em64t 1 + ++arch_canon: sw_64: sw_64 2 ++arch_canon: sw_64sw6b: sw_64sw6b 2 ++ + arch_canon: alpha: alpha 2 + arch_canon: alphaev5: alphaev5 2 + arch_canon: alphaev56: alphaev56 2 +@@ -310,6 +317,9 @@ + buildarchtranslate: i486: i386 + buildarchtranslate: i386: i386 + ++buildarchtranslate: sw_64: sw_64 ++buildarchtranslate: sw_64sw6b: sw_64 ++ + buildarchtranslate: alphaev5: alpha + buildarchtranslate: alphaev56: alpha + buildarchtranslate: alphapca56: alpha +@@ -402,6 +412,9 @@ + arch_compat: alphaev5: alpha + arch_compat: alpha: axp noarch + ++arch_compat: sw_64sw6b: sw_64 ++arch_compat: sw_64: axp noarch ++ + arch_compat: athlon: i686 + arch_compat: geode: i686 + arch_compat: pentium4: pentium3 +@@ -567,6 +580,9 @@ + buildarch_compat: alphaev5: alpha + buildarch_compat: alpha: noarch + ++buildarch_compat: sw_64sw6b: sw_64 ++buildarch_compat: sw_64: noarch ++ + buildarch_compat: m68k: noarch + + buildarch_compat: ppc8260: noarch +diff -Naur rpm-4.14.3.org/tools/elfdeps.c rpm-4.14.3.sw/tools/elfdeps.c +--- rpm-4.14.3.org/tools/elfdeps.c 2023-05-11 17:16:20.820506688 +0800 ++++ rpm-4.14.3.sw/tools/elfdeps.c 2023-05-12 14:45:04.537749039 +0800 +@@ -86,6 +86,7 @@ + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) { + switch (ehdr->e_machine) { + case EM_ALPHA: ++ case EM_SW_64: + case EM_FAKE_ALPHA: + /* alpha doesn't traditionally have 64bit markers */ + break; diff --git a/rpm.spec b/rpm.spec index 4c1bd12..2e970ff 100644 --- a/rpm.spec +++ b/rpm.spec @@ -178,6 +178,7 @@ Patch3002: 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch # defined as source file to seperate with other patches Source1000: 0001-support-sqlite-backend-rpmdb.patch +Patch2002: rpm-4.14.3-sw.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -758,6 +759,7 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - do not switch rpmdb to sqlite (xuchunmei@linux.alibaba.com) - Fix a copy-paste --help description of --whatconflicts (wangkaiqiang@inspur.com) - https://bugzilla.openanolis.cn/show_bug.cgi?id=8035 (wangkaiqiang@inspur.com) +- Add sw64 Architecture (nijie@wxiat.com) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 -- Gitee From 3bdff0b6685327b2ddbe6d3a53c72a1ddd0db85a Mon Sep 17 00:00:00 2001 From: Weisson Date: Thu, 18 Jan 2024 16:38:01 +0800 Subject: [PATCH 13/15] update config to support sw64 Architecture #2dc31a54cc38e40324a437a192da8e964e8d4904. Signed-off-by: Weisson --- 2002-rpm-anolis-support-sw_64.patch | 53 +++++++++++++++++++++++++++++ 2004-rpm-anolis-support-sw_64.patch | 53 +++++++++++++++++++++++++++++ rpm.spec | 2 ++ 3 files changed, 108 insertions(+) create mode 100644 2002-rpm-anolis-support-sw_64.patch create mode 100644 2004-rpm-anolis-support-sw_64.patch diff --git a/2002-rpm-anolis-support-sw_64.patch b/2002-rpm-anolis-support-sw_64.patch new file mode 100644 index 0000000..0fdee40 --- /dev/null +++ b/2002-rpm-anolis-support-sw_64.patch @@ -0,0 +1,53 @@ +From 8f1f102e29093740b8d0ebde97dbec84a2e36b73 Mon Sep 17 00:00:00 2001 +From: Weisson +Date: Thu, 18 Jan 2024 16:28:07 +0800 +Subject: [PATCH] update config utils to support sw. + +Signed-off-by: Weisson +--- + config.guess | 8 ++++++++ + config.sub | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/config.guess b/config.guess +index f32079a..5fa922c 100755 +--- a/config.guess ++++ b/config.guess +@@ -921,6 +921,14 @@ EOF + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ sw) UNAME_MACHINE=sw_64 ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi ++ echo ${UNAME_MACHINE}-sunway-linux-${LIBC} ++ exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; +diff --git a/config.sub b/config.sub +index 6759825..8273800 100755 +--- a/config.sub ++++ b/config.sub +@@ -238,6 +238,7 @@ case $basic_machine in + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ ++ | sw_64 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ +@@ -314,6 +315,7 @@ case $basic_machine in + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ ++ | sw_64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ +-- +2.31.1 + diff --git a/2004-rpm-anolis-support-sw_64.patch b/2004-rpm-anolis-support-sw_64.patch new file mode 100644 index 0000000..0fdee40 --- /dev/null +++ b/2004-rpm-anolis-support-sw_64.patch @@ -0,0 +1,53 @@ +From 8f1f102e29093740b8d0ebde97dbec84a2e36b73 Mon Sep 17 00:00:00 2001 +From: Weisson +Date: Thu, 18 Jan 2024 16:28:07 +0800 +Subject: [PATCH] update config utils to support sw. + +Signed-off-by: Weisson +--- + config.guess | 8 ++++++++ + config.sub | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/config.guess b/config.guess +index f32079a..5fa922c 100755 +--- a/config.guess ++++ b/config.guess +@@ -921,6 +921,14 @@ EOF + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ sw) UNAME_MACHINE=sw_64 ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi ++ echo ${UNAME_MACHINE}-sunway-linux-${LIBC} ++ exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; +diff --git a/config.sub b/config.sub +index 6759825..8273800 100755 +--- a/config.sub ++++ b/config.sub +@@ -238,6 +238,7 @@ case $basic_machine in + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ ++ | sw_64 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ +@@ -314,6 +315,7 @@ case $basic_machine in + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ ++ | sw_64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ +-- +2.31.1 + diff --git a/rpm.spec b/rpm.spec index 2e970ff..c90ec55 100644 --- a/rpm.spec +++ b/rpm.spec @@ -179,6 +179,7 @@ Patch3002: 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch # defined as source file to seperate with other patches Source1000: 0001-support-sqlite-backend-rpmdb.patch Patch2002: rpm-4.14.3-sw.patch +Patch2003: 2004-rpm-anolis-support-sw_64.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -760,6 +761,7 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - Fix a copy-paste --help description of --whatconflicts (wangkaiqiang@inspur.com) - https://bugzilla.openanolis.cn/show_bug.cgi?id=8035 (wangkaiqiang@inspur.com) - Add sw64 Architecture (nijie@wxiat.com) +- update config to support sw64 Architecture. (Weisson@linux.alibaba.com) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 -- Gitee From b562f126c9061261351cd4393cae1292f23b504d Mon Sep 17 00:00:00 2001 From: Weisson Date: Mon, 8 Apr 2024 15:08:24 +0800 Subject: [PATCH 14/15] keep compatibility between sw and other architecture. Signed-off-by: Weisson --- ...ty-between-sw-and-other-architecture.patch | 31 +++++++++++++++++++ rpm.spec | 2 ++ 2 files changed, 33 insertions(+) create mode 100644 rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch diff --git a/rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch b/rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch new file mode 100644 index 0000000..8902a97 --- /dev/null +++ b/rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch @@ -0,0 +1,31 @@ +From 38131090ed022d9e133ccf601004e7ec1745d87c Mon Sep 17 00:00:00 2001 +From: Weisson +Date: Mon, 8 Apr 2024 14:59:22 +0800 +Subject: [PATCH] keep compatibility between sw and other architecture. + +Signed-off-by: Weisson +--- + system.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/system.h b/system.h +index 570cef1..a8f3043 100644 +--- a/system.h ++++ b/system.h +@@ -127,4 +127,13 @@ extern int fdatasync(int fildes); + + #include + ++/* ============= for sw arch compatibility ======== */ ++#ifndef EM_SW_64 ++# ifndef SW_64 ++# define EM_SW_64 0x9916 ++# else ++# define EM_SW_64 0x9906 ++# endif ++#endif ++ + #endif /* H_SYSTEM */ +-- +2.39.3 + diff --git a/rpm.spec b/rpm.spec index c90ec55..db0ee7b 100644 --- a/rpm.spec +++ b/rpm.spec @@ -180,6 +180,7 @@ Patch3002: 0001-fix-a-copy-paste-help-description-of-whatconflicts.patch Source1000: 0001-support-sqlite-backend-rpmdb.patch Patch2002: rpm-4.14.3-sw.patch Patch2003: 2004-rpm-anolis-support-sw_64.patch +Patch2004: rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -762,6 +763,7 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - https://bugzilla.openanolis.cn/show_bug.cgi?id=8035 (wangkaiqiang@inspur.com) - Add sw64 Architecture (nijie@wxiat.com) - update config to support sw64 Architecture. (Weisson@linux.alibaba.com) +- keep compatibility between sw and other architecture. (Weisson@linux.alibaba.com) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 -- Gitee From d6db181d25e777e3b217558e0cd86906bbca4210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AE=E4=B9=A6?= Date: Wed, 29 May 2024 02:22:03 +0000 Subject: [PATCH 15/15] !46 Fix compatibility of debugedit tool on sw_64 platform. * Fix compatibility of debugedit tool on sw_64 platform. --- ...y-of-debugedit-tool-on-sw_64-platfor.patch | 42 +++++++++++++++++++ rpm.spec | 2 + 2 files changed, 44 insertions(+) create mode 100644 rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch diff --git a/rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch b/rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch new file mode 100644 index 0000000..16f0d82 --- /dev/null +++ b/rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch @@ -0,0 +1,42 @@ +From 4c18e2a55783adc416834c86a6ed8491d8347236 Mon Sep 17 00:00:00 2001 +From: Weisson +Date: Tue, 28 May 2024 15:24:55 +0800 +Subject: [PATCH] Fix compatibility of debugedit tool on sw_64 platform. + +Signed-off-by: Weisson +--- + system.h | 4 ++++ + tools/debugedit.c | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/system.h b/system.h +index a8f3043..666ab5e 100644 +--- a/system.h ++++ b/system.h +@@ -136,4 +136,8 @@ extern int fdatasync(int fildes); + # endif + #endif + ++#ifndef R_SW_64_REFLONG ++# define R_SW_64_REFLONG 1 ++#endif ++ + #endif /* H_SYSTEM */ +diff --git a/tools/debugedit.c b/tools/debugedit.c +index 1d1c808..759ce26 100644 +--- a/tools/debugedit.c ++++ b/tools/debugedit.c +@@ -581,6 +581,10 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype) + if (rtype != R_ALPHA_REFLONG) + goto fail; + break; ++ case EM_SW_64: ++ if (rtype != R_SW_64_REFLONG) ++ goto fail; ++ break; + #if defined(EM_AARCH64) && defined(R_AARCH64_ABS32) + case EM_AARCH64: + if (rtype != R_AARCH64_ABS32) +-- +1.8.3.1 + diff --git a/rpm.spec b/rpm.spec index db0ee7b..5366433 100644 --- a/rpm.spec +++ b/rpm.spec @@ -181,6 +181,7 @@ Source1000: 0001-support-sqlite-backend-rpmdb.patch Patch2002: rpm-4.14.3-sw.patch Patch2003: 2004-rpm-anolis-support-sw_64.patch Patch2004: rpm-4.14.3-keep-compatibility-between-sw-and-other-architecture.patch +Patch2005: rpm-4.14.3-Fix-compatibility-of-debugedit-tool-on-sw_64-platfor.patch # Partially GPL/LGPL dual-licensed and some bits with BSD # SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD @@ -764,6 +765,7 @@ rpm -q rpm 2>&1 | grep bdb && rpmdb --rebuilddb - Add sw64 Architecture (nijie@wxiat.com) - update config to support sw64 Architecture. (Weisson@linux.alibaba.com) - keep compatibility between sw and other architecture. (Weisson@linux.alibaba.com) +- Fix compatibility of debugedit tool on sw_64 platform. (Weisson@linux.alibaba.com) * Tue Dec 12 2023 Florian Festi - 4.14.3-31 -- Gitee