File rpm-relocate-header-filelist.patch of Package atikon-bb-rpm
# This software uses code based on 'ayum' from 'Reiner Hauser', also GPL2 licensed.
# https://gitlab.cern.ch/atlas-sit/ayum
diff -urN rpm-orig/lib/misc.h rpm-patched2/lib/misc.h
--- rpm-orig/lib/misc.h 2021-06-21 14:00:44.601611962 +0200
+++ rpm-patched2/lib/misc.h 2022-03-15 13:26:46.917143770 +0100
@@ -52,7 +52,6 @@
* @param fs file state set
* @param h package header to relocate
*/
-RPM_GNUC_INTERNAL
void rpmRelocateFileList(rpmRelocation *relocs, int numRelocations, rpmfs fs, Header h);
RPM_GNUC_INTERNAL
diff -urN rpm-orig/python/header-py.c rpm-patched2/python/header-py.c
--- rpm-orig/python/header-py.c 2021-06-21 14:00:44.644612642 +0200
+++ rpm-patched2/python/header-py.c 2022-03-15 13:27:21.017478411 +0100
@@ -216,6 +216,88 @@
Py_RETURN_NONE;
}
+static PyObject *
+hdrRelocateFilelist(PyObject *self, PyObject * args)
+{
+ PyObject *header = NULL;
+ PyObject *relocations = NULL;
+
+ Header h = NULL;
+ rpmRelocation *relocs = NULL;
+ ssize_t list_size;
+
+ if (!PyArg_ParseTuple(args, "OO:relocateFilelist", &header, &relocations)) {
+ PyErr_SetString(PyExc_TypeError, "invalid arguments");
+ return NULL;
+ }
+
+ if (hdrObject_Check(header)) {
+ h = ((hdrObject *)header)->h;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "expected a header object");
+ return NULL;
+ }
+
+ if(relocations && relocations != Py_None) {
+ ssize_t i;
+
+ if(!PyList_Check(relocations)) {
+ PyErr_SetString(PyExc_TypeError, "expected a list for relocations");
+ return NULL;
+ }
+
+ // each list entry is a tuple(oldpath, newpath)
+ list_size = PyList_Size(relocations);
+ relocs = (rpmRelocation *)malloc((list_size + 1) * sizeof(rpmRelocation));
+ for(i = 0; i < list_size; i++) {
+ PyObject *oldpath, *newpath;
+ PyObject *item = PyList_GetItem(relocations, i);
+ if(!PyTuple_Check(item) || PyTuple_Size(item) != 2) {
+ PyErr_SetString(PyExc_TypeError, "expected a tuple with two strings");
+ return NULL;
+ }
+ oldpath = PyTuple_GetItem(item, 0);
+ newpath = PyTuple_GetItem(item, 1);
+ if(!PyUnicode_Check(oldpath) || !PyUnicode_Check(newpath)) {
+ PyErr_SetString(PyExc_TypeError, "expected a tuple with two strings");
+ return NULL;
+ }
+ relocs[i].oldPath = strdup(PyUnicode_AsUTF8(oldpath));
+ relocs[i].newPath = strdup(PyUnicode_AsUTF8(newpath));
+ }
+ relocs[i].oldPath = NULL;
+ relocs[i].newPath = NULL;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "expected a list for relocations");
+ return NULL;
+ }
+
+ Header new_h = headerCopy(h);
+
+ // relocate the filename locations
+ rpmRelocateFileList(relocs, list_size, NULL, new_h);
+
+ // RPM keeps track of the installation prefix when relocation is in effect
+ // this can be a list with multiple prefixes but, in our use case, everything is under
+ // a single prefix so we can just replace the whole list with the relocation target
+ const char ** instprefixes;
+ instprefixes = malloc(1 * sizeof(char *));
+
+ // we only allow a single relocation (enforced above) so taking the first entry is a safe bet
+ instprefixes[0] = relocs[0].newPath;
+
+ // remove the old header otherwise headerPutStringArray() would append to it
+ headerDel(new_h, RPMTAG_INSTPREFIXES);
+ headerPutStringArray(new_h, RPMTAG_INSTPREFIXES, instprefixes, 1);
+
+ free(instprefixes);
+
+ return hdr_Wrap(&hdr_Type, new_h);
+}
+
+
static PyObject * hdrFormat(hdrObject * s, PyObject * args, PyObject * kwds)
{
const char * fmt;
@@ -360,6 +442,8 @@
"hdr.fiFromHeader() -- Return rpm.fi object containing the file\nmeta data from the header.\n\nDEPRECATED - Use rpm.files(hdr) instead."},
{"__reduce__", (PyCFunction)hdr_reduce, METH_NOARGS,
NULL},
+ {"relocateFilelist", (PyCFunction) hdrRelocateFilelist, METH_VARARGS,
+ "Relocate file locations."},
{NULL, NULL} /* sentinel */
};
diff -urN rpm-orig/python/header-py.h rpm-patched2/python/header-py.h
--- rpm-orig/python/header-py.h 2021-06-21 14:00:44.644612642 +0200
+++ rpm-patched2/python/header-py.h 2022-03-15 13:26:46.917143770 +0100
@@ -2,6 +2,7 @@
#define RPMPYTHON_HEADER
#include <rpm/rpmtypes.h>
+#include "../lib/rpmfs.h"
typedef struct hdrObject_s hdrObject;
@@ -24,3 +25,5 @@
PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds);
PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds);
#endif
+
+void rpmRelocateFileList(rpmRelocation *relocs, int numRelocations, rpmfs fs, Header h);