--- /dev/null
+diff -Nru rpm-4.4.5.old/build/pack.c rpm-4.4.5/build/pack.c
+--- rpm-4.4.5.old/build/pack.c 2005-12-09 11:07:42.000000000 +0100
++++ rpm-4.4.5/build/pack.c 2006-04-22 22:00:58.000000000 +0200
+@@ -499,6 +499,12 @@
+ /* 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.6-1");
++ }
++
+ strcpy(buf, rpmio_flags);
+ buf[s - rpmio_flags] = '\0';
+ (void) headerAddEntry(h, RPMTAG_PAYLOADFLAGS, RPM_STRING_TYPE, buf+1, 1);
+diff -Nru rpm-4.4.5.old/lib/psm.c rpm-4.4.5/lib/psm.c
+--- rpm-4.4.5.old/lib/psm.c 2006-04-22 15:02:52.000000000 +0200
++++ rpm-4.4.5/lib/psm.c 2006-04-22 17:18:55.000000000 +0200
+@@ -2154,6 +2154,8 @@
+ t = stpcpy(t, ".gzdio");
+ if (!strcmp(payload_compressor, "bzip2"))
+ t = stpcpy(t, ".bzdio");
++ if (!strcmp(payload_compressor, "lzma"))
++ t = stpcpy(t, ".lzdio");
+
+ /*@-branchstate@*/
+ if (!hge(fi->h, RPMTAG_PAYLOADFORMAT, NULL,
+diff -Nru rpm-4.4.5.old/lib/rpmds.c rpm-4.4.5/lib/rpmds.c
+--- rpm-4.4.5.old/lib/rpmds.c 2005-12-09 10:52:23.000000000 +0100
++++ rpm-4.4.5/lib/rpmds.c 2006-04-22 22:04:23.000000000 +0200
+@@ -1324,6 +1324,9 @@
+ { "rpmlib(PayloadIsUstar)", "4.4.4-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
+ N_("package payload can be in ustar tar archive format.") },
++ { "rpmlib(PayloadIsLzma)", "4.4.6-1",
++ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
++ N_("package payload can be compressed using lzma.") },
+ { NULL, NULL, 0, NULL }
+ };
+
+diff -Nru rpm-4.4.5.old/rpm2cpio.c rpm-4.4.5/rpm2cpio.c
+--- rpm-4.4.5.old/rpm2cpio.c 2005-01-17 19:46:16.000000000 +0100
++++ rpm-4.4.5/rpm2cpio.c 2006-04-22 17:18:55.000000000 +0200
+@@ -76,6 +76,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 */
+diff -Nru rpm-4.4.5.old/rpmio/librpmio.vers rpm-4.4.5/rpmio/librpmio.vers
+--- rpm-4.4.5.old/rpmio/librpmio.vers 2005-11-01 14:37:40.000000000 +0100
++++ rpm-4.4.5/rpmio/librpmio.vers 2006-04-22 17:18:55.000000000 +0200
+@@ -85,6 +85,7 @@
+ isCompressed;
+ Link;
+ Lstat;
++ lzdio;
+ max_macro_depth;
+ Mkdir;
+ noLibio;
+diff -Nru rpm-4.4.5.old/rpmio/Makefile.am rpm-4.4.5/rpmio/Makefile.am
+--- rpm-4.4.5.old/rpmio/Makefile.am 2006-04-22 15:02:56.000000000 +0200
++++ rpm-4.4.5/rpmio/Makefile.am 2006-04-23 13:31:09.000000000 +0200
+@@ -22,14 +22,14 @@
+ argv.h fts.h rpmdav.h \
+ rpmio.h rpmurl.h rpmmacro.h rpmlog.h rpmmessages.h rpmerr.h rpmpgp.h \
+ rpmsq.h rpmsw.h ugid.h
+-noinst_HEADERS = rpmio_internal.h rpmlua.h rpmhook.h
++noinst_HEADERS = LzmaDecode.h rpmio_internal.h rpmlua.h rpmhook.h
+
+ BEECRYPTLOBJS = $(shell test X"@WITH_BEECRYPT_SUBDIR@" != X && cat $(top_builddir)/@WITH_BEECTYPT_SUBDIR@/listobjs)
+
+ usrlibdir = $(libdir)@MARK64@
+ usrlib_LTLIBRARIES = librpmio.la
+ librpmio_la_SOURCES = \
+- argv.c digest.c fts.c macro.c rpmdav.c \
++ LzmaDecode.c argv.c digest.c fts.c macro.c rpmdav.c \
+ rpmhook.c rpmio.c rpmlog.c rpmlua.c rpmmalloc.c \
+ rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c strtolocale.c \
+ stubs.c url.c ugid.c
+diff -Nru rpm-4.4.5.old/rpmio/rpmio.c rpm-4.4.5/rpmio/rpmio.c
+--- rpm-4.4.5.old/rpmio/rpmio.c 2006-04-22 15:02:55.000000000 +0200
++++ rpm-4.4.5/rpmio/rpmio.c 2006-04-23 14:43:10.000000000 +0200
+@@ -82,6 +82,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) */
+
+@@ -182,6 +183,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",
+@@ -2370,6 +2373,327 @@
+ /*@=moduncon@*/
+ #endif /* HAVE_BZLIB_H */
+
++#include "LzmaDecode.h"
++
++#define kInBufferSize (1 << 15)
++typedef struct _CBuffer
++{
++ ILzmaInCallback InCallback;
++ FILE *File;
++ unsigned char Buffer[kInBufferSize];
++} CBuffer;
++
++typedef struct lzfile {
++ CBuffer g_InBuffer;
++ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
++ unsigned char properties[LZMA_PROPERTIES_SIZE];
++
++// FILE *file;
++ int pid;
++} LZFILE;
++
++static size_t MyReadFile(FILE *file, void *data, size_t size)
++{
++ if (size == 0) return 0;
++ return fread(data, 1, size, file);
++}
++
++static int MyReadFileAndCheck(FILE *file, void *data, size_t size)
++{
++ return (MyReadFile(file, data, size) == size);
++}
++
++static int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
++{
++ CBuffer *b = (CBuffer *)object;
++ *buffer = b->Buffer;
++ *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize);
++ return LZMA_RESULT_OK;
++}
++
++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;
++}
++
++static FD_t lzdWriteOpen(int fdno, int fopen)
++{
++ int pid;
++ int p[2];
++
++ if (fdno < 0) return NULL;
++ if (pipe(p) < 0) {
++ close(fdno);
++ return NULL;
++ }
++ pid = fork();
++ if (pid < 0) {
++ close(fdno);
++ return NULL;
++ }
++ if (pid) {
++ FD_t fd;
++ LZFILE *lzfile;
++
++ close(fdno);
++ close(p[0]);
++ lzfile = calloc(1, sizeof(*lzfile));
++ if (lzfile == NULL) return NULL;
++ lzfile->g_InBuffer.File = fdopen(p[1], "wb");
++ lzfile->pid = pid;
++ if (lzfile->g_InBuffer.File == NULL) {
++ close(p[1]);
++ free(lzfile);
++ return NULL;
++ }
++ fd = fdNew("open (lzdOpen write)");
++ if (fopen) fdPop(fd);
++ fdPush(fd, lzdio, lzfile, -1);
++ return fdLink(fd, "lzdOpen");
++ } else {
++ int i;
++ /* lzma */
++ close(p[1]);
++ dup2(p[0], 0);
++ dup2(fdno, 1);
++ for (i = 3; i < 1024; i++) close(i);
++ if (execlp("lzma", "lzma", "e", "-si", "-so", NULL)) {
++ _exit(1);
++ }
++ }
++ return NULL; /* warning */
++}
++
++static FD_t lzdReadOpen(int fdno, int fopen)
++{
++ LZFILE *lzfile;
++ unsigned char ff[8];
++ FD_t fd;
++
++ if (fdno < 0) return NULL;
++ lzfile = calloc(1, sizeof(*lzfile));
++ if (lzfile == NULL) return NULL;
++ lzfile->g_InBuffer.File = fdopen(fdno, "rb");
++ if (lzfile->g_InBuffer.File == NULL) goto error2;
++
++ if (!MyReadFileAndCheck(lzfile->g_InBuffer.File, lzfile->properties, sizeof(lzfile->properties))) {
++error:
++ fclose(lzfile->g_InBuffer.File);
++error2:
++ free(lzfile);
++ return NULL;
++ }
++ if (!MyReadFileAndCheck(lzfile->g_InBuffer.File, ff, 8)) goto error;
++ if (LzmaDecodeProperties(&lzfile->state.Properties, lzfile->properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
++ goto error;
++ lzfile->state.Probs = (CProb *)malloc(LzmaGetNumProbs(&lzfile->state.Properties) * sizeof(CProb));
++ if (lzfile->state.Probs == NULL) goto error;
++
++ if (lzfile->state.Properties.DictionarySize == 0)
++ lzfile->state.Dictionary = 0;
++ else {
++ lzfile->state.Dictionary = (unsigned char *)malloc(lzfile->state.Properties.DictionarySize);
++ if (lzfile->state.Dictionary == NULL) {
++ free(lzfile->state.Probs);
++ goto error;
++ }
++ }
++ lzfile->g_InBuffer.InCallback.Read = LzmaReadCompressed;
++ LzmaDecoderInit(&lzfile->state);
++
++ fd = fdNew("open (lzdOpen read)");
++ if (fopen) fdPop(fd);
++ fdPush(fd, lzdio, lzfile, -1);
++ return fdLink(fd, "lzdOpen");
++}
++
++/*@-globuse@*/
++static /*@null@*/ FD_t lzdOpen(const char * path, const char * mode)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ if (mode == NULL)
++ return NULL;
++ if (mode[0] == 'w') {
++ int fdno = open(path, O_WRONLY);
++
++ if (fdno < 0) return NULL;
++ return lzdWriteOpen(fdno, 1);
++ } else {
++ int fdno = open(path, O_RDONLY);
++
++ if (fdno < 0) return NULL;
++ return lzdReadOpen(fdno, 1);
++ }
++}
++/*@=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;
++
++ if (fmode == NULL) return NULL;
++ fdno = fdFileno(fd);
++ fdSetFdno(fd, -1); /* XXX skip the fdio close */
++ if (fdno < 0) return NULL;
++ if (fmode[0] == 'w') {
++ return lzdWriteOpen(fdno, 0);
++ } else {
++ return lzdReadOpen(fdno, 0);
++ }
++}
++/*@=globuse@*/
++
++/*@-globuse@*/
++static int lzdFlush(FD_t fd)
++ /*@globals fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ LZFILE *lzfile = lzdFileno(fd);
++
++ if (lzfile == NULL || lzfile->g_InBuffer.File == NULL) return -2;
++ return fflush(lzfile->g_InBuffer.File);
++}
++/*@=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;
++ int res = 0;
++
++ if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
++ lzfile = lzdFileno(fd);
++ fdstat_enter(fd, FDSTAT_READ);
++ if (lzfile->g_InBuffer.File)
++ /*@-compdef@*/
++ res = LzmaDecode(&lzfile->state, &lzfile->g_InBuffer.InCallback, buf, count, &rc);
++ /*@=compdef@*/
++ if (res) {
++ if (lzfile)
++ 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;
++
++ if (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 = fwrite((void *)buf, 1, count, lzfile->g_InBuffer.File);
++ if (rc == -1) {
++ fd->errcookie = strerror(ferror(lzfile->g_InBuffer.File));
++ } else if (rc > 0) {
++ fdstat_exit(fd, FDSTAT_WRITE, rc);
++ }
++ return rc;
++}
++/*@=globuse@*/
++
++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);
++ /*@-noeffectuncon@*/ /* FIX: check rc */
++ fclose(lzfile->g_InBuffer.File);
++ if (lzfile->pid) wait4(lzfile->pid, NULL, 0, NULL);
++ else { /* reading */
++ free(lzfile->state.Probs);
++ if (lzfile->state.Dictionary) free(lzfile->state.Dictionary);
++ }
++ free(lzfile);
++ /*@=noeffectuncon@*/
++ rc = 0; /* XXX FIXME */
++
++ /* XXX TODO: preserve fd if errors */
++
++ if (fd) {
++ if (rc == -1) {
++ fd->errcookie = strerror(ferror(lzfile->g_InBuffer.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)
+@@ -2388,7 +2712,9 @@
+ errstr = fd->errcookie;
+ } else
+ #endif /* HAVE_BZLIB_H */
+-
++ if (fdGetIo(fd) == lzdio) {
++ errstr = fd->errcookie;
++ } else
+ {
+ errstr = (fd->syserrno ? strerror(fd->syserrno) : "");
+ }
+@@ -2683,6 +3009,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")) {
+@@ -2849,6 +3178,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);
+diff -Nru rpm-4.4.5.old/rpmio/rpmio.h rpm-4.4.5/rpmio/rpmio.h
+--- rpm-4.4.5.old/rpmio/rpmio.h 2005-11-04 00:19:54.000000000 +0100
++++ rpm-4.4.5/rpmio/rpmio.h 2006-04-22 17:18:55.000000000 +0200
+@@ -673,6 +673,10 @@
+
+ /**
+ */
++/*@observer@*/ /*@unchecked@*/ extern FDIO_t lzdio;
++
++/**
++ */
+ /*@observer@*/ /*@unchecked@*/ extern FDIO_t fadio;
+ /*@=exportlocal@*/
+ /*@}*/
+diff -Nru rpm-4.4.5.old/tools/rpmtool.c rpm-4.4.5/tools/rpmtool.c
+--- rpm-4.4.5.old/tools/rpmtool.c 2005-01-17 19:46:27.000000000 +0100
++++ rpm-4.4.5/tools/rpmtool.c 2006-04-22 17:18:55.000000000 +0200
+@@ -87,7 +87,8 @@
+ RPMIOBITS_UNCOMPRESS= (1 << 8),
+ RPMIOBITS_BINARY = (1 << 9),
+ RPMIOBITS_DUMP = (1 << 10),
+- RPMIOBITS_XML = (1 << 11)
++ RPMIOBITS_XML = (1 << 11),
++ RPMIOBITS_LZDIO = (1 << 16),
+ } rpmtoolIOBits;
+
+ static const char * iav[] = { "-", NULL };
+@@ -118,12 +119,13 @@
+ { "gzdio", RPMIOBITS_GZDIO },
+ { "bzdio", RPMIOBITS_BZDIO },
+ #define _RPMIOBITS_MODEMASK \
+- (RPMIOBITS_FDIO|RPMIOBITS_UFDIO|RPMIOBITS_GZDIO|RPMIOBITS_BZDIO)
++ (RPMIOBITS_FDIO|RPMIOBITS_UFDIO|RPMIOBITS_GZDIO|RPMIOBITS_BZDIO|RPMIOBITS_LZDIO)
+
+ { "uncompress", RPMIOBITS_UNCOMPRESS },
+ { "binary", RPMIOBITS_BINARY },
+ { "dump", RPMIOBITS_DUMP },
+ { "xml", RPMIOBITS_XML },
++ { "lzdio", RPMIOBITS_LZDIO },
+ { NULL, 0 },
+ };
+
+@@ -450,6 +452,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 */
+ if (gzdi == NULL) {