0bf1824
# LZMA support for Midnight Commander
0bf1824
# 2006-03-17
0bf1824
#
0bf1824
# This patch adds basic support for LZMA compressed files to
0bf1824
# Midnight Commander 4.6.1. You should have LZMA utils 4.32.x
0bf1824
# or later. Older versions of LZMA utils will *not* work.
0bf1824
#
0bf1824
# Copyright (C) 2006 Lasse Collin <lasse.collin@tukaani.org>
0bf1824
#
0bf1824
# This patch is free software; you can redistribute it and/or modify
0bf1824
# it under the terms of the GNU General Public License as published by
0bf1824
# the Free Software Foundation; either version 2 of the License, or
0bf1824
# (at your option) any later version.
0bf1824
#
0bf1824
# This program is distributed in the hope that it will be useful,
0bf1824
# but WITHOUT ANY WARRANTY; without even the implied warranty of
0bf1824
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0bf1824
# GNU General Public License for more details.
0bf1824
e78c6c9
diff -up mc-4.6.2-pre1/edit/edit.c.lzmavfs mc-4.6.2-pre1/edit/edit.c
e78c6c9
--- mc-4.6.2-pre1/edit/edit.c.lzmavfs	2008-08-05 15:31:29.000000000 +0200
e78c6c9
+++ mc-4.6.2-pre1/edit/edit.c	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -185,6 +185,7 @@ edit_load_file_fast (WEdit *edit, const 
0bf1824
 static const struct edit_filters {
0bf1824
     const char *read, *write, *extension;
0bf1824
 } all_filters[] = {
e78c6c9
+    { "lzma -cd %s 2>&1",   "lzma > %s",   ".lzma" },
0bf1824
     { "bzip2 -cd %s 2>&1",  "bzip2 > %s",  ".bz2" },
0bf1824
     { "gzip -cd %s 2>&1",   "gzip > %s",   ".gz"  },
0bf1824
     { "gzip -cd %s 2>&1",   "gzip > %s",   ".Z"   }
e78c6c9
diff -up mc-4.6.2-pre1/src/util.c.lzmavfs mc-4.6.2-pre1/src/util.c
e78c6c9
--- mc-4.6.2-pre1/src/util.c.lzmavfs	2008-08-05 15:31:29.000000000 +0200
e78c6c9
+++ mc-4.6.2-pre1/src/util.c	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -1239,7 +1239,7 @@ get_current_wd (char *buffer, int size)
e78c6c9
 enum compression_type
e78c6c9
 get_compression_type (int fd)
0bf1824
 {
0bf1824
-    unsigned char magic[4];
0bf1824
+    unsigned char magic[16];
0bf1824
 
0bf1824
     /* Read the magic signature */
0bf1824
     if (mc_read (fd, (char *) magic, 4) != 4)
e78c6c9
@@ -1283,6 +1283,31 @@ get_compression_type (int fd)
0bf1824
 	    return COMPRESSION_BZIP2;
0bf1824
 	}
0bf1824
     }
0bf1824
+
0bf1824
+    /* LZMA files; both LZMA_Alone and LZMA utils formats. The LZMA_Alone
0bf1824
+     * format is used by the LZMA_Alone tool from LZMA SDK. The LZMA utils
0bf1824
+     * format is the default format of LZMA utils 4.32.1 and later. */
0bf1824
+    if (magic[0] < 0xE1 || (magic[0] == 0xFF && magic[1] == 'L' &&
0bf1824
+	magic[2] == 'Z' && magic[3] == 'M')) {
0bf1824
+	if (mc_read (fd, (char *) magic + 4, 9) == 9) {
0bf1824
+	    /* LZMA utils format */
0bf1824
+	    if (magic[0] == 0xFF && magic[4] == 'A' && magic[5] == 0x00)
0bf1824
+		return COMPRESSION_LZMA;
0bf1824
+	    /* The LZMA_Alone format has no magic bytes, thus we
0bf1824
+	     * need to play a wizard. This can give false positives,
0bf1824
+	     * thus the detection below should be removed when
0bf1824
+	     * the newer LZMA utils format has got popular. */
0bf1824
+	    if (magic[0] < 0xE1 && magic[4] < 0x20 &&
0bf1824
+		((magic[10] == 0x00 && magic[11] == 0x00 &&
0bf1824
+		  magic[12] == 0x00) ||
0bf1824
+		 (magic[5] == 0xFF && magic[6] == 0xFF &&
0bf1824
+		  magic[7] == 0xFF && magic[8] == 0xFF &&
0bf1824
+		  magic[9] == 0xFF && magic[10] == 0xFF &&
0bf1824
+		  magic[11] == 0xFF && magic[12] == 0xFF)))
0bf1824
+		return COMPRESSION_LZMA;
0bf1824
+	}
0bf1824
+    }
0bf1824
+
0bf1824
     return 0;
0bf1824
 }
