Add support for "lzma alone" compression format (lzdio)
authorPanu Matilainen <pmatilai@redhat.com>
Wed, 18 Mar 2009 09:24:52 +0000 (11:24 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Wed, 18 Mar 2009 09:24:52 +0000 (11:24 +0200)
- "lzma alone" is superseeded by XZ but it's used by Suse and Mandriva
  distros so it's nice to have as it doesn't need much, only open differs
  from XZ
- rpmlib() dependency versions are an uuuuuuuugly mess here: Suse used
  "PayloadIsLzma = 4.4.2-1" so that's what we provide to be most compatible
  (hopefully). Built packages require "PayloadIsLzma <= 4.4.6-1" however
  to be compatible with Mandriva 2008.0. Did I already say it's ugly?
- Based on similar patch in Mandriva by Per Ã˜yvind Karlsen, but avoiding
  unnecessary renames in rpmio

build/pack.c
lib/psm.c
lib/rpmds.c
macros.in
rpm2cpio.c
rpmio/rpmio.c

index 31350e9..b872995 100644 (file)
@@ -388,6 +388,9 @@ rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
        } else if (strcmp(s+1, "xzdio") == 0) {
            compr = "xz";
            (void) rpmlibNeedsFeature(h, "PayloadIsXz", "5.2-1");
+       } else if (strcmp(s+1, "lzdio") == 0) {
+           compr = "lzma";
+           (void) rpmlibNeedsFeature(h, "PayloadIsLzma", "4.4.6-1");
        } else {
            rpmlog(RPMLOG_ERR, _("Unknown payload compression: %s\n"),
                   rpmio_flags);
index cfb42a8..a13f439 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -1609,6 +1609,8 @@ rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
            psm->rpmio_flags = "r.bzdio";
        if (!strcmp(payload_compressor, "xz"))
            psm->rpmio_flags = "r.xzdio";
+       if (!strcmp(payload_compressor, "lzma"))
+           psm->rpmio_flags = "r.lzdio";
        rpmtdFreeData(&pc);
        headerFree(h);
 
index 39649db..ba02ee3 100644 (file)
@@ -974,6 +974,9 @@ static const struct rpmlibProvides_s rpmlibProvides[] = {
     { "rpmlib(PayloadIsXz)",           "5.2-1",
        (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
     N_("package payload can be compressed using xz.") },
+    { "rpmlib(PayloadIsLzma)",         "4.4.2-1",
+       (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
+    N_("package payload can be compressed using lzma.") },
 #endif
     { "rpmlib(PayloadFilesHavePrefix)",        "4.0-1",
        (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
index 1c96068..aaa71ee 100644 (file)
--- a/macros.in
+++ b/macros.in
@@ -324,6 +324,7 @@ package or when debugging this package.\
 #              "w9.gzdio"      gzip level 9 (default).
 #              "w9.bzdio"      bzip2 level 9.
 #              "w7.xzdio"      xz level 7, xz's default.
+#              "w7.lzdio"      lzma-alone level 7, lzma's default
 #
 #%_source_payload      w9.gzdio
 #%_binary_payload      w9.gzdio
index cdf36b1..eabefa1 100644 (file)
@@ -80,6 +80,8 @@ int main(int argc, char *argv[])
            rpmio_flags = "r.bzdio";
        if (!strcmp(payload_compressor, "xz"))
            rpmio_flags = "r.xzdio";
+       if (!strcmp(payload_compressor, "lzma"))
+           rpmio_flags = "r.lzdio";
        rpmtdFreeData(&pc);
     }
 
index d471433..c704030 100644 (file)
@@ -36,7 +36,7 @@ extern int h_errno;
 #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) == xzdio)
+#define        LZDONLY(fd)     assert(fdGetIo(fd) == xzdio || fdGetIo(fd) == lzdio)
 
 #define        UFDONLY(fd)     /* assert(fdGetIo(fd) == ufdio) */
 
@@ -92,6 +92,7 @@ static const FDIO_t ufdio;
 static const FDIO_t gzdio;
 static const FDIO_t bzdio;
 static const FDIO_t xzdio;
+static const FDIO_t lzdio;
 
 /**
  */
@@ -142,6 +143,8 @@ static const char * fdbg(FD_t fd)
 #if HAVE_LZMA_H
        } else if (fps->io == xzdio) {
            sprintf(be, "XZD %p fdno %d", fps->fp, fps->fdno);
+       } else if (fps->io == lzdio) {
+           sprintf(be, "LZD %p fdno %d", fps->fp, fps->fdno);
 #endif
        } else if (fps->io == fpio) {
            sprintf(be, "%s %p(%d) fdno %d",
@@ -1162,7 +1165,7 @@ static const char * getFdErrstr (FD_t fd)
     } else
 #endif /* HAVE_BZLIB_H */
 #ifdef HAVE_LZMA_H
-    if (fdGetIo(fd) == xzdio) {
+    if (fdGetIo(fd) == xzdio || fdGetIo(fd) == lzdio) {
        errstr = fd->errcookie;
     } else
 #endif /* HAVE_LZMA_H */
@@ -1198,7 +1201,7 @@ typedef struct lzfile {
 
 } LZFILE;
 
-static LZFILE *lzopen_internal(const char *path, const char *mode, int fd)
+static LZFILE *lzopen_internal(const char *path, const char *mode, int fd, int xz)
 {
     int level = 7;     /* Use XZ's default compression level if unspecified */
     int encoding = 0;
@@ -1232,7 +1235,13 @@ static LZFILE *lzopen_internal(const char *path, const char *mode, int fd)
     lzfile->eof = 0;
     lzfile->strm = init_strm;
     if (encoding) {
-       ret = lzma_easy_encoder(&lzfile->strm, level, LZMA_CHECK_SHA256);
+       if (xz) {
+           ret = lzma_easy_encoder(&lzfile->strm, level, LZMA_CHECK_SHA256);
+       } else {
+           lzma_options_lzma options;
+           lzma_lzma_preset(&options, level);
+           ret = lzma_alone_encoder(&lzfile->strm, &options);
+       }
     } else {   /* lzma_easy_decoder_memusage(level) is not ready yet, use hardcoded limit for now */
        ret = lzma_auto_decoder(&lzfile->strm, 100<<20, 0);
     }
@@ -1244,16 +1253,28 @@ static LZFILE *lzopen_internal(const char *path, const char *mode, int fd)
     return lzfile;
 }
 
+static LZFILE *xzopen(const char *path, const char *mode)
+{
+    return lzopen_internal(path, mode, -1, 1);
+}
+
+static LZFILE *xzdopen(int fd, const char *mode)
+{
+    if (fd < 0)
+       return 0;
+    return lzopen_internal(0, mode, fd, 1);
+}
+
 static LZFILE *lzopen(const char *path, const char *mode)
 {
-    return lzopen_internal(path, mode, -1);
+    return lzopen_internal(path, mode, -1, 0);
 }
 
 static LZFILE *lzdopen(int fd, const char *mode)
 {
     if (fd < 0)
        return 0;
-    return lzopen_internal(0, mode, fd);
+    return lzopen_internal(0, mode, fd, 0);
 }
 
 static int lzflush(LZFILE *lzfile)
@@ -1355,7 +1376,7 @@ static inline void * lzdFileno(FD_t fd)
     FDSANE(fd);
     for (i = fd->nfps; i >= 0; i--) {
            FDSTACK_t * fps = &fd->fps[i];
-           if (fps->io != xzdio)
+           if (fps->io != xzdio && fps->io != lzdio)
                continue;
            rc = fps->fp;
        break;
@@ -1364,6 +1385,33 @@ static inline void * lzdFileno(FD_t fd)
     return rc;
 }
 
+static FD_t xzdOpen(const char * path, const char * mode)
+{
+    FD_t fd;
+    LZFILE *lzfile;
+    if ((lzfile = xzopen(path, mode)) == NULL)
+       return NULL;
+    fd = fdNew("open (xzdOpen)");
+    fdPop(fd); fdPush(fd, xzdio, lzfile, -1);
+    return fdLink(fd, "xzdOpen");
+}
+
+static FD_t xzdFdopen(void * cookie, const char * fmode)
+{
+    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 = xzdopen(fdno, fmode);
+    if (lzfile == NULL) return NULL;
+    fdPush(fd, xzdio, lzfile, fdno);
+    return fdLink(fd, "xzdFdopen");
+}
+
 static FD_t lzdOpen(const char * path, const char * mode)
 {
     FD_t fd;
@@ -1479,11 +1527,16 @@ DBGIO(fd, (stderr, "==>\tlzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, f
 
 static struct FDIO_s xzdio_s = {
   lzdRead, lzdWrite, lzdSeek, lzdClose, NULL, NULL, NULL, fdFileno,
-  NULL, lzdOpen, lzdFileno, lzdFlush
+  NULL, xzdOpen, lzdFileno, lzdFlush
 };
-
 static const FDIO_t xzdio = &xzdio_s;
 
+static struct FDIO_s lzdio_s = {
+  lzdRead, lzdWrite, lzdSeek, lzdClose, NULL, NULL, NULL, fdFileno,
+  NULL, lzdOpen, lzdFileno, lzdFlush
+};
+static const FDIO_t lzdio = &lzdio_s;
+
 #endif /* HAVE_LZMA_H */
 
 /* =============================================================== */
@@ -1721,6 +1774,9 @@ fprintf(stderr, "*** Fdopen(%p,%s) %s\n", fd, fmode, fdbg(fd));
 #if HAVE_LZMA_H
        } else if (!strcmp(end, "xzdio")) {
            iof = xzdio;
+           fd = xzdFdopen(fd, zstdio);
+       } else if (!strcmp(end, "lzdio")) {
+           iof = lzdio;
            fd = lzdFdopen(fd, zstdio);
 #endif
        } else if (!strcmp(end, "ufdio")) {
@@ -1850,7 +1906,7 @@ int Fflush(FD_t fd)
        return bzdFlush(vh);
 #endif
 #if HAVE_LZMA_H
-    if (vh && fdGetIo(fd) == xzdio)
+    if (vh && (fdGetIo(fd) == xzdio || fdGetIo(fd) == lzdio))
        return lzdFlush(vh);
 #endif
 /* FIXME: If we get here, something went wrong above */
@@ -1879,9 +1935,9 @@ int Ferror(FD_t fd)
            i--;        /* XXX fdio under bzdio always has fdno == -1 */
 #endif
 #if HAVE_LZMA_H
-       } else if (fps->io == xzdio) {
+       } else if (fps->io == xzdio || fps->io == lzdio) {
            ec = (fd->syserrno  || fd->errcookie != NULL) ? -1 : 0;
-           i--;        /* XXX fdio under xzdio always has fdno == -1 */
+           i--;        /* XXX fdio under xzdio/lzdio always has fdno == -1 */
 #endif
        } else {
        /* XXX need to check ufdio/gzdio/bzdio/fdio errors correctly. */