aboutsummaryrefslogtreecommitdiff
path: root/contrib/libarchive/libarchive/archive_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libarchive/libarchive/archive_write.c')
-rw-r--r--contrib/libarchive/libarchive/archive_write.c42
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) {