A new user interface for you! Read more...

File _service:download_src_package:05_add_lzma_xz_support.patch of Package mc

diff --git a/edit/edit.c b/edit/edit.c
index ff2b2e7..3b9c750 100644
--- a/edit/edit.c
+++ b/edit/edit.c
@@ -182,6 +182,8 @@ edit_load_file_fast (WEdit *edit, const char *filename)
 static const struct edit_filters {
     const char *read, *write, *extension;
 } all_filters[] = {
+    { "xz -cd %s 2>&1",     "xz > %s",     ".xz" },
+    { "lzma -cd %s 2>&1",   "lzma > %s",   ".lzma" },
     { "bzip2 -cd %s 2>&1",  "bzip2 > %s",  ".bz2" },
     { "gzip -cd %s 2>&1",   "gzip > %s",   ".gz"  },
     { "gzip -cd %s 2>&1",   "gzip > %s",   ".Z"   }
diff --git a/lib/mc.ext.in b/lib/mc.ext.in
index af63f0e..dfe72bb 100644
--- a/lib/mc.ext.in
+++ b/lib/mc.ext.in
@@ -119,6 +119,16 @@ regex/\.t(ar\.bz2|bz|b2)$
 	Open=%cd %p#utar
 	View=%view{ascii} bzip2 -dc %f 2>/dev/null | tar tvvf -
 
+# .tar.lzma, .tlz
+regex/\.t(ar\.lzma|lz)$
+	Open=%cd %p#utar
+	View=%view{ascii} lzma -dc %f 2>/dev/null | tar tvvf -
+
+# .tar.xz, .txz
+regex/\.t(ar\.xz|xz)$
+	Open=%cd %p#utar
+	View=%view{ascii} xz -dc %f 2>/dev/null | tar tvvf -
+
 # .tar.F - used in QNX
 regex/\.tar\.F$
 	# Open=%cd %p#utar
@@ -298,6 +303,14 @@ regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.bz2$
 	Open=case %d/%f in */log/*|*/logs/*) bzip2 -dc %f ;; *) bzip2 -dc %f | nroff @MAN_FLAGS@ @MANDOC@ ;; esac | %var{PAGER:more}
 	View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) bzip2 -dc %f ;; *) bzip2 -dc %f | nroff @MAN_FLAGS@ @MANDOC@ ;; esac
 
+regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.lzma$
+	Open=case %d/%f in */log/*|*/logs/*) lzma -dc %f ;; *) lzma -dc %f | nroff @MAN_FLAGS@ @MANDOC@ ;; esac | %var{PAGER:more}
+	View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) lzma -dc %f ;; *) lzma -dc %f | nroff @MAN_FLAGS@ @MANDOC@ ;; esac
+
+regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.xz$
+	Open=case %d/%f in */log/*|*/logs/*) xz -dc %f ;; *) xz -dc %f | nroff @MAN_FLAGS@ @MANDOC@ ;; esac | %var{PAGER:more}
+	View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) xz -dc %f ;; *) xz -dc %f | nroff @MAN_FLAGS@ @MANDOC@ ;; esac
+
 
 ### Images ###
 
@@ -545,6 +554,16 @@ type/^compress
 	Open=gzip -dc %f | %var{PAGER:more}
 	View=%view{ascii} gzip -dc %f 2>/dev/null
 
+# lzma
+regex/\.lzma$
+	Open=lzma -dc %f | %var{PAGER:more}
+	View=%view{ascii} lzma -dc %f 2>/dev/null
+
+# xz
+regex/\.xz$
+	Open=xz -dc %f | %var{PAGER:more}
+	View=%view{ascii} xz -dc %f 2>/dev/null
+
 
 ### Default ###
 
diff --git a/src/util.c b/src/util.c
index da6d1b2..b27f3b3 100644
--- a/src/util.c
+++ b/src/util.c
@@ -942,7 +942,7 @@ get_current_wd (char *buffer, int size)
 enum compression_type
 get_compression_type (int fd)
 {
-    unsigned char magic[4];
+    unsigned char magic[16];
 
     /* Read the magic signature */
     if (mc_read (fd, (char *) magic, 4) != 4)
@@ -986,6 +986,31 @@ get_compression_type (int fd)
 	    return COMPRESSION_BZIP2;
 	}
     }
