aboutsummaryrefslogtreecommitdiffstats
path: root/tar
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2020-02-11 23:48:03 +0000
committerMartin Matuska <mm@FreeBSD.org>2020-02-11 23:48:03 +0000
commit8185c4ae244f9a52ad987b36e7d6300500054d00 (patch)
tree11e2d7cd0caf20998ed1e1146e1c1d7fc747165e /tar
parent98c1f51f769841d99d879099f9075ff60d51ee4a (diff)
downloadsrc-8185c4ae244f9a52ad987b36e7d6300500054d00.tar.gz
src-8185c4ae244f9a52ad987b36e7d6300500054d00.zip
Update vendor/libarchive/dist to git 3288ebb0353beb51dfb09d444dedbe9235ead53dvendor/libarchive/3.4.2
Libarchive 3.4.2 Relevant vendor changes: PR #1289: atomic extraction support (bsdtar -x --safe-writes) PR #1308: big endian fix for UTF16 support in LHA reader PR #1326: reject RAR5 files that declare invalid header flags Issue #987: fix support 7z archive entries with Delta filter Issue #1317: fix compression output buffer handling in XAR writer Issue #1319: fix uname or gname longer than 32 characters in pax writer Issue #1325: fix use after free when archiving hardlinks in ISO9660 or XAR Use localtime_r() and gmtime_r() instead of localtime() and gmtime()
Notes
Notes: svn path=/vendor/libarchive/dist/; revision=357783 svn path=/vendor/libarchive/3.4.2/; revision=357784; tag=vendor/libarchive/3.4.2
Diffstat (limited to 'tar')
-rw-r--r--tar/bsdtar.149
-rw-r--r--tar/bsdtar.c6
-rw-r--r--tar/bsdtar.h7
-rw-r--r--tar/cmdline.c2
-rw-r--r--tar/test/CMakeLists.txt1
-rw-r--r--tar/test/test_basic.c2
-rw-r--r--tar/test/test_copy.c4
-rw-r--r--tar/test/test_option_C_upper.c2
-rw-r--r--tar/test/test_option_s.c6
-rw-r--r--tar/test/test_option_safe_writes.c77
-rw-r--r--tar/util.c22
11 files changed, 162 insertions, 16 deletions
diff --git a/tar/bsdtar.1 b/tar/bsdtar.1
index 04b56553ce02..f1574234905c 100644
--- a/tar/bsdtar.1
+++ b/tar/bsdtar.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 3, 2019
+.Dd January 31, 2020
.Dt TAR 1
.Os
.Sh NAME
@@ -209,15 +209,16 @@ specified on the command line.
.It Fl Fl exclude-vcs
Do not process files or directories internally used by the
version control systems
+.Sq Arch ,
+.Sq Bazaar ,
.Sq CVS ,
+.Sq Darcs ,
+.Sq Mercurial ,
.Sq RCS ,
.Sq SCCS ,
-.Sq SVN ,
-.Sq Arch ,
-.Sq Bazaar ,
-.Sq Mercurial
+.Sq SVN
and
-.Sq Darcs .
+.Sq git .
.It Fl Fl fflags
(c, r, u, x modes only)
Archive or extract platform-specific file attributes or file flags.
@@ -469,6 +470,13 @@ This is the reverse of
and the default behavior if
.Nm
is run as non-root in x mode.
+.It Fl Fl no-safe-writes
+(x mode only)
+Do not create temporary files and use
+.Xr rename 2
+to replace the original ones.
+This is the reverse of
+.Fl Fl safe-writes .
.It Fl Fl no-same-owner
(x mode only)
Do not extract owner and group IDs.
@@ -567,7 +575,14 @@ As above, but the corresponding key and value will be provided
only to modules whose name matches
.Ar module .
.El
-The currently supported modules and keys are:
+.Pp
+The complete list of supported modules and keys
+for create and append modes is in
+.Xr archive_write_set_options 3
+and for extract and list modes in
+.Xr archive_read_set_options 3 .
+.Pp
+Examples of supported options:
.Bl -tag -compact -width indent
.It Cm iso9660:joliet
Support Joliet extensions.
@@ -756,6 +771,26 @@ The default is
.Ar hrs
which applies substitutions to all names.
In particular, it is never necessary to specify h, r, or s.
+.It Fl Fl safe-writes
+(x mode only)
+Extract files atomically.
+By default
+.Nm
+unlinks the original file with the same name as the extracted file (if it
+exists), and then creates it immediately under the same name and writes to
+it.
+For a short period of time, applications trying to access the file might
+not find it, or see incomplete results.
+If
+.Fl Fl safe-writes
+is enabled,
+.Nm
+first creates a unique temporary file, then writes the new contents to
+the temporary file, and finally renames the temporary file to its final
+name atomically using
+.Xr rename 2 .
+This guarantees that an application accessing the file, will either see
+the old contents or the new contents at all times.
.It Fl Fl same-owner
(x mode only)
Extract owner and group IDs.
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index b59963d0f822..af41be5e4e26 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -542,6 +542,9 @@ main(int argc, char **argv)
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
bsdtar->flags |= OPTFLAG_NO_MAC_METADATA;
break;
+ case OPTION_NO_SAFE_WRITES:
+ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_SAFE_WRITES;
+ break;
case OPTION_NO_SAME_OWNER: /* GNU tar */
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
@@ -658,6 +661,9 @@ main(int argc, char **argv)
usage();
#endif
break;
+ case OPTION_SAFE_WRITES:
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_SAFE_WRITES;
+ break;
case OPTION_SAME_OWNER: /* GNU tar */
bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
break;
diff --git a/tar/bsdtar.h b/tar/bsdtar.h
index c61d568fd748..89aa3aa9198d 100644
--- a/tar/bsdtar.h
+++ b/tar/bsdtar.h
@@ -25,6 +25,9 @@
* $FreeBSD: src/usr.bin/tar/bsdtar.h,v 1.37 2008/12/06 07:37:14 kientzle Exp $
*/
+#ifndef BSDTAR_H_INCLUDED
+#define BSDTAR_H_INCLUDED
+
#include "bsdtar_platform.h"
#include <stdio.h>
@@ -161,6 +164,7 @@ enum {
OPTION_NO_ACLS,
OPTION_NO_FFLAGS,
OPTION_NO_MAC_METADATA,
+ OPTION_NO_SAFE_WRITES,
OPTION_NO_SAME_OWNER,
OPTION_NO_SAME_PERMISSIONS,
OPTION_NO_XATTRS,
@@ -174,6 +178,7 @@ enum {
OPTION_OPTIONS,
OPTION_PASSPHRASE,
OPTION_POSIX,
+ OPTION_SAFE_WRITES,
OPTION_SAME_OWNER,
OPTION_STRIP_COMPONENTS,
OPTION_TOTALS,
@@ -224,3 +229,5 @@ const char * passphrase_callback(struct archive *, void *);
void passphrase_free(char *);
void list_item_verbose(struct bsdtar *, FILE *,
struct archive_entry *);
+
+#endif
diff --git a/tar/cmdline.c b/tar/cmdline.c
index 21558e12df42..b80937ffcb6e 100644
--- a/tar/cmdline.c
+++ b/tar/cmdline.c
@@ -123,6 +123,7 @@ static const struct bsdtar_option {
{ "no-fflags", 0, OPTION_NO_FFLAGS },
{ "no-mac-metadata", 0, OPTION_NO_MAC_METADATA },
{ "no-recursion", 0, 'n' },
+ { "no-safe-writes", 0, OPTION_NO_SAFE_WRITES },
{ "no-same-owner", 0, OPTION_NO_SAME_OWNER },
{ "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS },
{ "no-xattr", 0, OPTION_NO_XATTRS },
@@ -144,6 +145,7 @@ static const struct bsdtar_option {
{ "posix", 0, OPTION_POSIX },
{ "preserve-permissions", 0, 'p' },
{ "read-full-blocks", 0, 'B' },
+ { "safe-writes", 0, OPTION_SAFE_WRITES },
{ "same-owner", 0, OPTION_SAME_OWNER },
{ "same-permissions", 0, 'p' },
{ "strip-components", 1, OPTION_STRIP_COMPONENTS },
diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt
index 459d9dcb1eff..2cd573acfaa5 100644
--- a/tar/test/CMakeLists.txt
+++ b/tar/test/CMakeLists.txt
@@ -59,6 +59,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
test_option_q.c
test_option_r.c
test_option_s.c
+ test_option_safe_writes.c
test_option_uid_uname.c
test_option_uuencode.c
test_option_xattrs.c
diff --git a/tar/test/test_basic.c b/tar/test/test_basic.c
index 9bb966a0cf86..b1c49834a45f 100644
--- a/tar/test/test_basic.c
+++ b/tar/test/test_basic.c
@@ -96,7 +96,7 @@ run_tar(const char *target, const char *pack_options,
/* Use the tar program to create an archive. */
r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target);
- failure("Error invoking %s cf -", testprog, pack_options);
+ failure("Error invoking %s cf -%s", testprog, pack_options);
assertEqualInt(r, 0);
assertChdir(target);
diff --git a/tar/test/test_copy.c b/tar/test/test_copy.c
index b828666b93fd..d618e45ca36b 100644
--- a/tar/test/test_copy.c
+++ b/tar/test/test_copy.c
@@ -256,13 +256,13 @@ verify_tree(size_t limit)
continue;
switch(dp[0]) {
case 'l': case 'm': case 'd':
- failure("strlen(p)=%d", strlen(p));
+ failure("strlen(p)=%zu", strlen(p));
assert(strlen(p) < limit);
assertEqualString(p,
filenames[strlen(p)]);
break;
case 'f': case 's':
- failure("strlen(p)=%d", strlen(p));
+ failure("strlen(p)=%zu", strlen(p));
assert(strlen(p) < limit + 1);
assertEqualString(p,
filenames[strlen(p)]);
diff --git a/tar/test/test_option_C_upper.c b/tar/test/test_option_C_upper.c
index dae985446892..538890f58178 100644
--- a/tar/test/test_option_C_upper.c
+++ b/tar/test/test_option_C_upper.c
@@ -117,7 +117,7 @@ DEFINE_TEST(test_option_C_upper)
assertMakeDir("test6", 0755);
assertChdir("test6");
r = systemf("%s -cf archive.tar -C XXX -C ../d1 file1 2>write.err",
- testprog, testworkdir);
+ testprog);
assert(r != 0);
assertNonEmptyFile("write.err");
assertEqualInt(0,
diff --git a/tar/test/test_option_s.c b/tar/test/test_option_s.c
index 09c72ee7d63d..fa799a295d01 100644
--- a/tar/test/test_option_s.c
+++ b/tar/test/test_option_s.c
@@ -92,10 +92,8 @@ DEFINE_TEST(test_option_s)
* Test 5: Name-switching substitutions when extracting archive.
*/
assertMakeDir("test5", 0755);
- systemf("%s -cf test5.tar in/d1/foo in/d1/bar",
- testprog, testprog);
- systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5",
- testprog, testprog);
+ systemf("%s -cf test5.tar in/d1/foo in/d1/bar", testprog);
+ systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5", testprog);
assertFileContents("foo", 3, "test5/in/d1/bar");
assertFileContents("bar", 3, "test5/in/d1/foo");
diff --git a/tar/test/test_option_safe_writes.c b/tar/test/test_option_safe_writes.c
new file mode 100644
index 000000000000..8edf5c69f7ec
--- /dev/null
+++ b/tar/test/test_option_safe_writes.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2020 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_safe_writes)
+{
+ /* Create files */
+ assertMakeDir("in", 0755);
+ assertEqualInt(0, chdir("in"));
+ assertMakeFile("f", 0644, "a");
+ assertMakeFile("fh", 0644, "b");
+ assertMakeFile("d", 0644, "c");
+ assertMakeFile("fs", 0644, "d");
+ assertMakeFile("ds", 0644, "e");
+ assertEqualInt(0, chdir(".."));
+
+ /* Tar files up */
+ assertEqualInt(0,
+ systemf("%s -c -C in -f t.tar f fh d fs ds "
+ ">pack.out 2>pack.err", testprog));
+
+ /* Verify that nothing went to stdout or stderr. */
+ assertEmptyFile("pack.err");
+ assertEmptyFile("pack.out");
+
+ /* Create various objects */
+ assertMakeDir("out", 0755);
+ assertEqualInt(0, chdir("out"));
+ assertMakeFile("f", 0644, "a");
+ assertMakeHardlink("fh", "f");
+ assertMakeDir("d", 0755);
+ if (canSymlink()) {
+ assertMakeSymlink("fs", "f", 0);
+ assertMakeSymlink("ds", "d", 1);
+ }
+ assertEqualInt(0, chdir(".."));
+
+ /* Extract created archive withe safe writes */
+ assertEqualInt(0,
+ systemf("%s -x -C out --safe-writes -f t.tar "
+ ">unpack.out 2>unpack.err", testprog));
+
+ /* Verify that nothing went to stdout or stderr. */
+ assertEmptyFile("unpack.err");
+ assertEmptyFile("unpack.out");
+
+ /* Verify that files were overwritten properly */
+ assertEqualInt(0, chdir("out"));
+ assertTextFileContents("a","f");
+ assertTextFileContents("b","fh");
+ assertTextFileContents("c","d");
+ assertTextFileContents("d","fs");
+ assertTextFileContents("e","ds");
+}
diff --git a/tar/util.c b/tar/util.c
index 662db5baa796..8ebec64c48d9 100644
--- a/tar/util.c
+++ b/tar/util.c
@@ -666,6 +666,14 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
const char *fmt;
time_t tim;
static time_t now;
+ struct tm *ltime;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+ struct tm tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+ errno_t terr;
+ __time64_t tmptime;
+#endif
/*
* We avoid collecting the entire list in memory at once by
@@ -737,7 +745,19 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y";
else
fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M";
- strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
+#if defined(HAVE_LOCALTIME_R)
+ ltime = localtime_r(&tim, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+ tmptime = tim;
+ terr = _localtime64_s(&tmbuf, &tmptime);
+ if (terr)
+ ltime = NULL;
+ else
+ ltime = &tmbuf;
+#else
+ ltime = localtime(&tim);
+#endif
+ strftime(tmp, sizeof(tmp), fmt, ltime);
fprintf(out, " %s ", tmp);
safe_fprintf(out, "%s", archive_entry_pathname(entry));