Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bug#509444: Patch for rpm to support lzma compressed cpio payloads

10 views
Skip to first unread message

Thayne Harbaugh

unread,
Mar 10, 2009, 3:50:13 PM3/10/09
to
Package: rpm
Version: 4.4.2.3-1
Followup-For: Bug #509444

The Debian rpm package does not support LZMA compressed cpio payloads.
This patch adds LZMA support to the rpm package. These patches are based
on patches from openSUSE and require a new libxz package being worked on
for Debian.


25-lzma-payload.diff:
Index: rpm-4.4.2.3/build/pack.c
===================================================================
--- rpm-4.4.2.3.orig/build/pack.c 2009-03-02 16:14:41.000000000 -0700
+++ rpm-4.4.2.3/build/pack.c 2009-03-02 16:14:51.000000000 -0700
@@ -479,6 +479,11 @@
/* Add prereq on rpm version that understands bzip2 payloads */
(void) rpmlibNeedsFeature(h, "PayloadIsBzip2", "3.0.5-1");
}
+ if (s[1] == 'l' && s[2] == 'z') {
+ (void) headerAddEntry(h, RPMTAG_PAYLOADCOMPRESSOR, RPM_STRING_TYPE,
+ "lzma", 1);
+ (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.2-1");
+ }
strcpy(buf, rpmio_flags);
buf[s - rpmio_flags] = '\0';
(void) headerAddEntry(h, RPMTAG_PAYLOADFLAGS, RPM_STRING_TYPE, buf+1, 1);
Index: rpm-4.4.2.3/lib/psm.c
===================================================================
--- rpm-4.4.2.3.orig/lib/psm.c 2009-03-02 16:14:41.000000000 -0700
+++ rpm-4.4.2.3/lib/psm.c 2009-03-02 16:14:51.000000000 -0700
@@ -2078,6 +2078,8 @@
t = stpcpy(t, ".gzdio");
if (!strcmp(payload_compressor, "bzip2"))
t = stpcpy(t, ".bzdio");
+ if (!strcmp(payload_compressor, "lzma"))
+ t = stpcpy(t, ".lzdio");
rc = RPMRC_OK;
} break;

Index: rpm-4.4.2.3/lib/rpmlibprov.c
===================================================================
--- rpm-4.4.2.3.orig/lib/rpmlibprov.c 2009-03-02 16:14:41.000000000 -0700
+++ rpm-4.4.2.3/lib/rpmlibprov.c 2009-03-02 16:14:51.000000000 -0700
@@ -56,6 +56,9 @@
( RPMSENSE_EQUAL),
N_("internal support for lua scripts.") },
#endif
+ { "rpmlib(PayloadIsLzma)", "4.4.2-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
+ N_("package payload can be compressed using lzma.") },
{ NULL, NULL, 0, NULL }
};

Index: rpm-4.4.2.3/macros.in
===================================================================
--- rpm-4.4.2.3.orig/macros.in 2009-03-02 16:14:51.000000000 -0700
+++ rpm-4.4.2.3/macros.in 2009-03-02 16:14:51.000000000 -0700
@@ -326,6 +326,7 @@
# Compression type and level for source/binary package payloads.
# "w9.gzdio" gzip level 9 (default).
# "w9.bzdio" bzip2 level 9.
+# "w5.lzdio" lzma level 5. (best compromise)
#
#%_source_payload w9.gzdio
#%_binary_payload w9.gzdio
Index: rpm-4.4.2.3/rpm2cpio.c
===================================================================
--- rpm-4.4.2.3.orig/rpm2cpio.c 2009-03-02 16:14:51.000000000 -0700
+++ rpm-4.4.2.3/rpm2cpio.c 2009-03-02 16:14:51.000000000 -0700
@@ -82,6 +82,8 @@
t = stpcpy(t, ".gzdio");
if (!strcmp(payload_compressor, "bzip2"))
t = stpcpy(t, ".bzdio");
+ if (!strcmp(payload_compressor, "lzma"))
+ t = stpcpy(t, ".lzdio");
}

gzdi = Fdopen(fdi, rpmio_flags); /* XXX gzdi == fdi */
Index: rpm-4.4.2.3/rpmio/rpmio.h
===================================================================
--- rpm-4.4.2.3.orig/rpmio/rpmio.h 2009-03-02 16:14:41.000000000 -0700
+++ rpm-4.4.2.3/rpmio/rpmio.h 2009-03-02 16:14:51.000000000 -0700
@@ -669,6 +669,10 @@

