aboutsummaryrefslogtreecommitdiffstats
path: root/archivers
diff options
context:
space:
mode:
authorwxs <wxs@FreeBSD.org>2009-10-22 21:27:20 +0800
committerwxs <wxs@FreeBSD.org>2009-10-22 21:27:20 +0800
commit21f738a6a9faae23d9944db6c3b3ecc4d8b3cc1d (patch)
tree28ec1f5d8a55e0f65039d0faa675098829b6f4f5 /archivers
parent68ac45e5338452e8a89322e8db12c522b24b56d7 (diff)
downloadfreebsd-ports-gnome-21f738a6a9faae23d9944db6c3b3ecc4d8b3cc1d.tar.gz
freebsd-ports-gnome-21f738a6a9faae23d9944db6c3b3ecc4d8b3cc1d.tar.zst
freebsd-ports-gnome-21f738a6a9faae23d9944db6c3b3ecc4d8b3cc1d.zip
- Add xz compression support.
PR: ports/139511 Submitted by: Anders F Björklund <afb@rpm5.org> (maintainer)
Diffstat (limited to 'archivers')
-rw-r--r--archivers/rpm5/Makefile15
-rw-r--r--archivers/rpm5/files/patch-xz-support650
2 files changed, 663 insertions, 2 deletions
diff --git a/archivers/rpm5/Makefile b/archivers/rpm5/Makefile
index 28af28bdc845..f3b63b59a108 100644
--- a/archivers/rpm5/Makefile
+++ b/archivers/rpm5/Makefile
@@ -6,7 +6,7 @@
PORTNAME= rpm
PORTVERSION= 5.0.3
-PORTREVISION= 4
+PORTREVISION= 5
CATEGORIES= archivers
MASTER_SITES= http://rpm5.org/files/rpm/rpm-5.0/
PATCHFILES= rpm-5.0.3.1.patch
@@ -22,6 +22,7 @@ LIB_DEPENDS= db-${DB_VERSION:C/(.)/\1./}:${PORTSDIR}/databases/db${DB_VERSION} \
neon.28:${PORTSDIR}/www/neon28 \
magic:${PORTSDIR}/sysutils/file \
xar:${PORTSDIR}/archivers/xar \
+ lzma:${PORTSDIR}/archivers/xz \
pcre.0:${PORTSDIR}/devel/pcre
BUILD_DEPENDS= ${LOCALBASE}/bin/gsed:${PORTSDIR}/textproc/gsed
.if !defined(NOPORTDOCS)
@@ -41,6 +42,13 @@ USE_PERL5_BUILD=5.8.0+
LATEST_LINK= rpm5
CONFLICTS= rpm-3.* rpm-4.*
+# need to autogen (for xz support)
+USE_AUTOTOOLS+= aclocal:110 autoconf:262 automake:110 autoheader:262
+ACLOCAL_ARGS+= -I m4 -I ${LOCALBASE}/share/aclocal
+AUTOMAKE_ARGS+= -a -c
+pre-configure:
+ cd ${WRKSRC}; ./autogen.sh
+
.if !defined(WITHOUT_LUA)
CONFIGURE_ARGS+=--with-lua=external
USE_LUA= 5.1-
@@ -87,6 +95,7 @@ CONFIGURE_ARGS+=--with-db=external --with-bugreport="${MAINTAINER}" \
--with-zlib=external \
--with-file=external \
--with-xar=external \
+ --with-xz=external \
--with-pcre=external \
--program-prefix="" \
--sysconfdir=${PREFIX}/etc \
@@ -116,7 +125,9 @@ CFLAGS+= -fPIC
post-patch::
@${REINPLACE_CMD} -E -e \
's:\$$\(libdir\)/pkgconfig:${PREFIX}/libdata/pkgconfig:' \
- ${WRKSRC}/scripts/Makefile.in
+ ${WRKSRC}/scripts/Makefile.am ${WRKSRC}/scripts/Makefile.in
+ @${REINPLACE_CMD} -e "s:/bin/sh:/usr/bin/env bash:" \
+ ${WRKSRC}/scripts/gendiff
.if defined(WITH_PERL)
post-configure:
diff --git a/archivers/rpm5/files/patch-xz-support b/archivers/rpm5/files/patch-xz-support
new file mode 100644
index 000000000000..dc19a6d63f7b
--- /dev/null
+++ b/archivers/rpm5/files/patch-xz-support
@@ -0,0 +1,650 @@
+diff -urp build/pack.c.orig build/pack.c
+--- build/pack.c.orig 2008-01-29 14:57:33.000000000 +0100
++++ build/pack.c 2009-06-08 10:54:15.000000000 +0200
+@@ -672,6 +672,13 @@ rpmRC writeRPM(Header *hdrp, unsigned ch
+ he->c = 1;
+ xx = headerPut(h, he, 0);
+ (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
++ } else if (s[1] == 'x' && s[2] == 'z') {
++ he->tag = RPMTAG_PAYLOADCOMPRESSOR;
++ he->t = RPM_STRING_TYPE;
++ he->p.str = "xz";
++ he->c = 1;
++ xx = headerPut(h, he, 0);
++ (void) rpmlibNeedsFeature(h, "PayloadIsXz", "5.2-1");
+ }
+ strcpy(buf, rpmio_flags);
+ buf[s - rpmio_flags] = '\0';
+diff -urp build/parsePrep.c.orig build/parsePrep.c
+--- build/parsePrep.c.orig 2007-12-31 17:21:47.000000000 +0100
++++ build/parsePrep.c 2009-04-06 08:38:11.000000000 +0200
+@@ -159,6 +159,9 @@ static char *doPatch(Spec spec, int c, i
+ case COMPRESSED_LZMA:
+ zipper = "%{__lzma}";
+ break;
++ case COMPRESSED_XZ:
++ zipper = "%{__xz}";
++ break;
+ }
+ zipper = rpmGetPath(zipper, NULL);
+
+@@ -289,6 +292,9 @@ _rpmmg_debug = 0;
+ case COMPRESSED_LZMA:
+ t = "%{__lzma} -dc";
+ break;
++ case COMPRESSED_XZ:
++ t = "%{__xz} -dc";
++ break;
+ case COMPRESSED_ZIP:
+ if (rpmIsVerbose() && !quietly)
+ t = "%{__unzip}";
+diff -urp configure.ac.orig configure.ac
+--- configure.ac.orig 2008-03-03 09:41:37.000000000 +0100
++++ configure.ac 2009-07-29 10:21:26.000000000 +0200
+@@ -469,6 +469,7 @@ AC_PATH_PROG(__TCLSH, tclsh, %{_bindir}/
+ AC_PATH_PROG(__UNZIP, unzip, %{_bindir}/unzip, $MYPATH)
+ AC_PATH_PROG(__WGET, wget, %{_bindir}/wget, $MYPATH)
+ AC_PATH_PROG(__XAR, xar, %{_bindir}/xar, $MYPATH)
++AC_PATH_PROG(__XZ, xz, %{_bindir}/xz, $MYPATH)
+ AC_PATH_PROG(__LD, ld, %{_bindir}/ld, $MYPATH)
+ AC_PATH_PROG(__NM, nm, %{_bindir}/nm, $MYPATH)
+ AC_PATH_PROG(__OBJCOPY, objcopy, %{_bindir}/objcopy, $MYPATH)
+@@ -927,6 +928,13 @@ RPM_CHECK_LIB(
+ [no,external:none], [],
+ [], [])
+
++dnl # LZMA Utils
++RPM_CHECK_LIB(
++ [XZ libLZMA], [xz],
++ [lzma], [lzma_auto_decoder], [lzma.h],
++ [no,external:none], [],
++ [], [])
++
+ dnl # BeeCrypt
+ RPM_CHECK_LIB(
+ [BeeCrypt], [beecrypt],
+diff -urp lib/psm.c.orig lib/psm.c
+--- lib/psm.c.orig 2008-02-05 21:23:53.000000000 +0100
++++ lib/psm.c 2009-04-06 08:38:13.000000000 +0200
+@@ -2408,6 +2408,8 @@ psm->te->h = headerFree(psm->te->h);
+ t = stpcpy(t, ".bzdio");
+ if (!strcmp(payload_compressor, "lzma"))
+ t = stpcpy(t, ".lzdio");
++ if (!strcmp(payload_compressor, "xz"))
++ t = stpcpy(t, ".xzdio");
+ payload_compressor = _free(payload_compressor);
+
+ he->tag = RPMTAG_PAYLOADFORMAT;
+diff -urp lib/rpmds.c.orig lib/rpmds.c
+--- lib/rpmds.c.orig 2007-12-15 12:17:03.000000000 +0100
++++ lib/rpmds.c 2009-04-06 08:38:13.000000000 +0200
+@@ -1391,6 +1391,11 @@ static struct rpmlibProvides_s rpmlibPro
+ { "rpmlib(FileDigestParameterized)", "4.4.6-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
+ N_("file digests can be other than MD5.") },
++#if defined(HAVE_LZMA_H)
++ { "rpmlib(PayloadIsXz)", "5.2-1",
++ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
++ N_("package payload can be compressed using xz.") },
++#endif
+ { NULL, NULL, 0, NULL }
+ };
+
+diff -urp macros.in.orig macros.in
+--- macros.in.orig 2008-03-03 09:41:19.000000000 +0100
++++ macros.in 2009-07-29 10:13:06.000000000 +0200
+@@ -93,6 +93,7 @@
+ %__vcheck %{__perl} %{_rpmhome}/vcheck
+ %__wget @__WGET@
+ %__xar @__XAR@
++%__xz @__XZ@
+
+ #==============================================================================
+ # ---- Build system path macros.
+diff -urp rpmio/macro.c.orig rpmio/macro.c
+--- rpmio/macro.c.orig 2008-02-05 21:23:56.000000000 +0100
++++ rpmio/macro.c 2009-04-13 09:20:07.000000000 +0200
+@@ -1314,6 +1314,9 @@ doFoo(MacroBuf mb, int negate, const cha
+ case 5: /* COMPRESSED_LZMA */
+ sprintf(be, "%%__lzma -dc '%s'", b);
+ break;
++ case 6: /* COMPRESSED_XZ */
++ sprintf(be, "%%__xz -dc '%s'", b);
++ break;
+ }
+ b = be;
+ } else if (STREQ("mkstemp", f, fn)) {
+@@ -2414,6 +2417,10 @@ int isCompressed(const char * file, rpmC
+ magic[11] == (unsigned char) 0x00 && magic[12] == (unsigned char) 0x00) /* lzmash */
+ *compressed = COMPRESSED_LZMA;
+ else
++ if (magic[0] == (unsigned char) 0xFD && magic[1] == 0x37 && magic[2] == 0x7A
++ && magic[3] == 0x58 && magic[4] == 0x5A && magic[5] == 0x00) /* xz */
++ *compressed = COMPRESSED_XZ;
++ else
+ if ((magic[0] == (unsigned char) 0037 && magic[1] == (unsigned char) 0213) /* gzip */
+ || (magic[0] == (unsigned char) 0037 && magic[1] == (unsigned char) 0236) /* old gzip */
+ || (magic[0] == (unsigned char) 0037 && magic[1] == (unsigned char) 0036) /* pack */
+diff -urp rpmio/rpmio.c.orig rpmio/rpmio.c
+--- rpmio/rpmio.c.orig 2008-01-29 14:57:50.000000000 +0100
++++ rpmio/rpmio.c 2009-07-29 11:57:14.000000000 +0200
+@@ -216,6 +216,10 @@ static /*@observer@*/ const char * fdbg(
+ #endif
+ } else if (fps->io == lzdio) {
+ sprintf(be, "LZD %p fdno %d", fps->fp, fps->fdno);
++#if defined(HAVE_LZMA_H)
++ } else if (fps->io == xzdio) {
++ sprintf(be, "XZD %p fdno %d", fps->fp, fps->fdno);
++#endif
+ } else if (fps->io == fpio) {
+ /*@+voidabstract@*/
+ sprintf(be, "%s %p(%d) fdno %d",
+@@ -3079,6 +3083,422 @@ static struct FDIO_s lzdio_s = {
+ FDIO_t lzdio = /*@-compmempass@*/ &lzdio_s /*@=compmempass@*/ ;
+
+ /* =============================================================== */
++/* Support for LZMA compression library.
++ */
++#if defined(HAVE_LZMA_H)
++
++/* provide necessary defines for inclusion of <lzma.h>
++ similar to LZMAUtils's internal <common.h> and as
++ explicitly stated in the top-level comment of <lzma.h> */
++#ifndef UINT32_C
++# define UINT32_C(n) n ## U
++#endif
++#ifndef UINT32_MAX
++# define UINT32_MAX UINT32_C(4294967295)
++#endif
++#if SIZEOF_UNSIGNED_LONG == 4
++# ifndef UINT64_C
++# define UINT64_C(n) n ## ULL
++# endif
++#else
++# ifndef UINT64_C
++# define UINT64_C(n) n ## UL
++# endif
++#endif
++#ifndef UINT64_MAX
++# define UINT64_MAX UINT64_C(18446744073709551615)
++#endif
++
++#include "lzma.h"
++
++#ifndef LZMA_PRESET_DEFAULT
++#define LZMA_PRESET_DEFAULT UINT32_C(6)
++#endif
++
++/*@access FD_t @*/
++
++#define XZDONLY(fd) assert(fdGetIo(fd) == xzdio)
++
++#define kBufferSize (1 << 15)
++
++typedef struct xzfile {
++/*@only@*/
++ uint8_t buf[kBufferSize]; /*!< IO buffer */
++ lzma_stream strm; /*!< LZMA stream */
++/*@dependent@*/
++ FILE * fp;
++ int encoding;
++ int eof;
++} XZFILE;
++
++/*@-globstate@*/
++/*@null@*/
++static XZFILE *xzopen_internal(const char *path, const char *mode, int fdno, int xz)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ int level = LZMA_PRESET_DEFAULT;
++ int encoding = 0;
++ FILE *fp;
++ XZFILE *xzfile;
++ lzma_stream tmp;
++ lzma_ret ret;
++
++ for (; *mode != '\0'; mode++) {
++ if (*mode == 'w')
++ encoding = 1;
++ else if (*mode == 'r')
++ encoding = 0;
++ else if (*mode >= '0' && *mode <= '9')
++ level = (int)(*mode - '0');
++ }
++ if (fdno != -1)
++ fp = fdopen(fdno, encoding ? "w" : "r");
++ else
++ fp = fopen(path, encoding ? "w" : "r");
++ if (!fp)
++ return NULL;
++ xzfile = calloc(1, sizeof(*xzfile));
++ if (!xzfile) {
++ (void) fclose(fp);
++ return NULL;
++ }
++ xzfile->fp = fp;
++ xzfile->encoding = encoding;
++ xzfile->eof = 0;
++ tmp = (lzma_stream)LZMA_STREAM_INIT;
++ xzfile->strm = tmp;
++ if (encoding) {
++ if (xz) {
++ ret = lzma_easy_encoder(&xzfile->strm, level, LZMA_CHECK_CRC32);
++ } else {
++ lzma_options_lzma options;
++ (void) lzma_lzma_preset(&options, level);
++ ret = lzma_alone_encoder(&xzfile->strm, &options);
++ }
++ } else {
++ /* We set the memlimit for decompression to 100MiB which should be
++ * more than enough to be sufficient for level 9 which requires 65 MiB.
++ */
++ ret = lzma_auto_decoder(&xzfile->strm, 100<<20, 0);
++ }
++ if (ret != LZMA_OK) {
++ (void) fclose(fp);
++ memset(xzfile, 0, sizeof(*xzfile));
++ free(xzfile);
++ return NULL;
++ }
++ return xzfile;
++}
++/*@=globstate@*/
++
++/*@null@*/
++static XZFILE *xzopen(const char *path, const char *mode)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ return xzopen_internal(path, mode, -1, 1);
++}
++
++/*@null@*/
++static XZFILE *xzdopen(int fdno, const char *mode)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ if (fdno < 0)
++ return NULL;
++ return xzopen_internal(0, mode, fdno, 1);
++}
++
++static int xzflush(XZFILE *xzfile)
++ /*@globals fileSystem @*/
++ /*@modifies xzfile, fileSystem @*/
++{
++ return fflush(xzfile->fp);
++}
++
++static int xzclose(/*@only@*/ XZFILE *xzfile)
++ /*@globals fileSystem @*/
++ /*@modifies *xzfile, fileSystem @*/
++{
++ lzma_ret ret;
++ size_t n;
++ int rc;
++
++ if (!xzfile)
++ return -1;
++ if (xzfile->encoding) {
++ for (;;) {
++ xzfile->strm.avail_out = kBufferSize;
++ xzfile->strm.next_out = (uint8_t *)xzfile->buf;
++ ret = lzma_code(&xzfile->strm, LZMA_FINISH);
++ if (ret != LZMA_OK && ret != LZMA_STREAM_END)
++ return -1;
++ n = kBufferSize - xzfile->strm.avail_out;
++ if (n && fwrite(xzfile->buf, 1, n, xzfile->fp) != n)
++ return -1;
++ if (ret == LZMA_STREAM_END)
++ break;
++ }
++ }
++ lzma_end(&xzfile->strm);
++ rc = fclose(xzfile->fp);
++ memset(xzfile, 0, sizeof(*xzfile));
++ free(xzfile);
++ return rc;
++}
++
++/*@-mustmod@*/
++static ssize_t xzread(XZFILE *xzfile, void *buf, size_t len)
++ /*@globals fileSystem @*/
++ /*@modifies xzfile, *buf, fileSystem @*/
++{
++ lzma_ret ret;
++ int eof = 0;
++
++ if (!xzfile || xzfile->encoding)
++ return -1;
++ if (xzfile->eof)
++ return 0;
++/*@-temptrans@*/
++ xzfile->strm.next_out = buf;
++/*@=temptrans@*/
++ xzfile->strm.avail_out = len;
++ for (;;) {
++ if (!xzfile->strm.avail_in) {
++ xzfile->strm.next_in = (uint8_t *)xzfile->buf;
++ xzfile->strm.avail_in = fread(xzfile->buf, 1, kBufferSize, xzfile->fp);
++ if (!xzfile->strm.avail_in)
++ eof = 1;
++ }
++ ret = lzma_code(&xzfile->strm, LZMA_RUN);
++ if (ret == LZMA_STREAM_END) {
++ xzfile->eof = 1;
++ return len - xzfile->strm.avail_out;
++ }
++ if (ret != LZMA_OK)
++ return -1;
++ if (!xzfile->strm.avail_out)
++ return len;
++ if (eof)
++ return -1;
++ }
++ /*@notreached@*/
++}
++/*@=mustmod@*/
++
++static ssize_t xzwrite(XZFILE *xzfile, void *buf, size_t len)
++ /*@globals fileSystem @*/
++ /*@modifies xzfile, fileSystem @*/
++{
++ lzma_ret ret;
++ size_t n;
++
++ if (!xzfile || !xzfile->encoding)
++ return -1;
++ if (!len)
++ return 0;
++/*@-temptrans@*/
++ xzfile->strm.next_in = buf;
++/*@=temptrans@*/
++ xzfile->strm.avail_in = len;
++ for (;;) {
++ xzfile->strm.next_out = (uint8_t *)xzfile->buf;
++ xzfile->strm.avail_out = kBufferSize;
++ ret = lzma_code(&xzfile->strm, LZMA_RUN);
++ if (ret != LZMA_OK)
++ return -1;
++ n = kBufferSize - xzfile->strm.avail_out;
++ if (n && fwrite(xzfile->buf, 1, n, xzfile->fp) != n)
++ return -1;
++ if (!xzfile->strm.avail_in)
++ return len;
++ }
++ /*@notreached@*/
++}
++
++/* =============================================================== */
++
++static inline /*@dependent@*/ /*@null@*/ void * xzdFileno(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 != xzdio && fps->io != lzdio)
++ continue;
++ rc = fps->fp;
++ break;
++ }
++
++ return rc;
++}
++
++/*@-globuse@*/
++static /*@null@*/ FD_t xzdOpen(const char * path, const char * fmode)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ FD_t fd;
++ mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
++ XZFILE * xzfile = xzopen(path, fmode);
++
++ if (xzfile == NULL)
++ return NULL;
++ fd = fdNew("open (xzdOpen)");
++ fdPop(fd); fdPush(fd, xzdio, xzfile, -1);
++ fdSetOpen(fd, path, fileno(xzfile->fp), mode);
++ return fdLink(fd, "xzdOpen");
++}
++/*@=globuse@*/
++
++/*@-globuse@*/
++static /*@null@*/ FD_t xzdFdopen(void * cookie, const char * fmode)
++ /*@globals fileSystem, internalState @*/
++ /*@modifies fileSystem, internalState @*/
++{
++ FD_t fd = c2f(cookie);
++ int fdno = fdFileno(fd);
++ XZFILE *xzfile;
++
++assert(fmode != NULL);
++ fdSetFdno(fd, -1); /* XXX skip the fdio close */
++ if (fdno < 0) return NULL;
++ xzfile = xzdopen(fdno, fmode);
++ if (xzfile == NULL) return NULL;
++ fdPush(fd, xzdio, xzfile, fdno);
++ return fdLink(fd, "xzdFdopen");
++}
++/*@=globuse@*/
++
++/*@-globuse@*/
++static int xzdFlush(void * cookie)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ FD_t fd = c2f(cookie);
++ return xzflush(xzdFileno(fd));
++}
++/*@=globuse@*/
++
++/* =============================================================== */
++/*@-globuse@*/
++/*@-mustmod@*/ /* LCL: *buf is modified */
++static ssize_t xzdRead(void * cookie, /*@out@*/ char * buf, size_t count)
++ /*@globals fileSystem, internalState @*/
++ /*@modifies *buf, fileSystem, internalState @*/
++{
++ FD_t fd = c2f(cookie);
++ XZFILE *xzfile;
++ ssize_t rc = -1;
++
++assert(fd != NULL);
++ if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
++ xzfile = xzdFileno(fd);
++assert(xzfile != NULL);
++ fdstat_enter(fd, FDSTAT_READ);
++/*@-compdef@*/
++ rc = xzread(xzfile, buf, count);
++/*@=compdef@*/
++DBGIO(fd, (stderr, "==>\txzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
++ 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 xzdWrite(void * cookie, const char * buf, size_t count)
++ /*@globals fileSystem, internalState @*/
++ /*@modifies fileSystem, internalState @*/
++{
++ FD_t fd = c2f(cookie);
++ XZFILE *xzfile;
++ 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);
++
++ xzfile = xzdFileno(fd);
++
++ fdstat_enter(fd, FDSTAT_WRITE);
++ rc = xzwrite(xzfile, (void *)buf, count);
++DBGIO(fd, (stderr, "==>\txzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
++ if (rc < 0) {
++ fd->errcookie = "Lzma: encoding error";
++ } else if (rc > 0) {
++ fdstat_exit(fd, FDSTAT_WRITE, rc);
++ }
++ return rc;
++}
++
++static inline int xzdSeek(void * cookie, /*@unused@*/ _libio_pos_t pos,
++ /*@unused@*/ int whence)
++ /*@*/
++{
++ FD_t fd = c2f(cookie);
++
++ XZDONLY(fd);
++ return -2;
++}
++
++static int xzdClose( /*@only@*/ void * cookie)
++ /*@globals fileSystem, internalState @*/
++ /*@modifies fileSystem, internalState @*/
++{
++ FD_t fd = c2f(cookie);
++ XZFILE *xzfile;
++ const char * errcookie;
++ int rc;
++
++ xzfile = xzdFileno(fd);
++
++ if (xzfile == NULL) return -2;
++ errcookie = strerror(ferror(xzfile->fp));
++
++ fdstat_enter(fd, FDSTAT_CLOSE);
++ /*@-dependenttrans@*/
++ rc = xzclose(xzfile);
++ /*@=dependenttrans@*/
++ fdstat_exit(fd, FDSTAT_CLOSE, rc);
++
++ if (fd && rc == -1)
++ fd->errcookie = errcookie;
++
++DBGIO(fd, (stderr, "==>\txzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
++
++ if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "XZDIO", stderr);
++ /*@-branchstate@*/
++ if (rc == 0)
++ fd = fdFree(fd, "open (xzdClose)");
++ /*@=branchstate@*/
++ return rc;
++}
++
++/*@-type@*/ /* LCL: function typedefs */
++static struct FDIO_s xzdio_s = {
++ xzdRead, xzdWrite, xzdSeek, xzdClose, xzdOpen, xzdFdopen, xzdFlush,
++};
++/*@=type@*/
++
++FDIO_t xzdio = /*@-compmempass@*/ &xzdio_s /*@=compmempass@*/ ;
++
++#endif /* HAVE_LZMA_H */
++
++/* =============================================================== */
+ /*@observer@*/
+ static const char * getFdErrstr (FD_t fd)
+ /*@*/
+@@ -3099,6 +3519,11 @@ static const char * getFdErrstr (FD_t fd
+ if (fdGetIo(fd) == lzdio) {
+ errstr = fd->errcookie;
+ } else
++#ifdef HAVE_LZMA_H
++ if (fdGetIo(fd) == xzdio) {
++ errstr = fd->errcookie;
++ } else
++#endif
+ {
+ errstr = (fd->syserrno ? strerror(fd->syserrno) : "");
+ }
+@@ -3416,6 +3841,11 @@ fprintf(stderr, "*** Fdopen(%p,%s) %s\n"
+ } else if (!strcmp(end, "lzdio")) {
+ iof = lzdio;
+ fd = lzdFdopen(fd, zstdio);
++#if defined(HAVE_LZMA_H)
++ } else if (!strcmp(end, "xzdio")) {
++ iof = xzdio;
++ fd = xzdFdopen(fd, zstdio);
++#endif
+ } else if (!strcmp(end, "ufdio")) {
+ iof = ufdio;
+ } else if (!strcmp(end, "fpio")) {
+@@ -3568,6 +3998,10 @@ int Fflush(FD_t fd)
+ if (vh && fdGetIo(fd) == bzdio)
+ return bzdFlush(vh);
+ #endif
++#if defined(HAVE_LZMA_H)
++ if (vh && fdGetIo(fd) == xzdio)
++ return xzdFlush(vh);
++#endif
+
+ return 0;
+ }
+@@ -3602,6 +4036,11 @@ int Ferror(FD_t fd)
+ } else if (fps->io == lzdio) {
+ ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
+ i--; /* XXX fdio under lzdio always has fdno == -1 */
++#if defined(HAVE_LZMA_H)
++ } else if (fps->io == xzdio) {
++ ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
++ i--; /* XXX fdio under xzdio always has fdno == -1 */
++#endif
+ } else {
+ /* XXX need to check ufdio/gzdio/bzdio/fdio errors correctly. */
+ ec = (fdFileno(fd) < 0 ? -1 : 0);
+diff -urp rpmio/rpmio.h.orig rpmio/rpmio.h
+--- rpmio/rpmio.h.orig 2007-12-09 14:04:30.000000000 +0100
++++ rpmio/rpmio.h 2009-04-06 08:38:33.000000000 +0200
+@@ -793,6 +793,10 @@ int ufdGetFile( /*@killref@*/ FD_t sfd,
+
+ /**
+ */
++/*@observer@*/ /*@unchecked@*/ extern FDIO_t xzdio;
++
++/**
++ */
+ /*@observer@*/ /*@unchecked@*/ extern FDIO_t fadio;
+ /*@=exportlocal@*/
+ /*@}*/
+diff -urp rpmio/rpmmacro.h.orig rpmio/rpmmacro.h
+--- rpmio/rpmmacro.h.orig 2008-01-29 14:57:50.000000000 +0100
++++ rpmio/rpmmacro.h 2009-04-06 08:38:33.000000000 +0200
+@@ -208,7 +208,8 @@ typedef enum rpmCompressedMagic_e {
+ COMPRESSED_BZIP2 = 2, /*!< bzip2 can handle */
+ COMPRESSED_ZIP = 3, /*!< unzip can handle */
+ COMPRESSED_LZOP = 4, /*!< lzop can handle */
+- COMPRESSED_LZMA = 5 /*!< lzma can handle */
++ COMPRESSED_LZMA = 5, /*!< lzma can handle */
++ COMPRESSED_XZ = 6 /*!< xz can handle */
+ } rpmCompressedMagic;
+
+ /**
+diff -urp tools/rpm2cpio.c.orig tools/rpm2cpio.c
+--- tools/rpm2cpio.c.orig 2007-12-09 14:04:30.000000000 +0100
++++ tools/rpm2cpio.c 2009-04-06 08:38:33.000000000 +0200
+@@ -89,6 +89,8 @@ int main(int argc, char **argv)
+ t = stpcpy(t, ".bzdio");
+ if (!strcmp(payload_compressor, "lzma"))
+ t = stpcpy(t, ".lzdio");
++ if (!strcmp(payload_compressor, "xz"))
++ t = stpcpy(t, ".xzdio");
+ he->p.ptr = _free(he->p.ptr);
+ }
+