0bf1824
 
e78c6c9
@@ -1293,6 +1318,7 @@ decompress_extension (int type)
0bf1824
 	case COMPRESSION_GZIP: return "#ugz";
0bf1824
 	case COMPRESSION_BZIP:   return "#ubz";
0bf1824
 	case COMPRESSION_BZIP2:  return "#ubz2";
0bf1824
+	case COMPRESSION_LZMA:  return "#ulzma";
0bf1824
 	}
0bf1824
 	/* Should never reach this place */
0bf1824
 	fprintf (stderr, "Fatal: decompress_extension called with an unknown argument\n");
e78c6c9
diff -up mc-4.6.2-pre1/src/util.h.lzmavfs mc-4.6.2-pre1/src/util.h
e78c6c9
--- mc-4.6.2-pre1/src/util.h.lzmavfs	2008-08-05 15:31:29.000000000 +0200
e78c6c9
+++ mc-4.6.2-pre1/src/util.h	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -186,7 +186,8 @@ enum compression_type {
0bf1824
 	COMPRESSION_NONE,
0bf1824
 	COMPRESSION_GZIP,
0bf1824
 	COMPRESSION_BZIP,
0bf1824
-	COMPRESSION_BZIP2
0bf1824
+	COMPRESSION_BZIP2,
0bf1824
+	COMPRESSION_LZMA
0bf1824
 };
0bf1824
 
