diff options
author | Martin Matuska <mm@FreeBSD.org> | 2011-12-26 22:25:58 +0000 |
---|---|---|
committer | Martin Matuska <mm@FreeBSD.org> | 2011-12-26 22:25:58 +0000 |
commit | 7691a6970b48b047c4290c0837e91dcab450db90 (patch) | |
tree | 15e9d164982e84a4b77c51d3cea2c450f6ec4ad1 /libarchive | |
parent | 4b16b4e80ed599fbac3f6e4427cd9fbb43d1ea1a (diff) | |
download | src-7691a6970b48b047c4290c0837e91dcab450db90.tar.gz src-7691a6970b48b047c4290c0837e91dcab450db90.zip |
Update to vendor revision 3982
Obtained from: http://libarchive.googlecode.com/svn/release/2.8
Notes
Notes:
svn path=/vendor/libarchive/dist/; revision=228905
Diffstat (limited to 'libarchive')
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 |