summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2004-11-05 05:26:30 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2004-11-05 05:26:30 +0000
commit3ede53f3e110b32ada789816c8ef2684c58e3783 (patch)
treebbc8fe472af0e8dbd66e73826de4bcb674aab1ff
parent9fb9f102864aa1304fc99f558ad7c467f0ee1713 (diff)
Notes
-rw-r--r--lib/libarchive/archive_write.314
-rw-r--r--lib/libarchive/archive_write.c5
-rw-r--r--lib/libarchive/archive_write_set_compression_bzip2.c45
-rw-r--r--lib/libarchive/archive_write_set_compression_gzip.c47
-rw-r--r--lib/libarchive/archive_write_set_compression_none.c26
-rw-r--r--lib/libarchive/archive_write_set_format_cpio.c18
-rw-r--r--lib/libarchive/archive_write_set_format_pax.c16
-rw-r--r--lib/libarchive/archive_write_set_format_shar.c167
-rw-r--r--lib/libarchive/archive_write_set_format_ustar.c8
9 files changed, 213 insertions, 133 deletions
diff --git a/lib/libarchive/archive_write.3 b/lib/libarchive/archive_write.3
index b7af9d56ca75..cea07006fa95 100644
--- a/lib/libarchive/archive_write.3
+++ b/lib/libarchive/archive_write.3
@@ -190,6 +190,7 @@ Build and write a header using the data in the provided
structure.
.It Fn archive_write_data
Write data corresponding to the header just written.
+Returns number of bytes written or -1 on error.
.It Fn archive_write_close
Complete the archive and invoke the close callback.
.It Fn archive_write_finish
@@ -321,20 +322,19 @@ and
.Fn archive_error_string
functions will return appropriate values.
Note that if the client-provided write callback function
-returns -1, that error will be propagated back to the caller
+returns a non-zero value, that error will be propagated back to the caller
through whatever API function resulted in that call, which
may include
.Fn archive_write_header ,
.Fn archive_write_data ,
or
.Fn archive_write_close .
-In such a case, the
+The client callback can call
+.Fn archive_set_error
+to provide values that can then be retrieved by
.Fn archive_errno
-or
-.Fn archive_error_string
-fields will not return useful information; you should use
-client-private data to return error information
-back to your mainline code.
+and
+.Fn archive_error_string .
.Sh SEE ALSO
.Xr tar 1 ,
.Xr libarchive 3 ,
diff --git a/lib/libarchive/archive_write.c b/lib/libarchive/archive_write.c
index 40f660d05c53..76b42884cda7 100644
--- a/lib/libarchive/archive_write.c
+++ b/lib/libarchive/archive_write.c
@@ -215,9 +215,12 @@ archive_write_header(struct archive *a, struct archive_entry *entry)
/*
* Note that the compressor is responsible for blocking.
*/
+/* Should be "ssize_t", but that breaks the ABI. <sigh> */
int
archive_write_data(struct archive *a, const void *buff, size_t s)
{
+ int ret;
archive_check_magic(a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA);
- return (a->format_write_data(a, buff, s));
+ ret = (a->format_write_data)(a, buff, s);
+ return (ret == ARCHIVE_OK ? (ssize_t)s : -1);
}
diff --git a/lib/libarchive/archive_write_set_compression_bzip2.c b/lib/libarchive/archive_write_set_compression_bzip2.c
index c7cee5e6d580..901ce8c69fc0 100644
--- a/lib/libarchive/archive_write_set_compression_bzip2.c
+++ b/lib/libarchive/archive_write_set_compression_bzip2.c
@@ -32,6 +32,7 @@
__FBSDID("$FreeBSD$");
#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bzlib.h>
@@ -153,15 +154,17 @@ archive_compressor_bzip2_init(struct archive *a)
/*
* Write data to the compressed stream.
+ *
+ * Returns ARCHIVE_OK if all data written, error otherwise.
*/
-static ssize_t
+static int
archive_compressor_bzip2_write(struct archive *a, const void *buff,
size_t length)
{
struct private_data *state;
state = a->compression_data;
- if (!a->client_writer) {
+ if (a->client_writer == NULL) {
archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
"No write callback is registered? "
"This is probably an internal programming error.");
@@ -175,9 +178,9 @@ archive_compressor_bzip2_write(struct archive *a, const void *buff,
SET_NEXT_IN(state, buff);
state->stream.avail_in = length;
if (drive_compressor(a, state, 0))
- return (-1);
+ return (ARCHIVE_FATAL);
a->file_position += length;
- return (length);
+ return (ARCHIVE_OK);
}
@@ -191,6 +194,7 @@ archive_compressor_bzip2_finish(struct archive *a)
int ret;
struct private_data *state;
ssize_t target_block_length;
+ ssize_t bytes_written;
unsigned tocopy;
state = a->compression_data;
@@ -246,12 +250,16 @@ archive_compressor_bzip2_finish(struct archive *a)
}
/* Write the last block */
- ret = (a->client_writer)(a, a->client_data, state->compressed,
- block_length);
+ bytes_written = (a->client_writer)(a, a->client_data,
+ state->compressed, block_length);
- a->raw_position += ret;
- if (ret != 0)
- goto cleanup;
+ /* TODO: Handle short write of final block. */
+ if (bytes_written <= 0)
+ ret = ARCHIVE_FATAL;
+ else {
+ a->raw_position += ret;
+ ret = ARCHIVE_OK;
+ }
/* Cleanup: shut down compressor, release memory, etc. */
cleanup:
@@ -284,27 +292,28 @@ cleanup:
static int
drive_compressor(struct archive *a, struct private_data *state, int finishing)
{
- size_t ret;
+ ssize_t bytes_written;
+ int ret;
for (;;) {
if (state->stream.avail_out == 0) {
- ret = (a->client_writer)(a, a->client_data,
+ bytes_written = (a->client_writer)(a, a->client_data,
state->compressed, state->compressed_buffer_size);
- if (ret <= 0) {
+ if (bytes_written <= 0) {
/* TODO: Handle this write failure */
return (ARCHIVE_FATAL);
- } else if (ret < state->compressed_buffer_size) {
+ } else if ((size_t)bytes_written < state->compressed_buffer_size) {
/* Short write: Move remainder to
* front and keep filling */
memmove(state->compressed,
- state->compressed + ret,
- state->compressed_buffer_size - ret);
+ state->compressed + bytes_written,
+ state->compressed_buffer_size - bytes_written);
}
- a->raw_position += ret;
+ a->raw_position += bytes_written;
state->stream.next_out = state->compressed +
- state->compressed_buffer_size - ret;
- state->stream.avail_out = ret;
+ state->compressed_buffer_size - bytes_written;
+ state->stream.avail_out = bytes_written;
}
ret = BZ2_bzCompress(&(state->stream),
diff --git a/lib/libarchive/archive_write_set_compression_gzip.c b/lib/libarchive/archive_write_set_compression_gzip.c
index 003cf2b55895..c9dafde1c387 100644
--- a/lib/libarchive/archive_write_set_compression_gzip.c
+++ b/lib/libarchive/archive_write_set_compression_gzip.c
@@ -179,7 +179,7 @@ archive_compressor_gzip_init(struct archive *a)
/*
* Write data to the compressed stream.
*/
-static ssize_t
+static int
archive_compressor_gzip_write(struct archive *a, const void *buff,
size_t length)
{
@@ -187,7 +187,7 @@ archive_compressor_gzip_write(struct archive *a, const void *buff,
int ret;
state = a->compression_data;
- if (!a->client_writer) {
+ if (a->client_writer == NULL) {
archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
"No write callback is registered? "
"This is probably an internal programming error.");
@@ -205,7 +205,7 @@ archive_compressor_gzip_write(struct archive *a, const void *buff,
return (ret);
a->file_position += length;
- return (length);
+ return (ARCHIVE_OK);
}
@@ -215,7 +215,7 @@ archive_compressor_gzip_write(struct archive *a, const void *buff,
static int
archive_compressor_gzip_finish(struct archive *a)
{
- ssize_t block_length, target_block_length;
+ ssize_t block_length, target_block_length, bytes_written;
int ret;
struct private_data *state;
unsigned tocopy;
@@ -273,9 +273,13 @@ archive_compressor_gzip_finish(struct archive *a)
/* If it overflowed, flush and start a new block. */
if (tocopy < 8) {
- ret = (a->client_writer)(a, a->client_data, state->compressed,
- state->compressed_buffer_size);
- a->raw_position += ret;
+ bytes_written = (a->client_writer)(a, a->client_data,
+ state->compressed, state->compressed_buffer_size);
+ if (bytes_written <= 0) {
+ ret = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ a->raw_position += bytes_written;
state->stream.next_out = state->compressed;
state->stream.avail_out = state->compressed_buffer_size;
memcpy(state->stream.next_out, trailer + tocopy, 8-tocopy);
@@ -306,9 +310,13 @@ archive_compressor_gzip_finish(struct archive *a)
}
/* Write the last block */
- ret = (a->client_writer)(a, a->client_data, state->compressed,
- block_length);
- a->raw_position += ret;
+ bytes_written = (a->client_writer)(a, a->client_data,
+ state->compressed, block_length);
+ if (bytes_written <= 0) {
+ ret = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ a->raw_position += bytes_written;
/* Cleanup: shut down compressor, release memory, etc. */
cleanup:
@@ -340,27 +348,28 @@ cleanup:
static int
drive_compressor(struct archive *a, struct private_data *state, int finishing)
{
- size_t ret;
+ ssize_t bytes_written;
+ int ret;
for (;;) {
if (state->stream.avail_out == 0) {
- ret = (a->client_writer)(a, a->client_data,
+ bytes_written = (a->client_writer)(a, a->client_data,
state->compressed, state->compressed_buffer_size);
- if (ret <= 0) {
+ if (bytes_written <= 0) {
/* TODO: Handle this write failure */
return (ARCHIVE_FATAL);
- } else if (ret < state->compressed_buffer_size) {
+ } else if ((size_t)bytes_written < state->compressed_buffer_size) {
/* Short write: Move remaining to
* front of block and keep filling */
memmove(state->compressed,
- state->compressed + ret,
- state->compressed_buffer_size - ret);
+ state->compressed + bytes_written,
+ state->compressed_buffer_size - bytes_written);
}
- a->raw_position += ret;
+ a->raw_position += bytes_written;
state->stream.next_out
= state->compressed +
- state->compressed_buffer_size - ret;
- state->stream.avail_out = ret;
+ state->compressed_buffer_size - bytes_written;
+ state->stream.avail_out = bytes_written;
}
ret = deflate(&(state->stream),
diff --git a/lib/libarchive/archive_write_set_compression_none.c b/lib/libarchive/archive_write_set_compression_none.c
index 7a598c688272..bca9d77663d8 100644
--- a/lib/libarchive/archive_write_set_compression_none.c
+++ b/lib/libarchive/archive_write_set_compression_none.c
@@ -104,13 +104,13 @@ archive_compressor_none_init(struct archive *a)
/*
* Write data to the stream.
*/
-static ssize_t
+static int
archive_compressor_none_write(struct archive *a, const void *vbuff,
size_t length)
{
const char *buff;
ssize_t remaining, to_copy;
- int ret;
+ ssize_t bytes_written;
struct archive_none *state;
state = a->compression_data;
@@ -129,10 +129,12 @@ archive_compressor_none_write(struct archive *a, const void *vbuff,
* output buffer.
*/
if (state->avail == 0) {
- ret = (a->client_writer)(a, a->client_data,
+ bytes_written = (a->client_writer)(a, a->client_data,
state->buffer, state->buffer_size);
- /* XXX TODO: if ret < state->buffer_size XXX */
- a->raw_position += ret;
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ /* XXX TODO: if bytes_written < state->buffer_size */
+ a->raw_position += bytes_written;
state->next = state->buffer;
state->avail = state->buffer_size;
}
@@ -147,7 +149,7 @@ archive_compressor_none_write(struct archive *a, const void *vbuff,
remaining -= to_copy;
}
a->file_position += length;
- return (length);
+ return (ARCHIVE_OK);
}
@@ -159,6 +161,7 @@ archive_compressor_none_finish(struct archive *a)
{
ssize_t block_length;
ssize_t target_block_length;
+ ssize_t bytes_written;
int ret;
int ret2;
struct archive_none *state;
@@ -193,9 +196,14 @@ archive_compressor_none_finish(struct archive *a)
target_block_length - block_length);
block_length = target_block_length;
}
- ret = (a->client_writer)(a, a->client_data, state->buffer,
- block_length);
- a->raw_position += ret;
+ bytes_written = (a->client_writer)(a, a->client_data,
+ state->buffer, block_length);
+ if (bytes_written <= 0)
+ ret = ARCHIVE_FATAL;
+ else {
+ a->raw_position += bytes_written;
+ ret = ARCHIVE_OK;
+ }
}
/* Close the output */
diff --git a/lib/libarchive/archive_write_set_format_cpio.c b/lib/libarchive/archive_write_set_format_cpio.c
index 91f8283b362d..c4e669816307 100644
--- a/lib/libarchive/archive_write_set_format_cpio.c
+++ b/lib/libarchive/archive_write_set_format_cpio.c
@@ -99,7 +99,7 @@ archive_write_cpio_header(struct archive *a, struct archive_entry *entry)
{
struct cpio *cpio;
const char *p, *path;
- int pathlength, ret, written;
+ int pathlength, ret;
const struct stat *st;
struct cpio_header h;
@@ -142,19 +142,19 @@ archive_write_cpio_header(struct archive *a, struct archive_entry *entry)
else
format_octal(st->st_size, &h.c_filesize, sizeof(h.c_filesize));
- written = (a->compression_write)(a, &h, sizeof(h));
- if (written < (int)sizeof(h))
+ ret = (a->compression_write)(a, &h, sizeof(h));
+ if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- written = (a->compression_write)(a, path, pathlength);
- if (written < (int)pathlength)
+ ret = (a->compression_write)(a, path, pathlength);
+ if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
cpio->entry_bytes_remaining = st->st_size;
/* Write the symlink now. */
if (p != NULL && *p != '\0')
- (a->compression_write)(a, p, strlen(p));
+ ret = (a->compression_write)(a, p, strlen(p));
return (ret);
}
@@ -233,13 +233,13 @@ archive_write_cpio_finish_entry(struct archive *a)
int to_write, ret;
cpio = a->format_data;
- ret = 0;
+ ret = ARCHIVE_OK;
while (cpio->entry_bytes_remaining > 0) {
to_write = cpio->entry_bytes_remaining < a->null_length ?
cpio->entry_bytes_remaining : a->null_length;
ret = (a->compression_write)(a, a->nulls, to_write);
- if (ret < to_write)
- return (-1);
+ if (ret != ARCHIVE_OK)
+ return (ret);
cpio->entry_bytes_remaining -= to_write;
}
return (ret);
diff --git a/lib/libarchive/archive_write_set_format_pax.c b/lib/libarchive/archive_write_set_format_pax.c
index 7987e08982d9..a4e4f2a9f71a 100644
--- a/lib/libarchive/archive_write_set_format_pax.c
+++ b/lib/libarchive/archive_write_set_format_pax.c
@@ -622,7 +622,7 @@ archive_write_pax_header(struct archive *a,
__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0);
/* If we built any extended attributes, write that entry first. */
- ret = 0;
+ ret = ARCHIVE_OK;
if (archive_strlen(&(pax->pax_header)) > 0) {
struct stat st;
struct archive_entry *pax_attr_entry;
@@ -663,7 +663,7 @@ archive_write_pax_header(struct archive *a,
exit(1);
}
r = (a->compression_write)(a, paxbuff, 512);
- if (r < 512) {
+ if (r != ARCHIVE_OK) {
pax->entry_bytes_remaining = 0;
pax->entry_padding = 0;
return (ARCHIVE_FATAL);
@@ -677,7 +677,7 @@ archive_write_pax_header(struct archive *a,
r = archive_write_data(a, pax->pax_header.s,
archive_strlen(&(pax->pax_header)));
a->state = oldstate;
- if (r < (int)archive_strlen(&(pax->pax_header))) {
+ if (r != ARCHIVE_OK) {
/* If a write fails, we're pretty much toast. */
return (ARCHIVE_FATAL);
}
@@ -687,8 +687,8 @@ archive_write_pax_header(struct archive *a,
/* Write the header for main entry. */
r = (a->compression_write)(a, ustarbuff, 512);
- if (ret != ARCHIVE_OK)
- ret = (r < 512) ? ARCHIVE_FATAL : ARCHIVE_OK;
+ if (r != ARCHIVE_OK)
+ return (r);
/*
* Inform the client of the on-disk size we're using, so
@@ -839,9 +839,9 @@ write_nulls(struct archive *a, size_t padding)
while (padding > 0) {
to_write = padding < a->null_length ? padding : a->null_length;
ret = (a->compression_write)(a, a->nulls, to_write);
- if (ret <= 0)
- return (ARCHIVE_FATAL);
- padding -= ret;
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ padding -= to_write;
}
return (ARCHIVE_OK);
}
diff --git a/lib/libarchive/archive_write_set_format_shar.c b/lib/libarchive/archive_write_set_format_shar.c
index 2e3f348369cd..b636cfbd431f 100644
--- a/lib/libarchive/archive_write_set_format_shar.c
+++ b/lib/libarchive/archive_write_set_format_shar.c
@@ -50,8 +50,7 @@ struct shar {
int uuavail;
char uubuffer[3];
int wrote_header;
- char *work;
- size_t work_len;
+ struct archive_string work;
};
static int archive_write_shar_finish(struct archive *);
@@ -70,23 +69,13 @@ shar_printf(struct archive *a, const char *fmt, ...)
{
struct shar *shar;
va_list ap;
- int required;
int ret;
shar = a->format_data;
- if (shar->work_len <= 0) {
- shar->work_len = 1024;
- shar->work = malloc(shar->work_len);
- }
-
va_start(ap, fmt);
- required = vsnprintf(shar->work, shar->work_len, fmt, ap);
- if ((size_t)required >= shar->work_len) {
- shar->work_len = required + 256;
- realloc(shar->work, shar->work_len);
- required = vsnprintf(shar->work, shar->work_len, fmt, ap);
- }
- ret = ((a->compression_write)(a, shar->work, strlen(shar->work)));
+ archive_string_empty(&(shar->work));
+ archive_string_vsprintf(&(shar->work), fmt, ap);
+ ret = ((a->compression_write)(a, shar->work.s, strlen(shar->work.s)));
va_end(ap);
return (ret);
}
@@ -149,11 +138,16 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
char *p, *pp;
struct shar *shar;
const struct stat *st;
+ int ret;
shar = a->format_data;
if (!shar->wrote_header) {
- shar_printf(a, "#!/bin/sh\n");
- shar_printf(a, "# This is a shell archive\n");
+ ret = shar_printf(a, "#!/bin/sh\n");
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = shar_printf(a, "# This is a shell archive\n");
+ if (ret != ARCHIVE_OK)
+ return (ret);
shar->wrote_header = 1;
}
@@ -192,7 +186,9 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
}
/* Stock preparation for all file types. */
- shar_printf(a, "echo x %s\n", name);
+ ret = shar_printf(a, "echo x %s\n", name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
if (!S_ISDIR(st->st_mode)) {
/* Try to create the dir. */
@@ -206,8 +202,10 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
if (strcmp(p, ".") == 0) {
/* Don't try to "mkdir ." */
} else if (shar->last_dir == NULL) {
- shar_printf(a,
+ ret = shar_printf(a,
"mkdir -p %s > /dev/null 2>&1\n", p);
+ if (ret != ARCHIVE_OK)
+ return (ret);
shar->last_dir = p;
} else if (strcmp(p, shar->last_dir) == 0) {
/* We've already created this exact dir. */
@@ -217,8 +215,10 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
/* We've already created a subdir. */
free(p);
} else {
- shar_printf(a,
+ ret = shar_printf(a,
"mkdir -p %s > /dev/null 2>&1\n", p);
+ if (ret != ARCHIVE_OK)
+ return (ret);
free(shar->last_dir);
shar->last_dir = p;
}
@@ -227,27 +227,41 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
/* Handle file-type specific issues. */
shar->has_data = 0;
- if ((linkname = archive_entry_hardlink(entry)) != NULL)
- shar_printf(a, "ln -f %s %s\n", linkname, name);
- else if ((linkname = archive_entry_symlink(entry)) != NULL)
- shar_printf(a, "ln -fs %s %s\n", linkname, name);
- else {
+ if ((linkname = archive_entry_hardlink(entry)) != NULL) {
+ ret = shar_printf(a, "ln -f %s %s\n", linkname, name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ } else if ((linkname = archive_entry_symlink(entry)) != NULL) {
+ ret = shar_printf(a, "ln -fs %s %s\n", linkname, name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ } else {
switch(st->st_mode & S_IFMT) {
case S_IFREG:
- if (archive_entry_size(entry) == 0)
- shar_printf(a, "touch %s\n", name);
- else {
+ if (archive_entry_size(entry) == 0) {
+ /* More portable than "touch." */
+ ret = shar_printf(a, "test -e \"%s\" || :> \"%s\"\n", name, name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ } else {
if (shar->dump) {
- shar_printf(a,
+ ret = shar_printf(a,
"uudecode -o %s << 'SHAR_END'\n",
name);
- shar_printf(a, "begin %o %s\n",
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = shar_printf(a, "begin %o %s\n",
archive_entry_mode(entry) & 0777,
name);
- } else
- shar_printf(a,
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ } else {
+ ret = shar_printf(a,
"sed 's/^X//' > %s << 'SHAR_END'\n",
name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
shar->has_data = 1;
shar->end_of_line = 1;
shar->outpos = 0;
@@ -255,7 +269,10 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
}
break;
case S_IFDIR:
- shar_printf(a, "mkdir -p %s > /dev/null 2>&1\n", name);
+ ret = shar_printf(a, "mkdir -p %s > /dev/null 2>&1\n",
+ name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
/* Record that we just created this directory. */
if (shar->last_dir != NULL)
free(shar->last_dir);
@@ -271,17 +288,23 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
*/
break;
case S_IFIFO:
- shar_printf(a, "mkfifo %s\n", name);
+ ret = shar_printf(a, "mkfifo %s\n", name);
+ if (ret != ARCHIVE_OK)
+ return (ret);
break;
case S_IFCHR:
- shar_printf(a, "mknod %s c %d %d\n", name,
+ ret = shar_printf(a, "mknod %s c %d %d\n", name,
archive_entry_rdevmajor(entry),
archive_entry_rdevminor(entry));
+ if (ret != ARCHIVE_OK)
+ return (ret);
break;
case S_IFBLK:
- shar_printf(a, "mknod %s b %d %d\n", name,
+ ret = shar_printf(a, "mknod %s b %d %d\n", name,
archive_entry_rdevmajor(entry),
archive_entry_rdevminor(entry));
+ if (ret != ARCHIVE_OK)
+ return (ret);
break;
default:
return (ARCHIVE_WARN);
@@ -293,18 +316,18 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry)
/* XXX TODO: This could be more efficient XXX */
static int
-archive_write_shar_data_sed(struct archive *a, const void *buff, size_t length)
+archive_write_shar_data_sed(struct archive *a, const void *buff, size_t n)
{
struct shar *shar;
const char *src;
- size_t n;
+ int ret;
shar = a->format_data;
if (!shar->has_data)
return (0);
src = buff;
- n = length;
+ ret = ARCHIVE_OK;
shar->outpos = 0;
while (n-- > 0) {
if (shar->end_of_line) {
@@ -316,14 +339,17 @@ archive_write_shar_data_sed(struct archive *a, const void *buff, size_t length)
shar->outbuff[shar->outpos++] = *src++;
if (shar->outpos > sizeof(shar->outbuff) - 2) {
- (a->compression_write)(a, shar->outbuff, shar->outpos);
+ ret = (a->compression_write)(a, shar->outbuff,
+ shar->outpos);
+ if (ret != ARCHIVE_OK)
+ return (ret);
shar->outpos = 0;
}
}
if (shar->outpos > 0)
- (a->compression_write)(a, shar->outbuff, shar->outpos);
- return (length);
+ ret = (a->compression_write)(a, shar->outbuff, shar->outpos);
+ return (ret);
}
#define UUENC(c) (((c)!=0) ? ((c) & 077) + ' ': '`')
@@ -357,6 +383,7 @@ archive_write_shar_data_uuencode(struct archive *a, const void *buff,
struct shar *shar;
const char *src;
size_t n;
+ int ret;
shar = a->format_data;
if (!shar->has_data)
@@ -367,8 +394,10 @@ archive_write_shar_data_uuencode(struct archive *a, const void *buff,
if (shar->uuavail == 3)
uuencode_group(shar);
if (shar->outpos >= 60) {
- shar_printf(a, "%c%s\n", UUENC(shar->outbytes),
+ ret = shar_printf(a, "%c%s\n", UUENC(shar->outbytes),
shar->outbuff);
+ if (ret != ARCHIVE_OK)
+ return (ret);
shar->outpos = 0;
shar->outbytes = 0;
}
@@ -376,7 +405,7 @@ archive_write_shar_data_uuencode(struct archive *a, const void *buff,
shar->uubuffer[shar->uuavail++] = *src++;
shar->outbytes++;
}
- return (length);
+ return (ARCHIVE_OK);
}
static int
@@ -384,6 +413,7 @@ archive_write_shar_finish_entry(struct archive *a)
{
const char *g, *p, *u;
struct shar *shar;
+ int ret;
shar = a->format_data;
if (shar->entry == NULL)
@@ -395,37 +425,51 @@ archive_write_shar_finish_entry(struct archive *a)
if (shar->uuavail > 0)
uuencode_group(shar);
if (shar->outpos > 0) {
- shar_printf(a, "%c%s\n", UUENC(shar->outbytes),
- shar->outbuff);
+ ret = shar_printf(a, "%c%s\n",
+ UUENC(shar->outbytes), shar->outbuff);
+ if (ret != ARCHIVE_OK)
+ return (ret);
shar->outpos = 0;
shar->uuavail = 0;
shar->outbytes = 0;
}
- shar_printf(a, "%c\n", UUENC(0));
- shar_printf(a, "end\n", UUENC(0));
- shar_printf(a, "SHAR_END\n");
+ ret = shar_printf(a, "%c\n", UUENC(0));
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = shar_printf(a, "end\n", UUENC(0));
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = shar_printf(a, "SHAR_END\n");
+ if (ret != ARCHIVE_OK)
+ return (ret);
}
/* Restore file mode, owner, flags. */
/*
* TODO: Don't immediately restore mode for
* directories; defer that to end of script.
*/
- shar_printf(a, "chmod %o %s\n",
+ ret = shar_printf(a, "chmod %o %s\n",
archive_entry_mode(shar->entry) & 07777,
archive_entry_pathname(shar->entry));
+ if (ret != ARCHIVE_OK)
+ return (ret);
u = archive_entry_uname(shar->entry);
g = archive_entry_gname(shar->entry);
if (u != NULL || g != NULL) {
- shar_printf(a, "chown %s%s%s %s\n",
+ ret = shar_printf(a, "chown %s%s%s %s\n",
(u != NULL) ? u : "",
(g != NULL) ? ":" : "", (g != NULL) ? g : "",
archive_entry_pathname(shar->entry));
+ if (ret != ARCHIVE_OK)
+ return (ret);
}
if ((p = archive_entry_fflags_text(shar->entry)) != NULL) {
- shar_printf(a, "chflags %s %s\n", p,
+ ret = shar_printf(a, "chflags %s %s\n", p,
archive_entry_pathname(shar->entry));
+ if (ret != ARCHIVE_OK)
+ return (ret);
}
/* TODO: restore ACLs */
@@ -433,9 +477,14 @@ archive_write_shar_finish_entry(struct archive *a)
} else {
if (shar->has_data) {
/* Finish sed-encoded data: ensure last line ends. */
- if (!shar->end_of_line)
- shar_printf(a, "\n");
- shar_printf(a, "SHAR_END\n");
+ if (!shar->end_of_line) {
+ ret = shar_printf(a, "\n");
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ ret = shar_printf(a, "SHAR_END\n");
+ if (ret != ARCHIVE_OK)
+ return (ret);
}
}
@@ -448,6 +497,7 @@ static int
archive_write_shar_finish(struct archive *a)
{
struct shar *shar;
+ int ret;
/*
* TODO: Accumulate list of directory names/modes and
@@ -463,7 +513,9 @@ archive_write_shar_finish(struct archive *a)
* shar_finish to free the format-specific data).
*/
if (shar->wrote_header) {
- shar_printf(a, "exit\n");
+ ret = shar_printf(a, "exit\n");
+ if (ret != ARCHIVE_OK)
+ return (ret);
/* Shar output is never padded. */
archive_write_set_bytes_in_last_block(a, 1);
/*
@@ -475,8 +527,7 @@ archive_write_shar_finish(struct archive *a)
archive_entry_free(shar->entry);
if (shar->last_dir != NULL)
free(shar->last_dir);
- if (shar->work != NULL)
- free(shar->work);
+ archive_string_free(&(shar->work));
free(shar);
a->format_data = NULL;
return (ARCHIVE_OK);
diff --git a/lib/libarchive/archive_write_set_format_ustar.c b/lib/libarchive/archive_write_set_format_ustar.c
index 3961e7de12ea..51ca5759d236 100644
--- a/lib/libarchive/archive_write_set_format_ustar.c
+++ b/lib/libarchive/archive_write_set_format_ustar.c
@@ -157,8 +157,8 @@ archive_write_ustar_header(struct archive *a, struct archive_entry *entry)
if (ret != ARCHIVE_OK)
return (ret);
ret = (a->compression_write)(a, buff, 512);
- if (ret < 512)
- return (ARCHIVE_FATAL);
+ if (ret != ARCHIVE_OK)
+ return (ret);
ustar->entry_bytes_remaining = archive_entry_size(entry);
ustar->entry_padding = 0x1ff & (- ustar->entry_bytes_remaining);
@@ -469,8 +469,8 @@ write_nulls(struct archive *a, size_t padding)
while (padding > 0) {
to_write = padding < a->null_length ? padding : a->null_length;
ret = (a->compression_write)(a, a->nulls, to_write);
- if (ret < to_write)
- return (ARCHIVE_FATAL);
+ if (ret != ARCHIVE_OK)
+ return (ret);
padding -= to_write;
}
return (ARCHIVE_OK);