From 5268756cc2ec80029799d0a8ba06614f7584f00b Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 3 Aug 2008 12:46:13 -0400 Subject: [PATCH] IFC SVN-Revision: 176 --- cpio/Makefile | 2 +- cpio/cmdline.c | 3 +- cpio/config_freebsd.h | 2 +- cpio/cpio.c | 5 +- cpio/cpio.h | 3 +- libarchive/archive_read_support_format_tar.c | 4 +- libarchive/archive_read_support_format_zip.c | 22 ++-- libarchive/archive_write_disk.c | 2 +- libarchive/config_freebsd.h | 2 +- libarchive/test/Makefile | 14 +-- libarchive/test/test_compat_gtar_1.tgz.uu | 1 + libarchive/test/test_compat_zip_1.zip.uu | 1 + .../test/test_pax_filename_encoding.tar.gz.uu | 1 + .../test_read_format_gtar_sparse_1_13.tgz.uu | 1 + .../test_read_format_gtar_sparse_1_17.tgz.uu | 1 + ...ead_format_gtar_sparse_1_17_posix00.tgz.uu | 1 + ...ead_format_gtar_sparse_1_17_posix01.tgz.uu | 1 + ...ead_format_gtar_sparse_1_17_posix10.tgz.uu | 1 + ...t_gtar_sparse_1_17_posix10_modified.tar.uu | 1 + ...test_read_format_tar_empty_filename.tar.uu | 1 + libarchive/test/test_read_format_zip.c | 7 +- tar/Makefile | 2 +- tar/bsdtar.1 | 9 +- tar/bsdtar.h | 3 +- tar/config_freebsd.h | 2 +- tar/read.c | 2 +- tar/write.c | 111 ++++++++---------- 27 files changed, 114 insertions(+), 91 deletions(-) diff --git a/cpio/Makefile b/cpio/Makefile index aca098467..31463b029 100644 --- a/cpio/Makefile +++ b/cpio/Makefile @@ -1,4 +1,4 @@ -# $FreeBSD: src/usr.bin/cpio/Makefile,v 1.4 2008/06/16 07:24:05 dougb Exp $ +# $FreeBSD: src/usr.bin/cpio/Makefile,v 1.5 2008/07/05 05:17:33 kientzle Exp $ .include diff --git a/cpio/cmdline.c b/cpio/cmdline.c index a602e39c1..d51d7e731 100644 --- a/cpio/cmdline.c +++ b/cpio/cmdline.c @@ -26,7 +26,7 @@ #include "cpio_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.3 2008/06/21 02:20:20 kientzle Exp $"); +__FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.4 2008/07/29 15:23:31 kientzle Exp $"); #ifdef HAVE_ERRNO_H #include @@ -91,6 +91,7 @@ static const struct option cpio_longopts[] = { { "link", no_argument, NULL, 'l' }, { "list", no_argument, NULL, 't' }, { "make-directories", no_argument, NULL, 'd' }, + { "no-preserve-owner", no_argument, NULL, OPTION_NO_PRESERVE_OWNER }, { "null", no_argument, NULL, '0' }, { "owner", required_argument, NULL, 'R' }, { "pass-through", no_argument, NULL, 'p' }, diff --git a/cpio/config_freebsd.h b/cpio/config_freebsd.h index 992c850f9..25a8b5967 100644 --- a/cpio/config_freebsd.h +++ b/cpio/config_freebsd.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/usr.bin/cpio/config_freebsd.h,v 1.2 2008/07/05 05:15:07 kientzle Exp $ */ /* A default configuration for FreeBSD, used if there is no config.h. */ diff --git a/cpio/cpio.c b/cpio/cpio.c index b889a16fa..ee932c975 100644 --- a/cpio/cpio.c +++ b/cpio/cpio.c @@ -26,7 +26,7 @@ #include "cpio_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.4 2008/06/24 15:18:40 kientzle Exp $"); +__FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.10 2008/07/30 03:35:45 kientzle Exp $"); #include #include @@ -176,6 +176,9 @@ main(int argc, char *argv[]) case 'm': /* POSIX 1997 */ cpio->extract_flags |= ARCHIVE_EXTRACT_TIME; break; + case OPTION_NO_PRESERVE_OWNER: /* GNU cpio */ + cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; + break; case 'O': /* GNU cpio */ cpio->filename = optarg; break; diff --git a/cpio/cpio.h b/cpio/cpio.h index 3afd95203..80a89cc89 100644 --- a/cpio/cpio.h +++ b/cpio/cpio.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/usr.bin/cpio/cpio.h,v 1.2 2008/06/21 02:20:20 kientzle Exp $ + * $FreeBSD: src/usr.bin/cpio/cpio.h,v 1.3 2008/07/29 15:23:31 kientzle Exp $ */ #ifndef CPIO_H_INCLUDED @@ -94,6 +94,7 @@ int owner_parse(const char *, int *, int *); /* Fake short equivalents for long options that otherwise lack them. */ enum { OPTION_INSECURE = 1, + OPTION_NO_PRESERVE_OWNER, OPTION_QUIET, OPTION_VERSION }; diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c index 0c2f0077c..4ebe57aa7 100644 --- a/libarchive/archive_read_support_format_tar.c +++ b/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.69 2008/05/27 04:46:12 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.70 2008/07/10 09:50:55 cperciva Exp $"); #ifdef HAVE_ERRNO_H #include @@ -2161,7 +2161,6 @@ utf8_decode(struct tar *tar, const char *src, size_t length) { wchar_t *dest; ssize_t n; - int err; /* Ensure pax_entry buffer is big enough. */ if (tar->pax_entry_length <= length) { @@ -2183,7 +2182,6 @@ utf8_decode(struct tar *tar, const char *src, size_t length) } dest = tar->pax_entry; - err = 0; while (length > 0) { n = UTF8_mbrtowc(dest, src, length); if (n < 0) diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index f04f69bb2..ed4f58ff6 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/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.24 2008/06/15 05:15:53 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.26 2008/06/30 16:19:26 des Exp $"); #ifdef HAVE_ERRNO_H #include @@ -53,6 +53,9 @@ struct zip { int64_t entry_compressed_bytes_read; int64_t entry_uncompressed_bytes_read; + /* Running CRC32 of the decompressed data */ + unsigned long entry_crc32; + unsigned version; unsigned system; unsigned flags; @@ -70,7 +73,7 @@ struct zip { char end_of_entry; char end_of_entry_cleanup; - long crc32; + unsigned long crc32; ssize_t filename_length; ssize_t extra_length; int64_t uncompressed_size; @@ -299,6 +302,7 @@ archive_read_format_zip_read_header(struct archive_read *a, zip->end_of_entry_cleanup = 0; zip->entry_uncompressed_bytes_read = 0; zip->entry_compressed_bytes_read = 0; + zip->entry_crc32 = crc32(0, NULL, 0); if ((h = __archive_read_ahead(a, 4)) == NULL) return (ARCHIVE_FATAL); @@ -523,14 +527,13 @@ archive_read_format_zip_read_data(struct archive_read *a, "ZIP uncompressed data is wrong size"); return (ARCHIVE_WARN); } -/* TODO: Compute CRC. */ -/* - if (zip->crc32 != zip->entry_crc32_calculated) { + /* Check computed CRC against header */ + if (zip->crc32 != zip->entry_crc32) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ZIP data CRC error"); + "ZIP bad CRC: 0x%lx should be 0x%lx", + zip->entry_crc32, zip->crc32); return (ARCHIVE_WARN); } -*/ /* End-of-entry cleanup done. */ zip->end_of_entry_cleanup = 1; } @@ -570,6 +573,11 @@ archive_read_format_zip_read_data(struct archive_read *a, } break; } + /* Update checksum */ + if (r == ARCHIVE_OK && *size) { + zip->entry_crc32 = + crc32(zip->entry_crc32, *buff, *size); + } return (r); } diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index 5685a1cc2..44e721eb8 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -25,7 +25,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.26 2008/06/21 19:05:29 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.28 2008/07/05 01:48:33 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include diff --git a/libarchive/config_freebsd.h b/libarchive/config_freebsd.h index 4182b71df..5f2d5bcc7 100644 --- a/libarchive/config_freebsd.h +++ b/libarchive/config_freebsd.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/config_freebsd.h,v 1.10 2008/06/15 05:12:47 kientzle Exp $ + * $FreeBSD: src/lib/libarchive/config_freebsd.h,v 1.11 2008/07/05 01:50:07 kientzle Exp $ */ /* FreeBSD 5.0 and later have ACL support. */ diff --git a/libarchive/test/Makefile b/libarchive/test/Makefile index 0812ff44e..dfcf6fb88 100644 --- a/libarchive/test/Makefile +++ b/libarchive/test/Makefile @@ -1,4 +1,4 @@ -# $FreeBSD: src/lib/libarchive/test/Makefile,v 1.21 2008/06/15 05:05:53 kientzle Exp $ +# $FreeBSD: src/lib/libarchive/test/Makefile,v 1.23 2008/06/26 11:58:26 des Exp $ # Where to find the libarchive sources LA_SRCDIR=${.CURDIR}/.. @@ -72,7 +72,7 @@ TESTS= \ # Build the test program using all libarchive sources + the test sources. SRCS= ${LA_SRCS} \ ${TESTS} \ - ${.OBJDIR}/list.h \ + list.h \ main.c \ read_open_memory.c @@ -84,19 +84,19 @@ DPADD=${LIBBZ2} ${LIBZ} CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\" LDADD= -lz -lbz2 CFLAGS+= -static -g -CFLAGS+= -I${LA_SRCDIR} +CFLAGS+= -I${LA_SRCDIR} -I. # Uncomment to link against dmalloc -LDADD+= -L/usr/local/lib -ldmalloc -CFLAGS+= -I/usr/local/include -DUSE_DMALLOC -WARNS=6 +#LDADD+= -L/usr/local/lib -ldmalloc +#CFLAGS+= -I/usr/local/include -DUSE_DMALLOC +#WARNS=6 # Build libarchive_test and run it. check test: libarchive_test ./libarchive_test -v -r ${.CURDIR} # list.h is just a list of all tests, as indicated by DEFINE_TEST macro lines -${.OBJDIR}/list.h: ${TESTS} Makefile +list.h: ${TESTS} Makefile (cd ${.CURDIR}; cat ${TESTS}) | grep DEFINE_TEST > list.h CLEANFILES += *.out *.o *.core *~ list.h diff --git a/libarchive/test/test_compat_gtar_1.tgz.uu b/libarchive/test/test_compat_gtar_1.tgz.uu index f088a4a5f..d6fbeb8ae 100644 --- a/libarchive/test/test_compat_gtar_1.tgz.uu +++ b/libarchive/test/test_compat_gtar_1.tgz.uu @@ -1,3 +1,4 @@ +$FreeBSD: src/lib/libarchive/test/test_compat_gtar_1.tgz.uu,v 1.2 2008/07/03 03:26:30 peter Exp $ begin 644 test_compat_gtar_1.tgz M'XL(`,N`6T<``^W62PZ",!`&X!YE3@`SI:6Z'W+PJB)43=4 MJO^W:1.Z:#KYATG2)!T5]7Y95/N-Z@:UF)ZO7B9"-TPD[%@4%1W=Y\'IV$P. diff --git a/libarchive/test/test_compat_zip_1.zip.uu b/libarchive/test/test_compat_zip_1.zip.uu index e13a6cac2..29cdf96b0 100644 --- a/libarchive/test/test_compat_zip_1.zip.uu +++ b/libarchive/test/test_compat_zip_1.zip.uu @@ -1,3 +1,4 @@ +$FreeBSD: src/lib/libarchive/test/test_compat_zip_1.zip.uu,v 1.2 2008/06/30 15:49:12 des Exp $ begin 644 test_compat_zip_1.zip M4$L#!!0`"``(``B$@S<````````````````4````345402U)3D8O34%.249% M4U0N34;S3OF'X^&9LZM":V):GYCYZ?YOFQ5W]\NH= diff --git a/libarchive/test/test_read_format_gtar_sparse_1_13.tgz.uu b/libarchive/test/test_read_format_gtar_sparse_1_13.tgz.uu index a298e59fa..8d84902bb 100644 --- a/libarchive/test/test_read_format_gtar_sparse_1_13.tgz.uu +++ b/libarchive/test/test_read_format_gtar_sparse_1_13.tgz.uu @@ -1,3 +1,4 @@ +$FreeBSD: src/lib/libarchive/test/test_read_format_gtar_sparse_1_13.tgz.uu,v 1.2 2008/07/03 03:26:30 peter Exp $ begin 644 test_read_format_gtar_sparse_1_13.tgz M'XL(`&&";$<``^W72VX;1Q2%XNYD*Q``P\\L&.(\OYSNP/)LGE` M!SDF.D#^SP,G94&\7?VS']^[O0'H$?N"!!V@4A_GWJ8*$".\V MK=Y8U1+KB\#H)L2G;BV77=?/EZ?K^]-#E31[WQYCC?+V<5/SSRG*:BU*1,_U diff --git a/libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tgz.uu b/libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tgz.uu index 41038960b..1a3ec90a0 100644 --- a/libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tgz.uu +++ b/libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tgz.uu @@ -1,3 +1,4 @@ +$FreeBSD: src/lib/libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tgz.uu,v 1.2 2008/07/03 03:26:30 peter Exp $ begin 644 test_read_format_gtar_sparse_1_17_posix00.tgz M'XL(`&*";$<``^W9S6[;1A2&8:UU%;Z!RO/#^5MHW:R*;'H!K,,`06L[$&7` M[=5W%#FN'(Q-Z1S5K-#W642!E&/3/M\$'\'5]GXG;,#F`_,,F5F>?QSN/ZR'3^O-=IE:K7:^O1DV diff --git a/libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tgz.uu b/libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tgz.uu index c74c08fb3..ce11fcde9 100644 --- a/libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tgz.uu +++ b/libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tgz.uu @@ -1,3 +1,4 @@ +$FreeBSD: src/lib/libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tgz.uu,v 1.2 2008/07/03 03:26:30 peter Exp $ begin 644 test_read_format_gtar_sparse_1_17_posix10.tgz M'XL(`&.";$<``^W7RV[;5A1&88WU%'J!RN=^&7B:9E0$*/H`1,*!B]@))`

