diff -ru orig/rpm2cpio new/rpm2cpio
--- orig/rpm2cpio	2009-10-30 10:56:40.000000000 +0100
+++ new/rpm2cpio	2009-10-30 11:08:24.000000000 +0100
@@ -31,6 +31,7 @@
 
 # add a path if desired
 $gzip = "gzip";
+$lzma = "lzma";
 
 sub printhelp {
   print <<HERE;
@@ -78,7 +79,10 @@
   $pos = tell($f);
   read $f,$rpm,16;
   $smagic = unpack("n", $rpm);
+  # Check for gzip magic
   last if $smagic eq 0x1f8b;
+  # Check for lzma magic
+  last if $smagic eq 0x5d00;
   # Turns out that every header except the start of the gzip one is
   # padded to an 8 bytes boundary.
   if ($pos & 0x7) {
@@ -99,7 +103,17 @@
   die "bogus RPM\n";
 }
 
-open(ZCAT, "|gzip -cd") || die "can't pipe to gzip\n";
+# Check for gzip magic
+if ($smagic eq 0x1f8b) {
+  open(ZCAT, "|gzip -cd") || die "can't pipe to gzip\n";
+}
+# Check for lzma magic
+elsif ($smagic eq 0x5d00) {
+  open(ZCAT, "|lzma -cd") || die "can't pipe to lzma\n";
+}
+else {
+  die "No CPIO srchive found\n";
+}
 print STDERR "CPIO archive found!\n";
 
 print ZCAT $rpm;
diff -ru orig/rpmunpack.c new/rpmunpack.c
--- orig/rpmunpack.c	1998-06-28 15:16:59.000000000 +0200
+++ new/rpmunpack.c	2009-10-30 16:18:05.000000000 +0100
@@ -23,8 +23,13 @@
  */
 #define BUFSIZE		512
 #define RPM_MAGIC	"\355\253\356\333"
+#define HEADER_MAGIC	"\216\255\350\001"
+#define GZ_MAGIC	"\037\213"
 #define GZ_MAGIC_1	'\037'
 #define GZ_MAGIC_2	'\213'
+#define LZMA_MAGIC	"\135\0"
+#define LZMA_MAGIC_1	'\135'
+#define LZMA_MAGIC_2	'\0'
 
 
 
@@ -32,8 +37,10 @@
  * Global variables
  */
 static char buffer[BUFSIZE];
+static char outname[75];
 static char *progname;
-static int infile, outfile;
+static FILE *infile;
+static int outfile;
 
 
 
@@ -44,7 +51,7 @@
 {
   int err;
 
-  if ((err = read(infile, buffer, num)) != num) {
+  if ((err = fread(buffer,1, num, infile)) != num) {
 	if (err < 0)
 		perror(progname);
 	else
@@ -56,11 +63,25 @@
 
 
 /*
+ * Unpack the buffer onto a long
+ */
+static long unpack(char *data)
+{
+	long dword;
+	unsigned char *byte = (unsigned char*)data;
+	dword = ((long)byte[0]<<24) | ((long)byte[1]<<16) | ((long)byte[2]<<8) | ((long)byte[3]);
+	return dword;
+}
+
+
+
+/*
  * Main program
  */
 void main(int argc, char **argv)
 {
-  int len, status = 0;
+  int len, pos, status_gz = 0, status_lzma = 0;
+  long sections, bytes;
 
   /* Get our own program name */
   if ((progname = strrchr(argv[0], '/')) == NULL)
@@ -76,8 +97,8 @@
 
   /* Open input file */
   if (argc == 1)
-	infile = STDIN_FILENO;
-  else if ((infile = open(argv[1], O_RDONLY)) < 0) {
+	infile = stdin;
+  else if ((infile = fopen(argv[1], "rb")) < 0) {
 	perror(progname);
 	exit(1);
   }
@@ -93,13 +114,7 @@
   buffer[64] = '\0';
 
   /* Open output file */
-  strcat(buffer, ".cpio.gz");
-  if (infile == STDIN_FILENO)
-	outfile = STDOUT_FILENO;
-  else if ((outfile = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
-	perror(progname);
-	exit(1);
-  }
+  strcpy(outname, buffer);
 
   /*
    * Now search for the GZIP signature. This is rather awkward, but I don't
@@ -111,25 +126,72 @@
    * never appears before offset 0x200, so we skip these first couple of
    * bytes to make the signature scan a little more reliable.
    */
-  myread(0x200 - 74);
-  while (status < 2) {
-	myread(1);
-	if (status == 0 && buffer[0] == GZ_MAGIC_1)
-		status++;
-	else if (status == 1 && buffer[0] == GZ_MAGIC_2)
-		status++;
+  myread(96 - 74);
+  while (status_gz < 1 && status_lzma < 1) {
+	pos = ftell(infile);
+	myread(16);
+	if (!strncmp(buffer, GZ_MAGIC, 2)) {
+		status_gz++;
+		break;
+	}
+	if (!strncmp(buffer, LZMA_MAGIC, 2)) {
+		status_lzma++;
+		break;
+	}
+	/* Hopefully we stay alligned when ftell doesn't work */
+	if (pos >= 0 && pos & 7) {
+		pos += 7;
+		pos &= ~7;
+		fseek(infile, pos, SEEK_SET);
+		myread(16);
+	}
+	if (strncmp(buffer, HEADER_MAGIC, 4)) {
+		fprintf(stderr, "unrecognized RPM header\n");
+		exit(1);
+	}
+	sections = unpack(buffer + 8);
+	bytes = unpack(buffer + 12);
+	if (pos >= 0) {
+		pos += 16;
+		pos += 16 * sections;
+		pos += bytes;
+		fseek(infile, pos, SEEK_SET);
+	}
 	else
-		status = 0;
+	{
+		for (pos = (16 * sections) + bytes; pos >= BUFSIZE; pos -= BUFSIZE)
+			myread(BUFSIZE);
+		if (pos)
+			myread(pos);
+	}
+  }
+
+  if (status_gz) {
+	strcat(outname, ".cpio.gz");
+  }
+  else if (status_lzma) {
+	strcat(outname, ".cpio.lzma");
+  }
+  else {
+	fprintf(stderr, "no cpio file in RPM file\n");
+	exit(1);
   }
-  buffer[0] = GZ_MAGIC_1;
-  buffer[1] = GZ_MAGIC_2;
-  if (write(outfile, buffer, 2) < 0) {
+
+  /* Open output file */
+  if (infile == stdin)
+	outfile = STDOUT_FILENO;
+  else if ((outfile = open(outname, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
+	perror(progname);
+	exit(1);
+  }
+
+  if (write(outfile, buffer, 16) < 0) {
 	perror(progname);
 	exit(1);
   }
 
   /* Now simply copy the GZIP archive into the output file */
-  while ((len = read(infile, buffer, BUFSIZE)) > 0) {
+  while ((len = fread(buffer, 1, BUFSIZE, infile)) > 0) {
 	if (write(outfile, buffer, len) < 0) {
 		perror(progname);
 		exit(1);
@@ -140,6 +202,6 @@
 	exit(1);
   }
   close(outfile);
-  close(infile);
+  fclose(infile);
   exit(0);
 }
