002-lzmp.patch 26 KB

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