1 assert(0 == archive_read_finish(a)); #else diff --git a/tar/Makefile b/tar/Makefile index 6b3b8165c..fa72cfbd1 100644 --- a/tar/Makefile +++ b/tar/Makefile @@ -1,4 +1,4 @@ -# $FreeBSD: src/usr.bin/tar/Makefile,v 1.36 2008/05/26 17:10:10 kientzle Exp $ +# $FreeBSD: src/usr.bin/tar/Makefile,v 1.37 2008/07/05 02:09:54 kientzle Exp $ PROG= bsdtar BSDTAR_VERSION_STRING=2.5.5 diff --git a/tar/bsdtar.1 b/tar/bsdtar.1 index e790d60cc..a6015dc6e 100644 --- a/tar/bsdtar.1 +++ b/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.43 2008/05/26 17:10:10 kientzle Exp $ +.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.44 2008/07/26 17:22:40 simon Exp $ .\" .Dd May 15, 2008 .Dt BSDTAR 1 @@ -412,6 +412,12 @@ will produce output similar to that of Additional .Fl v options will provide additional detail. +.It Fl -version +Print version of +.Nm +and +.Nm libarchive , +and exit. .It Fl W Ar longopt=value Long options (preceded by .Fl - ) @@ -544,6 +550,7 @@ format can be used to create an output archive with arbitrary ownership, permissions, or names that differ from existing data on disk: .Pp .Dl $ cat input.mtree +.Dl #mtree .Dl usr/bin uid=0 gid=0 mode=0755 type=dir .Dl usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls .Dl $ tar -cvf output.tar @input.mtree diff --git a/tar/bsdtar.h b/tar/bsdtar.h index 4153a44f9..90c9315de 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.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/usr.bin/tar/bsdtar.h,v 1.33 2008/05/26 17:10:10 kientzle Exp $ + * $FreeBSD: src/usr.bin/tar/bsdtar.h,v 1.34 2008/07/05 08:03:08 cperciva Exp $ */ #include "bsdtar_platform.h" @@ -94,6 +94,7 @@ struct bsdtar { struct archive_entry_linkresolver *resolver; struct archive_dir *archive_dir; /* for write.c */ struct name_cache *gname_cache; /* for write.c */ + char *buff; /* for write.c */ struct matching *matching; /* for matching.c */ struct security *security; /* for read.c */ struct name_cache *uname_cache; /* for write.c */ diff --git a/tar/config_freebsd.h b/tar/config_freebsd.h index bdfe71b41..69790d8f5 100644 --- a/tar/config_freebsd.h +++ b/tar/config_freebsd.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/usr.bin/tar/config_freebsd.h,v 1.4 2008/05/26 17:10:10 kientzle Exp $ + * $FreeBSD: src/usr.bin/tar/config_freebsd.h,v 1.5 2008/07/05 02:09:13 kientzle Exp $ */ /* A default configuration for FreeBSD, used if there is no config.h. */ diff --git a/tar/read.c b/tar/read.c index fbb82533a..fadd57de8 100644 --- a/tar/read.c +++ b/tar/read.c @@ -24,7 +24,7 @@ */ #include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.38 2008/05/26 17:10:10 kientzle Exp $"); +__FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.39 2008/07/05 02:05:55 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include diff --git a/tar/write.c b/tar/write.c index 93531b8d0..d038fac9e 100644 --- a/tar/write.c +++ b/tar/write.c @@ -24,7 +24,7 @@ */ #include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.70 2008/05/26 17:10:10 kientzle Exp $"); +__FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.76 2008/07/05 08:10:55 cperciva Exp $"); #ifdef HAVE_SYS_TYPES_H #include @@ -79,6 +79,9 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.70 2008/05/26 17:10:10 kientzle #include "bsdtar.h" #include "tree.h" +/* Size of buffer for holding file data prior to writing. */ +#define FILEDATABUFLEN 65536 + /* Fixed size of uname/gname caches. */ #define name_cache_size 101 @@ -137,7 +140,7 @@ static void write_entry(struct bsdtar *, struct archive *, const struct stat *, const char *pathname, const char *accpath); static void write_entry_backend(struct bsdtar *, struct archive *, - struct archive_entry *, int); + struct archive_entry *); static int write_file_data(struct bsdtar *, struct archive *, struct archive_entry *, int fd); static void write_hierarchy(struct bsdtar *, struct archive *, @@ -152,9 +155,6 @@ tar_mode_c(struct bsdtar *bsdtar) if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - a = archive_write_new(); /* Support any format that the library supports. */ @@ -216,16 +216,6 @@ tar_mode_c(struct bsdtar *bsdtar) bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); write_archive(a, bsdtar); - - if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); - } - - archive_write_finish(a); - - /* Restore old SIGINFO + SIGUSR1 handlers. */ - siginfo_done(bsdtar); } /* @@ -244,9 +234,6 @@ tar_mode_r(struct bsdtar *bsdtar) /* Sanity-test some arguments and the file. */ test_for_append(bsdtar); - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666); @@ -317,12 +304,6 @@ tar_mode_r(struct bsdtar *bsdtar) write_archive(a, bsdtar); /* XXX check return val XXX */ - if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); - } - - archive_write_finish(a); close(bsdtar->fd); bsdtar->fd = -1; } @@ -345,9 +326,6 @@ tar_mode_u(struct bsdtar *bsdtar) /* Sanity-test some arguments and the file. */ test_for_append(bsdtar); - /* We want to catch SIGINFO and SIGUSR1. */ - siginfo_init(bsdtar); - bsdtar->fd = open(bsdtar->filename, O_RDWR); if (bsdtar->fd < 0) bsdtar_errc(bsdtar, 1, errno, @@ -406,12 +384,6 @@ tar_mode_u(struct bsdtar *bsdtar) write_archive(a, bsdtar); - if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); - } - - archive_write_finish(a); close(bsdtar->fd); bsdtar->fd = -1; @@ -434,6 +406,13 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) const char *arg; struct archive_entry *entry, *sparse_entry; + /* We want to catch SIGINFO and SIGUSR1. */ + siginfo_init(bsdtar); + + /* Allocate a buffer for file data. */ + if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL) + bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory"); + if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, @@ -453,7 +432,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) bsdtar_warnc(bsdtar, 1, 0, "Missing argument for -C"); bsdtar->return_value = 1; - return; + goto cleanup; } } set_chdir(bsdtar, arg); @@ -473,8 +452,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { - int fd = -1; - write_entry_backend(bsdtar, a, entry, fd); + write_entry_backend(bsdtar, a, entry); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); @@ -485,6 +463,20 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } + +cleanup: + /* Free file data buffer. */ + free(bsdtar->buff); + + if (bsdtar->option_totals) { + fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", + (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); + } + + archive_write_finish(a); + + /* Restore old SIGINFO + SIGUSR1 handlers. */ + siginfo_done(bsdtar); } /* @@ -616,22 +608,23 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) static int copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) { - char buff[64*1024]; ssize_t bytes_read; ssize_t bytes_written; off_t progress = 0; - bytes_read = archive_read_data(ina, buff, sizeof(buff)); + bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN); while (bytes_read > 0) { siginfo_printinfo(bsdtar, progress); - bytes_written = archive_write_data(a, buff, bytes_read); + bytes_written = archive_write_data(a, bsdtar->buff, + bytes_read); if (bytes_written < bytes_read) { bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); return (-1); } progress += bytes_written; - bytes_read = archive_read_data(ina, buff, sizeof(buff)); + bytes_read = archive_read_data(ina, bsdtar->buff, + FILEDATABUFLEN); } return (0); @@ -798,11 +791,12 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) */ static void write_entry_backend(struct bsdtar *bsdtar, struct archive *a, - struct archive_entry *entry, int fd) + struct archive_entry *entry) { + int fd = -1; int e; - if (fd == -1 && archive_entry_size(entry) > 0) { + if (archive_entry_size(entry) > 0) { const char *pathname = archive_entry_sourcepath(entry); fd = open(pathname, O_RDONLY); if (fd == -1) { @@ -837,8 +831,14 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a, if (e >= ARCHIVE_WARN && fd >= 0 && archive_entry_size(entry) > 0) { if (write_file_data(bsdtar, a, entry, fd)) exit(1); - close(fd); } + + /* + * If we opened a file, close it now even if there was an error + * which made us decide not to write the archive body. + */ + if (fd >= 0) + close(fd); } /* @@ -849,14 +849,12 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, const struct stat *st, const char *pathname, const char *accpath) { struct archive_entry *entry, *sparse_entry; - int fd; #ifdef __linux int r; unsigned long stflags; #endif static char linkbuffer[PATH_MAX+1]; - fd = -1; entry = archive_entry_new(); archive_entry_set_pathname(entry, pathname); @@ -910,6 +908,7 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, const struct stat *st, #endif #ifdef __linux + int fd; if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) && ((fd = open(accpath, O_RDONLY|O_NONBLOCK)) >= 0) && ((r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags)), close(fd), (fd = -1), r) >= 0 && @@ -935,8 +934,7 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, const struct stat *st, siginfo_printinfo(bsdtar, 0); while (entry != NULL) { - write_entry_backend(bsdtar, a, entry, fd); - fd = -1; + write_entry_backend(bsdtar, a, entry); archive_entry_free(entry); entry = sparse_entry; sparse_entry = NULL; @@ -947,31 +945,26 @@ cleanup: fprintf(stderr, "\n"); abort: - if (fd >= 0) - close(fd); - - archive_entry_free(entry); + if (entry != NULL) + archive_entry_free(entry); } -/* Helper function to copy file to archive, with stack-allocated buffer. */ +/* Helper function to copy file to archive. */ static int write_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive_entry *entry, int fd) { - char buff[64*1024]; ssize_t bytes_read; ssize_t bytes_written; off_t progress = 0; - /* XXX TODO: Allocate buffer on heap and store pointer to - * it in bsdtar structure; arrange cleanup as well. XXX */ - - bytes_read = read(fd, buff, sizeof(buff)); + bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN); while (bytes_read > 0) { siginfo_printinfo(bsdtar, progress); - bytes_written = archive_write_data(a, buff, bytes_read); + bytes_written = archive_write_data(a, bsdtar->buff, + FILEDATABUFLEN); if (bytes_written < 0) { /* Write failed; this is bad */ bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); @@ -985,7 +978,7 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a, return (0); } progress += bytes_written; - bytes_read = read(fd, buff, sizeof(buff)); + bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN); } return 0; } -- 2.47.3