[Rpm-maint] [Suse patch] Check rpm payload format

Panu Matilainen pmatilai at redhat.com
Tue May 22 08:10:15 UTC 2007

The idea here is obvious enough, I just somewhat disagree with the 
implementation. See below the patch for further comments...


Check if the payloadformat really is "cpio", fail with an error
message if it is not. Use a different message for the "drpm"
delta-rpm format. rh#140052

Upstream proposes a different approach, patching the "Requires"
list, which the current deltarpm implementation can't do, because
it uses a verbatim copy of the original header. Sigh.

I still believe that rpm should check for known formats, i.e.
now that rpm understands ustar it should insist that the format
is either "cpio" or "ustar".

--- ./lib/rpminstall.c.orig	2005-12-14 21:01:09.000000000 +0000
+++ ./lib/rpminstall.c	2005-12-15 14:47:35.000000000 +0000
@@ -470,6 +470,7 @@ if (fileURL[0] == '=') {
  	 eiu->fnp++, eiu->prevx++)
  	const char * fileName;
+	const char * payloadformat;

  	rpmMessage(RPMMESS_DEBUG, "============== %s\n", *eiu->fnp);
  	(void) urlPath(*eiu->fnp, &fileName);
@@ -510,6 +511,17 @@ if (fileURL[0] == '=') {
  	    /*@switchbreak@*/ break;

+	payloadformat = 0;
+	if (!headerGetEntry(eiu->h, RPMTAG_PAYLOADFORMAT, NULL, (void **)&payloadformat, NULL))
+	    payloadformat = 0;
+	if (payloadformat && strcmp(payloadformat, "cpio") != 0) {
+	    if (!strcmp(payloadformat, "drpm"))
+		rpmMessage(RPMMESS_ERROR, _("%s is a deltarpm, create a real rpm from it first!\n"), *eiu->fnp);
+	    else
+		rpmMessage(RPMMESS_ERROR, _("%s contains no cpio payload\n"), *eiu->fnp);
+	    eiu->numFailed++; *eiu->fnp = NULL;
+	    continue;
+	}
  	eiu->isSource = headerIsEntry(eiu->h, RPMTAG_SOURCEPACKAGE);

  	if (eiu->isSource) {


The above patch takes care of rpm cli usage only, I think a better place 
would be to check within rpmtsAddInstallElement() which takes care of rpm 
cli AND any API users who check for return values from it like they 

diff -r 4c3b70808142 lib/depends.c
--- a/lib/depends.c	Thu May 17 11:06:55 2007 +0100
+++ b/lib/depends.c	Fri May 18 14:35:31 2007 +0300
@@ -139,6 +139,7 @@ int rpmtsAddInstallElement(rpmts ts, Hea
      HGE_t hge = (HGE_t)headerGetEntryMinMemory;
      const char * arch;
      const char * os;
+    const char * payloadfmt;
      rpmds oldChk, newChk;
      rpmds obsoletes;
      alKey pkgKey;	/* addedPackages key */
@@ -155,8 +156,17 @@ int rpmtsAddInstallElement(rpmts ts, Hea
      xx = hge(h, RPMTAG_ARCH, NULL, (void **)&arch, NULL);
      os = NULL;
      xx = hge(h, RPMTAG_OS, NULL, (void **)&os, NULL);
+    payloadfmt = NULL;
+    xx = hge(h, RPMTAG_PAYLOADFORMAT, NULL, (void **)&payloadfmt, NULL);
      hcolor = hGetColor(h);
      pkgKey = RPMAL_NOMATCH;
+    if (payloadfmt && strncmp(payloadfmt, "cpio", strlen("cpio"))) {
+    	rpmMessage(RPMMESS_ERROR, _("Unsupported payload (%s) in package\n"), 
+	           payloadfmt);
+	ec = 1;
+	goto exit;
+    }

      /* XXX Always add source headers. */
      isSource = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);


There are (at least) two issues still however: current python bindings 
have no way to report a ts.addInstall() failure, so eg with yum it ends up 
trying to install it anyway. I'll send a patch for that in a separate 
mail for discussion... The other issue is that not all delta rpms appear 
to be equal. createrepo is a suse-deltarpm and brltty is from yum-presto 
fedora repo:

[root at dhcp115 ~]# rpm -Uv --nodeps --noscripts 
Preparing packages for installation...
error: unpacking of archive failed: cpio: Bad magic
[root at dhcp115 ~]# rpm -Uv --nodeps --noscripts 
Preparing packages for installation...
error: unpacking of archive failed: cpio: Bad magic
[root at dhcp115 ~]# rpm -qp --queryformat "%{PAYLOADFORMAT}\n" 
[root at dhcp115 ~]# rpm -qp --queryformat "%{PAYLOADFORMAT}\n" 

Somebody more familiar with Delta RPMS care to comment, is this a matter 
of different deltarpm versions being used or ...?

 	- Panu -

More information about the Rpm-maint mailing list