File deltarpm.lzma.diff of Package deltarpm

diff -ur Makefile.orig Makefile
--- Makefile.orig	2007-03-06 14:35:55.000000000 +0100
+++ Makefile	2008-04-22 13:39:58.000000000 +0200
@@ -5,7 +5,7 @@
 zlibdir=zlib-1.2.2.f-rsyncable
 CFLAGS = -O2 -Wall
 CPPFLAGS = -DDELTARPM_64BIT -DBSDIFF_NO_SUF -DRPMDUMPHEADER=\"$(rpmdumpheader)\" -I$(zlibdir)
-LDLIBS = -lbz2 $(zlibdir)/libz.a
+LDLIBS = -lbz2 $(zlibdir)/libz.a -llzma
 LDFLAGS =
 
 all: makedeltarpm applydeltarpm rpmdumpheader makedeltaiso applydeltaiso combinedeltarpm fragiso
@@ -19,7 +19,7 @@
 rpmdumpheader: rpmdumpheader.o
 	$(CC) $(LDFLAGS) $^ -lrpm -o $@
 
-makedeltaiso: makedeltaiso.o delta.o rpmoffs.o util.o md5.o cfile.o $(zlibdir)/libz.a
+makedeltaiso: makedeltaiso.o delta.o rpmoffs.o rpmhead.o util.o md5.o cfile.o $(zlibdir)/libz.a
 
 applydeltaiso: applydeltaiso.o util.o md5.o cfile.o $(zlibdir)/libz.a
 
diff -ur applydeltaiso.c.orig applydeltaiso.c
--- applydeltaiso.c.orig	2005-06-13 19:53:20.000000000 +0200
+++ applydeltaiso.c	2008-04-22 13:56:15.000000000 +0200
@@ -10,9 +10,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 
 #include <zlib.h>
 #include <bzlib.h>
+#include <lzma.h>
 
 #include "util.h"
 #include "md5.h"
@@ -73,18 +75,6 @@
 
 void applydelta(FILE *fpold, struct cfile *ocf, struct cfile *cf, unsigned char *outdata, unsigned int outlen, unsigned int *nmp, int nmpn);
 
-char *
-comp2str(int comp)
-{
-  if (comp == CFILE_COMP_UN)
-    return "uncomp.";
-  if (comp == CFILE_COMP_GZ)
-    return "gzip";
-  if (comp == CFILE_COMP_BZ)
-    return "bzip";
-  return "???";
-}
-
 void
 processrpm(FILE *fpold, struct cfile *ocf, struct cfile *cf, unsigned int *nmp, int nmpn)
 {
@@ -102,6 +92,8 @@
       exit(1);
     }
   ctype = namebuf[0];
