From df3c1316b07d107960eddb0873b86ed561163949 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Tue, 9 Mar 2004 19:50:41 +0000 Subject: [PATCH] Many fixes. Portability: Thanks to Juergen Lock, libarchive now compiles cleanly on Linux. Along the way, I cleaned up a lot of error return codes and reorganized some code to simplify conditional compilation of certain sections. Bug fixes: * pax format now actually stores filenames that are 101-154 characters long. * pax format now allows newline characters in extended attributes (this fixes a long-standing bug in ACL handling) * mtime/atime are now restored for directories * directory list is now sorted prior to fix-up to permit correct restore of non-writable dir heirarchies --- lib/libarchive/Makefile | 10 +- lib/libarchive/Makefile.freebsd | 10 +- lib/libarchive/archive.h | 14 + lib/libarchive/archive.h.in | 14 + lib/libarchive/archive_check_magic.c | 6 +- lib/libarchive/archive_entry.c | 4 +- lib/libarchive/archive_platform.h | 73 ++++++ lib/libarchive/archive_private.h | 11 +- lib/libarchive/archive_read.c | 13 +- .../archive_read_data_into_buffer.c | 4 +- lib/libarchive/archive_read_data_into_fd.c | 6 +- lib/libarchive/archive_read_extract.c | 246 +++++++++++++----- lib/libarchive/archive_read_open_file.c | 4 +- lib/libarchive/archive_read_open_filename.c | 4 +- .../archive_read_support_compression_all.c | 4 +- .../archive_read_support_compression_bzip2.c | 24 +- .../archive_read_support_compression_gzip.c | 24 +- .../archive_read_support_compression_none.c | 4 +- .../archive_read_support_format_all.c | 4 +- .../archive_read_support_format_cpio.c | 4 +- .../archive_read_support_format_gnutar.c | 4 +- .../archive_read_support_format_tar.c | 18 +- lib/libarchive/archive_string.c | 4 +- lib/libarchive/archive_string_sprintf.c | 5 +- lib/libarchive/archive_util.c | 6 +- lib/libarchive/archive_write.c | 4 +- lib/libarchive/archive_write_open_file.c | 4 +- lib/libarchive/archive_write_open_filename.c | 4 +- .../archive_write_set_compression_bzip2.c | 22 +- .../archive_write_set_compression_gzip.c | 22 +- .../archive_write_set_compression_none.c | 8 +- lib/libarchive/archive_write_set_format.c | 7 +- .../archive_write_set_format_by_name.c | 7 +- .../archive_write_set_format_cpio.c | 4 +- lib/libarchive/archive_write_set_format_pax.c | 20 +- .../archive_write_set_format_shar.c | 6 +- .../archive_write_set_format_ustar.c | 23 +- 37 files changed, 448 insertions(+), 203 deletions(-) create mode 100644 lib/libarchive/archive_platform.h diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index 2abc4bdf545e..8e13dcb6b6eb 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -109,13 +109,13 @@ MLINKS += libarchive.3 archive.3 INCS = archive.h archive_entry.h -CFLAGS+=-DDEBUG -g .if defined(DMALLOC) -CFLAGS+=-DDMALLOC -I/usr/local/include -LDFLAGS+=-L/usr/local/lib -ldmalloc +DEBUG_FLAGS+= -DDEBUG -g +CFLAGS+= -DHAVE_DMALLOC -I/usr/local/include +LDFLAGS+= -L/usr/local/lib -ldmalloc .endif -# Should be WARNS=10, except that zlib.h is borked. -WARNS?= 3 +# Should be WARNS=6, except that zlib.h is borked. +WARNS?= 3 .include diff --git a/lib/libarchive/Makefile.freebsd b/lib/libarchive/Makefile.freebsd index 2abc4bdf545e..8e13dcb6b6eb 100644 --- a/lib/libarchive/Makefile.freebsd +++ b/lib/libarchive/Makefile.freebsd @@ -109,13 +109,13 @@ MLINKS += libarchive.3 archive.3 INCS = archive.h archive_entry.h -CFLAGS+=-DDEBUG -g .if defined(DMALLOC) -CFLAGS+=-DDMALLOC -I/usr/local/include -LDFLAGS+=-L/usr/local/lib -ldmalloc +DEBUG_FLAGS+= -DDEBUG -g +CFLAGS+= -DHAVE_DMALLOC -I/usr/local/include +LDFLAGS+= -L/usr/local/lib -ldmalloc .endif -# Should be WARNS=10, except that zlib.h is borked. -WARNS?= 3 +# Should be WARNS=6, except that zlib.h is borked. +WARNS?= 3 .include diff --git a/lib/libarchive/archive.h b/lib/libarchive/archive.h index 948e67b8a58f..f0028b0c9dab 100644 --- a/lib/libarchive/archive.h +++ b/lib/libarchive/archive.h @@ -51,6 +51,20 @@ struct archive_entry; #define ARCHIVE_RETRY (-2) /* Retry might succeed. */ #define ARCHIVE_FATAL (-3) /* No more operations are possible. */ +/* + * As far as possible, archive_errno returns standard platform errno codes. + * Of course, the details vary by platform, so the actual definitions + * here are stored in "archive_platform.h". The symbols are listed here + * for reference; as a rule, clients should not need to know the exact + * platform-dependent error code. + */ +/* Unrecognized or invalid file format. */ +/* #define ARCHIVE_ERRNO_FILE_FORMAT */ +/* Illegal usage of the library. */ +/* #define ARCHIVE_ERRNO_PROGRAMMER_ERROR */ +/* Unknown or unclassified error. */ +/* #define ARCHIVE_ERRNO_MISC */ + /* * Callbacks are invoked to automatically read/write/open/close the archive. * You can provide your own for complex tasks (like breaking archives diff --git a/lib/libarchive/archive.h.in b/lib/libarchive/archive.h.in index 948e67b8a58f..f0028b0c9dab 100644 --- a/lib/libarchive/archive.h.in +++ b/lib/libarchive/archive.h.in @@ -51,6 +51,20 @@ struct archive_entry; #define ARCHIVE_RETRY (-2) /* Retry might succeed. */ #define ARCHIVE_FATAL (-3) /* No more operations are possible. */ +/* + * As far as possible, archive_errno returns standard platform errno codes. + * Of course, the details vary by platform, so the actual definitions + * here are stored in "archive_platform.h". The symbols are listed here + * for reference; as a rule, clients should not need to know the exact + * platform-dependent error code. + */ +/* Unrecognized or invalid file format. */ +/* #define ARCHIVE_ERRNO_FILE_FORMAT */ +/* Illegal usage of the library. */ +/* #define ARCHIVE_ERRNO_PROGRAMMER_ERROR */ +/* Unknown or unclassified error. */ +/* #define ARCHIVE_ERRNO_MISC */ + /* * Callbacks are invoked to automatically read/write/open/close the archive. * You can provide your own for complex tasks (like breaking archives diff --git a/lib/libarchive/archive_check_magic.c b/lib/libarchive/archive_check_magic.c index 719ba9e1d656..b83730fe8840 100644 --- a/lib/libarchive/archive_check_magic.c +++ b/lib/libarchive/archive_check_magic.c @@ -24,10 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#include + +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c index d48ab325a86a..268afe615e39 100644 --- a/lib/libarchive/archive_entry.c +++ b/lib/libarchive/archive_entry.c @@ -24,12 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_platform.h b/lib/libarchive/archive_platform.h new file mode 100644 index 000000000000..fca65a116bff --- /dev/null +++ b/lib/libarchive/archive_platform.h @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2003-2004 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * This header is the first thing included in any of the libarchive + * source files. As far as possible, platform-specific issues should + * be dealt with here and not within individual source files. + */ + +#ifndef ARCHIVE_PLATFORM_H_INCLUDED +#define ARCHIVE_PLATFORM_H_INCLUDED + +/* FreeBSD-specific definitions. */ +#ifdef __FreeBSD__ +#include /* For __FBSDID */ +#define HAVE_POSIX_ACL 1 +#define HAVE_CHFLAGS 1 +#define HAVE_LUTIMES 1 +#define HAVE_LCHMOD 1 +#define ARCHIVE_ERRNO_FILE_FORMAT EFTYPE +#define ARCHIVE_ERRNO_PROGRAMMER EDOOFUS +#define ARCHIVE_ERRNO_MISC (-1) +#endif + +/* No non-FreeBSD platform will have __FBSDID, so just define it here. */ +#ifndef __FreeBSD__ +#define __FBSDID(a) /* null */ +#endif + +/* Linux */ +#ifdef LINUX +#define ARCHIVE_ERRNO_FILE_FORMAT EILSEQ +#define ARCHIVE_ERRNO_PROGRAMMER EINVAL +#define ARCHIVE_ERRNO_MISC (-1) +#define st_atimespec st_atim +#define st_mtimespec st_mtim +#define st_ctimespec st_ctim +#endif + +/* + * XXX TODO: Use autoconf to handle non-FreeBSD platforms. + * + * #if !defined(__FreeBSD__) + * #include "config.h" + * #endif + */ + +#endif /* !ARCHIVE_H_INCLUDED */ diff --git a/lib/libarchive/archive_private.h b/lib/libarchive/archive_private.h index 58c093b5d86b..a42f23902f01 100644 --- a/lib/libarchive/archive_private.h +++ b/lib/libarchive/archive_private.h @@ -42,16 +42,7 @@ * directories so that they can be initially restored writable, then * fixed up at end. This also handles mtime/atime fixups. */ -struct archive_extract_dir_entry { - struct archive_extract_dir_entry *next; - mode_t mode; - int64_t mtime; - int64_t atime; - unsigned long mtime_nanos; - unsigned long atime_nanos; - /* Note: ctime cannot be restored, so don't bother */ - char *name; -}; +struct archive_extract_dir_entry; struct archive { /* diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c index 1c24d2dc7214..e51ea02df5fc 100644 --- a/lib/libarchive/archive_read.c +++ b/lib/libarchive/archive_read.c @@ -32,10 +32,10 @@ * needlessly bloating statically-linked clients. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -183,8 +183,8 @@ choose_decompressor(struct archive *a, const void *buffer, size_t bytes_read) * support this stream. */ if (best_bid < 1) { - archive_set_error(a, EFTYPE, "Unrecognized archive format"); - /* EFTYPE == "Inappropriate file type or format" */ + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, + "Unrecognized archive format"); return (ARCHIVE_FATAL); } @@ -303,7 +303,8 @@ choose_format(struct archive *a) * can't support this stream. */ if (best_bid < 1) { - archive_set_error(a, EFTYPE, "Unrecognized archive format"); + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, + "Unrecognized archive format"); return (ARCHIVE_FATAL); } @@ -374,7 +375,7 @@ archive_read_data_skip(struct archive *a) return (ARCHIVE_FATAL); } if (bytes_read == 0) { - archive_set_error(a, 0, + archive_set_error(a, EIO, "Premature end of archive entry"); return (ARCHIVE_FATAL); } diff --git a/lib/libarchive/archive_read_data_into_buffer.c b/lib/libarchive/archive_read_data_into_buffer.c index 988a2bf42650..f41111558544 100644 --- a/lib/libarchive/archive_read_data_into_buffer.c +++ b/lib/libarchive/archive_read_data_into_buffer.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_data_into_fd.c b/lib/libarchive/archive_read_data_into_fd.c index 7dad23379350..b8d620a74b9d 100644 --- a/lib/libarchive/archive_read_data_into_fd.c +++ b/lib/libarchive/archive_read_data_into_fd.c @@ -24,10 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#include + +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c index 0c438ea56dff..80a4aa12e8a7 100644 --- a/lib/libarchive/archive_read_extract.c +++ b/lib/libarchive/archive_read_extract.c @@ -24,15 +24,17 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include #include +#ifdef HAVE_POSIX_ACL #include +#endif #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -75,13 +77,33 @@ static int archive_read_extract_symbolic_link(struct archive *, static int mkdirpath(struct archive *, const char *); static int mkdirpath_recursive(char *path); static int mksubdir(char *path); +#ifdef HAVE_POSIX_ACL +static int set_acl(struct archive *a, const char *acl_text, + acl_type_t type, const char *pathname); +#endif static int set_acls(struct archive *, struct archive_entry *); static int set_extended_perm(struct archive *, struct archive_entry *, int flags); static int set_fflags(struct archive *, struct archive_entry *); static int set_ownership(struct archive *, struct archive_entry *, int); -static int set_perm(struct archive *, struct archive_entry *, int mode, int flags); +static int set_perm(struct archive *, struct archive_entry *, int mode, + int flags); static int set_time(struct archive *, struct archive_entry *, int); +static struct archive_extract_dir_entry * + sort_dir_list(struct archive_extract_dir_entry *p); + + +struct archive_extract_dir_entry { + struct archive_extract_dir_entry *next; + mode_t mode; + int64_t mtime; + int64_t atime; + unsigned long mtime_nanos; + unsigned long atime_nanos; + /* Note: ctime cannot be restored, so don't bother */ + char *name; +}; + /* * Extract this entry to disk. @@ -108,15 +130,21 @@ archive_read_extract(struct archive *a, struct archive_entry *entry, int flags) writable_mode = archive_entry_stat(entry)->st_mode | 0700; /* - * If this dir isn't writable, restore it with write - * permissions and add it to the fixup list for later - * handling. + * In order to correctly restore non-writable dirs or + * dir timestamps, we need to maintain a fix-up list. */ - if (archive_entry_stat(entry)->st_mode != writable_mode) { + if (archive_entry_stat(entry)->st_mode != writable_mode || + flags & ARCHIVE_EXTRACT_TIME) { le = malloc(sizeof(struct archive_extract_dir_entry)); le->next = a->archive_extract_dir_list; a->archive_extract_dir_list = le; le->mode = archive_entry_stat(entry)->st_mode; + le->mtime = archive_entry_stat(entry)->st_mtime; + le->mtime_nanos = + archive_entry_stat(entry)->st_mtimespec.tv_nsec; + le->atime = archive_entry_stat(entry)->st_atime; + le->atime_nanos = + archive_entry_stat(entry)->st_atimespec.tv_nsec; le->name = malloc(strlen(archive_entry_pathname(entry)) + 1); strcpy(le->name, archive_entry_pathname(entry)); @@ -172,39 +200,112 @@ archive_read_extract(struct archive *a, struct archive_entry *entry, int flags) /* * Cleanup function for archive_extract. Free name/mode list and - * restore permissions. + * restore permissions and dir timestamps. This must be done last; + * otherwise, the dir permission might prevent us from restoring a + * file. Similarly, the act of restoring a file touches the directory + * and changes the timestamp on the dir, so we have to touch-up the + * timestamps at the end as well. Note that tar/cpio do not require + * that archives be in a particular order; there is no way to know + * when the last file has been restored within a directory, so there's + * no way to optimize the memory usage here by fixing up the directory + * any earlier than the end-of-archive. * - * TODO: Restore times here as well. + * XXX TODO: Directory ACLs should be restored here, for the same + * reason we set directory perms here. XXX * * Registering this function (rather than calling it explicitly by - * name from archive_read_finish) reduces link pollution, since + * name from archive_read_finish) reduces static link pollution, since * applications that don't use this API won't get this file linked in. */ static void archive_extract_cleanup(struct archive *a) { - struct archive_extract_dir_entry *lp; + struct archive_extract_dir_entry *next, *p; - /* - * TODO: Does dir list need to be sorted so permissions are restored - * depth-first? - */ - while (a->archive_extract_dir_list) { - lp = a->archive_extract_dir_list->next; - chmod(a->archive_extract_dir_list->name, - a->archive_extract_dir_list->mode); - /* - * TODO: Consider using this hook to restore dir - * timestamps as well. However, dir timestamps don't - * really matter, and it would be a memory issue to - * record timestamps for every directory - * extracted... Ugh. - */ - if (a->archive_extract_dir_list->name) - free(a->archive_extract_dir_list->name); - free(a->archive_extract_dir_list); - a->archive_extract_dir_list = lp; + /* Sort dir list so directories are fixed up in depth-first order. */ + p = sort_dir_list(a->archive_extract_dir_list); + + while (p != NULL) { + struct timeval times[2]; + + times[1].tv_sec = p->mtime; + times[1].tv_usec = p->mtime_nanos / 1000; + times[0].tv_sec = p->atime; + times[0].tv_usec = p->atime_nanos / 1000; + + chmod(p->name, p->mode); + utimes(p->name, times); + + next = p->next; + free(p->name); + free(p); + p = next; } + a->archive_extract_dir_list = NULL; +} + +/* + * Simple O(n log n) merge sort to order the directories prior to fix-up. + */ +static struct archive_extract_dir_entry * +sort_dir_list(struct archive_extract_dir_entry *p) +{ + struct archive_extract_dir_entry *a, *b, *t; + + if (p == NULL) + return NULL; + /* A one-item list is already sorted. */ + if (p->next == NULL) + return (p); + + /* Step 1: split the list. */ + t = p; + a = p->next->next; + while (a != NULL) { + /* Step a twice, t once. */ + a = a->next; + if (a != NULL) + a = a->next; + t = t->next; + } + /* Now, t is at the mid-point, so break the list here. */ + b = t->next; + t->next = NULL; + a = p; + + /* Step 2: Recursively sort the two sub-lists. */ + a = sort_dir_list(a); + b = sort_dir_list(b); + + /* Step 3: Merge the returned lists. */ + /* Pick the first element for the merged list. */ + if (strcmp(a->name, b->name) > 0) { + t = p = a; + a = a->next; + } else { + t = p = b; + b = b->next; + } + + /* Always put the later element on the list first. */ + while (a != NULL && b != NULL) { + if (strcmp(a->name, b->name) > 0) { + t->next = a; + a = a->next; + } else { + t->next = b; + b = b->next; + } + t = t->next; + } + + /* Only one list is non-empty, so just splice it on. */ + if (a != NULL) + t->next = a; + if (b != NULL) + t->next = b; + + return (p); } static int @@ -620,7 +721,12 @@ set_time(struct archive *a, struct archive_entry *entry, int flags) times[0].tv_sec = st->st_atime; times[0].tv_usec = st->st_atimespec.tv_nsec / 1000; +#ifdef HAVE_LUTIMES if (lutimes(archive_entry_pathname(entry), times) != 0) { +#else + if ((archive_entry_mode(entry) & S_IFMT) != S_IFLNK && + utimes(archive_entry_pathname(entry), times) != 0) { +#endif archive_set_error(a, errno, "Can't update time for %s", archive_entry_pathname(entry)); return (ARCHIVE_WARN); @@ -645,7 +751,12 @@ set_perm(struct archive *a, struct archive_entry *entry, int mode, int flags) return (ARCHIVE_OK); name = archive_entry_pathname(entry); +#ifdef HAVE_LCHMOD if (lchmod(name, mode) != 0) { +#else + if ((archive_entry_mode(entry) & S_IFMT) != S_IFLNK && + chmod(name, mode) != 0) { +#endif archive_set_error(a, errno, "Can't set permissions"); return (ARCHIVE_WARN); } @@ -688,6 +799,7 @@ set_fflags(struct archive *a, struct archive_entry *entry) if (fflags == NULL) return (ARCHIVE_WARN); +#ifdef HAVE_CHFLAGS fflags_p = fflags; if (strtofflags(&fflags_p, &set, &clear) != 0 && stat(name, &st) == 0) { @@ -699,6 +811,8 @@ set_fflags(struct archive *a, struct archive_entry *entry) ret = ARCHIVE_WARN; } } +#endif + free(fflags); return (ret); } @@ -709,46 +823,58 @@ set_fflags(struct archive *a, struct archive_entry *entry) static int set_acls(struct archive *a, struct archive_entry *entry) { - const char *acldesc; - acl_t acl; +#ifdef HAVE_POSIX_ACL + const char *acl_text; const char *name; int ret; ret = ARCHIVE_OK; + name = archive_entry_pathname(entry); - acldesc = archive_entry_acl(entry); - if (acldesc != NULL) { - acl = acl_from_text(acldesc); - if (acl == NULL) { - archive_set_error(a, errno, "Error parsing acl '%s'", - acldesc); - ret = ARCHIVE_WARN; - } else { - if (acl_set_file(name, ACL_TYPE_ACCESS, acl) != 0) { - archive_set_error(a, errno, - "Failed to set acl"); - ret = ARCHIVE_WARN; - } - acl_free(acl); - } + acl_text = archive_entry_acl(entry); + ret = set_acl(a, acl_text, ACL_TYPE_ACCESS, name); + if (ret == ARCHIVE_OK) { + acl_text = archive_entry_acl_default(entry); + ret = set_acl(a, acl_text, ACL_TYPE_DEFAULT, name); } - acldesc = archive_entry_acl_default(entry); - if (acldesc != NULL) { - acl = acl_from_text(acldesc); - if (acl == NULL) { - archive_set_error(a, errno, "error parsing acl '%s'", - acldesc); + return (ret); +#else + /* Default empty function body to satisfy mainline code. */ + (void)a; + (void)entry; + return (ARCHIVE_OK); +#endif +} + +#ifdef HAVE_POSIX_ACL +static int +set_acl(struct archive *a, const char *acl_text, acl_type_t type, + const char *name) +{ + acl_t acl; + int ret; + + ret = ARCHIVE_OK; + + if (acl_text == NULL) + return (ret); + + acl = acl_from_text(acl_text); + if (acl == NULL) { + archive_set_error(a, errno, "Error parsing acl '%s'", + acl_text); + ret = ARCHIVE_WARN; + } else { + if (acl_set_file(name, type, acl) != 0) { + archive_set_error(a, errno, + "Failed to set acl '%s' (type %d)", + acl_text, type); ret = ARCHIVE_WARN; - } else { - if (acl_set_file(name, ACL_TYPE_DEFAULT, acl) != 0) { - archive_set_error(a, errno, - "Failed to set acl"); - ret = ARCHIVE_WARN; - } - acl_free(acl); } + acl_free(acl); } return (ret); } +#endif diff --git a/lib/libarchive/archive_read_open_file.c b/lib/libarchive/archive_read_open_file.c index f2fdc63c3c1a..a07ff2957078 100644 --- a/lib/libarchive/archive_read_open_file.c +++ b/lib/libarchive/archive_read_open_file.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_open_filename.c b/lib/libarchive/archive_read_open_filename.c index f2fdc63c3c1a..a07ff2957078 100644 --- a/lib/libarchive/archive_read_open_filename.c +++ b/lib/libarchive/archive_read_open_filename.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_support_compression_all.c b/lib/libarchive/archive_read_support_compression_all.c index 2d5efe15383f..0363f6a6e383 100644 --- a/lib/libarchive/archive_read_support_compression_all.c +++ b/lib/libarchive/archive_read_support_compression_all.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif diff --git a/lib/libarchive/archive_read_support_compression_bzip2.c b/lib/libarchive/archive_read_support_compression_bzip2.c index c97160f8869e..85ae5a9e712a 100644 --- a/lib/libarchive/archive_read_support_compression_bzip2.c +++ b/lib/libarchive/archive_read_support_compression_bzip2.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -181,25 +181,25 @@ init(struct archive *a, const void *buff, size_t n) } /* Library setup failed: Clean up. */ - archive_set_error(a, -1, "Internal error initializing %s library", - a->compression_name); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Internal error initializing %s library", a->compression_name); free(state->uncompressed_buffer); free(state); /* Override the error message if we know what really went wrong. */ switch (ret) { case BZ_PARAM_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "invalid setup parameter"); break; case BZ_MEM_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "out of memory"); break; case BZ_CONFIG_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "mis-compiled library"); break; @@ -221,7 +221,7 @@ read_ahead(struct archive *a, const void **p, size_t min) state = a->compression_data; was_avail = -1; if (!a->client_reader) { - archive_set_error(a, EINVAL, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No read callback is registered? " "This is probably an internal programming error."); return (ARCHIVE_FATAL); @@ -284,8 +284,8 @@ finish(struct archive *a) case BZ_OK: break; default: - archive_set_error(a, -1, "Failed to clean up %s compressor", - a->compression_name); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Failed to clean up %s compressor", a->compression_name); ret = ARCHIVE_FATAL; } @@ -323,7 +323,7 @@ drive_decompressor(struct archive *a, struct private_data *state) goto fatal; } if (ret == 0 && total_decompressed == 0) { - archive_set_error(a, -1, + archive_set_error(a, EIO, "Premature end of %s compressed data", a->compression_name); return (ARCHIVE_FATAL); @@ -359,7 +359,7 @@ drive_decompressor(struct archive *a, struct private_data *state) /* Return a fatal error. */ fatal: - archive_set_error(a, -1, "%s decompression failed", + archive_set_error(a, ARCHIVE_ERRNO_MISC, "%s decompression failed", a->compression_name); return (ARCHIVE_FATAL); } diff --git a/lib/libarchive/archive_read_support_compression_gzip.c b/lib/libarchive/archive_read_support_compression_gzip.c index d0816b0da2ce..c6d86cd01eeb 100644 --- a/lib/libarchive/archive_read_support_compression_gzip.c +++ b/lib/libarchive/archive_read_support_compression_gzip.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -185,25 +185,25 @@ init(struct archive *a, const void *buff, size_t n) } /* Library setup failed: Clean up. */ - archive_set_error(a, -1, "Internal error initializing %s library", - a->compression_name); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Internal error initializing %s library", a->compression_name); free(state->uncompressed_buffer); free(state); /* Override the error message if we know what really went wrong. */ switch (ret) { case Z_STREAM_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "invalid setup parameter"); break; case Z_MEM_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ENOMEM, "Internal error initializing compression library: " "out of memory"); break; case Z_VERSION_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "invalid library version"); break; @@ -225,7 +225,7 @@ read_ahead(struct archive *a, const void **p, size_t min) state = a->compression_data; was_avail = -1; if (!a->client_reader) { - archive_set_error(a, EINVAL, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No read callback is registered? " "This is probably an internal programming error."); return (ARCHIVE_FATAL); @@ -288,8 +288,8 @@ finish(struct archive *a) case Z_OK: break; default: - archive_set_error(a, -1, "Failed to clean up %s compressor", - a->compression_name); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Failed to clean up %s compressor", a->compression_name); ret = ARCHIVE_FATAL; } @@ -332,7 +332,7 @@ drive_decompressor(struct archive *a, struct private_data *state) goto fatal; } if (ret == 0 && total_decompressed == 0) { - archive_set_error(a, -1, + archive_set_error(a, EIO, "Premature end of %s compressed data", a->compression_name); return (ARCHIVE_FATAL); @@ -493,7 +493,7 @@ drive_decompressor(struct archive *a, struct private_data *state) /* Return a fatal error. */ fatal: - archive_set_error(a, -1, "%s decompression failed", + archive_set_error(a, ARCHIVE_ERRNO_MISC, "%s decompression failed", a->compression_name); return (ARCHIVE_FATAL); } diff --git a/lib/libarchive/archive_read_support_compression_none.c b/lib/libarchive/archive_read_support_compression_none.c index 0f7e42f4145f..0704b4e4c192 100644 --- a/lib/libarchive/archive_read_support_compression_none.c +++ b/lib/libarchive/archive_read_support_compression_none.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_support_format_all.c b/lib/libarchive/archive_read_support_format_all.c index ded39f81cf7f..883c4ce72ed4 100644 --- a/lib/libarchive/archive_read_support_format_all.c +++ b/lib/libarchive/archive_read_support_format_all.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif diff --git a/lib/libarchive/archive_read_support_format_cpio.c b/lib/libarchive/archive_read_support_format_cpio.c index 73518db7e6ab..de11aa55d8fa 100644 --- a/lib/libarchive/archive_read_support_format_cpio.c +++ b/lib/libarchive/archive_read_support_format_cpio.c @@ -24,12 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_support_format_gnutar.c b/lib/libarchive/archive_read_support_format_gnutar.c index fd1a9cc0dfbb..98fbef60156e 100644 --- a/lib/libarchive/archive_read_support_format_gnutar.c +++ b/lib/libarchive/archive_read_support_format_gnutar.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c index 47b40116b7dd..5bfd944c9d85 100644 --- a/lib/libarchive/archive_read_support_format_tar.c +++ b/lib/libarchive/archive_read_support_format_tar.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -627,6 +627,9 @@ pax_header(struct archive *a, struct archive_entry *entry, struct stat *st, return (0); /* Null-terminate 'key' value. */ + /* XXX TODO: 'key' is officially UTF-8; should + * decode UTF-8 key to wchar here, then do + * all wchar matching below. XXX */ key = p; p = strchr(key, '='); if (p == NULL) @@ -638,13 +641,12 @@ pax_header(struct archive *a, struct archive_entry *entry, struct stat *st, return (-1); /* Null-terminate 'value' portion. */ + /* XXX need to decode UTF-8 value, make everything + * else wchar-clean. */ + /* XXX should use pointer/length so that NULLs can + * appear within the value portion. */ value = p + 1; - p = strchr(value, '\n'); - if (p == NULL) - return (-1); - if (p > line + line_length) - return (-1); - *p = 0; + line[line_length - 1] = 0; if (pax_attribute(a, entry, st, key, value)) return (-1); diff --git a/lib/libarchive/archive_string.c b/lib/libarchive/archive_string.c index 8f50a422cccc..b100fb9c7ee8 100644 --- a/lib/libarchive/archive_string.c +++ b/lib/libarchive/archive_string.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); /* @@ -32,7 +32,7 @@ __FBSDID("$FreeBSD$"); * strings while minimizing heap activity. */ -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_string_sprintf.c b/lib/libarchive/archive_string_sprintf.c index c24a7479a728..5609dd929c9e 100644 --- a/lib/libarchive/archive_string_sprintf.c +++ b/lib/libarchive/archive_string_sprintf.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); /* @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); * the core code, so it cannot easily be omitted.) */ -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -63,6 +63,7 @@ __archive_string_vsprintf(struct archive_string *as, const char *fmt, __archive_string_ensure(as, l + 1); l = vsnprintf(as->s, as->buffer_length, fmt, ap); } + as->length = l; } /* diff --git a/lib/libarchive/archive_util.c b/lib/libarchive/archive_util.c index a3b1a6a2917c..587e8af803b4 100644 --- a/lib/libarchive/archive_util.c +++ b/lib/libarchive/archive_util.c @@ -24,10 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#include + +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_write.c b/lib/libarchive/archive_write.c index cd8434e9c8a9..050d7e23dffb 100644 --- a/lib/libarchive/archive_write.c +++ b/lib/libarchive/archive_write.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); /* @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_write_open_file.c b/lib/libarchive/archive_write_open_file.c index 65d3d45272d1..cae6cd60766a 100644 --- a/lib/libarchive/archive_write_open_file.c +++ b/lib/libarchive/archive_write_open_file.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_write_open_filename.c b/lib/libarchive/archive_write_open_filename.c index 65d3d45272d1..cae6cd60766a 100644 --- a/lib/libarchive/archive_write_open_filename.c +++ b/lib/libarchive/archive_write_open_filename.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_write_set_compression_bzip2.c b/lib/libarchive/archive_write_set_compression_bzip2.c index 23828a29cef6..ed6ebb4e16c3 100644 --- a/lib/libarchive/archive_write_set_compression_bzip2.c +++ b/lib/libarchive/archive_write_set_compression_bzip2.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -122,7 +122,7 @@ archive_compressor_bzip2_init(struct archive *a) } /* Library setup failed: clean up. */ - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library"); free(state->compressed); free(state); @@ -130,17 +130,17 @@ archive_compressor_bzip2_init(struct archive *a) /* Override the error message if we know what really went wrong. */ switch (ret) { case BZ_PARAM_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "invalid setup parameter"); break; case BZ_MEM_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ENOMEM, "Internal error initializing compression library: " "out of memory"); break; case BZ_CONFIG_ERROR: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error initializing compression library: " "mis-compiled library"); break; @@ -161,7 +161,7 @@ archive_compressor_bzip2_write(struct archive *a, const void *buff, state = a->compression_data; if (!a->client_writer) { - archive_set_error(a, EINVAL, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No write callback is registered? " "This is probably an internal programming error."); return (ARCHIVE_FATAL); @@ -194,7 +194,7 @@ archive_compressor_bzip2_finish(struct archive *a) state = a->compression_data; ret = ARCHIVE_OK; if (a->client_writer == NULL) { - archive_set_error(a, EINVAL, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No write callback is registered?\n" "This is probably an internal programming error."); ret = ARCHIVE_FATAL; @@ -256,7 +256,8 @@ archive_compressor_bzip2_finish(struct archive *a) case BZ_OK: break; default: - archive_set_error(a, -1, "Failed to clean up compressor"); + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, + "Failed to clean up compressor"); ret = ARCHIVE_FATAL; } @@ -319,7 +320,8 @@ drive_compressor(struct archive *a, struct private_data *state, int finishing) return (ARCHIVE_OK); default: /* Any other return value indicates an error */ - archive_set_error(a, -1, "Bzip2 compression failed"); + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, + "Bzip2 compression failed"); return (ARCHIVE_FATAL); } } diff --git a/lib/libarchive/archive_write_set_compression_gzip.c b/lib/libarchive/archive_write_set_compression_gzip.c index 7c9ade691061..cd44e8ea1f6b 100644 --- a/lib/libarchive/archive_write_set_compression_gzip.c +++ b/lib/libarchive/archive_write_set_compression_gzip.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -149,7 +149,7 @@ archive_compressor_gzip_init(struct archive *a) } /* Library setup failed: clean up. */ - archive_set_error(a, -1, "Internal error " + archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal error " "initializing compression library"); free(state->compressed); free(state); @@ -157,7 +157,8 @@ archive_compressor_gzip_init(struct archive *a) /* Override the error message if we know what really went wrong. */ switch (ret) { case Z_STREAM_ERROR: - archive_set_error(a, EINVAL, "Internal error initializing " + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Internal error initializing " "compression library: invalid setup parameter"); break; case Z_MEM_ERROR: @@ -165,7 +166,8 @@ archive_compressor_gzip_init(struct archive *a) "compression library"); break; case Z_VERSION_ERROR: - archive_set_error(a, -1, "Internal error initializing " + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Internal error initializing " "compression library: invalid library version"); break; } @@ -185,7 +187,7 @@ archive_compressor_gzip_write(struct archive *a, const void *buff, state = a->compression_data; if (!a->client_writer) { - archive_set_error(a, EDOOFUS, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No write callback is registered? " "This is probably an internal programming error."); return (ARCHIVE_FATAL); @@ -220,7 +222,7 @@ archive_compressor_gzip_finish(struct archive *a) state = a->compression_data; ret = 0; if (a->client_writer == NULL) { - archive_set_error(a, EDOOFUS, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No write callback is registered? " "This is probably an internal programming error."); ret = ARCHIVE_FATAL; @@ -310,7 +312,8 @@ archive_compressor_gzip_finish(struct archive *a) case Z_OK: break; default: - archive_set_error(a, -1, "Failed to clean up compressor"); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Failed to clean up compressor"); ret = ARCHIVE_FATAL; } free(state->compressed); @@ -373,7 +376,8 @@ drive_compressor(struct archive *a, struct private_data *state, int finishing) return (ARCHIVE_OK); default: /* Any other return value indicates an error. */ - archive_set_error(a, -1, "GZip compression failed"); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "GZip compression failed"); return (ARCHIVE_FATAL); } } diff --git a/lib/libarchive/archive_write_set_compression_none.c b/lib/libarchive/archive_write_set_compression_none.c index b0ed24cd497b..579fa8f160d3 100644 --- a/lib/libarchive/archive_write_set_compression_none.c +++ b/lib/libarchive/archive_write_set_compression_none.c @@ -24,10 +24,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -119,7 +119,7 @@ archive_compressor_none_write(struct archive *a, const void *vbuff, state = a->compression_data; buff = vbuff; if (a->client_writer == NULL) { - archive_set_error(a, EDOOFUS, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No write callback is registered? " "This is probably an internal programming error."); return (ARCHIVE_FATAL); @@ -167,7 +167,7 @@ archive_compressor_none_finish(struct archive *a) state = a->compression_data; ret = ret2 = ARCHIVE_OK; if (a->client_writer == NULL) { - archive_set_error(a, EDOOFUS, + archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, "No write callback is registered? " "This is probably an internal programming error."); return (ARCHIVE_FATAL); diff --git a/lib/libarchive/archive_write_set_format.c b/lib/libarchive/archive_write_set_format.c index 711699cd91c3..5f6df0ef8451 100644 --- a/lib/libarchive/archive_write_set_format.c +++ b/lib/libarchive/archive_write_set_format.c @@ -24,9 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); +#include + +#include #include "archive.h" #include "archive_private.h" @@ -57,6 +60,6 @@ archive_write_set_format(struct archive *a, int code) return ((codes[i].setter)(a)); } - archive_set_error(a, -1, "No such format"); + archive_set_error(a, EINVAL, "No such format"); return (ARCHIVE_FATAL); } diff --git a/lib/libarchive/archive_write_set_format_by_name.c b/lib/libarchive/archive_write_set_format_by_name.c index e313a982938a..b67dab5c16f3 100644 --- a/lib/libarchive/archive_write_set_format_by_name.c +++ b/lib/libarchive/archive_write_set_format_by_name.c @@ -24,9 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); +#include + +#include #include #include "archive.h" @@ -54,6 +57,6 @@ archive_write_set_format_by_name(struct archive *a, const char *name) return ((names[i].setter)(a)); } - archive_set_error(a, -1, "No such format '%s'", name); + archive_set_error(a, EINVAL, "No such format '%s'", name); return (ARCHIVE_FATAL); } diff --git a/lib/libarchive/archive_write_set_format_cpio.c b/lib/libarchive/archive_write_set_format_cpio.c index f0df03ef1def..be7b4c96e2bf 100644 --- a/lib/libarchive/archive_write_set_format_cpio.c +++ b/lib/libarchive/archive_write_set_format_cpio.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include diff --git a/lib/libarchive/archive_write_set_format_pax.c b/lib/libarchive/archive_write_set_format_pax.c index 9b3d78190f4d..8c5342ecd658 100644 --- a/lib/libarchive/archive_write_set_format_pax.c +++ b/lib/libarchive/archive_write_set_format_pax.c @@ -24,12 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -270,11 +270,11 @@ archive_write_pax_header(struct archive *a, case S_IFIFO: break; case S_IFSOCK: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, "tar format cannot archive socket"); return (ARCHIVE_WARN); default: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, "tar format cannot archive this"); return (ARCHIVE_WARN); } @@ -294,15 +294,12 @@ archive_write_pax_header(struct archive *a, p = archive_entry_pathname(entry_main); if (strlen(p) <= 100) /* Short enough for just 'name' field */ name_start = p; /* Record a zero-length prefix */ - else { + else /* Find the largest suffix that fits in 'name' field. */ name_start = strchr(p + strlen(p) - 100 - 1, '/'); - if (name_start == NULL) /* No feasible break point. */ - name_start = p + strlen(p); - } /* If name is too long, add 'path' to pax extended attrs. */ - if (name_start - p > 155) { + if (name_start == NULL || name_start - p > 155) { add_pax_attr(&(pax->pax_header), "path", p); archive_entry_set_pathname(entry_main, build_ustar_entry_name(ustar_entry_name, p)); @@ -599,7 +596,10 @@ build_ustar_entry_name(char *dest, const char *src) } } - strlcpy(dest, prefix, basename - prefix + 1 + basename_length); + /* The OpenBSD strlcpy function is safer, but less portable. */ + /* Rather than maintain two versions, just use the strncpy version. */ + strncpy(dest, prefix, basename - prefix + basename_length); + dest[basename - prefix + basename_length] = '\0'; return (dest); } diff --git a/lib/libarchive/archive_write_set_format_shar.c b/lib/libarchive/archive_write_set_format_shar.c index 676f997b645a..42042c40f24e 100644 --- a/lib/libarchive/archive_write_set_format_shar.c +++ b/lib/libarchive/archive_write_set_format_shar.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -165,7 +165,7 @@ archive_write_shar_header(struct archive *a, struct archive_entry *entry) archive_entry_set_size(entry, 0); if (archive_entry_hardlink(entry) == NULL && archive_entry_symlink(entry) == NULL) { - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_MISC, "shar format cannot archive this"); return (ARCHIVE_WARN); } diff --git a/lib/libarchive/archive_write_set_format_ustar.c b/lib/libarchive/archive_write_set_format_ustar.c index 649be5efc43f..5e294786946b 100644 --- a/lib/libarchive/archive_write_set_format_ustar.c +++ b/lib/libarchive/archive_write_set_format_ustar.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "archive_platform.h" __FBSDID("$FreeBSD$"); #include -#ifdef DMALLOC +#ifdef HAVE_DMALLOC #include #endif #include @@ -183,10 +183,12 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512], * remaining name are too large, return an error. */ if (!p) { - archive_set_error(a, -1, "Pathname too long"); + archive_set_error(a, ENAMETOOLONG, + "Pathname too long"); ret = ARCHIVE_WARN; } else if (p > pp + sizeof(h->prefix)) { - archive_set_error(a, -1, "Pathname too long"); + archive_set_error(a, ENAMETOOLONG, + "Pathname too long"); ret = ARCHIVE_WARN; } else { /* Copy prefix and remainder to appropriate places */ @@ -200,7 +202,8 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512], p = archive_entry_symlink(entry); if (p != NULL && p[0] != '\0') { if (strlen(p) > sizeof(h->linkname)) { - archive_set_error(a, -1, "Link contents too long"); + archive_set_error(a, ENAMETOOLONG, + "Link contents too long"); ret = ARCHIVE_WARN; } else memcpy(h->linkname, p, strlen(p)); @@ -209,7 +212,8 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512], p = archive_entry_uname(entry); if (p != NULL && p[0] != '\0') { if (strlen(p) > sizeof(h->uname)) { - archive_set_error(a, -1, "Username too long"); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Username too long"); ret = ARCHIVE_WARN; } else memcpy(h->uname, p, strlen(p)); @@ -218,7 +222,8 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512], p = archive_entry_gname(entry); if (p != NULL && p[0] != '\0') { if (strlen(p) > sizeof(h->gname)) { - archive_set_error(a, -1, "Group name too long"); + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Group name too long"); ret = ARCHIVE_WARN; } else memcpy(h->gname, p, strlen(p)); @@ -291,12 +296,12 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512], case S_IFDIR: h->typeflag[0] = '5' ; break; case S_IFIFO: h->typeflag[0] = '6' ; break; case S_IFSOCK: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, "tar format cannot archive socket"); ret = ARCHIVE_WARN; break; default: - archive_set_error(a, -1, + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, "tar format cannot archive this"); ret = ARCHIVE_WARN; }