002-lzmp.patch 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp
  2. ===================================================================
  3. --- /dev/null 1970-01-01 00:00:00.000000000 +0000
  4. +++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp 2009-06-01 22:01:10.000000000 +0200
  5. @@ -0,0 +1,895 @@
  6. +/*
  7. + * LZMA command line tool similar to gzip to encode and decode LZMA files.
  8. + *
  9. + * Copyright (C) 2005 Ville Koskinen
  10. + *
  11. + * This program is free software; you can redistribute it and/or
  12. + * modify it under the terms of the GNU General Public License
  13. + * as published by the Free Software Foundation; either version 2
  14. + * of the License, or (at your option) any later version.
  15. + *
  16. + * This program is distributed in the hope that it will be useful,
  17. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. + * GNU General Public License for more details.
  20. + *
  21. + * You should have received a copy of the GNU General Public License
  22. + * along with this program; if not, write to the Free Software
  23. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  24. + * USA.
  25. + */
  26. +
  27. +#include "../../../Common/MyInitGuid.h"
  28. +
  29. +#include <iostream>
  30. +using std::cout;
  31. +using std::cerr;
  32. +using std::endl;
  33. +
  34. +#include <cstdio>
  35. +#include <cstdlib>
  36. +#include <cstring>
  37. +
  38. +#include <string>
  39. +using std::string;
  40. +#include <vector>
  41. +using std::vector;
  42. +typedef vector<string> stringVector;
  43. +
  44. +#include <unistd.h>
  45. +#include <getopt.h>
  46. +#include <signal.h>
  47. +
  48. +#include <sys/types.h>
  49. +#include <sys/stat.h>
  50. +#include <utime.h>
  51. +#include <sys/time.h> // futimes()
  52. +
  53. +// For Solaris
  54. +#ifndef HAVE_FUTIMES
  55. +//#define futimes(fd, tv) futimesat(fd, NULL, tv)
  56. +#endif
  57. +
  58. +#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
  59. +#include <fcntl.h>
  60. +#include <io.h>
  61. +#define MY_SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
  62. +#else
  63. +#define MY_SET_BINARY_MODE(file)
  64. +#endif
  65. +
  66. +#include "../../../7zip/Common/FileStreams.h"
  67. +
  68. +#include "../../../Common/Types.h"
  69. +
  70. +#include "../../../7zip/Compress/LzmaDecoder.h"
  71. +#include "../../../7zip/Compress/LzmaEncoder.h"
  72. +
  73. +#include "Exception.h"
  74. +
  75. +#include "lzma_version.h"
  76. +
  77. +namespace lzma {
  78. +
  79. +const char *PROGRAM_VERSION = PACKAGE_VERSION;
  80. +const char *PROGRAM_COPYRIGHT = "Copyright (C) 2006 Ville Koskinen";
  81. +
  82. +/* LZMA_Alone switches:
  83. + -a{N}: set compression mode - [0, 2], default: 2 (max)
  84. + -d{N}: set dictionary - [0,28], default: 23 (8MB)
  85. + -fb{N}: set number of fast bytes - [5, 255], default: 128
  86. + -lc{N}: set number of literal context bits - [0, 8], default: 3
  87. + -lp{N}: set number of literal pos bits - [0, 4], default: 0
  88. + -pb{N}: set number of pos bits - [0, 4], default: 2
  89. + -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, bt4b, pat2r, pat2,
  90. + pat2h, pat3h, pat4h, hc3, hc4], default: bt4
  91. +*/
  92. +
  93. +struct lzma_option {
  94. + short compression_mode; // -a
  95. + short dictionary; // -d
  96. + short fast_bytes; // -fb
  97. + wchar_t *match_finder; // -mf
  98. + short literal_context_bits; // -lc
  99. + short literal_pos_bits; // -lp
  100. + short pos_bits; // -pb
  101. +};
  102. +
  103. +/* The following is a mapping from gzip/bzip2 style -1 .. -9 compression modes
  104. + * to the corresponding LZMA compression modes. Thanks, Larhzu, for coining
  105. + * these. */
  106. +const lzma_option option_mapping[] = {
  107. + { 0, 0, 0, NULL, 0, 0, 0}, // -0 (needed for indexing)
  108. + { 0, 16, 64, L"hc4", 3, 0, 2}, // -1
  109. + { 0, 20, 64, L"hc4", 3, 0, 2}, // -2
  110. + { 1, 19, 64, L"bt4", 3, 0, 2}, // -3
  111. + { 2, 20, 64, L"bt4", 3, 0, 2}, // -4
  112. + { 2, 21, 128, L"bt4", 3, 0, 2}, // -5
  113. + { 2, 22, 128, L"bt4", 3, 0, 2}, // -6
  114. + { 2, 23, 128, L"bt4", 3, 0, 2}, // -7
  115. + { 2, 24, 255, L"bt4", 3, 0, 2}, // -8
  116. + { 2, 25, 255, L"bt4", 3, 0, 2}, // -9
  117. +};
  118. +
  119. +struct extension_pair {
  120. + char *from;
  121. + char *to;
  122. +};
  123. +
  124. +const extension_pair known_extensions[] = {
  125. + { ".lzma", "" },
  126. + { ".tlz", ".tar" },
  127. + { NULL, NULL }
  128. +};
  129. +
  130. +/* Sorry, I just happen to like enumerations. */
  131. +enum PROGRAM_MODE {
  132. + PM_COMPRESS = 0,
  133. + PM_DECOMPRESS,
  134. + PM_TEST,
  135. + PM_HELP,
  136. + PM_LICENSE,
  137. + PM_VERSION
  138. +};
  139. +
  140. +enum {
  141. + STATUS_OK = 0,
  142. + STATUS_ERROR = 1,
  143. + STATUS_WARNING = 2
  144. +};
  145. +
  146. +/* getopt options. */
  147. +/* struct option { name, has_arg, flag, val } */
  148. +const struct option long_options[] = {
  149. + { "stdout", 0, 0, 'c' },
  150. + { "decompress", 0, 0, 'd' },
  151. + { "compress", 0, 0, 'z' },
  152. + { "keep", 0, 0, 'k' },
  153. + { "force", 0, 0, 'f' },
  154. + { "test", 0, 0, 't' },
  155. + { "suffix", 1, 0, 'S' },
  156. + { "quiet", 0, 0, 'q' },
  157. + { "verbose", 0, 0, 'v' },
  158. + { "help", 0, 0, 'h' },
  159. + { "license", 0, 0, 'L' },
  160. + { "version", 0, 0, 'V' },
  161. + { "fast", 0, 0, '1' },
  162. + { "best", 0, 0, '9' },
  163. + { 0, 0, 0, 0 }
  164. +};
  165. +
  166. +/* getopt option string (for the above options). */
  167. +const char option_string[] = "cdzkftS:qvhLV123456789A:D:F:";
  168. +
  169. +/* Defaults. */
  170. +PROGRAM_MODE program_mode = PM_COMPRESS;
  171. +int verbosity = 0;
  172. +bool stdinput = false;
  173. +bool stdoutput = false;
  174. +bool keep = false;
  175. +bool force = false;
  176. +int compression_mode = 7;
  177. +//char *suffix = strdup(".lzma");
  178. +char *suffix = strdup(known_extensions[0].from);
  179. +lzma_option advanced_options = { -1, -1, -1, NULL, -1, -1, -1 };
  180. +
  181. +void print_help(const char *const argv0)
  182. +{
  183. + // Help goes to stdout while other messages go to stderr.
  184. + cout << "\nlzma " << PROGRAM_VERSION
  185. + << " " << PROGRAM_COPYRIGHT << "\n"
  186. + "Based on LZMA SDK " << LZMA_SDK_VERSION_STRING << " "
  187. + << LZMA_SDK_COPYRIGHT_STRING
  188. + << "\n\nUsage: " << argv0
  189. + << " [flags and input files in any order]\n"
  190. +" -c --stdout output to standard output\n"
  191. +" -d --decompress force decompression\n"
  192. +" -z --compress force compression\n"
  193. +" -k --keep keep (don't delete) input files\n"
  194. +" -f --force force overwrite of output file and compress links\n"
  195. +" -t --test test compressed file integrity\n"
  196. +" -S .suf --suffix .suf use suffix .suf on compressed files\n"
  197. +" -q --quiet suppress error messages\n"
  198. +" -v --verbose be verbose\n"
  199. +" -h --help print this message\n"
  200. +" -L --license display the license information\n"
  201. +" -V --version display version numbers of LZMA SDK and lzma\n"
  202. +" -1 .. -2 fast compression\n"
  203. +" -3 .. -9 good to excellent compression. -7 is the default.\n"
  204. +" --fast alias for -1\n"
  205. +" --best alias for -9 (usually *not* what you want)\n\n"
  206. +" Memory usage depends a lot on the chosen compression mode -1 .. -9.\n"
  207. +" See the man page lzma(1) for details.\n\n";
  208. +}
  209. +
  210. +void print_license(void)
  211. +{
  212. + cout << "\n LZMA command line tool " << PROGRAM_VERSION << " - "
  213. + << PROGRAM_COPYRIGHT
  214. + << "\n LZMA SDK " << LZMA_SDK_VERSION_STRING << " - "
  215. + << LZMA_SDK_COPYRIGHT_STRING
  216. + << "\n This program is a part of the LZMA utils package.\n"
  217. + " http://tukaani.org/lzma/\n\n"
  218. +" This program is free software; you can redistribute it and/or\n"
  219. +" modify it under the terms of the GNU General Public License\n"
  220. +" as published by the Free Software Foundation; either version 2\n"
  221. +" of the License, or (at your option) any later version.\n"
  222. +"\n"
  223. +" This program is distributed in the hope that it will be useful,\n"
  224. +" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  225. +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
  226. +" GNU General Public License for more details.\n"
  227. +"\n";
  228. +}
  229. +
  230. +void print_version(void)
  231. +{
  232. + cout << "LZMA command line tool " << PROGRAM_VERSION << "\n"
  233. + << "LZMA SDK " << LZMA_SDK_VERSION_STRING << "\n";
  234. +}
  235. +
  236. +short str2int (const char *str, const int &min, const int &max)
  237. +{
  238. + int value = -1;
  239. + char *endptr = NULL;
  240. + if (str == NULL || str[0] == '\0')
  241. + throw ArgumentException("Invalid integer option");
  242. + value = strtol (str, &endptr, 10);
  243. + if (*endptr != '\0' || value < min || value > max)
  244. + throw ArgumentException("Invalid integer option");
  245. + return value;
  246. +}
  247. +
  248. +void parse_options(int argc, char **argv, stringVector &filenames)
  249. +{
  250. + /* Snatched from getopt(3). */
  251. + int c;
  252. +
  253. + /* Check how we were called */
  254. + {
  255. + char *p = strrchr (argv[0], '/'); // Remove path prefix, if any
  256. + if (p++ == NULL)
  257. + p = argv[0];
  258. + if (strstr (p, "un") != NULL) {
  259. + program_mode = PM_DECOMPRESS;
  260. + } else if (strstr (p, "cat") != NULL) {
  261. + program_mode = PM_DECOMPRESS;
  262. + stdoutput = true;
  263. + }
  264. + }
  265. +
  266. + while (-1 != (c = getopt_long(argc, argv, option_string,
  267. + long_options, NULL))) {
  268. + switch (c) {
  269. + // stdout
  270. + case 'c':
  271. + stdoutput = true;
  272. + break;
  273. +
  274. + // decompress
  275. + case 'd':
  276. + program_mode = PM_DECOMPRESS;
  277. + break;
  278. +
  279. + // compress
  280. + case 'z':
  281. + program_mode = PM_COMPRESS;
  282. + break;
  283. +
  284. + // keep
  285. + case 'k':
  286. + keep = true;
  287. + break;
  288. +
  289. + // force
  290. + case 'f':
  291. + force = true;
  292. + break;
  293. +
  294. + // test
  295. + case 't':
  296. + program_mode = PM_TEST;
  297. + break;
  298. +
  299. + // suffix
  300. + case 'S':
  301. + if (optarg) {
  302. + free(suffix);
  303. + suffix = strdup(optarg);
  304. + }
  305. + break;
  306. +
  307. + // quiet
  308. + case 'q':
  309. + verbosity = 0;
  310. + break;
  311. +
  312. + // verbose
  313. + case 'v':
  314. + verbosity++;
  315. + break;
  316. +
  317. + // help
  318. + case 'h':
  319. + program_mode = PM_HELP;
  320. + break;
  321. +
  322. + // license
  323. + case 'L':
  324. + program_mode = PM_LICENSE;
  325. + break;
  326. +
  327. + // version
  328. + case 'V':
  329. + program_mode = PM_VERSION;
  330. + break;
  331. +
  332. + case '1': case '2': case '3': case '4': case '5':
  333. + case '6': case '7': case '8': case '9':
  334. + compression_mode = c - '0';
  335. + break;
  336. +
  337. + // Advanced options //
  338. + // Compression mode
  339. + case 'A':
  340. + advanced_options.compression_mode =
  341. + str2int (optarg, 0, 2);
  342. + break;
  343. +
  344. + // Dictionary size
  345. + case 'D':
  346. + advanced_options.dictionary =
  347. + str2int (optarg, 0, 28);
  348. + break;
  349. +
  350. + // Fast bytes
  351. + case 'F':
  352. + advanced_options.fast_bytes =
  353. + str2int (optarg, 0, 273);
  354. + break;
  355. +
  356. + default:
  357. + throw ArgumentException("");
  358. + break;
  359. + } // switch(c)
  360. + } // while(1)
  361. +
  362. + for (int i = optind; i < argc; i++) {
  363. + if (strcmp("-", argv[i]) == 0)
  364. + continue;
  365. + filenames.push_back(argv[i]);
  366. + }
  367. +} // parse_options
  368. +
  369. +void set_encoder_properties(NCompress::NLzma::CEncoder *encoder,
  370. + lzma_option &opt)
  371. +{
  372. + /* Almost verbatim from LzmaAlone.cpp. */
  373. + PROPID propIDs[] =
  374. + {
  375. + NCoderPropID::kDictionarySize,
  376. + NCoderPropID::kPosStateBits,
  377. + NCoderPropID::kLitContextBits,
  378. + NCoderPropID::kLitPosBits,
  379. + NCoderPropID::kAlgorithm,
  380. + NCoderPropID::kNumFastBytes,
  381. + NCoderPropID::kMatchFinder,
  382. + NCoderPropID::kEndMarker
  383. + };
  384. + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
  385. +#define VALUE(x) (advanced_options.x >= 0 ? advanced_options.x : opt.x)
  386. + PROPVARIANT properties[kNumProps];
  387. + for (int p = 0; p < 6; p++)
  388. + properties[p].vt = VT_UI4;
  389. + properties[0].ulVal = UInt32(1 << VALUE (dictionary));
  390. + properties[1].ulVal = UInt32(VALUE (pos_bits));
  391. + properties[2].ulVal = UInt32(VALUE (literal_context_bits));
  392. + properties[3].ulVal = UInt32(VALUE (literal_pos_bits));
  393. + properties[4].ulVal = UInt32(VALUE (compression_mode));
  394. + properties[5].ulVal = UInt32(VALUE (fast_bytes));
  395. +#undef VALUE
  396. +
  397. + properties[6].vt = VT_BSTR;
  398. + properties[6].bstrVal = (BSTR)opt.match_finder;
  399. +
  400. + properties[7].vt = VT_BOOL;
  401. + properties[7].boolVal = stdinput ? VARIANT_TRUE : VARIANT_FALSE;
  402. +
  403. + if (encoder->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
  404. + throw Exception("SetCoderProperties() error");
  405. +}
  406. +
  407. +void encode(NCompress::NLzma::CEncoder *encoderSpec,
  408. + CMyComPtr<ISequentialInStream> inStream,
  409. + CMyComPtr<ISequentialOutStream> outStream,
  410. + lzma_option encoder_options,
  411. + UInt64 fileSize)
  412. +{
  413. + set_encoder_properties(encoderSpec, encoder_options);
  414. +
  415. + encoderSpec->WriteCoderProperties(outStream);
  416. +
  417. + for (int i = 0; i < 8; i++)
  418. + {
  419. + Byte b = Byte(fileSize >> (8 * i));
  420. + if (outStream->Write(&b, sizeof(b), 0) != S_OK)
  421. + throw Exception("Write error while encoding");
  422. + }
  423. +
  424. + HRESULT result = encoderSpec->Code(inStream, outStream, 0, 0, 0);
  425. +
  426. + if (result == E_OUTOFMEMORY)
  427. + throw Exception("Cannot allocate memory");
  428. + else if (result != S_OK) {
  429. + char buffer[33];
  430. + snprintf(buffer, 33, "%d", (unsigned int)result);
  431. + throw Exception(string("Encoder error: ") + buffer);
  432. + }
  433. +}
  434. +
  435. +void decode(NCompress::NLzma::CDecoder *decoderSpec,
  436. + CMyComPtr<ISequentialInStream> inStream,
  437. + CMyComPtr<ISequentialOutStream> outStream)
  438. +{
  439. + const UInt32 kPropertiesSize = 5;
  440. + Byte properties[kPropertiesSize];
  441. + UInt32 processedSize;
  442. + UInt64 fileSize = 0;
  443. +
  444. + if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK)
  445. + throw Exception("Read error");
  446. + if (processedSize != kPropertiesSize)
  447. + throw Exception("Read error");
  448. + if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
  449. + throw Exception("SetDecoderProperties() error");
  450. +
  451. + for (int i = 0; i < 8; i++)
  452. + {
  453. + Byte b;
  454. +
  455. + if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK)
  456. + throw Exception("Read error");
  457. + if (processedSize != 1)
  458. + throw Exception("Read error");
  459. +
  460. + fileSize |= ((UInt64)b) << (8 * i);
  461. + }
  462. +
  463. + if (decoderSpec->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
  464. + throw Exception("Decoder error");
  465. +}
  466. +
  467. +int open_instream(const string infile,
  468. + CMyComPtr<ISequentialInStream> &inStream,
  469. + UInt64 &fileSize)
  470. +{
  471. + CInFileStream *inStreamSpec = new CInFileStream;
  472. + inStream = inStreamSpec;
  473. + if (!inStreamSpec->Open(infile.c_str()))
  474. + throw Exception("Cannot open input file " + infile);
  475. +
  476. + inStreamSpec->File.GetLength(fileSize);
  477. +
  478. + return inStreamSpec->File.GetHandle();
  479. +}
  480. +
  481. +int open_outstream(const string outfile,
  482. + CMyComPtr<ISequentialOutStream> &outStream)
  483. +{
  484. + COutFileStream *outStreamSpec = new COutFileStream;
  485. + outStream = outStreamSpec;
  486. +
  487. + bool open_by_force = (program_mode == PM_TEST) | force;
  488. +
  489. + if (!outStreamSpec->Create(outfile.c_str(), open_by_force))
  490. + throw Exception("Cannot open output file " + outfile);
  491. +
  492. + return outStreamSpec->File.GetHandle();
  493. +}
  494. +
  495. +double get_ratio(int inhandle, int outhandle)
  496. +{
  497. + struct stat in_stats, out_stats;
  498. + fstat(inhandle, &in_stats);
  499. + fstat(outhandle, &out_stats);
  500. +
  501. + return (double)out_stats.st_size / (double)in_stats.st_size;
  502. +}
  503. +
  504. +mode_t get_file_mode(string filename)
  505. +{
  506. + struct stat in_stat;
  507. + lstat(filename.c_str(), &in_stat);
  508. +
  509. + return in_stat.st_mode;
  510. +}
  511. +
  512. +bool string_ends_with(string str, string ending)
  513. +{
  514. + return equal(ending.rbegin(), ending.rend(), str.rbegin());
  515. +}
  516. +
  517. +bool extension_is_known(string filename)
  518. +{
  519. + bool known_format = false;
  520. + extension_pair extension; int i = 1;
  521. +
  522. + extension = known_extensions[0];
  523. + while (extension.from != NULL) {
  524. + if (string_ends_with(filename, extension.from)) {
  525. + known_format = true;
  526. + break;
  527. + }
  528. + extension = known_extensions[i];
  529. + i++;
  530. + }
  531. +
  532. + if (!known_format) {
  533. + if (!string_ends_with(filename, suffix)) {
  534. + return false;
  535. + }
  536. + }
  537. +
  538. + return true;
  539. +}
  540. +
  541. +string replace_extension(string filename)
  542. +{
  543. + int suffix_starts_at = filename.length() - strlen (suffix);
  544. + string from_suffix = filename.substr(suffix_starts_at, strlen (suffix));
  545. + string ret = filename.substr(0, suffix_starts_at);
  546. + extension_pair extension; int i = 1;
  547. +
  548. + bool found_replacement = false;
  549. + extension = known_extensions[0];
  550. + while (extension.from != NULL) {
  551. + if (from_suffix.compare(extension.from) == 0) {
  552. + ret += extension.to;
  553. + found_replacement = true;
  554. + break;
  555. + }
  556. +
  557. + extension = known_extensions[i];
  558. + i++;
  559. + }
  560. +
  561. + return ret;
  562. +}
  563. +
  564. +string pretty_print_status(string filename, string output_filename,
  565. + string ratio)
  566. +{
  567. + string ret = "";
  568. +
  569. + ret += filename;
  570. + ret += ":\t ";
  571. +
  572. + if (program_mode == PM_TEST) {
  573. + ret += "decoded succesfully";
  574. +
  575. + return ret;
  576. + }
  577. +
  578. + if (!stdinput && !stdoutput) {
  579. + ret += ratio;
  580. + ret += " -- ";
  581. + }
  582. +
  583. + if (program_mode == PM_COMPRESS) {
  584. + if (keep) {
  585. + ret += "encoded succesfully";
  586. +
  587. + return ret;
  588. + }
  589. +
  590. + ret += "replaced with ";
  591. + ret += output_filename;
  592. +
  593. + return ret;
  594. + }
  595. +
  596. + if (program_mode == PM_DECOMPRESS) {
  597. + if (keep) {
  598. + ret += "decoded succesfully";
  599. +
  600. + return ret;
  601. + }
  602. +
  603. + ret += "replaced with ";
  604. + ret += output_filename;
  605. +
  606. + return ret;
  607. + }
  608. +
  609. + return ret;
  610. +}
  611. +
  612. +static string archive_name; // I know, it is crude, but I haven't found any other
  613. + // way then making a global variable to transfer filename to handler
  614. +
  615. +void signal_handler (int signum)
  616. +{
  617. + unlink (archive_name.c_str()); // deleting
  618. + signal (signum, SIG_DFL); // we return the default function to used signal
  619. + kill (getpid(), signum); // and then send this signal to the process again
  620. +}
  621. +
  622. +} // namespace lzma
  623. +
  624. +
  625. +int main(int argc, char **argv)
  626. +{
  627. + using namespace lzma;
  628. + using std::cerr;
  629. +
  630. + stringVector filenames;
  631. +
  632. + signal (SIGTERM,signal_handler);
  633. + signal (SIGHUP,signal_handler);
  634. + signal (SIGINT,signal_handler);
  635. +
  636. + try {
  637. + parse_options(argc, argv, filenames);
  638. + }
  639. + catch (...) {
  640. + return STATUS_ERROR;
  641. + }
  642. +
  643. + if (program_mode == PM_HELP) {
  644. + print_help(argv[0]);
  645. + return STATUS_OK;
  646. + }
  647. + else if (program_mode == PM_LICENSE) {
  648. + print_license();
  649. + return STATUS_OK;
  650. + }
  651. + else if (program_mode == PM_VERSION) {
  652. + print_version();
  653. + return STATUS_OK;
  654. + }
  655. +
  656. + if (filenames.empty()) {
  657. + stdinput = true;
  658. + stdoutput = true;
  659. +
  660. + /* FIXME: get rid of this */
  661. + filenames.push_back("-");
  662. + }
  663. +
  664. + /* Protection: always create new files with 0600 in order to prevent
  665. + * outsiders from reading incomplete data. */
  666. + umask(0077);
  667. +
  668. + bool warning = false;
  669. +
  670. + for (int i = 0; i < filenames.size(); i++) {
  671. + CMyComPtr<ISequentialInStream> inStream;
  672. + CMyComPtr<ISequentialOutStream> outStream;
  673. + UInt64 fileSize = 0;
  674. + int inhandle = 0, outhandle = 0;
  675. + string output_filename;
  676. +
  677. + if (stdinput) {
  678. + inStream = new CStdInFileStream;
  679. + MY_SET_BINARY_MODE(stdin);
  680. + fileSize = (UInt64)(Int64)-1;
  681. +
  682. + inhandle = STDIN_FILENO;
  683. +
  684. + outStream = new CStdOutFileStream;
  685. + MY_SET_BINARY_MODE(stdout);
  686. +
  687. + outhandle = STDOUT_FILENO;
  688. + }
  689. + else {
  690. + mode_t infile_mode = get_file_mode(filenames[i]);
  691. + if (!S_ISREG(infile_mode)) {
  692. + if (S_ISDIR(infile_mode)) {
  693. + warning = true;
  694. + cerr << argv[0] << ": " << filenames[i] << ": "
  695. + << "cowardly refusing to work on directory"
  696. + << endl;
  697. +
  698. + continue;
  699. + }
  700. + else if (S_ISLNK(infile_mode)) {
  701. + if (!stdoutput && !force) {
  702. + warning = true;
  703. +
  704. + cerr << argv[0] << ": " << filenames[i] << ": "
  705. + << "cowardly refusing to work on symbolic link "
  706. + << "(use --force to force encoding or decoding)"
  707. + << endl;
  708. +
  709. + continue;
  710. + }
  711. + }
  712. + else {
  713. + warning = true;
  714. +
  715. + cerr << argv[0] << ": " << filenames[i] << ": "
  716. + << "doesn't exist or is not a regular file"
  717. + << endl;
  718. +
  719. + continue;
  720. + }
  721. + }
  722. +
  723. + // Test if the file already ends with *suffix.
  724. + if (program_mode == PM_COMPRESS && !force
  725. + && string_ends_with(filenames[i],
  726. + suffix)) {
  727. + warning = true;
  728. +
  729. + cerr << filenames[i] << " already has "
  730. + << suffix << " suffix -- unchanged\n";
  731. +
  732. + continue;
  733. + }
  734. +
  735. + // Test if the file extension is known.
  736. + if (program_mode == PM_DECOMPRESS
  737. + && !extension_is_known(filenames[i])) {
  738. + warning = true;
  739. +
  740. + cerr << filenames[i] << ": "
  741. + << " unknown suffix -- unchanged"
  742. + << endl;
  743. +
  744. + continue;
  745. + }
  746. +
  747. + try {
  748. + inhandle = open_instream(filenames[i], inStream, fileSize);
  749. + }
  750. + catch (Exception e) {
  751. + cerr << argv[0] << ": " << e.what() << endl;
  752. + return STATUS_ERROR;
  753. + }
  754. +
  755. + if (stdoutput) {
  756. + outStream = new CStdOutFileStream;
  757. + MY_SET_BINARY_MODE(stdout);
  758. +
  759. + outhandle = STDOUT_FILENO;
  760. + }
  761. + else {
  762. + /* Testing mode is nothing else but decoding
  763. + * and throwing away the result. */
  764. + if (program_mode == PM_TEST)
  765. + output_filename = "/dev/null";
  766. + else if (program_mode == PM_DECOMPRESS)
  767. + output_filename = replace_extension(filenames[i]);
  768. + else
  769. + output_filename = filenames[i]
  770. + + suffix;
  771. + archive_name = output_filename;
  772. +
  773. + try {
  774. + outhandle = open_outstream(output_filename, outStream);
  775. + }
  776. + catch (Exception e) {
  777. + cerr << argv[0] << ": " << e.what() << endl;
  778. + return STATUS_ERROR;
  779. + }
  780. + }
  781. +
  782. + }
  783. +
  784. + // Unless --force is specified, do not read/write compressed
  785. + // data from/to a terminal.
  786. + if (!force) {
  787. + if (program_mode == PM_COMPRESS && isatty(outhandle)) {
  788. + cerr << argv[0] << ": compressed data not "
  789. + "written to a terminal. Use "
  790. + "-f to force compression.\n"
  791. + << argv[0] << ": For help, type: "
  792. + << argv[0] << " -h\n";
  793. + return STATUS_ERROR;
  794. + } else if (program_mode == PM_DECOMPRESS
  795. + && isatty(inhandle)) {
  796. + cerr << argv[0] << ": compressed data not "
  797. + "read from a terminal. Use "
  798. + "-f to force decompression.\n"
  799. + << argv[0] << ": For help, type: "
  800. + << argv[0] << " -h\n";
  801. + return STATUS_ERROR;
  802. + }
  803. + }
  804. +
  805. + if (program_mode == PM_COMPRESS) {
  806. + NCompress::NLzma::CEncoder *encoderSpec =
  807. + new NCompress::NLzma::CEncoder;
  808. +
  809. + lzma_option options = option_mapping[compression_mode];
  810. +
  811. + try {
  812. + encode(encoderSpec, inStream, outStream, options, fileSize);
  813. + }
  814. + catch (Exception e) {
  815. + cerr << argv[0] << ": " << e.what() << endl;
  816. + unlink(output_filename.c_str());
  817. + delete(encoderSpec);
  818. +
  819. + return STATUS_ERROR;
  820. + }
  821. +
  822. + delete(encoderSpec);
  823. + }
  824. + else { // PM_DECOMPRESS | PM_TEST
  825. + NCompress::NLzma::CDecoder *decoderSpec =
  826. + new NCompress::NLzma::CDecoder;
  827. +
  828. + try {
  829. + decode(decoderSpec, inStream, outStream);
  830. + }
  831. + catch (Exception e) {
  832. + cerr << argv[0] << ": " << e.what() << endl;
  833. + unlink(output_filename.c_str());
  834. + delete(decoderSpec);
  835. +
  836. + return STATUS_ERROR;
  837. + }
  838. +
  839. + delete(decoderSpec);
  840. + }
  841. +
  842. + /* Set permissions and owners. */
  843. + if ( (program_mode == PM_COMPRESS || program_mode == PM_DECOMPRESS )
  844. + && (!stdinput && !stdoutput) ) {
  845. +
  846. + int ret = 0;
  847. + struct stat file_stats;
  848. + ret = fstat(inhandle, &file_stats);
  849. +
  850. + ret = fchmod(outhandle, file_stats.st_mode);
  851. + ret = fchown(outhandle, file_stats.st_uid, file_stats.st_gid);
  852. + // We need to call fchmod() again, since otherwise the SUID bits
  853. + // are lost.
  854. + ret = fchmod(outhandle, file_stats.st_mode);
  855. +
  856. + struct timeval file_times[2];
  857. + // Access time
  858. + file_times[0].tv_sec = file_stats.st_atime;
  859. + file_times[0].tv_usec = 0;
  860. + // Modification time
  861. + file_times[1].tv_sec = file_stats.st_mtime;
  862. + file_times[1].tv_usec = 0;
  863. +
  864. + ret = futimes(outhandle, file_times);
  865. +
  866. + if (!keep)
  867. + unlink(filenames[i].c_str());
  868. + }
  869. +
  870. + if (verbosity > 0) {
  871. + if (stdoutput) {
  872. + cerr << filenames[i] << ":\t ";
  873. + cerr << "decoded succesfully"
  874. + << endl;
  875. + }
  876. +
  877. + else {
  878. + char buf[10] = { 0 };
  879. +
  880. + if (program_mode == PM_DECOMPRESS)
  881. + snprintf(buf, 10, "%.2f%%",
  882. + (1 - get_ratio(outhandle, inhandle)) * 100);
  883. + if (program_mode == PM_COMPRESS)
  884. + snprintf(buf, 10, "%.2f%%",
  885. + (1 - get_ratio(inhandle, outhandle)) * 100);
  886. +
  887. + string ratio = buf;
  888. + cerr << pretty_print_status(filenames[i], output_filename,
  889. + ratio)
  890. + << endl;
  891. + }
  892. + }
  893. + }
  894. +
  895. + if (warning)
  896. + return STATUS_WARNING;
  897. +
  898. + return STATUS_OK;
  899. +}
  900. +
  901. Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h
  902. ===================================================================
  903. --- /dev/null 1970-01-01 00:00:00.000000000 +0000
  904. +++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h 2009-06-01 22:01:10.000000000 +0200
  905. @@ -0,0 +1,45 @@
  906. +/* A couple of exceptions for lzmp.
  907. + *
  908. + * Copyright (C) 2005 Ville Koskinen
  909. + *
  910. + * This program is free software; you can redistribute it and/or
  911. + * modify it under the terms of the GNU General Public License
  912. + * as published by the Free Software Foundation; either version 2
  913. + * of the License, or (at your option) any later version.
  914. + *
  915. + * This program is distributed in the hope that it will be useful,
  916. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  917. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  918. + * GNU General Public License for more details.
  919. + */
  920. +
  921. +#ifndef _EXCEPTION_H_
  922. +#define _EXCEPTION_H_
  923. +
  924. +#include <string>
  925. +using std::string;
  926. +
  927. +class Exception
  928. +{
  929. +private:
  930. + string message;
  931. +public:
  932. + Exception(char *what): message(what) { }
  933. + Exception(string what): message(what) { }
  934. +
  935. + ~Exception() { }
  936. +
  937. + string what(void) { return message; }
  938. +};
  939. +
  940. +class ArgumentException: public Exception
  941. +{
  942. +public:
  943. + ArgumentException(char *what): Exception(what) { }
  944. + ArgumentException(string what): Exception(what) { }
  945. +
  946. + ~ArgumentException() { }
  947. +};
  948. +
  949. +#endif
  950. +
  951. Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
  952. ===================================================================
  953. --- lzma-4.65.orig/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2009-06-01 22:00:54.000000000 +0200
  954. +++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2009-06-01 22:06:13.000000000 +0200
  955. @@ -1,9 +1,10 @@
  956. -PROG = lzma
  957. +PROG = lzma_alone
  958. +PROG2 = lzma
  959. CXX = g++ -O2 -Wall
  960. CXX_C = gcc -O2 -Wall
  961. LIB = -lm
  962. RM = rm -f
  963. -CFLAGS = -c -D_FILE_OFFSET_BITS=64
  964. +CFLAGS = -c -I ../../../ -D_FILE_OFFSET_BITS=64 -DPACKAGE_VERSION="\"4.32.0beta3\""
  965. ifdef SystemDrive
  966. IS_MINGW = 1
  967. @@ -45,12 +46,35 @@
  968. Lzma86Dec.o \
  969. Lzma86Enc.o \
  970. +OBJS2 = \
  971. + C_FileIO.o \
  972. + CRC.o \
  973. + Alloc.o \
  974. + FileStreams.o \
  975. + StreamUtils.o \
  976. + InBuffer.o \
  977. + OutBuffer.o \
  978. + LzmaDecoder.o \
  979. + StringConvert.o \
  980. + StringToInt.o \
  981. + LzmaEncoder.o \
  982. + LzmaDec.o \
  983. + LzmaEnc.o \
  984. + LzFind.o \
  985. + 7zCrc.o \
  986. + lzmp.o
  987. -all: $(PROG)
  988. +all: $(PROG) $(PROG2)
  989. $(PROG): $(OBJS)
  990. $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
  991. +$(PROG2): $(OBJS2)
  992. + $(CXX) -o $(PROG2) $(LDFLAGS) $(OBJS2) $(LIB)
  993. +
  994. +lzmp.o: lzmp.cpp
  995. + $(CXX) $(CFLAGS) lzmp.cpp
  996. +
  997. LzmaAlone.o: LzmaAlone.cpp
  998. $(CXX) $(CFLAGS) LzmaAlone.cpp
  999. @@ -131,5 +153,5 @@
  1000. $(CXX_C) $(CFLAGS) ../../../../C/LzmaUtil/Lzma86Enc.c
  1001. clean:
  1002. - -$(RM) $(PROG) $(OBJS)
  1003. + -$(RM) $(PROG) $(PROG2) $(OBJS)
  1004. Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h
  1005. ===================================================================
  1006. --- /dev/null 1970-01-01 00:00:00.000000000 +0000
  1007. +++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h 2009-06-01 22:01:10.000000000 +0200
  1008. @@ -0,0 +1,31 @@
  1009. +#ifndef LZMA_VERSION_H
  1010. +#define LZMA_VERSION_H
  1011. +
  1012. +/*
  1013. + Version and copyright information used by LZMA utils.
  1014. +*/
  1015. +
  1016. +static const char *LZMA_SDK_VERSION_STRING = "4.43";
  1017. +
  1018. +static const char *LZMA_SDK_COPYRIGHT_STRING =
  1019. + "Copyright (C) 1999-2006 Igor Pavlov";
  1020. +
  1021. +static const char *LZMA_SDK_COPYRIGHT_INFO =
  1022. + " See http://7-zip.org/sdk.html or the documentation of LZMA SDK for\n"
  1023. + " the license. For reference, the version 4.43 is free software\n"
  1024. + " licensed under the GNU LGPL.";
  1025. +
  1026. +
  1027. +static const char *LZMA_UTILS_VERSION_STRING = PACKAGE_VERSION;
  1028. +
  1029. +static const char *LZMA_UTILS_COPYRIGHT_STRING =
  1030. + "Copyright (C) 2006 Lasse Collin";
  1031. +
  1032. +static const char *LZMA_UTILS_COPYRIGHT_INFO =
  1033. + "This program comes with ABSOLUTELY NO WARRANTY.\n"
  1034. + "You may redistribute copies of this program\n"
  1035. + "under the terms of the GNU General Public License.\n"
  1036. + "For more information about these matters, see the file "
  1037. + "named COPYING.\n";
  1038. +
  1039. +#endif /* ifndef LZMA_VERSION_H */
  1040. Index: lzma-4.65/CPP/Common/C_FileIO.h
  1041. ===================================================================
  1042. --- lzma-4.65.orig/CPP/Common/C_FileIO.h 2009-05-15 23:33:51.000000000 +0200
  1043. +++ lzma-4.65/CPP/Common/C_FileIO.h 2009-06-01 22:06:56.000000000 +0200
  1044. @@ -24,6 +24,7 @@
  1045. bool Close();
  1046. bool GetLength(UInt64 &length) const;
  1047. off_t Seek(off_t distanceToMove, int moveMethod) const;
  1048. + int GetHandle() const { return _handle; }
  1049. };
  1050. class CInFile: public CFileBase