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.") }, { "rpmlib(FileDigestParameterized)", "4.4.6-1", (RPMSENSE_RPMLIB|RPMSENSE_EQUAL), N_("file digests can be other than MD5.") }, 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 @@ -24,7 +24,7 @@ rpmio.h rpmurl.h rpmmacro.h rpmlog.h rpmmessages.h rpmerr.h rpmpgp.h \ rpmsq.h rpmsw.h ugid.h noinst_HEADERS = md2.h md4.h rmd128.h rmd160.h tiger.h \ - rpmio_internal.h rpmlua.h rpmhook.h + LzmaDecode.h rpmio_internal.h rpmlua.h rpmhook.h BEECRYPTLOBJS = $(shell test X"@WITH_BEECRYPT_SUBDIR@" != X && cat $(top_builddir)/@WITH_BEECTYPT_SUBDIR@/listobjs) @@ -34,7 +34,8 @@ argv.c digest.c fts.c macro.c md2.c md4.c rmd128.c rmd160.c tiger.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 + stubs.c url.c ugid.c \ + LzmaDecode.c librpmio_la_LDFLAGS = -no-undefined -release $(LT_CURRENT).$(LT_REVISION) $(LDFLAGS) \ @WITH_BEECRYPT_LIB@ \ @WITH_NEON_LIB@ \ 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 (execl("/usr/bin/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) {