diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index 17cb5d90bfdb..4ffff1bb14a9 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -7,9 +7,10 @@ LIB= archive -SHLIB_MAJOR= 1 -VERSION= 1.00.009 -ARCHIVE_API_FEATURE= 1 +VERSION= 1.01.010 +ARCHIVE_API_FEATURE= 2 +ARCHIVE_API_VERSION= 1 +SHLIB_MAJOR= ${ARCHIVE_API_VERSION} CFLAGS+= -DPACKAGE_NAME=\"lib${LIB}\" CFLAGS+= -DPACKAGE_VERSION=\"${VERSION}\" CFLAGS+= -I${.OBJDIR} @@ -182,7 +183,7 @@ CLEANFILES+= archive.h # Build archive.h from archive.h.in archive.h: archive.h.in Makefile cat ${.CURDIR}/archive.h.in | \ - sed 's/@ARCHIVE_API_VERSION@/${SHLIB_MAJOR}/' | \ + sed 's/@ARCHIVE_API_VERSION@/${ARCHIVE_API_VERSION}/' | \ sed 's/@ARCHIVE_API_FEATURE@/${ARCHIVE_API_FEATURE}/' | \ cat > archive.h diff --git a/lib/libarchive/archive.h.in b/lib/libarchive/archive.h.in index 0a79200322ac..52603437eb6a 100644 --- a/lib/libarchive/archive.h.in +++ b/lib/libarchive/archive.h.in @@ -41,7 +41,8 @@ * the features you're relying on. Specific values of FEATURE are * documented here: * - * 1 - Version test is available. + * 1 - Version tests are available. + * 2 - archive_{read,write}_close available separately from _finish. */ #define ARCHIVE_API_VERSION @ARCHIVE_API_VERSION@ int archive_api_version(void); @@ -138,7 +139,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data); * 4) Repeatedly call archive_read_next_header to get information about * successive archive entries. Call archive_read_data to extract * data for entries of interest. - * 5) Call archive_read_finish to destroy the object. + * 5) Call archive_read_finish to end processing. */ struct archive *archive_read_new(void); @@ -237,7 +238,10 @@ int archive_read_extract(struct archive *, struct archive_entry *, void archive_read_extract_set_progress_callback(struct archive *, void (*_progress_func)(void *), void *_user_data); -/* Close the file, release any resources, and destroy the object. */ +/* Close the file and release most resources. */ +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. */ void archive_read_finish(struct archive *); /*- @@ -250,7 +254,8 @@ void archive_read_finish(struct archive *); * - construct an appropriate struct archive_entry structure * - archive_write_header to write the header * - archive_write_data to write the entry data - * 5) archive_write_finish to close the output and cleanup the writer + * 5) archive_write_close to close the output + * 6) archive_write_finish to cleanup the writer and release resources */ struct archive *archive_write_new(void); int archive_write_set_bytes_per_block(struct archive *, @@ -287,6 +292,7 @@ int archive_write_open_file(struct archive *, const char *_file); int archive_write_header(struct archive *, struct archive_entry *); int archive_write_data(struct archive *, const void *, size_t); +int archive_write_close(struct archive *); void archive_write_finish(struct archive *); /* diff --git a/lib/libarchive/archive_read.3 b/lib/libarchive/archive_read.3 index 11ec7e849868..f42838c98717 100644 --- a/lib/libarchive/archive_read.3 +++ b/lib/libarchive/archive_read.3 @@ -49,6 +49,7 @@ .Nm archive_read_data_into_fd , .Nm archive_read_extract , .Nm archive_read_extract_set_progress_callback , +.Nm archive_read_close .Nm archive_read_finish .Nd functions for reading tar archives .Sh SYNOPSIS @@ -95,6 +96,8 @@ .Fn archive_read_extract "struct archive *" "int flags" .Ft void .Fn archive_read_extract_set_progress_callback "struct archive *" "void (*func)(void *)" "void *user_data" +.Ft int +.Fn archive_read_close "struct archive *" .Ft void .Fn archive_read_finish "struct archive *" .Sh DESCRIPTION @@ -231,9 +234,12 @@ The progress function will be invoked with the pointer provided to this call. Generally, the data pointed to should include a reference to the archive 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 -Complete the archive, invoke the close callback, and release -all resources. +Invokes +.Fn archive_read_close +if it wasn't invoked maually, then release all resources. .El .Pp Note that the library determines most of the relevant information about diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c index b68b5a608466..2f9a998e4214 100644 --- a/lib/libarchive/archive_read.c +++ b/lib/libarchive/archive_read.c @@ -441,18 +441,15 @@ archive_read_data_block(struct archive *a, } /* - * Cleanup and free the archive object. + * Close the file and release most resources. * * Be careful: client might just call read_new and then read_finish. * Don't assume we actually read anything or performed any non-trivial * initialization. */ -void -archive_read_finish(struct archive *a) +int +archive_read_close(struct archive *a) { - int i; - int slots; - archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY); a->state = ARCHIVE_STATE_CLOSED; @@ -465,6 +462,21 @@ archive_read_finish(struct archive *a) /* Close the input machinery. */ if (a->compression_finish != NULL) (a->compression_finish)(a); + return (ARCHIVE_OK); +} + +/* + * Release memory and other resources. + */ +void +archive_read_finish(struct archive *a) +{ + int i; + int slots; + + archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY); + if (a->state != ARCHIVE_STATE_CLOSED) + archive_read_close(a); /* Cleanup format-specific data. */ slots = sizeof(a->formats) / sizeof(a->formats[0]); diff --git a/lib/libarchive/archive_write.3 b/lib/libarchive/archive_write.3 index ee1bdc93cb2e..b7af9d56ca75 100644 --- a/lib/libarchive/archive_write.3 +++ b/lib/libarchive/archive_write.3 @@ -45,6 +45,7 @@ .Nm archive_write_prepare , .Nm archive_write_header , .Nm archive_write_data , +.Nm archive_write_close , .Nm archive_write_finish .Nd functions for creating archives .Sh SYNOPSIS @@ -82,6 +83,8 @@ .Ft int .Fn archive_write_data "struct archive *" "const void *" "size_t" .Ft int +.Fn archive_write_close "struct archive *" +.Ft void .Fn archive_write_finish "struct archive *" .Sh DESCRIPTION These functions provide a complete API for creating streaming @@ -187,9 +190,12 @@ Build and write a header using the data in the provided structure. .It Fn archive_write_data Write data corresponding to the header just written. +.It Fn archive_write_close +Complete the archive and invoke the close callback. .It Fn archive_write_finish -Complete the archive, invoke the close callback, and release -all resources. +Invokes +.Fn archive_write_close +if it wasn't invoked manually, then release all resources. .El .Pp The callback functions are defined as follows: @@ -321,7 +327,7 @@ may include .Fn archive_write_header , .Fn archive_write_data , or -.Fn archive_write_finish . +.Fn archive_write_close . In such a case, the .Fn archive_errno or diff --git a/lib/libarchive/archive_write.c b/lib/libarchive/archive_write.c index eded384b758a..d3dfc26c61a4 100644 --- a/lib/libarchive/archive_write.c +++ b/lib/libarchive/archive_write.c @@ -141,14 +141,14 @@ archive_write_open(struct archive *a, void *client_data, /* - * Cleanup and free the archive object. + * Close out the archive. * * Be careful: user might just call write_new and then write_finish. * Don't assume we actually wrote anything or performed any non-trivial * initialization. */ -void -archive_write_finish(struct archive *a) +int +archive_write_close(struct archive *a) { archive_check_magic(a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY); @@ -164,6 +164,20 @@ archive_write_finish(struct archive *a) if (a->compression_finish != NULL) (a->compression_finish)(a); + a->state = ARCHIVE_STATE_CLOSED; + return (ARCHIVE_OK); +} + +/* + * Destroy the archive structure. + */ +void +archive_write_finish(struct archive *a) +{ + archive_check_magic(a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY); + if (a->state != ARCHIVE_STATE_CLOSED) + archive_write_close(a); + /* Release various dynamic buffers. */ free((void *)(uintptr_t)(const void *)a->nulls); archive_string_free(&a->error_string);