+
+    /* LZMA files; both LZMA_Alone and LZMA utils formats. The LZMA_Alone
+     * format is used by the LZMA_Alone tool from LZMA SDK. The LZMA utils
+     * format is the default format of LZMA utils 4.32.1 and later. */
+    if (magic[0] < 0xE1 || (magic[0] == 0xFF && magic[1] == 'L' &&
+	magic[2] == 'Z' && magic[3] == 'M')) {
+	if (mc_read (fd, (char *) magic + 4, 9) == 9) {
+	    /* LZMA utils format */
+	    if (magic[0] == 0xFF && magic[4] == 'A' && magic[5] == 0x00)
+		return COMPRESSION_LZMA;
+	    /* The LZMA_Alone format has no magic bytes, thus we
+	     * need to play a wizard. This can give false positives,
+	     * thus the detection below should be removed when
+	     * the newer LZMA utils format has got popular. */
+	    if (magic[0] < 0xE1 && magic[4] < 0x20 &&
+		((magic[10] == 0x00 && magic[11] == 0x00 &&
+		  magic[12] == 0x00) ||
+		 (magic[5] == 0xFF && magic[6] == 0xFF &&
+		  magic[7] == 0xFF && magic[8] == 0xFF &&
+		  magic[9] == 0xFF && magic[10] == 0xFF &&
+		  magic[11] == 0xFF && magic[12] == 0xFF)))
+		return COMPRESSION_LZMA;
+	}
+    }
+
     return 0;
 }
 
@@ -996,6 +1021,8 @@ decompress_extension (int type)
 	case COMPRESSION_GZIP: return "#ugz";
 	case COMPRESSION_BZIP:   return "#ubz";
 	case COMPRESSION_BZIP2:  return "#ubz2";
+	case COMPRESSION_LZMA:  return "#ulzma";
+	case COMPRESSION_XZ:  return "#uxz";
 	}
 	/* Should never reach this place */
 	fprintf (stderr, "Fatal: decompress_extension called with an unknown argument\n");
