diff options
author | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-10-11 07:33:00 +0900 |
---|---|---|
committer | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-10-11 07:33:00 +0900 |
commit | 9e454d6753f7a939e0eb9b0f1eaa454683842d60 (patch) | |
tree | cf5caddf080366b59ee3d857da0723d2db4ad6f3 /libarchive/archive_write_add_filter_grzip.c | |
parent | 7ba3fa3e7943c426d5bd36f541648c59604df3c5 (diff) | |
download | libarchive-9e454d6753f7a939e0eb9b0f1eaa454683842d60.tar.gz |
Improve archive_write_filter_program handing to be able to
use options for an external program from
archive_write_filter_{grzip,lrzip,lzop}.
Diffstat (limited to 'libarchive/archive_write_add_filter_grzip.c')
-rw-r--r-- | libarchive/archive_write_add_filter_grzip.c | 113 |
1 files changed, 106 insertions, 7 deletions
diff --git a/libarchive/archive_write_add_filter_grzip.c b/libarchive/archive_write_add_filter_grzip.c index 6c0478c3..b5255903 100644 --- a/libarchive/archive_write_add_filter_grzip.c +++ b/libarchive/archive_write_add_filter_grzip.c @@ -27,19 +27,118 @@ __FBSDID("$FreeBSD$"); +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + #include "archive.h" #include "archive_write_private.h" +struct write_grzip { + struct archive_write_program_data *pdata; +}; + +static int archive_write_grzip_open(struct archive_write_filter *); +static int archive_write_grzip_options(struct archive_write_filter *, + const char *, const char *); +static int archive_write_grzip_write(struct archive_write_filter *, + const void *, size_t); +static int archive_write_grzip_close(struct archive_write_filter *); +static int archive_write_grzip_free(struct archive_write_filter *); + int -archive_write_add_filter_grzip(struct archive *a) +archive_write_add_filter_grzip(struct archive *_a) +{ + struct archive_write_filter *f = __archive_write_allocate_filter(_a); + struct write_grzip *data; + + archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, + ARCHIVE_STATE_NEW, "archive_write_add_filter_grzip"); + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + archive_set_error(_a, ENOMEM, "Can't allocate memory"); + return (ARCHIVE_FATAL); + } + data->pdata = __archive_write_program_allocate(); + if (data->pdata == NULL) { + free(data); + archive_set_error(_a, ENOMEM, "Can't allocate memory"); + return (ARCHIVE_FATAL); + } + + f->name = "grzip"; + f->code = ARCHIVE_FILTER_GRZIP; + f->data = data; + f->open = archive_write_grzip_open; + f->options = archive_write_grzip_options; + f->write = archive_write_grzip_write; + f->close = archive_write_grzip_close; + f->free = archive_write_grzip_free; + + /* Note: This filter always uses an external program, so we + * return "warn" to inform of the fact. */ + return (ARCHIVE_WARN); +} + +static int +archive_write_grzip_options(struct archive_write_filter *f, const char *key, + const char *value) +{ + (void)f; /* UNUSED */ + (void)key; /* UNUSED */ + (void)value; /* UNUSED */ + /* Note: The "warn" return is just to inform the options + * supervisor that we didn't handle it. It will generate + * a suitable error if no one used this option. */ + return (ARCHIVE_WARN); +} + +static int +archive_write_grzip_open(struct archive_write_filter *f) { - char * const argv[] = { "grzip", NULL }; + struct write_grzip *data = (struct write_grzip *)f->data; int r; - r = __archive_write_programv(a, "grzip", ARCHIVE_FILTER_GRZIP, - "grzip", argv); - if (r == ARCHIVE_OK) - /* This filter always uses an external program. */ - r = ARCHIVE_WARN; + r = __archive_write_program_set_cmd(data->pdata, "grzip"); + if (r != ARCHIVE_OK) + goto memerr; + r = __archive_write_program_add_arg(data->pdata, "grzip"); + if (r != ARCHIVE_OK) + goto memerr; + r = __archive_write_program_open(f, data->pdata); return (r); +memerr: + archive_set_error(f->archive, ENOMEM, "Can't allocate memory"); + return (ARCHIVE_FATAL); +} + +static int +archive_write_grzip_write(struct archive_write_filter *f, + const void *buff, size_t length) +{ + struct write_grzip *data = (struct write_grzip *)f->data; + + return __archive_write_program_write(f, data->pdata, buff, length); +} + +static int +archive_write_grzip_close(struct archive_write_filter *f) +{ + struct write_grzip *data = (struct write_grzip *)f->data; + + return __archive_write_program_close(f, data->pdata); +} + +static int +archive_write_grzip_free(struct archive_write_filter *f) +{ + struct write_grzip *data = (struct write_grzip *)f->data; + + __archive_write_program_free(data->pdata); + free(data); + return (ARCHIVE_OK); } |