aboutsummaryrefslogtreecommitdiffstats
path: root/libarchive
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2011-12-26 22:25:58 +0000
committerMartin Matuska <mm@FreeBSD.org>2011-12-26 22:25:58 +0000
commit7691a6970b48b047c4290c0837e91dcab450db90 (patch)
tree15e9d164982e84a4b77c51d3cea2c450f6ec4ad1 /libarchive
parent4b16b4e80ed599fbac3f6e4427cd9fbb43d1ea1a (diff)
downloadsrc-7691a6970b48b047c4290c0837e91dcab450db90.tar.gz
src-7691a6970b48b047c4290c0837e91dcab450db90.zip
Update to vendor revision 3982
Notes
Notes: svn path=/vendor/libarchive/dist/; revision=228905
Diffstat (limited to 'libarchive')
-rw-r--r--libarchive/archive.h26
-rw-r--r--libarchive/archive_entry.32
-rw-r--r--libarchive/archive_private.h2
-rw-r--r--libarchive/archive_read.310
-rw-r--r--libarchive/archive_read.c8
-rw-r--r--libarchive/archive_read_disk.314
-rw-r--r--libarchive/archive_read_disk.c6
-rw-r--r--libarchive/archive_read_extract.c5
-rw-r--r--libarchive/archive_read_support_format_cpio.c15
-rw-r--r--libarchive/archive_read_support_format_iso9660.c92
-rw-r--r--libarchive/archive_read_support_format_zip.c53
-rw-r--r--libarchive/archive_util.32
-rw-r--r--libarchive/archive_virtual.c30
-rw-r--r--libarchive/archive_write.324
-rw-r--r--libarchive/archive_write.c8
-rw-r--r--libarchive/archive_write_disk.312
-rw-r--r--libarchive/archive_write_disk.c6
-rw-r--r--libarchive/archive_write_set_format_cpio.c12
-rw-r--r--libarchive/cpio.550
-rw-r--r--libarchive/libarchive-formats.52
-rw-r--r--libarchive/libarchive.354
-rw-r--r--libarchive/tar.52
-rw-r--r--libarchive/test/test_acl_freebsd.c5
-rw-r--r--libarchive/test/test_compat_zip.c33
-rw-r--r--libarchive/test/test_compat_zip_2.zip.uu10
25 files changed, 346 insertions, 137 deletions
diff --git a/libarchive/archive.h b/libarchive/archive.h
index 140df548b738..f4a4ea11e171 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -493,11 +493,10 @@ __LA_DECL void archive_read_extract_set_skip_file(struct archive *,
/* Close the file and release most resources. */
__LA_DECL int archive_read_close(struct archive *);
/* Release all resources and destroy the object. */
-/* Note that archive_read_finish will call archive_read_close for you. */
-#if ARCHIVE_VERSION_NUMBER < 2000000
-/* Erroneously declared to return void in libarchive 1.x */
-__LA_DECL void archive_read_finish(struct archive *);
-#else
+/* Note that archive_read_free will call archive_read_close for you. */
+__LA_DECL int archive_read_free(struct archive *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Synonym for archive_read_free() for backwards compatibility. */
__LA_DECL int archive_read_finish(struct archive *);
#endif
@@ -514,7 +513,7 @@ __LA_DECL int archive_read_finish(struct archive *);
* - archive_write_header to write the header
* - archive_write_data to write the entry data
* 5) archive_write_close to close the output
- * 6) archive_write_finish to cleanup the writer and release resources
+ * 6) archive_write_free to cleanup the writer and release resources
*/
__LA_DECL struct archive *archive_write_new(void);
__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
@@ -595,13 +594,12 @@ __LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
#endif
__LA_DECL int archive_write_finish_entry(struct archive *);
__LA_DECL int archive_write_close(struct archive *);
-#if ARCHIVE_VERSION_NUMBER < 2000000
-/* Return value was incorrect in libarchive 1.x. */
-__LA_DECL void archive_write_finish(struct archive *);
-#else
-/* Libarchive 2.x and later returns an error if this fails. */
-/* It can fail if the archive wasn't already closed, in which case
- * archive_write_finish() will implicitly call archive_write_close(). */
+
+/* This can fail if the archive wasn't already closed, in which case
+ * archive_write_free() will implicitly call archive_write_close(). */
+__LA_DECL int archive_write_free(struct archive *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Synonym for archive_write_free() for backwards compatibility. */
__LA_DECL int archive_write_finish(struct archive *);
#endif
@@ -630,7 +628,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
* - construct an appropriate struct archive_entry structure
* - archive_write_header to create the file/dir/etc on disk
* - archive_write_data to write the entry data
- * 4) archive_write_finish to cleanup the writer and release resources
+ * 4) archive_write_free to cleanup the writer and release resources
*
* In particular, you can use this in conjunction with archive_read()
* to pull entries out of an archive and create them on disk.
diff --git a/libarchive/archive_entry.3 b/libarchive/archive_entry.3
index 9ceb18b7aad6..f7ca88e51952 100644
--- a/libarchive/archive_entry.3
+++ b/libarchive/archive_entry.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
.\"
.Dd May 12, 2008
-.Dt archive_entry 3
+.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
.Nm archive_entry_acl_add_entry ,
diff --git a/libarchive/archive_private.h b/libarchive/archive_private.h
index 63384b82fed0..fba3d62a20af 100644
--- a/libarchive/archive_private.h
+++ b/libarchive/archive_private.h
@@ -58,7 +58,7 @@
struct archive_vtable {
int (*archive_close)(struct archive *);
- int (*archive_finish)(struct archive *);
+ int (*archive_free)(struct archive *);
int (*archive_write_header)(struct archive *,
struct archive_entry *);
int (*archive_write_finish_entry)(struct archive *);
diff --git a/libarchive/archive_read.3 b/libarchive/archive_read.3
index 5d5f539107ef..7b8e648a23e8 100644
--- a/libarchive/archive_read.3
+++ b/libarchive/archive_read.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd April 13, 2009
-.Dt archive_read 3
+.Dt ARCHIVE_READ 3
.Os
.Sh NAME
.Nm archive_read_new ,
@@ -69,7 +69,7 @@
.Nm archive_read_extract2 ,
.Nm archive_read_extract_set_progress_callback ,
.Nm archive_read_close ,
-.Nm archive_read_finish
+.Nm archive_read_free
.Nd functions for reading streaming archives
.Sh SYNOPSIS
.In archive.h
@@ -196,7 +196,7 @@
.Ft int
.Fn archive_read_close "struct archive *"
.Ft int
-.Fn archive_read_finish "struct archive *"
+.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for reading streaming archives.
The general process is to first create the
@@ -457,7 +457,7 @@ object and the archive_entry object so that various statistics
can be retrieved for the progress display.
.It Fn archive_read_close
Complete the archive and invoke the close callback.
-.It Fn archive_read_finish
+.It Fn archive_read_free
Invokes
.Fn archive_read_close
if it was not invoked manually, then release all resources.
@@ -600,7 +600,7 @@ list_archive(const char *name)
printf("%s\en",archive_entry_pathname(entry));
archive_read_data_skip(a);
}
- archive_read_finish(a);
+ archive_read_free(a);
free(mydata);
}
diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
index b1558b666f10..90b9bee535cd 100644
--- a/libarchive/archive_read.c
+++ b/libarchive/archive_read.c
@@ -60,7 +60,7 @@ static int choose_format(struct archive_read *);
static int cleanup_filters(struct archive_read *);
static struct archive_vtable *archive_read_vtable(void);
static int _archive_read_close(struct archive *);
-static int _archive_read_finish(struct archive *);
+static int _archive_read_free(struct archive *);
static struct archive_vtable *
archive_read_vtable(void)
@@ -69,7 +69,7 @@ archive_read_vtable(void)
static int inited = 0;
if (!inited) {
- av.archive_finish = _archive_read_finish;
+ av.archive_free = _archive_read_free;
av.archive_close = _archive_read_close;
}
return (&av);
@@ -779,7 +779,7 @@ cleanup_filters(struct archive_read *a)
* Release memory and other resources.
*/
static int
-_archive_read_finish(struct archive *_a)
+_archive_read_free(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
int i;
@@ -787,7 +787,7 @@ _archive_read_finish(struct archive *_a)
int r = ARCHIVE_OK;
__archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_finish");
+ "archive_read_free");
if (a->archive.state != ARCHIVE_STATE_CLOSED)
r = archive_read_close(&a->archive);
diff --git a/libarchive/archive_read_disk.3 b/libarchive/archive_read_disk.3
index 98ec6482f3f0..1d725a90e950 100644
--- a/libarchive/archive_read_disk.3
+++ b/libarchive/archive_read_disk.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read_disk.3 190957 2009-04-12 05:04:02Z kientzle $
.\"
.Dd March 10, 2009
-.Dt archive_read_disk 3
+.Dt ARCHIVE_READ_DISK 3
.Os
.Sh NAME
.Nm archive_read_disk_new ,
@@ -39,7 +39,7 @@
.Nm archive_read_disk_set_gname_lookup ,
.Nm archive_read_disk_set_standard_lookup ,
.Nm archive_read_close ,
-.Nm archive_read_finish
+.Nm archive_read_free
.Nd functions for reading objects from disk
.Sh SYNOPSIS
.In archive.h
@@ -81,7 +81,7 @@
.Ft int
.Fn archive_read_close "struct archive *"
.Ft int
-.Fn archive_read_finish "struct archive *"
+.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide an API for reading information about
objects on disk.
@@ -178,9 +178,9 @@ This affects the file ownership fields and ACL values in the
object.
.It Fn archive_read_close
This currently does nothing.
-.It Fn archive_write_finish
+.It Fn archive_read_free
Invokes
-.Fn archive_write_close
+.Fn archive_read_close
if it was not invoked manually, then releases all resources.
.El
More information about the
@@ -213,7 +213,7 @@ file_to_archive(struct archive *a, const char *name)
while ((bytes_read = read(fd, buff, sizeof(buff))) > 0)
archive_write_data(a, buff, bytes_read);
archive_write_finish_entry(a);
- archive_read_finish(ard);
+ archive_read_free(ard);
archive_entry_free(entry);
}
.Ed
@@ -276,7 +276,7 @@ and first appeared in
The
.Nm libarchive
library was written by
-.An Tim Kientzle Aq kientzle@freebsd.org .
+.An Tim Kientzle Aq kientzle@FreeBSD.org .
.Sh BUGS
The
.Dq standard
diff --git a/libarchive/archive_read_disk.c b/libarchive/archive_read_disk.c
index 8fad7f137334..dc43e179c7c5 100644
--- a/libarchive/archive_read_disk.c
+++ b/libarchive/archive_read_disk.c
@@ -33,7 +33,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk.c 189429 2009-03-06 04
#include "archive_private.h"
#include "archive_read_disk_private.h"
-static int _archive_read_finish(struct archive *);
+static int _archive_read_free(struct archive *);
static int _archive_read_close(struct archive *);
static const char *trivial_lookup_gname(void *, gid_t gid);
static const char *trivial_lookup_uname(void *, uid_t uid);
@@ -45,7 +45,7 @@ archive_read_disk_vtable(void)
static int inited = 0;
if (!inited) {
- av.archive_finish = _archive_read_finish;
+ av.archive_free = _archive_read_free;
av.archive_close = _archive_read_close;
}
return (&av);
@@ -129,7 +129,7 @@ archive_read_disk_new(void)
}
static int
-_archive_read_finish(struct archive *_a)
+_archive_read_free(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
diff --git a/libarchive/archive_read_extract.c b/libarchive/archive_read_extract.c
index 0096127702b9..013be05531b2 100644
--- a/libarchive/archive_read_extract.c
+++ b/libarchive/archive_read_extract.c
@@ -173,10 +173,7 @@ archive_read_extract_cleanup(struct archive_read *a)
{
int ret = ARCHIVE_OK;
-#if ARCHIVE_API_VERSION > 1
- ret =
-#endif
- archive_write_finish(a->extract->ad);
+ ret = archive_write_free(a->extract->ad);
free(a->extract);
a->extract = NULL;
return (ret);
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
index ed579b90cb37..23a2025d0954 100644
--- a/libarchive/archive_read_support_format_cpio.c
+++ b/libarchive/archive_read_support_format_cpio.c
@@ -42,6 +42,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 20116
#include "archive_private.h"
#include "archive_read_private.h"
+#ifdef _MSC_VER
+#define __packed
+#pragma pack(push, 1)
+#endif
struct cpio_bin_header {
unsigned char c_magic[2];
unsigned char c_dev[2];
@@ -54,7 +58,7 @@ struct cpio_bin_header {
unsigned char c_mtime[4];
unsigned char c_namesize[2];
unsigned char c_filesize[4];
-};
+} __packed;
struct cpio_odc_header {
char c_magic[6];
@@ -68,7 +72,7 @@ struct cpio_odc_header {
char c_mtime[11];
char c_namesize[6];
char c_filesize[11];
-};
+} __packed;
struct cpio_newc_header {
char c_magic[6];
@@ -85,7 +89,12 @@ struct cpio_newc_header {
char c_rdevminor[8];
char c_namesize[8];
char c_crc[8];
-};
+} __packed;
+
+#ifdef _MSC_VER
+#undef __packed
+#pragma pack(pop)
+#endif
struct links_entry {
struct links_entry *next;
diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index f35f0ea80bf3..2c1301ad57bb 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -302,8 +302,6 @@ struct file_info {
struct file_info *first;
struct file_info **last;
} rede_files;
- /* To check a ininity loop. */
- struct file_info *loop_by;
};
struct heap_queue {
@@ -1799,26 +1797,82 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
file->re = 0;
parent->subdirs--;
} else if (file->re) {
- /* This file's parent is not rr_moved, clear invalid
- * "RE" mark. */
- if (parent == NULL || parent->rr_moved == 0)
- file->re = 0;
- else if ((flags & 0x02) == 0) {
- file->rr_moved_has_re_only = 0;
- file->re = 0;
+ /*
+ * Sanity check: file's parent is rr_moved.
+ */
+ if (parent == NULL || parent->rr_moved == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge RE");
+ return (NULL);
+ }
+ /*
+ * Sanity check: file does not have "CL" extension.
+ */
+ if (file->cl_offset) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge RE and CL");
+ return (NULL);
+ }
+ /*
+ * Sanity check: The file type must be a directory.
+ */
+ if ((flags & 0x02) == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge RE");
+ return (NULL);
}
} else if (parent != NULL && parent->rr_moved)
file->rr_moved_has_re_only = 0;
else if (parent != NULL && (flags & 0x02) &&
(parent->re || parent->re_descendant))
file->re_descendant = 1;
- if (file->cl_offset != 0) {
+ if (file->cl_offset) {
+ struct file_info *p;
+
+ if (parent == NULL || parent->parent == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
+ /*
+ * Sanity check: The file type must be a regular file.
+ */
+ if ((flags & 0x02) != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
parent->subdirs++;
/* Overwrite an offset and a number of this "CL" entry
* to appear before other dirs. "+1" to those is to
* make sure to appear after "RE" entry which this
* "CL" entry should be connected with. */
file->offset = file->number = file->cl_offset + 1;
+
+ /*
+ * Sanity check: cl_offset does not point at its
+ * the parents or itself.
+ */
+ for (p = parent; p; p = p->parent) {
+ if (p->offset == file->cl_offset) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
+ }
+ if (file->cl_offset == file->offset ||
+ parent->rr_moved) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
}
}
@@ -1922,6 +1976,13 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
*/
break;
}
+ if (p[0] == 'P' && p[1] == 'L') {
+ /*
+ * PL extension won't appear;
+ * contents are always ignored.
+ */
+ break;
+ }
if (p[0] == 'P' && p[1] == 'N') {
if (version == 1 && data_length == 16) {
file->rdev = toi(data,4);
@@ -2697,15 +2758,12 @@ rede_add_entry(struct file_info *file)
{
struct file_info *re;
+ /*
+ * Find "RE" entry.
+ */
re = file->parent;
- while (re != NULL && !re->re) {
- /* Sanity check to prevent a infinity loop
- * cause by a currupted iso file. */
- if (re->loop_by == file)
- return (-1);
- re->loop_by = file;
+ while (re != NULL && !re->re)
re = re->parent;
- }
if (re == NULL)
return (-1);
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 207915708343..572cc58549ec 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -128,6 +128,7 @@ static int archive_read_format_zip_read_data(struct archive_read *,
static int archive_read_format_zip_read_data_skip(struct archive_read *a);
static int archive_read_format_zip_read_header(struct archive_read *,
struct archive_entry *);
+static int search_next_signature(struct archive_read *);
static int zip_read_data_deflate(struct archive_read *a, const void **buff,
size_t *size, off_t *offset);
static int zip_read_data_none(struct archive_read *a, const void **buff,
@@ -317,10 +318,17 @@ archive_read_format_zip_read_header(struct archive_read *a,
signature = (const char *)h;
}
+ /* If we don't see a PK signature here, scan forward. */
if (signature[0] != 'P' || signature[1] != 'K') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad ZIP file");
- return (ARCHIVE_FATAL);
+ r = search_next_signature(a);
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad ZIP file");
+ return (ARCHIVE_FATAL);
+ }
+ if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ signature = (const char *)h;
}
/*
@@ -375,6 +383,42 @@ archive_read_format_zip_read_header(struct archive_read *a,
}
static int
+search_next_signature(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip;
+ ssize_t bytes;
+ int64_t skipped = 0;
+
+ for (;;) {
+ h = __archive_read_ahead(a, 4, &bytes);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ q = p + bytes;
+
+ while (p + 4 <= q) {
+ if (p[0] == 'P' && p[1] == 'K') {
+ if ((p[2] == '\001' && p[3] == '\002')
+ || (p[2] == '\003' && p[3] == '\004')
+ || (p[2] == '\005' && p[3] == '\006')
+ || (p[2] == '\007' && p[3] == '\010')
+ || (p[2] == '0' && p[3] == '0')) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ }
+ ++p;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ skipped += skip;
+ }
+}
+
+static int
zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
struct zip *zip)
{
@@ -888,6 +932,9 @@ process_extra(const void* extra, struct zip* zip)
if (datasize >= 4)
zip->gid = archive_le16dec(p + offset + 2);
break;
+ case 0x7875:
+ /* Info-Zip Unix Extra Field (type 3) "ux". */
+ break;
default:
break;
}
diff --git a/libarchive/archive_util.3 b/libarchive/archive_util.3
index 98609e565a71..6570902c39af 100644
--- a/libarchive/archive_util.3
+++ b/libarchive/archive_util.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_util.3 201098 2009-12-28 02:58:14Z kientzle $
.\"
.Dd January 8, 2005
-.Dt archive_util 3
+.Dt ARCHIVE_UTIL 3
.Os
.Sh NAME
.Nm archive_clear_error ,
diff --git a/libarchive/archive_virtual.c b/libarchive/archive_virtual.c
index a5c0b39b9cc1..836886270f9f 100644
--- a/libarchive/archive_virtual.c
+++ b/libarchive/archive_virtual.c
@@ -42,26 +42,35 @@ archive_read_close(struct archive *a)
return ((a->vtable->archive_close)(a));
}
-#if ARCHIVE_API_VERSION > 1
int
-archive_write_finish(struct archive *a)
+archive_write_free(struct archive *a)
{
- return ((a->vtable->archive_finish)(a));
+ return ((a->vtable->archive_free)(a));
}
-#else
-/* Temporarily allow library to compile with either 1.x or 2.0 API. */
-void
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* For backwards compatibility; will be removed with libarchive 4.0. */
+int
archive_write_finish(struct archive *a)
{
- (void)(a->vtable->archive_finish)(a);
+ return ((a->vtable->archive_free)(a));
}
#endif
int
+archive_read_free(struct archive *a)
+{
+ return ((a->vtable->archive_free)(a));
+}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* For backwards compatibility; will be removed with libarchive 4.0. */
+int
archive_read_finish(struct archive *a)
{
- return ((a->vtable->archive_finish)(a));
+ return ((a->vtable->archive_free)(a));
}
+#endif
int
archive_write_header(struct archive *a, struct archive_entry *entry)
@@ -76,12 +85,7 @@ archive_write_finish_entry(struct archive *a)
return ((a->vtable->archive_write_finish_entry)(a));
}
-#if ARCHIVE_API_VERSION > 1
ssize_t
-#else
-/* Temporarily allow library to compile with either 1.x or 2.0 API. */
-int
-#endif
archive_write_data(struct archive *a, const void *buff, size_t s)
{
return ((a->vtable->archive_write_data)(a, buff, s));
diff --git a/libarchive/archive_write.3 b/libarchive/archive_write.3
index ffe0c9b45f0c..6534128b0c98 100644
--- a/libarchive/archive_write.3
+++ b/libarchive/archive_write.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
.Dd May 11, 2008
-.Dt archive_write 3
+.Dt ARCHIVE_WRITE 3
.Os
.Sh NAME
.Nm archive_write_new ,
@@ -55,7 +55,7 @@
.Nm archive_write_data ,
.Nm archive_write_finish_entry ,
.Nm archive_write_close ,
-.Nm archive_write_finish
+.Nm archive_write_free
.Nd functions for creating archives
.Sh SYNOPSIS
.In archive.h
@@ -125,7 +125,7 @@
.Ft int
.Fn archive_write_close "struct archive *"
.Ft int
-.Fn archive_write_finish "struct archive *"
+.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating streaming
archive files.
@@ -363,16 +363,16 @@ and
as needed.
.It Fn archive_write_close
Complete the archive and invoke the close callback.
-.It Fn archive_write_finish
+.It Fn archive_write_free
Invokes
.Fn archive_write_close
-if it was not invoked manually, then releases all resources.
-Note that this function was declared to return
-.Ft void
-in libarchive 1.x, which made it impossible to detect errors when
+if necessary, then releases all resources.
+If you need detailed information about
.Fn archive_write_close
-was invoked implicitly from this function.
-This is corrected beginning with libarchive 2.0.
+failures, you should be careful to call it separately, as
+you cannot obtain error information after
+.Fn archive_write_free
+returns.
.El
More information about the
.Va struct archive
@@ -529,7 +529,7 @@ write_archive(const char *outname, const char **filename)
archive_entry_free(entry);
filename++;
}
- archive_write_finish(a);
+ archive_write_free(a);
}
int main(int argc, const char **argv)
@@ -580,7 +580,7 @@ may include
.Fn archive_write_data ,
.Fn archive_write_close ,
or
-.Fn archive_write_finish .
+.Fn archive_write_free .
The client callback can call
.Fn archive_set_error
to provide values that can then be retrieved by
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index e0d942b0754f..eba7227221a2 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -60,7 +60,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:
static struct archive_vtable *archive_write_vtable(void);
static int _archive_write_close(struct archive *);
-static int _archive_write_finish(struct archive *);
+static int _archive_write_free(struct archive *);
static int _archive_write_header(struct archive *, struct archive_entry *);
static int _archive_write_finish_entry(struct archive *);
static ssize_t _archive_write_data(struct archive *, const void *, size_t);
@@ -73,7 +73,7 @@ archive_write_vtable(void)
if (!inited) {
av.archive_close = _archive_write_close;
- av.archive_finish = _archive_write_finish;
+ av.archive_free = _archive_write_free;
av.archive_write_header = _archive_write_header;
av.archive_write_finish_entry = _archive_write_finish_entry;
av.archive_write_data = _archive_write_data;
@@ -383,13 +383,13 @@ _archive_write_close(struct archive *_a)
* Destroy the archive structure.
*/
static int
-_archive_write_finish(struct archive *_a)
+_archive_write_free(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
int r = ARCHIVE_OK;
__archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_finish");
+ ARCHIVE_STATE_ANY, "archive_write_free");
if (a->archive.state != ARCHIVE_STATE_CLOSED)
r = archive_write_close(&a->archive);
diff --git a/libarchive/archive_write_disk.3 b/libarchive/archive_write_disk.3
index 5ed4a5038f18..d7fed6d5ef27 100644
--- a/libarchive/archive_write_disk.3
+++ b/libarchive/archive_write_disk.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: src/lib/libarchive/archive_write_disk.3,v 1.4 2008/09/04 05:22:00 kientzle Exp $
.\"
.Dd August 5, 2008
-.Dt archive_write_disk 3
+.Dt ARCHIVE_WRITE_DISK 3
.Os
.Sh NAME
.Nm archive_write_disk_new ,
@@ -38,7 +38,7 @@
.Nm archive_write_data ,
.Nm archive_write_finish_entry ,
.Nm archive_write_close ,
-.Nm archive_write_finish
+.Nm archive_write_free
.Nd functions for creating objects on disk
.Sh SYNOPSIS
.In archive.h
@@ -73,7 +73,7 @@
.Ft int
.Fn archive_write_close "struct archive *"
.Ft int
-.Fn archive_write_finish "struct archive *"
+.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating objects on
disk from
@@ -239,7 +239,7 @@ The
.Nm
library maintains a list of all such deferred attributes and
sets them when this function is invoked.
-.It Fn archive_write_finish
+.It Fn archive_write_free
Invokes
.Fn archive_write_close
if it was not invoked manually, then releases all resources.
@@ -339,7 +339,7 @@ In particular, the directory
.Pa aa
is created as well as the final object
.Pa bb .
-In theory, this can be exploited to create an entire directory heirarchy
+In theory, this can be exploited to create an entire directory hierarchy
with a single request.
Of course, this does not work if the
.Cm ARCHIVE_EXTRACT_NODOTDOT
@@ -371,5 +371,5 @@ compact implementation when appropriate.
.Pp
There should be a corresponding
.Nm archive_read_disk
-interface that walks a directory heirarchy and returns archive
+interface that walks a directory hierarchy and returns archive
entry objects. \ No newline at end of file
diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c
index 7d9a43d8897b..6518807ba063 100644
--- a/libarchive/archive_write_disk.c
+++ b/libarchive/archive_write_disk.c
@@ -252,7 +252,7 @@ static ssize_t write_data_block(struct archive_write_disk *,
static struct archive_vtable *archive_write_disk_vtable(void);
static int _archive_write_close(struct archive *);
-static int _archive_write_finish(struct archive *);
+static int _archive_write_free(struct archive *);
static int _archive_write_header(struct archive *, struct archive_entry *);
static int _archive_write_finish_entry(struct archive *);
static ssize_t _archive_write_data(struct archive *, const void *, size_t);
@@ -291,7 +291,7 @@ archive_write_disk_vtable(void)
if (!inited) {
av.archive_close = _archive_write_close;
- av.archive_finish = _archive_write_finish;
+ av.archive_free = _archive_write_free;
av.archive_write_header = _archive_write_header;
av.archive_write_finish_entry = _archive_write_finish_entry;
av.archive_write_data = _archive_write_data;
@@ -1295,7 +1295,7 @@ _archive_write_close(struct archive *_a)
}
static int
-_archive_write_finish(struct archive *_a)
+_archive_write_free(struct archive *_a)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
int ret;
diff --git a/libarchive/archive_write_set_format_cpio.c b/libarchive/archive_write_set_format_cpio.c
index 4e8e1e0bdcab..b64b1cb06e27 100644
--- a/libarchive/archive_write_set_format_cpio.c
+++ b/libarchive/archive_write_set_format_cpio.c
@@ -62,6 +62,11 @@ struct cpio {
size_t ino_list_next;
};
+#ifdef _MSC_VER
+#define __packed
+#pragma pack(push, 1)
+#endif
+
struct cpio_header {
char c_magic[6];
char c_dev[6];
@@ -74,7 +79,12 @@ struct cpio_header {
char c_mtime[11];
char c_namesize[6];
char c_filesize[11];
-};
+} __packed;
+
+#ifdef _MSC_VER
+#undef __packed
+#pragma pack(pop)
+#endif
/*
* Set output format to 'cpio' format.
diff --git a/libarchive/cpio.5 b/libarchive/cpio.5
index f54462818ae2..13a4445b72e7 100644
--- a/libarchive/cpio.5
+++ b/libarchive/cpio.5
@@ -268,31 +268,6 @@ data, including ACLs and extended attributes, as special
entries in cpio archives.
.Pp
XXX Others? XXX
-.Sh BUGS
-The
-.Dq CRC
-format is mis-named, as it uses a simple checksum and
-not a cyclic redundancy check.
-.Pp
-The old binary format is limited to 16 bits for user id,
-group id, device, and inode numbers.
-It is limited to 4 gigabyte file sizes.
-.Pp
-The old ASCII format is limited to 18 bits for
-the user id, group id, device, and inode numbers.
-It is limited to 8 gigabyte file sizes.
-.Pp
-The new ASCII format is limited to 4 gigabyte file sizes.
-.Pp
-None of the cpio formats store user or group names,
-which are essential when moving files between systems with
-dissimilar user or group numbering.
-.Pp
-Especially when writing older cpio variants, it may be necessary
-to map actual device/inode values to synthesized values that
-fit the available fields.
-With very large filesystems, this may be necessary even for
-the newer formats.
.Sh SEE ALSO
.Xr cpio 1 ,
.Xr tar 5
@@ -323,3 +298,28 @@ license.
The character format was adopted as part of
.St -p1003.1-88 .
XXX when did "newc" appear? Who invented it? When did HP come out with their variant? When did Sun introduce ACLs and extended attributes? XXX
+.Sh BUGS
+The
+.Dq CRC
+format is mis-named, as it uses a simple checksum and
+not a cyclic redundancy check.
+.Pp
+The old binary format is limited to 16 bits for user id,
+group id, device, and inode numbers.
+It is limited to 4 gigabyte file sizes.
+.Pp
+The old ASCII format is limited to 18 bits for
+the user id, group id, device, and inode numbers.
+It is limited to 8 gigabyte file sizes.
+.Pp
+The new ASCII format is limited to 4 gigabyte file sizes.
+.Pp
+None of the cpio formats store user or group names,
+which are essential when moving files between systems with
+dissimilar user or group numbering.
+.Pp
+Especially when writing older cpio variants, it may be necessary
+to map actual device/inode values to synthesized values that
+fit the available fields.
+With very large filesystems, this may be necessary even for
+the newer formats.
diff --git a/libarchive/libarchive-formats.5 b/libarchive/libarchive-formats.5
index 0acdb50c2bd0..0bc275b5189d 100644
--- a/libarchive/libarchive-formats.5
+++ b/libarchive/libarchive-formats.5
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/libarchive-formats.5 201077 2009-12-28 01:50:23Z kientzle $
.\"
.Dd December 27, 2009
-.Dt libarchive-formats 5
+.Dt LIBARCHIVE-FORMATS 5
.Os
.Sh NAME
.Nm libarchive-formats
diff --git a/libarchive/libarchive.3 b/libarchive/libarchive.3
index 8c19d008a90f..bdab54b43dc1 100644
--- a/libarchive/libarchive.3
+++ b/libarchive/libarchive.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD: src/lib/libarchive/libarchive.3,v 1.11 2007/01/09 08:05:56 kientzle Exp $
.\"
-.Dd August 19, 2006
+.Dd July 17, 2010
.Dt LIBARCHIVE 3
.Os
.Sh NAME
@@ -61,13 +61,14 @@ GNU-format tar archives,
.It
most common cpio archive formats,
.It
-ISO9660 CD images (with or without RockRidge extensions),
+ISO9660 CD images (including RockRidge and Joliet extensions),
.It
Zip archives.
.El
The library automatically detects archives compressed with
.Xr gzip 1 ,
.Xr bzip2 1 ,
+.Xr xz 1 ,
or
.Xr compress 1
and decompresses them transparently.
@@ -87,6 +88,8 @@ archives,
.It
POSIX octet-oriented cpio archives,
.It
+Zip archive,
+.It
two different variants of shar archives.
.El
Pax interchange format is an extension of the tar archive format that
@@ -168,12 +171,12 @@ You can use
(which works much like the
.Xr read 2
system call)
-to read this data from the archive.
+to read this data from the archive, or
+.Fn archive_read_data_block
+which provides a slightly more efficient interface.
You may prefer to use the higher-level
.Fn archive_read_data_skip ,
which reads and discards the data for this entry,
-.Fn archive_read_data_to_buffer ,
-which reads the data into an in-memory buffer,
.Fn archive_read_data_to_file ,
which copies the data to the provided file descriptor, or
.Fn archive_read_extract ,
@@ -192,7 +195,7 @@ Once you have finished reading data from the archive, you
should call
.Fn archive_read_close
to close the archive, then call
-.Fn archive_read_finish
+.Fn archive_read_free
to release all resources, including all memory allocated by the library.
.Pp
The
@@ -230,12 +233,34 @@ You can then use
to write the actual data.
.Pp
After all entries have been written, use the
-.Fn archive_write_finish
+.Fn archive_write_free
function to release all resources.
.Pp
The
.Xr archive_write 3
manual page provides more detailed calling information for this API.
+.Sh WRITING ENTRIES TO DISK
+The
+.Xr archive_write_disk 3
+API allows you to write
+.Xr archive_entry 3
+objects to disk using the same API used by
+.Xr archive_write 3 .
+The
+.Xr archive_write_disk 3
+API is used internally by
+.Fn archive_read_extract ;
+using it directly can provide greater control over how entries
+get written to disk.
+This API also makes it possible to share code between
+archive-to-archive copy and archive-to-disk extraction
+operations.
+.Sh READING ENTRIES FROM DISK
+The
+.Xr archive_read_disk 3
+provides some support for populating
+.Xr archive_entry 3
+objects from information in the filesystem.
.Sh DESCRIPTION
Detailed descriptions of each function are provided by the
corresponding manual pages.
@@ -259,7 +284,9 @@ In particular, pax interchange format can easily accommodate pathnames
in arbitrary character sets that exceed
.Va PATH_MAX .
.Sh RETURN VALUES
-Most functions return zero on success, non-zero on error.
+Most functions return
+.Cm ARCHIVE_OK
+(zero) on success, non-zero on error.
The return value indicates the general severity of the error, ranging
from
.Cm ARCHIVE_WARN ,
@@ -329,3 +356,14 @@ stored in an
is supported by all formats.
For example, cpio formats do not support nanosecond timestamps;
old tar formats do not support large device numbers.
+.Pp
+The
+.Xr archive_read_disk 3
+API should support iterating over filesystems;
+that would make it possible to share code among
+disk-to-archive, archive-to-archive, archive-to-disk,
+and disk-to-disk operations.
+Currently, it only supports reading the
+information for a single file.
+(Which is still quite useful, as it hides a lot
+of system-specific details.)
diff --git a/libarchive/tar.5 b/libarchive/tar.5
index aafd535a1a58..143d3508328f 100644
--- a/libarchive/tar.5
+++ b/libarchive/tar.5
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/tar.5 201077 2009-12-28 01:50:23Z kientzle $
.\"
.Dd December 27, 2009
-.Dt tar 5
+.Dt TAR 5
.Os
.Sh NAME
.Nm tar
diff --git a/libarchive/test/test_acl_freebsd.c b/libarchive/test/test_acl_freebsd.c
index be502067f5fe..c684a7ae9e81 100644
--- a/libarchive/test/test_acl_freebsd.c
+++ b/libarchive/test/test_acl_freebsd.c
@@ -220,6 +220,11 @@ DEFINE_TEST(test_acl_freebsd)
skipping("ACL tests require that ACL support be enabled on the filesystem");
return;
}
+ if (n != 0 && errno == EINVAL) {
+ close(fd);
+ skipping("POSIX.1e ACL tests require that POSIX.1e ACL support be enabled on the filesystem");
+ return;
+ }
failure("acl_set_fd(): errno = %d (%s)",
errno, strerror(errno));
assertEqualInt(0, n);
diff --git a/libarchive/test/test_compat_zip.c b/libarchive/test/test_compat_zip.c
index d8bc4de36080..c6916cbbda6c 100644
--- a/libarchive/test/test_compat_zip.c
+++ b/libarchive/test/test_compat_zip.c
@@ -71,10 +71,43 @@ finish:
#endif
}
+/*
+ * Verify that we skip junk between entries. The compat_zip_2.zip file
+ * has several bytes of junk between 'file1' and 'file2'. Such
+ * junk is routinely introduced by some Zip writers when they manipulate
+ * existing zip archives.
+ */
+static void
+test_compat_zip_2(void)
+{
+ char name[] = "test_compat_zip_2.zip";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
+
+ /* Read first entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+
+ /* Read first entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
DEFINE_TEST(test_compat_zip)
{
test_compat_zip_1();
+ test_compat_zip_2();
}
diff --git a/libarchive/test/test_compat_zip_2.zip.uu b/libarchive/test/test_compat_zip_2.zip.uu
new file mode 100644
index 000000000000..c33e9d99e2e2
--- /dev/null
+++ b/libarchive/test/test_compat_zip_2.zip.uu
@@ -0,0 +1,10 @@
+$FreeBSD$
+
+begin 644 test_compat_zip_2.zip
+M4$L#!`H``````'V59CT````````````````%````9FEL93$M2E5.2RU02P,$
+M"@``````@95F/<>D!,D&````!@````4```!F:6QE,F9I;&4R"E!+`0(>`PH`
+M`````'V59CT````````````````%``````````````"D@0````!F:6QE,5!+
+M`0(>`PH``````(&59CW'I`3)!@````8````%``````````````"D@2D```!F
+::6QE,E!+!08``````@`"`&8```!2````````
+`
+end