port lzmp that is packaged by debian, build it, but do not install it yet
authorFlorian Fainelli <florian@openwrt.org>
Mon, 1 Jun 2009 20:31:49 +0000 (20:31 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Mon, 1 Jun 2009 20:31:49 +0000 (20:31 +0000)
SVN-Revision: 16282

tools/lzma/Makefile
tools/lzma/patches/001-large_files.patch [new file with mode: 0644]
tools/lzma/patches/002-lzmp.patch [new file with mode: 0644]
tools/lzma/patches/003-compile_fixes.patch [new file with mode: 0644]

index 83391fc..bebfbaf 100644 (file)
@@ -18,9 +18,11 @@ HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
 include $(INCLUDE_DIR)/host-build.mk
 
 UTIL_DIR=$(HOST_BUILD_DIR)/C/LzmaUtil
+ALONE_DIR=$(HOST_BUILD_DIR)/CPP/7zip/Compress/LZMA_Alone
 
 define Host/Compile
        $(MAKE) -C $(UTIL_DIR) -f makefile.gcc
+       $(MAKE) -C $(ALONE_DIR) -f makefile.gcc
 endef
 
 define Host/Install
diff --git a/tools/lzma/patches/001-large_files.patch b/tools/lzma/patches/001-large_files.patch
new file mode 100644 (file)
index 0000000..b95fe9e
--- /dev/null
@@ -0,0 +1,13 @@
+Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
+===================================================================
+--- lzma-4.65.orig/CPP/7zip/Compress/LZMA_Alone/makefile.gcc   2009-05-15 23:33:51.000000000 +0200
++++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc        2009-06-01 22:00:54.000000000 +0200
+@@ -3,7 +3,7 @@
+ CXX_C = gcc -O2 -Wall
+ LIB = -lm
+ RM = rm -f
+-CFLAGS = -c
++CFLAGS = -c -D_FILE_OFFSET_BITS=64
+ ifdef SystemDrive
+ IS_MINGW = 1
diff --git a/tools/lzma/patches/002-lzmp.patch b/tools/lzma/patches/002-lzmp.patch
new file mode 100644 (file)
index 0000000..72d881c
--- /dev/null
@@ -0,0 +1,1059 @@
+Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp    2009-06-01 22:01:10.000000000 +0200
+@@ -0,0 +1,895 @@
++/*
++ * LZMA command line tool similar to gzip to encode and decode LZMA files.
++ *
++ * Copyright (C) 2005 Ville Koskinen
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
++ * USA.
++ */
++
++#include "../../../Common/MyInitGuid.h"
++
++#include <iostream>
++using std::cout;
++using std::cerr;
++using std::endl;
++
++#include <cstdio>
++#include <cstdlib>
++#include <cstring>
++
++#include <string>
++using std::string;
++#include <vector>
++using std::vector;
++typedef vector<string> stringVector;
++
++#include <unistd.h>
++#include <getopt.h>
++#include <signal.h>
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <utime.h>
++#include <sys/time.h> // futimes()
++
++// For Solaris
++#ifndef HAVE_FUTIMES
++//#define futimes(fd, tv) futimesat(fd, NULL, tv)
++#endif
++
++#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
++#include <fcntl.h>
++#include <io.h>
++#define MY_SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
++#else
++#define MY_SET_BINARY_MODE(file)
++#endif
++
++#include "../../../7zip/Common/FileStreams.h"
++
++#include "../../../Common/Types.h"
++
++#include "../../../7zip/Compress/LzmaDecoder.h"
++#include "../../../7zip/Compress/LzmaEncoder.h"
++
++#include "Exception.h"
++
++#include "lzma_version.h"
++
++namespace lzma {
++
++const char *PROGRAM_VERSION = PACKAGE_VERSION;
++const char *PROGRAM_COPYRIGHT = "Copyright (C) 2006 Ville Koskinen";
++
++/* LZMA_Alone switches:
++    -a{N}:  set compression mode - [0, 2], default: 2 (max)
++    -d{N}:  set dictionary - [0,28], default: 23 (8MB)
++    -fb{N}: set number of fast bytes - [5, 255], default: 128
++    -lc{N}: set number of literal context bits - [0, 8], default: 3
++    -lp{N}: set number of literal pos bits - [0, 4], default: 0
++    -pb{N}: set number of pos bits - [0, 4], default: 2
++    -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, bt4b, pat2r, pat2,
++                pat2h, pat3h, pat4h, hc3, hc4], default: bt4
++*/
++
++struct lzma_option {
++      short compression_mode;                 // -a
++      short dictionary;                       // -d
++      short fast_bytes;                       // -fb
++      wchar_t *match_finder;                  // -mf
++      short literal_context_bits;             // -lc
++      short literal_pos_bits;                 // -lp
++      short pos_bits;                         // -pb
++};
++
++/* The following is a mapping from gzip/bzip2 style -1 .. -9 compression modes
++ * to the corresponding LZMA compression modes. Thanks, Larhzu, for coining
++ * these. */
++const lzma_option option_mapping[] = {
++      { 0,  0,  0,    NULL, 0, 0, 0},         // -0 (needed for indexing)
++      { 0, 16, 64,  L"hc4", 3, 0, 2},         // -1
++      { 0, 20, 64,  L"hc4", 3, 0, 2},         // -2
++      { 1, 19, 64,  L"bt4", 3, 0, 2},         // -3
++      { 2, 20, 64,  L"bt4", 3, 0, 2},         // -4
++      { 2, 21, 128, L"bt4", 3, 0, 2},         // -5
++      { 2, 22, 128, L"bt4", 3, 0, 2},         // -6
++      { 2, 23, 128, L"bt4", 3, 0, 2},         // -7
++      { 2, 24, 255, L"bt4", 3, 0, 2},         // -8
++      { 2, 25, 255, L"bt4", 3, 0, 2},         // -9
++};
++
++struct extension_pair {
++      char *from;
++      char *to;
++};
++
++const extension_pair known_extensions[] = {
++      { ".lzma", "" },
++      { ".tlz", ".tar" },
++      { NULL, NULL }
++};
++
++/* Sorry, I just happen to like enumerations. */
++enum PROGRAM_MODE {
++      PM_COMPRESS = 0,
++      PM_DECOMPRESS,
++      PM_TEST,
++      PM_HELP,
++      PM_LICENSE,
++      PM_VERSION
++};
++
++enum {
++      STATUS_OK = 0,
++      STATUS_ERROR = 1,
++      STATUS_WARNING = 2
++};
++
++/* getopt options. */
++/* struct option { name, has_arg, flag, val } */
++const struct option long_options[] = {
++      { "stdout", 0, 0, 'c' },
++      { "decompress", 0, 0, 'd' },
++      { "compress", 0, 0, 'z' },
++      { "keep", 0, 0, 'k' },
++      { "force", 0, 0, 'f' },
++      { "test", 0, 0, 't' },
++      { "suffix", 1, 0, 'S' },
++      { "quiet", 0, 0, 'q' },
++      { "verbose", 0, 0, 'v' },
++      { "help", 0, 0, 'h' },
++      { "license", 0, 0, 'L' },
++      { "version", 0, 0, 'V' },
++      { "fast", 0, 0, '1' },
++      { "best", 0, 0, '9' },
++      { 0, 0, 0, 0 }
++};
++
++/* getopt option string (for the above options). */
++const char option_string[] = "cdzkftS:qvhLV123456789A:D:F:";
++
++/* Defaults. */
++PROGRAM_MODE program_mode = PM_COMPRESS;
++int   verbosity                       = 0;
++bool  stdinput                        = false;
++bool  stdoutput                       = false;
++bool  keep                            = false;
++bool  force                           = false;
++int   compression_mode                = 7;
++//char        *suffix                         = strdup(".lzma");
++char  *suffix                         = strdup(known_extensions[0].from);
++lzma_option   advanced_options        = { -1, -1, -1, NULL, -1, -1, -1 };
++
++void print_help(const char *const argv0)
++{
++      // Help goes to stdout while other messages go to stderr.
++      cout << "\nlzma " << PROGRAM_VERSION
++              << " " << PROGRAM_COPYRIGHT << "\n"
++              "Based on LZMA SDK " << LZMA_SDK_VERSION_STRING << " "
++              << LZMA_SDK_COPYRIGHT_STRING
++              << "\n\nUsage: " << argv0
++              << " [flags and input files in any order]\n"
++"  -c --stdout       output to standard output\n"
++"  -d --decompress   force decompression\n"
++"  -z --compress     force compression\n"
++"  -k --keep         keep (don't delete) input files\n"
++"  -f --force        force overwrite of output file and compress links\n"
++"  -t --test         test compressed file integrity\n"
++"  -S .suf  --suffix .suf   use suffix .suf on compressed files\n"
++"  -q --quiet        suppress error messages\n"
++"  -v --verbose      be verbose\n"
++"  -h --help         print this message\n"
++"  -L --license      display the license information\n"
++"  -V --version      display version numbers of LZMA SDK and lzma\n"
++"  -1 .. -2          fast compression\n"
++"  -3 .. -9          good to excellent compression. -7 is the default.\n"
++"     --fast         alias for -1\n"
++"     --best         alias for -9 (usually *not* what you want)\n\n"
++"  Memory usage depends a lot on the chosen compression mode -1 .. -9.\n"
++"  See the man page lzma(1) for details.\n\n";
++}
++
++void print_license(void)
++{
++      cout << "\n  LZMA command line tool " << PROGRAM_VERSION << " - "
++              << PROGRAM_COPYRIGHT
++              << "\n  LZMA SDK " << LZMA_SDK_VERSION_STRING << " - "
++              << LZMA_SDK_COPYRIGHT_STRING
++              << "\n  This program is a part of the LZMA utils package.\n"
++              "  http://tukaani.org/lzma/\n\n"
++"  This program is free software; you can redistribute it and/or\n"
++"  modify it under the terms of the GNU General Public License\n"
++"  as published by the Free Software Foundation; either version 2\n"
++"  of the License, or (at your option) any later version.\n"
++"\n"
++"  This program is distributed in the hope that it will be useful,\n"
++"  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
++"  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
++"  GNU General Public License for more details.\n"
++"\n";
++}
++
++void print_version(void)
++{
++      cout << "LZMA command line tool " << PROGRAM_VERSION << "\n"
++              << "LZMA SDK " << LZMA_SDK_VERSION_STRING << "\n";
++}
++
++short str2int (const char *str, const int &min, const int &max)
++{
++      int value = -1;
++      char *endptr = NULL;
++      if (str == NULL || str[0] == '\0')
++              throw ArgumentException("Invalid integer option");
++      value = strtol (str, &endptr, 10);
++      if (*endptr != '\0' || value < min || value > max)
++              throw ArgumentException("Invalid integer option");
++      return value;
++}
++
++void parse_options(int argc, char **argv, stringVector &filenames)
++{
++      /* Snatched from getopt(3). */
++      int c;
++
++      /* Check how we were called */
++      {
++              char *p = strrchr (argv[0], '/'); // Remove path prefix, if any
++              if (p++ == NULL)
++                      p = argv[0];
++              if (strstr (p, "un") != NULL) {
++                      program_mode = PM_DECOMPRESS;
++              } else if (strstr (p, "cat") != NULL) {
++                      program_mode = PM_DECOMPRESS;
++                      stdoutput = true;
++              }
++      }
++
++      while (-1 != (c = getopt_long(argc, argv, option_string,
++                      long_options, NULL))) {
++              switch (c) {
++                      // stdout
++                      case 'c':
++                              stdoutput = true;
++                              break;
++
++                      // decompress
++                      case 'd':
++                              program_mode = PM_DECOMPRESS;
++                              break;
++
++                      // compress
++                      case 'z':
++                              program_mode = PM_COMPRESS;
++                              break;
++
++                      // keep
++                      case 'k':
++                              keep = true;
++                              break;
++
++                      // force
++                      case 'f':
++                              force = true;
++                              break;
++
++                      // test
++                      case 't':
++                              program_mode = PM_TEST;
++                              break;
++
++                      // suffix
++                      case 'S':
++                              if (optarg) {
++                                      free(suffix);
++                                      suffix = strdup(optarg);
++                              }
++                              break;
++
++                      // quiet
++                      case 'q':
++                              verbosity = 0;
++                              break;
++
++                      // verbose
++                      case 'v':
++                              verbosity++;
++                              break;
++
++                      // help
++                      case 'h':
++                              program_mode = PM_HELP;
++                              break;
++
++                      // license
++                      case 'L':
++                              program_mode = PM_LICENSE;
++                              break;
++
++                      // version
++                      case 'V':
++                              program_mode = PM_VERSION;
++                              break;
++
++                      case '1': case '2': case '3': case '4': case '5':
++                      case '6': case '7': case '8': case '9':
++                              compression_mode = c - '0';
++                              break;
++
++                      // Advanced options //
++                      // Compression mode
++                      case 'A':
++                              advanced_options.compression_mode =
++                                              str2int (optarg, 0, 2);
++                              break;
++
++                      // Dictionary size
++                      case 'D':
++                              advanced_options.dictionary =
++                                              str2int (optarg, 0, 28);
++                              break;
++
++                      // Fast bytes
++                      case 'F':
++                              advanced_options.fast_bytes =
++                                              str2int (optarg, 0, 273);
++                              break;
++
++                      default:
++                              throw ArgumentException("");
++                              break;
++              } // switch(c)
++      } // while(1)
++
++      for (int i = optind; i < argc; i++) {
++              if (strcmp("-", argv[i]) == 0)
++                      continue;
++              filenames.push_back(argv[i]);
++      }
++} // parse_options
++
++void set_encoder_properties(NCompress::NLzma::CEncoder *encoder,
++              lzma_option &opt)
++{
++      /* Almost verbatim from LzmaAlone.cpp. */
++          PROPID propIDs[] =
++      {
++              NCoderPropID::kDictionarySize,
++              NCoderPropID::kPosStateBits,
++              NCoderPropID::kLitContextBits,
++              NCoderPropID::kLitPosBits,
++              NCoderPropID::kAlgorithm,
++              NCoderPropID::kNumFastBytes,
++              NCoderPropID::kMatchFinder,
++              NCoderPropID::kEndMarker
++      };
++      const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
++#define VALUE(x) (advanced_options.x >= 0 ? advanced_options.x : opt.x)
++      PROPVARIANT properties[kNumProps];
++      for (int p = 0; p < 6; p++)
++              properties[p].vt = VT_UI4;
++      properties[0].ulVal = UInt32(1 << VALUE (dictionary));
++      properties[1].ulVal = UInt32(VALUE (pos_bits));
++      properties[2].ulVal = UInt32(VALUE (literal_context_bits));
++      properties[3].ulVal = UInt32(VALUE (literal_pos_bits));
++      properties[4].ulVal = UInt32(VALUE (compression_mode));
++      properties[5].ulVal = UInt32(VALUE (fast_bytes));
++#undef VALUE
++
++      properties[6].vt = VT_BSTR;
++      properties[6].bstrVal = (BSTR)opt.match_finder;
++
++      properties[7].vt = VT_BOOL;
++      properties[7].boolVal = stdinput ? VARIANT_TRUE : VARIANT_FALSE;
++
++      if (encoder->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
++              throw Exception("SetCoderProperties() error");
++}
++
++void encode(NCompress::NLzma::CEncoder *encoderSpec,
++              CMyComPtr<ISequentialInStream> inStream,
++              CMyComPtr<ISequentialOutStream> outStream,
++              lzma_option encoder_options,
++              UInt64 fileSize)
++{
++      set_encoder_properties(encoderSpec, encoder_options);
++
++      encoderSpec->WriteCoderProperties(outStream);
++
++      for (int i = 0; i < 8; i++)
++      {
++              Byte b = Byte(fileSize >> (8 * i));
++              if (outStream->Write(&b, sizeof(b), 0) != S_OK)
++                      throw Exception("Write error while encoding");
++      }
++
++      HRESULT result = encoderSpec->Code(inStream, outStream, 0, 0, 0);
++
++      if (result == E_OUTOFMEMORY)
++              throw Exception("Cannot allocate memory");
++      else if (result != S_OK) {
++              char buffer[33];
++              snprintf(buffer, 33, "%d", (unsigned int)result);
++              throw Exception(string("Encoder error: ") + buffer);
++      }
++}
++
++void decode(NCompress::NLzma::CDecoder *decoderSpec,
++              CMyComPtr<ISequentialInStream> inStream,
++              CMyComPtr<ISequentialOutStream> outStream)
++{
++      const UInt32 kPropertiesSize = 5;
++      Byte properties[kPropertiesSize];
++      UInt32 processedSize;
++      UInt64 fileSize = 0;
++
++      if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK)
++              throw Exception("Read error");
++      if (processedSize != kPropertiesSize)
++              throw Exception("Read error");
++      if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
++              throw Exception("SetDecoderProperties() error");
++
++      for (int i = 0; i < 8; i++)
++      {
++              Byte b;
++
++              if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK)
++                      throw Exception("Read error");
++              if (processedSize != 1)
++                      throw Exception("Read error");
++
++              fileSize |= ((UInt64)b) << (8 * i);
++      }
++
++      if (decoderSpec->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
++              throw Exception("Decoder error");
++}
++
++int open_instream(const string infile,
++              CMyComPtr<ISequentialInStream> &inStream,
++              UInt64 &fileSize)
++{
++      CInFileStream *inStreamSpec = new CInFileStream;
++      inStream = inStreamSpec;
++      if (!inStreamSpec->Open(infile.c_str()))
++              throw Exception("Cannot open input file " + infile);
++
++      inStreamSpec->File.GetLength(fileSize);
++
++      return inStreamSpec->File.GetHandle();
++}
++
++int open_outstream(const string outfile,
++              CMyComPtr<ISequentialOutStream> &outStream)
++{
++      COutFileStream *outStreamSpec = new COutFileStream;
++      outStream = outStreamSpec;
++
++      bool open_by_force = (program_mode == PM_TEST) | force;
++
++      if (!outStreamSpec->Create(outfile.c_str(), open_by_force))
++              throw Exception("Cannot open output file " + outfile);
++
++      return outStreamSpec->File.GetHandle();
++}
++
++double get_ratio(int inhandle, int outhandle)
++{
++      struct stat in_stats, out_stats;
++      fstat(inhandle, &in_stats);
++      fstat(outhandle, &out_stats);
++
++      return (double)out_stats.st_size / (double)in_stats.st_size;
++}
++
++mode_t get_file_mode(string filename)
++{
++      struct stat in_stat;
++      lstat(filename.c_str(), &in_stat);
++
++      return in_stat.st_mode;
++}
++
++bool string_ends_with(string str, string ending)
++{
++      return equal(ending.rbegin(), ending.rend(), str.rbegin());
++}
++
++bool extension_is_known(string filename)
++{
++      bool known_format = false;
++      extension_pair extension; int i = 1;
++
++      extension = known_extensions[0];
++      while (extension.from != NULL) {
++              if (string_ends_with(filename, extension.from)) {
++                      known_format = true;
++                      break;
++              }
++              extension = known_extensions[i];
++              i++;
++      }
++
++      if (!known_format) {
++              if (!string_ends_with(filename, suffix)) {
++                      return false;
++              }
++      }
++
++      return true;
++}
++
++string replace_extension(string filename)
++{
++      int suffix_starts_at = filename.length() - strlen (suffix);
++      string from_suffix = filename.substr(suffix_starts_at, strlen (suffix));
++      string ret = filename.substr(0, suffix_starts_at);
++      extension_pair extension; int i = 1;
++
++      bool found_replacement = false;
++      extension = known_extensions[0];
++      while (extension.from != NULL) {
++              if (from_suffix.compare(extension.from) == 0) {
++                      ret += extension.to;
++                      found_replacement = true;
++                      break;
++              }
++
++              extension = known_extensions[i];
++              i++;
++      }
++
++      return ret;
++}
++
++string pretty_print_status(string filename, string output_filename,
++              string ratio)
++{
++      string ret = "";
++
++      ret += filename;
++      ret += ":\t ";
++
++      if (program_mode == PM_TEST) {
++              ret += "decoded succesfully";
++
++              return ret;
++      }
++
++      if (!stdinput && !stdoutput) {
++              ret += ratio;
++              ret += " -- ";
++      }
++
++      if (program_mode == PM_COMPRESS) {
++              if (keep) {
++                      ret += "encoded succesfully";
++
++                      return ret;
++              }
++
++              ret += "replaced with ";
++              ret += output_filename;
++
++              return ret;
++      }
++
++      if (program_mode == PM_DECOMPRESS) {
++              if (keep) {
++                      ret += "decoded succesfully";
++
++                      return ret;
++              }
++
++              ret += "replaced with ";
++              ret += output_filename;
++
++              return ret;
++      }
++
++      return ret;
++}
++
++static string archive_name; // I know, it is crude, but I haven't found any other
++    // way then making a global variable to transfer filename to handler
++
++void signal_handler (int signum)
++{
++    unlink (archive_name.c_str()); // deleting
++    signal (signum, SIG_DFL); // we return the default function to used signal
++    kill (getpid(), signum); // and then send this signal to the process again
++}
++
++} // namespace lzma
++
++
++int main(int argc, char **argv)
++{
++      using namespace lzma;
++      using std::cerr;
++
++      stringVector filenames;
++
++      signal (SIGTERM,signal_handler);
++      signal (SIGHUP,signal_handler);
++      signal (SIGINT,signal_handler);
++
++      try {
++              parse_options(argc, argv, filenames);
++      }
++      catch (...) {
++              return STATUS_ERROR;
++      }
++
++      if (program_mode == PM_HELP) {
++              print_help(argv[0]);
++              return STATUS_OK;
++      }
++      else if (program_mode == PM_LICENSE) {
++              print_license();
++              return STATUS_OK;
++      }
++      else if (program_mode == PM_VERSION) {
++              print_version();
++              return STATUS_OK;
++      }
++
++      if (filenames.empty()) {
++              stdinput = true;
++              stdoutput = true;
++
++              /* FIXME: get rid of this */
++              filenames.push_back("-");
++      }
++
++      /* Protection: always create new files with 0600 in order to prevent
++       * outsiders from reading incomplete data. */
++      umask(0077);
++
++      bool warning = false;
++
++      for (int i = 0; i < filenames.size(); i++) {
++              CMyComPtr<ISequentialInStream> inStream;
++              CMyComPtr<ISequentialOutStream> outStream;
++              UInt64 fileSize = 0;
++              int inhandle = 0, outhandle = 0;
++              string output_filename;
++
++              if (stdinput) {
++                      inStream = new CStdInFileStream;
++                      MY_SET_BINARY_MODE(stdin);
++                      fileSize = (UInt64)(Int64)-1;
++
++                      inhandle = STDIN_FILENO;
++
++                      outStream = new CStdOutFileStream;
++                      MY_SET_BINARY_MODE(stdout);
++
++                      outhandle = STDOUT_FILENO;
++              }
++              else {
++                      mode_t infile_mode = get_file_mode(filenames[i]);
++                      if (!S_ISREG(infile_mode)) {
++                              if (S_ISDIR(infile_mode)) {
++                                      warning = true;
++                                      cerr << argv[0] << ": " << filenames[i] << ": "
++                                              << "cowardly refusing to work on directory"
++                                              << endl;
++
++                                      continue;
++                              }
++                              else if (S_ISLNK(infile_mode)) {
++                                      if (!stdoutput && !force) {
++                                              warning = true;
++
++                                      cerr << argv[0] << ": " << filenames[i] << ": "
++                                                      << "cowardly refusing to work on symbolic link "
++                                                      << "(use --force to force encoding or decoding)"
++                                                      << endl;
++
++                                              continue;
++                                      }
++                              }
++                              else {
++                                      warning = true;
++
++                                      cerr << argv[0] << ": " << filenames[i] << ": "
++                                              << "doesn't exist or is not a regular file"
++                                              << endl;
++
++                                      continue;
++                              }
++                      }
++
++                      // Test if the file already ends with *suffix.
++                      if (program_mode == PM_COMPRESS && !force
++                                      && string_ends_with(filenames[i],
++                                              suffix)) {
++                              warning = true;
++
++                              cerr << filenames[i] << " already has "
++                                      << suffix << " suffix -- unchanged\n";
++
++                              continue;
++                      }
++
++                      // Test if the file extension is known.
++                      if (program_mode == PM_DECOMPRESS
++                                      && !extension_is_known(filenames[i])) {
++                              warning = true;
++
++                              cerr << filenames[i] << ": "
++                                      << " unknown suffix -- unchanged"
++                                      << endl;
++
++                              continue;
++                      }
++
++                      try {
++                              inhandle = open_instream(filenames[i], inStream, fileSize);
++                      }
++                      catch (Exception e) {
++                              cerr << argv[0] << ": " << e.what() << endl;
++                              return STATUS_ERROR;
++                      }
++
++                      if (stdoutput) {
++                              outStream = new CStdOutFileStream;
++                              MY_SET_BINARY_MODE(stdout);
++
++                              outhandle = STDOUT_FILENO;
++                      }
++                      else {
++                              /* Testing mode is nothing else but decoding
++                               * and throwing away the result. */
++                              if (program_mode == PM_TEST)
++                                      output_filename = "/dev/null";
++                              else if (program_mode == PM_DECOMPRESS)
++                                      output_filename = replace_extension(filenames[i]);
++                              else
++                                      output_filename = filenames[i]
++                                                      + suffix;
++                              archive_name = output_filename;
++
++                              try {
++                                      outhandle = open_outstream(output_filename, outStream);
++                              }
++                              catch (Exception e) {
++                                      cerr << argv[0] << ": " << e.what() << endl;
++                                      return STATUS_ERROR;
++                              }
++                      }
++
++              }
++
++              // Unless --force is specified, do not read/write compressed
++              // data from/to a terminal.
++              if (!force) {
++                      if (program_mode == PM_COMPRESS && isatty(outhandle)) {
++                              cerr << argv[0] << ": compressed data not "
++                                      "written to a terminal. Use "
++                                      "-f to force compression.\n"
++                                      << argv[0] << ": For help, type: "
++                                      << argv[0] << " -h\n";
++                              return STATUS_ERROR;
++                      } else if (program_mode == PM_DECOMPRESS
++                                      && isatty(inhandle)) {
++                              cerr << argv[0] << ": compressed data not "
++                                      "read from a terminal. Use "
++                                      "-f to force decompression.\n"
++                                      << argv[0] << ": For help, type: "
++                                      << argv[0] << " -h\n";
++                              return STATUS_ERROR;
++                      }
++              }
++
++              if (program_mode == PM_COMPRESS) {
++                          NCompress::NLzma::CEncoder *encoderSpec =
++                                    new NCompress::NLzma::CEncoder;
++
++                      lzma_option options = option_mapping[compression_mode];
++
++                      try {
++                              encode(encoderSpec, inStream, outStream, options, fileSize);
++                      }
++                      catch (Exception e) {
++                              cerr << argv[0] << ": " << e.what() << endl;
++                              unlink(output_filename.c_str());
++                              delete(encoderSpec);
++
++                              return STATUS_ERROR;
++                      }
++
++                      delete(encoderSpec);
++              }
++              else {                  // PM_DECOMPRESS | PM_TEST
++                  NCompress::NLzma::CDecoder *decoderSpec =
++                      new NCompress::NLzma::CDecoder;
++
++                      try {
++                              decode(decoderSpec, inStream, outStream);
++                      }
++                      catch (Exception e) {
++                              cerr << argv[0] << ": " << e.what() << endl;
++                              unlink(output_filename.c_str());
++                              delete(decoderSpec);
++
++                              return STATUS_ERROR;
++                      }
++
++                      delete(decoderSpec);
++              }
++
++              /* Set permissions and owners. */
++              if ( (program_mode == PM_COMPRESS || program_mode == PM_DECOMPRESS )
++                              && (!stdinput && !stdoutput) ) {
++
++                      int ret = 0;
++                      struct stat file_stats;
++                      ret = fstat(inhandle, &file_stats);
++
++                      ret = fchmod(outhandle, file_stats.st_mode);
++                      ret = fchown(outhandle, file_stats.st_uid, file_stats.st_gid);
++                      // We need to call fchmod() again, since otherwise the SUID bits
++                      // are lost.
++                      ret = fchmod(outhandle, file_stats.st_mode);
++
++                      struct timeval file_times[2];
++                      // Access time
++                      file_times[0].tv_sec = file_stats.st_atime;
++                      file_times[0].tv_usec = 0;
++                      // Modification time
++                      file_times[1].tv_sec = file_stats.st_mtime;
++                      file_times[1].tv_usec = 0;
++
++                      ret = futimes(outhandle, file_times);
++
++                      if (!keep)
++                              unlink(filenames[i].c_str());
++              }
++
++              if (verbosity > 0) {
++                      if (stdoutput) {
++                              cerr << filenames[i] << ":\t ";
++                              cerr << "decoded succesfully"
++                                      << endl;
++                      }
++
++                      else {
++                              char buf[10] = { 0 };
++
++                              if (program_mode == PM_DECOMPRESS)
++                                      snprintf(buf, 10, "%.2f%%",
++                                                      (1 - get_ratio(outhandle, inhandle)) * 100);
++                              if (program_mode == PM_COMPRESS)
++                                      snprintf(buf, 10, "%.2f%%",
++                                                      (1 - get_ratio(inhandle, outhandle)) * 100);
++
++                              string ratio = buf;
++                              cerr << pretty_print_status(filenames[i], output_filename,
++                                              ratio)
++                                      << endl;
++                      }
++              }
++      }
++
++      if (warning)
++              return STATUS_WARNING;
++
++      return STATUS_OK;
++}
++
+Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h 2009-06-01 22:01:10.000000000 +0200
+@@ -0,0 +1,45 @@
++/* A couple of exceptions for lzmp.
++ *
++ * Copyright (C) 2005 Ville Koskinen
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef _EXCEPTION_H_
++#define _EXCEPTION_H_
++
++#include <string>
++using std::string;
++
++class Exception
++{
++private:
++      string message;
++public:
++      Exception(char *what): message(what) { }
++      Exception(string what): message(what) { }
++
++      ~Exception() { }
++
++      string what(void) { return message; }
++};
++
++class ArgumentException: public Exception
++{
++public:
++      ArgumentException(char *what): Exception(what) { }
++      ArgumentException(string what): Exception(what) { }
++
++      ~ArgumentException() { }
++};
++
++#endif
++
+Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
+===================================================================
+--- lzma-4.65.orig/CPP/7zip/Compress/LZMA_Alone/makefile.gcc   2009-06-01 22:00:54.000000000 +0200
++++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc        2009-06-01 22:06:13.000000000 +0200
+@@ -1,9 +1,10 @@
+-PROG = lzma
++PROG = lzma_alone
++PROG2 = lzma
+ CXX = g++ -O2 -Wall
+ CXX_C = gcc -O2 -Wall
+ LIB = -lm
+ RM = rm -f
+-CFLAGS = -c -D_FILE_OFFSET_BITS=64
++CFLAGS = -c -I ../../../ -D_FILE_OFFSET_BITS=64 -DPACKAGE_VERSION="\"4.32.0beta3\""
+ ifdef SystemDrive
+ IS_MINGW = 1
+@@ -45,12 +46,35 @@
+   Lzma86Dec.o \
+   Lzma86Enc.o \
++OBJS2 = \
++      C_FileIO.o \
++      CRC.o \
++      Alloc.o \
++      FileStreams.o \
++      StreamUtils.o \
++      InBuffer.o \
++      OutBuffer.o \
++      LzmaDecoder.o \
++      StringConvert.o \
++      StringToInt.o \
++      LzmaEncoder.o \
++      LzmaDec.o \
++      LzmaEnc.o \
++      LzFind.o \
++      7zCrc.o \
++      lzmp.o
+-all: $(PROG)
++all: $(PROG) $(PROG2)
+ $(PROG): $(OBJS)
+       $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
++$(PROG2): $(OBJS2)
++      $(CXX) -o $(PROG2) $(LDFLAGS) $(OBJS2) $(LIB)
++
++lzmp.o: lzmp.cpp
++      $(CXX) $(CFLAGS) lzmp.cpp
++
+ LzmaAlone.o: LzmaAlone.cpp
+       $(CXX) $(CFLAGS) LzmaAlone.cpp
+@@ -131,5 +153,5 @@
+       $(CXX_C) $(CFLAGS) ../../../../C/LzmaUtil/Lzma86Enc.c
+ clean:
+-      -$(RM) $(PROG) $(OBJS)
++      -$(RM) $(PROG) $(PROG2) $(OBJS)
+Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h      2009-06-01 22:01:10.000000000 +0200
+@@ -0,0 +1,31 @@
++#ifndef LZMA_VERSION_H
++#define LZMA_VERSION_H
++
++/*
++    Version and copyright information used by LZMA utils.
++*/
++
++static const char *LZMA_SDK_VERSION_STRING = "4.43";
++
++static const char *LZMA_SDK_COPYRIGHT_STRING =
++              "Copyright (C) 1999-2006 Igor Pavlov";
++
++static const char *LZMA_SDK_COPYRIGHT_INFO =
++              "  See http://7-zip.org/sdk.html or the documentation of LZMA SDK for\n"
++              "  the license. For reference, the version 4.43 is free software\n"
++              "  licensed under the GNU LGPL.";
++
++
++static const char *LZMA_UTILS_VERSION_STRING = PACKAGE_VERSION;
++
++static const char *LZMA_UTILS_COPYRIGHT_STRING =
++              "Copyright (C) 2006 Lasse Collin";
++
++static const char *LZMA_UTILS_COPYRIGHT_INFO =
++              "This program comes with ABSOLUTELY NO WARRANTY.\n"
++              "You may redistribute copies of this program\n"
++              "under the terms of the GNU General Public License.\n"
++              "For more information about these matters, see the file "
++              "named COPYING.\n";
++
++#endif /* ifndef LZMA_VERSION_H */
+Index: lzma-4.65/CPP/Common/C_FileIO.h
+===================================================================
+--- lzma-4.65.orig/CPP/Common/C_FileIO.h       2009-05-15 23:33:51.000000000 +0200
++++ lzma-4.65/CPP/Common/C_FileIO.h    2009-06-01 22:06:56.000000000 +0200
+@@ -24,6 +24,7 @@
+   bool Close();
+   bool GetLength(UInt64 &length) const;
+   off_t Seek(off_t distanceToMove, int moveMethod) const;
++  int GetHandle() const { return _handle; }
+ };
+ class CInFile: public CFileBase
diff --git a/tools/lzma/patches/003-compile_fixes.patch b/tools/lzma/patches/003-compile_fixes.patch
new file mode 100644 (file)
index 0000000..49ae66b
--- /dev/null
@@ -0,0 +1,26 @@
+diff -urN lzma-4.65/CPP/7zip/Common/FileStreams.h lzma-4.65.new/CPP/7zip/Common/FileStreams.h
+--- lzma-4.65/CPP/7zip/Common/FileStreams.h    2009-05-15 23:33:51.000000000 +0200
++++ lzma-4.65.new/CPP/7zip/Common/FileStreams.h        2009-06-01 22:30:01.000000000 +0200
+@@ -72,6 +72,7 @@
+   public IOutStream,
+   public CMyUnknownImp
+ {
++public:
+   #ifdef USE_WIN_FILE
+   NWindows::NFile::NIO::COutFile File;
+   #else
+diff -urN lzma-4.65/CPP/Common/MyWindows.h lzma-4.65.new/CPP/Common/MyWindows.h
+--- lzma-4.65/CPP/Common/MyWindows.h   2009-05-15 23:33:51.000000000 +0200
++++ lzma-4.65.new/CPP/Common/MyWindows.h       2009-06-01 22:29:26.000000000 +0200
+@@ -101,8 +101,11 @@
+ #ifdef __cplusplus
++#ifndef INITGUID
++#define INITGUID
+ DEFINE_GUID(IID_IUnknown,
+ 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
++#endif
+ struct IUnknown
+ {
+   STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;