/**
*/
+/*@observer@*/ /*@unchecked@*/ extern FDIO_t lzdio;
+
+/**
+ */
/*@observer@*/ /*@unchecked@*/ extern FDIO_t fadio;
/*@=exportlocal@*/
/*@}*/
Index: rpm-4.4.2.3/scripts/rpm2cpio.sh
===================================================================
--- rpm-4.4.2.3.orig/scripts/rpm2cpio.sh 2009-03-02 16:14:41.000000000 -0700
+++ rpm-4.4.2.3/scripts/rpm2cpio.sh 2009-03-02 16:14:51.000000000 -0700
@@ -23,4 +23,14 @@
hdrsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $hdrsize`

-dd if=$pkg ibs=$o skip=1 2>/dev/null | gunzip
+comp=`dd if="$pkg" ibs=$o skip=1 count=1 2>/dev/null \
+ | dd bs=3 count=1 2>/dev/null`
+
+gz="`echo . | awk '{ printf("%c%c", 0x1f, 0x8b); }'`"
+case "$comp" in
+ BZh) dd if="$pkg" ibs=$o skip=1 2>/dev/null | bunzip2 ;;
+ "$gz"*) dd if="$pkg" ibs=$o skip=1 2>/dev/null | gunzip ;;
+ # no magic in old lzma format, if unknown we assume that's lzma for now
+ *) dd if="$pkg" ibs=$o skip=1 2>/dev/null | unlzma ;;
+ #*) echo "Unrecognized rpm file: $pkg"; return 1 ;;
+esac
Index: rpm-4.4.2.3/rpmio/Makefile.am
===================================================================
--- rpm-4.4.2.3.orig/rpmio/Makefile.am 2009-03-02 16:14:41.000000000 -0700
+++ rpm-4.4.2.3/rpmio/Makefile.am 2009-03-02 16:14:51.000000000 -0700
@@ -41,7 +41,7 @@
@WITH_MAGIC_LIB@ \
@WITH_ZLIB_LIB@ \
-lpthread
-librpmio_la_LIBADD = # $(BEECRYPTLOBJS)
+librpmio_la_LIBADD = -llzma # $(BEECRYPTLOBJS)
librpmio_la_DEPENDENCIES = # .created

.created:


26-lzma-payload-2.diff:
Index: rpm-4.4.2.3/rpmio/rpmio.c
===================================================================
--- rpm-4.4.2.3.orig/rpmio/rpmio.c 2009-03-08 16:44:20.000000000 -0600
+++ rpm-4.4.2.3/rpmio/rpmio.c 2009-03-08 16:50:03.000000000 -0600
@@ -84,6 +84,7 @@
#define FDONLY(fd) assert(fdGetIo(fd) == fdio)
#define GZDONLY(fd) assert(fdGetIo(fd) == gzdio)
#define BZDONLY(fd) assert(fdGetIo(fd) == bzdio)
+#define LZDONLY(fd) assert(fdGetIo(fd) == lzdio)

#define UFDONLY(fd) /* assert(fdGetIo(fd) == ufdio) */

@@ -189,6 +190,8 @@
} else if (fps->io == bzdio) {
sprintf(be, "BZD %p fdno %d", fps->fp, fps->fdno);
#endif
+ } else if (fps->io == lzdio) {
+ sprintf(be, "LZD %p fdno %d", fps->fp, fps->fdno);
} else if (fps->io == fpio) {
/*@+voidabstract@*/
sprintf(be, "%s %p(%d) fdno %d",
@@ -2782,6 +2785,349 @@
/*@=moduncon@*/
#endif /* HAVE_BZLIB_H */

+#include <sys/types.h>
+#include <inttypes.h>
+#include <lzma.h>
+
+#define kBufferSize (1 << 15)
+
+typedef struct lzfile {
+ /* IO buffer */
+ uint8_t buf[kBufferSize];
+
+ lzma_stream strm;
+
+ FILE *file;
+
+ int encoding;
+ int eof;
+
+} LZFILE;
+
+static LZFILE *lzopen_internal(const char *path, const char *mode, int fd)
+{
+ int level = 5;
+ int encoding = 0;
+ FILE *fp;
+ LZFILE *lzfile;
+ lzma_ret ret;
+ lzma_stream lzma_strm_tmp = LZMA_STREAM_INIT;
+
+ for (; *mode; mode++) {
+ if (*mode == 'w')
+ encoding = 1;
+ else if (*mode == 'r')
+ encoding = 0;
+ else if (*mode >= '1' && *mode <= '9')
+ level = *mode - '0';
+ }
+ if (fd != -1)
+ fp = fdopen(fd, encoding ? "w" : "r");
+ else
+ fp = fopen(path, encoding ? "w" : "r");
+ if (!fp)
+ return NULL;
+ lzfile = calloc(1, sizeof(*lzfile));
+ if (!lzfile) {
+ fclose(fp);
+ return NULL;
+ }
+ lzfile->file = fp;
+ lzfile->encoding = encoding;
+ lzfile->eof = 0;
+ lzfile->strm = lzma_strm_tmp;
+ if (encoding) {
+ lzma_options_lzma opt_lzma;
+ if (lzma_lzma_preset(&opt_lzma, level - 1))
+ return NULL;
+ ret = lzma_alone_encoder(&lzfile->strm, &opt_lzma);
+ } else {
+ ret = lzma_auto_decoder(&lzfile->strm, UINT64_C(64) * 1024 * 1024, 0);
+ }
+ if (ret != LZMA_OK) {
+ fclose(fp);
+ free(lzfile);
+ return NULL;
+ }
+ return lzfile;
+}
+
+static LZFILE *lzopen(const char *path, const char *mode)
+{
+ return lzopen_internal(path, mode, -1);
+}
+
+static LZFILE *lzdopen(int fd, const char *mode)
+{
+ if (fd < 0)
+ return NULL;
+ return lzopen_internal(0, mode, fd);
+}
+
+static int lzflush(LZFILE *lzfile)
+{
+ return fflush(lzfile->file);
+}
+
+static int lzclose(LZFILE *lzfile)
+{
+ lzma_ret ret;
+ int n;
+
+ if (!lzfile)
+ return -1;
+ if (lzfile->encoding) {
+ for (;;) {
+ lzfile->strm.avail_out = kBufferSize;
+ lzfile->strm.next_out = lzfile->buf;
+ ret = lzma_code(&lzfile->strm, LZMA_FINISH);
+ if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+ return -1;
+ n = kBufferSize - lzfile->strm.avail_out;
+ if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n)
+ return -1;
+ if (ret == LZMA_STREAM_END)
+ break;
+ }
+ }
+ lzma_end(&lzfile->strm);
+ return fclose(lzfile->file);
+ free(lzfile);
+}
+
+static ssize_t lzread(LZFILE *lzfile, void *buf, size_t len)
+{
+ lzma_ret ret;
+ int eof = 0;
+
+ if (!lzfile || lzfile->encoding)
+ return -1;
+ if (lzfile->eof)
+ return 0;
+ lzfile->strm.next_out = buf;
+ lzfile->strm.avail_out = len;
+ for (;;) {
+ if (!lzfile->strm.avail_in) {
+ lzfile->strm.next_in = lzfile->buf;
+ lzfile->strm.avail_in = fread(lzfile->buf, 1, kBufferSize, lzfile->file);
+ if (!lzfile->strm.avail_in)
+ eof = 1;
+ }
+ ret = lzma_code(&lzfile->strm, LZMA_RUN);
+ if (ret == LZMA_STREAM_END) {
+ lzfile->eof = 1;
+ return len - lzfile->strm.avail_out;
+ }
+ if (ret != LZMA_OK)
+ return -1;
+ if (!lzfile->strm.avail_out)
+ return len;
+ if (eof)
+ return -1;
+ }
+}
+
+static ssize_t lzwrite(LZFILE *lzfile, void *buf, size_t len)
+{
+ lzma_ret ret;
+ int n;
+ if (!lzfile || !lzfile->encoding)
+ return -1;
+ if (!len)
+ return 0;
+ lzfile->strm.next_in = buf;
+ lzfile->strm.avail_in = len;
+ for (;;) {
+ lzfile->strm.next_out = lzfile->buf;
+ lzfile->strm.avail_out = kBufferSize;
+ ret = lzma_code(&lzfile->strm, LZMA_RUN);
+ if (ret != LZMA_OK)
+ return -1;
+ n = kBufferSize - lzfile->strm.avail_out;
+ if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n)
+ return -1;
+ if (!lzfile->strm.avail_in)
+ return len;
+ }
+}
+
+/* =============================================================== */
+
+static inline /*@dependent@*/ void * lzdFileno(FD_t fd)
+/*@*/
+{
+ void * rc = NULL;
+ int i;
+
+ FDSANE(fd);
+ for (i = fd->nfps; i >= 0; i--) {
+/*@-boundsread@*/
+ FDSTACK_t * fps = &fd->fps[i];
+/*@=boundsread@*/
+ if (fps->io != lzdio)
+ continue;
+ rc = fps->fp;
+ break;
+ }
+
+ return rc;
+}
+
+/*@-globuse@*/
+static /*@null@*/ FD_t lzdOpen(const char * path, const char * mode)
+/*@globals fileSystem @*/
+/*@modifies fileSystem @*/
+{
+ FD_t fd;
+ LZFILE *lzfile;
+ if ((lzfile = lzopen(path, mode)) == NULL)
+ return NULL;
+ fd = fdNew("open (lzdOpen)");
+ fdPop(fd); fdPush(fd, lzdio, lzfile, -1);
+ return fdLink(fd, "lzdOpen");
+}
+/*@=globuse@*/
+
+
+/*@-globuse@*/
+static /*@null@*/ FD_t lzdFdopen(void * cookie, const char * fmode)
+/*@globals fileSystem, internalState @*/
+/*@modifies fileSystem, internalState @*/
+{
+ FD_t fd = c2f(cookie);
+ int fdno;
+ LZFILE *lzfile;
+
+ if (fmode == NULL) return NULL;
+ fdno = fdFileno(fd);
+ fdSetFdno(fd, -1); /* XXX skip the fdio close */
+ if (fdno < 0) return NULL;
+ lzfile = lzdopen(fdno, fmode);
+ if (lzfile == NULL) return NULL;
+ fdPush(fd, lzdio, lzfile, fdno);
+ return fdLink(fd, "lzdFdopen");
+}
+/*@=globuse@*/
+
+/*@-globuse@*/
+static int lzdFlush(FD_t fd)
+/*@globals fileSystem @*/
+/*@modifies fileSystem @*/
+{
+ return lzflush(lzdFileno(fd));
+}
+/*@=globuse@*/
+
+/* =============================================================== */
+/*@-globuse@*/
+/*@-mustmod@*/ /* LCL: *buf is modified */
+static ssize_t lzdRead(void * cookie, /*@out@*/ char * buf, size_t count)
+/*@globals fileSystem, internalState @*/
+/*@modifies *buf, fileSystem, internalState @*/
+{
+ FD_t fd = c2f(cookie);
+ LZFILE *lzfile;
+ ssize_t rc = 0;
+
+ if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
+ lzfile = lzdFileno(fd);
+ fdstat_enter(fd, FDSTAT_READ);
+ if (lzfile)
+ /*@-compdef@*/
+ rc = lzread(lzfile, buf, count);
+ /*@=compdef@*/
+ if (rc == -1) {
+ fd->errcookie = "Lzma: decoding error";
+ } else if (rc >= 0) {
+ fdstat_exit(fd, FDSTAT_READ, rc);
+ /*@-compdef@*/
+ if (fd->ndigests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
+ /*@=compdef@*/
+ }
+ return rc;
+}
+/*@=mustmod@*/
+/*@=globuse@*/
+
+/*@-globuse@*/
+static ssize_t lzdWrite(void * cookie, const char * buf, size_t count)
+/*@globals fileSystem, internalState @*/
+/*@modifies fileSystem, internalState @*/
+{
+ FD_t fd = c2f(cookie);
+ LZFILE *lzfile;
+ ssize_t rc = 0;
+
+ if (fd == NULL || fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
+
+ if (fd->ndigests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
+
+ lzfile = lzdFileno(fd);
+
+ fdstat_enter(fd, FDSTAT_WRITE);
+ rc = lzwrite(lzfile, (void *)buf, count);
+ if (rc < 0) {
+ fd->errcookie = "Lzma: encoding error";
+ } else if (rc > 0) {
+ fdstat_exit(fd, FDSTAT_WRITE, rc);
+ }
+ return rc;
+}
+
+static inline int lzdSeek(void * cookie, /*@unused@*/ _libio_pos_t pos,
+ /*@unused@*/ int whence)
+/*@*/
+{
+ FD_t fd = c2f(cookie);
+
+ LZDONLY(fd);
+ return -2;
+}
+
+static int lzdClose( /*@only@*/ void * cookie)
+/*@globals fileSystem, internalState @*/
+/*@modifies fileSystem, internalState @*/
+{
+ FD_t fd = c2f(cookie);
+ LZFILE *lzfile;
+ int rc;
+
+ lzfile = lzdFileno(fd);
+
+ if (lzfile == NULL) return -2;
+ fdstat_enter(fd, FDSTAT_CLOSE);
+ /*@-dependenttrans@*/
+ rc = lzclose(lzfile);
+ /*@=dependenttrans@*/
+
+ /* XXX TODO: preserve fd if errors */
+
+ if (fd) {
+ if (rc == -1) {
+ fd->errcookie = strerror(ferror(lzfile->file));
+ } else if (rc >= 0) {
+ fdstat_exit(fd, FDSTAT_CLOSE, rc);
+ }
+ }
+
+ DBGIO(fd, (stderr, "==>\tlzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
+
+ if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "LZDIO", stderr);
+ /*@-branchstate@*/
+ if (rc == 0)
+ fd = fdFree(fd, "open (lzdClose)");
+ /*@=branchstate@*/
+ return rc;
+}
+
+/*@-type@*/ /* LCL: function typedefs */
+static struct FDIO_s lzdio_s = {
+ lzdRead, lzdWrite, lzdSeek, lzdClose, XfdLink, XfdFree, XfdNew, fdFileno,
+ NULL, lzdOpen, lzdFileno, lzdFlush, NULL, NULL, NULL, NULL, NULL
+};
+/*@=type@*/
+FDIO_t lzdio = /*@-compmempass@*/ &lzdio_s /*@=compmempass@*/ ;
+
/* =============================================================== */
/*@observer@*/
static const char * getFdErrstr (FD_t fd)
@@ -2797,10 +3143,12 @@

#ifdef HAVE_BZLIB_H
if (fdGetIo(fd) == bzdio) {
- errstr = fd->errcookie;
+ errstr = fd->errcookie;
} else
#endif /* HAVE_BZLIB_H */
-
+ if (fdGetIo(fd) == lzdio) {
+ errstr = fd->errcookie;
+ } else
{
errstr = (fd->syserrno ? strerror(fd->syserrno) : "");
}
@@ -3114,6 +3462,9 @@
fd = bzdFdopen(fd, zstdio);
/*@=internalglobs@*/
#endif
+ } else if (!strcmp(end, "lzdio")) {
+ iof = lzdio;
+ fd = lzdFdopen(fd, zstdio);
} else if (!strcmp(end, "ufdio")) {
iof = ufdio;
} else if (!strcmp(end, "fpio")) {
@@ -3301,6 +3652,9 @@
ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
i--; /* XXX fdio under bzdio always has fdno == -1 */
#endif
+ } else if (fps->io == lzdio) {
+ ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
+ i--; /* XXX fdio under lzdio always has fdno == -1 */
} else {
/* XXX need to check ufdio/gzdio/bzdio/fdio errors correctly. */
ec = (fdFileno(fd) < 0 ? -1 : 0);

-- System Information:
Debian Release: squeeze/sid
APT prefers testing
APT policy: (990, 'testing'), (300, 'unstable'), (200, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages rpm depends on:
ii libbeecrypt6 4.1.2-7 open source C library of cryptogra
ii libbz2-1.0 1.0.5-1 high-quality block-sorting file co
ii libc6 2.9-4 GNU C Library: Shared libraries
ii libpopt0 1.14-4 lib for parsing cmdline parameters
ii librpm4.4 4.4.2.3-1 RPM shared library
ii perl 5.10.0-19 Larry Wall's Practical Extraction
ii zlib1g 1:1.2.3.3.dfsg-12 compression library - runtime

rpm recommends no packages.

Versions of packages rpm suggests:
ii alien 8.74 convert and install rpm and other

-- no debconf information

--
To UNSUBSCRIBE, email to debian-bugs-...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listm...@lists.debian.org

0 new messages