summaryrefslogtreecommitdiff
path: root/libarchive/archive_write_add_filter_gzip.c
diff options
context:
space:
mode:
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-10-12 06:57:36 +0900
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-10-12 06:57:36 +0900
commit6879299837ff53709e11cb337f8b47002147f78c (patch)
tree911f699a6589743bebabb5e8beb3fab4059a2498 /libarchive/archive_write_add_filter_gzip.c
parenta4c8851c5d531b092699b9ae8cc8300703b30800 (diff)
downloadlibarchive-6879299837ff53709e11cb337f8b47002147f78c.tar.gz
Use an external gzip program when zlib is unavailable.
Diffstat (limited to 'libarchive/archive_write_add_filter_gzip.c')
-rw-r--r--libarchive/archive_write_add_filter_gzip.c82
1 files changed, 72 insertions, 10 deletions
diff --git a/libarchive/archive_write_add_filter_gzip.c b/libarchive/archive_write_add_filter_gzip.c
index 3d3f1f47..c7d3714f 100644
--- a/libarchive/archive_write_add_filter_gzip.c
+++ b/libarchive/archive_write_add_filter_gzip.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201
#include "archive.h"
#include "archive_private.h"
+#include "archive_string.h"
#include "archive_write_private.h"
#if ARCHIVE_VERSION_NUMBER < 4000000
@@ -54,24 +55,19 @@ archive_write_set_compression_gzip(struct archive *a)
}
#endif
-#ifndef HAVE_ZLIB_H
-int
-archive_write_add_filter_gzip(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "gzip compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-#else
/* Don't compile this if we don't have zlib. */
struct private_data {
int compression_level;
+#ifdef HAVE_ZLIB_H
z_stream stream;
int64_t total_in;
unsigned char *compressed;
size_t compressed_buffer_size;
unsigned long crc;
+#else
+ struct archive_write_program_data *pdata;
+#endif
};
/*
@@ -88,8 +84,10 @@ static int archive_compressor_gzip_write(struct archive_write_filter *,
const void *, size_t);
static int archive_compressor_gzip_close(struct archive_write_filter *);
static int archive_compressor_gzip_free(struct archive_write_filter *);
+#ifdef HAVE_ZLIB_H
static int drive_compressor(struct archive_write_filter *,
struct private_data *, int finishing);
+#endif
/*
@@ -110,21 +108,39 @@ archive_write_add_filter_gzip(struct archive *_a)
return (ARCHIVE_FATAL);
}
f->data = data;
- data->compression_level = Z_DEFAULT_COMPRESSION;
f->open = &archive_compressor_gzip_open;
f->options = &archive_compressor_gzip_options;
f->close = &archive_compressor_gzip_close;
f->free = &archive_compressor_gzip_free;
f->code = ARCHIVE_FILTER_GZIP;
f->name = "gzip";
+#ifdef HAVE_ZLIB_H
+ data->compression_level = Z_DEFAULT_COMPRESSION;
return (ARCHIVE_OK);
+#else
+ data->pdata = __archive_write_program_allocate();
+ if (data->pdata == NULL) {
+ free(data);
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ data->compression_level = 0;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Using external gzip program");
+ return (ARCHIVE_WARN);
+#endif
}
static int
archive_compressor_gzip_free(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
+
+#ifdef HAVE_ZLIB_H
free(data->compressed);
+#else
+ __archive_write_program_free(data->pdata);
+#endif
free(data);
f->data = NULL;
return (ARCHIVE_OK);
@@ -153,6 +169,7 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
return (ARCHIVE_WARN);
}
+#ifdef HAVE_ZLIB_H
/*
* Setup callback.
*/
@@ -367,4 +384,49 @@ drive_compressor(struct archive_write_filter *f,
}
}
+#else /* HAVE_ZLIB_H */
+
+static int
+archive_compressor_gzip_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ struct archive_string as;
+ int r;
+
+ archive_string_init(&as);
+ archive_strcpy(&as, "gzip");
+
+ /* Specify compression level. */
+ if (data->compression_level > 0) {
+ archive_strcat(&as, " -");
+ archive_strappend_char(&as, '0' + data->compression_level);
+ }
+ r = __archive_write_program_set_cmd(data->pdata, as.s);
+ archive_string_free(&as);
+ if (r != ARCHIVE_OK) {
+ archive_set_error(f->archive, ENOMEM, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ f->write = archive_compressor_gzip_write;
+
+ return __archive_write_program_open(f, data->pdata);
+}
+
+static int
+archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_compressor_gzip_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ return __archive_write_program_close(f, data->pdata);
+}
+
#endif /* HAVE_ZLIB_H */