1 /*-
2 * Copyright (c) 2009 Michihiro NAKAJIMA
3 * Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "archive_platform.h"
28
29 __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_xz.c 201167 2009-12-29 06:06:20Z kientzle $");
30
31 #ifdef HAVE_ERRNO_H
32 #include <errno.h>
33 #endif
34 #include <stdio.h>
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #ifdef HAVE_STRING_H
39 #include <string.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #if HAVE_LZMA_H
45 #include <lzma.h>
46 #elif HAVE_LZMADEC_H
47 #include <lzmadec.h>
48 #endif
49
50 #include "archive.h"
51 #include "archive_endian.h"
52 #include "archive_private.h"
53 #include "archive_read_private.h"
54
55 #if HAVE_LZMA_H && HAVE_LIBLZMA
56
57 struct private_data {
58 lzma_stream stream;
59 unsigned char *out_block;
60 size_t out_block_size;
61 int64_t total_out;
62 char eof; /* True = found end of compressed data. */
63 };
64
65 /* Combined lzma/xz filter */
66 static ssize_t xz_filter_read(struct archive_read_filter *, const void **);
67 static int xz_filter_close(struct archive_read_filter *);
68 static int xz_lzma_bidder_init(struct archive_read_filter *);
69
70 #elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
71
72 struct private_data {
73 lzmadec_stream stream;
74 unsigned char *out_block;
75 size_t out_block_size;
76 int64_t total_out;
77 char eof; /* True = found end of compressed data. */
78 };
79
80 /* Lzma-only filter */
81 static ssize_t lzma_filter_read(struct archive_read_filter *, const void **);
82 static int lzma_filter_close(struct archive_read_filter *);
83 #endif
84
85 /*
86 * Note that we can detect xz and lzma compressed files even if we
87 * can't decompress them. (In fact, we like detecting them because we
88 * can give better error messages.) So the bid framework here gets
89 * compiled even if no lzma library is available.
90 */
91 static int xz_bidder_bid(struct archive_read_filter_bidder *,
92 struct archive_read_filter *);
93 static int xz_bidder_init(struct archive_read_filter *);
94 static int lzma_bidder_bid(struct archive_read_filter_bidder *,
95 struct archive_read_filter *);
96 static int lzma_bidder_init(struct archive_read_filter *);
97
98 int
archive_read_support_compression_xz(struct archive * _a)99 archive_read_support_compression_xz(struct archive *_a)
100 {
101 struct archive_read *a = (struct archive_read *)_a;
102 struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);
103
104 archive_clear_error(_a);
105 if (bidder == NULL)
106 return (ARCHIVE_FATAL);
107
108 bidder->data = NULL;
109 bidder->bid = xz_bidder_bid;
110 bidder->init = xz_bidder_init;
111 bidder->options = NULL;
112 bidder->free = NULL;
113 #if HAVE_LZMA_H && HAVE_LIBLZMA
114 return (ARCHIVE_OK);
115 #else
116 archive_set_error(_a, ARCHIVE_ERRNO_MISC,
117 "Using external unxz program for xz decompression");
118 return (ARCHIVE_WARN);
119 #endif
120 }
121
122 int
archive_read_support_compression_lzma(struct archive * _a)123 archive_read_support_compression_lzma(struct archive *_a)
124 {
125 struct archive_read *a = (struct archive_read *)_a;
126 struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);
127
128 archive_clear_error(_a);
129 if (bidder == NULL)
130 return (ARCHIVE_FATAL);
131
132 bidder->data = NULL;
133 bidder->bid = lzma_bidder_bid;
134 bidder->init = lzma_bidder_init;
135 bidder->options = NULL;
136 bidder->free = NULL;
137 #if HAVE_LZMA_H && HAVE_LIBLZMA
138 return (ARCHIVE_OK);
139 #elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
140 return (ARCHIVE_OK);
141 #else
142 archive_set_error(_a, ARCHIVE_ERRNO_MISC,
143 "Using external unlzma program for lzma decompression");
144 return (ARCHIVE_WARN);
145 #endif
146 }
147
148 /*
149 * Test whether we can handle this data.
150 */
151 static int
xz_bidder_bid(struct archive_read_filter_bidder * self,struct archive_read_filter * filter)152 xz_bidder_bid(struct archive_read_filter_bidder *self,
153 struct archive_read_filter *filter)
154 {
155 const unsigned char *buffer;
156 ssize_t avail;
157 int bits_checked;
158
159 (void)self; /* UNUSED */
160
161 buffer = __archive_read_filter_ahead(filter, 6, &avail);
162 if (buffer == NULL)
163 return (0);
164
165 /*
166 * Verify Header Magic Bytes : FD 37 7A 58 5A 00
167 */
168 bits_checked = 0;
169 if (buffer[0] != 0xFD)
170 return (0);
171 bits_checked += 8;
172 if (buffer[1] != 0x37)
173 return (0);
174 bits_checked += 8;
175 if (buffer[2] != 0x7A)
176 return (0);
177 bits_checked += 8;
178 if (buffer[3] != 0x58)
179 return (0);
180 bits_checked += 8;
181 if (buffer[4] != 0x5A)
182 return (0);
183 bits_checked += 8;
184 if (buffer[5] != 0x00)
185 return (0);
186 bits_checked += 8;
187
188 return (bits_checked);
189 }
190
191 /*
192 * Test whether we can handle this data.
193 *
194 * <sigh> LZMA has a rather poor file signature. Zeros do not
195 * make good signature bytes as a rule, and the only non-zero byte
196 * here is an ASCII character. For example, an uncompressed tar
197 * archive whose first file is ']' would satisfy this check. It may
198 * be necessary to exclude LZMA from compression_all() because of
199 * this. Clients of libarchive would then have to explicitly enable
200 * LZMA checking instead of (or in addition to) compression_all() when
201 * they have other evidence (file name, command-line option) to go on.
202 */
203 static int
lzma_bidder_bid(struct archive_read_filter_bidder * self,struct archive_read_filter * filter)204 lzma_bidder_bid(struct archive_read_filter_bidder *self,
205 struct archive_read_filter *filter)
206 {
207 const unsigned char *buffer;
208 ssize_t avail;
209 uint32_t dicsize;
210 uint64_t uncompressed_size;
211 int bits_checked;
212
213 (void)self; /* UNUSED */
214
215 buffer = __archive_read_filter_ahead(filter, 14, &avail);
216 if (buffer == NULL)
217 return (0);
218
219 /* First byte of raw LZMA stream is commonly 0x5d.
220 * The first byte is a special number, which consists of
221 * three parameters of LZMA compression, a number of literal
222 * context bits(which is from 0 to 8, default is 3), a number
223 * of literal pos bits(which is from 0 to 4, default is 0),
224 * a number of pos bits(which is from 0 to 4, default is 2).
225 * The first byte is made by
226 * (pos bits * 5 + literal pos bit) * 9 + * literal contest bit,
227 * and so the default value in this field is
228 * (2 * 5 + 0) * 9 + 3 = 0x5d.
229 * lzma of LZMA SDK has options to change those parameters.
230 * It means a range of this field is from 0 to 224. And lzma of
231 * XZ Utils with option -e records 0x5e in this field. */
232 /* NOTE: If this checking of the first byte increases false
233 * recognition, we should allow only 0x5d and 0x5e for the first
234 * byte of LZMA stream. */
235 bits_checked = 0;
236 if (buffer[0] > (4 * 5 + 4) * 9 + 8)
237 return (0);
238 /* Most likely value in the first byte of LZMA stream. */
239 if (buffer[0] == 0x5d || buffer[0] == 0x5e)
240 bits_checked += 8;
241
242 /* Sixth through fourteenth bytes are uncompressed size,
243 * stored in little-endian order. `-1' means uncompressed
244 * size is unknown and lzma of XZ Utils always records `-1'
245 * in this field. */
246 uncompressed_size = archive_le64dec(buffer+5);
247 if (uncompressed_size == (uint64_t)ARCHIVE_LITERAL_LL(-1))
248 bits_checked += 64;
249
250 /* Second through fifth bytes are dictionary size, stored in
251 * little-endian order. The minimum dictionary size is
252 * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option
253 * -d12 and the maxinam dictionary size is 1 << 27(128MiB)
254 * which the one uses with option -d27.
255 * NOTE: A comment of LZMA SDK source code says this dictionary
256 * range is from 1 << 12 to 1 << 30. */
257 dicsize = archive_le32dec(buffer+1);
258 switch (dicsize) {
259 case 0x00001000:/* lzma of LZMA SDK option -d12. */
260 case 0x00002000:/* lzma of LZMA SDK option -d13. */
261 case 0x00004000:/* lzma of LZMA SDK option -d14. */
262 case 0x00008000:/* lzma of LZMA SDK option -d15. */
263 case 0x00010000:/* lzma of XZ Utils option -0 and -1.
264 * lzma of LZMA SDK option -d16. */
265 case 0x00020000:/* lzma of LZMA SDK option -d17. */
266 case 0x00040000:/* lzma of LZMA SDK option -d18. */
267 case 0x00080000:/* lzma of XZ Utils option -2.
268 * lzma of LZMA SDK option -d19. */
269 case 0x00100000:/* lzma of XZ Utils option -3.
270 * lzma of LZMA SDK option -d20. */
271 case 0x00200000:/* lzma of XZ Utils option -4.
272 * lzma of LZMA SDK option -d21. */
273 case 0x00400000:/* lzma of XZ Utils option -5.
274 * lzma of LZMA SDK option -d22. */
275 case 0x00800000:/* lzma of XZ Utils option -6.
276 * lzma of LZMA SDK option -d23. */
277 case 0x01000000:/* lzma of XZ Utils option -7.
278 * lzma of LZMA SDK option -d24. */
279 case 0x02000000:/* lzma of XZ Utils option -8.
280 * lzma of LZMA SDK option -d25. */
281 case 0x04000000:/* lzma of XZ Utils option -9.
282 * lzma of LZMA SDK option -d26. */
283 case 0x08000000:/* lzma of LZMA SDK option -d27. */
284 bits_checked += 32;
285 break;
286 default:
287 /* If a memory usage for encoding was not enough on
288 * the platform where LZMA stream was made, lzma of
289 * XZ Utils automatically decreased the dictionary
290 * size to enough memory for encoding by 1Mi bytes
291 * (1 << 20).*/
292 if (dicsize <= 0x03F00000 && dicsize >= 0x00300000 &&
293 (dicsize & ((1 << 20)-1)) == 0 &&
294 bits_checked == 8 + 64) {
295 bits_checked += 32;
296 break;
297 }
298 /* Otherwise dictionary size is unlikely. But it is
299 * possible that someone makes lzma stream with
300 * liblzma/LZMA SDK in one's dictionary size. */
301 return (0);
302 }
303
304 /* TODO: The above test is still very weak. It would be
305 * good to do better. */
306
307 return (bits_checked);
308 }
309
310 #if HAVE_LZMA_H && HAVE_LIBLZMA
311
312 /*
313 * liblzma 4.999.7 and later support both lzma and xz streams.
314 */
315 static int
xz_bidder_init(struct archive_read_filter * self)316 xz_bidder_init(struct archive_read_filter *self)
317 {
318 self->code = ARCHIVE_COMPRESSION_XZ;
319 self->name = "xz";
320 return (xz_lzma_bidder_init(self));
321 }
322
323 static int
lzma_bidder_init(struct archive_read_filter * self)324 lzma_bidder_init(struct archive_read_filter *self)
325 {
326 self->code = ARCHIVE_COMPRESSION_LZMA;
327 self->name = "lzma";
328 return (xz_lzma_bidder_init(self));
329 }
330
331 /*
332 * Setup the callbacks.
333 */
334 static int
xz_lzma_bidder_init(struct archive_read_filter * self)335 xz_lzma_bidder_init(struct archive_read_filter *self)
336 {
337 static const size_t out_block_size = 64 * 1024;
338 void *out_block;
339 struct private_data *state;
340 int ret;
341
342 state = (struct private_data *)calloc(sizeof(*state), 1);
343 out_block = (unsigned char *)malloc(out_block_size);
344 if (state == NULL || out_block == NULL) {
345 archive_set_error(&self->archive->archive, ENOMEM,
346 "Can't allocate data for xz decompression");
347 free(out_block);
348 free(state);
349 return (ARCHIVE_FATAL);
350 }
351
352 self->data = state;
353 state->out_block_size = out_block_size;
354 state->out_block = out_block;
355 self->read = xz_filter_read;
356 self->skip = NULL; /* not supported */
357 self->close = xz_filter_close;
358
359 state->stream.avail_in = 0;
360
361 state->stream.next_out = state->out_block;
362 state->stream.avail_out = state->out_block_size;
363
364 /* Initialize compression library.
365 * TODO: I don't know what value is best for memlimit.
366 * maybe, it needs to check memory size which
367 * running system has.
368 */
369 if (self->code == ARCHIVE_COMPRESSION_XZ)
370 ret = lzma_stream_decoder(&(state->stream),
371 (1U << 30),/* memlimit */
372 LZMA_CONCATENATED);
373 else
374 ret = lzma_alone_decoder(&(state->stream),
375 (1U << 30));/* memlimit */
376
377 if (ret == LZMA_OK)
378 return (ARCHIVE_OK);
379
380 /* Library setup failed: Choose an error message and clean up. */
381 switch (ret) {
382 case LZMA_MEM_ERROR:
383 archive_set_error(&self->archive->archive, ENOMEM,
384 "Internal error initializing compression library: "
385 "Cannot allocate memory");
386 break;
387 case LZMA_OPTIONS_ERROR:
388 archive_set_error(&self->archive->archive,
389 ARCHIVE_ERRNO_MISC,
390 "Internal error initializing compression library: "
391 "Invalid or unsupported options");
392 break;
393 default:
394 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
395 "Internal error initializing lzma library");
396 break;
397 }
398
399 free(state->out_block);
400 free(state);
401 self->data = NULL;
402 return (ARCHIVE_FATAL);
403 }
404
405 /*
406 * Return the next block of decompressed data.
407 */
408 static ssize_t
xz_filter_read(struct archive_read_filter * self,const void ** p)409 xz_filter_read(struct archive_read_filter *self, const void **p)
410 {
411 struct private_data *state;
412 size_t decompressed;
413 ssize_t avail_in;
414 int ret;
415
416 state = (struct private_data *)self->data;
417
418 /* Empty our output buffer. */
419 state->stream.next_out = state->out_block;
420 state->stream.avail_out = state->out_block_size;
421
422 /* Try to fill the output buffer. */
423 while (state->stream.avail_out > 0 && !state->eof) {
424 state->stream.next_in =
425 __archive_read_filter_ahead(self->upstream, 1, &avail_in);
426 if (state->stream.next_in == NULL && avail_in < 0)
427 return (ARCHIVE_FATAL);
428 state->stream.avail_in = avail_in;
429
430 /* Decompress as much as we can in one pass. */
431 ret = lzma_code(&(state->stream),
432 (state->stream.avail_in == 0)? LZMA_FINISH: LZMA_RUN);
433 switch (ret) {
434 case LZMA_STREAM_END: /* Found end of stream. */
435 state->eof = 1;
436 /* FALL THROUGH */
437 case LZMA_OK: /* Decompressor made some progress. */
438 __archive_read_filter_consume(self->upstream,
439 avail_in - state->stream.avail_in);
440 break;
441 case LZMA_MEM_ERROR:
442 archive_set_error(&self->archive->archive, ENOMEM,
443 "Lzma library error: Cannot allocate memory");
444 return (ARCHIVE_FATAL);
445 case LZMA_MEMLIMIT_ERROR:
446 archive_set_error(&self->archive->archive, ENOMEM,
447 "Lzma library error: Out of memory");
448 return (ARCHIVE_FATAL);
449 case LZMA_FORMAT_ERROR:
450 archive_set_error(&self->archive->archive,
451 ARCHIVE_ERRNO_MISC,
452 "Lzma library error: format not recognized");
453 return (ARCHIVE_FATAL);
454 case LZMA_OPTIONS_ERROR:
455 archive_set_error(&self->archive->archive,
456 ARCHIVE_ERRNO_MISC,
457 "Lzma library error: Invalid options");
458 return (ARCHIVE_FATAL);
459 case LZMA_DATA_ERROR:
460 archive_set_error(&self->archive->archive,
461 ARCHIVE_ERRNO_MISC,
462 "Lzma library error: Corrupted input data");
463 return (ARCHIVE_FATAL);
464 case LZMA_BUF_ERROR:
465 archive_set_error(&self->archive->archive,
466 ARCHIVE_ERRNO_MISC,
467 "Lzma library error: No progress is possible");
468 return (ARCHIVE_FATAL);
469 default:
470 /* Return an error. */
471 archive_set_error(&self->archive->archive,
472 ARCHIVE_ERRNO_MISC,
473 "Lzma decompression failed: Unknown error");
474 return (ARCHIVE_FATAL);
475 }
476 }
477
478 decompressed = state->stream.next_out - state->out_block;
479 state->total_out += decompressed;
480 if (decompressed == 0)
481 *p = NULL;
482 else
483 *p = state->out_block;
484 return (decompressed);
485 }
486
487 /*
488 * Clean up the decompressor.
489 */
490 static int
xz_filter_close(struct archive_read_filter * self)491 xz_filter_close(struct archive_read_filter *self)
492 {
493 struct private_data *state;
494
495 state = (struct private_data *)self->data;
496 lzma_end(&(state->stream));
497 free(state->out_block);
498 free(state);
499 return (ARCHIVE_OK);
500 }
501
502 #else
503
504 #if HAVE_LZMADEC_H && HAVE_LIBLZMADEC
505
506 /*
507 * If we have the older liblzmadec library, then we can handle
508 * LZMA streams but not XZ streams.
509 */
510
511 /*
512 * Setup the callbacks.
513 */
514 static int
lzma_bidder_init(struct archive_read_filter * self)515 lzma_bidder_init(struct archive_read_filter *self)
516 {
517 static const size_t out_block_size = 64 * 1024;
518 void *out_block;
519 struct private_data *state;
520 ssize_t ret, avail_in;
521
522 self->code = ARCHIVE_COMPRESSION_LZMA;
523 self->name = "lzma";
524
525 state = (struct private_data *)calloc(sizeof(*state), 1);
526 out_block = (unsigned char *)malloc(out_block_size);
527 if (state == NULL || out_block == NULL) {
528 archive_set_error(&self->archive->archive, ENOMEM,
529 "Can't allocate data for lzma decompression");
530 free(out_block);
531 free(state);
532 return (ARCHIVE_FATAL);
533 }
534
535 self->data = state;
536 state->out_block_size = out_block_size;
537 state->out_block = out_block;
538 self->read = lzma_filter_read;
539 self->skip = NULL; /* not supported */
540 self->close = lzma_filter_close;
541
542 /* Prime the lzma library with 18 bytes of input. */
543 state->stream.next_in = (unsigned char *)(uintptr_t)
544 __archive_read_filter_ahead(self->upstream, 18, &avail_in);
545 if (state->stream.next_in == NULL)
546 return (ARCHIVE_FATAL);
547 state->stream.avail_in = avail_in;
548 state->stream.next_out = state->out_block;
549 state->stream.avail_out = state->out_block_size;
550
551 /* Initialize compression library. */
552 ret = lzmadec_init(&(state->stream));
553 __archive_read_filter_consume(self->upstream,
554 avail_in - state->stream.avail_in);
555 if (ret == LZMADEC_OK)
556 return (ARCHIVE_OK);
557
558 /* Library setup failed: Clean up. */
559 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
560 "Internal error initializing lzma library");
561
562 /* Override the error message if we know what really went wrong. */
563 switch (ret) {
564 case LZMADEC_HEADER_ERROR:
565 archive_set_error(&self->archive->archive,
566 ARCHIVE_ERRNO_MISC,
567 "Internal error initializing compression library: "
568 "invalid header");
569 break;
570 case LZMADEC_MEM_ERROR:
571 archive_set_error(&self->archive->archive, ENOMEM,
572 "Internal error initializing compression library: "
573 "out of memory");
574 break;
575 }
576
577 free(state->out_block);
578 free(state);
579 self->data = NULL;
580 return (ARCHIVE_FATAL);
581 }
582
583 /*
584 * Return the next block of decompressed data.
585 */
586 static ssize_t
lzma_filter_read(struct archive_read_filter * self,const void ** p)587 lzma_filter_read(struct archive_read_filter *self, const void **p)
588 {
589 struct private_data *state;
590 size_t decompressed;
591 ssize_t avail_in, ret;
592
593 state = (struct private_data *)self->data;
594
595 /* Empty our output buffer. */
596 state->stream.next_out = state->out_block;
597 state->stream.avail_out = state->out_block_size;
598
599 /* Try to fill the output buffer. */
600 while (state->stream.avail_out > 0 && !state->eof) {
601 state->stream.next_in = (unsigned char *)(uintptr_t)
602 __archive_read_filter_ahead(self->upstream, 1, &avail_in);
603 if (state->stream.next_in == NULL && avail_in < 0)
604 return (ARCHIVE_FATAL);
605 state->stream.avail_in = avail_in;
606
607 /* Decompress as much as we can in one pass. */
608 ret = lzmadec_decode(&(state->stream), avail_in == 0);
609 switch (ret) {
610 case LZMADEC_STREAM_END: /* Found end of stream. */
611 state->eof = 1;
612 /* FALL THROUGH */
613 case LZMADEC_OK: /* Decompressor made some progress. */
614 __archive_read_filter_consume(self->upstream,
615 avail_in - state->stream.avail_in);
616 break;
617 case LZMADEC_BUF_ERROR: /* Insufficient input data? */
618 archive_set_error(&self->archive->archive,
619 ARCHIVE_ERRNO_MISC,
620 "Insufficient compressed data");
621 return (ARCHIVE_FATAL);
622 default:
623 /* Return an error. */
624 archive_set_error(&self->archive->archive,
625 ARCHIVE_ERRNO_MISC,
626 "Lzma decompression failed");
627 return (ARCHIVE_FATAL);
628 }
629 }
630
631 decompressed = state->stream.next_out - state->out_block;
632 state->total_out += decompressed;
633 if (decompressed == 0)
634 *p = NULL;
635 else
636 *p = state->out_block;
637 return (decompressed);
638 }
639
640 /*
641 * Clean up the decompressor.
642 */
643 static int
lzma_filter_close(struct archive_read_filter * self)644 lzma_filter_close(struct archive_read_filter *self)
645 {
646 struct private_data *state;
647 int ret;
648
649 state = (struct private_data *)self->data;
650 ret = ARCHIVE_OK;
651 switch (lzmadec_end(&(state->stream))) {
652 case LZMADEC_OK:
653 break;
654 default:
655 archive_set_error(&(self->archive->archive),
656 ARCHIVE_ERRNO_MISC,
657 "Failed to clean up %s compressor",
658 self->archive->archive.compression_name);
659 ret = ARCHIVE_FATAL;
660 }
661
662 free(state->out_block);
663 free(state);
664 return (ret);
665 }
666
667 #else
668
669 /*
670 *
671 * If we have no suitable library on this system, we can't actually do
672 * the decompression. We can, however, still detect compressed
673 * archives and emit a useful message.
674 *
675 */
676 static int
lzma_bidder_init(struct archive_read_filter * self)677 lzma_bidder_init(struct archive_read_filter *self)
678 {
679 int r;
680
681 r = __archive_read_program(self, "unlzma");
682 /* Note: We set the format here even if __archive_read_program()
683 * above fails. We do, after all, know what the format is
684 * even if we weren't able to read it. */
685 self->code = ARCHIVE_COMPRESSION_LZMA;
686 self->name = "lzma";
687 return (r);
688 }
689
690 #endif /* HAVE_LZMADEC_H */
691
692
693 static int
xz_bidder_init(struct archive_read_filter * self)694 xz_bidder_init(struct archive_read_filter *self)
695 {
696 int r;
697
698 r = __archive_read_program(self, "unxz");
699 /* Note: We set the format here even if __archive_read_program()
700 * above fails. We do, after all, know what the format is
701 * even if we weren't able to read it. */
702 self->code = ARCHIVE_COMPRESSION_XZ;
703 self->name = "xz";
704 return (r);
705 }
706
707
708 #endif /* HAVE_LZMA_H */
709