archive_read_support_compression_xz.c revision 267654
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: releng/9.3/contrib/libarchive/libarchive/archive_read_support_compression_xz.c 229592 2012-01-05 12:06:54Z mm $"); 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 57struct 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 */ 66static ssize_t xz_filter_read(struct archive_read_filter *, const void **); 67static int xz_filter_close(struct archive_read_filter *); 68static int xz_lzma_bidder_init(struct archive_read_filter *); 69 70#elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC 71 72struct 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 */ 81static ssize_t lzma_filter_read(struct archive_read_filter *, const void **); 82static 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 */ 91static int xz_bidder_bid(struct archive_read_filter_bidder *, 92 struct archive_read_filter *); 93static int xz_bidder_init(struct archive_read_filter *); 94static int lzma_bidder_bid(struct archive_read_filter_bidder *, 95 struct archive_read_filter *); 96static int lzma_bidder_init(struct archive_read_filter *); 97 98int 99archive_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 122int 123archive_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 */ 151static int 152xz_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 */ 203static int 204lzma_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 */ 315static int 316xz_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 323static int 324lzma_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 */ 334static int 335xz_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 */ 408static ssize_t 409xz_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 */ 490static int 491xz_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 */ 514static int 515lzma_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 */ 586static ssize_t 587lzma_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 */ 643static int 644lzma_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 */ 676static int 677lzma_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 693static int 694xz_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