From 313ffdebd6db09c10d753db314291d8a77a63fc5 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 13 Jul 2007 06:59:51 +0000 Subject: [PATCH] Synchronous libarchive to 2.2.4 from FreeBSD, including fixes related to FreeBSD Security Advisory FreeBSD-SA-07:05.libarchive. --- contrib/libarchive-2/libarchive/archive.h.in | 70 +- .../libarchive-2/libarchive/archive_entry.3 | 2 +- .../libarchive-2/libarchive/archive_entry.c | 2 +- .../libarchive-2/libarchive/archive_entry.h | 2 +- .../libarchive/archive_entry_copy_stat.c | 2 +- .../libarchive/archive_entry_private.h | 2 +- .../libarchive/archive_entry_stat.c | 2 +- .../libarchive/archive_platform.h | 2 +- .../libarchive-2/libarchive/archive_read.3 | 2 +- .../libarchive-2/libarchive/archive_read.c | 2 +- .../libarchive/archive_read_extract.c | 2 +- .../libarchive/archive_read_open_fd.c | 26 +- .../libarchive/archive_read_open_file.c | 28 +- .../libarchive/archive_read_open_filename.c | 27 +- .../libarchive/archive_read_open_memory.c | 4 +- .../libarchive/archive_read_private.h | 2 +- .../archive_read_support_compression_bzip2.c | 2 +- ...rchive_read_support_compression_compress.c | 2 +- .../archive_read_support_compression_gzip.c | 2 +- .../archive_read_support_compression_none.c | 2 +- ...archive_read_support_compression_program.c | 2 +- .../archive_read_support_format_ar.c | 2 +- .../archive_read_support_format_cpio.c | 2 +- .../archive_read_support_format_empty.c | 2 +- .../archive_read_support_format_iso9660.c | 2 +- .../archive_read_support_format_tar.c | 634 ++++++++++++++---- .../archive_read_support_format_zip.c | 2 +- .../libarchive-2/libarchive/archive_string.c | 2 +- .../libarchive-2/libarchive/archive_string.h | 2 +- .../libarchive-2/libarchive/archive_util.3 | 2 +- .../libarchive-2/libarchive/archive_util.c | 8 +- .../libarchive-2/libarchive/archive_write.3 | 2 +- .../libarchive-2/libarchive/archive_write.c | 2 +- .../libarchive/archive_write_disk.c | 2 +- .../archive_write_disk_set_standard_lookup.c | 2 +- .../libarchive/archive_write_private.h | 2 +- .../archive_write_set_compression_bzip2.c | 2 +- .../archive_write_set_compression_gzip.c | 2 +- .../archive_write_set_compression_none.c | 2 +- .../archive_write_set_compression_program.c | 2 +- .../libarchive/archive_write_set_format.c | 3 +- .../libarchive/archive_write_set_format_ar.c | 2 +- .../archive_write_set_format_by_name.c | 4 +- .../archive_write_set_format_cpio.c | 2 +- ...c => archive_write_set_format_cpio_newc.c} | 141 ++-- .../libarchive/archive_write_set_format_pax.c | 2 +- .../archive_write_set_format_shar.c | 2 +- .../archive_write_set_format_ustar.c | 13 +- contrib/libarchive-2/libarchive/filter_fork.c | 2 +- contrib/libarchive-2/libarchive/filter_fork.h | 2 + .../libarchive/libarchive_internals.3 | 2 +- contrib/libarchive-2/tar/bsdtar.1 | 8 +- 52 files changed, 787 insertions(+), 259 deletions(-) copy contrib/libarchive-2/libarchive/{archive_write_set_format_cpio.c => archive_write_set_format_cpio_newc.c} (56%) diff --git a/contrib/libarchive-2/libarchive/archive.h.in b/contrib/libarchive-2/libarchive/archive.h.in index 7a085d0a44..843276f72d 100644 --- a/contrib/libarchive-2/libarchive/archive.h.in +++ b/contrib/libarchive-2/libarchive/archive.h.in @@ -22,7 +22,7 @@ * (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: src/lib/libarchive/archive.h.in,v 1.43 2007/05/02 05:29:55 cperciva Exp $ + * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.46 2007/07/06 15:36:37 kientzle Exp $ */ #ifndef ARCHIVE_H_INCLUDED @@ -50,31 +50,68 @@ typedef unsigned short mode_t; extern "C" { #endif +/* + * Each of the version identifiers comes as a macro and a function. + * The macro identifies the installed header; the function identifies + * the library version (which may not be the same if you're using a + * dynamically-linked version of the library). + */ /* - * If ARCHIVE_API_VERSION != archive_api_version(), then the library you - * were linked with is using an incompatible API to the one you were - * compiled with. This is almost certainly a fatal problem. - * - * ARCHIVE_API_FEATURE is incremented with each significant feature - * addition, so you can test (at compile or run time) if a particular - * feature is implemented. It's no big deal if ARCHIVE_API_FEATURE != - * archive_api_feature(), as long as both are high enough to include - * the features you're relying on. Specific values of FEATURE are - * documented here: + * Textual name/version of the library, useful for version displays. + */ +#define ARCHIVE_LIBRARY_VERSION "libarchive @ARCHIVE_VERSION@" +const char * archive_version(void); + +/* + * Major version number: If ARCHIVE_API_VERSION != + * archive_api_version(), then the library you were linked with is + * using an incompatible API to the one you were compiled with. This + * is almost certainly a fatal problem. + */ +#define ARCHIVE_API_VERSION @ARCHIVE_API_MAJOR@ +int archive_api_version(void); + +/* + * Minor version number: ARCHIVE_API_FEATURE is incremented with each + * significant feature addition, so you can test (at compile or run + * time) if a particular feature is implemented. It's no big deal if + * ARCHIVE_API_FEATURE != archive_api_feature(), as long as both are + * high enough to include the features you're relying on. Specific + * values of FEATURE are documented here: * * 1 - Version tests are available. * 2 - archive_{read,write}_close available separately from _finish. * 3 - open_memory, open_memory2, open_FILE, open_fd available * 5 - archive_write_disk interface available + * + * Unfortunately, this count resets whenever ARCHIVE_API_VERSION changes, + * making it awkward to use in practice. For that reason, it is deprecated + * in favor of the more-accurate version stamp below. It will eventually + * be removed. */ -#define ARCHIVE_API_VERSION @ARCHIVE_API_MAJOR@ -int archive_api_version(void); #define ARCHIVE_API_FEATURE @ARCHIVE_API_MINOR@ int archive_api_feature(void); -/* Textual name/version of the library. */ -#define ARCHIVE_LIBRARY_VERSION "libarchive @ARCHIVE_VERSION@" -const char * archive_version(void); + +/* + * The "version stamp" is a single integer that makes it easy to check + * the exact version: for version a.b.c, the version stamp is + * printf("%d%03d%03d",a,b,c). For example, version 2.12.108 has + * version stamp 2012108. + * + * This was introduced with libarchive 1.9.0 in the libarchive 1.x family + * and libarchive 2.2.4 in the libarchive 2.x family. The following + * may be useful if you really want to do feature detection for earlier + * libarchive versions: + * + * #ifndef ARCHIVE_VERSION_STAMP + * #define ARCHIVE_VERSION_STAMP \ + * (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000) + * #endif + */ +#define ARCHIVE_VERSION_STAMP @ARCHIVE_VERSION_STAMP@ +int archive_version_stamp(void); + #define ARCHIVE_BYTES_PER_RECORD 512 #define ARCHIVE_DEFAULT_BYTES_PER_BLOCK 10240 @@ -390,6 +427,7 @@ int archive_write_set_format_by_name(struct archive *, int archive_write_set_format_ar_bsd(struct archive *); int archive_write_set_format_ar_svr4(struct archive *); int archive_write_set_format_cpio(struct archive *); +int archive_write_set_format_cpio_newc(struct archive *); /* TODO: int archive_write_set_format_old_tar(struct archive *); */ int archive_write_set_format_pax(struct archive *); int archive_write_set_format_pax_restricted(struct archive *); diff --git a/contrib/libarchive-2/libarchive/archive_entry.3 b/contrib/libarchive-2/libarchive/archive_entry.3 index ff6066fe78..11b9356264 100644 --- a/contrib/libarchive-2/libarchive/archive_entry.3 +++ b/contrib/libarchive-2/libarchive/archive_entry.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.13 2007/03/03 07:37:36 kientzle Exp $ +.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.14 2007/05/29 01:00:18 kientzle Exp $ .\" .Dd December 15, 2003 .Dt archive_entry 3 diff --git a/contrib/libarchive-2/libarchive/archive_entry.c b/contrib/libarchive-2/libarchive/archive_entry.c index 908987d420..6772d7f01f 100644 --- a/contrib/libarchive-2/libarchive/archive_entry.c +++ b/contrib/libarchive-2/libarchive/archive_entry.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry.c,v 1.42 2007/04/14 02:37:22 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry.c,v 1.43 2007/05/29 01:00:18 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include diff --git a/contrib/libarchive-2/libarchive/archive_entry.h b/contrib/libarchive-2/libarchive/archive_entry.h index 3c42f16fad..6946751538 100644 --- a/contrib/libarchive-2/libarchive/archive_entry.h +++ b/contrib/libarchive-2/libarchive/archive_entry.h @@ -22,7 +22,7 @@ * (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: src/lib/libarchive/archive_entry.h,v 1.21 2007/03/01 06:22:34 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_entry.h,v 1.22 2007/05/29 01:00:18 kientzle Exp $ */ #ifndef ARCHIVE_ENTRY_H_INCLUDED diff --git a/contrib/libarchive-2/libarchive/archive_entry_copy_stat.c b/contrib/libarchive-2/libarchive/archive_entry_copy_stat.c index 5b3d35e2aa..514db02743 100644 --- a/contrib/libarchive-2/libarchive/archive_entry_copy_stat.c +++ b/contrib/libarchive-2/libarchive/archive_entry_copy_stat.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_copy_stat.c,v 1.1 2007/05/29 01:00:18 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include diff --git a/contrib/libarchive-2/libarchive/archive_entry_private.h b/contrib/libarchive-2/libarchive/archive_entry_private.h index 34b8e26663..234ba47e84 100644 --- a/contrib/libarchive-2/libarchive/archive_entry_private.h +++ b/contrib/libarchive-2/libarchive/archive_entry_private.h @@ -22,7 +22,7 @@ * (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$ + * $FreeBSD: src/lib/libarchive/archive_entry_private.h,v 1.1 2007/05/29 01:00:18 kientzle Exp $ */ #ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED diff --git a/contrib/libarchive-2/libarchive/archive_entry_stat.c b/contrib/libarchive-2/libarchive/archive_entry_stat.c index d06ee2c81d..6ef5b37287 100644 --- a/contrib/libarchive-2/libarchive/archive_entry_stat.c +++ b/contrib/libarchive-2/libarchive/archive_entry_stat.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_stat.c,v 1.1 2007/05/29 01:00:18 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include diff --git a/contrib/libarchive-2/libarchive/archive_platform.h b/contrib/libarchive-2/libarchive/archive_platform.h index b6815f5179..0f8a170166 100644 --- a/contrib/libarchive-2/libarchive/archive_platform.h +++ b/contrib/libarchive-2/libarchive/archive_platform.h @@ -22,7 +22,7 @@ * (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: src/lib/libarchive/archive_platform.h,v 1.26 2007/04/15 00:53:38 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.27 2007/05/29 01:00:18 kientzle Exp $ */ /* diff --git a/contrib/libarchive-2/libarchive/archive_read.3 b/contrib/libarchive-2/libarchive/archive_read.3 index e6955da6b0..9e4f878dc1 100644 --- a/contrib/libarchive-2/libarchive/archive_read.3 +++ b/contrib/libarchive-2/libarchive/archive_read.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libarchive/archive_read.3,v 1.33 2007/04/07 05:53:11 kientzle Exp $ +.\" $FreeBSD: src/lib/libarchive/archive_read.3,v 1.34 2007/05/29 01:00:18 kientzle Exp $ .\" .Dd August 19, 2006 .Dt archive_read 3 diff --git a/contrib/libarchive-2/libarchive/archive_read.c b/contrib/libarchive-2/libarchive/archive_read.c index 9eab499890..5433097120 100644 --- a/contrib/libarchive-2/libarchive/archive_read.c +++ b/contrib/libarchive-2/libarchive/archive_read.c @@ -32,7 +32,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read.c,v 1.34 2007/04/05 15:51:19 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read.c,v 1.35 2007/05/29 01:00:18 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_extract.c b/contrib/libarchive-2/libarchive/archive_read_extract.c index a317ca916f..423ff7dd3c 100644 --- a/contrib/libarchive-2/libarchive/archive_read_extract.c +++ b/contrib/libarchive-2/libarchive/archive_read_extract.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.58 2007/04/16 04:04:49 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.59 2007/05/29 01:00:18 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_open_fd.c b/contrib/libarchive-2/libarchive/archive_read_open_fd.c index 4db681c3a2..2ebd46d6cd 100644 --- a/contrib/libarchive-2/libarchive/archive_read_open_fd.c +++ b/contrib/libarchive-2/libarchive/archive_read_open_fd.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_fd.c,v 1.11 2007/01/09 08:05:55 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_fd.c,v 1.13 2007/06/26 03:06:48 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_fd.c,v 1.11 2007/01/09 struct read_fd_data { int fd; size_t block_size; + char can_skip; void *buffer; }; @@ -77,6 +78,8 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size) return (ARCHIVE_FATAL); } mine->fd = fd; + /* lseek() hardly ever works, so disable it by default. See below. */ + mine->can_skip = 0; return (archive_read_open2(a, mine, file_open, file_read, file_skip, file_close)); } @@ -91,8 +94,18 @@ file_open(struct archive *a, void *client_data) return (ARCHIVE_FATAL); } - if (S_ISREG(st.st_mode)) + if (S_ISREG(st.st_mode)) { archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); + /* + * Enabling skip here is a performance optimization for + * anything that supports lseek(). On FreeBSD, only + * regular files and raw disk devices support lseek() and + * there's no portable way to determine if a device is + * a raw disk device, so we only enable this optimization + * for regular files. + */ + mine->can_skip = 1; + } return (ARCHIVE_OK); } @@ -121,8 +134,14 @@ file_skip(struct archive *a, void *client_data, off_t request) struct read_fd_data *mine = (struct read_fd_data *)client_data; off_t old_offset, new_offset; + if (!mine->can_skip) + return (0); + /* Reduce request to the next smallest multiple of block_size */ request = (request / mine->block_size) * mine->block_size; + if (request == 0) + return (0); + /* * Hurray for lazy evaluation: if the first lseek fails, the second * one will not be executed. @@ -130,6 +149,9 @@ file_skip(struct archive *a, void *client_data, off_t request) if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) < 0) || ((new_offset = lseek(mine->fd, request, SEEK_CUR)) < 0)) { + /* If seek failed once, it will probably fail again. */ + mine->can_skip = 0; + if (errno == ESPIPE) { /* diff --git a/contrib/libarchive-2/libarchive/archive_read_open_file.c b/contrib/libarchive-2/libarchive/archive_read_open_file.c index 6d83955163..55c431c7da 100644 --- a/contrib/libarchive-2/libarchive/archive_read_open_file.c +++ b/contrib/libarchive-2/libarchive/archive_read_open_file.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_file.c,v 1.19 2007/01/09 08:05:55 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_file.c,v 1.20 2007/06/26 03:06:48 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include @@ -51,6 +51,7 @@ struct read_FILE_data { FILE *f; size_t block_size; void *buffer; + char can_skip; }; static int file_close(struct archive *, void *); @@ -80,6 +81,8 @@ archive_read_open_FILE(struct archive *a, FILE *f) return (ARCHIVE_FATAL); } mine->f = f; + /* Suppress skip by default. See below. */ + mine->can_skip = 0; return (archive_read_open2(a, mine, file_open, file_read, file_skip, file_close)); } @@ -95,8 +98,11 @@ file_open(struct archive *a, void *client_data) * it's not a file. (FILE * objects can wrap many kinds * of I/O streams.) */ - if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) + if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) { archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); + /* Enable the seek optimization for regular files. */ + mine->can_skip = 1; + } return (ARCHIVE_OK); } @@ -125,21 +131,25 @@ file_skip(struct archive *a, void *client_data, off_t request) { struct read_FILE_data *mine = (struct read_FILE_data *)client_data; + (void)a; /* UNUSED */ + /* - * Note: the 'fd' and 'filename' versions round the request - * down to a multiple of the block size to ensure proper - * operation on block-oriented media such as tapes. But stdio - * doesn't work with such media (it doesn't ensure blocking), - * so we don't need to bother. + * If we can't skip, return 0 as the amount we did step and + * the caller will work around by reading and discarding. */ + if (!mine->can_skip) + return (0); + if (request == 0) + return (0); + #if HAVE_FSEEKO if (fseeko(mine->f, request, SEEK_CUR) != 0) #else if (fseek(mine->f, request, SEEK_CUR) != 0) #endif { - archive_set_error(a, errno, "Error skipping forward"); - return (ARCHIVE_FATAL); + mine->can_skip = 0; + return (0); } return (request); } diff --git a/contrib/libarchive-2/libarchive/archive_read_open_filename.c b/contrib/libarchive-2/libarchive/archive_read_open_filename.c index 47bc4efaa5..02e7902f3a 100644 --- a/contrib/libarchive-2/libarchive/archive_read_open_filename.c +++ b/contrib/libarchive-2/libarchive/archive_read_open_filename.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_filename.c,v 1.18 2007/01/09 08:05:55 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_filename.c,v 1.20 2007/06/26 03:06:48 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include @@ -52,6 +52,7 @@ struct read_file_data { size_t block_size; void *buffer; mode_t st_mode; /* Mode bits for opened file. */ + char can_skip; /* This file supports skipping. */ char filename[1]; /* Must be last! */ }; @@ -95,6 +96,8 @@ archive_read_open_filename(struct archive *a, const char *filename, mine->block_size = block_size; mine->buffer = NULL; mine->fd = -1; + /* lseek() almost never works; disable it by default. See below. */ + mine->can_skip = 0; return (archive_read_open2(a, mine, file_open, file_read, file_skip, file_close)); } @@ -121,8 +124,19 @@ file_open(struct archive *a, void *client_data) if (fstat(mine->fd, &st) == 0) { /* If we're reading a file from disk, ensure that we don't overwrite it with an extracted file. */ - if (S_ISREG(st.st_mode)) + if (S_ISREG(st.st_mode)) { archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); + /* + * Enabling skip here is a performance + * optimization for anything that supports + * lseek(). On FreeBSD, only regular files + * and raw disk devices support lseek() and + * there's no portable way to determine if a + * device is a raw disk device, so we only + * enable this optimization for regular files. + */ + mine->can_skip = 1; + } /* Remember mode so close can decide whether to flush. */ mine->st_mode = st.st_mode; } else { @@ -165,8 +179,14 @@ file_skip(struct archive *a, void *client_data, off_t request) struct read_file_data *mine = (struct read_file_data *)client_data; off_t old_offset, new_offset; + if (!mine->can_skip) /* We can't skip, so ... */ + return (0); /* ... skip zero bytes. */ + /* Reduce request to the next smallest multiple of block_size */ request = (request / mine->block_size) * mine->block_size; + if (request == 0) + return (0); + /* * Hurray for lazy evaluation: if the first lseek fails, the second * one will not be executed. @@ -174,6 +194,9 @@ file_skip(struct archive *a, void *client_data, off_t request) if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) < 0) || ((new_offset = lseek(mine->fd, request, SEEK_CUR)) < 0)) { + /* If skip failed once, it will probably fail again. */ + mine->can_skip = 0; + if (errno == ESPIPE) { /* diff --git a/contrib/libarchive-2/libarchive/archive_read_open_memory.c b/contrib/libarchive-2/libarchive/archive_read_open_memory.c index 3fc8522bc7..61f574fa77 100644 --- a/contrib/libarchive-2/libarchive/archive_read_open_memory.c +++ b/contrib/libarchive-2/libarchive/archive_read_open_memory.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.4 2007/04/02 00:25:11 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $"); #include #include @@ -134,7 +134,7 @@ memory_read_skip(struct archive *a, void *client_data, off_t skip) struct read_memory_data *mine = (struct read_memory_data *)client_data; (void)a; /* UNUSED */ - if (skip > mine->end - mine->buffer) + if ((off_t)skip > (off_t)(mine->end - mine->buffer)) skip = mine->end - mine->buffer; /* Round down to block size. */ skip /= mine->read_size; diff --git a/contrib/libarchive-2/libarchive/archive_read_private.h b/contrib/libarchive-2/libarchive/archive_read_private.h index d8cfa75386..f0f5202113 100644 --- a/contrib/libarchive-2/libarchive/archive_read_private.h +++ b/contrib/libarchive-2/libarchive/archive_read_private.h @@ -22,7 +22,7 @@ * (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: src/lib/libarchive/archive_read_private.h,v 1.2 2007/04/02 00:11:54 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_read_private.h,v 1.3 2007/05/29 01:00:18 kientzle Exp $ */ #ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED diff --git a/contrib/libarchive-2/libarchive/archive_read_support_compression_bzip2.c b/contrib/libarchive-2/libarchive/archive_read_support_compression_bzip2.c index c92494020a..aa664d10b1 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_compression_bzip2.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_compression_bzip2.c @@ -25,7 +25,7 @@ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_bzip2.c,v 1.15 2007/04/05 05:18:16 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_bzip2.c,v 1.16 2007/05/29 01:00:18 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_compression_compress.c b/contrib/libarchive-2/libarchive/archive_read_support_compression_compress.c index cb434105b4..050099b210 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_compression_compress.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_compression_compress.c @@ -64,7 +64,7 @@ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_compress.c,v 1.9 2007/04/05 05:18:16 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_compress.c,v 1.10 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_compression_gzip.c b/contrib/libarchive-2/libarchive/archive_read_support_compression_gzip.c index b2e0d8bd95..89784b8dfc 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_compression_gzip.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_compression_gzip.c @@ -25,7 +25,7 @@ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_gzip.c,v 1.14 2007/04/05 05:18:16 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_gzip.c,v 1.15 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H diff --git a/contrib/libarchive-2/libarchive/archive_read_support_compression_none.c b/contrib/libarchive-2/libarchive/archive_read_support_compression_none.c index e976398bb8..58a5559167 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_compression_none.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_compression_none.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_none.c,v 1.16 2007/04/05 05:18:16 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_none.c,v 1.17 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_compression_program.c b/contrib/libarchive-2/libarchive/archive_read_support_compression_program.c index d40679769f..6815a3bd8b 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_compression_program.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_compression_program.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_program.c,v 1.1 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_SYS_WAIT_H # include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_format_ar.c b/contrib/libarchive-2/libarchive/archive_read_support_format_ar.c index 4ffc1cd80a..97ed28af1f 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_format_ar.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_format_ar.c @@ -26,7 +26,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_ar.c,v 1.5 2007/04/15 00:53:38 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_ar.c,v 1.6 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_format_cpio.c b/contrib/libarchive-2/libarchive/archive_read_support_format_cpio.c index d816e9ed9f..7a056b9f43 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_format_cpio.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_format_cpio.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_cpio.c,v 1.23 2007/04/13 16:07:25 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_cpio.c,v 1.24 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_format_empty.c b/contrib/libarchive-2/libarchive/archive_read_support_format_empty.c index f664b874d0..837fdef997 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_format_empty.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_format_empty.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_empty.c,v 1.2 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_empty.c,v 1.3 2007/05/29 01:00:19 kientzle Exp $"); #include "archive.h" #include "archive_entry.h" diff --git a/contrib/libarchive-2/libarchive/archive_read_support_format_iso9660.c b/contrib/libarchive-2/libarchive/archive_read_support_format_iso9660.c index fbc4c89d92..d77bd871c0 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_format_iso9660.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_format_iso9660.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_iso9660.c,v 1.22 2007/04/02 00:29:52 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_iso9660.c,v 1.23 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_read_support_format_tar.c b/contrib/libarchive-2/libarchive/archive_read_support_format_tar.c index 14c5535f6b..f01015cf5d 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_format_tar.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_format_tar.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.55 2007/05/21 04:45:24 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.58 2007/07/12 15:00:28 cperciva Exp $"); #ifdef HAVE_ERRNO_H #include @@ -150,22 +150,34 @@ struct tar { struct archive_string longname; struct archive_string pax_header; struct archive_string pax_global; + struct archive_string line; wchar_t *pax_entry; size_t pax_entry_length; int header_recursion_depth; off_t entry_bytes_remaining; off_t entry_offset; off_t entry_padding; + off_t realsize; struct sparse_block *sparse_list; + struct sparse_block *sparse_last; + int64_t sparse_offset; + int64_t sparse_numbytes; + int sparse_gnu_major; + int sparse_gnu_minor; + char sparse_gnu_pending; }; static size_t UTF8_mbrtowc(wchar_t *pwc, const char *s, size_t n); static int archive_block_is_null(const unsigned char *p); static char *base64_decode(const wchar_t *, size_t, size_t *); -static int gnu_read_sparse_data(struct archive_read *, struct tar *, +static void gnu_add_sparse_entry(struct tar *, + off_t offset, off_t remaining); +static int gnu_sparse_old_read(struct archive_read *, struct tar *, const struct archive_entry_header_gnutar *header); -static void gnu_parse_sparse_data(struct archive_read *, struct tar *, +static void gnu_sparse_old_parse(struct tar *, const struct gnu_sparse *sparse, int length); +static int gnu_sparse_01_parse(struct tar *, const wchar_t *); +static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *); static int header_Solaris_ACL(struct archive_read *, struct tar *, struct archive_entry *, const void *); static int header_common(struct archive_read *, struct tar *, @@ -194,11 +206,12 @@ static int archive_read_format_tar_skip(struct archive_read *a); static int archive_read_format_tar_read_header(struct archive_read *, struct archive_entry *); static int checksum(struct archive_read *, const void *); -static int pax_attribute(struct archive_entry *, +static int pax_attribute(struct tar *, struct archive_entry *, wchar_t *key, wchar_t *value); static int pax_header(struct archive_read *, struct tar *, struct archive_entry *, char *attr); static void pax_time(const wchar_t *, int64_t *sec, long *nanos); +static ssize_t readline(struct archive_read *, struct tar *, const char **); static int read_body_to_string(struct archive_read *, struct tar *, struct archive_string *, const void *h); static int64_t tar_atol(const char *, unsigned); @@ -250,17 +263,23 @@ static int archive_read_format_tar_cleanup(struct archive_read *a) { struct tar *tar; + struct sparse_block *p; tar = (struct tar *)(a->format->data); + while (tar->sparse_list != NULL) { + p = tar->sparse_list; + tar->sparse_list = p->next; + free(p); + } archive_string_free(&tar->acl_text); archive_string_free(&tar->entry_name); archive_string_free(&tar->entry_linkname); archive_string_free(&tar->entry_uname); archive_string_free(&tar->entry_gname); + archive_string_free(&tar->line); archive_string_free(&tar->pax_global); archive_string_free(&tar->pax_header); - if (tar->pax_entry != NULL) - free(tar->pax_entry); + free(tar->pax_entry); free(tar); (a->format->data) = NULL; return (ARCHIVE_OK); @@ -400,9 +419,11 @@ archive_read_format_tar_read_header(struct archive_read *a, static int default_inode; static int default_dev; struct tar *tar; + struct sparse_block *sp; const char *p; int r; size_t l; + ssize_t size; /* Assign default device/inode values. */ archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */ @@ -415,9 +436,40 @@ archive_read_format_tar_read_header(struct archive_read *a, tar = (struct tar *)(a->format->data); tar->entry_offset = 0; + while (tar->sparse_list != NULL) { + sp = tar->sparse_list; + tar->sparse_list = sp->next; + free(sp); + } + tar->sparse_last = NULL; r = tar_read_header(a, tar, entry); + /* + * Yuck. See comments for gnu_sparse_10_read for why this + * is here and not in _read_data where it "should" go. + */ + if (tar->sparse_gnu_pending + && tar->sparse_gnu_major == 1 + && tar->sparse_gnu_minor == 0) { + tar->sparse_gnu_pending = 0; + /* Read initial sparse map. */ + size = gnu_sparse_10_read(a, tar); + if (size < 0) + return (size); + tar->entry_bytes_remaining -= size; + tar->entry_padding += size; + } + + /* + * "non-sparse" files are really just sparse files with + * a single block. + */ + if (tar->sparse_list == NULL) + gnu_add_sparse_entry(tar, 0, tar->entry_bytes_remaining); + + tar->realsize = archive_entry_size(entry); + if (r == ARCHIVE_OK) { /* * "Regular" entry with trailing '/' is really @@ -442,55 +494,64 @@ archive_read_format_tar_read_data(struct archive_read *a, struct sparse_block *p; tar = (struct tar *)(a->format->data); - if (tar->sparse_list != NULL) { - /* Remove exhausted entries from sparse list. */ - while (tar->sparse_list != NULL && - tar->sparse_list->remaining == 0) { - p = tar->sparse_list; - tar->sparse_list = p->next; - free(p); - } - if (tar->sparse_list == NULL) { - /* We exhausted the entire sparse list. */ - tar->entry_bytes_remaining = 0; - } - } - if (tar->entry_bytes_remaining > 0) { - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); - if (bytes_read == 0) { + if (tar->sparse_gnu_pending) { + if (tar->sparse_gnu_major == 1 && tar->sparse_gnu_minor == 0) { + /* + * We should parse the sparse data + * here, but have to parse it as part of the + * header because of a bug in GNU tar 1.16.1. + */ + } else { + *size = 0; + *offset = 0; archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated tar archive"); - return (ARCHIVE_FATAL); - } - if (bytes_read < 0) - return (ARCHIVE_FATAL); - if (bytes_read > tar->entry_bytes_remaining) - bytes_read = tar->entry_bytes_remaining; - if (tar->sparse_list != NULL) { - /* Don't read more than is available in the - * current sparse block. */ - if (tar->sparse_list->remaining < bytes_read) - bytes_read = tar->sparse_list->remaining; - tar->entry_offset = tar->sparse_list->offset; - tar->sparse_list->remaining -= bytes_read; - tar->sparse_list->offset += bytes_read; + "Unrecognized GNU sparse file format"); + return (ARCHIVE_WARN); } - *size = bytes_read; - *offset = tar->entry_offset; - tar->entry_offset += bytes_read; - tar->entry_bytes_remaining -= bytes_read; - (a->decompressor->consume)(a, bytes_read); - return (ARCHIVE_OK); - } else { + tar->sparse_gnu_pending = 0; + } + + /* Remove exhausted entries from sparse list. */ + while (tar->sparse_list != NULL && + tar->sparse_list->remaining == 0) { + p = tar->sparse_list; + tar->sparse_list = p->next; + free(p); + } + + /* If we're at end of file, return EOF. */ + if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) { if ((a->decompressor->skip)(a, tar->entry_padding) < 0) return (ARCHIVE_FATAL); tar->entry_padding = 0; *buff = NULL; *size = 0; - *offset = tar->entry_offset; + *offset = tar->realsize; return (ARCHIVE_EOF); } + + bytes_read = (a->decompressor->read_ahead)(a, buff, 1); + if (bytes_read == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Truncated tar archive"); + return (ARCHIVE_FATAL); + } + if (bytes_read < 0) + return (ARCHIVE_FATAL); + if (bytes_read > tar->entry_bytes_remaining) + bytes_read = tar->entry_bytes_remaining; + /* Don't read more than is available in the + * current sparse block. */ + if (tar->sparse_list->remaining < bytes_read) + bytes_read = tar->sparse_list->remaining; + *size = bytes_read; + *offset = tar->sparse_list->offset; + tar->sparse_list->remaining -= bytes_read; + tar->sparse_list->offset += bytes_read; + tar->entry_bytes_remaining -= bytes_read; + (a->decompressor->consume)(a, bytes_read); + return (ARCHIVE_OK); } static int @@ -521,6 +582,7 @@ archive_read_format_tar_skip(struct archive_read *a) tar->sparse_list = p->next; free(p); } + tar->sparse_last = NULL; return (ARCHIVE_OK); } @@ -628,7 +690,13 @@ tar_read_header(struct archive_read *a, struct tar *tar, } } --tar->header_recursion_depth; - return (err); + /* We return warnings or success as-is. Anything else is fatal. */ + if (err == ARCHIVE_WARN || err == ARCHIVE_OK) + return (err); + if (err == ARCHIVE_EOF) + /* EOF when recursively reading a header is bad. */ + archive_set_error(&a->archive, EINVAL, "Damaged tar archive"); + return (ARCHIVE_FATAL); } /* @@ -699,32 +767,55 @@ static int header_Solaris_ACL(struct archive_read *a, struct tar *tar, struct archive_entry *entry, const void *h) { - int err, err2; - char *p; + const struct archive_entry_header_ustar *header; + size_t size; + int err; + char *acl, *p; wchar_t *wp; + /* + * read_body_to_string adds a NUL terminator, but we need a little + * more to make sure that we don't overrun acl_text later. + */ + header = (const struct archive_entry_header_ustar *)h; + size = tar_atol(header->size, sizeof(header->size)); err = read_body_to_string(a, tar, &(tar->acl_text), h); - err2 = tar_read_header(a, tar, entry); - err = err_combine(err, err2); - - /* XXX Ensure p doesn't overrun acl_text */ + if (err != ARCHIVE_OK) + return (err); + err = tar_read_header(a, tar, entry); + if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) + return (err); /* Skip leading octal number. */ /* XXX TODO: Parse the octal number and sanity-check it. */ - p = tar->acl_text.s; - while (*p != '\0') + p = acl = tar->acl_text.s; + while (*p != '\0' && p < acl + size) p++; p++; - wp = (wchar_t *)malloc((strlen(p) + 1) * sizeof(wchar_t)); - if (wp != NULL) { - utf8_decode(wp, p, strlen(p)); - err2 = __archive_entry_acl_parse_w(entry, wp, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - err = err_combine(err, err2); - free(wp); + if (p >= acl + size) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Malformed Solaris ACL attribute"); + return(ARCHIVE_WARN); } + /* Skip leading octal number. */ + size -= (p - acl); + acl = p; + + while (*p != '\0' && p < acl + size) + p++; + + wp = (wchar_t *)malloc((p - acl + 1) * sizeof(wchar_t)); + if (wp == NULL) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate work buffer for ACL parsing"); + return (ARCHIVE_FATAL); + } + utf8_decode(wp, acl, p - acl); + err = __archive_entry_acl_parse_w(entry, wp, + ARCHIVE_ENTRY_ACL_TYPE_ACCESS); + free(wp); return (err); } @@ -735,15 +826,17 @@ static int header_longlink(struct archive_read *a, struct tar *tar, struct archive_entry *entry, const void *h) { - int err, err2; + int err; err = read_body_to_string(a, tar, &(tar->longlink), h); - err2 = tar_read_header(a, tar, entry); - if (err == ARCHIVE_OK && err2 == ARCHIVE_OK) { - /* Set symlink if symlink already set, else hardlink. */ - archive_entry_set_link(entry, tar->longlink.s); - } - return (err_combine(err, err2)); + if (err != ARCHIVE_OK) + return (err); + err = tar_read_header(a, tar, entry); + if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) + return (err); + /* Set symlink if symlink already set, else hardlink. */ + archive_entry_set_link(entry, tar->longlink.s); + return (ARCHIVE_OK); } /* @@ -753,14 +846,17 @@ static int header_longname(struct archive_read *a, struct tar *tar, struct archive_entry *entry, const void *h) { - int err, err2; + int err; err = read_body_to_string(a, tar, &(tar->longname), h); + if (err != ARCHIVE_OK) + return (err); /* Read and parse "real" header, then override name. */ - err2 = tar_read_header(a, tar, entry); - if (err == ARCHIVE_OK && err2 == ARCHIVE_OK) - archive_entry_set_pathname(entry, tar->longname.s); - return (err_combine(err, err2)); + err = tar_read_header(a, tar, entry); + if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) + return (err); + archive_entry_set_pathname(entry, tar->longname.s); + return (ARCHIVE_OK); } @@ -793,6 +889,11 @@ read_body_to_string(struct archive_read *a, struct tar *tar, (void)tar; /* UNUSED */ header = (const struct archive_entry_header_ustar *)h; size = tar_atol(header->size, sizeof(header->size)); + if ((size > 1048576) || (size < 0)) { + archive_set_error(&a->archive, EINVAL, + "Special header too large"); + return (ARCHIVE_FATAL); + } /* Read the body into the string. */ archive_string_ensure(as, size+1); @@ -800,6 +901,8 @@ read_body_to_string(struct archive_read *a, struct tar *tar, dest = as->s; while (padded_size > 0) { bytes_read = (a->decompressor->read_ahead)(a, &src, padded_size); + if (bytes_read == 0) + return (ARCHIVE_EOF); if (bytes_read < 0) return (ARCHIVE_FATAL); if (bytes_read > padded_size) @@ -847,7 +950,8 @@ header_common(struct archive_read *a, struct tar *tar, archive_entry_set_mode(entry, tar_atol(header->mode, sizeof(header->mode))); archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid))); archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid))); - archive_entry_set_size(entry, tar_atol(header->size, sizeof(header->size))); + tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size)); + archive_entry_set_size(entry, tar->entry_bytes_remaining); archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0); /* Handle the tar type flag appropriately. */ @@ -892,29 +996,35 @@ header_common(struct archive_read *a, struct tar *tar, */ if (archive_entry_size(entry) > 0 && a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE && - archive_read_format_tar_bid(a) > 50) + archive_read_format_tar_bid(a) > 50) { archive_entry_set_size(entry, 0); - break; + tar->entry_bytes_remaining = 0; + } case '2': /* Symlink */ archive_entry_set_filetype(entry, AE_IFLNK); archive_entry_set_size(entry, 0); + tar->entry_bytes_remaining = 0; archive_entry_set_symlink(entry, tar->entry_linkname.s); break; case '3': /* Character device */ archive_entry_set_filetype(entry, AE_IFCHR); archive_entry_set_size(entry, 0); + tar->entry_bytes_remaining = 0; break; case '4': /* Block device */ archive_entry_set_filetype(entry, AE_IFBLK); archive_entry_set_size(entry, 0); + tar->entry_bytes_remaining = 0; break; case '5': /* Dir */ archive_entry_set_filetype(entry, AE_IFDIR); archive_entry_set_size(entry, 0); + tar->entry_bytes_remaining = 0; break; case '6': /* FIFO device */ archive_entry_set_filetype(entry, AE_IFIFO); archive_entry_set_size(entry, 0); + tar->entry_bytes_remaining = 0; break; case 'D': /* GNU incremental directory type */ /* @@ -972,7 +1082,6 @@ header_old_tar(struct archive_read *a, struct tar *tar, /* Grab rest of common fields */ header_common(a, tar, entry, h); - tar->entry_bytes_remaining = archive_entry_size(entry); tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); return (0); } @@ -984,11 +1093,13 @@ static int header_pax_global(struct archive_read *a, struct tar *tar, struct archive_entry *entry, const void *h) { - int err, err2; + int err; err = read_body_to_string(a, tar, &(tar->pax_global), h); - err2 = tar_read_header(a, tar, entry); - return (err_combine(err, err2)); + if (err != ARCHIVE_OK) + return (err); + err = tar_read_header(a, tar, entry); + return (err); } static int @@ -997,10 +1108,14 @@ header_pax_extensions(struct archive_read *a, struct tar *tar, { int err, err2; - read_body_to_string(a, tar, &(tar->pax_header), h); + err = read_body_to_string(a, tar, &(tar->pax_header), h); + if (err != ARCHIVE_OK) + return (err); /* Parse the next header. */ err = tar_read_header(a, tar, entry); + if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) + return (err); /* * TODO: Parse global/default options into 'entry' struct here @@ -1014,7 +1129,6 @@ header_pax_extensions(struct archive_read *a, struct tar *tar, */ err2 = pax_header(a, tar, entry, tar->pax_header.s); err = err_combine(err, err2); - tar->entry_bytes_remaining = archive_entry_size(entry); tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); return (err); } @@ -1065,7 +1179,6 @@ header_ustar(struct archive_read *a, struct tar *tar, tar_atol(header->rdevminor, sizeof(header->rdevminor))); } - tar->entry_bytes_remaining = archive_entry_size(entry); tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); return (0); @@ -1099,8 +1212,11 @@ pax_header(struct archive_read *a, struct tar *tar, l--; break; } - if (*p < '0' || *p > '9') - return (-1); + if (*p < '0' || *p > '9') { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Ignoring malformed pax extended attributes"); + return (ARCHIVE_WARN); + } line_length *= 10; line_length += *p - '0'; if (line_length > 999999) { @@ -1112,8 +1228,19 @@ pax_header(struct archive_read *a, struct tar *tar, l--; } - if (line_length > attr_length) - return (0); + /* + * Parsed length must be no bigger than available data, + * at least 1, and the last character of the line must + * be '\n'. + */ + if (line_length > attr_length + || line_length < 1 + || attr[line_length - 1] != '\n') + { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Ignoring malformed pax extended attribute"); + return (ARCHIVE_WARN); + } /* Ensure pax_entry buffer is big enough. */ if (tar->pax_entry_length <= line_length) { @@ -1160,7 +1287,7 @@ pax_header(struct archive_read *a, struct tar *tar, value = wp + 1; /* Identify this attribute and set it in the entry. */ - err2 = pax_attribute(entry, key, value); + err2 = pax_attribute(tar, entry, key, value); err = err_combine(err, err2); /* Skip to next line */ @@ -1215,19 +1342,72 @@ pax_attribute_xattr(struct archive_entry *entry, * extensions should always have keywords of the form "VENDOR.attribute" * In particular, it's quite feasible to support many different * vendor extensions here. I'm using "LIBARCHIVE" for extensions - * unique to this library (currently, there are none). + * unique to this library. * - * Investigate other vendor-specific extensions, as well and see if + * Investigate other vendor-specific extensions and see if * any of them look useful. */ static int -pax_attribute(struct archive_entry *entry, +pax_attribute(struct tar *tar, struct archive_entry *entry, wchar_t *key, wchar_t *value) { int64_t s; long n; switch (key[0]) { + case 'G': + /* GNU "0.0" sparse pax format. */ + if (wcscmp(key, L"GNU.sparse.numblocks") == 0) { + tar->sparse_offset = -1; + tar->sparse_numbytes = -1; + tar->sparse_gnu_major = 0; + tar->sparse_gnu_minor = 0; + } + if (wcscmp(key, L"GNU.sparse.offset") == 0) { + tar->sparse_offset = tar_atol10(value, wcslen(value)); + if (tar->sparse_numbytes != -1) { + gnu_add_sparse_entry(tar, + tar->sparse_offset, tar->sparse_numbytes); + tar->sparse_offset = -1; + tar->sparse_numbytes = -1; + } + } + if (wcscmp(key, L"GNU.sparse.numbytes") == 0) { + tar->sparse_numbytes = tar_atol10(value, wcslen(value)); + if (tar->sparse_numbytes != -1) { + gnu_add_sparse_entry(tar, + tar->sparse_offset, tar->sparse_numbytes); + tar->sparse_offset = -1; + tar->sparse_numbytes = -1; + } + } + if (wcscmp(key, L"GNU.sparse.size") == 0) + archive_entry_set_size(entry, + tar_atol10(value, wcslen(value))); + + /* GNU "0.1" sparse pax format. */ + if (wcscmp(key, L"GNU.sparse.map") == 0) { + tar->sparse_gnu_major = 0; + tar->sparse_gnu_minor = 1; + if (gnu_sparse_01_parse(tar, value) != ARCHIVE_OK) + return (ARCHIVE_WARN); + } + + /* GNU "1.0" sparse pax format */ + if (wcscmp(key, L"GNU.sparse.major") == 0) { + tar->sparse_gnu_major = tar_atol10(value, wcslen(value)); + tar->sparse_gnu_pending = 1; + } + if (wcscmp(key, L"GNU.sparse.minor") == 0) { + tar->sparse_gnu_minor = tar_atol10(value, wcslen(value)); + tar->sparse_gnu_pending = 1; + } + if (wcscmp(key, L"GNU.sparse.name") == 0) + archive_entry_copy_pathname_w(entry, value); + if (wcscmp(key, L"GNU.sparse.realsize") == 0) + archive_entry_set_size(entry, + tar_atol10(value, wcslen(value))); + break; case 'L': /* Our extensions */ /* TODO: Handle arbitrary extended attributes... */ @@ -1306,8 +1486,12 @@ pax_attribute(struct archive_entry *entry, case 's': /* POSIX has reserved 'security.*' */ /* Someday: if (wcscmp(key, L"security.acl")==0) { ... } */ - if (wcscmp(key, L"size")==0) - archive_entry_set_size(entry, tar_atol10(value, wcslen(value))); + if (wcscmp(key, L"size")==0) { + tar->entry_bytes_remaining = tar_atol10(value, wcslen(value)); + archive_entry_set_size(entry, tar->entry_bytes_remaining); + } + tar->entry_bytes_remaining = 0; + break; case 'u': if (wcscmp(key, L"uid")==0) @@ -1418,7 +1602,6 @@ header_gnutar(struct archive_read *a, struct tar *tar, } else archive_entry_set_rdev(entry, 0); - tar->entry_bytes_remaining = archive_entry_size(entry); tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); /* Grab GNU-specific fields. */ @@ -1432,7 +1615,7 @@ header_gnutar(struct archive_read *a, struct tar *tar, } if (header->sparse[0].offset[0] != 0) { - gnu_read_sparse_data(a, tar, header); + gnu_sparse_old_read(a, tar, header); } else { if (header->isextended[0] != 0) { /* XXX WTF? XXX */ @@ -1442,8 +1625,38 @@ header_gnutar(struct archive_read *a, struct tar *tar, return (0); } +static void +gnu_add_sparse_entry(struct tar *tar, off_t offset, off_t remaining) +{ + struct sparse_block *p; + + p = (struct sparse_block *)malloc(sizeof(*p)); + if (p == NULL) + __archive_errx(1, "Out of memory"); + memset(p, 0, sizeof(*p)); + if (tar->sparse_last != NULL) + tar->sparse_last->next = p; + else + tar->sparse_list = p; + tar->sparse_last = p; + p->offset = offset; + p->remaining = remaining; +} + +/* + * GNU tar old-format sparse data. + * + * GNU old-format sparse data is stored in a fixed-field + * format. Offset/size values are 11-byte octal fields (same + * format as 'size' field in ustart header). These are + * stored in the header, allocating subsequent header blocks + * as needed. Extending the header in this way is a pretty + * severe POSIX violation; this design has earned GNU tar a + * lot of criticism. + */ + static int -gnu_read_sparse_data(struct archive_read *a, struct tar *tar, +gnu_sparse_old_read(struct archive_read *a, struct tar *tar, const struct archive_entry_header_gnutar *header) { ssize_t bytes_read; @@ -1455,7 +1668,7 @@ gnu_read_sparse_data(struct archive_read *a, struct tar *tar, }; const struct extended *ext; - gnu_parse_sparse_data(a, tar, header->sparse, 4); + gnu_sparse_old_parse(tar, header->sparse, 4); if (header->isextended[0] == 0) return (ARCHIVE_OK); @@ -1471,7 +1684,7 @@ gnu_read_sparse_data(struct archive_read *a, struct tar *tar, } (a->decompressor->consume)(a, 512); ext = (const struct extended *)data; - gnu_parse_sparse_data(a, tar, ext->sparse, 21); + gnu_sparse_old_parse(tar, ext->sparse, 21); } while (ext->isextended[0] != 0); if (tar->sparse_list != NULL) tar->entry_offset = tar->sparse_list->offset; @@ -1479,34 +1692,165 @@ gnu_read_sparse_data(struct archive_read *a, struct tar *tar, } static void -gnu_parse_sparse_data(struct archive_read *a, struct tar *tar, +gnu_sparse_old_parse(struct tar *tar, const struct gnu_sparse *sparse, int length) { - struct sparse_block *last; - struct sparse_block *p; + while (length > 0 && sparse->offset[0] != 0) { + gnu_add_sparse_entry(tar, + tar_atol(sparse->offset, sizeof(sparse->offset)), + tar_atol(sparse->numbytes, sizeof(sparse->numbytes))); + sparse++; + length--; + } +} - (void)a; /* UNUSED */ +/* + * GNU tar sparse format 0.0 + * + * Beginning with GNU tar 1.15, sparse files are stored using + * information in the pax extended header. The GNU tar maintainers + * have gone through a number of variations in the process of working + * out this scheme; furtunately, they're all numbered. + * + * Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the + * number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to + * store offset/size for each block. The repeated instances of these + * latter fields violate the pax specification (which frowns on + * duplicate keys), so this format was quickly replaced. + */ - last = tar->sparse_list; - while (last != NULL && last->next != NULL) - last = last->next; +/* + * GNU tar sparse format 0.1 + * + * This version replaced the offset/numbytes attributes with + * a single "map" attribute that stored a list of integers. This + * format had two problems: First, the "map" attribute could be very + * long, which caused problems for some implementations. More + * importantly, the sparse data was lost when extracted by archivers + * that didn't recognize this extension. + */ - while (length > 0 && sparse->offset[0] != 0) { - p = (struct sparse_block *)malloc(sizeof(*p)); - if (p == NULL) - __archive_errx(1, "Out of memory"); - memset(p, 0, sizeof(*p)); - if (last != NULL) - last->next = p; +static int +gnu_sparse_01_parse(struct tar *tar, const wchar_t *p) +{ + const wchar_t *e; + off_t offset = -1, size = -1; + + for (;;) { + e = p; + while (*e != '\0' && *e != ',') { + if (*e < '0' || *e > '9') + return (ARCHIVE_WARN); + e++; + } + if (offset < 0) { + offset = tar_atol10(p, e - p); + if (offset < 0) + return (ARCHIVE_WARN); + } else { + size = tar_atol10(p, e - p); + if (size < 0) + return (ARCHIVE_WARN); + gnu_add_sparse_entry(tar, offset, size); + offset = -1; + } + if (*e == '\0') + return (ARCHIVE_OK); + p = e + 1; + } +} + +/* + * GNU tar sparse format 1.0 + * + * The idea: The offset/size data is stored as a series of base-10 + * ASCII numbers prepended to the file data, so that dearchivers that + * don't support this format will extract the block map along with the + * data and a separate post-process can restore the sparseness. + * + * Unfortunately, GNU tar 1.16 adds bogus padding to the end of the + * entry that depends on the size of the map; this means we have to + * parse the sparse map when we read the header (otherwise, entry_skip + * will fail). This is why sparse_10_read is called from read_header + * above, instead of at the beginning of read_data, where it "should" + * go. + * + * This variant also replaced GNU.sparse.size with GNU.sparse.realsize + * and introduced the GNU.sparse.major/GNU.sparse.minor attributes. + */ + +/* + * Read the next line from the input, and parse it as a decimal + * integer followed by '\n'. Returns positive integer value or + * negative on error. + */ +static int64_t +gnu_sparse_10_atol(struct archive_read *a, struct tar *tar, + ssize_t *total_read) +{ + int64_t l, limit, last_digit_limit; + const char *p; + ssize_t bytes_read; + int base, digit; + + base = 10; + limit = INT64_MAX / base; + last_digit_limit = INT64_MAX % base; + + bytes_read = readline(a, tar, &p); + if (bytes_read <= 0) + return (ARCHIVE_FATAL); + *total_read += bytes_read; + + l = 0; + while (bytes_read > 0) { + if (*p == '\n') + return (l); + if (*p < '0' || *p >= '0' + base) + return (ARCHIVE_WARN); + digit = *p - '0'; + if (l > limit || (l == limit && digit > last_digit_limit)) + l = UINT64_MAX; /* Truncate on overflow. */ else - tar->sparse_list = p; - last = p; - p->offset = tar_atol(sparse->offset, sizeof(sparse->offset)); - p->remaining = - tar_atol(sparse->numbytes, sizeof(sparse->numbytes)); - sparse++; - length--; + l = (l * base) + digit; + p++; + bytes_read--; + } + /* TODO: Error message. */ + return (ARCHIVE_WARN); +} + +/* + * Returns number of bytes consumed to read the sparse block data. + */ +static ssize_t +gnu_sparse_10_read(struct archive_read *a, struct tar *tar) +{ + ssize_t bytes_read = 0; + int entries; + off_t offset, size, to_skip; + + /* Parse entries. */ + entries = gnu_sparse_10_atol(a, tar, &bytes_read); + if (entries < 0) + return (ARCHIVE_FATAL); + /* Parse the individual entries. */ + while (entries-- > 0) { + /* Parse offset/size */ + offset = gnu_sparse_10_atol(a, tar, &bytes_read); + if (offset < 0) + return (ARCHIVE_FATAL); + size = gnu_sparse_10_atol(a, tar, &bytes_read); + if (size < 0) + return (ARCHIVE_FATAL); + /* Add a new sparse entry. */ + gnu_add_sparse_entry(tar, offset, size); } + /* Skip rest of block... */ + to_skip = 0x1ff & -bytes_read; + if (to_skip != (a->decompressor->skip)(a, to_skip)) + return (ARCHIVE_FATAL); + return (bytes_read + to_skip); } /*- @@ -1574,7 +1918,6 @@ tar_atol8(const char *p, unsigned char_cnt) return (sign < 0) ? -l : l; } - /* * Note that this implementation does not (and should not!) obey * locale settings; you cannot simply substitute strtol here, since @@ -1647,6 +1990,57 @@ tar_atol256(const char *_p, unsigned char_cnt) return (l); } +/* + * Returns length of line (including trailing newline) + * or negative on error. 'start' argument is updated to + * point to first character of line. This avoids copying + * when possible. + */ +static ssize_t +readline(struct archive_read *a, struct tar *tar, const char **start) +{ + ssize_t bytes_read; + ssize_t total_size = 0; + const void *t; + const char *s; + void *p; + + bytes_read = (a->decompressor->read_ahead)(a, &t, 1); + if (bytes_read <= 0) + return (ARCHIVE_FATAL); + s = t; /* Start of line? */ + p = memchr(t, '\n', bytes_read); + /* If we found '\n' in the read buffer, return pointer to that. */ + if (p != NULL) { + bytes_read = 1 + ((const char *)p) - s; + (a->decompressor->consume)(a, bytes_read); + *start = s; + return (bytes_read); + } + /* Otherwise, we need to accumulate in a line buffer. */ + for (;;) { + archive_string_ensure(&tar->line, total_size + bytes_read); + memcpy(tar->line.s + total_size, t, bytes_read); + (a->decompressor->consume)(a, bytes_read); + total_size += bytes_read; + /* If we found '\n', clean up and return. */ + if (p != NULL) { + *start = tar->line.s; + return (total_size); + } + /* Read some more. */ + bytes_read = (a->decompressor->read_ahead)(a, &t, 1); + if (bytes_read <= 0) + return (ARCHIVE_FATAL); + s = t; /* Start of line? */ + p = memchr(t, '\n', bytes_read); + /* If we found '\n', trim the read. */ + if (p != NULL) { + bytes_read = 1 + ((const char *)p) - s; + } + } +} + static int utf8_decode(wchar_t *dest, const char *src, size_t length) { diff --git a/contrib/libarchive-2/libarchive/archive_read_support_format_zip.c b/contrib/libarchive-2/libarchive/archive_read_support_format_zip.c index 25ec437290..651e8dd793 100644 --- a/contrib/libarchive-2/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive-2/libarchive/archive_read_support_format_zip.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.12 2007/04/15 00:53:38 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.13 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_string.c b/contrib/libarchive-2/libarchive/archive_string.c index e1041453ff..eb26a74935 100644 --- a/contrib/libarchive-2/libarchive/archive_string.c +++ b/contrib/libarchive-2/libarchive/archive_string.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_string.c,v 1.9 2007/01/13 03:30:14 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_string.c,v 1.10 2007/05/29 01:00:19 kientzle Exp $"); /* * Basic resizable string support, to simplify manipulating arbitrary-sized diff --git a/contrib/libarchive-2/libarchive/archive_string.h b/contrib/libarchive-2/libarchive/archive_string.h index 749f591d60..596db9a148 100644 --- a/contrib/libarchive-2/libarchive/archive_string.h +++ b/contrib/libarchive-2/libarchive/archive_string.h @@ -22,7 +22,7 @@ * (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: src/lib/libarchive/archive_string.h,v 1.8 2007/01/09 08:05:55 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_string.h,v 1.9 2007/05/29 01:00:19 kientzle Exp $ * */ diff --git a/contrib/libarchive-2/libarchive/archive_util.3 b/contrib/libarchive-2/libarchive/archive_util.3 index 1d8a356425..b8a030e493 100644 --- a/contrib/libarchive-2/libarchive/archive_util.3 +++ b/contrib/libarchive-2/libarchive/archive_util.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libarchive/archive_util.3,v 1.6 2007/03/03 07:37:36 kientzle Exp $ +.\" $FreeBSD: src/lib/libarchive/archive_util.3,v 1.7 2007/05/29 01:00:19 kientzle Exp $ .\" .Dd January 8, 2005 .Dt archive_util 3 diff --git a/contrib/libarchive-2/libarchive/archive_util.c b/contrib/libarchive-2/libarchive/archive_util.c index 63bd5ae908..d73366357d 100644 --- a/contrib/libarchive-2/libarchive/archive_util.c +++ b/contrib/libarchive-2/libarchive/archive_util.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_util.c,v 1.13 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_util.c,v 1.15 2007/07/06 15:36:38 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include @@ -51,6 +51,12 @@ archive_api_version(void) return (ARCHIVE_API_VERSION); } +int +archive_version_stamp(void) +{ + return (ARCHIVE_VERSION_STAMP); +} + const char * archive_version(void) { diff --git a/contrib/libarchive-2/libarchive/archive_write.3 b/contrib/libarchive-2/libarchive/archive_write.3 index 07c26a0ff7..c07b6b570e 100644 --- a/contrib/libarchive-2/libarchive/archive_write.3 +++ b/contrib/libarchive-2/libarchive/archive_write.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libarchive/archive_write.3,v 1.21 2007/03/03 07:37:36 kientzle Exp $ +.\" $FreeBSD: src/lib/libarchive/archive_write.3,v 1.22 2007/05/29 01:00:19 kientzle Exp $ .\" .Dd August 19, 2006 .Dt archive_write 3 diff --git a/contrib/libarchive-2/libarchive/archive_write.c b/contrib/libarchive-2/libarchive/archive_write.c index 77e410b177..2977063979 100644 --- a/contrib/libarchive-2/libarchive/archive_write.c +++ b/contrib/libarchive-2/libarchive/archive_write.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write.c,v 1.25 2007/03/11 10:29:52 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write.c,v 1.26 2007/05/29 01:00:19 kientzle Exp $"); /* * This file contains the "essential" portions of the write API, that diff --git a/contrib/libarchive-2/libarchive/archive_write_disk.c b/contrib/libarchive-2/libarchive/archive_write_disk.c index ac2bcbde0a..691dfe48a0 100644 --- a/contrib/libarchive-2/libarchive/archive_write_disk.c +++ b/contrib/libarchive-2/libarchive/archive_write_disk.c @@ -25,7 +25,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.11 2007/05/21 04:22:38 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.12 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_disk_set_standard_lookup.c b/contrib/libarchive-2/libarchive/archive_write_disk_set_standard_lookup.c index 4448b3e07d..427b87615a 100644 --- a/contrib/libarchive-2/libarchive/archive_write_disk_set_standard_lookup.c +++ b/contrib/libarchive-2/libarchive/archive_write_disk_set_standard_lookup.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk_set_standard_lookup.c,v 1.2 2007/04/20 15:32:13 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk_set_standard_lookup.c,v 1.4 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_private.h b/contrib/libarchive-2/libarchive/archive_write_private.h index 083b6cac7f..82935f4627 100644 --- a/contrib/libarchive-2/libarchive/archive_write_private.h +++ b/contrib/libarchive-2/libarchive/archive_write_private.h @@ -22,7 +22,7 @@ * (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: src/lib/libarchive/archive_write_private.h,v 1.1 2007/03/03 07:37:36 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/archive_write_private.h,v 1.2 2007/05/29 01:00:19 kientzle Exp $ */ #ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED diff --git a/contrib/libarchive-2/libarchive/archive_write_set_compression_bzip2.c b/contrib/libarchive-2/libarchive/archive_write_set_compression_bzip2.c index 43e1d08c60..0883ea1de2 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_compression_bzip2.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_compression_bzip2.c @@ -28,7 +28,7 @@ /* Don't compile this if we don't have bzlib. */ #if HAVE_BZLIB_H -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_bzip2.c,v 1.11 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_bzip2.c,v 1.12 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_compression_gzip.c b/contrib/libarchive-2/libarchive/archive_write_set_compression_gzip.c index 6e74048052..56a0a11fd9 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_compression_gzip.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_compression_gzip.c @@ -28,7 +28,7 @@ /* Don't compile this if we don't have zlib. */ #if HAVE_ZLIB_H -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_gzip.c,v 1.13 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_gzip.c,v 1.14 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_compression_none.c b/contrib/libarchive-2/libarchive/archive_write_set_compression_none.c index 7b254a85d4..0ad962a500 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_compression_none.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_compression_none.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_none.c,v 1.14 2007/04/15 04:42:52 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_none.c,v 1.15 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_compression_program.c b/contrib/libarchive-2/libarchive/archive_write_set_compression_program.c index 4f28a0feff..fc1481dbcd 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_compression_program.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_compression_program.c @@ -25,7 +25,7 @@ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_program.c,v 1.1 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_SYS_WAIT_H # include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format.c b/contrib/libarchive-2/libarchive/archive_write_set_format.c index b04bef7fba..e5f89211a2 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format.c,v 1.4 2007/01/09 08:05:56 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format.c,v 1.5 2007/06/22 05:47:00 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include @@ -42,6 +42,7 @@ static struct { int code; int (*setter)(struct archive *); } codes[] = { { ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio }, + { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc }, { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio }, { ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar }, { ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar }, diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_ar.c b/contrib/libarchive-2/libarchive/archive_write_set_format_ar.c index 52af5f9a63..bf3ea4de5d 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_ar.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_ar.c @@ -26,7 +26,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ar.c,v 1.2 2007/04/14 22:34:10 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ar.c,v 1.3 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_by_name.c b/contrib/libarchive-2/libarchive/archive_write_set_format_by_name.c index 1759a8f19b..0d7cae4867 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_by_name.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_by_name.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_by_name.c,v 1.6 2007/04/14 22:34:10 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_by_name.c,v 1.7 2007/06/22 05:47:00 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include @@ -49,6 +49,8 @@ struct { const char *name; int (*setter)(struct archive *); } names[] = { "argnu", archive_write_set_format_ar_svr4 }, { "arsvr4", archive_write_set_format_ar_svr4 }, { "cpio", archive_write_set_format_cpio }, + { "newc", archive_write_set_format_cpio_newc }, + { "odc", archive_write_set_format_cpio }, { "pax", archive_write_set_format_pax }, { "posix", archive_write_set_format_pax }, { "shar", archive_write_set_format_shar }, diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c b/contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c index a713bfe84b..6459477e42 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_cpio.c,v 1.10 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_cpio.c,v 1.11 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c b/contrib/libarchive-2/libarchive/archive_write_set_format_cpio_newc.c similarity index 56% copy from contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c copy to contrib/libarchive-2/libarchive/archive_write_set_format_cpio_newc.c index a713bfe84b..ab48d38004 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_cpio.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_cpio_newc.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2006 Rudolf Marek SYSGO s.r.o. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +25,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_cpio.c,v 1.10 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_cpio_newc.c,v 1.1 2007/06/22 05:47:00 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include @@ -42,39 +43,43 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_cpio.c,v 1.10 20 #include "archive_private.h" #include "archive_write_private.h" -static ssize_t archive_write_cpio_data(struct archive_write *, +static ssize_t archive_write_newc_data(struct archive_write *, const void *buff, size_t s); -static int archive_write_cpio_finish(struct archive_write *); -static int archive_write_cpio_destroy(struct archive_write *); -static int archive_write_cpio_finish_entry(struct archive_write *); -static int archive_write_cpio_header(struct archive_write *, +static int archive_write_newc_finish(struct archive_write *); +static int archive_write_newc_destroy(struct archive_write *); +static int archive_write_newc_finish_entry(struct archive_write *); +static int archive_write_newc_header(struct archive_write *, struct archive_entry *); -static int format_octal(int64_t, void *, int); -static int64_t format_octal_recursive(int64_t, char *, int); +static int format_hex(int64_t, void *, int); +static int64_t format_hex_recursive(int64_t, char *, int); struct cpio { uint64_t entry_bytes_remaining; + int padding; }; -struct cpio_header { +struct cpio_header_newc { char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesize[6]; - char c_filesize[11]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_checksum[8]; }; /* * Set output format to 'cpio' format. */ int -archive_write_set_format_cpio(struct archive *_a) +archive_write_set_format_cpio_newc(struct archive *_a) { struct archive_write *a = (struct archive_write *)_a; struct cpio *cpio; @@ -92,23 +97,24 @@ archive_write_set_format_cpio(struct archive *_a) a->format_data = cpio; a->pad_uncompressed = 1; - a->format_write_header = archive_write_cpio_header; - a->format_write_data = archive_write_cpio_data; - a->format_finish_entry = archive_write_cpio_finish_entry; - a->format_finish = archive_write_cpio_finish; - a->format_destroy = archive_write_cpio_destroy; - a->archive_format = ARCHIVE_FORMAT_CPIO_POSIX; - a->archive_format_name = "POSIX cpio"; + a->format_write_header = archive_write_newc_header; + a->format_write_data = archive_write_newc_data; + a->format_finish_entry = archive_write_newc_finish_entry; + a->format_finish = archive_write_newc_finish; + a->format_destroy = archive_write_newc_destroy; + a->archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC; + a->archive_format_name = "SVR4 cpio nocrc"; return (ARCHIVE_OK); } static int -archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry) +archive_write_newc_header(struct archive_write *a, struct archive_entry *entry) { struct cpio *cpio; const char *p, *path; int pathlength, ret; - struct cpio_header h; + struct cpio_header_newc h; + int pad; cpio = (struct cpio *)a->format_data; ret = 0; @@ -117,48 +123,54 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry) pathlength = strlen(path) + 1; /* Include trailing null. */ memset(&h, 0, sizeof(h)); - format_octal(070707, &h.c_magic, sizeof(h.c_magic)); - format_octal(archive_entry_dev(entry), &h.c_dev, sizeof(h.c_dev)); - /* - * TODO: Generate artificial inode numbers rather than just - * re-using the ones off the disk. That way, the 18-bit c_ino - * field only limits the number of files in the archive. - */ - if (archive_entry_ino(entry) > 0777777) { + format_hex(0x070701, &h.c_magic, sizeof(h.c_magic)); + format_hex(archive_entry_devmajor(entry), &h.c_devmajor, sizeof(h.c_devmajor)); + format_hex(archive_entry_devminor(entry), &h.c_devminor, sizeof(h.c_devminor)); + if (archive_entry_ino(entry) > 0xffffffff) { archive_set_error(&a->archive, ERANGE, "large inode number truncated"); ret = ARCHIVE_WARN; } - format_octal(archive_entry_ino(entry) & 0777777, &h.c_ino, sizeof(h.c_ino)); - format_octal(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode)); - format_octal(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid)); - format_octal(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid)); - format_octal(archive_entry_nlink(entry), &h.c_nlink, sizeof(h.c_nlink)); + format_hex(archive_entry_ino(entry) & 0xffffffff, &h.c_ino, sizeof(h.c_ino)); + format_hex(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode)); + format_hex(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid)); + format_hex(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid)); + format_hex(archive_entry_nlink(entry), &h.c_nlink, sizeof(h.c_nlink)); if (archive_entry_filetype(entry) == AE_IFBLK - || archive_entry_filetype(entry) == AE_IFCHR) - format_octal(archive_entry_dev(entry), &h.c_rdev, sizeof(h.c_rdev)); - else - format_octal(0, &h.c_rdev, sizeof(h.c_rdev)); - format_octal(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime)); - format_octal(pathlength, &h.c_namesize, sizeof(h.c_namesize)); + || archive_entry_filetype(entry) == AE_IFCHR) { + format_hex(archive_entry_rdevmajor(entry), &h.c_rdevmajor, sizeof(h.c_rdevmajor)); + format_hex(archive_entry_rdevminor(entry), &h.c_rdevminor, sizeof(h.c_rdevminor)); + } else { + format_hex(0, &h.c_rdevmajor, sizeof(h.c_rdevmajor)); + format_hex(0, &h.c_rdevminor, sizeof(h.c_rdevminor)); + } + format_hex(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime)); + format_hex(pathlength, &h.c_namesize, sizeof(h.c_namesize)); + format_hex(0, &h.c_checksum, sizeof(h.c_checksum)); /* Symlinks get the link written as the body of the entry. */ p = archive_entry_symlink(entry); if (p != NULL && *p != '\0') - format_octal(strlen(p), &h.c_filesize, sizeof(h.c_filesize)); + format_hex(strlen(p), &h.c_filesize, sizeof(h.c_filesize)); else - format_octal(archive_entry_size(entry), &h.c_filesize, sizeof(h.c_filesize)); + format_hex(archive_entry_size(entry), &h.c_filesize, sizeof(h.c_filesize)); ret = (a->compressor.write)(a, &h, sizeof(h)); if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL); + /* Pad pathname to even length. */ ret = (a->compressor.write)(a, path, pathlength); if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL); + pad = 0x3 & - (pathlength + sizeof(struct cpio_header_newc)); + if (pad) + ret = (a->compressor.write)(a, "\0\0\0", pad); + if (ret != ARCHIVE_OK) + return (ARCHIVE_FATAL); cpio->entry_bytes_remaining = archive_entry_size(entry); - + cpio->padding = 3 & (-cpio->entry_bytes_remaining); /* Write the symlink now. */ if (p != NULL && *p != '\0') ret = (a->compressor.write)(a, p, strlen(p)); @@ -167,7 +179,7 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry) } static ssize_t -archive_write_cpio_data(struct archive_write *a, const void *buff, size_t s) +archive_write_newc_data(struct archive_write *a, const void *buff, size_t s) { struct cpio *cpio; int ret; @@ -188,34 +200,34 @@ archive_write_cpio_data(struct archive_write *a, const void *buff, size_t s) * Format a number into the specified field. */ static int -format_octal(int64_t v, void *p, int digits) +format_hex(int64_t v, void *p, int digits) { int64_t max; int ret; - max = (((int64_t)1) << (digits * 3)) - 1; + max = (((int64_t)1) << (digits * 4)) - 1; if (v >= 0 && v <= max) { - format_octal_recursive(v, (char *)p, digits); + format_hex_recursive(v, (char *)p, digits); ret = 0; } else { - format_octal_recursive(max, (char *)p, digits); + format_hex_recursive(max, (char *)p, digits); ret = -1; } return (ret); } static int64_t -format_octal_recursive(int64_t v, char *p, int s) +format_hex_recursive(int64_t v, char *p, int s) { if (s == 0) return (v); - v = format_octal_recursive(v, p+1, s-1); - *p = '0' + (v & 7); - return (v >>= 3); + v = format_hex_recursive(v, p+1, s-1); + *p = "0123456789abcdef"[v & 0xf]; + return (v >>= 4); } static int -archive_write_cpio_finish(struct archive_write *a) +archive_write_newc_finish(struct archive_write *a) { struct cpio *cpio; int er; @@ -225,13 +237,13 @@ archive_write_cpio_finish(struct archive_write *a) trailer = archive_entry_new(); archive_entry_set_nlink(trailer, 1); archive_entry_set_pathname(trailer, "TRAILER!!!"); - er = archive_write_cpio_header(a, trailer); + er = archive_write_newc_header(a, trailer); archive_entry_free(trailer); return (er); } static int -archive_write_cpio_destroy(struct archive_write *a) +archive_write_newc_destroy(struct archive_write *a) { struct cpio *cpio; @@ -242,7 +254,7 @@ archive_write_cpio_destroy(struct archive_write *a) } static int -archive_write_cpio_finish_entry(struct archive_write *a) +archive_write_newc_finish_entry(struct archive_write *a) { struct cpio *cpio; int to_write, ret; @@ -257,5 +269,6 @@ archive_write_cpio_finish_entry(struct archive_write *a) return (ret); cpio->entry_bytes_remaining -= to_write; } + ret = (a->compressor.write)(a, a->nulls, cpio->padding); return (ret); } diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_pax.c b/contrib/libarchive-2/libarchive/archive_write_set_format_pax.c index 9a3f7d9552..471feb8307 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_pax.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_pax.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_pax.c,v 1.39 2007/03/03 07:37:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_pax.c,v 1.41 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_shar.c b/contrib/libarchive-2/libarchive/archive_write_set_format_shar.c index f99c305cdf..f26ba028ea 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_shar.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_shar.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_shar.c,v 1.17 2007/05/19 05:09:09 cperciva Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_shar.c,v 1.18 2007/05/29 01:00:19 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include diff --git a/contrib/libarchive-2/libarchive/archive_write_set_format_ustar.c b/contrib/libarchive-2/libarchive/archive_write_set_format_ustar.c index 32971b5782..61c90d5041 100644 --- a/contrib/libarchive-2/libarchive/archive_write_set_format_ustar.c +++ b/contrib/libarchive-2/libarchive/archive_write_set_format_ustar.c @@ -24,7 +24,8 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.21 2007/04/02 00:34:36 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.24 2007/06/11 05:17:30 kientzle Exp $"); + #ifdef HAVE_ERRNO_H #include @@ -277,6 +278,16 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512], else { /* Store in two pieces, splitting at a '/'. */ p = strchr(pp + strlen(pp) - USTAR_name_size - 1, '/'); + /* + * If the separator we found is the first '/', find + * the next one. (This is a pathological case that + * occurs for paths of exactly 101 bytes that start with + * '/'; it occurs because the separating '/' is not + * stored explicitly and the reconstruction assumes that + * an empty prefix means there is no '/' separator.) + */ + if (p == pp) + p = strchr(p + 1, '/'); /* * If there is no path separator, or the prefix or * remaining name are too large, return an error. diff --git a/contrib/libarchive-2/libarchive/filter_fork.c b/contrib/libarchive-2/libarchive/filter_fork.c index a7ee48b463..ac3f75c5d9 100644 --- a/contrib/libarchive-2/libarchive/filter_fork.c +++ b/contrib/libarchive-2/libarchive/filter_fork.c @@ -25,7 +25,7 @@ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: src/lib/libarchive/filter_fork.c,v 1.1 2007/05/29 01:00:20 kientzle Exp $"); #if defined(HAVE_POLL) # if defined(HAVE_POLL_H) diff --git a/contrib/libarchive-2/libarchive/filter_fork.h b/contrib/libarchive-2/libarchive/filter_fork.h index c4c3c752f2..685efda09f 100644 --- a/contrib/libarchive-2/libarchive/filter_fork.h +++ b/contrib/libarchive-2/libarchive/filter_fork.h @@ -21,6 +21,8 @@ * 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: src/lib/libarchive/filter_fork.h,v 1.1 2007/05/29 01:00:20 kientzle Exp $ */ #ifndef FILTER_FORK_H diff --git a/contrib/libarchive-2/libarchive/libarchive_internals.3 b/contrib/libarchive-2/libarchive/libarchive_internals.3 index c8f79ffac5..1161f65fb4 100644 --- a/contrib/libarchive-2/libarchive/libarchive_internals.3 +++ b/contrib/libarchive-2/libarchive/libarchive_internals.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD$ +.\" $FreeBSD: src/lib/libarchive/libarchive_internals.3,v 1.1 2007/05/29 01:00:20 kientzle Exp $ .\" .Dd April 16, 2007 .Dt LIBARCHIVE 3 diff --git a/contrib/libarchive-2/tar/bsdtar.1 b/contrib/libarchive-2/tar/bsdtar.1 index f2237f06b6..44b7909fc7 100644 --- a/contrib/libarchive-2/tar/bsdtar.1 +++ b/contrib/libarchive-2/tar/bsdtar.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.33 2007/01/09 08:12:17 kientzle Exp $ +.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.35 2007/05/29 05:39:10 kientzle Exp $ .\" .Dd April 13, 2004 .Dt BSDTAR 1 @@ -50,6 +50,9 @@ .Sh DESCRIPTION .Nm creates and manipulates streaming archive files. +This implementation can extract from tar, pax, cpio, zip, jar, ar, +and ISO 9660 cdrom images and can create tar, pax, cpio, ar, +and shar archives. .Pp The first synopsis form shows a .Dq bundled @@ -464,6 +467,9 @@ To extract all entries from the archive on the default tape drive: .Dl Nm Fl x .Pp +To examine the contents of an ISO 9660 cdrom image: +.Dl Nm Fl tf Pa image.iso +.Pp To move file hierarchies, invoke .Nm as -- 2.41.0