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);

openSUSE Build Service is sponsored by