From 06f39cd345eb77dcfaa05c430cde8808ffacd1ac Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Fri, 17 Apr 2009 00:55:52 +0000 Subject: [PATCH] Implement command-line fallbacks for gzip and bzip2 decompression as well. Not an issue for FreeBSD, since the base system has the necessary libraries. Since all decompressors are always available now, we can unconditionally enable them in archive_read_support_compression_all(). --- .../archive_read_support_compression_all.c | 22 ++++++++++++------- .../archive_read_support_compression_bzip2.c | 17 +++++++++++--- .../archive_read_support_compression_gzip.c | 16 +++++++++++--- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/lib/libarchive/archive_read_support_compression_all.c b/lib/libarchive/archive_read_support_compression_all.c index 745f1ffdfb1..284eab5cb98 100644 --- a/lib/libarchive/archive_read_support_compression_all.c +++ b/lib/libarchive/archive_read_support_compression_all.c @@ -31,18 +31,24 @@ __FBSDID("$FreeBSD$"); int archive_read_support_compression_all(struct archive *a) { -#if HAVE_BZLIB_H + /* Bzip falls back to "bunzip2" command-line */ archive_read_support_compression_bzip2(a); -#endif /* The decompress code doesn't use an outside library. */ archive_read_support_compression_compress(a); /* Gzip decompress falls back to "gunzip" command-line. */ archive_read_support_compression_gzip(a); -#if HAVE_LZMADEC_H - /* LZMA bidding is subject to false positives because - * the LZMA file format has a very weak signature. It - * may not be feasible to include LZMA detection here. */ - /* archive_read_support_compression_lzma(a); */ -#endif + /* The LZMA file format has a very weak signature, so it + * may not be feasible to keep this here, but we'll try. + * This will come back out if there are problems. */ + /* Lzma falls back to "unlzma" command-line program. */ + archive_read_support_compression_lzma(a); + /* Xz falls back to "unxz" command-line program. */ + archive_read_support_compression_xz(a); + + /* Note: We always return ARCHIVE_OK here, even if some of the + * above return ARCHIVE_WARN. The intent here is to enable + * "as much as possible." Clients who need specific + * compression should enable those individually so they can + * verify the level of support. */ return (ARCHIVE_OK); } diff --git a/lib/libarchive/archive_read_support_compression_bzip2.c b/lib/libarchive/archive_read_support_compression_bzip2.c index 506dcfebff9..693bdd63b70 100644 --- a/lib/libarchive/archive_read_support_compression_bzip2.c +++ b/lib/libarchive/archive_read_support_compression_bzip2.c @@ -86,7 +86,13 @@ archive_read_support_compression_bzip2(struct archive *_a) reader->init = bzip2_reader_init; reader->options = NULL; reader->free = bzip2_reader_free; +#if HAVE_BZLIB_H return (ARCHIVE_OK); +#else + archive_set_error(_a, ARCHIVE_ERRNO_MISC, + "Using external bunzip2 program"); + return (ARCHIVE_WARN); +#endif } static int @@ -150,10 +156,15 @@ bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_fi static int bzip2_reader_init(struct archive_read_filter *self) { + int r; - archive_set_error(&self->archive->archive, -1, - "This version of libarchive was compiled without bzip2 support"); - return (ARCHIVE_FATAL); + r = __archive_read_program(self, "bunzip2"); + /* Note: We set the format here even if __archive_read_program() + * above fails. We do, after all, know what the format is + * even if we weren't able to read it. */ + self->code = ARCHIVE_COMPRESSION_BZIP2; + self->name = "bzip2"; + return (r); } diff --git a/lib/libarchive/archive_read_support_compression_gzip.c b/lib/libarchive/archive_read_support_compression_gzip.c index bc3f1438dc9..14535405d14 100644 --- a/lib/libarchive/archive_read_support_compression_gzip.c +++ b/lib/libarchive/archive_read_support_compression_gzip.c @@ -92,7 +92,14 @@ archive_read_support_compression_gzip(struct archive *_a) bidder->init = gzip_bidder_init; bidder->options = NULL; bidder->free = NULL; /* No data, so no cleanup necessary. */ + /* Signal the extent of gzip support with the return value here. */ +#if HAVE_ZLIB_H return (ARCHIVE_OK); +#else + archive_set_error(_a, ARCHIVE_ERRNO_MISC, + "Using external gunzip program"); + return (ARCHIVE_WARN); +#endif } /* @@ -207,9 +214,9 @@ gzip_bidder_bid(struct archive_read_filter_bidder *self, #ifndef HAVE_ZLIB_H /* - * If we don't have the library on this system, we can't actually do the - * decompression. We can, however, still detect compressed archives - * and emit a useful message. + * If we don't have the library on this system, we can't do the + * decompression directly. We can, however, try to run gunzip + * in case that's available. */ static int gzip_bidder_init(struct archive_read_filter *self) @@ -217,6 +224,9 @@ gzip_bidder_init(struct archive_read_filter *self) int r; r = __archive_read_program(self, "gunzip"); + /* Note: We set the format here even if __archive_read_program() + * above fails. We do, after all, know what the format is + * even if we weren't able to read it. */ self->code = ARCHIVE_COMPRESSION_GZIP; self->name = "gzip"; return (r);