e78c6c9
 /* Looks for ``magic'' bytes at the start of the VFS file to guess the
e78c6c9
diff -up mc-4.6.2-pre1/vfs/extfs/iso9660.in.lzmavfs mc-4.6.2-pre1/vfs/extfs/iso9660.in
e78c6c9
--- mc-4.6.2-pre1/vfs/extfs/iso9660.in.lzmavfs	2006-07-19 13:19:52.000000000 +0200
e78c6c9
+++ mc-4.6.2-pre1/vfs/extfs/iso9660.in	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -29,6 +29,7 @@ test_iso () {
0bf1824
 mcisofs_list () {
0bf1824
 # left as a reminder to implement compressed image support =)
0bf1824
 case "$1" in
0bf1824
+  *.lzma) MYCAT="lzma -dc";;
0bf1824
   *.bz2) MYCAT="bzip2 -dc";;
0bf1824
   *.gz)  MYCAT="gzip -dc";;
0bf1824
   *.z)   MYCAT="gzip -dc";;
e78c6c9
diff -up mc-4.6.2-pre1/vfs/extfs/lslR.in.lzmavfs mc-4.6.2-pre1/vfs/extfs/lslR.in
e78c6c9
--- mc-4.6.2-pre1/vfs/extfs/lslR.in.lzmavfs	2003-06-22 11:54:21.000000000 +0200
e78c6c9
+++ mc-4.6.2-pre1/vfs/extfs/lslR.in	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -12,6 +12,7 @@ AWK=@AWK@
0bf1824
 
0bf1824
 mclslRfs_list () {
0bf1824
 case "$1" in
0bf1824
+  *.lzma) MYCAT="lzma -dc";;
0bf1824
   *.bz2) MYCAT="bzip2 -dc";;
0bf1824
   *.gz)  MYCAT="gzip -dc";;
0bf1824
   *.z)   MYCAT="gzip -dc";;
e78c6c9
diff -up mc-4.6.2-pre1/vfs/extfs/mailfs.in.lzmavfs mc-4.6.2-pre1/vfs/extfs/mailfs.in
e78c6c9
--- mc-4.6.2-pre1/vfs/extfs/mailfs.in.lzmavfs	2006-05-28 14:35:57.000000000 +0200
e78c6c9
+++ mc-4.6.2-pre1/vfs/extfs/mailfs.in	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -7,6 +7,7 @@ use bytes;
0bf1824
 
0bf1824
 $zcat="zcat";                 # gunzip to stdout
0bf1824
 $bzcat="bzip2 -dc";           # bunzip2 to stdout
0bf1824
+$lzcat="lzma -dc";            # unlzma to stdout
0bf1824
 $file="file";                 # "file" command
0bf1824
 $TZ='GMT';                    # default timezone (for Date module)
0bf1824
 
e78c6c9
@@ -182,6 +183,8 @@ if (/gzip/) {
0bf1824
     exit 1 unless (open IN, "$zcat $mbox_qname|");
0bf1824
 } elsif (/bzip/) {
0bf1824
     exit 1 unless (open IN, "$bzcat $mbox_qname|");
0bf1824
+} elsif (/lzma/) {
0bf1824
+    exit 1 unless (open IN, "$lzcat $mbox_qname|");
0bf1824
 } else {
0bf1824
     exit 1 unless (open IN, "<$mbox_name");
0bf1824
 }
e78c6c9
diff -up mc-4.6.2-pre1/vfs/extfs/patchfs.in.lzmavfs mc-4.6.2-pre1/vfs/extfs/patchfs.in
e78c6c9
--- mc-4.6.2-pre1/vfs/extfs/patchfs.in.lzmavfs	2004-11-17 00:00:40.000000000 +0100
e78c6c9
+++ mc-4.6.2-pre1/vfs/extfs/patchfs.in	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -12,6 +12,7 @@ use POSIX;
0bf1824
 use File::Temp 'tempfile';
0bf1824
 
0bf1824
 # standard binaries
0bf1824
+my $lzma = 'lzma';
0bf1824
 my $bzip = 'bzip2';
0bf1824
 my $gzip = 'gzip';
0bf1824
 my $fileutil = 'file';
e78c6c9
@@ -70,7 +71,9 @@ sub myin
0bf1824
     my ($qfname)=(quotemeta $_[0]);
0bf1824
 
0bf1824
     $_=`$fileutil $qfname`;
0bf1824
-    if (/bzip/) {
0bf1824
+    if (/lzma/) {
0bf1824
+	return "$lzma -dc $qfname";
0bf1824
+    } elsif (/bzip/) {
0bf1824
 	return "$bzip -dc $qfname";
0bf1824
     } elsif (/gzip/) {
0bf1824
 	return "$gzip -dc $qfname";
e78c6c9
@@ -86,7 +89,9 @@ sub myout
0bf1824
     my ($sep) = $append ? '>>' : '>';
0bf1824
 
0bf1824
     $_=`$fileutil $qfname`;
0bf1824
-    if (/bzip/) {
0bf1824
+    if (/lzma/) {
0bf1824
+	return "$lzma -c $sep $qfname";
0bf1824
+    } elsif (/bzip/) {
0bf1824
 	return "$bzip -c $sep $qfname";
0bf1824
     } elsif (/gzip/) {
0bf1824
 	return "$gzip -c $sep $qfname";
e78c6c9
diff -up mc-4.6.2-pre1/vfs/extfs/sfs.ini.lzmavfs mc-4.6.2-pre1/vfs/extfs/sfs.ini
e78c6c9
--- mc-4.6.2-pre1/vfs/extfs/sfs.ini.lzmavfs	1998-12-15 16:57:43.000000000 +0100
e78c6c9
+++ mc-4.6.2-pre1/vfs/extfs/sfs.ini	2008-08-05 15:31:29.000000000 +0200
e78c6c9
@@ -10,6 +10,8 @@ bz/1	bzip < %1 > %3
0bf1824
 ubz/1	bzip -d < %1 > %3
0bf1824
 bz2/1	bzip2 < %1 > %3
0bf1824
 ubz2/1	bzip2 -d < %1 > %3
0bf1824
+lzma/1	lzma < %1 > %3
0bf1824
+ulzma/1	lzma -d < %1 > %3
0bf1824
 tar/1	tar cf %3 %1
0bf1824
 tgz/1	tar czf %3 %1
0bf1824
 uhtml/1	lynx -force_html -dump %1 > %3