+  if (ctype < 254)
+    ctype = CFILE_MKCOMP(ctype & 15, ctype >> 4);
   i = namebuf[1];
   if (cf->read(cf, namebuf, i) != i)
     {
@@ -136,7 +128,7 @@
   if (ctype == 254)
     printf("%s: copying unchanged payload\n", namebuf);
   else
-    printf("%s (%s): applying delta\n", namebuf, comp2str(ctype));
+    printf("%s (%s): applying delta\n", namebuf, cfile_comp2str(ctype));
   rpmn = cget4(cf);
   if (rpmn < 0 || rpmn >= nmpn)
     {
diff -ur applydeltarpm.c.orig applydeltarpm.c
--- applydeltarpm.c.orig	2007-03-06 14:35:16.000000000 +0100
+++ applydeltarpm.c	2008-04-22 14:47:29.000000000 +0200
@@ -21,6 +21,7 @@
 
 #include <bzlib.h>
 #include <zlib.h>
+#include <lzma.h>
 
 #include "util.h"
 #include "md5.h"
@@ -936,19 +937,6 @@
   return b;
 }
 
-char *comp2str(int comp)
-{
-  if (comp == CFILE_COMP_BZ)
-    return "bzip2";
-  if (comp == CFILE_COMP_GZ)
-    return "gzip";
-  if (comp == CFILE_COMP_GZ_RSYNC)
-    return "gzip rsyncable";
-  if (comp == CFILE_COMP_UN)
-    return "uncompressed";
-  return "???";
-}
-
 int
 cfile_write_uncomp(struct cfile *f, void *buf, int len)
 {
@@ -1252,13 +1240,15 @@
   addblkcomp = CFILE_COMP_BZ;
   if (d.addblklen > 9 && d.addblk[0] == 0x1f && d.addblk[1] == 0x8b)
     addblkcomp = CFILE_COMP_GZ;
+  else if (d.addblklen > 3 && (d.addblk[0] == 255 && d.addblk[1] == 'L' && d.addblk[2] == 'Z'))
+    addblkcomp = CFILE_COMP_LZMA;
   if (info)
     {
       unsigned int *size;
       if (d.version)
 	printf("deltarpm version: %c\n", d.version & 0xff);
       printf("deltarpm type: %s\n", d.h ? "standard" : d.targetcomp != CFILE_COMP_UN || d.inn != 0 || d.outn != 0 ? "rpm-only" : "rpm-only, no diff");
-      printf("deltarpm compression: %s\n", comp2str(d.deltacomp));
+      printf("deltarpm compression: %s\n", cfile_comp2str(d.deltacomp));
       printf("sequence: %s-", d.nevr);
       for (i = 0; i < d.seql; i++)
 	printf("%02x", d.seq[i]);
@@ -1271,7 +1261,7 @@
 	{
 	  printf("target payload size: %llu\n", (unsigned long long)d.paylen);
 	  if (d.targetcomp != CFILE_COMP_XX)
-	    printf("target payload compression: %s\n", comp2str(d.targetcomp));
+	    printf("target payload compression: %s\n", cfile_comp2str(d.targetcomp));
 	}
       if (d.targetsize == 0)
 	{
@@ -1294,7 +1284,7 @@
 	  printf("internal data size: %llu\n", (unsigned long long)d.inlen);
 	  printf("compressed add data size: %d\n", d.addblklen);
 	  if (d.addblklen)
-	    printf("compressed add data compression: %s\n", comp2str(addblkcomp));
+	    printf("compressed add data compression: %s\n", cfile_comp2str(addblkcomp));
 	  printf("instructions: %d\n", d.inn + d.outn);
 	}
       if (bfp)
diff -ur cfile.c.orig cfile.c
--- cfile.c.orig	2005-09-29 15:44:19.000000000 +0200
+++ cfile.c	2008-04-22 14:29:25.000000000 +0200
@@ -8,10 +8,12 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <unistd.h>
 
 #include <zlib.h>
 #include <bzlib.h>
+#include <lzma.h>
 
 #include "cfile.h"
 
@@ -274,11 +276,11 @@
 {
   int r;
   BZ2_bzDecompressEnd(&f->strm.bz);
-  if (f->fd == CFILE_IO_CFILE && f->strm.gz.avail_in)
+  if (f->fd == CFILE_IO_CFILE && f->strm.bz.avail_in)
     {
       struct cfile *cf = (struct cfile *)f->fp;
-      if (cf->unread(cf, f->strm.gz.next_in, f->strm.gz.avail_in) != -1)
-        f->strm.gz.avail_in = 0;
+      if (cf->unread(cf, f->strm.bz.next_in, f->strm.bz.avail_in) != -1)
+        f->strm.bz.avail_in = 0;
     }
   r = (f->len != CFILE_LEN_UNLIMITED ? f->len : 0) + f->strm.bz.avail_in;
   if (f->unreadbuf != f->buf)
@@ -357,7 +359,9 @@
 static struct cfile *
 cwopen_bz(struct cfile *f)
 {
-  if (BZ2_bzCompressInit(&f->strm.bz, 9, 0, 30) != BZ_OK)
+  if (!f->level)
+    f->level = 9;
+  if (BZ2_bzCompressInit(&f->strm.bz, f->level, 0, 30) != BZ_OK)
     {
       free(f);
       return 0;
@@ -605,13 +609,15 @@
 
   f->crc = crc32(0L, Z_NULL, 0);
   f->crclen = 0;
+  if (!f->level)
+    f->level = Z_BEST_COMPRESSION;
 #ifdef Z_RSYNCABLE
-  ret = deflateInit2(&f->strm.gz, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY | (f->comp == CFILE_COMP_GZ_RSYNC ? Z_RSYNCABLE : 0));
+  ret = deflateInit2(&f->strm.gz, f->level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY | (f->comp == CFILE_COMP_GZ_RSYNC ? Z_RSYNCABLE : 0));
 #else
   if (f->comp == CFILE_COMP_GZ_RSYNC)
     ret = Z_VERSION_ERROR;
   else
-    ret = deflateInit2(&f->strm.gz, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
+    ret = deflateInit2(&f->strm.gz, f->level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
 #endif
   if (ret != Z_OK)
     {
@@ -642,6 +648,159 @@
   return cfile_unreadbuf(f, buf, len, 0);
 }
 
+
+/*****************************************************************
+ *  lzma io
+ */
+
+static struct cfile *
+cropen_lz(struct cfile *f)
+{
+  f->strm.lz = LZMA_STREAM_INIT_VAR;
+  if (lzma_auto_decoder(&f->strm.lz, 0, 0) != LZMA_OK)
+    {
+      free(f);
+      return 0;
+    }
+  f->eof = 0;
+  f->strm.lz.avail_in = f->bufN == -1 ? 0 : f->bufN;
+  f->strm.lz.next_in  = (unsigned char *)f->buf;
+  return f;
+}
+
+static int
+crread_lz(struct cfile *f, void *buf, int len)
+{
+  int ret, used;
+  if (f->eof)
+    return 0;
+  f->strm.lz.avail_out = len;
+  f->strm.lz.next_out = buf;
+  for (;;)
+    {
+      if (f->strm.lz.avail_in == 0 && f->bufN)
+	{
+	  if (cfile_readbuf(f, f->buf, sizeof(f->buf)) == -1)
+	    return -1;
+	  f->strm.lz.avail_in = f->bufN;
+	  f->strm.lz.next_in = (unsigned char *)f->buf;
+	}
+      used = f->strm.lz.avail_in;
+      ret = lzma_code(&f->strm.lz, LZMA_RUN);
+      if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+	return -1;
+      used -= f->strm.lz.avail_in;
+      if (used && f->ctxup)
+	f->ctxup(f->ctx, (unsigned char *)(f->strm.lz.next_in - used), used);
+      f->bytes += used;
+      if (ret == LZMA_STREAM_END)
+	{
+	  f->eof = 1;
+	  return len - f->strm.lz.avail_out;
+	}
+      if (f->strm.lz.avail_out == 0)
+	return len;
+      if (f->bufN == 0)
+	return -1;
+    }
+}
+
+static int
+crclose_lz(struct cfile *f)
+{
+  int r;
+  lzma_end(&f->strm.lz);
+  if (f->fd == CFILE_IO_CFILE && f->strm.lz.avail_in)
+    {
+      struct cfile *cf = (struct cfile *)f->fp;
+      if (cf->unread(cf, (void *)f->strm.lz.next_in, f->strm.lz.avail_in) != -1)
+        f->strm.lz.avail_in = 0;
+    }
+  r = (f->len != CFILE_LEN_UNLIMITED ? f->len : 0) + f->strm.lz.avail_in;
+  if (f->unreadbuf != f->buf)
+    free(f->unreadbuf);
+  free(f);
+  return r;
+}
+
+static struct cfile *
+cwopen_lz(struct cfile *f)
+{
+  lzma_options_alone alone;
+
+  if (!f->level)
+    f->level = 3;
+  lzma_init_encoder();
+  f->strm.lz = LZMA_STREAM_INIT_VAR;
+  alone.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
+  memcpy(&alone.lzma, &lzma_preset_lzma[f->level - 1], sizeof(alone.lzma));
+  if (lzma_alone_encoder(&f->strm.lz, &alone) != LZMA_OK)
+    {
+      free(f);
+      return 0;
+    }
+  return f;
+}
+
+static int
+cwclose_lz(struct cfile *f)
+{
+  int bytes, ret, n;
+  f->strm.lz.avail_in = 0;
+  f->strm.lz.next_in = 0;
+  for (;;)
+    {
+      f->strm.lz.avail_out = sizeof(f->buf);
+      f->strm.lz.next_out = (unsigned char *)f->buf;
+      ret = lzma_code(&f->strm.lz, LZMA_FINISH);
+      if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+        return -1;
+      n = sizeof(f->buf) - f->strm.lz.avail_out;
+      if (n > 0)
+        if (cfile_writebuf(f, f->buf, n) != n)
+          return -1;
+      if (ret == LZMA_STREAM_END)
+        break;
+    }
+  lzma_end(&f->strm.lz);
+  if (f->fd == CFILE_IO_ALLOC)
+    cwclose_fixupalloc(f);
+  bytes = f->bytes;
+  free(f);
+  return bytes;
+}
+
+static int
+cwwrite_lz(struct cfile *f, void *buf, int len)
+{
+  int n, ret;
+
+  if (len <= 0)
+    return len < 0 ? -1 : 0;
+  f->strm.lz.avail_in = len;
+  f->strm.lz.next_in = buf;
+  for (;;)
+    {
+      f->strm.lz.avail_out = sizeof(f->buf);
+      f->strm.lz.next_out = (unsigned char *)f->buf;
+      ret = lzma_code(&f->strm.lz, LZMA_RUN);
+      if (ret != LZMA_OK)
+	return -1;
+      n = sizeof(f->buf) - f->strm.lz.avail_out;
+      if (n > 0)
+	if (cfile_writebuf(f, f->buf, n) != n)
+	  return -1;
+      if (f->strm.lz.avail_in == 0)
+	return len;
+    }
+}
+
+static int
+crunread_lz(struct cfile *f, void *buf, int len)
+{
+  return cfile_unreadbuf(f, buf, len, 0);
+}
+
 /*****************************************************************
  *  uncompressed io
  */
@@ -939,10 +1098,15 @@
 	    comp = CFILE_COMP_BZ;
 	  else if (f->buf[0] == 0x1f && f->buf[1] == 0x8b)
 	    comp = CFILE_COMP_GZ;
+	  else if (f->buf[0] == 255 && f->buf[1] == 'L' && f->buf[2] == 'Z')
+	    comp = CFILE_COMP_LZMA;
+	  else if (f->buf[0] == 0135 && f->buf[1] == 0 && f->buf[2] == 0)
+	    comp = CFILE_COMP_LZMA;
 	}
     }
-  f->comp = comp;
-  switch (comp)
+  f->comp = CFILE_COMPALGO(comp);
+  f->level = CFILE_COMPLEVEL(comp);
+  switch (f->comp)
     {
     case CFILE_COMP_UN:
       f->read   = mode == CFILE_OPEN_RD ? crread_un : 0;
@@ -969,6 +1133,14 @@
       f->write  = mode == CFILE_OPEN_WR ? cwwrite_bz : 0;
       f->close  = mode == CFILE_OPEN_RD ? crclose_bz : cwclose_bz;
       return mode == CFILE_OPEN_RD ? cropen_bz(f) : cwopen_bz(f);
+    case CFILE_COMP_LZMA:
+      f->strm.lz.allocator = 0;
+      f->strm.lz.internal = 0;
+      f->read   = mode == CFILE_OPEN_RD ? crread_lz : 0;
+      f->unread = mode == CFILE_OPEN_RD ? crunread_lz : 0;
+      f->write  = mode == CFILE_OPEN_WR ? cwwrite_lz : 0;
+      f->close  = mode == CFILE_OPEN_RD ? crclose_lz : cwclose_lz;
+      return mode == CFILE_OPEN_RD ? cropen_lz(f) : cwopen_lz(f);
     default:
       free(f);
       return 0;
@@ -1010,3 +1182,48 @@
     }
   return l;
 }
+
+char *
+cfile_comp2str(int comp)
+{
+  if (CFILE_COMPLEVEL(comp))
+    {
+      static char buf[64];
+      sprintf(buf, "%s.%d", cfile_comp2str(CFILE_COMPALGO(comp)), CFILE_COMPLEVEL(comp));
+      return buf;
+    }
+  switch (comp)
+    {    
+    case CFILE_COMP_UN:
+      return "uncomp.";
+    case CFILE_COMP_GZ:
+      return "gzip";
+    case CFILE_COMP_GZ_RSYNC:
+      return "gzip rsyncable";
+    case CFILE_COMP_BZ:
+      return "bzip";
+    case CFILE_COMP_LZMA:
+      return "lzma";
+    }    
+  return "???";
+}
+
+int
+cfile_setlevel(int comp, int level)
+{
+  int deflevel = 0;
+  comp = CFILE_COMPALGO(comp);
+  switch(comp)
+    {
+    case CFILE_COMP_GZ:
+    case CFILE_COMP_GZ_RSYNC:
+    case CFILE_COMP_BZ:
+      deflevel = 9;
+      break;
+    default:
+      break;
+    }
+  if (level == 0 || level == deflevel)
+    return comp;
+  return CFILE_MKCOMP(comp, level);
+}
diff -ur cfile.h.orig cfile.h
--- cfile.h.orig	2005-06-21 15:13:40.000000000 +0200
+++ cfile.h	2008-04-22 12:06:14.000000000 +0200
@@ -9,6 +9,7 @@
   int fd;
   void *fp;
   int comp;
+  int level;
   size_t len;
   unsigned char buf[4096];
   int bufN;
@@ -23,6 +24,7 @@
   union {
     bz_stream bz;
     z_stream gz;
+    lzma_stream lz;
   } strm;
   int (*read)(struct cfile *f, void *buf, int len);
   int (*write)(struct cfile *f, void *buf, int len);
@@ -45,8 +47,16 @@
 #define CFILE_COMP_XX (255)
 #define CFILE_COMP_UN (0)
 #define CFILE_COMP_GZ (1)
-#define CFILE_COMP_BZ (2)
+#define CFILE_COMP_BZ_20 (2)
 #define CFILE_COMP_GZ_RSYNC (3)
+#define CFILE_COMP_BZ_17 (4)
+#define CFILE_COMP_LZMA (5)
+
+#define CFILE_COMP_BZ CFILE_COMP_BZ_20
+
+#define CFILE_MKCOMP(comp, level) ((comp) | ((level) << 8))
+#define CFILE_COMPALGO(comp) ((comp) & 255)
+#define CFILE_COMPLEVEL(comp) ((comp) >> 8 & 255)
 
 #define CFILE_OPEN_RD ('r')
 #define CFILE_OPEN_WR ('w')
@@ -64,3 +74,5 @@
 struct cfile *cfile_open(int mode, int fd, void *fp, int comp, size_t len, void (*ctxup)(void *, unsigned char *, unsigned int), void *ctx);
 int cfile_copy(struct cfile *in, struct cfile *out, int flags);
 int cfile_detect_rsync(struct cfile *f);
+char *cfile_comp2str(int comp);
+int cfile_setlevel(int comp, int level);
diff -ur combinedeltarpm.c.orig combinedeltarpm.c
--- combinedeltarpm.c.orig	2007-03-06 14:35:55.000000000 +0100
+++ combinedeltarpm.c	2008-04-22 10:40:47.000000000 +0200
@@ -14,6 +14,7 @@
 
 #include <bzlib.h>
 #include <zlib.h>
+#include <lzma.h>
 #include <sys/stat.h>
 
 #include "util.h"
@@ -380,6 +381,8 @@
   if (!strcmp(comp, "gzip rsyncable"))
     return CFILE_COMP_GZ_RSYNC;
 #endif
+  if (!strcmp(comp, "lzma"))
+    return CFILE_COMP_LZMA;
   if (!strcmp(comp, "uncompressed"))
     return CFILE_COMP_UN;
   fprintf(stderr, "unknown compression type: %s\n", comp);
diff -ur fragiso.c.orig fragiso.c
--- fragiso.c.orig	2007-03-06 14:35:55.000000000 +0100
+++ fragiso.c	2008-04-22 13:37:17.000000000 +0200
@@ -10,9 +10,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <unistd.h>
 
 #include <zlib.h>
+#include <lzma.h>
 #include <bzlib.h>
 
 #include "rpmhead.h"
@@ -212,7 +214,7 @@
       fprintf(stderr, "bad rpm (bad h): %s\n", name);
       exit(1);
     }
-  /* ok, all header are read in, extrac information */
+  /* ok, all header are read in, extract information */
   rpmn = headstring(h, TAG_NAME);
   if (!rpmn)
     {
diff -ur makedeltaiso.c.orig makedeltaiso.c
--- makedeltaiso.c.orig	2005-09-30 15:52:37.000000000 +0200
+++ makedeltaiso.c	2008-04-22 14:14:32.000000000 +0200
@@ -14,6 +14,7 @@
 
 #include <zlib.h>
 #include <bzlib.h>
+#include <lzma.h>
 
 #include "rpmoffs.h"
 #include "delta.h"
@@ -279,19 +280,6 @@
 
 void diffit(struct cfile *fpout, FILE *fpold, FILE *fpnew, unsigned char *old, unsigned int oldl, unsigned char *new, int newl, struct rpmpay *newpays, int newpayn, struct rpmpay *oldpays, int oldpayn, MD5_CTX *ctx);
 
-char *comp2str(int comp)
-{
-  if (comp == CFILE_COMP_UN)
-    return "uncomp.";
-  if (comp == CFILE_COMP_GZ)
-    return "gzip";
-  if (comp == CFILE_COMP_GZ_RSYNC)
-    return "gzip rsyncable";
-  if (comp == CFILE_COMP_BZ)
-    return "bzip";
-  return "???";
-}
-
 unsigned int payread(FILE *fp, off64_t off, unsigned int len, unsigned char **pp, MD5_CTX *ctx, unsigned char *namebuf)
 {
   int l, r;
@@ -402,7 +390,11 @@
 	  namebuf[0] = 254;
 	}
       else
-	printf("%s (%s): creating delta...", namebuf + 2, comp2str(namebuf[0]));
+	{
+	  int comp = cfile_setlevel(namebuf[0], pay->level);
+	  printf("%s (%s): creating delta...", namebuf + 2, cfile_comp2str(comp));
+	  namebuf[0] = CFILE_COMPALGO(comp) | (CFILE_COMPLEVEL(comp) << 4);	/* argh! */
+	}
       fflush(stdout);
       if (fpout->write(fpout, namebuf, l + 2) != l + 2)
 	{
diff -ur makedeltarpm.c.orig makedeltarpm.c
--- makedeltarpm.c.orig	2007-03-06 14:35:55.000000000 +0100
+++ makedeltarpm.c	2008-04-22 14:41:24.000000000 +0200
@@ -15,6 +15,7 @@
 
 #include <bzlib.h>
 #include <zlib.h>
+#include <lzma.h>
 
 #include "util.h"
 #include "md5.h"
@@ -347,6 +348,8 @@
   if (!strcmp(comp, "gzip rsyncable"))
     return CFILE_COMP_GZ_RSYNC;
 #endif
+  if (!strcmp(comp, "lzma"))
+    return CFILE_COMP_LZMA;
   if (!strcmp(comp, "uncompressed"))
     return CFILE_COMP_UN;
   fprintf(stderr, "unknown compression type: %s\n", comp);
@@ -483,6 +486,7 @@
   int paycomp = CFILE_COMP_XX;
   int addblkcomp = CFILE_COMP_BZ;
   int targetcomp = CFILE_COMP_XX;
+  char *payloadflags;
 
   memset(&d, 0, sizeof(d));
   while ((c = getopt(argc, argv, "vV:prl:s:z:u")) != -1)
@@ -685,6 +689,8 @@
       targetcomp = CFILE_COMP_UN;
       if (paycomp == CFILE_COMP_XX)
 	paycomp = CFILE_COMP_GZ;	/* no need for better compression */
+      if (addblkcomp == CFILE_COMP_XX)
+	addblkcomp = CFILE_COMP_GZ;
       d.targetsize = fullsize;
       d.targetcomp = targetcomp;
       d.targetcomppara = 0;
@@ -760,8 +766,13 @@
 	  exit(1);
 	}
       targetcomp = newbz->comp;
+      if ((payloadflags = headstring(d.h, TAG_PAYLOADFLAGS)) != 0)
+	if (*payloadflags >= '1' && *payloadflags <= '9')
+	  targetcomp = cfile_setlevel(targetcomp, *payloadflags - '0');
       if (paycomp == CFILE_COMP_XX)
 	paycomp = targetcomp;
+      if (addblkcomp == CFILE_COMP_XX)
+	addblkcomp = targetcomp;
       while ((l = newbz->read(newbz, buf, sizeof(buf))) > 0)
 	addtocpio(&newcpio, &newcpiolen, (unsigned char *)buf, l);
       if (l < 0)
@@ -1138,8 +1149,13 @@
 	  exit(1);
 	}
       targetcomp = newbz->comp;
+      if ((payloadflags = headstring(d.h, TAG_PAYLOADFLAGS)) != 0)
+	if (*payloadflags >= '1' && *payloadflags <= '9')
+	  targetcomp = cfile_setlevel(targetcomp, *payloadflags - '0');
       if (paycomp == CFILE_COMP_XX)
 	paycomp = targetcomp;
+      if (addblkcomp == CFILE_COMP_XX)
+	addblkcomp = targetcomp;
       while ((l = newbz->read(newbz, buf, sizeof(buf))) > 0)
 	addtocpio(&newcpio, &newcpiolen, (unsigned char *)buf, l);
       if (l < 0)
diff -ur readdeltarpm.c.orig readdeltarpm.c
--- readdeltarpm.c.orig	2005-06-14 15:49:21.000000000 +0200
+++ readdeltarpm.c	2008-04-22 10:42:28.000000000 +0200
@@ -14,6 +14,7 @@
 
 #include <bzlib.h>
 #include <zlib.h>
+#include <lzma.h>
 #include <sys/stat.h>
 
 #include "util.h"
@@ -384,7 +385,9 @@
   else
     {
       char *compressor = headstring(d->h, TAG_PAYLOADCOMPRESSOR);
-      if (compressor && !strcmp(compressor, "bzip2"))
+      if (compressor && !strcmp(compressor, "lzma"))
+	d->targetcomp = CFILE_COMP_LZMA;
+      else if (compressor && !strcmp(compressor, "bzip2"))
 	d->targetcomp = CFILE_COMP_BZ;
       else
 	d->targetcomp = CFILE_COMP_GZ;
diff -ur rpmhead.h.orig rpmhead.h
--- rpmhead.h.orig	2007-03-06 14:35:55.000000000 +0100
+++ rpmhead.h	2008-03-18 12:45:29.000000000 +0100
@@ -27,6 +27,7 @@
 #define TAG_DIRNAMES    1118
 #define TAG_PAYLOADFORMAT 1124
 #define TAG_PAYLOADCOMPRESSOR 1125
+#define TAG_PAYLOADFLAGS 1126
 
 #define SIGTAG_SIZE     1000
 #define SIGTAG_MD5      1004
diff -ur rpmoffs.c.orig rpmoffs.c
--- rpmoffs.c.orig	2005-05-06 22:21:28.000000000 +0200
+++ rpmoffs.c	2008-04-22 14:18:08.000000000 +0200
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 
 #include "rpmoffs.h"
+#include "rpmhead.h"
 
 static unsigned int
 get4(unsigned char *p)
@@ -44,7 +45,7 @@
 static int rpmpayn;
 
 static void
-addrpm(char *name, off64_t o, unsigned int l)
+addrpm(char *name, off64_t o, unsigned int l, int level)
 {
   char *n;
   if ((rpmpayn & 31) == 0)
@@ -70,6 +71,7 @@
   rpmpays[rpmpayn].l = l;
   rpmpays[rpmpayn].x = 0;
   rpmpays[rpmpayn].lx = 0;
+  rpmpays[rpmpayn].level = level;
   rpmpayn++;
 }
 
@@ -100,7 +102,7 @@
   unsigned char blk2[0x800];
   unsigned char name[256];
   int namel;
-  unsigned int filepos, filelen, filepos2, hstart;
+  unsigned int filepos, filelen, filepos2, hoffset;
   unsigned char *pt, *ep;
   int i, j, l, nl, el, nml, nmf, hcnt, hdcnt;
 
@@ -112,8 +114,17 @@
   unsigned int ce_off;
   unsigned int ce_len;
 
+  unsigned char *rpmb;
+  int len, rpmblen, rpmbalen;
+  int level;
+
   off64_t paystart;
   int paylen;
+  struct rpmhead *h;
+  char *payloadflags;
+
+  rpmbalen = 0x800 * 4;
+  rpmb = malloc(rpmbalen);
 
   readblk(fp, blk, 16);
   if (memcmp(blk, "\001CD001", 6))
@@ -250,58 +261,76 @@
 	    continue;
 	  if (filelen < 0x70 || strcmp((char *)name + namel - 4, ".rpm"))
 	    continue;
-	  readblk(fp, blk2, filepos);
+
 	  filepos2 = filepos;
-	  if (get4(blk2) != 0xdbeeabed)
+	  readblk(fp, rpmb, filepos2++);
+	  rpmblen = 0x800;
+	  if (get4(rpmb) != 0xdbeeabed)
 	    continue;
-	  if (get4(blk2 + 0x60) != 0x01e8ad8e)
+	  if (get4(rpmb + 0x60) != 0x01e8ad8e)
 	    {
 	      fprintf(stderr, "bad rpm (bad sigheader): %s\n", name);
 	      exit(1);
 	    }
-	  hcnt = get4n(blk2 + 0x68);
-	  hdcnt = get4n(blk2 + 0x6c);
+	  hcnt = get4n(rpmb + 0x68);
+	  hdcnt = get4n(rpmb + 0x6c);
 	  if ((hdcnt & 7) != 0)
 	   hdcnt += 8 - (hdcnt & 7);
-          if (0x70 + hcnt * 16 + hdcnt + 0x70 >= filelen)
+	  len = 0x60 + 16 + hcnt * 16 + hdcnt + 16;
+          if (len > filelen)
 	    {
 	      fprintf(stderr, "bad rpm (no header): %s\n", name);
 	      exit(1);
 	    }
-	  hstart = 0x70 + hcnt * 16 + hdcnt;
-          if (hstart >= 0x800)
+	  while (rpmblen < len)
 	    {
-	      filepos2 += hstart / 0x800;
-	      readblk(fp, blk2, filepos2);
-	      hstart &= 0x7ff;
+	      if (rpmblen + 0x800 > rpmbalen)
+		{
+		  rpmbalen += 0x800 * 4;
+		  rpmb = realloc(rpmb, rpmbalen);
+		}
+	      readblk(fp, rpmb + rpmblen, filepos2++);
+	      rpmblen += 0x800;
 	    }
-	  if (get4(blk2 + hstart) != 0x01e8ad8e)
+	  hoffset = len - 16;
+	  if (get4(rpmb + hoffset) != 0x01e8ad8e)
 	    {
 	      fprintf(stderr, "bad rpm (bad header): %s\n", name);
 	      exit(1);
 	    }
-	  hstart += 8;
-          if (hstart >= 0x800)
+	  hcnt = get4n(rpmb + hoffset + 8);
+	  hdcnt = get4n(rpmb + hoffset + 12);
+	  len += hcnt * 16 + hdcnt;
+	  if (len >= filelen)
 	    {
-	      filepos2++;
-	      readblk(fp, blk2, filepos2);
-	      hstart &= 0x7ff;
-	    }
-	  hcnt = get4n(blk2 + hstart);
-	  hdcnt = get4n(blk2 + hstart + 4);
-	  hstart += 0x8 + hcnt * 16 + hdcnt;
-          if (hstart >= 0x800)
-	    {
-	      filepos2 += hstart / 0x800;
-	      hstart &= 0x7ff;
-            }
-	  if (hstart + (filepos2 - filepos) * 0x800 > filelen)
+	      fprintf(stderr, "bad rpm (EOF): %s\n", name);
+	      exit(1);
+	    }
+	  while (rpmblen < len)
 	    {
-	      fprintf(stderr, "bad rpm (no payload): %s\n", name);
+	      if (rpmblen + 0x800 > rpmbalen)
+		{
+		  rpmbalen += 0x800 * 4;
+		  rpmb = realloc(rpmb, rpmbalen);
+		}
+	      readblk(fp, rpmb + rpmblen, filepos2++);
+	      rpmblen += 0x800;
+	    }
+	  paystart = 0x800 * (off64_t)filepos + len;
+	  paylen = filelen - len;
+	  h = readhead_buf(rpmb + hoffset, 16 + hcnt * 16 + hdcnt, 0);
+          if (!h)
+	    {
+	      fprintf(stderr, "bad rpm (bad h): %s\n", name);
 	      exit(1);
 	    }
-	  paystart = 0x800 * (off64_t)filepos2 + hstart;
-	  paylen = filelen - (hstart + (filepos2 - filepos) * 0x800);
+	  level = 0;
+	  payloadflags = headstring(h, TAG_PAYLOADFLAGS);
+	  if (payloadflags && *payloadflags >= '1' && *payloadflags <= '9')
+	    level = *payloadflags - '0';
+
+	  free(h);
+
 	  namel -= 4;
           name[namel] = 0;
 	  l = namel;
@@ -330,11 +359,12 @@
 		    }
 		}
 	    }
-	  addrpm((char *)name, paystart, paylen);
+	  addrpm((char *)name, paystart, paylen, level);
 	}
     }
+  free(rpmb);
   sortrpm();
-  addrpm(0, 0, 0);
+  addrpm(0, 0, 0, 0);
   i = rpmpayn - 1;
   *retp = rpmpays;
   rpmpayn = 0;
diff -ur rpmoffs.h.orig rpmoffs.h
--- rpmoffs.h.orig	2005-02-03 19:41:51.000000000 +0100
+++ rpmoffs.h	2008-04-22 13:30:52.000000000 +0200
@@ -5,6 +5,7 @@
   unsigned int lx;
   off64_t o;
   unsigned int l;
+  int level;
 };
 
 int rpmoffs(FILE *fp, char *isoname, struct rpmpay **retp);
diff -ur writedeltarpm.c.orig writedeltarpm.c
--- writedeltarpm.c.orig	2005-06-13 19:21:41.000000000 +0200
+++ writedeltarpm.c	2008-04-22 10:42:39.000000000 +0200
@@ -14,6 +14,7 @@
 
 #include <bzlib.h>
 #include <zlib.h>
+#include <lzma.h>
 #include <sys/stat.h>
 
 #include "md5.h"