diff options
Diffstat (limited to 'contrib/libarchive/libarchive/archive_write.c')
-rw-r--r-- | contrib/libarchive/libarchive/archive_write.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/contrib/libarchive/libarchive/archive_write.c b/contrib/libarchive/libarchive/archive_write.c index 7d308a2ba8a5..b70bc785c738 100644 --- a/contrib/libarchive/libarchive/archive_write.c +++ b/contrib/libarchive/libarchive/archive_write.c @@ -24,7 +24,6 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); /* * This file contains the "essential" portions of the write API, that @@ -115,7 +114,7 @@ archive_write_new(void) /* Initialize a block of nulls for padding purposes. */ a->null_length = 1024; - nulls = (unsigned char *)calloc(1, a->null_length); + nulls = (unsigned char *)calloc(a->null_length, sizeof(unsigned char)); if (nulls == NULL) { free(a); return (NULL); @@ -201,6 +200,10 @@ __archive_write_allocate_filter(struct archive *_a) struct archive_write_filter *f; f = calloc(1, sizeof(*f)); + + if (f == NULL) + return (NULL); + f->archive = _a; f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; if (a->filter_first == NULL) @@ -306,6 +309,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length) return (__archive_write_filter(a->filter_first, buff, length)); } +static int +__archive_write_filters_flush(struct archive_write *a) +{ + struct archive_write_filter *f; + int ret, ret1; + + ret = ARCHIVE_OK; + for (f = a->filter_first; f != NULL; f = f->next_filter) { + if (f->flush != NULL && f->bytes_written > 0) { + ret1 = (f->flush)(f); + if (ret1 < ret) + ret = ret1; + if (ret1 < ARCHIVE_WARN) + f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; + } + } + return (ret); +} + int __archive_write_nulls(struct archive_write *a, size_t length) { @@ -548,6 +570,10 @@ archive_write_open2(struct archive *_a, void *client_data, a->client_data = client_data; client_filter = __archive_write_allocate_filter(_a); + + if (client_filter == NULL) + return (ARCHIVE_FATAL); + client_filter->open = archive_write_client_open; client_filter->write = archive_write_client_write; client_filter->close = archive_write_client_close; @@ -732,6 +758,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry) return (ARCHIVE_FAILED); } + /* Flush filters at boundary. */ + r2 = __archive_write_filters_flush(a); + if (r2 == ARCHIVE_FAILED) { + return (ARCHIVE_FAILED); + } + if (r2 == ARCHIVE_FATAL) { + a->archive.state = ARCHIVE_STATE_FATAL; + return (ARCHIVE_FATAL); + } + if (r2 < ret) + ret = r2; + /* Format and write header. */ r2 = ((a->format_write_header)(a, entry)); if (r2 == ARCHIVE_FAILED) { |