summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--8fc4e71f9b51438f09c8206ceb1b407bbaca8aab.patch30
-rw-r--r--Add-IMA-digest-list-support.patch622
-rw-r--r--Add-digest-list-plugin.patch700
-rw-r--r--Add-loongarch-architecture-support.patch75
-rw-r--r--Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch40
-rw-r--r--add-default-machine-name-to-support-loongarch.patch30
-rw-r--r--add-dist-to-release-by-default.patch37
-rw-r--r--backport-An-enumeration-is-not-a-bitfield-use-an-integer-inst.patch36
-rw-r--r--backport-Check-inside-root-when-querying-for-files.patch38
-rw-r--r--backport-Fix-V-option-usage-in-our-tests.patch242
-rw-r--r--backport-Fix-a-memleak-on-invalid-command-line-options.patch85
-rw-r--r--backport-Fix-a-theoretical-use-of-uninitialized-struct-member.patch31
-rw-r--r--backport-Fix-an-ancient-memleak-on-caps-parsing-add-tests.patch34
-rw-r--r--backport-Fix-an-enum-int-type-mismatch-in-rpmfiArchiveReadToF.patch32
-rw-r--r--backport-Fix-an-enum-int-type-mismatch-in-transaction-verify-.patch28
-rw-r--r--backport-Fix-crash-on-Lua-file-trigger-exiting-with-return-ed.patch81
-rw-r--r--backport-Fix-division-by-zero-in-elfdeps-RhBug-2299414.patch30
-rw-r--r--backport-Fix-enum-type-mismatch-in-rpmTagGetValue.patch30
-rw-r--r--backport-Fix-pointer-bogosity-in-rpmlog-callback.patch31
-rw-r--r--backport-Fix-potential-use-of-uninitialized-pgp-struct.patch35
-rw-r--r--backport-Fix-potential-use-of-uninitialized-pipe-array.patch35
-rw-r--r--backport-Fix-root-relocation-regression.patch66
-rw-r--r--backport-Fix-some-int-enum-confusion-in-the-build-code.patch68
-rw-r--r--backport-Fix-spec-parser-leaks-from-trans-f-file.patch31
-rw-r--r--backport-Free-old-cookie-value-to-prevent-a-memory-leak.patch28
-rw-r--r--backport-Let-eBPF-ELF-files-be-packaged-in-noarch-packages.patch44
-rw-r--r--backport-Make-sure-dirs-are-not-relocated-twice.patch114
-rw-r--r--backport-Reset-recursion-depth-for-error-message.patch81
-rw-r--r--backport-Tip-toe-around-rpmfiFN-thin-ice-in-fsm.patch38
-rw-r--r--backport-Use-proper-type-for-copyTagsFromMainDebug.patch30
-rw-r--r--backport-Use-the-internal-DB_CTRL-enum-for-intenal-uses-consi.patch28
-rw-r--r--backport-Use-unsigned-integers-for-buildtime-too-for-Y2K38-sa.patch32
-rw-r--r--backport-Use-unsigned-integers-more-consistently-in-the-handl.patch66
-rw-r--r--backport-revert-Permit-building-rpm-from-git-without-pandoc.patch32
-rw-r--r--bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch83
-rw-r--r--bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch35
-rw-r--r--get-in-use-of-ndb.patch42
-rw-r--r--revert-always-execute-file-trigger-scriptlet-callbac.patch26
-rw-r--r--rpm-4.12.0-rpm2cpio-hack.patch18
-rw-r--r--rpm-Add-sw64-architecture.patch172
-rw-r--r--rpm.spec730
-rw-r--r--sources1
-rw-r--r--still-in-use-of-python-scripts-from-old-version.patch210
44 files changed, 4278 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..1432b95 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/rpm-4.18.2.tar.bz2
diff --git a/8fc4e71f9b51438f09c8206ceb1b407bbaca8aab.patch b/8fc4e71f9b51438f09c8206ceb1b407bbaca8aab.patch
new file mode 100644
index 0000000..ca28701
--- /dev/null
+++ b/8fc4e71f9b51438f09c8206ceb1b407bbaca8aab.patch
@@ -0,0 +1,30 @@
+From 8fc4e71f9b51438f09c8206ceb1b407bbaca8aab Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Tue, 17 Sep 2024 13:13:13 +0200
+Subject: [PATCH] brp-remove-la-files: Remove symlinks, too
+
+As we check for file contents delete symlink before looking at regular
+files.
+
+Resolves: #3304
+---
+ scripts/brp-remove-la-files | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/scripts/brp-remove-la-files b/scripts/brp-remove-la-files
+index 58c513bf88..cffbd655c5 100755
+--- a/scripts/brp-remove-la-files
++++ b/scripts/brp-remove-la-files
+@@ -5,6 +5,12 @@ if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then
+ exit 0
+ fi
+
++# Check and remove symlinks first
++find "$RPM_BUILD_ROOT" -type l -name '*.la' 2>/dev/null -print0 |
++ xargs -0 grep --fixed-strings '.la - a libtool library file' --files-with-matches --null |
++ xargs -0 rm --force
++
++# Process regular files
+ find "$RPM_BUILD_ROOT" -type f -name '*.la' 2>/dev/null -print0 |
+ xargs -0 grep --fixed-strings '.la - a libtool library file' --files-with-matches --null |
+ xargs -0 rm --force
diff --git a/Add-IMA-digest-list-support.patch b/Add-IMA-digest-list-support.patch
new file mode 100644
index 0000000..223c645
--- /dev/null
+++ b/Add-IMA-digest-list-support.patch
@@ -0,0 +1,622 @@
+From 92ed69a1e2051f202a2532c28cb0b17facda1924 Mon Sep 17 00:00:00 2001
+From: zhoushuiqing <zhoushuiqing2@huawei.com>
+Date: Fri, 16 Jun 2023 11:35:21 +0800
+Subject: [PATCH] Add IMA digest list support
+
+---
+ build/files.c | 305 ++++++++++++++++++++++++++++++++++++++--
+ build/parsePreamble.c | 3 +-
+ macros.in | 1 +
+ plugins/Makefile.am | 4 +
+ plugins/selinux.c | 3 +-
+ rpmio/rpmpgp_internal.c | 32 +----
+ rpmio/rpmpgp_internal.h | 29 ++++
+ 7 files changed, 336 insertions(+), 41 deletions(-)
+
+diff --git a/build/files.c b/build/files.c
+index eb008ab..3fc3551 100644
+--- a/build/files.c
++++ b/build/files.c
+@@ -50,6 +50,8 @@
+ #define DEBUG_LIB_PREFIX "/usr/lib/debug/"
+ #define DEBUG_ID_DIR "/usr/lib/debug/.build-id"
+ #define DEBUG_DWZ_DIR "/usr/lib/debug/.dwz"
++#define DIGEST_LIST_DIR "/.digest_lists"
++#define DEST_DIGEST_LIST_DIR "/etc/ima/digest_lists"
+
+ #undef HASHTYPE
+ #undef HTKEYTYPE
+@@ -129,6 +131,8 @@ typedef struct AttrRec_s {
+
+ /* list of files */
+ static StringBuf check_fileList = NULL;
++/* list of files per binary package */
++static StringBuf check_fileList_bin_pkg = NULL;
+
+ typedef struct FileEntry_s {
+ rpmfileAttrs attrFlags;
+@@ -193,6 +197,10 @@ typedef struct FileList_s {
+ struct FileEntry_s cur;
+ } * FileList;
+
++static char *digest_list_dir;
++
++static int genDigestList(Header header, FileList fl, StringBuf fileList);
++
+ static void nullAttrRec(AttrRec ar)
+ {
+ memset(ar, 0, sizeof(*ar));
+@@ -992,6 +1000,139 @@ static int seenHardLink(FileRecords files, FileListRec flp, rpm_ino_t *fileid)
+ * @param pkg (sub) package
+ * @param isSrc pass 1 for source packages 0 otherwise
+ */
++static void genDigestListInput(FileList fl, Package pkg, int isSrc)
++{
++ FileListRec flp;
++ char buf[BUFSIZ];
++ char file_info[BUFSIZ];
++ char file_digest[128 * 2 + 1];
++ int i, gen_digest_lists = 1;
++ uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo;
++ Header h = pkg->header; /* just a shortcut */
++
++ /*
++ * See if non-md5 file digest algorithm is requested. If not
++ * specified, quietly assume md5. Otherwise check if supported type.
++ */
++ digestalgo = rpmExpandNumeric(isSrc ? "%{_source_filedigest_algorithm}" :
++ "%{_binary_filedigest_algorithm}");
++ if (digestalgo == 0) {
++ digestalgo = defaultalgo;
++ }
++
++ if (rpmDigestLength(digestalgo) == 0) {
++ rpmlog(RPMLOG_WARNING,
++ _("Unknown file digest algorithm %u, falling back to MD5\n"),
++ digestalgo);
++ digestalgo = defaultalgo;
++ }
++
++ /* Sort the big list */
++ if (fl->files.recs) {
++ qsort(fl->files.recs, fl->files.used,
++ sizeof(*(fl->files.recs)), compareFileListRecs);
++ }
++
++ /* Generate the header. */
++ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) {
++ /* Merge duplicate entries. */
++ while (i < (fl->files.used - 1) &&
++ rstreq(flp->cpioPath, flp[1].cpioPath)) {
++
++ /* Two entries for the same file found, merge the entries. */
++ /* Note that an %exclude is a duplication of a file reference */
++
++ /* file flags */
++ flp[1].flags |= flp->flags;
++
++ if (!(flp[1].flags & RPMFILE_EXCLUDE))
++ rpmlog(RPMLOG_WARNING, _("File listed twice: %s\n"),
++ flp->cpioPath);
++
++ /* file mode */
++ if (S_ISDIR(flp->fl_mode)) {
++ if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) <
++ (flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)))
++ flp[1].fl_mode = flp->fl_mode;
++ } else {
++ if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) <
++ (flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)))
++ flp[1].fl_mode = flp->fl_mode;
++ }
++
++ /* uid */
++ if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) <
++ (flp->specdFlags & (SPECD_UID | SPECD_DEFUID)))
++ {
++ flp[1].fl_uid = flp->fl_uid;
++ flp[1].uname = flp->uname;
++ }
++
++ /* gid */
++ if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) <
++ (flp->specdFlags & (SPECD_GID | SPECD_DEFGID)))
++ {
++ flp[1].fl_gid = flp->fl_gid;
++ flp[1].gname = flp->gname;
++ }
++
++ /* verify flags */
++ if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) <
++ (flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)))
++ flp[1].verifyFlags = flp->verifyFlags;
++
++ /* XXX to-do: language */
++
++ flp++; i++;
++ }
++
++ /* Skip files that were marked with %exclude. */
++ if (flp->flags & RPMFILE_EXCLUDE)
++ {
++ argvAdd(&pkg->fileExcludeList, flp->cpioPath);
++ continue;
++ }
++
++ buf[0] = '\0';
++ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST))
++ (void) rpmDoDigest(digestalgo, flp->diskPath, 1,
++ (unsigned char *)buf);
++ headerPutString(h, RPMTAG_FILEDIGESTS, buf);
++ snprintf(file_digest, sizeof(file_digest), "%s", buf);
++
++ if (check_fileList_bin_pkg && S_ISREG(flp->fl_mode) &&
++ !(flp->flags & RPMFILE_GHOST)) {
++ appendStringBuf(check_fileList_bin_pkg, "path=");
++ appendStringBuf(check_fileList_bin_pkg, flp->diskPath);
++ snprintf(file_info, sizeof(file_info),
++ "|digestalgopgp=%d|digest=%s|mode=%d"
++ "|uname=%s|gname=%s|caps=%s\n",
++ digestalgo, file_digest, flp->fl_mode,
++ rpmstrPoolStr(fl->pool, flp->uname),
++ rpmstrPoolStr(fl->pool, flp->gname), flp->caps &&
++ strlen(flp->caps) ? flp->caps : "");
++ appendStringBuf(check_fileList_bin_pkg, file_info);
++ }
++
++ if (S_ISREG(flp->fl_mode) &&
++ !strncmp(flp->cpioPath, DEST_DIGEST_LIST_DIR,
++ sizeof(DEST_DIGEST_LIST_DIR) - 1))
++ gen_digest_lists = 0;
++ }
++
++ if (gen_digest_lists &&
++ genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0)
++ fl->processingFailed = 1;
++}
++
++/**
++ * Add file entries to header.
++ * @todo Should directories have %doc/%config attributes? (#14531)
++ * @todo Remove RPMTAG_OLDFILENAMES, add dirname/basename instead.
++ * @param fl package file tree walk data
++ * @param pkg (sub) package
++ * @param isSrc pass 1 for source packages 0 otherwise
++ */
+ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+ {
+ FileListRec flp;
+@@ -1003,6 +1144,11 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+ int override_date = 0;
+ time_t source_date_epoch = 0;
+ char *srcdate = getenv("SOURCE_DATE_EPOCH");
++ struct rpmtd_s oldfiledigests;
++
++ headerGet(h, RPMTAG_FILEDIGESTS, &oldfiledigests, HEADERGET_ALLOC);
++ headerDel(h, RPMTAG_FILEDIGESTS);
++ rpmtdInit(&oldfiledigests);
+
+ /* Limit the maximum date to SOURCE_DATE_EPOCH if defined
+ * similar to the tar --clamp-mtime option
+@@ -1200,13 +1346,18 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+ if (fl->haveCaps) {
+ headerPutString(h, RPMTAG_FILECAPS, flp->caps);
+ }
+-
++
+ buf[0] = '\0';
+- if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST))
+- (void) rpmDoDigest(digestalgo, flp->diskPath, 1,
+- (unsigned char *)buf);
+- headerPutString(h, RPMTAG_FILEDIGESTS, buf);
+-
++ if (strstr(flp->diskPath, DIGEST_LIST_DIR) || !oldfiledigests.count) {
++ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST))
++ (void) rpmDoDigest(digestalgo, flp->diskPath, 1,
++ (unsigned char *)buf);
++ headerPutString(h, RPMTAG_FILEDIGESTS, buf);
++ } else {
++ headerPutString(h, RPMTAG_FILEDIGESTS,
++ rpmtdNextString(&oldfiledigests));
++ }
++
+ buf[0] = '\0';
+ if (S_ISLNK(flp->fl_mode)) {
+ ssize_t llen = readlink(flp->diskPath, buf, BUFSIZ-1);
+@@ -1247,6 +1398,7 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+
+ headerPutUint32(h, RPMTAG_FILEFLAGS, &(flp->flags) ,1);
+ }
++
+ pkg->dpaths[npaths] = NULL;
+
+ if (totalFileSize < UINT32_MAX) {
+@@ -1285,6 +1437,7 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+ /* Binary packages with dirNames cannot be installed by legacy rpm. */
+ (void) rpmlibNeedsFeature(pkg, "CompressedFileNames", "3.0.4-1");
+ }
++ rpmtdFreeData(&oldfiledigests);
+ }
+
+ static FileRecords FileRecordsFree(FileRecords files)
+@@ -1359,8 +1512,8 @@ static int validFilename(const char *fn)
+ * @param statp file stat (possibly NULL)
+ * @return RPMRC_OK on success
+ */
+-static rpmRC addFile(FileList fl, const char * diskPath,
+- struct stat * statp)
++static rpmRC addFile_common(FileList fl, const char * diskPath,
++ struct stat * statp, int digest_list)
+ {
+ size_t plen = strlen(diskPath);
+ char buf[plen + 1];
+@@ -1371,6 +1524,10 @@ static rpmRC addFile(FileList fl, const char * diskPath,
+ gid_t fileGid;
+ const char *fileUname;
+ const char *fileGname;
++ char realPath[PATH_MAX];
++ int digest_list_prefix = 0;
++ struct stat st;
++ int exclude = 0;
+ rpmRC rc = RPMRC_FAIL; /* assume failure */
+
+ /* Strip trailing slash. The special case of '/' path is handled below. */
+@@ -1406,6 +1563,33 @@ static rpmRC addFile(FileList fl, const char * diskPath,
+ if (*cpioPath == '\0')
+ cpioPath = "/";
+
++ snprintf(realPath, sizeof(realPath), "%s", diskPath);
++ rpmCleanPath(realPath);
++
++ digest_list_prefix = (!strncmp(realPath, digest_list_dir,
++ strlen(digest_list_dir)));
++
++ if ((!digest_list && digest_list_prefix) ||
++ (digest_list && !digest_list_prefix)) {
++ rc = RPMRC_OK;
++ goto exit;
++ }
++
++ if (digest_list) {
++ if (strncmp(cpioPath, DIGEST_LIST_DIR, sizeof(DIGEST_LIST_DIR) - 1)) {
++ rc = RPMRC_OK;
++ goto exit;
++ }
++
++ cpioPath += sizeof(DIGEST_LIST_DIR) - 1;
++
++ snprintf(realPath, sizeof(realPath), "%.*s%s",
++ (int)(strlen(digest_list_dir) - sizeof(DIGEST_LIST_DIR) + 1),
++ digest_list_dir, cpioPath);
++ if (!stat(realPath, &st))
++ exclude = 1;
++ }
++
+ /*
+ * Unless recursing, we dont have stat() info at hand. Handle the
+ * various cases, preserving historical behavior wrt %dev():
+@@ -1543,6 +1727,8 @@ static rpmRC addFile(FileList fl, const char * diskPath,
+ }
+
+ flp->flags = fl->cur.attrFlags;
++ if (exclude)
++ flp->flags |= RPMFILE_EXCLUDE;
+ flp->specdFlags = fl->cur.specdFlags;
+ flp->verifyFlags = fl->cur.verifyFlags;
+
+@@ -1563,6 +1749,32 @@ exit:
+ return rc;
+ }
+
++/**
++ * Add a file to the package manifest.
++ * @param fl package file tree walk data
++ * @param diskPath path to file
++ * @param statp file stat (possibly NULL)
++ * @return RPMRC_OK on success
++ */
++static rpmRC addFile(FileList fl, const char * diskPath,
++ struct stat * statp)
++{
++ return addFile_common(fl, diskPath, statp, 0);
++}
++
++/**
++ * Add a digest list to the package manifest.
++ * @param fl package file tree walk data
++ * @param diskPath path to digest list
++ * @param statp file stat (possibly NULL)
++ * @return RPMRC_OK on success
++ */
++static rpmRC addDigestList(FileList fl, const char * diskPath,
++ struct stat * statp)
++{
++ return addFile_common(fl, diskPath, statp, 1);
++}
++
+ /**
+ * Add directory (and all of its files) to the package manifest.
+ * @param fl package file tree walk data
+@@ -2584,6 +2796,61 @@ static void addPackageFileList (struct FileList_s *fl, Package pkg,
+ argvFree(fileNames);
+ }
+
++/**
++ * Generate digest lists list for current binary package.
++ * @header package header
++ * @fl file list
++ * @param fileList packaged file list
++ * @return -1 if skipped, 0 on OK, 1 on error
++ */
++static int genDigestList(Header header, FileList fl, StringBuf fileList)
++{
++ const char *errorString;
++ char *binFormat = rpmGetPath("%{_rpmfilename}", NULL);
++ char *binRpm = headerFormat(header, binFormat, &errorString);
++ static char * av_brp[] = { "%{?__brp_digest_list}", DIGEST_LIST_DIR + 1, NULL, NULL };
++ StringBuf sb_stdout = NULL;
++ int rc = -1;
++ char * s = rpmExpand(av_brp[0], NULL);
++
++ if (!(s && *s))
++ goto exit;
++
++ if (!strchr(binRpm, '/'))
++ goto exit;
++
++ av_brp[2] = strchr(binRpm, '/') + 1;
++ rpmlog(RPMLOG_NOTICE, _("Generating digest list: %s\n"), s);
++
++ rc = rpmfcExec(av_brp, fileList, &sb_stdout, 0, binRpm);
++ if (sb_stdout && getStringBuf(sb_stdout)) {
++ const char * t = getStringBuf(sb_stdout), *ptr;
++ char *digest_list_path;
++
++ while((ptr = strchr(t, '\n'))) {
++ digest_list_path = strndup(t, ptr - t);
++ if (!digest_list_path) {
++ rc = -1;
++ goto exit;
++ }
++ FileEntryFree(&fl->cur);
++ resetPackageFilesDefaults(fl, fl->pkgFlags);
++ rc = addDigestList(fl, digest_list_path, NULL);
++ free(digest_list_path);
++ if (rc != RPMRC_OK)
++ break;
++
++ t = ptr + 1;
++ }
++ }
++exit:
++ free(binFormat);
++ free(binRpm);
++ free(s);
++ freeStringBuf(sb_stdout);
++ return rc;
++}
++
+ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
+ Package pkg, int didInstall, int test)
+ {
+@@ -2597,6 +2861,10 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
+ if (readFilesManifest(spec, pkg, *fp))
+ return RPMRC_FAIL;
+ }
++
++ /* Init the buffer containing the list of packaged files */
++ check_fileList_bin_pkg = newStringBuf();
++
+ /* Init the file list structure */
+ memset(&fl, 0, sizeof(fl));
+
+@@ -2652,12 +2920,17 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
+ if (checkHardLinks(&fl.files))
+ (void) rpmlibNeedsFeature(pkg, "PartialHardlinkSets", "4.0.4-1");
+
++ genDigestListInput(&fl, pkg, 0);
++ if (fl.processingFailed)
++ goto exit;
++
+ genCpioListAndHeader(&fl, pkg, 0);
+
+ exit:
+ FileListFree(&fl);
+ specialDirFree(specialDoc);
+ specialDirFree(specialLic);
++ freeStringBuf(check_fileList_bin_pkg);
+ return fl.processingFailed ? RPMRC_FAIL : RPMRC_OK;
+ }
+
+@@ -3126,6 +3399,7 @@ static void addPackageDeps(Package from, Package to, enum rpmTag_e tag)
+ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
+ int didInstall, int test)
+ {
++ struct stat st;
+ Package pkg;
+ rpmRC rc = RPMRC_OK;
+ char *buildroot;
+@@ -3142,7 +3416,14 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
+ check_fileList = newStringBuf();
+ genSourceRpmName(spec);
+ buildroot = rpmGenPath(spec->rootDir, spec->buildRoot, NULL);
+-
++
++ digest_list_dir = rpmGenPath(buildroot, DIGEST_LIST_DIR, NULL);
++ if (!digest_list_dir)
++ goto exit;
++
++ if (!stat(digest_list_dir, &st))
++ rpmlog(RPMLOG_NOTICE, _("Ignoring files in: %s\n"), digest_list_dir);
++
+ if (rpmExpandNumeric("%{?_debuginfo_subpackages}")) {
+ maindbg = findDebuginfoPackage(spec);
+ if (maindbg) {
+@@ -3248,6 +3529,7 @@ exit:
+ check_fileList = freeStringBuf(check_fileList);
+ _free(buildroot);
+ _free(uniquearch);
+-
++ _free(digest_list_dir);
++
+ return rc;
+ }
+diff --git a/build/parsePreamble.c b/build/parsePreamble.c
+index 729fd4f..306a029 100644
+--- a/build/parsePreamble.c
++++ b/build/parsePreamble.c
+@@ -801,7 +801,8 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
+ SINGLE_TOKEN_ONLY;
+ if (tag == RPMTAG_RELEASE) {
+ char *dist = rpmExpand("%{?dist}",NULL);
+- rasprintf(&field,"%s%s",field,dist);
++ rasprintf(&field,"%s%s",field,
++ (dist && strstr(field, dist)) ? "" : dist);
+ free(dist);
+ }
+ if (rpmCharCheck(spec, field, ALLOWED_CHARS_VERREL, NULL))
+diff --git a/macros.in b/macros.in
+index 949fd7d..c00d270 100644
+--- a/macros.in
++++ b/macros.in
+@@ -1135,6 +1135,7 @@ package or when debugging this package.\
+ %__transaction_prioreset %{__plugindir}/prioreset.so
+ %__transaction_audit %{__plugindir}/audit.so
+ %__transaction_dbus_announce %{__plugindir}/dbus_announce.so
++%__transaction_digest_list %{__plugindir}/digest_list.so
+
+ #------------------------------------------------------------------------------
+ # Macros for further automated spec %setup and patch application
+diff --git a/plugins/Makefile.am b/plugins/Makefile.am
+index 822c7d2..161fe4c 100644
+--- a/plugins/Makefile.am
++++ b/plugins/Makefile.am
+@@ -69,3 +69,7 @@ audit_la_sources = audit.c
+ audit_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @WITH_AUDIT_LIB@
+ plugins_LTLIBRARIES += audit.la
+ endif
++
++digest_list_la_sources = digest_list.c
++digest_list_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
++plugins_LTLIBRARIES += digest_list.la
+diff --git a/plugins/selinux.c b/plugins/selinux.c
+index 316ff88..ac1e354 100644
+--- a/plugins/selinux.c
++++ b/plugins/selinux.c
+@@ -64,7 +64,8 @@ static rpmRC selinux_tsm_pre(rpmPlugin plugin, rpmts ts)
+ rpmRC rc = RPMRC_OK;
+
+ /* If SELinux isn't enabled on the system, dont mess with it */
+- if (!is_selinux_enabled()) {
++ if (!is_selinux_enabled() || selinux_file_context_path() == NULL ||
++ access(selinux_file_context_path(), F_OK)) {
+ rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
+ }
+
+diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c
+index 19947be..16bf57e 100644
+--- a/rpmio/rpmpgp_internal.c
++++ b/rpmio/rpmpgp_internal.c
+@@ -19,34 +19,6 @@
+
+ static int _print = 0;
+
+-/** \ingroup rpmio
+- * Values parsed from OpenPGP signature/pubkey packet(s).
+- */
+-struct pgpDigParams_s {
+- char * userid;
+- uint8_t * hash;
+- uint8_t tag;
+-
+- uint8_t key_flags; /*!< key usage flags */
+- uint8_t version; /*!< version number. */
+- uint32_t time; /*!< key/signature creation time. */
+- uint8_t pubkey_algo; /*!< public key algorithm. */
+-
+- uint8_t hash_algo;
+- uint8_t sigtype;
+- uint32_t hashlen;
+- uint8_t signhash16[2];
+- pgpKeyID_t signid;
+- uint8_t saved; /*!< Various flags. `PGPDIG_SAVED_*` are never reset.
+- * `PGPDIG_SIG_HAS_*` are reset for each signature. */
+-#define PGPDIG_SAVED_TIME (1 << 0)
+-#define PGPDIG_SAVED_ID (1 << 1)
+-#define PGPDIG_SIG_HAS_CREATION_TIME (1 << 2)
+-#define PGPDIG_SIG_HAS_KEY_FLAGS (1 << 3)
+-
+- pgpDigAlg alg;
+-};
+-
+ /** \ingroup rpmio
+ * Container for values parsed from an OpenPGP signature and public key.
+ */
+@@ -484,6 +456,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
+ }
+
+ p = ((uint8_t *)v) + sizeof(*v);
++ _digp->data = p;
+ rc = tag ? pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp) : 0;
+ } break;
+ case 4:
+@@ -545,7 +518,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
+ p += 2;
+ if (p > hend)
+ return 1;
+-
++ _digp->data = p;
+ rc = tag ? pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp) : 0;
+ } break;
+ default:
+@@ -636,6 +609,7 @@ static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen,
+ }
+
+ p = ((uint8_t *)v) + sizeof(*v);
++ _digp->data = p;
+ rc = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _digp);
+ }
+ } break;
+diff --git a/rpmio/rpmpgp_internal.h b/rpmio/rpmpgp_internal.h
+index 64b50de..67fecb0 100644
+--- a/rpmio/rpmpgp_internal.h
++++ b/rpmio/rpmpgp_internal.h
+@@ -10,6 +10,35 @@ typedef int (*verifyfunc)(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
+ uint8_t *hash, size_t hashlen, int hash_algo);
+ typedef void (*freefunc)(pgpDigAlg digp);
+
++/** \ingroup rpmio
++ * Values parsed from OpenPGP signature/pubkey packet(s).
++ */
++struct pgpDigParams_s {
++ char * userid;
++ uint8_t * hash;
++ const uint8_t * data;
++ uint8_t tag;
++
++ uint8_t key_flags; /*!< key usage flags */
++ uint8_t version; /*!< version number. */
++ uint32_t time; /*!< key/signature creation time. */
++ uint8_t pubkey_algo; /*!< public key algorithm. */
++
++ uint8_t hash_algo;
++ uint8_t sigtype;
++ uint32_t hashlen;
++ uint8_t signhash16[2];
++ pgpKeyID_t signid;
++ uint8_t saved; /*!< Various flags. `PGPDIG_SAVED_*` are never reset.
++ * `PGPDIG_SIG_HAS_*` are reset for each signature. */
++#define PGPDIG_SAVED_TIME (1 << 0)
++#define PGPDIG_SAVED_ID (1 << 1)
++#define PGPDIG_SIG_HAS_CREATION_TIME (1 << 2)
++#define PGPDIG_SIG_HAS_KEY_FLAGS (1 << 3)
++
++ pgpDigAlg alg;
++};
++
+ struct pgpDigAlg_s {
+ setmpifunc setmpi;
+ verifyfunc verify;
+--
+2.39.1
+
diff --git a/Add-digest-list-plugin.patch b/Add-digest-list-plugin.patch
new file mode 100644
index 0000000..14c89b5
--- /dev/null
+++ b/Add-digest-list-plugin.patch
@@ -0,0 +1,700 @@
+From 3b2fb7d5a40d25c3295e02eb3695a45189342369 Mon Sep 17 00:00:00 2001
+From: zhoushuiqing <zhoushuiqing2@huawei.com>
+Date: Fri, 16 Jun 2023 11:21:37 +0800
+Subject: [PATCH] Add-digest-list-plugin
+
+Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
+---
+ plugins/digest_list.c | 680 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 680 insertions(+)
+ create mode 100644 plugins/digest_list.c
+
+diff --git a/plugins/digest_list.c b/plugins/digest_list.c
+new file mode 100644
+index 0000000..715b8d6
+--- /dev/null
++++ b/plugins/digest_list.c
+@@ -0,0 +1,680 @@
++/*
++ * Copyright (C) 2020-2021 Huawei Technologies Duesseldorf GmbH
++ *
++ * Author: Roberto Sassu <roberto.sassu@huawei.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation, version 2 of the
++ * License.
++ *
++ * File: digest_list.c
++ * Plugin to load digest lists in the Linux kernel.
++ */
++
++#include "system.h"
++#include "errno.h"
++
++#include <fcntl.h>
++#include <rpm/rpmlog.h>
++#include <rpm/rpmts.h>
++#include <rpm/header.h>
++#include <rpm/rpmpgp.h>
++#include "rpmio/rpmpgp_internal.h"
++#include <rpm/rpmfileutil.h>
++#include "lib/rpmplugin.h"
++#include <netinet/in.h>
++#include <sys/stat.h>
++#include <openssl/sha.h>
++#include <sys/xattr.h>
++#include <sys/capability.h>
++#include <linux/xattr.h>
++#include <asm/byteorder.h>
++#include <sys/wait.h>
++
++#include "debug.h"
++
++#define IMA_DIR "/sys/kernel/security/ima"
++#define DIGEST_LIST_DATA_PATH IMA_DIR "/digest_list_data"
++#define DIGEST_LIST_DATA_DEL_PATH IMA_DIR "/digest_list_data_del"
++#define DIGEST_LIST_COUNT IMA_DIR "/digests_count"
++#define DIGEST_LIST_DEFAULT_PATH "/etc/ima/digest_lists"
++#define RPM_PARSER "/usr/libexec/rpm_parser"
++
++enum hash_algo {
++ HASH_ALGO_MD4,
++ HASH_ALGO_MD5,
++ HASH_ALGO_SHA1,
++ HASH_ALGO_RIPE_MD_160,
++ HASH_ALGO_SHA256,
++ HASH_ALGO_SHA384,
++ HASH_ALGO_SHA512,
++ HASH_ALGO_SHA224,
++ HASH_ALGO_RIPE_MD_128,
++ HASH_ALGO_RIPE_MD_256,
++ HASH_ALGO_RIPE_MD_320,
++ HASH_ALGO_WP_256,
++ HASH_ALGO_WP_384,
++ HASH_ALGO_WP_512,
++ HASH_ALGO_TGR_128,
++ HASH_ALGO_TGR_160,
++ HASH_ALGO_TGR_192,
++ HASH_ALGO_SM3_256,
++ HASH_ALGO__LAST
++};
++
++#define PGPHASHALGO__LAST PGPHASHALGO_SHA224 + 1
++enum hash_algo pgp_algo_mapping[PGPHASHALGO__LAST] = {
++ [PGPHASHALGO_MD5] = HASH_ALGO_MD5,
++ [PGPHASHALGO_SHA1] = HASH_ALGO_SHA1,
++ [PGPHASHALGO_SHA224] = HASH_ALGO_SHA224,
++ [PGPHASHALGO_SHA256] = HASH_ALGO_SHA256,
++ [PGPHASHALGO_SHA384] = HASH_ALGO_SHA384,
++ [PGPHASHALGO_SHA512] = HASH_ALGO_SHA512,
++};
++
++/* from integrity.h */
++enum evm_ima_xattr_type {
++ IMA_XATTR_DIGEST = 0x01,
++ EVM_XATTR_HMAC,
++ EVM_IMA_XATTR_DIGSIG,
++ IMA_XATTR_DIGEST_NG,
++ EVM_XATTR_PORTABLE_DIGSIG,
++ EVM_IMA_XATTR_DIGEST_LIST,
++ IMA_XATTR_LAST
++};
++
++struct evm_ima_xattr_data {
++ uint8_t type;
++ uint8_t digest[SHA512_DIGEST_LENGTH + 1];
++} __attribute__((packed));
++
++struct signature_v2_hdr {
++ uint8_t type; /* xattr type */
++ uint8_t version; /* signature format version */
++ uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */
++ __be32 keyid; /* IMA key identifier - not X509/PGP specific */
++ __be16 sig_size; /* signature size */
++ uint8_t sig[0]; /* signature payload */
++} __attribute__((packed));
++
++static int digest_list_count_is_zero(void)
++{
++ int fd = 0, ret = 0;
++ char first = 0;
++
++ fd = open(DIGEST_LIST_COUNT, O_RDONLY);
++ if (fd < 0) {
++ rpmlog(RPMLOG_ERR, "digest_list: could not open IMA interface "
++ "'%s': %s\n", DIGEST_LIST_COUNT, strerror(errno));
++ return -EACCES;
++ }
++
++ ret = read(fd, &first, 1);
++ if (ret <= 0) {
++ rpmlog(RPMLOG_ERR, "digest_list: could not read from IMA "
++ "interface '%s': %s\n", DIGEST_LIST_COUNT,
++ strerror(errno));
++ close(fd);
++ return -EACCES;
++ }
++
++ close(fd);
++ return (first == '0');
++}
++
++static int upload_digest_list(char *path, int type, int digest_list_signed)
++{
++ int ret = 0, fd = 0;
++ pid_t pid = 0;
++ size_t size = 0;
++ struct stat st;
++ const char *ima_path = NULL;
++
++ ima_path = (type == TR_REMOVED) ? DIGEST_LIST_DATA_DEL_PATH :
++ DIGEST_LIST_DATA_PATH;
++ if (stat(ima_path, &st) == -1) {
++ rpmlog(RPMLOG_DEBUG, "digest_list: '%s' interface "
++ "not exist\n", ima_path);
++ return RPMRC_OK;
++ }
++
++ /* First determine if kernel interface can accept new digest lists */
++ if (digest_list_count_is_zero()) {
++ rpmlog(RPMLOG_DEBUG, "digest_list: the count is 0, not "
++ "upload '%s' to IMA interface '%s'\n", path, ima_path);
++ return RPMRC_OK;
++ }
++
++ /* If the digest list is not signed, execute the RPM parser */
++ if (!digest_list_signed) {
++ if (stat(RPM_PARSER, &st) == -1) {
++ rpmlog(RPMLOG_DEBUG, "digest_list: %s not found, "
++ "not uploading digest list\n", RPM_PARSER);
++ return RPMRC_OK;
++ }
++
++ if ((pid = fork()) == 0) {
++ execlp(RPM_PARSER, RPM_PARSER, (type == TR_ADDED) ?
++ "add" : "del", path, NULL);
++ _exit(EXIT_FAILURE);
++ }
++
++ waitpid(pid, &ret, 0);
++ if (ret != 0)
++ rpmlog(RPMLOG_ERR, "digest_list: %s returned %d\n",
++ RPM_PARSER, ret);
++ return RPMRC_OK;
++ }
++
++ /* If the digest list is signed, write path to the IMA interface */
++ fd = open(ima_path, O_WRONLY);
++ if (fd < 0) {
++ rpmlog(RPMLOG_ERR, "digest_list: rcould not open IMA interface "
++ "'%s': %s\n", ima_path, strerror(errno));
++ return -EACCES;
++ }
++
++ /* Write the path of the digest list to securityfs */
++ size = write(fd, path, strlen(path));
++ if (size != strlen(path)) {
++ rpmlog(RPMLOG_ERR, "digest_list: could not write '%s' to IMA "
++ "interface '%s': %s\n", path, ima_path, strerror(errno));
++ ret = -EIO;
++ goto out;
++ }
++
++ rpmlog(RPMLOG_DEBUG, "digest_list: written '%s' to '%s'\n", path,
++ ima_path);
++out:
++ close(fd);
++ return ret;
++}
++
++static int write_rpm_digest_list(rpmte te, char *path)
++{
++ FD_t fd;
++ int ret = 0;
++ ssize_t written = 0;
++ Header rpm = rpmteHeader(te);
++ rpmtd immutable = rpmtdNew();
++
++ headerGet(rpm, RPMTAG_HEADERIMMUTABLE, immutable, 0);
++
++ fd = Fopen(path, "w.ufdio");
++ if (fd == NULL || Ferror(fd)) {
++ ret = -EACCES;
++ goto out;
++ }
++
++ written = Fwrite(rpm_header_magic, sizeof(uint8_t),
++ sizeof(rpm_header_magic), fd);
++ if (written != sizeof(rpm_header_magic)) {
++ ret = -EIO;
++ goto out;
++ }
++
++ written = Fwrite(immutable->data, sizeof(uint8_t),
++ immutable->count, fd);
++ if (written != immutable->count || Ferror(fd))
++ ret = -EIO;
++out:
++ Fclose(fd);
++ rpmtdFree(immutable);
++ return ret;
++}
++
++static int write_rpm_digest_list_ima_xattr(rpmte te, char *path)
++{
++ FD_t fd;
++ ssize_t written = 0;
++ int ret = 0, sig_size = 0, sig_size_rounded = 0;
++ uint8_t sig[2048] = { 0 };
++ pgpDigParams sigp = NULL;
++ struct signature_v2_hdr *sig_hdr = (struct signature_v2_hdr *)sig;
++ Header rpm = rpmteHeader(te);
++ rpmtd signature = rpmtdNew();
++
++ headerGet(rpm, RPMTAG_RSAHEADER, signature, 0);
++ ret = pgpPrtParams(signature->data, signature->count,
++ PGPTAG_SIGNATURE, &sigp);
++ if (ret) {
++ ret = -ENOENT;
++ goto out;
++ }
++
++ fd = Fopen(path, "a.ufdio");
++ if (fd == NULL || Ferror(fd)) {
++ ret = -EACCES;
++ goto out;
++ }
++
++ written = Fwrite(sigp->hash, sizeof(uint8_t),
++ sigp->hashlen, fd);
++ if (written != sigp->hashlen || Ferror(fd)) {
++ ret = -EIO;
++ goto out;
++ }
++
++ if (sigp->version == 4) {
++ /* V4 trailer is six octets long (rfc4880) */
++ uint8_t trailer[6];
++ uint32_t nb = sigp->hashlen;
++ nb = htonl(nb);
++ trailer[0] = sigp->version;
++ trailer[1] = 0xff;
++ memcpy(trailer+2, &nb, 4);
++
++ written = Fwrite(trailer, sizeof(uint8_t), sizeof(trailer), fd);
++ if (written != sizeof(trailer) || Ferror(fd)) {
++ ret = -EIO;
++ goto out;
++ }
++ }
++
++ Fclose(fd);
++
++ sig_hdr->type = EVM_IMA_XATTR_DIGSIG;
++ sig_hdr->version = 2;
++ sig_hdr->hash_algo = pgp_algo_mapping[sigp->hash_algo];
++ memcpy((void *)&sig_hdr->keyid, sigp->signid + sizeof(uint32_t),
++ sizeof(uint32_t));
++
++ sig_size = (pgpMpiBits(sigp->data) + 7) >> 3;
++ if (sizeof(sig_hdr) + sig_size > sizeof(sig)) {
++ rpmlog(RPMLOG_ERR,
++ "digest_list: signature in %s too big\n", path);
++ ret = -E2BIG;
++ goto out;
++ }
++
++ sig_size_rounded = ((sig_size + 7) >> 3) * 8;
++ sig_hdr->sig_size = __cpu_to_be16(sig_size_rounded);
++
++ memcpy(sig_hdr->sig + sig_size_rounded - sig_size,
++ (uint8_t *)sigp->data + 2, sig_size);
++
++ ret = lsetxattr(path, XATTR_NAME_IMA,
++ sig, sizeof(*sig_hdr) + sig_size_rounded, 0);
++ if (ret < 0)
++ rpmlog(RPMLOG_ERR, "digest_list: could not apply security.ima "
++ "on '%s': %s\n", path, strerror(errno));
++ else
++ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima successfully "
++ "applied on '%s'\n", path);
++out:
++ pgpDigParamsFree(sigp);
++ rpmtdFree(signature);
++ return ret;
++}
++
++static int fill_pgp_signature_header(rpmte te, struct signature_v2_hdr *sig_hdr)
++{
++ int ret = 0;
++ pgpDigParams sigp = NULL;
++ Header rpm = rpmteHeader(te);
++ rpmtd signature = rpmtdNew();
++
++ headerGet(rpm, RPMTAG_RSAHEADER, signature, 0);
++ ret = pgpPrtParams(signature->data, signature->count,
++ PGPTAG_SIGNATURE, &sigp);
++ if (ret) {
++ ret = -ENOENT;
++ goto out;
++ }
++
++ sig_hdr->type = EVM_IMA_XATTR_DIGSIG;
++ sig_hdr->version = 2;
++ sig_hdr->hash_algo = HASH_ALGO_SHA256;
++ memcpy((void *)&sig_hdr->keyid, sigp->signid + sizeof(uint32_t),
++ sizeof(uint32_t));
++out:
++ pgpDigParamsFree(sigp);
++ rpmtdFree(signature);
++ return ret;
++}
++
++static int write_digest_list_ima_xattr(rpmte te, char *path, char *path_sig)
++{
++ FD_t fd;
++ struct stat st;
++ int ret = 0, sig_size, hdr_exist;
++ uint8_t sig[2048] = { 0 };
++ struct signature_v2_hdr *sig_hdr = (struct signature_v2_hdr *)sig;
++
++ if (stat(path_sig, &st) == -1)
++ return -EACCES;
++
++ /* Check if the signature has already included a header */
++ hdr_exist = st.st_size % 128 == 0 ? 0 : 1;
++ if (!hdr_exist) {
++ ret = fill_pgp_signature_header(te, sig_hdr);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (sizeof(sig_hdr) + st.st_size > sizeof(sig)) {
++ rpmlog(RPMLOG_ERR, "digest_list: signature in %s too big\n",
++ path);
++ return -E2BIG;
++ }
++
++ fd = Fopen(path_sig, "r.ufdio");
++ if (fd < 0) {
++ rpmlog(RPMLOG_ERR, "digest_list: could not open '%s': %s\n",
++ path_sig, strerror(errno));
++ return -EACCES;
++ }
++
++ sig_size = Fread(sig_hdr->sig, sizeof(uint8_t), st.st_size, fd);
++ if (sig_size != st.st_size || Ferror(fd)) {
++ rpmlog(RPMLOG_ERR, "digest_list: could not read '%s': %s\n",
++ path_sig, strerror(errno));
++ Fclose(fd);
++ return -EIO;
++ }
++
++ sig_hdr->sig_size = __cpu_to_be16(sig_size);
++ Fclose(fd);
++ rpmlog(RPMLOG_DEBUG,
++ "digest_list: read signature of %d bytes from '%s'\n",
++ sig_size, path_sig);
++
++ /* The signature may include the header */
++ if (hdr_exist)
++ ret = lsetxattr(path, XATTR_NAME_IMA, sig_hdr->sig, sig_size, 0);
++ else
++ ret = lsetxattr(path, XATTR_NAME_IMA, sig, sizeof(*sig_hdr) + sig_size, 0);
++
++ if (ret < 0)
++ rpmlog(RPMLOG_ERR, "digest_list: could not apply security.ima "
++ "on '%s': %s\n", path, strerror(errno));
++ else
++ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima successfully "
++ "applied on '%s'\n", path);
++
++ return ret;
++}
++
++static int check_append_signature(const char *path)
++{
++ const char *magic_str="~Module signature appended~";
++ int magic_len = strlen(magic_str);
++ char buf[magic_len + 1];
++ FILE *fp = NULL;
++ struct stat st;
++ int file_size = 0;
++ int ret = 0;
++ long offset = 0;
++
++ if (stat(path, &st) == -1)
++ return 0;
++
++ file_size = st.st_size;
++
++ /* the character \0xa is append to MAGIC */
++ offset = magic_len + 1;
++ if (file_size < offset) {
++ rpmlog(RPMLOG_DEBUG, "digest_list: not have sig, do nothing\n");
++ return 0;
++ }
++
++ fp = fopen(path, "rb+");
++ if (!fp) {
++ rpmlog(RPMLOG_ERR, "digest_list: could not open '%s': %s\n", path, strerror(errno));
++ return 0;
++ }
++
++ ret = fseek(fp, (-offset), SEEK_END);
++ if (ret) {
++ rpmlog(RPMLOG_ERR, "digest_list: seek file fail with %s\n", strerror(errno));
++ fclose(fp);
++ return 0;
++ }
++
++ ret = fread(buf, 1, magic_len, fp);
++ if (ret == magic_len) {
++ if (strncmp(buf, magic_str, magic_len) == 0) {
++ fclose(fp);
++ return 1;
++ }
++ }
++
++ fclose(fp);
++ return 0;
++}
++
++static int process_digest_list(rpmte te, int parser, int pre)
++{
++ char *path = NULL, *path_sig = NULL;
++ int digest_list_signed = 0;
++ int digest_list_signed_append = 0;
++ struct stat st;
++ ssize_t size;
++ int type = rpmteType(te);
++ struct __user_cap_header_struct cap_header_data;
++ cap_user_header_t cap_header = &cap_header_data;
++ struct __user_cap_data_struct cap_data_data;
++ cap_user_data_t cap_data = &cap_data_data;
++ rpmRC ret = RPMRC_OK;
++
++ path = malloc(PATH_MAX);
++ if (!path) {
++ ret = RPMRC_FAIL;
++ goto out;
++ }
++
++ path_sig = malloc(PATH_MAX);
++ if (!path_sig) {
++ ret = RPMRC_FAIL;
++ goto out;
++ }
++
++ if (parser)
++ snprintf(path_sig, PATH_MAX,
++ "%s.sig/0-parser_list-compact-libexec.sig",
++ DIGEST_LIST_DEFAULT_PATH);
++ else
++ snprintf(path_sig, PATH_MAX,
++ "%s.sig/0-metadata_list-compact-%s-%s-%s.%s.sig",
++ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te),
++ rpmteR(te), rpmteA(te));
++
++ if (!stat(path_sig, &st)) {
++ digest_list_signed = 1;
++ rpmlog(RPMLOG_DEBUG, "digest_list: digest_list_signed = 1\n");
++ } else {
++ rpmlog(RPMLOG_DEBUG, "digest_list: digest_list_signed = 0\n");
++ }
++
++ if (parser && !digest_list_signed) {
++ rpmlog(RPMLOG_DEBUG, "digest_list: parser has to be signed!");
++ goto out;
++ }
++
++ if (parser)
++ snprintf(path, PATH_MAX, "%s/0-parser_list-compact-libexec",
++ DIGEST_LIST_DEFAULT_PATH);
++ else
++ snprintf(path, PATH_MAX,
++ "%s/0-metadata_list-compact-%s-%s-%s.%s",
++ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te),
++ rpmteR(te), rpmteA(te));
++
++ if (stat(path, &st) == -1) {
++ rpmlog(RPMLOG_DEBUG, "digest_list: failed to find digest list file path!");
++ goto out;
++ }
++
++ if (!digest_list_signed && check_append_signature(path)) {
++ digest_list_signed = 1;
++ digest_list_signed_append = 1;
++ }
++
++ if (!parser && !digest_list_signed)
++ snprintf(path, PATH_MAX, "%s/0-metadata_list-rpm-%s-%s-%s.%s",
++ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te),
++ rpmteR(te), rpmteA(te));
++
++ size = lgetxattr(path, XATTR_NAME_IMA, NULL, 0);
++
++ if (type == TR_ADDED && !pre && size < 0) {
++ if (!digest_list_signed) {
++ /* Write RPM header to the disk */
++ ret = write_rpm_digest_list(te, path);
++ if (ret < 0) {
++ ret = RPMRC_FAIL;
++ goto out;
++ }
++ }
++
++ /* don't call lsetxattr without CAP_SYS_ADMIN */
++ cap_header->pid = getpid();
++ cap_header->version = _LINUX_CAPABILITY_VERSION_1;
++ if (capget(cap_header, cap_data) < 0) {
++ ret = -ENOENT;
++ goto out;
++ }
++ if (!(cap_data->effective & CAP_TO_MASK(CAP_SYS_ADMIN))) {
++ ret = -EPERM;
++ goto out;
++ }
++
++ if (!digest_list_signed) {
++ /* Write RPM header sig to security.ima */
++ ret = write_rpm_digest_list_ima_xattr(te, path);
++ } else if (digest_list_signed_append) {
++ ret = RPMRC_OK;
++ } else {
++ ret = write_digest_list_ima_xattr(te, path, path_sig);
++ }
++
++ if (ret < 0) {
++ ret = RPMRC_FAIL;
++ goto out;
++ }
++ } else if (type == TR_ADDED && pre) {
++ if (size < 0)
++ goto out;
++
++ /* rpm is overwriting the digest list, remove from the kernel */
++ type = TR_REMOVED;
++ }
++
++ /* Upload digest list to securityfs */
++ upload_digest_list(path, type, digest_list_signed);
++
++ if (type == TR_REMOVED) {
++ if (!digest_list_signed) {
++ unlink(path);
++ goto out;
++ }
++ }
++out:
++ free(path);
++ free(path_sig);
++ return ret;
++}
++
++rpmte cur_te;
++int digest_list_counter;
++
++static rpmRC digest_list_psm_pre(rpmPlugin plugin, rpmte te)
++{
++ Header rpm = rpmteHeader(te);
++ rpmtd dirnames, dirindexes;
++ int i = -1;
++
++ digest_list_counter = 0;
++
++ dirnames = rpmtdNew();
++ headerGet(rpm, RPMTAG_DIRNAMES, dirnames, 0);
++
++ while ((i = rpmtdNext(dirnames)) >= 0) {
++ char *dirname = (char *) rpmtdGetString(dirnames);
++
++ if (!strncmp(dirname, DIGEST_LIST_DEFAULT_PATH,
++ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1) &&
++ dirname[sizeof(DIGEST_LIST_DEFAULT_PATH) - 1] == '/')
++ break;
++ }
++
++ rpmtdFree(dirnames);
++
++ if (i == -1)
++ return RPMRC_OK;
++
++ dirindexes = rpmtdNew();
++ headerGet(rpm, RPMTAG_DIRINDEXES, dirindexes, 0);
++ while (rpmtdNext(dirindexes) >= 0)
++ if (rpmtdGetNumber(dirindexes) == i)
++ digest_list_counter++;
++
++ rpmtdFree(dirindexes);
++
++ cur_te = te;
++ return RPMRC_OK;
++}
++
++static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi,
++ const char* path, mode_t file_mode,
++ rpmFsmOp op, int pre, int res)
++{
++ rpmFileAction action = XFO_ACTION(op);
++
++ if (!digest_list_counter)
++ return RPMRC_OK;
++
++ if (!cur_te)
++ return RPMRC_OK;
++
++ if (!pre && res != RPMRC_OK)
++ return res;
++
++ if (!pre && rpmteType(cur_te) != TR_ADDED)
++ return RPMRC_OK;
++
++ if (pre && action == FA_SKIP)
++ return RPMRC_OK;
++
++ if (path == NULL || strncmp(path, DIGEST_LIST_DEFAULT_PATH,
++ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1) ||
++ path[sizeof(DIGEST_LIST_DEFAULT_PATH) - 1] != '/')
++ return RPMRC_OK;
++
++ if (!pre && --digest_list_counter)
++ return RPMRC_OK;
++
++ rpmlog(RPMLOG_DEBUG, "process ima digest, pre: %d, action: %d, teType: %d\n",
++ pre, action, rpmteType(cur_te));
++ process_digest_list(cur_te, 0, pre);
++ if (!strcmp(rpmteN(cur_te), "digest-list-tools")) {
++ if (pre && rpmteType(cur_te) == TR_REMOVED)
++ return RPMRC_OK;
++
++ rpmlog(RPMLOG_DEBUG, "process parser digest\n");
++ process_digest_list(cur_te, 1, pre);
++ }
++
++ return RPMRC_OK;
++}
++
++static rpmRC digest_list_file_pre(rpmPlugin plugin, rpmfi fi,
++ const char* path, mode_t file_mode,
++ rpmFsmOp op)
++{
++ return digest_list_file_common(plugin, fi, path, file_mode, op, 1, 0);
++}
++
++static rpmRC digest_list_file_post(rpmPlugin plugin, rpmfi fi,
++ const char* path, mode_t file_mode,
++ rpmFsmOp op, int res)
++{
++ return digest_list_file_common(plugin, fi, path, file_mode, op, 0, res);
++}
++
++struct rpmPluginHooks_s digest_list_hooks = {
++ .psm_pre = digest_list_psm_pre,
++ .fsm_file_pre = digest_list_file_pre,
++ .fsm_file_post = digest_list_file_post,
++};
+--
+2.46.0
+
diff --git a/Add-loongarch-architecture-support.patch b/Add-loongarch-architecture-support.patch
new file mode 100644
index 0000000..6b539a7
--- /dev/null
+++ b/Add-loongarch-architecture-support.patch
@@ -0,0 +1,75 @@
+From 3100da59abd272fc3f301a30ebabedf86b0b4a00 Mon Sep 17 00:00:00 2001
+From: Sun Haiyong <sunhaiyong@loongson.cn>
+Date: Tue, 21 Dec 2021 20:40:27 +0800
+Subject: [PATCH] Add loongarch architecture support.
+
+---
+ installplatform | 12 ++++++++++++
+ rpmrc.in | 17 +++++++++++++++++
+ 2 files changed, 29 insertions(+)
+
+diff --git a/installplatform b/installplatform
+index ddcaa6d..fd37b0c 100755
+--- a/installplatform
++++ b/installplatform
+@@ -180,6 +180,12 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do
+ CANONARCH=riscv64
+ CANONCOLOR=3
+ ;;
++ loongarch32)
++ ISANAME=loongarch
++ ISABITS=32
++ CANONARCH=loongarch32
++ CANONCOLOR=0
++ ;;
+ loongarch64)
+ ISANAME=loongarch
+ ISABITS=64
+diff --git a/rpmrc.in b/rpmrc.in
+index 6861b0a..74caf90 100644
+--- a/rpmrc.in
++++ b/rpmrc.in
+@@ -157,7 +157,7 @@ archcolor: aarch64 2
+ archcolor: aarch64_ilp32 1
+ archcolor: riscv64 2
+
+-
++archcolor: loongarch32 1
+ archcolor: loongarch64 2
+
+ #############################################################
+@@ -263,6 +263,7 @@ arch_canon: riscv: riscv64 22
+ arch_canon: riscv64: riscv64 22
+
+ arch_canon: loongarch64: loongarch64 23
++arch_canon: loongarch32: loongarch32 24
+
+ #############################################################
+ # Canonical OS names and numbers
+@@ -395,6 +396,7 @@ buildarchtranslate: aarch64_ilp32: aarch64_ilp32
+ buildarchtranslate: riscv: riscv64
+ buildarchtranslate: riscv64: riscv64
+
++buildarchtranslate: loongarch32: loongarch32
+ buildarchtranslate: loongarch64: loongarch64
+
+ #########################################/####################
+@@ -538,6 +540,7 @@ os_compat: bsdi4.0: bsdi
+
+ os_compat: Darwin: MacOSX
+
++arch_compat: loongarch32: noarch
+ arch_compat: loongarch64: noarch
+
+ buildarch_compat: ia64: noarch
+@@ -645,6 +648,7 @@ buildarch_compat: sh4: noarch
+ buildarch_compat: sh4a: sh4
+
+
++buildarch_compat: loongarch32: noarch
+ buildarch_compat: loongarch64: noarch
+
+ # \endverbatim
+--
+2.27.0
+
diff --git a/Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch b/Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch
new file mode 100644
index 0000000..73d236a
--- /dev/null
+++ b/Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch
@@ -0,0 +1,40 @@
+From eee654b9652fb9387018f9653431a11401a354fd Mon Sep 17 00:00:00 2001
+From: openeuler-basic <shenyangyang4@huawei.com>
+Date: Thu, 9 Jan 2020 19:16:58 +0800
+Subject: [PATCH] Unbundle config site and add RPM LD FLAGS macro
+
+---
+ macros.in | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/macros.in b/macros.in
+index a2411d7..8cb8a5a 100644
+--- a/macros.in
++++ b/macros.in
+@@ -727,10 +727,11 @@ package or when debugging this package.\
+ RPM_SOURCE_DIR=\"%{_sourcedir}\"\
+ RPM_BUILD_DIR=\"%{_builddir}\"\
+ RPM_OPT_FLAGS=\"%{optflags}\"\
++ RPM_LD_FLAGS=\"%{?build_ldflags}\"\
+ RPM_ARCH=\"%{_arch}\"\
+ RPM_OS=\"%{_os}\"\
+ RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\
+- export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
++ export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS RPM_OPT_FLAGS\
+ RPM_DOC_DIR=\"%{_docdir}\"\
+ export RPM_DOC_DIR\
+ RPM_PACKAGE_NAME=\"%{NAME}\"\
+@@ -746,7 +747,9 @@ package or when debugging this package.\
+ %{?_javaclasspath:CLASSPATH=\"%{_javaclasspath}\"\
+ export CLASSPATH}\
+ PKG_CONFIG_PATH=\"${PKG_CONFIG_PATH}:%{_libdir}/pkgconfig:%{_datadir}/pkgconfig\"\
+- export PKG_CONFIG_PATH
++ export PKG_CONFIG_PATH\
++ CONFIG_SITE=${CONFIG_SITE:-NONE}\
++ export CONFIG_SITE
+
+ %___build_pre \
+ %{___build_pre_env} \
+--
+2.27.0
+
diff --git a/add-default-machine-name-to-support-loongarch.patch b/add-default-machine-name-to-support-loongarch.patch
new file mode 100644
index 0000000..f127fe0
--- /dev/null
+++ b/add-default-machine-name-to-support-loongarch.patch
@@ -0,0 +1,30 @@
+From f492b34a694a4bf40e075a030c01f360eaa5500e Mon Sep 17 00:00:00 2001
+From: Wenlong Zhang <zhangwenlong@loongson.cn>
+Date: Fri, 27 May 2022 09:41:38 +0800
+Subject: [PATCH] add default machine name to support loongarch
+
+---
+ lib/rpmrc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/lib/rpmrc.c b/lib/rpmrc.c
+index 120777c..bd0dbca 100644
+--- a/lib/rpmrc.c
++++ b/lib/rpmrc.c
+@@ -1242,6 +1242,13 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os)
+ }
+ # endif /* riscv */
+
++# if defined(__linux__) && defined(__loongarch__)
++ if (sizeof(long) == 4)
++ strcpy(un.machine, "loongarch32");
++ else if (sizeof(long) == 8)
++ strcpy(un.machine, "loongarch64");
++# endif /* loongarch */
++
+ # if defined(__GNUC__) && defined(__alpha__)
+ {
+ unsigned long amask, implver;
+--
+2.27.0
+
diff --git a/add-dist-to-release-by-default.patch b/add-dist-to-release-by-default.patch
new file mode 100644
index 0000000..374a5d5
--- /dev/null
+++ b/add-dist-to-release-by-default.patch
@@ -0,0 +1,37 @@
+From af9a2347cd725a8dbb6045d7d3e9661d524af110 Mon Sep 17 00:00:00 2001
+From: openEuler Buildteam <buildteam@openeuler.org>
+Date: Wed, 4 Mar 2020 16:12:58 +0800
+Subject: [PATCH] add dist to release by default
+
+---
+ build/parsePreamble.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/build/parsePreamble.c b/build/parsePreamble.c
+index b0a17c8..cac899a 100644
+--- a/build/parsePreamble.c
++++ b/build/parsePreamble.c
+@@ -808,6 +808,11 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
+ case RPMTAG_VERSION:
+ case RPMTAG_RELEASE:
+ SINGLE_TOKEN_ONLY;
++ if (tag == RPMTAG_RELEASE) {
++ char *dist = rpmExpand("%{?dist}",NULL);
++ rasprintf(&field,"%s%s",field,dist);
++ free(dist);
++ }
+ if (rpmCharCheck(spec, field, ALLOWED_CHARS_VERREL, NULL))
+ goto exit;
+ headerPutString(pkg->header, tag, field);
+@@ -987,6 +992,8 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
+ }
+ rc = RPMRC_OK;
+ exit:
++ if (tag == RPMTAG_RELEASE)
++ free(field);
+ return rc;
+ }
+
+--
+1.8.3.1
+
diff --git a/backport-An-enumeration-is-not-a-bitfield-use-an-integer-inst.patch b/backport-An-enumeration-is-not-a-bitfield-use-an-integer-inst.patch
new file mode 100644
index 0000000..158288a
--- /dev/null
+++ b/backport-An-enumeration-is-not-a-bitfield-use-an-integer-inst.patch
@@ -0,0 +1,36 @@
+From 7108c172f4e60c83ecc1eeb2a766eb7eaa5956d7 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Fri, 15 Mar 2024 10:03:26 +0200
+Subject: [PATCH] An enumeration is not a bitfield, use an integer instead
+
+Enums are good for individual bitfield flag names, but combination of
+the bits is not a legit value really.
+
+Conflict:don't modify rpmfileutil.h because 8ef29094fa is not mearged; adapt context.
+Reference:https://github.com/rpm-software-management/rpm/commit/7108c172f4e60c83ecc1eeb2a766eb7eaa5956d7
+
+---
+ include/rpm/rpmmacro.h | 5 +++--
+ 1 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/include/rpm/rpmmacro.h b/include/rpm/rpmmacro.h
+index 979763a76..7b23fda59 100644
+--- a/include/rpm/rpmmacro.h
++++ b/include/rpm/rpmmacro.h
+@@ -62,10 +62,11 @@ extern const char * macrofiles;
+ /* rpm macro expansion flags */
+ #define RPMEXPAND_EXPAND_ARGS (1 << 0) /*!< expand arguments of parametric macros */
+
+-typedef enum rpmMacroFlags_e {
++enum rpmMacroFlags_e {
+ RPMMACRO_DEFAULT = 0,
+ RPMMACRO_LITERAL = (1 << 0), /*!< do not expand body of macro */
+-} rpmMacroFlags;
++};
++typedef rpmFlags rpmMacroFlags;
+
+ /** \ingroup rpmmacro
+ * Print macros to file stream.
+--
+2.33.0
+
diff --git a/backport-Check-inside-root-when-querying-for-files.patch b/backport-Check-inside-root-when-querying-for-files.patch
new file mode 100644
index 0000000..3759486
--- /dev/null
+++ b/backport-Check-inside-root-when-querying-for-files.patch
@@ -0,0 +1,38 @@
+From 3e820eaa4c8cb94a63338366cbf014dc5264eba2 Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Tue, 25 Jul 2023 12:08:42 +0200
+Subject: [PATCH] Check inside --root when querying for files
+
+rpm -qf checks if the argument actually exists if it can't be found in
+the rpmdb and gives different messages based on that.
+
+This was done without taking the root dir into account leading to wrong
+messages if the file only exists in the root dir but not outside.
+
+Resolves: #2576
+---
+ lib/query.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/lib/query.c b/lib/query.c
+index e816241b7..dc2dc910b 100644
+--- a/lib/query.c
++++ b/lib/query.c
+@@ -470,11 +470,13 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
+
+ if (mi == NULL) {
+ struct stat sb;
+- if (lstat(fn, &sb) != 0)
++ char * full_fn = rpmGetPath(rpmtsRootDir(ts), fn, NULL);
++ if (lstat(full_fn, &sb) != 0)
+ rpmlog(RPMLOG_ERR, _("file %s: %s\n"), fn, strerror(errno));
+ else
+ rpmlog(RPMLOG_NOTICE,
+ _("file %s is not owned by any package\n"), fn);
++ free(full_fn);
+ }
+
+ free(fn);
+--
+2.27.0
+
diff --git a/backport-Fix-V-option-usage-in-our-tests.patch b/backport-Fix-V-option-usage-in-our-tests.patch
new file mode 100644
index 0000000..0c3e9fa
--- /dev/null
+++ b/backport-Fix-V-option-usage-in-our-tests.patch
@@ -0,0 +1,242 @@
+From 826cbb8869e7d640fe3c2582a3a8dacf393e1ee0 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Wed, 21 Aug 2024 15:02:36 +0200
+Subject: [PATCH] Fix -V option usage in our tests
+
+Conflict:adapt context because 760eb8638 is not merged
+Reference:https://github.com/rpm-software-management/rpm/commit/826cbb8869e7d640fe3c2582a3a8dacf393e1ee0
+
+Coupling -V with -a when querying for specific packages makes little
+sense and only causes the order of the output lines to depend on the
+database ordering.
+
+This is known to vary between the ndb and sqlite backends in particular,
+confusing some of the tests that expect the lines to be in a specific
+order.
+
+While at it, fix all such questionable usages, even those that only
+entail one package argument.
+
+Fixes: #3242
+---
+ tests/rpme.at | 16 ++++++++--------
+ tests/rpmverify.at | 38 +++++++++++++++++++-------------------
+ 2 files changed, 27 insertions(+), 27 deletions(-)
+
+diff --git a/tests/rpme.at b/tests/rpme.at
+index ead757579..058d929fd 100644
+--- a/tests/rpme.at
++++ b/tests/rpme.at
+@@ -293,9 +293,9 @@ done
+ RPMTEST_CHECK([
+ runroot rpm -U --ignoreos /build/RPMS/noarch/conflicta-1.0-1.noarch.rpm
+ runroot rpm -U --ignoreos --excludepath=/usr/share /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+-runroot rpm -Vav --nogroup --nouser conflicta conflictb
++runroot rpm -Vv --nogroup --nouser conflicta conflictb
+ runroot rpm -e conflicta
+-runroot rpm -Vav --nogroup --nouser conflictb
++runroot rpm -Vv --nogroup --nouser conflictb
+ runroot rpm -e conflictb
+ runroot rpm -Vp --nogroup --nouser /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+ ],
+@@ -310,9 +310,9 @@ missing /usr/share/my.version
+ RPMTEST_CHECK([
+ runroot rpm -U --ignoreos --excludepath=/usr/share /build/RPMS/noarch/conflicta-1.0-1.noarch.rpm
+ runroot rpm -U --ignoreos /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+-runroot rpm -Vav --nogroup --nouser conflicta conflictb
++runroot rpm -Vv --nogroup --nouser conflicta conflictb
+ runroot rpm -e conflicta
+-runroot rpm -Vav --nogroup --nouser conflictb
++runroot rpm -Vv --nogroup --nouser conflictb
+ runroot rpm -e conflictb
+ runroot rpm -Vp --nogroup --nouser /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+ ],
+@@ -327,9 +327,9 @@ missing /usr/share/my.version
+ RPMTEST_CHECK([
+ runroot rpm -U --ignoreos /build/RPMS/noarch/conflicta-1.0-1.noarch.rpm
+ runroot rpm -U --ignoreos --force /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+-runroot rpm -Vav --nogroup --nouser conflicta conflictb
++runroot rpm -Vv --nogroup --nouser conflicta conflictb
+ runroot rpm -e conflicta
+-runroot rpm -Vav --nogroup --nouser conflictb
++runroot rpm -Vv --nogroup --nouser conflictb
+ runroot rpm -e conflictb
+ runroot rpm -Vp --nogroup --nouser /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+ ],
+@@ -344,9 +344,9 @@ missing /usr/share/my.version
+ RPMTEST_CHECK([
+ runroot rpm -U --ignoreos /build/RPMS/noarch/conflicta-1.0-1.noarch.rpm
+ runroot rpm -U --ignoreos --force /build/RPMS/noarch/conflictb-1.0-1.noarch.rpm
+-runroot rpm -Vav --nogroup --nouser conflicta conflictb
++runroot rpm -Vv --nogroup --nouser conflicta conflictb
+ runroot rpm -e conflictb
+-runroot rpm -Vav --nogroup --nouser conflicta
++runroot rpm -Vv --nogroup --nouser conflicta
+ runroot rpm -e conflicta
+ ],
+ [0],
+diff --git a/tests/rpmverify.at b/tests/rpmverify.at
+index 3a87b085f..32427021d 100644
+--- a/tests/rpmverify.at
++++ b/tests/rpmverify.at
+@@ -304,13 +304,13 @@ touch -t 201703171717 ${tf}
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-2.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ cat "${tf}"
+
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ cat "${tf}"
+
+ echo "xx" > "${tf}"
+@@ -319,7 +319,7 @@ cat "${tf}"
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-4.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ cat "${tf}"
+
+ touch -t 201703171717 ${tf}
+@@ -327,7 +327,7 @@ touch -t 201703171717 ${tf}
+ runroot rpm -U --oldpackage \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ cat "${tf}"
+ ],
+ [0],
+@@ -352,7 +352,7 @@ touch -t 201703171717 ${tf}
+ runroot rpm -Uvv --fsmdebug \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-2.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ cat "${tf}"
+
+@@ -360,7 +360,7 @@ cat "${tf}"
+ runroot rpm -Uvv --fsmdebug \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ cat "${tf}"
+ echo "xx" > "${tf}"
+@@ -369,7 +369,7 @@ cat "${tf}"
+ runroot rpm -Uvv --fsmdebug \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-4.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ cat "${tf}"
+
+@@ -378,7 +378,7 @@ touch -t 201703171717 ${tf}
+ runroot rpm -U -Uvv --fsmdebug --oldpackage \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ cat "${tf}"
+ ],
+@@ -449,13 +449,13 @@ readlink "${tf}"
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-2.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ readlink "${tf}"
+
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ readlink "${tf}"
+
+ ln -sf "xx" "${tf}"
+@@ -464,13 +464,13 @@ readlink "${tf}"
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-4.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ readlink "${tf}"
+
+ runroot rpm -U --oldpackage \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ readlink "${tf}"
+ ],
+ [0],
+@@ -494,7 +494,7 @@ readlink "${tf}"
+ runroot rpm -Uvv --fsmdebug \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-2.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ readlink "${tf}"
+
+@@ -502,7 +502,7 @@ readlink "${tf}"
+ runroot rpm -Uvv --fsmdebug \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ readlink "${tf}"
+ ln -sf "xx" "${tf}"
+@@ -511,14 +511,14 @@ readlink "${tf}"
+ runroot rpm -Uvv --fsmdebug \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-4.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ readlink "${tf}"
+
+ runroot rpm -U -Uvv --fsmdebug --oldpackage \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-3.0-1.noarch.rpm > output.txt 2>&1
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ grep -c "touch" output.txt
+ readlink "${tf}"
+ ],
+@@ -554,17 +554,17 @@ for v in "1.0" "2.0"; do
+ done
+
+ runroot rpm -U /build/RPMS/noarch/replacetest-1.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-2.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ chmod 777 "${tf}"
+ runroot rpm -U \
+ --oldpackage \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-1.0-1.noarch.rpm
+-runroot rpm -Va --nouser --nogroup replacetest
++runroot rpm -V --nouser --nogroup replacetest
+ ],
+ [0],
+ [],
+--
+2.33.0
+
diff --git a/backport-Fix-a-memleak-on-invalid-command-line-options.patch b/backport-Fix-a-memleak-on-invalid-command-line-options.patch
new file mode 100644
index 0000000..faff556
--- /dev/null
+++ b/backport-Fix-a-memleak-on-invalid-command-line-options.patch
@@ -0,0 +1,85 @@
+From 1825dbf8244b129665a69481c4537a57b9e03a8f Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Wed, 21 Feb 2024 16:07:05 +0200
+Subject: [PATCH] Fix a memleak on invalid command line options
+
+ The OS will clean it up yes, but in the meanwhile ASAN (when enabled)
+ blew up on your face and scared you silly. Use the opportunity to add a
+ test for a test on invalid option.
+
+---
+ lib/poptALL.c | 11 ++++++++---
+ tests/rpmgeneral.at | 10 +++++++++-
+ 2 files changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/lib/poptALL.c b/lib/poptALL.c
+index b24c13e..a2bbedc 100644
+--- a/lib/poptALL.c
++++ b/lib/poptALL.c
+@@ -296,7 +296,7 @@ rpmcliFini(poptContext optCon)
+ poptContext
+ rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
+ {
+- poptContext optCon;
++ poptContext optCon = NULL;
+ int rc;
+ const char *ctx, *execPath;
+
+@@ -336,14 +336,14 @@ rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
+ while ((rc = poptGetNextOpt(optCon)) > 0) {
+ fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
+ xgetprogname(), rc);
+- exit(EXIT_FAILURE);
++ goto err;
+ }
+
+ if (rc < -1) {
+ fprintf(stderr, "%s: %s: %s\n", xgetprogname(),
+ poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
+ poptStrerror(rc));
+- exit(EXIT_FAILURE);
++ goto err;
+ }
+
+ /* Read rpm configuration (if not already read). */
+@@ -355,4 +355,9 @@ rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
+ }
+
+ return optCon;
++
++err:
++ poptFreeContext(optCon);
++ exit(EXIT_FAILURE);
++ return NULL; /* not reached */
+ }
+diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at
+index cf1f507..4281315 100644
+--- a/tests/rpmgeneral.at
++++ b/tests/rpmgeneral.at
+@@ -26,7 +26,6 @@ RPMTEST_CHECK([runroot rpm --version],[0],
+ ])
+ RPMTEST_CLEANUP
+
+-
+ # ------------------------------
+ AT_SETUP([rpmbuild --version])
+ AT_KEYWORDS([basic])
+@@ -35,6 +34,15 @@ RPMTEST_CHECK([runroot rpmbuild --version],[0],
+ ])
+ RPMTEST_CLEANUP
+
++AT_SETUP([rpm invalid option])
++AT_KEYWORDS([basic])
++AT_CHECK([runroot rpm --badopt],
++[1],
++[],
++[rpm: --badopt: unknown option
++])
++AT_CLEANUP
++
+ # Check that libtool versioning matches expectations, it's easy to screw up.
+ AT_SETUP([rpm library version])
+ AT_KEYWORDS([basic])
+--
+2.33.0
+
diff --git a/backport-Fix-a-theoretical-use-of-uninitialized-struct-member.patch b/backport-Fix-a-theoretical-use-of-uninitialized-struct-member.patch
new file mode 100644
index 0000000..69a0dc7
--- /dev/null
+++ b/backport-Fix-a-theoretical-use-of-uninitialized-struct-member.patch
@@ -0,0 +1,31 @@
+From 656fe42af1d497c35769c740fcc98950e1455bad Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Wed, 24 Jan 2024 12:44:34 +0200
+Subject: [PATCH] Fix a theoretical use of uninitialized struct members
+
+If rpmScriptFromTriggerTag() was called with tm other than the three
+handled cases in the switch, the rpmtd_s structs would be uninitialized
+and weird things could happen. The value of tm is hardwired in all the
+existing callers AFAICS but the extra safety doesn't hurt either.
+
+Discovered by static analysis in RHEL.
+---
+ lib/rpmscript.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/rpmscript.c b/lib/rpmscript.c
+index b18f851a3..3f6313278 100644
+--- a/lib/rpmscript.c
++++ b/lib/rpmscript.c
+@@ -641,6 +641,8 @@ rpmScript rpmScriptFromTriggerTag(Header h, rpmTagVal triggerTag,
+ headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTFLAGS, &tflags, hgflags);
+ prefix = "transfile";
+ break;
++ default:
++ return NULL;
+ }
+
+ if (rpmtdSetIndex(&tscripts, ix) >= 0 && rpmtdSetIndex(&tprogs, ix) >= 0) {
+--
+2.33.0
+
diff --git a/backport-Fix-an-ancient-memleak-on-caps-parsing-add-tests.patch b/backport-Fix-an-ancient-memleak-on-caps-parsing-add-tests.patch
new file mode 100644
index 0000000..bc0dd4d
--- /dev/null
+++ b/backport-Fix-an-ancient-memleak-on-caps-parsing-add-tests.patch
@@ -0,0 +1,34 @@
+From a385821780804b558ae18aec820d127e4144fafd Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 11 Apr 2024 12:08:04 +0300
+Subject: [PATCH] Fix an ancient memleak on %caps() parsing, add tests
+
+Conflict:don't modify tests because the test case depends on the gcc.
+Reference:https://github.com/rpm-software-management/rpm/commit/a385821780804b558ae18aec820d127e4144fafd
+
+This leak has been there ever since rpm 4.7.0, so pretty close to 15
+years. ASAN would've caught it, if it had it been tested. Oops.
+Of course, in the fakechroot era we couldn't have tested installation
+but we could've at least tested the parsing side.
+
+Add tests for parsing, query and install functionality, and fix the
+leak that is now very visible.
+---
+ build/files.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/build/files.c b/build/files.c
+index 14e4c55ef..b059458a1 100644
+--- a/build/files.c
++++ b/build/files.c
+@@ -228,6 +228,7 @@ static void copyFileEntry(FileEntry src, FileEntry dest)
+ static void FileEntryFree(FileEntry entry)
+ {
+ argvFree(entry->langs);
++ free(entry->caps);
+ memset(entry, 0, sizeof(*entry));
+ }
+
+--
+2.33.0
+
diff --git a/backport-Fix-an-enum-int-type-mismatch-in-rpmfiArchiveReadToF.patch b/backport-Fix-an-enum-int-type-mismatch-in-rpmfiArchiveReadToF.patch
new file mode 100644
index 0000000..eb10f73
--- /dev/null
+++ b/backport-Fix-an-enum-int-type-mismatch-in-rpmfiArchiveReadToF.patch
@@ -0,0 +1,32 @@
+From 6c01f4c84f768b6c6b247a11106bf51b40015e66 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Mon, 18 Mar 2024 09:56:51 +0200
+Subject: [PATCH] Fix an enum/int type mismatch in rpmfiArchiveReadToFilePsm()
+
+rpmfiDigestAlgo() hysterically returns a signed int (and that's what
+really ought to be changed) but lets at least make all these uses
+consistent.
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/6c01f4c84f768b6c6b247a11106bf51b40015e66
+
+---
+ lib/rpmfi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/rpmfi.c b/lib/rpmfi.c
+index cfb388b4c..db1460711 100644
+--- a/lib/rpmfi.c
++++ b/lib/rpmfi.c
+@@ -2384,7 +2384,7 @@ int rpmfiArchiveReadToFilePsm(rpmfi fi, FD_t fd, int nodigest, rpmpsm psm)
+
+ rpm_loff_t left = rpmfiFSize(fi);
+ const unsigned char * fidigest = NULL;
+- rpmHashAlgo digestalgo = 0;
++ int digestalgo = 0;
+ int rc = 0;
+ char buf[BUFSIZ*4];
+
+--
+2.33.0
+
diff --git a/backport-Fix-an-enum-int-type-mismatch-in-transaction-verify-.patch b/backport-Fix-an-enum-int-type-mismatch-in-transaction-verify-.patch
new file mode 100644
index 0000000..5b8ae40
--- /dev/null
+++ b/backport-Fix-an-enum-int-type-mismatch-in-transaction-verify-.patch
@@ -0,0 +1,28 @@
+From 90cfa466ae88b06595012084eada25a42064322c Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Mon, 18 Mar 2024 09:48:48 +0200
+Subject: [PATCH] Fix an enum/int type mismatch in transaction verify code
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/90cfa466ae88b06595012084eada25a42064322c
+
+---
+ lib/transaction.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/transaction.c b/lib/transaction.c
+index fcde554a6..6a49eb242 100644
+--- a/lib/transaction.c
++++ b/lib/transaction.c
+@@ -1288,7 +1288,7 @@ static int verifyPackageFiles(rpmts ts, rpm_loff_t total)
+ .vfylevel = vfylevel,
+ };
+ int verified = 0;
+- rpmRC prc = RPMRC_FAIL;
++ int prc = RPMRC_FAIL;
+
+ rpmtsNotify(ts, p, RPMCALLBACK_VERIFY_PROGRESS, oc++, total);
+ FD_t fd = rpmtsNotify(ts, p, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
+--
+2.33.0
+
diff --git a/backport-Fix-crash-on-Lua-file-trigger-exiting-with-return-ed.patch b/backport-Fix-crash-on-Lua-file-trigger-exiting-with-return-ed.patch
new file mode 100644
index 0000000..b1f97fb
--- /dev/null
+++ b/backport-Fix-crash-on-Lua-file-trigger-exiting-with-return-ed.patch
@@ -0,0 +1,81 @@
+From 05fbeb97a92608a9f66faa3f8d1c0fb67b0db62c Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Wed, 7 Aug 2024 12:42:36 +0300
+Subject: [PATCH] Fix crash on Lua file trigger exiting with return'ed data
+ (#3029)
+
+Conflict:modify the test code because b9b3f3515164 and 7f59c7dd2f4
+ is not merged.
+Reference:https://github.com/rpm-software-management/rpm/commit/05fbeb97a92608a9f66faa3f8d1c0fb67b0db62c
+
+Reset the Lua stack on return from rpmluaRunScript() to discard any
+unhandled returned data from the scriptlet. This may happen if there's
+eg "return 0" from a non-macro scriptlet.
+
+We could check for a numeric return value here and treat it as an exit
+code, but then what to do with other kinds of returned data?
+Our documentation states errors in Lua scriptlets should be signaled with
+Lua error() function, it seems better to stick with that and avoid
+introducing ambiguities and incompatibilities.
+
+Update the existing file trigger tests to cover this case.
+
+Fixes: #3029
+---
+ rpmio/rpmlua.c | 2 ++
+ tests/data/SPECS/filetriggers.spec | 11 +++++++++++
+ tests/rpmscript.at | 3 +++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c
+index ecb21eb82..858be7739 100644
+--- a/rpmio/rpmlua.c
++++ b/rpmio/rpmlua.c
+@@ -303,6 +303,8 @@ int rpmluaRunScript(rpmlua lua, const char *script, const char *name,
+
+ exit:
+ free(buf);
++ /* discard any unhandled return data from the script */
++ lua_settop(L, otop);
+ return ret;
+ }
+
+diff --git a/tests/data/SPECS/filetriggers.spec b/tests/data/SPECS/filetriggers.spec
+index 3e2ee0034..e8d3bc7cd 100644
+--- a/tests/data/SPECS/filetriggers.spec
++++ b/tests/data/SPECS/filetriggers.spec
+@@ -52,6 +52,17 @@ end
+ print("")
+ io.flush()
+
++%filetriggerun -p <lua> -- /usr/bin
++print("filetriggerun(/usr/bin*)<lua>: "..arg[2].." "..arg[3])
++a = rpm.next_file()
++while a do
++ print(a)
++ a = rpm.next_file()
++end
++print("")
++io.flush()
++return 0
++
+ %filetriggerin -- /foo
+ echo "filetriggerin(/foo*):"
+ cat
+diff --git a/tests/rpmscript.at b/tests/rpmscript.at
+index 8fc729a56..d47705008 100644
+--- a/tests/rpmscript.at
++++ b/tests/rpmscript.at
+@@ -461,6 +461,9 @@ filetriggerpostun(/foo*):
+ filetriggerun(/usr/bin*): 0
+ /usr/bin/hello
+
++filetriggerun(/usr/bin*)<lua>: 0
++/usr/bin/hello
++
+ filetriggerpostun(/usr/bin*): 0
+ /usr/bin/hello
+
+--
+2.33.0
+
diff --git a/backport-Fix-division-by-zero-in-elfdeps-RhBug-2299414.patch b/backport-Fix-division-by-zero-in-elfdeps-RhBug-2299414.patch
new file mode 100644
index 0000000..48b114e
--- /dev/null
+++ b/backport-Fix-division-by-zero-in-elfdeps-RhBug-2299414.patch
@@ -0,0 +1,30 @@
+From 02ffc5158d1ad270e0b5c7ce6dfe4414a6ec029f Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Wed, 31 Jul 2024 16:19:40 +0200
+Subject: [PATCH] Fix division by zero in elfdeps (RhBug:2299414)
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/02ffc5158d1ad270e0b5c7ce6dfe4414a6ec029f
+
+Assume that the section does not hold a table if sh_entsize is 0 (as
+specified in the elf(5) man page) and just skip it if that's the case.
+---
+ tools/elfdeps.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/elfdeps.c b/tools/elfdeps.c
+index cb388f08d..822359ab9 100644
+--- a/tools/elfdeps.c
++++ b/tools/elfdeps.c
+@@ -196,6 +196,8 @@ static void processVerNeed(Elf_Scn *scn, GElf_Shdr *shdr, elfInfo *ei)
+ static void processDynamic(Elf_Scn *scn, GElf_Shdr *shdr, elfInfo *ei)
+ {
+ Elf_Data *data = NULL;
++ if (shdr->sh_entsize == 0)
++ return;
+ while ((data = elf_getdata(scn, data)) != NULL) {
+ for (int i = 0; i < (shdr->sh_size / shdr->sh_entsize); i++) {
+ const char *s = NULL;
+--
+2.33.0
+
diff --git a/backport-Fix-enum-type-mismatch-in-rpmTagGetValue.patch b/backport-Fix-enum-type-mismatch-in-rpmTagGetValue.patch
new file mode 100644
index 0000000..736e70f
--- /dev/null
+++ b/backport-Fix-enum-type-mismatch-in-rpmTagGetValue.patch
@@ -0,0 +1,30 @@
+From 3a227fdf2965aa6bfc0727170419e9da6cf1fbe2 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Mon, 18 Mar 2024 09:50:05 +0200
+Subject: [PATCH] Fix enum type mismatch in rpmTagGetValue()
+
+This returns a tag value, not type.
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/3a227fdf2965aa6bfc0727170419e9da6cf1fbe2
+
+---
+ lib/tagname.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/tagname.c b/lib/tagname.c
+index 4e7c30d2b..4748cf19c 100644
+--- a/lib/tagname.c
++++ b/lib/tagname.c
+@@ -171,7 +171,7 @@ rpmTagType rpmTagGetType(rpmTagVal tag)
+ rpmTagVal rpmTagGetValue(const char * tagstr)
+ {
+ const struct headerTagTableEntry_s *t;
+- rpmTagType tagval = RPMTAG_NOT_FOUND;
++ rpmTagVal tagval = RPMTAG_NOT_FOUND;
+
+ pthread_once(&tagsLoaded, loadTags);
+
+--
+2.33.0
+
diff --git a/backport-Fix-pointer-bogosity-in-rpmlog-callback.patch b/backport-Fix-pointer-bogosity-in-rpmlog-callback.patch
new file mode 100644
index 0000000..d95cf48
--- /dev/null
+++ b/backport-Fix-pointer-bogosity-in-rpmlog-callback.patch
@@ -0,0 +1,31 @@
+From f8a72afbdb560dc534ca1ff390bc54e01d1144a6 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Mon, 8 Apr 2024 14:41:48 +0300
+Subject: [PATCH] Fix pointer bogosity in rpmlog callback
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/f8a72afbdb560dc534ca1ff390bc54e01d1144a6
+
+rpmlogCallbackData is already a pointer type, we don't want a pointer
+to a pointer for this. Kinda surprising it actually worked, but then
+it's just a void pointer so...
+---
+ rpmio/rpmlog.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rpmio/rpmlog.c b/rpmio/rpmlog.c
+index 2bb5ab0e3..3ccbe2692 100644
+--- a/rpmio/rpmlog.c
++++ b/rpmio/rpmlog.c
+@@ -382,7 +382,7 @@ static void dolog(struct rpmlogRec_s *rec, int saverec)
+ int cbrc = RPMLOG_DEFAULT;
+ int needexit = 0;
+ FILE *clog = NULL;
+- rpmlogCallbackData *cbdata = NULL;
++ rpmlogCallbackData cbdata = NULL;
+ rpmlogCallback cbfunc = NULL;
+ rpmlogCtx ctx = rpmlogCtxAcquire(saverec);
+
+--
+2.33.0
+
diff --git a/backport-Fix-potential-use-of-uninitialized-pgp-struct.patch b/backport-Fix-potential-use-of-uninitialized-pgp-struct.patch
new file mode 100644
index 0000000..4595196
--- /dev/null
+++ b/backport-Fix-potential-use-of-uninitialized-pgp-struct.patch
@@ -0,0 +1,35 @@
+From 1b90b8c7d176026b669ce28c6e185724a4b208b0 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Fri, 7 Jun 2024 10:14:25 +0200
+Subject: [PATCH] Fix potential use of uninitialized pgp struct
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/1b90b8c7d176026b669ce28c6e185724a4b208b0
+
+We only call initPgpData() after base64 encoding the pubkey so if the
+latter fails, the kd struct will be left uninitialized and subsequently
+read from after skipping to the exit label. Fix by initializing it.
+
+Found by Coverity.
+
+Fixes: RHEL-22605
+---
+ lib/rpmts.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/rpmts.c b/lib/rpmts.c
+index 3070b97e6..76964c60a 100644
+--- a/lib/rpmts.c
++++ b/lib/rpmts.c
+@@ -508,6 +508,8 @@ static int makePubkeyHeader(rpmts ts, rpmPubkey key, rpmPubkey *subkeys,
+ int rc = -1;
+ int i;
+
++ memset(&kd, 0, sizeof(kd));
++
+ if ((enc = rpmPubkeyBase64(key)) == NULL)
+ goto exit;
+
+--
+2.33.0
+
diff --git a/backport-Fix-potential-use-of-uninitialized-pipe-array.patch b/backport-Fix-potential-use-of-uninitialized-pipe-array.patch
new file mode 100644
index 0000000..c90e429
--- /dev/null
+++ b/backport-Fix-potential-use-of-uninitialized-pipe-array.patch
@@ -0,0 +1,35 @@
+From bff65aad8af719542c7b0c6429e09223c014a909 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Thu, 6 Jun 2024 09:15:02 +0200
+Subject: [PATCH] Fix potential use of uninitialized pipe array
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/bff65aad8af719542c7b0c6429e09223c014a909
+
+We only call pipe(2) after the script is written to disk so if the
+latter fails, the array will be left uninitialized and subsequently read
+after skipping to the exit label. Fix by initializing it.
+
+Found by Coverity.
+
+Fixes: RHEL-22604
+---
+ lib/rpmscript.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/rpmscript.c b/lib/rpmscript.c
+index 281c55c53..1de4acf8e 100644
+--- a/lib/rpmscript.c
++++ b/lib/rpmscript.c
+@@ -316,7 +316,7 @@ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
+ char * fn = NULL;
+ pid_t pid, reaped;
+ int status;
+- int inpipe[2];
++ int inpipe[2] = { -1, -1 };
+ FILE *in = NULL;
+ const char *line;
+ char *mline = NULL;
+--
+2.33.0
+
diff --git a/backport-Fix-root-relocation-regression.patch b/backport-Fix-root-relocation-regression.patch
new file mode 100644
index 0000000..bfe792b
--- /dev/null
+++ b/backport-Fix-root-relocation-regression.patch
@@ -0,0 +1,66 @@
+From 308ac60677732e9979b9ce11e5a3085906da1901 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Fri, 26 Jul 2024 10:44:04 +0200
+Subject: [PATCH] Fix root relocation regression
+
+Conflict:Do not modify the test code because the current test code is
+ different from that of the upstream community. If we directly
+ modify the test code, the test wull fail. Guaranteed by local
+ use cases.
+Reference:https://github.com/rpm-software-management/rpm/commit/308ac60677732e9979b9ce11e5a3085906da1901
+
+When relocating the root directory, make sure we insert the new path's
+dirname to dirNames[] even if the root itself is owned by the package.
+
+This appears to have been the intention from the first version (largely
+untouched since) of this code as we allow the root to pass through the
+first checks (by setting len to 0 in that case) as well as the second
+for loop where we do the relocations.
+
+This allows fsm to properly create and remove the relocated directory
+since we're now using fd-based calls (#1919) and the parent directory
+needs to be opened first.
+
+No need to do string comparison here, the empty basename signals that
+we're processing the root directory, so just use that.
+
+Building a relocatable package that owns the root directory seems to be
+a handy way to create user-installable packages (see RHEL-28967) and it
+happened to work before with the path-based calls so this technically
+was a regression. Add a test that emulates this use case.
+
+Fixes: #3173
+---
+ lib/relocation.c | 8 +++++---
+ 1 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/lib/relocation.c b/lib/relocation.c
+index d31cf4779..0202b5c46 100644
+--- a/lib/relocation.c
++++ b/lib/relocation.c
+@@ -181,8 +181,9 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
+ rpmFileTypes ft;
+ int fnlen;
+
++ size_t baselen = strlen(baseNames[i]);
+ size_t len = maxlen +
+- strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1;
++ strlen(dirNames[dirIndexes[i]]) + baselen + 1;
+ if (len >= fileAlloced) {
+ fileAlloced = len * 2;
+ fn = xrealloc(fn, fileAlloced);
+@@ -244,8 +245,9 @@ assert(fn != NULL); /* XXX can't happen */
+ continue;
+ }
+
+- /* Relocation on full paths only, please. */
+- if (fnlen != len) continue;
++ /* Relocation on '/' and full paths only, please. */
++ if (baselen && fnlen != len)
++ continue;
+
+ rpmlog(RPMLOG_DEBUG, "relocating %s to %s\n",
+ fn, relocations[j].newPath);
+--
+2.33.0
+
diff --git a/backport-Fix-some-int-enum-confusion-in-the-build-code.patch b/backport-Fix-some-int-enum-confusion-in-the-build-code.patch
new file mode 100644
index 0000000..0583b6d
--- /dev/null
+++ b/backport-Fix-some-int-enum-confusion-in-the-build-code.patch
@@ -0,0 +1,68 @@
+From f2eb6fa6ba77fbf5f62add8a01544cce8c0beb6b Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Fri, 15 Mar 2024 16:41:28 +0200
+Subject: [PATCH] Fix some int/enum confusion in the build code
+
+These things are not really returning rpmRC values, especially as they
+need to pass around RPMRC_MISSINGBUILDREQUIRES which is not part of the
+enum.
+
+For doRmSource(), 0 and 1 aren't any more enums values than 0 and -1 are,
+and besides, the sole caller isn't even checking the return code.
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/f2eb6fa6ba77fbf5f62add8a01544cce8c0beb6b
+
+---
+ build/build.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/build/build.c b/build/build.c
+index 8e6c8f842..69ab69fc9 100644
+--- a/build/build.c
++++ b/build/build.c
+@@ -78,7 +78,7 @@ static char * buildHost(void)
+
+ /**
+ */
+-static rpmRC doRmSource(rpmSpec spec)
++static int doRmSource(rpmSpec spec)
+ {
+ struct Source *p;
+ Package pkg;
+@@ -100,7 +100,7 @@ static rpmRC doRmSource(rpmSpec spec)
+ }
+ }
+ exit:
+- return !rc ? 0 : 1;
++ return rc;
+ }
+
+ /*
+@@ -290,9 +290,9 @@ static int doBuildRequires(rpmSpec spec, int test)
+ return rc;
+ }
+
+-static rpmRC doCheckBuildRequires(rpmts ts, rpmSpec spec, int test)
++static int doCheckBuildRequires(rpmts ts, rpmSpec spec, int test)
+ {
+- rpmRC rc = RPMRC_OK;
++ int rc = RPMRC_OK;
+ rpmps ps = rpmSpecCheckDeps(ts, spec);
+
+ if (ps) {
+@@ -323,9 +323,9 @@ static rpmRC doBuildDir(rpmSpec spec, int test, StringBuf *sbp)
+ return rc;
+ }
+
+-static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)
++static int buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)
+ {
+- rpmRC rc = RPMRC_OK;
++ int rc = RPMRC_OK;
+ int missing_buildreqs = 0;
+ int test = (what & RPMBUILD_NOBUILD);
+ char *cookie = buildArgs->cookie ? xstrdup(buildArgs->cookie) : NULL;
+--
+2.33.0
+
diff --git a/backport-Fix-spec-parser-leaks-from-trans-f-file.patch b/backport-Fix-spec-parser-leaks-from-trans-f-file.patch
new file mode 100644
index 0000000..af59a03
--- /dev/null
+++ b/backport-Fix-spec-parser-leaks-from-trans-f-file.patch
@@ -0,0 +1,31 @@
+From 26a1323022e3153d99b2f1095fe040f52fb2e3f3 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Tue, 30 Jan 2024 14:55:54 +0200
+Subject: [PATCH] Fix spec parser leaks from %*trans -f <file>
+
+Conflict:don't free preunTransFile and postunTransFile because
+db46bd8bd1 is not merged
+
+The untrans-versions leak because grepping around didn't turn up
+the trans-counterparts ... because they didn't exist either.
+Those leaks are adults by now.
+---
+ build/spec.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/build/spec.c b/build/spec.c
+index 824afba27..6f8a6a155 100644
+--- a/build/spec.c
++++ b/build/spec.c
+@@ -143,6 +143,8 @@ Package freePackage(Package pkg)
+ pkg->preUnFile = _free(pkg->preUnFile);
+ pkg->postUnFile = _free(pkg->postUnFile);
+ pkg->verifyFile = _free(pkg->verifyFile);
++ pkg->preTransFile = _free(pkg->preTransFile);
++ pkg->postTransFile = _free(pkg->postTransFile);
+
+ pkg->header = headerFree(pkg->header);
+ pkg->ds = rpmdsFree(pkg->ds);
+--
+2.33.0
+
diff --git a/backport-Free-old-cookie-value-to-prevent-a-memory-leak.patch b/backport-Free-old-cookie-value-to-prevent-a-memory-leak.patch
new file mode 100644
index 0000000..27976f9
--- /dev/null
+++ b/backport-Free-old-cookie-value-to-prevent-a-memory-leak.patch
@@ -0,0 +1,28 @@
+From 1849c99826fdc64e8bd0847675e28e2619c64de6 Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Mon, 13 May 2024 15:42:07 +0200
+Subject: [PATCH] Free old cookie value to prevent a memory leak
+
+This keeps the old behaviour of overriding the cookie. This may not me
+correct as the code looks like it reads the cookie from the srpm when
+doing rpmbuild --rebuild for the purpose of preserving it. Otoh the
+current behaviour with overriding it even in this case has been around
+for years. This whole cookie business seems to have some other issues,
+too, and needs further investigation. Here we are only trying to fix the
+memory leak.
+---
+ build/pack.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/build/pack.c b/build/pack.c
+index 4318a6132f..e87d66deb6 100644
+--- a/build/pack.c
++++ b/build/pack.c
+@@ -472,6 +472,7 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
+
+ /* Create and add the cookie */
+ if (cookie) {
++ free(*cookie);
+ rasprintf(cookie, "%s %d", buildHost, buildTime);
+ headerPutString(pkg->header, RPMTAG_COOKIE, *cookie);
+ }
diff --git a/backport-Let-eBPF-ELF-files-be-packaged-in-noarch-packages.patch b/backport-Let-eBPF-ELF-files-be-packaged-in-noarch-packages.patch
new file mode 100644
index 0000000..b05cf19
--- /dev/null
+++ b/backport-Let-eBPF-ELF-files-be-packaged-in-noarch-packages.patch
@@ -0,0 +1,44 @@
+From 5ece87a250880b08ccecfc5b34986347d8cca843 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 8 Feb 2024 09:44:51 +0200
+Subject: [PATCH] Let eBPF ELF files be packaged in noarch packages
+
+ eBPF ELF represents a virtual machine where our file colors make no
+ sense at all. Filter out the color from these files to avoid a
+ "Arch dependent binaries in noarch package" error from them in noarch
+ packages.
+
+ We don't want to pull in clang to the check images just because of
+ this, so add a pre-built binary for the check and a simple way to
+ reproduce from the test-spec.
+
+ Fixes: #2875
+
+Reference:https://github.com/rpm-software-management/rpm/commit/5ece87a250880b08ccecfc5b34986347d8cca843
+Conflict:Deleted binary files and test code because it would add clang
+Requires.
+---
+ build/rpmfc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/build/rpmfc.c b/build/rpmfc.c
+index 07171fa..6d40a19 100644
+--- a/build/rpmfc.c
++++ b/build/rpmfc.c
+@@ -1151,6 +1151,13 @@ static uint32_t getElfColor(const char *fn)
+ color = RPMFC_ELF32;
+ break;
+ }
++
++ /* Exceptions to coloring */
++ switch (ehdr.e_machine) {
++ case EM_BPF:
++ color = 0;
++ break;
++ }
+ }
+ if (elf)
+ elf_end(elf);
+--
+2.33.0
+
diff --git a/backport-Make-sure-dirs-are-not-relocated-twice.patch b/backport-Make-sure-dirs-are-not-relocated-twice.patch
new file mode 100644
index 0000000..5848533
--- /dev/null
+++ b/backport-Make-sure-dirs-are-not-relocated-twice.patch
@@ -0,0 +1,114 @@
+From 31c14ba6610568c2d634647fed1fb57221178da9 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Fri, 26 Jul 2024 10:43:50 +0200
+Subject: [PATCH] Make sure dirs are not relocated twice
+
+Conflict:adapt context
+Reference:https://github.com/rpm-software-management/rpm/commit/31c14ba6610568c2d634647fed1fb57221178da9
+
+When processing relocations, new dirnames are added to dirNames[] first
+and then the rest is relocated. However, we go through the entire array
+in the latter step, meaning that we may accidentally relocate an already
+relocated path.
+
+Most relocations are fine as they involve two separate directory trees,
+and we already skip over directories that don't match the old prefix.
+However, that breaks apart if we're relocating to a nested subdirectory
+(e.g. /opt -> /opt/new/dir).
+
+Fix this by simply stopping at the original dirCount as the new entries
+are always added to the end of dirNames[].
+
+Such relocations are perhaps not very common (or even unsupported) but
+relocating the root directory itself may be useful (see the next commit
+for details) and that is subject to the same issue.
+
+Note that we currently don't handle root relocations properly to start
+with but that will be addressed in the next commit, this prepares the
+ground.
+---
+ lib/relocation.c | 6 +++---
+ tests/rpmi.at | 35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+), 3 deletions(-)
+
+diff --git a/lib/relocation.c b/lib/relocation.c
+index 1eab60211..d31cf4779 100644
+--- a/lib/relocation.c
++++ b/lib/relocation.c
+@@ -124,7 +124,7 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
+ char ** baseNames;
+ char ** dirNames;
+ uint32_t * dirIndexes;
+- rpm_count_t fileCount, dirCount;
++ rpm_count_t fileCount, dirCount, dirCountOrig;
+ int nrelocated = 0;
+ int fileAlloced = 0;
+ char * fn = NULL;
+@@ -163,7 +163,7 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
+ baseNames = bnames.data;
+ dirIndexes = dindexes.data;
+ fileCount = rpmtdCount(&bnames);
+- dirCount = rpmtdCount(&dnames);
++ dirCount = dirCountOrig = rpmtdCount(&dnames);
+ /* XXX TODO: use rpmtdDup() instead */
+ dirNames = dnames.data = duparray(dnames.data, dirCount);
+ dnames.flags |= RPMTD_PTR_ALLOCED;
+@@ -297,7 +297,7 @@ assert(fn != NULL); /* XXX can't happen */
+ }
+
+ /* Finish off by relocating directories. */
+- for (i = dirCount - 1; i >= 0; i--) {
++ for (i = dirCountOrig - 1; i >= 0; i--) {
+ for (j = numRelocations - 1; j >= 0; j--) {
+
+ if (relocations[j].oldPath == NULL) /* XXX can't happen */
+diff --git a/tests/rpmi.at b/tests/rpmi.at
+index 7d1a0a871..372be0a8b 100644
+--- a/tests/rpmi.at
++++ b/tests/rpmi.at
+@@ -1135,6 +1135,42 @@ runroot rpm -U --relocate /opt/bin=/bin \
+ ],
+ [])
+ RPMTEST_CLEANUP
++
++AT_SETUP([rpm -i relocatable package 2])
++AT_KEYWORDS([install relocate])
++RPMDB_INIT
++
++runroot rpmbuild --quiet -bb /data/SPECS/reloc.spec
++runroot rpmbuild --quiet -bb /data/SPECS/fakeshell.spec
++
++runroot rpm -U /build/RPMS/noarch/fakeshell-1.0-1.noarch.rpm
++
++RPMTEST_CHECK([
++runroot rpm -U \
++ --relocate /opt/bin=/opt/bin/foo/bar \
++ --relocate /opt/etc=/opt/etc/foo/bar \
++ --relocate /opt/lib=/opt/lib/foo/bar \
++ /build/RPMS/noarch/reloc-1.0-1.noarch.rpm
++runroot rpm -ql reloc
++],
++[0],
++[1: /opt/bin/foo/bar
++2: /opt/etc/foo/bar
++3: /opt/lib/foo/bar
++0: /opt/bin/foo/bar
++1: /opt/etc/foo/bar
++2: /opt/lib/foo/bar
++/opt
++/opt/bin/foo/bar
++/opt/bin/foo/bar/typo
++/opt/etc/foo/bar
++/opt/etc/foo/bar/conf
++/opt/lib/foo/bar
++/opt/lib/foo/bar/notlib
++],
++[])
++RPMTEST_CLEANUP
++
+ AT_SETUP([rpm -i with/without --excludedocs])
+ AT_KEYWORDS([install excludedocs])
+ RPMTEST_CHECK([
+--
+2.33.0
+
diff --git a/backport-Reset-recursion-depth-for-error-message.patch b/backport-Reset-recursion-depth-for-error-message.patch
new file mode 100644
index 0000000..4b5baee
--- /dev/null
+++ b/backport-Reset-recursion-depth-for-error-message.patch
@@ -0,0 +1,81 @@
+From ef87d2503498f65577b5d7af07cd453d622fe02c Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Thu, 18 Jul 2024 13:04:28 +0200
+Subject: [PATCH] Reset recursion depth for error message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Conflict:adapt context
+Reference:https://github.com/rpm-software-management/rpm/commit/ef87d2503498f65577b5d7af07cd453d622fe02c
+
+$ rpm --define 'aaa %[%aaa]' --eval '%aaa'
+
+let to a core dump due to a stack overflow. This was cause by the
+generation of the error message failing due to being too deep in the
+recursion of the macro expansion - creating more error messages.
+
+Resetting the depth counter allows rendering the error message. As we are
+failing and breaking off the parse run this is fine to do.
+
+Thanks to Miro Hrončok for reporting
+
+Resolves: #3197
+---
+ rpmio/macro.c | 4 +++-
+ tests/rpmmacro.at | 22 ++++++++++++++++++++++
+ 2 files changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/rpmio/macro.c b/rpmio/macro.c
+index b2fb1326d..3f34f718e 100644
+--- a/rpmio/macro.c
++++ b/rpmio/macro.c
+@@ -447,9 +447,11 @@ static int mbInit(rpmMacroBuf mb, MacroExpansionData *med, size_t slen)
+ if (mb->buf == NULL)
+ mbAllocBuf(mb, slen);
+ if (++mb->depth > max_macro_depth) {
++ mb->depth--;
++ /* ensure error message can be rendered */
++ mb->mc->depth = 0;
+ mbErr(mb, 1,
+ _("Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration.\n"));
+- mb->depth--;
+ return -1;
+ }
+ med->tpos = mb->tpos; /* save expansion pointer for printExpand */
+diff --git a/tests/rpmmacro.at b/tests/rpmmacro.at
+index 372cfa3ed..3adf48b61 100644
+--- a/tests/rpmmacro.at
++++ b/tests/rpmmacro.at
+@@ -133,6 +133,28 @@ runroot rpm --define "this that" --define "that_that foo" --eval '%{expand:%{%{t
+ ])
+ RPMTEST_CLEANUP
+
++AT_SETUP([recursive macro])
++AT_KEYWORDS([macros])
++RPMTEST_CHECK([
++runroot rpm --define 'aaa %aaa' --eval '%aaa'
++],
++[1],
++[],
++[error: Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration.
++])
++RPMTEST_CLEANUP
++
++AT_SETUP([recursive expression])
++AT_KEYWORDS([macros])
++RPMTEST_CHECK([
++runroot rpm --define 'aaa %\\[%aaa\\]' --eval '%aaa'
++],
++[1],
++[],
++[error: Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration.
++])
++RPMTEST_CLEANUP
++
+ AT_SETUP([parametrized macro 1])
+ AT_KEYWORDS([macros])
+ RPMTEST_CHECK([
+--
+2.33.0
+
diff --git a/backport-Tip-toe-around-rpmfiFN-thin-ice-in-fsm.patch b/backport-Tip-toe-around-rpmfiFN-thin-ice-in-fsm.patch
new file mode 100644
index 0000000..af38276
--- /dev/null
+++ b/backport-Tip-toe-around-rpmfiFN-thin-ice-in-fsm.patch
@@ -0,0 +1,38 @@
+From 7bf818c8344ecbf0e14a26e6393582ae79df864e Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Tue, 30 Jan 2024 15:04:03 +0200
+Subject: [PATCH] Tip-toe around rpmfiFN() thin ice in fsm
+
+Any pointer gotten from rpmfiFN() is only valid until the next
+rpmfiFN() call, and here the path can end up inside plugins which
+may have their own reasons for calling rpmfiFN(). At which point
+the dest we passed would be invalid. strdup() it to appease ASAN,
+but this needs a saner solution really.
+---
+ lib/fsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/fsm.c b/lib/fsm.c
+index a54e43bae..36708acc3 100644
+--- a/lib/fsm.c
++++ b/lib/fsm.c
+@@ -736,7 +736,7 @@ static int fsmSetmeta(int fd, int dirfd, const char *path,
+ int nofcaps)
+ {
+ int rc = 0;
+- const char *dest = rpmfiFN(fi);
++ char *dest = xstrdup(rpmfiFN(fi));
+
+ if (!rc && !getuid()) {
+ rc = fsmChown(fd, dirfd, path, st->st_mode, st->st_uid, st->st_gid);
+@@ -756,6 +756,7 @@ static int fsmSetmeta(int fd, int dirfd, const char *path,
+ fd, path, dest,
+ st->st_mode, action);
+ }
++ free(dest);
+
+ return rc;
+ }
+--
+2.33.0
+
diff --git a/backport-Use-proper-type-for-copyTagsFromMainDebug.patch b/backport-Use-proper-type-for-copyTagsFromMainDebug.patch
new file mode 100644
index 0000000..441920a
--- /dev/null
+++ b/backport-Use-proper-type-for-copyTagsFromMainDebug.patch
@@ -0,0 +1,30 @@
+From 42694806bf73b07514554233d0d58d17a58cd863 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 9 Feb 2023 13:05:24 +0200
+Subject: [PATCH] Use proper type for copyTagsFromMainDebug
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/42694806bf73b07514554233d0d58d17a58cd863
+
+The array contains a non-enum value (0), this is why headerCopyTags()
+uses rpmTagVal pointer, not rpmTag.
+---
+ build/files.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/build/files.c b/build/files.c
+index 666c66651..24b4d80bf 100644
+--- a/build/files.c
++++ b/build/files.c
+@@ -2858,7 +2858,7 @@ exit:
+ return rc;
+ }
+
+-static rpmTag copyTagsFromMainDebug[] = {
++static rpmTagVal copyTagsFromMainDebug[] = {
+ RPMTAG_ARCH,
+ RPMTAG_SUMMARY,
+ RPMTAG_DESCRIPTION,
+--
+2.33.0
+
diff --git a/backport-Use-the-internal-DB_CTRL-enum-for-intenal-uses-consi.patch b/backport-Use-the-internal-DB_CTRL-enum-for-intenal-uses-consi.patch
new file mode 100644
index 0000000..64e7b6a
--- /dev/null
+++ b/backport-Use-the-internal-DB_CTRL-enum-for-intenal-uses-consi.patch
@@ -0,0 +1,28 @@
+From 1d6987a8ede061db611ff02eda62315e0ae24d2b Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Mon, 18 Mar 2024 10:02:52 +0200
+Subject: [PATCH] Use the internal DB_CTRL* enum for intenal uses consistently
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/1d6987a8ede061db611ff02eda62315e0ae24d2b
+
+---
+ lib/rpmdb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/rpmdb.c b/lib/rpmdb.c
+index 2f0d72afd..4ad12230b 100644
+--- a/lib/rpmdb.c
++++ b/lib/rpmdb.c
+@@ -69,7 +69,7 @@ static int buildIndexes(rpmdb db)
+
+ dbSetFSync(db, 0);
+
+- dbCtrl(db, RPMDB_CTRL_LOCK_RW);
++ dbCtrl(db, DB_CTRL_LOCK_RW);
+
+ mi = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0);
+ while ((h = rpmdbNextIterator(mi))) {
+--
+2.33.0
+
diff --git a/backport-Use-unsigned-integers-for-buildtime-too-for-Y2K38-sa.patch b/backport-Use-unsigned-integers-for-buildtime-too-for-Y2K38-sa.patch
new file mode 100644
index 0000000..6d249be
--- /dev/null
+++ b/backport-Use-unsigned-integers-for-buildtime-too-for-Y2K38-sa.patch
@@ -0,0 +1,32 @@
+From 97aa64d8281974fb369c66d5aef8650515b89c52 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Wed, 24 Jan 2024 12:03:39 +0200
+Subject: [PATCH] Use unsigned integers for buildtime too for Y2K38 safety
+
+This little patch buys us 68 extra years to move to 64bit time tags
+in rpm. That seems achievable.
+
+Fixes: #1228
+---
+ build/build.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/build/build.c b/build/build.c
+index e4081c673..0ac8bf6c9 100644
+--- a/build/build.c
++++ b/build/build.c
+@@ -36,9 +36,9 @@ static rpm_time_t getBuildTime(void)
+ if (srcdate == endptr || *endptr || errno != 0)
+ rpmlog(RPMLOG_ERR, _("unable to parse SOURCE_DATE_EPOCH\n"));
+ else
+- buildTime = (int32_t) epoch;
++ buildTime = (uint32_t) epoch;
+ } else
+- buildTime = (int32_t) time(NULL);
++ buildTime = (uint32_t) time(NULL);
+
+ return buildTime;
+ }
+--
+2.33.0
+
diff --git a/backport-Use-unsigned-integers-more-consistently-in-the-handl.patch b/backport-Use-unsigned-integers-more-consistently-in-the-handl.patch
new file mode 100644
index 0000000..4127e88
--- /dev/null
+++ b/backport-Use-unsigned-integers-more-consistently-in-the-handl.patch
@@ -0,0 +1,66 @@
+From 8e6108a5964c7289f3db70f3d188293276416528 Mon Sep 17 00:00:00 2001
+From: Daniel Alley <dalley@redhat.com>
+Date: Thu, 8 Dec 2022 09:40:00 -0500
+Subject: [PATCH] Use unsigned integers more consistently in the handling of
+ tag data
+
+Conflict:NA
+Reference:https://github.com/rpm-software-management/rpm/commit/8e6108a5964c7289f3db70f3d188293276416528
+
+Not a functional change, it just makes the code more clear and
+self-consistent.
+---
+ lib/header.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/lib/header.c b/lib/header.c
+index 004102dd2..72fb3d4fe 100644
+--- a/lib/header.c
++++ b/lib/header.c
+@@ -568,7 +568,7 @@ static int regionSwab(indexEntry entry, int il, int dl,
+ }
+ } break;
+ case RPM_INT32_TYPE:
+- { int32_t * it = ie.data;
++ { uint32_t * it = ie.data;
+ for (; ie.info.count > 0; ie.info.count--, it += 1) {
+ if (dataEnd && ((unsigned char *)it) >= dataEnd)
+ return -1;
+@@ -576,7 +576,7 @@ static int regionSwab(indexEntry entry, int il, int dl,
+ }
+ } break;
+ case RPM_INT16_TYPE:
+- { int16_t * it = ie.data;
++ { uint16_t * it = ie.data;
+ for (; ie.info.count > 0; ie.info.count--, it += 1) {
+ if (dataEnd && ((unsigned char *)it) >= dataEnd)
+ return -1;
+@@ -772,9 +772,9 @@ static void * doExport(const struct indexEntry_s *hindex, int indexUsed,
+ count = entry->info.count;
+ src = entry->data;
+ while (count--) {
+- *((int32_t *)te) = htonl(*((int32_t *)src));
+- te += sizeof(int32_t);
+- src += sizeof(int32_t);
++ *((uint32_t *)te) = htonl(*((uint32_t *)src));
++ te += sizeof(uint32_t);
++ src += sizeof(uint32_t);
+ }
+ break;
+
+@@ -782,9 +782,9 @@ static void * doExport(const struct indexEntry_s *hindex, int indexUsed,
+ count = entry->info.count;
+ src = entry->data;
+ while (count--) {
+- *((int16_t *)te) = htons(*((int16_t *)src));
+- te += sizeof(int16_t);
+- src += sizeof(int16_t);
++ *((uint16_t *)te) = htons(*((uint16_t *)src));
++ te += sizeof(uint16_t);
++ src += sizeof(uint16_t);
+ }
+ break;
+
+--
+2.33.0
+
diff --git a/backport-revert-Permit-building-rpm-from-git-without-pandoc.patch b/backport-revert-Permit-building-rpm-from-git-without-pandoc.patch
new file mode 100644
index 0000000..9874031
--- /dev/null
+++ b/backport-revert-Permit-building-rpm-from-git-without-pandoc.patch
@@ -0,0 +1,32 @@
+From 9841eed905b9433dc5d89583d34e4590842aa582 Mon Sep 17 00:00:00 2001
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Wed, 5 Oct 2022 09:21:09 +0300
+Subject: [PATCH] Permit building rpm from git without pandoc
+
+Pandoc is only required for converting .md to man pages, which is not
+terribly interesting unless you're creating a dist tarball. We already
+have an automake conditional for pandoc, might as well use it.
+"make dist" will still fail without pandoc, but that's exactly how we
+want it.
+
+(cherry picked from commit 1b8f7a182fe917ed5af5086d715cae529540a4d3)
+---
+ docs/Makefile.am | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/docs/Makefile.am b/docs/Makefile.am
+index 89b92e3..a93b669 100644
+--- a/docs/Makefile.am
++++ b/docs/Makefile.am
+@@ -1,8 +1,6 @@
+ ## Process this file with automake to produce Makefile.in
+
+-if PANDOC
+ SUBDIRS = man
+-endif
+
+ EXTRA_DIST =
+
+--
+2.27.0
+
diff --git a/bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch b/bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch
new file mode 100644
index 0000000..ae68b6d
--- /dev/null
+++ b/bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch
@@ -0,0 +1,83 @@
+diff -Nur rpm-4.14.2.old/installplatform rpm-4.14.2/installplatform
+--- rpm-4.14.2.old/installplatform 2017-08-10 16:08:07.113108701 +0800
++++ rpm-4.14.2/installplatform 2019-01-30 17:28:25.511000000 +0800
+@@ -186,6 +186,13 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do
+ CANONARCH=loongarch64
+ CANONCOLOR=3
+ ;;
++ aarch64_ilp32)
++ ISANAME=aarch
++ ISABITS=32
++ CANONARCH=aarch64
++ CANONCOLOR=0
++ LIB=libilp32
++ ;;
+ noarch)
+ CANONARCH=noarch
+ CANONCOLOR=0
+diff --git a/rpmrc.in b/rpmrc.in
+index 2975a3a..6861b0a 100644
+--- a/rpmrc.in
++++ b/rpmrc.in
+@@ -101,7 +101,7 @@ optflags: sh4 -O2 -g -mieee
+ optflags: sh4a -O2 -g -mieee
+
+ optflags: aarch64 -O2 -g
+-
++optflags: aarch64_ilp32 -O2 -g -mabi=ilp32
+ optflags: riscv64 -O2 -g
+
+ optflags: loongarch64 -O2 -g
+@@ -154,7 +154,7 @@ archcolor: sh3 1
+ archcolor: sh4 1
+
+ archcolor: aarch64 2
+-
++archcolor: aarch64_ilp32 1
+ archcolor: riscv64 2
+
+
+@@ -253,7 +253,7 @@ arch_canon: sh4: sh4 17
+ arch_canon: sh4a: sh4a 17
+ arch_canon: xtensa: xtensa 18
+ arch_canon: aarch64: aarch64 19
+-
++arch_canon: aarch64_ilp32: aarch64 19
+ arch_canon: mipsr6: mipsr6 20
+ arch_canon: mipsr6el: mipsr6el 20
+ arch_canon: mips64r6: mips64r6 21
+@@ -391,13 +391,13 @@ buildarchtranslate: sh4: sh4
+ buildarchtranslate: sh4a: sh4
+
+ buildarchtranslate: aarch64: aarch64
+-
++buildarchtranslate: aarch64_ilp32: aarch64_ilp32
+ buildarchtranslate: riscv: riscv64
+ buildarchtranslate: riscv64: riscv64
+
+ buildarchtranslate: loongarch64: loongarch64
+
+-#############################################################
++#########################################/####################
+ # Architecture compatibility
+
+ arch_compat: alphaev67: alphaev6
+@@ -503,7 +503,8 @@ arch_compat: sh3: noarch
+ arch_compat: sh4: noarch
+ arch_compat: sh4a: sh4
+
+-arch_compat: aarch64: noarch
++arch_compat: aarch64_ilp32: aarch64 noarch
++arch_compat: aarch64: aarch64_ilp32 noarch
+
+ arch_compat: riscv: noarch
+ arch_compat: riscv64: noarch
+@@ -542,7 +543,7 @@ arch_compat: loongarch64: noarch
+ buildarch_compat: ia64: noarch
+
+ buildarch_compat: aarch64: noarch
+-
++buildarch_compat: aarch64_ilp32: noarch
+ buildarch_compat: riscv: noarch
+ buildarch_compat: riscv64: noarch
+
diff --git a/bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch b/bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch
new file mode 100644
index 0000000..2379331
--- /dev/null
+++ b/bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch
@@ -0,0 +1,35 @@
+From c6699a7e90acfaa421830ce0fc12940335e40d7b Mon Sep 17 00:00:00 2001
+From: shanshishi <shanshishi@huawei.com>
+Date: Sun, 19 May 2019 16:49:45 +0800
+Subject: [PATCH] rpm: wait once get rpmlock fail
+
+reason: When executing the rpm command concurrently, it will block some
+times, because of lock is applied before.
+
+Signed-off-by: shanshishi <shanshishi@huawei.com>
+---
+ lib/rpmlock.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/lib/rpmlock.c b/lib/rpmlock.c
+index d693c4b..86e07b3 100644
+--- a/lib/rpmlock.c
++++ b/lib/rpmlock.c
+@@ -125,13 +125,10 @@ rpmlock rpmlockNew(const char *lock_path, const char *descr)
+ int rpmlockAcquire(rpmlock lock)
+ {
+ int locked = 0; /* assume failure */
+- int myerrno = errno;
+- int maywait = isatty(STDIN_FILENO); /* dont wait within scriptlets */
+- errno = myerrno;
+
+ if (lock) {
+ locked = rpmlock_acquire(lock, RPMLOCK_WRITE);
+- if (!locked && (lock->openmode & RPMLOCK_WRITE) && maywait) {
++ if (!locked && (lock->openmode & RPMLOCK_WRITE)) {
+ rpmlog(RPMLOG_WARNING, _("waiting for %s lock on %s\n"),
+ lock->descr, lock->path);
+ locked = rpmlock_acquire(lock, (RPMLOCK_WRITE|RPMLOCK_WAIT));
+--
+1.7.12.4
+
diff --git a/get-in-use-of-ndb.patch b/get-in-use-of-ndb.patch
new file mode 100644
index 0000000..500e40b
--- /dev/null
+++ b/get-in-use-of-ndb.patch
@@ -0,0 +1,42 @@
+From 8ba0780a26429bbb474e23112627ebbaeb9abfee Mon Sep 17 00:00:00 2001
+From: renmingshuai <renmingshuai@huawei.com>
+Date: Mon, 29 Nov 2021 10:53:24 +0800
+Subject: [PATCH] get in use of ndb
+
+---
+ configure.ac | 4 ++--
+ macros.in | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 6b161dc..ab1c667 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -490,9 +490,9 @@ 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@:>@)],
+- [build with sqlite rpm database format support (default=yes)])],
++ [build with sqlite rpm database format support (default=auto)])],
+ [enable_sqlite="$enableval"],
+- [enable_sqlite=yes])
++ [enable_sqlite=auto])
+
+ AS_IF([test "x$enable_sqlite" != "xno"], [
+ PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.22.0], [have_sqlite=yes], [have_sqlite=no])
+diff --git a/macros.in b/macros.in
+index 22f675c..3e81918 100644
+--- a/macros.in
++++ b/macros.in
+@@ -602,7 +602,7 @@ package or when debugging this package.\
+ # sqlite Sqlite database
+ # dummy dummy backend (no actual functionality)
+ #
+-%_db_backend @DB_BACKEND@
++%_db_backend ndb
+
+ #==============================================================================
+ # ---- GPG/PGP/PGP5 signature macros.
+--
+1.8.3.1
+
diff --git a/revert-always-execute-file-trigger-scriptlet-callbac.patch b/revert-always-execute-file-trigger-scriptlet-callbac.patch
new file mode 100644
index 0000000..c8fd59c
--- /dev/null
+++ b/revert-always-execute-file-trigger-scriptlet-callbac.patch
@@ -0,0 +1,26 @@
+From 9680c3f2f8ceeddced6e91048daeb9b93abf4c8d Mon Sep 17 00:00:00 2001
+From: openEuler Buildteam <buildteam@openeuler.org>
+Date: Wed, 25 Mar 2020 16:57:29 +0800
+Subject: [PATCH] revert always execute file trigger scriptlet callbacks with
+ owning header
+
+---
+ lib/rpmtriggers.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
+index 285b2f0..b7c76e7 100644
+--- a/lib/rpmtriggers.c
++++ b/lib/rpmtriggers.c
+@@ -437,7 +437,7 @@ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h,
+ inputFunc = (char *(*)(void *)) matchFilesNext;
+ rpmScriptSetNextFileFunc(script, inputFunc, mfi);
+
+- nerrors += runScript(ts, NULL, h, installPrefixes.data,
++ nerrors += runScript(ts, te, h, installPrefixes.data,
+ script, 0, -1);
+ rpmtdFreeData(&installPrefixes);
+ rpmScriptFree(script);
+--
+1.8.3.1
+
diff --git a/rpm-4.12.0-rpm2cpio-hack.patch b/rpm-4.12.0-rpm2cpio-hack.patch
new file mode 100644
index 0000000..206781c
--- /dev/null
+++ b/rpm-4.12.0-rpm2cpio-hack.patch
@@ -0,0 +1,18 @@
+diff --git a/rpm2cpio.c b/rpm2cpio.c
+index 940d6ce..d34e899 100644
+--- a/rpm2cpio.c
++++ b/rpm2cpio.c
+@@ -94,7 +94,12 @@ int main(int argc, char *argv[])
+ exit(EXIT_FAILURE);
+ }
+
+- rc = (ufdCopy(gzdi, fdo) == payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
++ /*
++ * XXX HACK for #1142949: should be equality test, but archive size
++ * short by cpio trailer size in packages built with rpm 4.12.0
++ * and its pre-releases.
++ */
++ rc = (ufdCopy(gzdi, fdo) >= payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
+
+ headerFree(h);
+ Fclose(fdo);
diff --git a/rpm-Add-sw64-architecture.patch b/rpm-Add-sw64-architecture.patch
new file mode 100644
index 0000000..e4e9fb0
--- /dev/null
+++ b/rpm-Add-sw64-architecture.patch
@@ -0,0 +1,172 @@
+From 3c8ac8643a0d7c3c3ce972c0a0685d9d1c9de9bc Mon Sep 17 00:00:00 2001
+From: wzx <wuzx1226@qq.com>
+Date: Thu, 27 Oct 2022 11:27:23 +0800
+Subject: [PATCH] Add sw64 architecture
+
+Add sw64 architecture in file config.guess config.sub installplatform lib/rpmrc.c macros.in rpmrc.in and tools/elfdeps.c to support sw64 architecture.
+
+Signed-off-by: wzx <wuzx1226@qq.com>
+---
+ build-aux/config.guess | 8 ++++++++
+ build-aux/config.sub | 1 +
+ installplatform | 6 ++++++
+ lib/rpmrc.c | 7 +++++++
+ macros.in | 1 +
+ rpmrc.in | 15 +++++++++++++++
+ tools/elfdeps.c | 1 +
+ 7 files changed, 39 insertions(+)
+
+diff --git a/build-aux/config.guess b/build-aux/config.guess
+index c7f17e8..b67d636 100755
+--- a/build-aux/config.guess
++++ b/build-aux/config.guess
+@@ -976,6 +976,14 @@ EOF
+ UNAME_MACHINE=aarch64_be
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
++ 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 2>/dev/null` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+diff --git a/build-aux/config.sub b/build-aux/config.sub
+index b51fb8c..84a8688 100755
+--- a/build-aux/config.sub
++++ b/build-aux/config.sub
+@@ -1155,6 +1155,7 @@ case $cpu-$vendor in
+ case $cpu in
+ 1750a | 580 \
+ | a29k \
++ | sw_64 \
+ | aarch64 | aarch64_be \
+ | abacus \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+diff --git a/installplatform b/installplatform
+index ca490e0..2700199 100755
+--- a/installplatform
++++ b/installplatform
+@@ -108,6 +108,12 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do
+ CANONARCH=arm
+ CANONCOLOR=0
+ ;;
++ sw_64*)
++ ISANAME=sw_64
++ ISABITS=64
++ CANONARCH=sw_64
++ CANONCOLOR=0
++ ;;
+ alpha*)
+ ISANAME=alpha
+ ISABITS=64
+diff --git a/lib/rpmrc.c b/lib/rpmrc.c
+index 120777c..5d9507d 100644
+--- a/lib/rpmrc.c
++++ b/lib/rpmrc.c
+@@ -1268,6 +1268,13 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os)
+ }
+ # endif
+
++# if defined(__GNUC__) && defined(__sw_64__)
++ {
++ strcpy(un.machine, "sw_64sw6b");
++ }
++# endif
++
++
+ # if defined(__linux__) && defined(__i386__)
+ {
+ char mclass = (char) (RPMClass() | '0');
+diff --git a/macros.in b/macros.in
+index 4dbf5b6..6722a74 100644
+--- a/macros.in
++++ b/macros.in
+@@ -1107,6 +1107,7 @@ package or when debugging this package.\
+ #------------------------------------------------------------------------------
+ # arch macro for all supported Alpha processors
+ %alpha alpha alphaev56 alphaev6 alphaev67
++%sw_64 sw_64 sw_64sw6b
+
+ #------------------------------------------------------------------------------
+ # arch macro for all supported PowerPC 64 processors
+diff --git a/rpmrc.in b/rpmrc.in
+index 3a48af4..8d70f91 100644
+--- a/rpmrc.in
++++ b/rpmrc.in
+@@ -25,6 +25,9 @@ optflags: x86_64 -O2 -g
+ 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
+@@ -112,6 +115,7 @@ optflags: riscv64 -O2 -g
+ archcolor: noarch 0
+ archcolor: i386 1
+ archcolor: alpha 2
++archcolor: sw_64 2
+ archcolor: sparc 1
+ archcolor: sparc64 2
+ archcolor: sparcv9 2
+@@ -176,6 +180,9 @@ arch_canon: amd64: amd64 1
+ 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
+@@ -315,6 +322,9 @@ buildarchtranslate: i586: i386
+ 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
+@@ -401,6 +411,8 @@ buildarchtranslate: riscv64: riscv64
+
+ #########################################/####################
+ # Architecture compatibility
++arch_compat: sw_64sw6b: sw_64
++arch_compat: sw_64: axp noarch
+
+ arch_compat: alphaev67: alphaev6
+ arch_compat: alphaev6: alphapca56
+@@ -570,6 +582,9 @@ buildarch_compat: sparcv9: sparcv8
+ buildarch_compat: sparcv8: sparc
+ buildarch_compat: sparc: noarch
+
++buildarch_compat: sw_64sw6b: sw_64
++buildarch_compat: sw_64: noarch
++
+ buildarch_compat: alphaev67: alphaev6
+ buildarch_compat: alphaev6: alphapca56
+ buildarch_compat: alphapca56: alphaev56
+diff --git a/tools/elfdeps.c b/tools/elfdeps.c
+index d205935..590021b 100644
+--- a/tools/elfdeps.c
++++ b/tools/elfdeps.c
+@@ -85,6 +85,7 @@ static const char *mkmarker(GElf_Ehdr *ehdr)
+ 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;
+--
+2.33.0
+
diff --git a/rpm.spec b/rpm.spec
new file mode 100644
index 0000000..5fa5746
--- /dev/null
+++ b/rpm.spec
@@ -0,0 +1,730 @@
+Name: rpm
+Version: 4.18.2
+Release: 16
+Summary: RPM Package Manager
+License: GPLv2+
+URL: http://www.rpm.org/
+Source0: http://ftp.rpm.org/releases/rpm-4.18.x/%{name}-%{version}.tar.bz2
+
+Patch1: Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch
+Patch2: rpm-4.12.0-rpm2cpio-hack.patch
+Patch3: add-dist-to-release-by-default.patch
+Patch4: revert-always-execute-file-trigger-scriptlet-callbac.patch
+Patch5: bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch
+Patch6: bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch
+Patch7: get-in-use-of-ndb.patch
+Patch8: still-in-use-of-python-scripts-from-old-version.patch
+Patch9: Add-loongarch-architecture-support.patch
+Patch10: rpm-Add-sw64-architecture.patch
+Patch11: add-default-machine-name-to-support-loongarch.patch
+Patch12: 8fc4e71f9b51438f09c8206ceb1b407bbaca8aab.patch
+
+Patch6000: backport-revert-Permit-building-rpm-from-git-without-pandoc.patch
+Patch6001: backport-Check-inside-root-when-querying-for-files.patch
+Patch6002: backport-Use-unsigned-integers-for-buildtime-too-for-Y2K38-sa.patch
+Patch6003: backport-Fix-a-theoretical-use-of-uninitialized-struct-member.patch
+Patch6004: backport-Fix-spec-parser-leaks-from-trans-f-file.patch
+Patch6005: backport-Tip-toe-around-rpmfiFN-thin-ice-in-fsm.patch
+Patch6006: backport-Fix-a-memleak-on-invalid-command-line-options.patch
+Patch6007: backport-Let-eBPF-ELF-files-be-packaged-in-noarch-packages.patch
+Patch6008: backport-Fix-some-int-enum-confusion-in-the-build-code.patch
+Patch6009: backport-Use-the-internal-DB_CTRL-enum-for-intenal-uses-consi.patch
+Patch6010: backport-An-enumeration-is-not-a-bitfield-use-an-integer-inst.patch
+Patch6011: backport-Fix-an-enum-int-type-mismatch-in-rpmfiArchiveReadToF.patch
+Patch6012: backport-Fix-an-enum-int-type-mismatch-in-transaction-verify-.patch
+Patch6013: backport-Fix-enum-type-mismatch-in-rpmTagGetValue.patch
+Patch6014: backport-Free-old-cookie-value-to-prevent-a-memory-leak.patch
+Patch6015: backport-Fix-pointer-bogosity-in-rpmlog-callback.patch
+Patch6016: backport-Fix-an-ancient-memleak-on-caps-parsing-add-tests.patch
+Patch6017: backport-Fix-potential-use-of-uninitialized-pipe-array.patch
+Patch6018: backport-Fix-potential-use-of-uninitialized-pgp-struct.patch
+Patch6019: backport-Use-unsigned-integers-more-consistently-in-the-handl.patch
+Patch6020: backport-Use-proper-type-for-copyTagsFromMainDebug.patch
+Patch6021: backport-Reset-recursion-depth-for-error-message.patch
+Patch6022: backport-Fix-division-by-zero-in-elfdeps-RhBug-2299414.patch
+Patch6023: backport-Make-sure-dirs-are-not-relocated-twice.patch
+Patch6024: backport-Fix-root-relocation-regression.patch
+Patch6025: backport-Fix-crash-on-Lua-file-trigger-exiting-with-return-ed.patch
+Patch6026: backport-Fix-V-option-usage-in-our-tests.patch
+
+Patch9000: Add-digest-list-plugin.patch
+Patch9001: Add-IMA-digest-list-support.patch
+
+BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel
+BuildRequires: zlib-devel zstd-devel >= 1.3.8 xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel
+BuildRequires: dbus-devel fakechroot elfutils-devel elfutils-libelf-devel ima-evm-utils
+BuildRequires: lua-devel libcap-devel libacl-devel libselinux-devel file-devel gettext-devel ncurses-devel
+BuildRequires: system-rpm-config dwz gnupg2 debugedit
+Requires: coreutils popt curl zstd >= 1.5.0-1 libcap crontabs logrotate
+Obsoletes: %{name}-build-libs %{name}-sign-libs %{name}-sign %{name}-cron
+Provides: %{name}-build-libs %{name}-sign-libs %{name}-sign %{name}-cron
+Obsoletes: %{name}-plugin-selinux %{name}-plugin-syslog %{name}-plugin-systemd-inhibit < 4.15.1-28 %{name}-plugin-ima %{name}-plugin-prioreset
+Provides: %{name}-plugin-selinux %{name}-plugin-syslog %{name}-plugin-ima %{name}-plugin-prioreset
+
+%description
+The RPM Package Manager (RPM) is a powerful package management system capability as below
+
+-building computer software from source into easily distributable packages
+-installing, updating and uninstalling packaged software
+-querying detailed information about the packaged software, whether installed or not
+-verifying integrity of packaged software and resulting software installation
+
+%package libs
+Summary: Shared library of rpm 4.18
+Requires: %{name} = %{version}-%{release}
+
+%description libs
+Shared library of rpm 4.18.
+
+%package build
+Summary: Scripts and executable programs used to build packages
+Requires: %{name} = %{version}-%{release}
+Requires: elfutils binutils findutils sed grep gawk diffutils file patch
+Requires: tar unzip gzip bzip2 cpio xz zstd pkgconfig system-rpm-config
+Requires: gdb-headless debugedit
+
+%description build
+This package provides scripts and executable programs that used to
+build rpm packages.
+
+%package -n python3-%{name}
+Summary: Python3 bindings for RPM user
+BuildRequires: python3-devel
+%{?python_provide:%python_provide python3-%{name}}
+Requires: %{name} = %{version}-%{release}
+Provides: %{name}-python3 = %{version}-%{release}
+Obsoletes: %{name}-python3 < %{version}-%{release}
+
+%description -n python3-%{name}
+This package contains a module that allow applications
+written with Python3 to use the interface
+supplied by RPM.
+
+%package devel
+Summary: Development files for RPM handling
+Requires: %{name} = %{version}-%{release}
+Requires: popt-devel
+
+%description devel
+%{summary}.
+
+%package plugin-systemd-inhibit
+Summary: rpm plugin to get systemd-inhibit lock
+Requires: %{name} = %{version}-%{release}
+
+%description plugin-systemd-inhibit
+This package use systemd-inhibit to block systemd from entering
+idle, sleep or shutdown while an rpm transcation is running.
+
+%package help
+Summary: Man page for %{name}
+BuildArch: noarch
+Obsoletes: apidocs
+
+%description help
+%{summary}.
+
+%prep
+%autosetup -n %{name}-%{version} -p1
+%ifnarch sw_64
+%patch10 -R -p1
+%endif
+
+%build
+CPPFLAGS="$CPPFLAGS -DLUA_COMPAT_APIINTCASTS"
+CFLAGS="$RPM_OPT_FLAGS -DLUA_COMPAT_APIINTCASTS"
+LDFLAGS="$LDFLAGS %{?__global_ldflags}"
+export CPPFLAGS CFLAGS LDFLAGS
+
+autoreconf -i -f
+
+for i in $(find . -name ltmain.sh) ; do
+ %{__sed} -i.backup -e 's~compiler_flags=$~compiler_flags="%{_hardened_ldflags}"~' $i
+done;
+
+./configure \
+ --prefix=%{_usr} \
+ --sysconfdir=%{_sysconfdir} \
+ --localstatedir=%{_var} \
+ --sharedstatedir=%{_var}/lib \
+ --libdir=%{_libdir} \
+ --build=%{_target_platform} \
+ --host=%{_target_platform} \
+ --with-vendor=%{_vendor} \
+ --with-external-db \
+ --with-lua \
+ --with-selinux \
+ --with-cap \
+ --with-acl \
+ --with-imaevm \
+ --enable-zstd \
+ --enable-python \
+ --enable-bdb-ro \
+ --enable-ndb \
+ --enable-bdb=no \
+ --enable-sqlite=no \
+ --with-crypto=openssl \
+ --with-fapolicyd=no \
+ --with-fsverity=no \
+ --enable-python
+
+%make_build
+
+%install
+%make_install
+
+mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily
+install -m 755 scripts/rpm.daily ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily/rpm
+
+# During the upgrade of the major rpm version, the dynamic library may not be compatible.
+# Therefore, ensure that no other rpm command is executed during the upgrade. A judgment
+# is added to the RPM script of the scheduled task. If the dynamic library is not the
+# dynamic library of the current version, exits directly.
+pushd ${RPM_BUILD_ROOT}%{_libdir}
+export SONAME=`ls librpm.so.*.*.*`
+popd
+sed -i "/bin\/sh/a \
+if [ ! -e %{_libdir}\/${SONAME} ]; then\n\
+ exit 0\n\
+fi" ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily/rpm
+cp ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily/rpm ${RPM_BUILD_ROOT}%{_rpmconfigdir}/rpm.daily
+
+mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d
+install -m 644 scripts/rpm.log ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/rpm
+
+install -m 755 build-aux/config.guess ${RPM_BUILD_ROOT}%{_rpmconfigdir}/
+install -m 755 build-aux/config.sub ${RPM_BUILD_ROOT}%{_rpmconfigdir}/
+
+mkdir -p ${RPM_BUILD_ROOT}/usr/lib/tmpfiles.d
+echo "r /var/lib/rpm/__db.*" > ${RPM_BUILD_ROOT}/usr/lib/tmpfiles.d/rpm.conf
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/rpm
+mkdir -p $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d
+mkdir -p $RPM_BUILD_ROOT/var/lib/rpm
+
+./rpmdb --define "_db_backend ndb" --dbpath=$(pwd)/ndb/ --initdb
+cp -va ndb/. $RPM_BUILD_ROOT/var/lib/rpm/
+
+%find_lang %{name}
+
+find $RPM_BUILD_ROOT -name "*.la"|xargs rm -f
+
+rm -f $RPM_BUILD_ROOT/%{_rpmconfigdir}/{perldeps.pl,perl.*,pythond*}
+rm -f $RPM_BUILD_ROOT/%{_fileattrsdir}/{perl*,python*}
+rm -f $RPM_BUILD_ROOT/%{_rpmconfigdir}/{tcl.req,osgideps.pl}
+rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/dbus-1/system.d/org.rpm.conf
+
+%check
+%ifnarch loongarch64
+make check || (cat tests/rpmtests.log; exit 0)
+# rpmbuild will automatically remove the build directory since b34333fa.
+# But it fails to remove some directories, see the issue #1382. We need
+# to explictly make clean it after checking.
+make clean
+%endif
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%post libs -p /sbin/ldconfig
+
+%postun libs -p /sbin/ldconfig
+
+%posttrans
+{
+ set -e
+ disable_auto_rebuilddb=$(rpm -E 0%%{?_disable_auto_rebuilddb})
+ if [ ${disable_auto_rebuilddb} -eq 0 ]; then
+ dbpath=$(rpm -E %{_dbpath})
+ while [ -e ${dbpath}/Packages ]
+ do
+ date >> /var/log/rebuilddb.log 2>&1
+ rpm -vvv --rebuilddb >> /var/log/rebuilddb.log 2>&1
+ done
+ fi
+} &
+
+%files -f %{name}.lang
+%defattr(-,root,root)
+%license COPYING
+%doc CREDITS
+/usr/lib/tmpfiles.d/rpm.conf
+%{_sysconfdir}/cron.daily/rpm
+%config(noreplace) %{_sysconfdir}/logrotate.d/rpm
+%dir %{_sysconfdir}/rpm
+%dir /var/lib/rpm
+%attr(0644, root, root) %ghost %config(missingok,noreplace) /var/lib/rpm/*
+%attr(0644, root, root) %ghost /var/lib/rpm/.*.lock
+%lang(fr) %{_mandir}/fr/man[18]/*.[18]*
+%lang(ko) %{_mandir}/ko/man[18]/*.[18]*
+%lang(ja) %{_mandir}/ja/man[18]/*.[18]*
+%lang(pl) %{_mandir}/pl/man[18]/*.[18]*
+%lang(ru) %{_mandir}/ru/man[18]/*.[18]*
+%lang(sk) %{_mandir}/sk/man[18]/*.[18]*
+
+%attr(0755, root, root) %dir %{_rpmconfigdir}
+%{_rpmconfigdir}/macros
+%{_rpmconfigdir}/macros.d
+%{_rpmconfigdir}/rpmpopt*
+%{_rpmconfigdir}/rpmrc
+%{_rpmconfigdir}/rpmdb_*
+%{_rpmconfigdir}/rpm.daily
+%{_rpmconfigdir}/rpm.log
+%{_rpmconfigdir}/rpm.supp
+%{_rpmconfigdir}/rpm2cpio.sh
+%{_rpmconfigdir}/tgpg
+%{_rpmconfigdir}/platform
+%{_libdir}/rpm-plugins/
+%exclude %{_libdir}/rpm-plugins/systemd_inhibit.so
+%exclude %{_libdir}/rpm-plugins/fsverity.so
+%exclude %{_libdir}/rpm-plugins/dbus_announce.so
+%dir %{_rpmconfigdir}/fileattrs
+%{_bindir}/rpm
+%{_bindir}/rpm2archive
+%{_bindir}/rpm2cpio
+%{_bindir}/rpmdb
+%{_bindir}/rpmkeys
+%{_bindir}/rpmquery
+%{_bindir}/rpmverify
+%{_bindir}/rpmsign
+%{_bindir}/rpmlua
+/usr/lib/rpm/rpmuncompress
+
+%files libs
+%{_libdir}/librpm*.so.9*
+
+%files build
+%defattr(-,root,root)
+%{_bindir}/rpmbuild
+%{_bindir}/gendiff
+%{_bindir}/rpmspec
+%{_mandir}/man1/gendiff.1*
+%{_mandir}/man8/rpmbuild.8.gz
+%{_mandir}/man8/rpmdeps.8.gz
+%{_mandir}/man8/rpmspec.8.gz
+
+%{_rpmconfigdir}/brp-*
+%{_rpmconfigdir}/check-*
+%{_rpmconfigdir}/find-lang.sh
+%{_rpmconfigdir}/*provides*
+%{_rpmconfigdir}/*requires*
+%{_rpmconfigdir}/*deps*
+%{_rpmconfigdir}/*.prov
+%{_rpmconfigdir}/*.req
+%{_rpmconfigdir}/mkinstalldirs
+%{_rpmconfigdir}/fileattrs/*
+%{_rpmconfigdir}/config.*
+
+%files -n python3-%{name}
+%defattr(-,root,root)
+%{python3_sitearch}/%{name}/
+%{python3_sitearch}/%{name}-%{version}*.egg-info
+
+%files devel
+%defattr(-,root,root)
+%{_bindir}/rpmgraph
+%{_libdir}/librp*[a-z].so
+%{_libdir}/pkgconfig/%{name}.pc
+%{_includedir}/%{name}/
+
+%files plugin-systemd-inhibit
+%{_libdir}/rpm-plugins/systemd_inhibit.so
+%{_mandir}/man8/rpm-plugin-systemd-inhibit.8*
+
+%files help
+%defattr(-,root,root)
+%doc docs/manual/[a-z]*
+%doc docs/librpm/html/*
+%{_mandir}/man8/rpm*.8*
+%exclude %{_mandir}/man8/rpm-plugin-systemd-inhibit.8*
+%exclude %{_mandir}/man8/rpm-plugin-dbus-announce.8*
+%exclude %{_mandir}/man8/rpmbuild.8.gz
+%exclude %{_mandir}/man8/rpmdeps.8.gz
+%exclude %{_mandir}/man8/rpmspec.8.gz
+
+%changelog
+* Wed Sep 11 2024 luhuaxin <luhuaxin1@huawei.com> - 4.18.2-15
+- Fix the log level of IMA digest_list
+
+* Wed Sep 4 2024 gengqihu<gengqihu2@h-partners.com> - 4.18.2-14
+- Backport some patches from upstream
+
+* Tue Sep 3 2024 gengqihu<gengqihu2@h-partners.com> - 4.18.2-13
+- Backport some patches from upstream
+
+* Thu Aug 22 2024 luhuaxin <luhuaxin1@huawei.com> - 4.18.2-12
+- Fix the calculation of hdr size
+
+* Tue Aug 20 2024 luhuaxin <luhuaxin1@huawei.com> - 4.18.2-11
+- Fix the wrong IMA signature header check
+
+* Mon Aug 19 2024 luhuaxin <luhuaxin1@huawei.com> - 4.18.2-10
+- Fix the judgement of digests count
+
+* Fri Aug 16 2024 luhuaxin <luhuaxin1@huawei.com> - 4.18.2-9
+- IMA digest list plugin support signature within IMA header
+
+* Wed Jul 24 2024 gengqihu<gengqihu2@h-partners.com> - 4.18.2-8
+- Backport some patches from upstream
+
+* Tue Jul 23 2024 zhangxingrong<zhangxingrong@uniontech.cn> - 4.18.2-7
+- Free old cookie value to prevent a memory leak
+
+* Mon Jun 3 2024 gengqihu<gengqihu2@h-partners.com> - 4.18.2-6
+- Backport some patches from upstream
+
+* Mon Mar 25 2024 hongjinghao<hongjinghao@huawei.com> - 4.18.2-5
+- Fix memleak and let eBPF ELF files be packaged in noarch packages
+
+* Thu Mar 21 2024 zhangguangzhi<zhangguangzhi3@huawei.com> - 4.18.2-4
+- ima digest list support modsig
+
+* Thu Mar 14 2024 gengqihu<gengqihu2@h-partners.com> - 4.18.2-3
+- Backport some patches from upstream
+
+* Wed Feb 21 2024 gengqihu<gengqihu2@h-partners.com> - 4.18.2-2
+- Modify the version of zstd in Requires
+
+* Sat Jan 27 2024 xujing<xujing125@huawei.com> - 4.18.2-1
+- update version to 4.18.2 (https://rpm.org/wiki/Releases/4.18.2)
+
+* Tue Sep 26 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-9
+- Fix potential segmentation fault
+
+* Fri Sep 08 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-8
+- support _disable_auto_rebuilddb macro in posttrans
+
+* Wed Sep 06 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-7
+- Fix a copy-paste error in --help
+
+* Tue Sep 05 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-6
+- Fix the coredump which may occur during upgrading of rpm
+
+* Tue Sep 5 2023 hongjinghao<hongjinghao@huawei.com> - 4.18.1-5
+- Fix a segfault on a non-stringable argument to macro call from Lua
+
+* Tue Aug 29 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-4
+- Check inside --root when querying for files
+
+* Wed Aug 02 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-3
+- backport some patches from upstream
+
+* Fri Jul 21 2023 xujing<xujing125@huawei.com> - 4.18.1-2
+- fix Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch is incorrectly adapted
+
+* Tue Jun 20 2023 renhongxun<renhongxun@h-partners.com> - 4.18.1-1
+- upgrade version to 4.18.1
+
+* Wed Jun 21 2023 renhongxun<renhongxun@h-partners.com> - 4.18.0-11
+- Fix per-file plugin hook regression introduced in 4.18
+
+* Mon Jun 19 2023 renhongxun<renhongxun@h-partners.com> - 4.18.0-10
+- Fix a segfault on a non-stringable argument to macro call from Lua
+
+* Fri Jun 16 2023 zhoushuiqing<zhoushuiqing2@huawei.com> - 4.18.0-9
+* Add digest list plugin support
+
+* Wed Jun 14 2023 renhongxun<renhongxun@h-partners.com> - 4.18.0-8
+* Fix a copy-paste --help description of --whatconflicts
+
+* Tue Feb 28 2023 renhongxun<renhongxun@h-partners.com> - 4.18.0-7
+- bugfix with upstream patches about fifo
+
+* Wed Feb 08 2023 gaoyusong<gaoyusong2@huawei.com> - 4.18.0-6
+- Revert digest list patches
+
+* Wed Feb 08 2023 gaoyusong<gaoyusong2@huawei.com> - 4.18.0-5
+- Sync IMA related patches
+
+* Wed Feb 08 2023 gaoyusong<gaoyusong2@huawei.com> - 4.18.0-4
+- Add digest list plugin support
+
+* Mon Feb 06 2023 xujing<xujing125@huawei.com> - 4.18.0-3
+- make clean after check to adapt rpm upstream logic
+
+* Mon Feb 06 2023 xujing<xujing125@huawei.com> - 4.18.0-2
+- don't automatically execute rmbuild
+
+* Thu Feb 02 2023 xujing<xujing125@huawei.com> - 4.18.0-1
+- update version to 4.18.0
+
+* Mon Dec 26 2022 xujing<xujing125@huawei.com> - 4.17.0-21
+- backport patches from upstream to fix resource leak
+
+* Mon Dec 19 2022 xujing<xujing125@huawei.com> - 4.17.0-20
+- Fix file leak when src rpm in URL format is used for installation
+
+* Mon Dec 19 2022 xujing<xujing125@huawei.com> - 4.17.0-19
+- backport patches from upstream to fix memleak
+
+* Mon Nov 28 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-18
+- Move file metadata setting back to unpack stage
+
+* Fri Nov 18 2022 huajingyun<huajingyun@loongson.cn> - 4.17.0-17
+- add default machine name loongarch support
+- disable test on loongarch
+
+* Wed Nov 16 2022 xujing<xujing125@huawei.com> - 4.17.0-16
+- rpm: fix rpm is blocked when open fifo file
+
+* Tue Nov 15 2022 yuelg<yuelg@chinaunicom.cn> - 4.17.0-15
+- Move rpm-build's help to rpm binary package
+
+* Mon Nov 14 2022 wuzx<wuzx1226@qq.com> - 4.17.0-14
+- Add sw64 architecture
+
+* Tue Nov 01 2022 licunlong<licunlong1@huawei.com> - 4.17.0-13
+- sync patches from upstream
+
+* Fri Sep 09 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-12
+- sync patches from upstream
+
+* Wed Aug 31 2022 Hongxun Ren<renhongxun@h-partners.com> - 4.17.0-11
+- fix CVE-2021-35937 CVE-2021-35938 CVE-2021-35939
+
+* Tue Aug 16 2022 Kou Wenqi<kouwenqi@kylinos.cn> - 4.17.0-10
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:requires zstd-devel >= 1.3.8 in build
+
+* Mon Aug 15 2022 Kou Wenqi<kouwenqi@kylinos.cn> - 4.17.0-9
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:requires zstd >= 1.4.0
+
+* Thu Aug 11 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-8
+- sync some patches from upstream
+
+* Thu Aug 11 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-7
+- sync some patches from upstream
+
+* Thu Aug 11 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-6
+- sync some patches from upstream
+
+* Tue Aug 09 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-5
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:sync changes from openEuler-22.03-LTS
+
+*Sat Jun 25 2022 lujie<lujie54@huawei.com> - 4.17.0-4
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:rpm selinux plugin check context file exist
+
+*Thu Feb 17 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-3
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:delete some libdb symbolic link
+
+* Wed Feb 16 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-2
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:bugfix on finding python3.x dir
+
+* Mon Dec 27 2021 renhongxun<renhongxun@huawei.com> - 4.17.0-1
+- Type:requirement
+- ID:NA
+- SUG:NA
+- DESC:upgrade to 4.17.0
+
+* Mon Sep 13 2021 zhangtianxing<zhangtianxing3@huawei.com> - 4.15.1-30
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:fix lsetxattr error in container
+
+* Thu Jul 22 2021 liudabo<liudabo1@huawei.com> - 4.15.1-29
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:deleting gdb build dependency
+
+* Thu Jul 08 2021 shixuantong <shixuantong@huawei.com> - 4.15.1-28
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:split rpm-plugin-systemd-inhibit out of rpm.
+
+* Thu Jul 08 2021 shixuantong <shixuantong@huawei.com> - 4.15.1-27
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:remove unnecessary installation dependencies
+
+* Mon Jun 28 2021 shangyibin <shangyibin1@huawei.com> - 4.15.1-26
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:modify dependency
+
+* Wed Jun 09 2021 shixuantong <shixuantong@huawei.com> - 4.15.1-25
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:Fix data race in packageBinaries() function and prioritize large packages
+
+* Wed Jun 2 2021 guoxiaoqi<guoxiaoqi2@huawei.com> - 4.15.1-23
+- Type:cve
+- ID:NA
+- SUG:NA
+- DESC:fix CVE-2021-20266
+
+* Sat May 22 2021 liudabo<liudabo1@huawei.com> - 4.15.1-22
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:Optimize signature header merge a bit
+
+* Tue Apr 13 2021 liudabo<liudabo1@huawei.com> - 4.15.1-22
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:Fix CVE-2021-20271
+
+* Mon Jan 11 2021 Liquor <lirui130@huawei.com> - 4.15.1-21
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:backport patches from upstream
+
+* Thu Dec 17 2020 Anakin Zhang <benjamin93@163.com> - 4.15.1-20
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:call process_digest_list before files are added
+
+* Thu Dec 17 2020 Anakin Zhang <benjamin93@163.com> - 4.15.1-19
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:use user.digest_list to avoid duplicate processing of the digest lists
+
+* Thu Oct 29 2020 Liquor <lirui130@huawei.com> - 4.15.1-18
+- Type:requirement
+- ID:NA
+- SUG:NA
+- DESC:remove python2
+
+* Tue Jul 14 2020 Roberto Sassu <roberto.sassu@huawei.com> - 4.15.1-17
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:add support for digest lists
+
+* Fri May 22 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-16
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:solve the error of setexecfilecon
+
+* Wed May 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-15
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:solve the failure of rpmsigdig.at test
+
+* Mon Mar 30 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-14
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add requires of some common build packages to rpm-build
+
+* Wed Mar 25 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-13
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:revert always execute file trigger scriptlet callbacks with owning header
+
+* Fri Mar 6 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-12
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:silence spurious error message from lsetfilecon()
+
+* Wed Mar 4 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-11
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add dist to release by default
+
+* Mon Mar 2 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-10
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:revert last commit
+
+* Thu Feb 27 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-9
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add dist to the name of package
+
+* Fri Feb 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-8
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:skip update the preference of gpg during make check
+
+* Mon Jan 20 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-7
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:delete unneeded obsoletes
+
+* Sat Jan 18 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-6
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:delete unneeded shared library
+
+* Tue Jan 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-5
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:change requires to build requires
+
+* Tue Jan 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-4
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add build requires of ima-evm-utils and old shared library
+
+* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-3
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add requires of shared library
+
+* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-2
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add subpack of librpm8 and librpm9 to support update
+
+* Fri Jan 10 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-1
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:update version to 4.15.1
+
+* Tue Dec 24 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.14.2-5
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:bugfix in files
+
+* Wed Nov 13 2019 hexiaowen<hexiaowen@huawei.com> - 4.14.2-4
+- add system-rpm-config buildrequires
+
+* Fri Sep 20 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.14.2-3
+- Delete redundant information
+
+* Mon Sep 09 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.14.2-2
+- Package init
diff --git a/sources b/sources
new file mode 100644
index 0000000..20d2d93
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+471f5ef532e7f41ff109994cfa959b9e rpm-4.18.2.tar.bz2
diff --git a/still-in-use-of-python-scripts-from-old-version.patch b/still-in-use-of-python-scripts-from-old-version.patch
new file mode 100644
index 0000000..50fdb6f
--- /dev/null
+++ b/still-in-use-of-python-scripts-from-old-version.patch
@@ -0,0 +1,210 @@
+From 4ec83c32024a8faf0a66a4275acbcd15751ee303 Mon Sep 17 00:00:00 2001
+From: renhongxun <renhongxun@huawei.com>
+Date: Wed, 29 Dec 2021 16:37:45 +0800
+Subject: [PATCH] still in use of python scripts from old version
+
+---
+ platform.in | 3 ++
+ scripts/Makefile.am | 8 +--
+ scripts/brp-python-bytecompile | 112 +++++++++++++++++++++++++++++++++++++++++
+ scripts/brp-python-hardlink | 25 +++++++++
+ 4 files changed, 144 insertions(+), 4 deletions(-)
+ create mode 100644 scripts/brp-python-bytecompile
+ create mode 100755 scripts/brp-python-hardlink
+
+diff --git a/platform.in b/platform.in
+index 71496b8..748186e 100644
+--- a/platform.in
++++ b/platform.in
+@@ -82,10 +82,13 @@
+ #
+
+ %__arch_install_post @ARCH_INSTALL_POST@
++%_python_bytecompile_errors_terminate_build 0
++%_python_bytecompile_extra 1
+
+ # Standard brp-macro naming:
+ # convert all '-' in basename to '_', add two leading underscores.
+ %__brp_compress %{_rpmconfigdir}/brp-compress %{?_prefix}
++%__brp_python_bytecompile %{_rpmconfigdir}/brp-python-bytecompile "" "%{?_python_bytecompile_errors_terminate_build}" "%{?_python_bytecompile_extra}"
+ %__brp_strip %{_rpmconfigdir}/brp-strip %{__strip}
+ %__brp_strip_comment_note %{_rpmconfigdir}/brp-strip-comment-note %{__strip} %{__objdump}
+ %__brp_strip_static_archive %{_rpmconfigdir}/brp-strip-static-archive %{__strip}
+diff --git a/scripts/Makefile.am b/scripts/Makefile.am
+index 4aed76b..5a1c494 100644
+--- a/scripts/Makefile.am
++++ b/scripts/Makefile.am
+@@ -6,8 +6,8 @@ AM_CFLAGS = @RPMCFLAGS@
+ CLEANFILES =
+
+ EXTRA_DIST = \
+- brp-compress \
+- brp-strip brp-strip-comment-note \
++ brp-compress brp-python-bytecompile \
++ brp-strip brp-strip-comment-note brp-python-hardlink \
+ brp-strip-static-archive brp-elfperms \
+ brp-remove-la-files \
+ check-files check-prereqs \
+@@ -23,8 +23,8 @@ EXTRA_DIST = \
+ fontconfig.prov script.req
+
+ rpmconfig_SCRIPTS = \
+- brp-compress \
+- brp-strip brp-strip-comment-note \
++ brp-compress brp-python-bytecompile \
++ brp-strip brp-strip-comment-note brp-python-hardlink \
+ brp-strip-static-archive brp-elfperms \
+ brp-remove-la-files \
+ check-files check-prereqs \
+diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile
+new file mode 100644
+index 0000000..d9c4832
+--- /dev/null
++++ b/scripts/brp-python-bytecompile
+@@ -0,0 +1,112 @@
++#!/bin/bash
++errors_terminate=$2
++extra=$3
++
++# If using normal root, avoid changing anything.
++if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then
++ exit 0
++fi
++
++# Figure out how deep we need to descend. We could pick an insanely high
++# number and hope it's enough, but somewhere, somebody's sure to run into it.
++depth=`(find "$RPM_BUILD_ROOT" -type f -name "*.py" -print0 ; echo /) | \
++ xargs -0 -n 1 dirname | sed 's,[^/],,g' | sort -u | tail -n 1 | wc -c`
++if [ -z "$depth" ] || [ "$depth" -le "1" ]; then
++ exit 0
++fi
++
++function python_bytecompile()
++{
++ local options=$1
++ local python_binary=$2
++ local exclude=$3
++ local python_libdir=$4
++ local depth=$5
++ local real_libdir=$6
++
++cat << EOF | $python_binary $options
++import compileall, sys, os, re
++
++python_libdir = "$python_libdir"
++depth = $depth
++real_libdir = "$real_libdir"
++build_root = "$RPM_BUILD_ROOT"
++exclude = r"$exclude"
++
++class Filter:
++ def search(self, path):
++ ret = not os.path.realpath(path).startswith(build_root)
++ if exclude:
++ ret = ret or re.search(exclude, path)
++ return ret
++
++sys.exit(not compileall.compile_dir(python_libdir, depth, real_libdir, force=1, rx=Filter(), quiet=1))
++EOF
++}
++
++# .pyc/.pyo files embed a "magic" value, identifying the ABI version of Python
++# bytecode that they are for.
++#
++# The files below RPM_BUILD_ROOT could be targeting multiple versions of
++# python (e.g. a single build that emits several subpackages e.g. a
++# python26-foo subpackage, a python31-foo subpackage etc)
++#
++# Support this by assuming that below each /usr/lib/python$VERSION/, all
++# .pyc/.pyo files are to be compiled for /usr/bin/python$VERSION.
++#
++# For example, below /usr/lib/python2.6/, we're targeting /usr/bin/python2.6
++# 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]$|[0-9]{2}$)"`;
++do
++ python_binary=/usr/bin/$(basename $python_libdir)
++ real_libdir=${python_libdir/$RPM_BUILD_ROOT/}
++ echo "Bytecompiling .py files below $python_libdir using $python_binary"
++
++ # Generate normal (.pyc) byte-compiled files.
++ python_bytecompile "" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir"
++ if [ $? -ne 0 ] && [ 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" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir"
++ if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then
++ # One or more of the files had a syntax error
++ exit 1
++ fi
++done
++
++
++# Handle other locations in the filesystem using the default python implementation
++# if extra is set to 0, don't do this
++if [ 0$extra -eq 0 ]; then
++ exit 0
++fi
++
++# If we don't have a default python interpreter, we cannot proceed
++default_python=${1:-/usr/bin/python}
++if [ ! -x "$default_python" ]; then
++ exit 0
++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
++
++# 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" "/"
++if [ $? -ne 0 ] && [ 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" "/"
++if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then
++ # One or more of the files had a syntax error
++ exit 1
++fi
++exit 0
+diff --git a/scripts/brp-python-hardlink b/scripts/brp-python-hardlink
+new file mode 100755
+index 0000000..5fd1b43
+--- /dev/null
++++ b/scripts/brp-python-hardlink
+@@ -0,0 +1,25 @@
++#!/bin/sh
++
++# If using normal root, avoid changing anything.
++if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then
++ exit 0
++fi
++
++hardlink_if_same() {
++ if cmp -s "$1" "$2" ; then
++ ln -f "$1" "$2"
++ return 0
++ fi
++ return 1
++}
++
++# Hardlink identical *.pyc, *.pyo, and *.opt-[12].pyc.
++# Originally from PLD's rpm-build-macros
++find "$RPM_BUILD_ROOT" -type f -name "*.pyc" -not -name "*.opt-[12].pyc" | while read pyc ; do
++ hardlink_if_same "$pyc" "${pyc%c}o"
++ o1pyc="${pyc%pyc}opt-1.pyc"
++ hardlink_if_same "$pyc" "$o1pyc"
++ o2pyc="${pyc%pyc}opt-2.pyc"
++ hardlink_if_same "$pyc" "$o2pyc" || hardlink_if_same "$o1pyc" "$o2pyc"
++done
++exit 0
+--
+1.8.3.1
+