#include "test.h"
-#define __LIBARCHIVE_BUILD 1
-#include "archive_getdate.h"
+#define parse_date archive_parse_date
static void
test_newer_time(void)
/* Test1: Allow newer time. */
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+ t = parse_date(now, "1980/2/1 0:0:1 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 1);
archive_entry_set_ctime(ae, t, 0);
failure("Its mtime should be excluded");
"1980/2/1 0:0:0 UTC"));
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+ t = parse_date(now, "1980/2/1 0:0:1 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
/* Test1: Allow newer time. */
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+ t = parse_date(now, "1980/2/1 0:0:1 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 1);
archive_entry_set_ctime(ae, t, 0);
failure("Its mtime should be excluded");
L"1980/2/1 0:0:0 UTC"));
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
+ t = parse_date(now, "1980/2/1 0:0:1 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
ARCHIVE_MATCH_OLDER, "1980/2/1 0:0:0 UTC"));
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_ctime(ae, t, 0);
failure("Its mtime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_ctime(ae, t, 0);
failure("Its ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
"1980/2/1 0:0:0 UTC"));
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
ARCHIVE_MATCH_OLDER, L"1980/2/1 0:0:0 UTC"));
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_ctime(ae, t, 0);
failure("Its mtime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
assertEqualInt(1, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_ctime(ae, t, 0);
failure("Its ctime should be excluded");
assertEqualInt(1, archive_match_time_excluded(m, ae));
L"1980/2/1 0:0:0 UTC"));
archive_entry_copy_pathname(ae, "file1");
- t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
+ t = parse_date(now, "1980/2/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
+ t = parse_date(now, "1980/1/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should not be excluded");
assertEqualInt(0, archive_match_time_excluded(m, ae));
assertEqualInt(0, archive_match_excluded(m, ae));
- t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
+ t = parse_date(now, "1980/3/1 0:0:0 UTC");
archive_entry_set_mtime(ae, t, 0);
archive_entry_set_ctime(ae, t, 0);
failure("Both Its mtime and ctime should be excluded");
--- /dev/null
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Zhaofeng Li
+ * All rights reserved.
+ */
+#include "test.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+/* system() on Windows runs its arguments through CMD.EXE, which has
+ * notoriously unfriendly quoting rules. The current best documented way around
+ * them is to wrap your *entire commandline* in sacrificial quotes.
+ *
+ * See CMD.EXE /? for more information. Excerpted here:
+ * | Otherwise, old behavior is to see if the first character is
+ * | a quote character and if so, strip the leading character and
+ * | remove the last quote character on the command line, preserving
+ * | any text after the last quote character.
+ *
+ * Since this test makes heavy use of systemf() with quoted arguments inside
+ * the commandline, this macro is unfortunately an easier workaround.
+ */
+#define systemf(command, ...) systemf("\"" command "\"", __VA_ARGS__)
+#endif
+
+DEFINE_TEST(test_option_mtime)
+{
+ /* Create three files with different mtimes. */
+ assertMakeDir("in", 0755);
+ assertChdir("in");
+ assertMakeFile("new_mtime", 0666, "new");
+ assertUtimes("new_mtime", 100000, 0, 100000, 0);
+ assertMakeFile("mid_mtime", 0666, "mid");
+ assertUtimes("mid_mtime", 10000, 0, 10000, 0);
+ assertMakeFile("old_mtime", 0666, "old");
+ // assertion_utimes silently discards 0 :(
+ assertUtimes("old_mtime", 1, 0, 1, 0);
+
+ /* Archive with --mtime 86400 */
+ assertEqualInt(0,
+ systemf("%s --format pax -cf ../noclamp.tar "
+ "--mtime \"1970/1/2 0:0:0 UTC\" .",
+ testprog));
+ assertChdir("..");
+
+ assertMakeDir("out.noclamp", 0755);
+ assertChdir("out.noclamp");
+ assertEqualInt(0, systemf("%s xf ../noclamp.tar", testprog));
+ assertFileMtime("new_mtime", 86400, 0);
+ assertFileMtime("mid_mtime", 86400, 0);
+ assertFileMtime("old_mtime", 86400, 0);
+ assertChdir("..");
+
+ /* Archive with --mtime 86400 --clamp-mtime */
+ assertChdir("in");
+ assertEqualInt(0,
+ systemf("%s --format pax -cf ../clamp.tar "
+ "--mtime \"1970/1/2 0:0:0 UTC\" --clamp-mtime .",
+ testprog));
+ assertChdir("..");
+
+ assertMakeDir("out.clamp", 0755);
+ assertChdir("out.clamp");
+ assertEqualInt(0, systemf("%s xf ../clamp.tar", testprog));
+ assertFileMtime("new_mtime", 86400, 0);
+ assertFileMtime("mid_mtime", 10000, 0);
+ assertFileMtime("old_mtime", 1, 0);
+ assertChdir("..");
+
+ /* Archive-to-archive copy with --mtime 0 */
+ assertEqualInt(0,
+ systemf("%s --format pax -cf ./archive2archive.tar "
+ "--mtime \"1970/1/1 0:0:0 UTC\" @noclamp.tar",
+ testprog));
+ assertMakeDir("out.archive2archive", 0755);
+ assertChdir("out.archive2archive");
+ assertEqualInt(0, systemf("%s xf ../archive2archive.tar", testprog));
+ assertFileMtime("new_mtime", 0, 0);
+ assertFileMtime("mid_mtime", 0, 0);
+ assertFileMtime("old_mtime", 0, 0);
+ assertChdir("..");
+}