diff --git a/src/util.h b/src/util.h
index 4e9a113..5e773f8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -179,7 +179,9 @@ enum compression_type {
 	COMPRESSION_NONE,
 	COMPRESSION_GZIP,
 	COMPRESSION_BZIP,
-	COMPRESSION_BZIP2
+	COMPRESSION_BZIP2,
+	COMPRESSION_LZMA,
+	COMPRESSION_XZ
 };
 
 /* Looks for ``magic'' bytes at the start of the VFS file to guess the
diff --git a/vfs/extfs/iso9660.in b/vfs/extfs/iso9660.in
index 91d1b1e..467efdb 100644
--- a/vfs/extfs/iso9660.in
+++ b/vfs/extfs/iso9660.in
@@ -29,6 +29,8 @@ test_iso () {
 mcisofs_list () {
 # left as a reminder to implement compressed image support =)
 case "$1" in
+  *.lzma) MYCAT="lzma -dc";;
+  *.xz)  MYCAT="xz -dc";;
   *.bz2) MYCAT="bzip2 -dc";;
   *.gz)  MYCAT="gzip -dc";;
   *.z)   MYCAT="gzip -dc";;
diff --git a/vfs/extfs/lslR.in b/vfs/extfs/lslR.in
index 273fe5e..67f5edb 100644
--- a/vfs/extfs/lslR.in
+++ b/vfs/extfs/lslR.in
@@ -12,6 +12,8 @@ AWK=@AWK@
 
 mclslRfs_list () {
 case "$1" in
+  *.lzma) MYCAT="lzma -dc";;
+  *.xz)  MYCAT="xz -dc";;
   *.bz2) MYCAT="bzip2 -dc";;
   *.gz)  MYCAT="gzip -dc";;
   *.z)   MYCAT="gzip -dc";;
diff --git a/vfs/extfs/mailfs.in b/vfs/extfs/mailfs.in
index 7bb62f9..91cf3d7 100644
--- a/vfs/extfs/mailfs.in
+++ b/vfs/extfs/mailfs.in
@@ -7,6 +7,8 @@ use bytes;
 
 $zcat="zcat";                 # gunzip to stdout
 $bzcat="bzip2 -dc";           # bunzip2 to stdout
+$lzcat="lzma -dc";            # unlzma to stdout
+$xzcat="xz -dc";              # unxz to stdout
 $file="file";                 # "file" command
 $TZ='GMT';                    # default timezone (for Date module)
 
@@ -182,6 +183,10 @@ if (/gzip/) {
     exit 1 unless (open IN, "$zcat $mbox_qname|");
 } elsif (/bzip/) {
     exit 1 unless (open IN, "$bzcat $mbox_qname|");
+} elsif (/lzma/) {
+    exit 1 unless (open IN, "$lzcat $mbox_qname|");
+} elsif (/xz/) {
+    exit 1 unless (open IN, "$xzcat $mbox_qname|");
 } else {
     exit 1 unless (open IN, "<$mbox_name");
 }
diff --git a/vfs/extfs/patchfs.in b/vfs/extfs/patchfs.in
index dc3757d..62a6d0d 100644
--- a/vfs/extfs/patchfs.in
+++ b/vfs/extfs/patchfs.in
@@ -12,6 +12,8 @@ use POSIX;
 use File::Temp 'tempfile';
 
 # standard binaries
+my $lzma = 'lzma';
+my $xz   = 'xz';
 my $bzip = 'bzip2';
 my $gzip = 'gzip';
 my $fileutil = 'file';
@@ -70,7 +71,11 @@ sub myin
     my ($qfname)=(quotemeta $_[0]);
 
     $_=`$fileutil $qfname`;
-    if (/bzip/) {
+    if (/xz/) {
+	return "$xz -dc $qfname";
+    } elsif (/lzma/) {
+	return "$lzma -dc $qfname";
+    } elsif (/bzip/) {
 	return "$bzip -dc $qfname";
     } elsif (/gzip/) {
 	return "$gzip -dc $qfname";
@@ -86,7 +89,11 @@ sub myout
     my ($sep) = $append ? '>>' : '>';
 
     $_=`$fileutil $qfname`;
-    if (/bzip/) {
+    if (/xz/) {
+	return "$xz -c $sep $qfname";
+    } elsif (/lzma/) {
+	return "$lzma -c $sep $qfname";
+    } elsif (/bzip/) {
 	return "$bzip -c $sep $qfname";
     } elsif (/gzip/) {
 	return "$gzip -c $sep $qfname";
diff --git a/vfs/extfs/sfs.ini b/vfs/extfs/sfs.ini
index 5c3d8e2..fc77e04 100644
--- a/vfs/extfs/sfs.ini
+++ b/vfs/extfs/sfs.ini
@@ -10,6 +10,10 @@ bz/1	bzip < %1 > %3
 ubz/1	bzip -d < %1 > %3
 bz2/1	bzip2 < %1 > %3
 ubz2/1	bzip2 -d < %1 > %3
+lzma/1	lzma < %1 > %3
+ulzma/1	lzma -d < %1 > %3
+xz/1	xz < %1 > %3
+uxz/1	xz -d < %1 > %3
 tar/1	tar cf %3 %1
 tgz/1	tar czf %3 %1
 uhtml/1	lynx -force_html -dump %1 > %3