]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add the ability to parse a date string into archive_matching.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 6 Feb 2012 13:28:00 +0000 (22:28 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 7 Feb 2012 07:33:19 +0000 (16:33 +0900)
Makefile.am
libarchive/CMakeLists.txt
libarchive/archive.h
libarchive/archive_getdate.c [moved from tar/getdate.c with 99% similarity]
libarchive/archive_matching.c
libarchive/test/CMakeLists.txt
libarchive/test/test_archive_getdate.c [moved from tar/test/test_getdate.c with 96% similarity]
libarchive/test/test_archive_matching_time.c
tar/CMakeLists.txt
tar/bsdtar.c
tar/test/CMakeLists.txt

index 540eb9587c972fcab022f14389c48e023a5c818f..c917d1e849fafb0bb766a481dee45b5f2d7067da 100644 (file)
@@ -102,6 +102,7 @@ libarchive_la_SOURCES=                                              \
        libarchive/archive_entry_stat.c                         \
        libarchive/archive_entry_strmode.c                      \
        libarchive/archive_entry_xattr.c                        \
+       libarchive/archive_getdate.c                            \
        libarchive/archive_matching.c                           \
        libarchive/archive_options.c                            \
        libarchive/archive_options_private.h                    \
@@ -258,6 +259,7 @@ libarchive_test_SOURCES=                                    \
        libarchive/test/test_archive_api_feature.c              \
        libarchive/test/test_archive_clear_error.c              \
        libarchive/test/test_archive_crypto.c                   \
+       libarchive/test/test_archive_getdate.c                  \
        libarchive/test/test_archive_matching_owner.c           \
        libarchive/test/test_archive_matching_path.c            \
        libarchive/test/test_archive_matching_time.c            \
@@ -597,7 +599,6 @@ bsdtar_SOURCES=                             \
                tar/bsdtar.h            \
                tar/bsdtar_platform.h   \
                tar/cmdline.c           \
-               tar/getdate.c           \
                tar/read.c              \
                tar/subst.c             \
                tar/util.c              \
@@ -644,14 +645,12 @@ endif
 #
 
 bsdtar_test_SOURCES=                                           \
-       tar/getdate.c                                           \
        tar/test/main.c                                         \
        tar/test/test.h                                         \
        tar/test/test_0.c                                       \
        tar/test/test_basic.c                                   \
        tar/test/test_copy.c                                    \
        tar/test/test_empty_mtree.c                             \
-       tar/test/test_getdate.c                                 \
        tar/test/test_help.c                                    \
        tar/test/test_option_C_upper.c                          \
        tar/test/test_option_H_upper.c                          \
index 2ffd55e68f65444fc23886037ff3b83cb75f6063..a4b18714423543e32994d9ebb5106363d55beb72 100644 (file)
@@ -28,6 +28,7 @@ SET(libarchive_SOURCES
   archive_entry_stat.c
   archive_entry_strmode.c
   archive_entry_xattr.c
+  archive_getdate.c
   archive_matching.c
   archive_options.c
   archive_options_private.h
index 2d8256db549ff3446f52b2387ac83d1531191256..bc49264f95dd1f60a2eb835f2142850c58bbc60f 100644 (file)
@@ -873,32 +873,69 @@ __LA_DECL int     archive_matching_path_unmatched_inclusions_next_w(
  */
 __LA_DECL int  archive_matching_time_excluded(struct archive *,
                    struct archive_entry *);
-/* Set inclusion file times. */
+/* Set inclusion mtime. */
 __LA_DECL int  archive_matching_newer_mtime(struct archive *,
                    time_t _sec, long _nsec);
+__LA_DECL int  archive_matching_newer_ctime(struct archive *,
+                   time_t _sec, long _nsec);
+__LA_DECL int  archive_matching_older_mtime(struct archive *,
+                   time_t _sec, long _nsec);
+__LA_DECL int  archive_matching_older_ctime(struct archive *,
+                   time_t _sec, long _nsec);
+/* Set inclusion mtime by string. */
+__LA_DECL int  archive_matching_newer_mtime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_newer_mtime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_equal_or_newer_mtime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_equal_or_newer_mtime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_newer_ctime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_newer_ctime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_equal_or_newer_ctime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_equal_or_newer_ctime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_older_mtime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_older_mtime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_equal_or_older_mtime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_equal_or_older_mtime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_older_ctime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_older_ctime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+__LA_DECL int  archive_matching_equal_or_older_ctime_str(struct archive *,
+                   const char *_datestr);
+__LA_DECL int  archive_matching_equal_or_older_ctime_str_w(struct archive *,
+                   const wchar_t *_datestr);
+/* Set inclusion mtime by a particluar file. */
 __LA_DECL int  archive_matching_newer_mtime_than(struct archive *,
                    const char *_pathname);
 __LA_DECL int  archive_matching_newer_mtime_than_w(struct archive *,
                    const wchar_t *_pathname);
-__LA_DECL int  archive_matching_newer_ctime(struct archive *,
-                   time_t _sec, long _nsec);
 __LA_DECL int  archive_matching_newer_ctime_than(struct archive *,
                    const char *_pathname);
 __LA_DECL int  archive_matching_newer_ctime_than_w(struct archive *,
                    const wchar_t *_pathname);
-__LA_DECL int  archive_matching_older_mtime(struct archive *,
-                   time_t _sec, long _nsec);
 __LA_DECL int  archive_matching_older_mtime_than(struct archive *,
                    const char *_pathname);
 __LA_DECL int  archive_matching_older_mtime_than_w(struct archive *,
                    const wchar_t *_pathname);
-__LA_DECL int  archive_matching_older_ctime(struct archive *,
-                   time_t _sec, long _nsec);
 __LA_DECL int  archive_matching_older_ctime_than(struct archive *,
                    const char *_pathname);
 __LA_DECL int  archive_matching_older_ctime_than_w(struct archive *,
                    const wchar_t *_pathname);
-/* Add inclusion file times with its filename. */
+/* Add inclusion a pair of a pathname and its mtime.
+ * If a pathname does not match any pathnames, the entry will be treated
+ * as matched. If the pathname matchs some pathnames, those mtimes will be
+ * tested. */
 __LA_DECL int  archive_matching_pathname_newer_mtime(
                    struct archive *, struct archive_entry *);
 
similarity index 99%
rename from tar/getdate.c
rename to libarchive/archive_getdate.c
index 0e15d9c8a5bed3f8e616e3214455f9c26df78653..f8b5a28d583d2cf35a53ffecb6c1aec0afa86241 100644 (file)
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <time.h>
 
 /* This file defines a single public function. */
-time_t get_date(time_t now, char *);
+time_t __archive_get_date(time_t now, char *);
 
 /* Basic time units. */
 #define        EPOCH           1970
@@ -894,7 +894,7 @@ difftm (struct tm *a, struct tm *b)
  * TODO: tokens[] array should be dynamically sized.
  */
 time_t
-get_date(time_t now, char *p)
+__archive_get_date(time_t now, char *p)
 {
        struct token    tokens[256];
        struct gdstate  _gds;
index eab4c36b7de2facbb99f0d5d96e1cbec5ae1b525..d38bda308eb57d7e536836811bc017199d3c8ccb 100644 (file)
@@ -83,6 +83,22 @@ struct id_array {
 #define TIME_IS_SET            2
 #define ID_IS_SET              4
 
+#define TTYPE_MTIME            0x10
+#define TTYPE_CTIME            0x20
+#define TCOND_EQUAL            0x01
+#define TCOND_NEWER            0x02
+#define TCOND_OLDER            0x04
+#define TIMETYPE_IS_CTIME(t)   ((t) & TTYPE_CTIME)
+#define MATCH_NEWER_MTIME      (TTYPE_MTIME | TCOND_NEWER)
+#define MATCH_EQ_NEWER_MTIME   (TTYPE_MTIME | TCOND_NEWER | TCOND_EQUAL)
+#define MATCH_OLDER_MTIME      (TTYPE_MTIME | TCOND_OLDER)
+#define MATCH_EQ_OLDER_MTIME   (TTYPE_MTIME | TCOND_OLDER | TCOND_EQUAL)
+#define MATCH_NEWER_CTIME      (TTYPE_CTIME | TCOND_NEWER)
+#define MATCH_EQ_NEWER_CTIME   (TTYPE_CTIME | TCOND_NEWER | TCOND_EQUAL)
+#define MATCH_OLDER_CTIME      (TTYPE_CTIME | TCOND_OLDER)
+#define MATCH_EQ_OLDER_CTIME   (TTYPE_CTIME | TCOND_OLDER | TCOND_EQUAL)
+
+
 struct archive_matching {
        struct archive           archive;
 
@@ -98,6 +114,7 @@ struct archive_matching {
        /*
         * Matching time stamps.
         */
+       time_t                   now;
        int                      newer_mtime_filter;
        time_t                   newer_mtime_sec;
        long                     newer_mtime_nsec;
@@ -142,10 +159,6 @@ static int cmp_node_mbs(const struct archive_rb_node *,
 static int     cmp_node_wcs(const struct archive_rb_node *,
                    const struct archive_rb_node *);
 static int     error_nomem(struct archive_matching *);
-static int     get_filetime_mbs(struct archive_matching *, const char *,
-                   int, time_t *, long *);
-static int     get_filetime_wcs(struct archive_matching *, const wchar_t *,
-                   int, time_t *, long *);
 static void    match_list_add(struct match_list *, struct match *);
 static void    match_list_free(struct match_list *);
 static void    match_list_init(struct match_list *);
@@ -170,9 +183,21 @@ static void        newer_file_list_init(struct newer_file_list *);
 static int     owner_excluded(struct archive_matching *,
                    struct archive_entry *);
 static int     path_excluded(struct archive_matching *, int, const void *);
+static int     set_timefilter(struct archive_matching *, int, time_t, long);
+static int     set_timefilter_pathname_mbs(struct archive_matching *,
+                   int, const char *);
+static int     set_timefilter_pathname_wcs(struct archive_matching *,
+                   int, const wchar_t *);
+static int     set_time_str(struct archive *, const char *, int,
+                   const char *);
+static int     set_time_str_w(struct archive *, const char *, int,
+                   const wchar_t *);
 static int     time_excluded(struct archive_matching *,
                    struct archive_entry *);
 
+time_t __archive_get_date(time_t now, const char *);
+#define get_date __archive_get_date
+
 static const struct archive_rb_tree_ops rb_ops_mbs = {
        cmp_node_mbs, cmp_key_mbs
 };
@@ -212,6 +237,7 @@ archive_matching_new(void)
        newer_file_list_init(&(a->newer_list));
        match_list_init(&(a->inclusion_unames));
        match_list_init(&(a->inclusion_gnames));
+       time(&a->now);
        return (&(a->archive));
 }
 
@@ -696,57 +722,31 @@ archive_matching_newer_mtime(struct archive *_a, time_t sec, long nsec)
            ARCHIVE_STATE_NEW, "archive_matching_newer_mtime");
        a = (struct archive_matching *)_a;
 
-       a->newer_mtime_filter = 1;
-       a->newer_mtime_sec = sec;
-       a->newer_mtime_nsec = nsec;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter(a, MATCH_NEWER_MTIME, sec, nsec);
 }
 
 int
 archive_matching_newer_mtime_than(struct archive *_a, const char *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_newer_mtime_than");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == '\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_mbs(a, pathname, 0, &(a->newer_mtime_sec),
-               &(a->newer_mtime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->newer_mtime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_mbs(a, MATCH_NEWER_MTIME, pathname);
 }
 
 int
 archive_matching_newer_mtime_than_w(struct archive *_a, const wchar_t *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_newer_mtime_than_w");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == L'\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_wcs(a, pathname, 0, &(a->newer_mtime_sec),
-               &(a->newer_mtime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->newer_mtime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_wcs(a, MATCH_NEWER_MTIME, pathname);
 }
 
 int
@@ -758,11 +758,7 @@ archive_matching_newer_ctime(struct archive *_a, time_t sec, long nsec)
            ARCHIVE_STATE_NEW, "archive_matching_newer_ctime");
        a = (struct archive_matching *)_a;
 
-       a->newer_ctime_filter = 1;
-       a->newer_ctime_sec = sec;
-       a->newer_ctime_nsec = nsec;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter(a, MATCH_NEWER_CTIME, sec, nsec);
 }
 
 int
@@ -770,46 +766,24 @@ archive_matching_newer_ctime_than(struct archive *_a,
     const char *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_newer_ctime_than");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == '\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_mbs(a, pathname, 1, &(a->newer_ctime_sec),
-           &(a->newer_ctime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->newer_ctime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_mbs(a, MATCH_NEWER_CTIME, pathname);
 }
 
 int
 archive_matching_newer_ctime_than_w(struct archive *_a, const wchar_t *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_newer_ctime_than_w");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == L'\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_wcs(a, pathname, 1, &(a->newer_ctime_sec),
-               &(a->newer_ctime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->newer_ctime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_wcs(a, MATCH_NEWER_CTIME, pathname);
 }
 
 int
@@ -821,57 +795,31 @@ archive_matching_older_mtime(struct archive *_a, time_t sec, long nsec)
            ARCHIVE_STATE_NEW, "archive_matching_older_mtime");
        a = (struct archive_matching *)_a;
 
-       a->older_mtime_filter = 1;
-       a->older_mtime_sec = sec;
-       a->older_mtime_nsec = nsec;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter(a, MATCH_OLDER_MTIME, sec, nsec);
 }
 
 int
 archive_matching_older_mtime_than(struct archive *_a, const char *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_older_mtime_than");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == '\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_mbs(a, pathname, 0, &(a->older_mtime_sec),
-               &(a->older_mtime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->older_mtime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_mbs(a, MATCH_OLDER_MTIME, pathname);
 }
 
 int
 archive_matching_older_mtime_than_w(struct archive *_a, const wchar_t *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_older_mtime_than_w");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == L'\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_wcs(a, pathname, 0, &(a->older_mtime_sec),
-           &(a->older_mtime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->older_mtime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_wcs(a, MATCH_OLDER_MTIME, pathname);
 }
 
 int
@@ -883,57 +831,31 @@ archive_matching_older_ctime(struct archive *_a, time_t sec, long nsec)
            ARCHIVE_STATE_NEW, "archive_matching_older_ctime");
        a = (struct archive_matching *)_a;
 
-       a->older_ctime_filter = 1;
-       a->older_ctime_sec = sec;
-       a->older_ctime_nsec = nsec;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter(a, MATCH_OLDER_CTIME, sec, nsec);
 }
 
 int
 archive_matching_older_ctime_than(struct archive *_a, const char *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_older_ctime_than");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == '\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_mbs(a, pathname, 1, &(a->older_ctime_sec),
-               &(a->older_ctime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->older_ctime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_mbs(a, MATCH_OLDER_CTIME, pathname);
 }
 
 int
 archive_matching_older_ctime_than_w(struct archive *_a, const wchar_t *pathname)
 {
        struct archive_matching *a;
-       int r;
 
        archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
            ARCHIVE_STATE_NEW, "archive_matching_older_ctime_than_w");
        a = (struct archive_matching *)_a;
 
-       if (pathname == NULL || *pathname == '\0') {
-               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
-               return (ARCHIVE_FAILED);
-       }
-       r = get_filetime_wcs(a, pathname, 1, &(a->older_ctime_sec),
-               &(a->older_ctime_nsec));
-       if (r != ARCHIVE_OK)
-               return (r);
-       a->older_ctime_filter = 1;
-       a->setflag |= TIME_IS_SET;
-       return (ARCHIVE_OK);
+       return set_timefilter_pathname_wcs(a, MATCH_OLDER_CTIME, pathname);
 }
 
 int
@@ -953,6 +875,133 @@ archive_matching_pathname_newer_mtime(struct archive *_a,
        return (add_newer_mtime_pathname(a, entry));
 }
 
+int
+archive_matching_newer_mtime_str(struct archive *_a, const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_newer_mtime_str",
+                       MATCH_NEWER_MTIME, _datestr);
+}
+
+int
+archive_matching_newer_mtime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_newer_mtime_str_w",
+                       MATCH_NEWER_MTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_newer_mtime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_equal_or_newer_mtime_str",
+                       MATCH_EQ_NEWER_MTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_newer_mtime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_equal_or_newer_mtime_str_w",
+                       MATCH_EQ_NEWER_MTIME, _datestr);
+}
+
+int
+archive_matching_newer_ctime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_newer_ctime_str",
+                       MATCH_NEWER_CTIME, _datestr);
+}
+
+int
+archive_matching_newer_ctime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_newer_ctime_str_w",
+                       MATCH_NEWER_CTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_newer_ctime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_equal_or_newer_ctime_str",
+                       MATCH_EQ_NEWER_CTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_newer_ctime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_equal_or_newer_ctime_str_w",
+                       MATCH_EQ_NEWER_CTIME, _datestr);
+}
+
+int
+archive_matching_older_mtime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_older_mtime_str",
+                       MATCH_OLDER_MTIME, _datestr);
+}
+
+int
+archive_matching_older_mtime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_older_mtime_str_w",
+                       MATCH_OLDER_MTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_older_mtime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_equal_or_older_mtime_str",
+                       MATCH_EQ_OLDER_MTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_older_mtime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_equal_or_older_mtime_str_w",
+                       MATCH_EQ_OLDER_MTIME, _datestr);
+}
+
+int
+archive_matching_older_ctime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_older_ctime_str",
+                       MATCH_OLDER_CTIME, _datestr);
+}
+
+int
+archive_matching_older_ctime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_older_ctime_str_w",
+                       MATCH_OLDER_CTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_older_ctime_str(struct archive *_a,
+    const char *_datestr)
+{
+       return set_time_str(_a, "archive_matching_equal_or_older_ctime_str",
+                       MATCH_EQ_OLDER_CTIME, _datestr);
+}
+
+int
+archive_matching_equal_or_older_ctime_str_w(struct archive *_a,
+    const wchar_t *_datestr)
+{
+       return set_time_str_w(_a, "archive_matching_equal_or_older_ctime_str_w",
+                       MATCH_EQ_OLDER_CTIME, _datestr);
+}
+
 /*
  * Test function for time stamps.
  *
@@ -982,41 +1031,140 @@ archive_matching_time_excluded(struct archive *_a,
        return (time_excluded(a, entry));
 }
 
+static int
+set_timefilter(struct archive_matching *a, int timetype, time_t sec, long nsec)
+{
+
+       switch (timetype) {
+       case MATCH_NEWER_MTIME:
+       case MATCH_EQ_NEWER_MTIME:
+               a->newer_mtime_filter = timetype;
+               a->newer_mtime_sec = sec;
+               a->newer_mtime_nsec = nsec;
+               break;
+       case MATCH_OLDER_MTIME:
+       case MATCH_EQ_OLDER_MTIME:
+               a->older_mtime_filter = timetype;
+               a->older_mtime_sec = sec;
+               a->older_mtime_nsec = nsec;
+               break;
+       case MATCH_NEWER_CTIME:
+       case MATCH_EQ_NEWER_CTIME:
+               a->newer_ctime_filter = timetype;
+               a->newer_ctime_sec = sec;
+               a->newer_ctime_nsec = nsec;
+               break;
+       case MATCH_OLDER_CTIME:
+       case MATCH_EQ_OLDER_CTIME:
+               a->older_ctime_filter = timetype;
+               a->older_ctime_sec = sec;
+               a->older_ctime_nsec = nsec;
+               break;
+       }
+       a->setflag |= TIME_IS_SET;
+       return (ARCHIVE_OK);
+}
+
+static int
+set_time_str(struct archive *_a, const char *_fn, int timetype,
+    const char *datestr)
+{
+       struct archive_matching *a;
+       time_t time;
+
+       archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
+           ARCHIVE_STATE_NEW, _fn);
+       a = (struct archive_matching *)_a;
+
+       if (datestr == NULL || *datestr == '\0') {
+               archive_set_error(&(a->archive), EINVAL, "date is empty");
+               return (ARCHIVE_FAILED);
+       }
+       time = get_date(a->now, datestr);
+       if (time == (time_t)-1) {
+               archive_set_error(&(a->archive), EINVAL, "invalid date string");
+               return (ARCHIVE_FAILED);
+       }
+       return set_timefilter(a, timetype, time, 0);
+}
+
+static int
+set_time_str_w(struct archive *_a, const char *_fn, int timetype,
+    const wchar_t *datestr)
+{
+       struct archive_matching *a;
+       struct archive_string as;
+       time_t time;
+
+       archive_check_magic(_a, ARCHIVE_MATCHING_MAGIC,
+           ARCHIVE_STATE_NEW, _fn);
+       a = (struct archive_matching *)_a;
+
+       if (datestr == NULL || *datestr == L'\0') {
+               archive_set_error(&(a->archive), EINVAL, "date is empty");
+               return (ARCHIVE_FAILED);
+       }
+
+       archive_string_init(&as);
+       if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) {
+               archive_string_free(&as);
+               if (errno == ENOMEM)
+                       return (error_nomem(a));
+               archive_set_error(&(a->archive), -1,
+                   "Failed to convert WCS to MBS");
+               return (ARCHIVE_FAILED);
+       }
+       time = get_date(a->now, as.s);
+       archive_string_free(&as);
+       if (time == (time_t)-1) {
+               archive_set_error(&(a->archive), EINVAL, "invalid date string");
+               return (ARCHIVE_FAILED);
+       }
+       return set_timefilter(a, timetype, time, 0);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #define EPOC_TIME (116444736000000000ui64)
 #else
 static int
-get_time(struct archive_matching *a, struct stat *st, int is_ctime,
-    time_t *time, long *ns)
+set_timefilter_stat(struct archive_matching *a, int timetype, struct stat *st)
 {
        struct archive_entry *ae;
+       time_t time;
+       long ns;
 
        ae = archive_entry_new();
        if (ae == NULL)
                return (error_nomem(a));
        archive_entry_copy_stat(ae, st);
-       if (is_ctime) {
-               *time = archive_entry_ctime(ae);
-               *ns = archive_entry_ctime_nsec(ae);
+       if (TIMETYPE_IS_CTIME(timetype)) {
+               time = archive_entry_ctime(ae);
+               ns = archive_entry_ctime_nsec(ae);
        } else {
-               *time = archive_entry_mtime(ae);
-               *ns = archive_entry_mtime_nsec(ae);
+               time = archive_entry_mtime(ae);
+               ns = archive_entry_mtime_nsec(ae);
        }
        archive_entry_free(ae);
-       return (ARCHIVE_OK);
+       return set_timefilter(a, timetype, time, ns);
 }
 #endif
 
 static int
-get_filetime_mbs(struct archive_matching *a, const char *path,
-    int is_ctime, time_t *time, long *ns)
+set_timefilter_pathname_mbs(struct archive_matching *a, int timetype,
+    const char *path)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
        /* NOTE: stat() on Windows cannot handle nano seconds. */
        HANDLE h;
        WIN32_FIND_DATA d;
        ULARGE_INTEGER utc;
+       time_t time;
+       long ns;
 
+       if (path == NULL || *path == '\0') {
+               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+               return (ARCHIVE_FAILED);
+       }
        h = FindFirstFileA(path, &d);
        if (h == INVALID_HANDLE_VALUE) {
                la_dosmaperr(GetLastError());
@@ -1025,7 +1173,7 @@ get_filetime_mbs(struct archive_matching *a, const char *path,
                return (ARCHIVE_FAILED);
        }
        FindClose(h);
-       if (is_ctime) {
+       if (TIMETYPE_IS_CTIME(timetype)) {
                utc.HighPart = d.ftCreationTime.dwHighDateTime;
                utc.LowPart = d.ftCreationTime.dwLowDateTime;
        } else {
@@ -1034,33 +1182,43 @@ get_filetime_mbs(struct archive_matching *a, const char *path,
        }
        if (utc.QuadPart >= EPOC_TIME) {
                utc.QuadPart -= EPOC_TIME;
-               *time = (time_t)(utc.QuadPart / 10000000);
-               *ns = (long)(utc.QuadPart % 10000000) * 100;
+               time = (time_t)(utc.QuadPart / 10000000);
+               ns = (long)(utc.QuadPart % 10000000) * 100;
        } else {
-               *time = 0;
-               *ns = 0;
+               time = 0;
+               ns = 0;
        }
-       return (ARCHIVE_OK);
+       return set_timefilter(a, timetype, time, ns);
 #else
        struct stat st;
 
+       if (path == NULL || *path == '\0') {
+               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+               return (ARCHIVE_FAILED);
+       }
        if (stat(path, &st) != 0) {
                archive_set_error(&(a->archive), errno, "Failed to stat()");
                return (ARCHIVE_FAILED);
        }
-       return (get_time(a, &st, is_ctime, time, ns));
+       return (set_timefilter_stat(a, timetype, &st));
 #endif
 }
 
 static int
-get_filetime_wcs(struct archive_matching *a, const wchar_t *path,
-    int is_ctime, time_t *time, long *ns)
+set_timefilter_pathname_wcs(struct archive_matching *a, int timetype,
+    const wchar_t *path)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
        HANDLE h;
        WIN32_FIND_DATAW d;
        ULARGE_INTEGER utc;
+       time_t time;
+       long ns;
 
+       if (path == NULL || *path == L'\0') {
+               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+               return (ARCHIVE_FAILED);
+       }
        h = FindFirstFileW(path, &d);
        if (h == INVALID_HANDLE_VALUE) {
                la_dosmaperr(GetLastError());
@@ -1069,7 +1227,7 @@ get_filetime_wcs(struct archive_matching *a, const wchar_t *path,
                return (ARCHIVE_FAILED);
        }
        FindClose(h);
-       if (is_ctime) {
+       if (TIMETYPE_IS_CTIME(timetype)) {
                utc.HighPart = d.ftCreationTime.dwHighDateTime;
                utc.LowPart = d.ftCreationTime.dwLowDateTime;
        } else {
@@ -1078,17 +1236,21 @@ get_filetime_wcs(struct archive_matching *a, const wchar_t *path,
        }
        if (utc.QuadPart >= EPOC_TIME) {
                utc.QuadPart -= EPOC_TIME;
-               *time = (time_t)(utc.QuadPart / 10000000);
-               *ns = (long)(utc.QuadPart % 10000000) * 100;
+               time = (time_t)(utc.QuadPart / 10000000);
+               ns = (long)(utc.QuadPart % 10000000) * 100;
        } else {
-               *time = 0;
-               *ns = 0;
+               time = 0;
+               ns = 0;
        }
-       return (ARCHIVE_OK);
+       return set_timefilter(a, timetype, time, ns);
 #else
        struct stat st;
        struct archive_string as;
 
+       if (path == NULL || *path == L'\0') {
+               archive_set_error(&(a->archive), EINVAL, "pathname is empty");
+               return (ARCHIVE_FAILED);
+       }
        archive_string_init(&as);
        if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) {
                archive_string_free(&as);
@@ -1104,7 +1266,7 @@ get_filetime_wcs(struct archive_matching *a, const wchar_t *path,
                return (ARCHIVE_FAILED);
        }
        archive_string_free(&as);
-       return (get_time(a, &st, is_ctime, time, ns));
+       return (set_timefilter_stat(a, timetype, &st));
 #endif
 }
 
@@ -1272,13 +1434,17 @@ time_excluded(struct archive_matching *a, struct archive_entry *entry)
                        sec = archive_entry_mtime(entry);
                if (sec < a->newer_ctime_sec)
                        return (1); /* Too old, skip it. */
-               if (archive_entry_ctime_is_set(entry))
-                       nsec = archive_entry_ctime_nsec(entry);
-               else
-                       nsec = archive_entry_mtime_nsec(entry);
-               if (sec == a->newer_ctime_sec
-                   && nsec <= a->newer_ctime_nsec)
-                       return (1); /* Too old, skip it. */
+               if (sec == a->newer_ctime_sec) {
+                       if (archive_entry_ctime_is_set(entry))
+                               nsec = archive_entry_ctime_nsec(entry);
+                       else
+                               nsec = archive_entry_mtime_nsec(entry);
+                       if (nsec < a->newer_ctime_nsec)
+                               return (1); /* Too old, skip it. */
+                       if (nsec == a->newer_ctime_nsec &&
+                           (a->newer_ctime_filter & TCOND_EQUAL) == 0)
+                               return (1); /* Equal, skip it. */
+               }
        }
        if (a->older_ctime_filter) {
                /* If ctime is not set, use mtime instead. */
@@ -1288,31 +1454,43 @@ time_excluded(struct archive_matching *a, struct archive_entry *entry)
                        sec = archive_entry_mtime(entry);
                if (sec > a->older_ctime_sec)
                        return (1); /* Too new, skip it. */
-               if (archive_entry_ctime_is_set(entry))
-                       nsec = archive_entry_ctime_nsec(entry);
-               else
-                       nsec = archive_entry_mtime_nsec(entry);
-               if (sec == a->older_ctime_sec
-                   && nsec >= a->older_ctime_nsec)
-                       return (1); /* Too new, skip it. */
+               if (sec == a->older_ctime_sec) {
+                       if (archive_entry_ctime_is_set(entry))
+                               nsec = archive_entry_ctime_nsec(entry);
+                       else
+                               nsec = archive_entry_mtime_nsec(entry);
+                       if (nsec > a->older_ctime_nsec)
+                               return (1); /* Too new, skip it. */
+                       if (nsec == a->older_ctime_nsec &&
+                           (a->older_ctime_filter & TCOND_EQUAL) == 0)
+                               return (1); /* Eeual, skip it. */
+               }
        }
        if (a->newer_mtime_filter) {
                sec = archive_entry_mtime(entry);
                if (sec < a->newer_mtime_sec)
                        return (1); /* Too old, skip it. */
-               nsec = archive_entry_mtime_nsec(entry);
-               if (sec == a->newer_mtime_sec
-                   && nsec <= a->newer_mtime_nsec)
-                       return (1); /* Too old, skip it. */
+               if (sec == a->newer_mtime_sec) {
+                       nsec = archive_entry_mtime_nsec(entry);
+                       if (nsec < a->newer_mtime_nsec)
+                               return (1); /* Too old, skip it. */
+                       if (nsec == a->newer_mtime_nsec &&
+                           (a->newer_mtime_filter & TCOND_EQUAL) == 0)
+                               return (1); /* Equal, skip it. */
+               }
        }
        if (a->older_mtime_filter) {
                sec = archive_entry_mtime(entry);
                if (sec > a->older_mtime_sec)
                        return (1); /* Too new, skip it. */
                nsec = archive_entry_mtime_nsec(entry);
-               if (sec == a->older_mtime_sec
-                   && nsec >= a->older_mtime_nsec)
-                       return (1); /* Too new, skip it. */
+               if (sec == a->older_mtime_sec) {
+                       if (nsec > a->older_mtime_nsec)
+                               return (1); /* Too new, skip it. */
+                       if (nsec == a->older_mtime_nsec &&
+                           (a->older_mtime_filter & TCOND_EQUAL) == 0)
+                               return (1); /* Equal, skip it. */
+               }
        }
 
        /* If there is no incluson list, include the file. */
index 479681cd43a7f7c6676adfe6a36ee5628dd397fc..7f0bfff5fd30fd2d7eff292b53ca33db5e72d155 100644 (file)
@@ -15,6 +15,7 @@ IF(ENABLE_TEST)
     test_archive_api_feature.c
     test_archive_clear_error.c
     test_archive_crypto.c
+    test_archive_getdate.c
     test_archive_matching_owner.c
     test_archive_matching_path.c
     test_archive_matching_time.c
similarity index 96%
rename from tar/test/test_getdate.c
rename to libarchive/test/test_archive_getdate.c
index eac571049fe8877701be06ce4a6fda89fb70b1e7..d6d5fdbf3873cebc1c7a92a8b0d9ddcdae4a41cd 100644 (file)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_getdate.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
+__FBSDID("$FreeBSD$");
 
 #include <time.h>
 
@@ -31,7 +31,8 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/test/test_getdate.c,v 1.2 2008/05/26 17:10:1
  * Verify that the getdate() function works.
  */
 
-time_t get_date(time_t, const char *);
+time_t __archive_get_date(time_t, const char *);
+#define get_date __archive_get_date
 
 DEFINE_TEST(test_getdate)
 {
index edd459e0b1f02dcdc73a9ac2cae354cf51dfe1d3..e9d84bc787cd7c15ca67b2a0842cd285ec3dceba 100644 (file)
@@ -26,6 +26,8 @@
 #include "test.h"
 __FBSDID("$FreeBSD$");
 
+time_t __archive_get_date(time_t, const char *);
+
 static void
 test_newer_time(void)
 {
@@ -77,6 +79,184 @@ test_newer_time(void)
        archive_matching_free(m);
 }
 
+static void
+test_newer_time_str(void)
+{
+       struct archive_entry *ae;
+       struct archive *m;
+       time_t now, t;
+
+       if (!assert((m = archive_matching_new()) != NULL))
+               return;
+       if (!assert((ae = archive_entry_new()) != NULL)) {
+               archive_matching_free(m);
+               return;
+       }
+
+       time(&now);
+
+       assertEqualIntA(m, 0, archive_matching_newer_mtime_str(m,
+                               "1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_newer_ctime_str(m,
+                               "1980/2/1 0:0:0 UTC"));
+
+       /* Test1: Allow newer time. */
+       archive_entry_copy_pathname(ae, "file1");
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       archive_entry_set_mtime(ae, t, 0);
+       archive_entry_set_ctime(ae, t, 1);
+       failure("Its ctime should be excluded");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+
+       /* Test2: Allow equal or newer time. */
+       assertEqualIntA(m, 0, archive_matching_equal_or_newer_mtime_str(m,
+                               "1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_equal_or_newer_ctime_str(m,
+                               "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");
+       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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       /* Clean up. */
+       archive_entry_free(ae);
+       archive_matching_free(m);
+}
+
+static void
+test_newer_time_str_w(void)
+{
+       struct archive_entry *ae;
+       struct archive *m;
+       time_t now, t;
+
+       if (!assert((m = archive_matching_new()) != NULL))
+               return;
+       if (!assert((ae = archive_entry_new()) != NULL)) {
+               archive_matching_free(m);
+               return;
+       }
+
+       time(&now);
+
+       assertEqualIntA(m, 0, archive_matching_newer_mtime_str_w(m,
+                               L"1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_newer_ctime_str_w(m,
+                               L"1980/2/1 0:0:0 UTC"));
+
+       /* Test1: Allow newer time. */
+       archive_entry_copy_pathname(ae, "file1");
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       archive_entry_set_mtime(ae, t, 0);
+       archive_entry_set_ctime(ae, t, 1);
+       failure("Its ctime should be excluded");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+
+       /* Test2: Allow equal or newer time. */
+       assertEqualIntA(m, 0, archive_matching_equal_or_newer_mtime_str_w(m,
+                               L"1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_equal_or_newer_ctime_str_w(m,
+                               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");
+       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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       /* Clean up. */
+       archive_entry_free(ae);
+       archive_matching_free(m);
+}
+
 static void
 test_newer_mtime_than_file_mbs(void)
 {
@@ -357,6 +537,188 @@ test_older_time(void)
        archive_matching_free(m);
 }
 
+static void
+test_older_time_str(void)
+{
+       struct archive_entry *ae;
+       struct archive *m;
+       time_t now, t;
+
+       if (!assert((m = archive_matching_new()) != NULL))
+               return;
+       if (!assert((ae = archive_entry_new()) != NULL)) {
+               archive_matching_free(m);
+               return;
+       }
+
+       time(&now);
+
+       /* Test1: Allow newer time. */
+       assertEqualIntA(m, 0, archive_matching_older_mtime_str(m,
+                               "1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_older_ctime_str(m,
+                               "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");
+       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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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");
+       archive_entry_set_ctime(ae, t, 0);
+       failure("Its mtime should be excluded");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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");
+       archive_entry_set_ctime(ae, t, 0);
+       failure("Its ctime should be excluded");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       /* Test2: Allow equal or newer time. */
+       assertEqualIntA(m, 0, archive_matching_equal_or_older_mtime_str(m,
+                               "1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_equal_or_older_ctime_str(m,
+                               "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");
+       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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       /* Clean up. */
+       archive_entry_free(ae);
+       archive_matching_free(m);
+}
+
+static void
+test_older_time_str_w(void)
+{
+       struct archive_entry *ae;
+       struct archive *m;
+       time_t now, t;
+
+       if (!assert((m = archive_matching_new()) != NULL))
+               return;
+       if (!assert((ae = archive_entry_new()) != NULL)) {
+               archive_matching_free(m);
+               return;
+       }
+
+       time(&now);
+
+       /* Test1: Allow newer time. */
+       assertEqualIntA(m, 0, archive_matching_older_mtime_str_w(m,
+                               L"1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_older_ctime_str_w(m,
+                               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");
+       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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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");
+       archive_entry_set_ctime(ae, t, 0);
+       failure("Its mtime should be excluded");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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");
+       archive_entry_set_ctime(ae, t, 0);
+       failure("Its ctime should be excluded");
+       assertEqualInt(1, archive_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       /* Test2: Allow equal or newer time. */
+       assertEqualIntA(m, 0, archive_matching_equal_or_older_mtime_str_w(m,
+                               L"1980/2/1 0:0:0 UTC"));
+       assertEqualIntA(m, 0, archive_matching_equal_or_older_ctime_str_w(m,
+                               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");
+       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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(0, archive_matching_excluded(m, ae));
+
+       t = __archive_get_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_matching_time_excluded(m, ae));
+       assertEqualInt(1, archive_matching_excluded(m, ae));
+
+       /* Clean up. */
+       archive_entry_free(ae);
+       archive_matching_free(m);
+}
+
 static void
 test_older_mtime_than_file_mbs(void)
 {
@@ -932,8 +1294,12 @@ DEFINE_TEST(test_archive_matching_time)
 
        /* Test: matching newer times. */
        test_newer_time();
+       test_newer_time_str();
+       test_newer_time_str_w();
        /* Test: matching older times. */
        test_older_time();
+       test_older_time_str();
+       test_older_time_str_w();
 
        /*
         * Create sample files for tests matching mtime.
index 39b336cd9392ec304d1a63fe87c512629e44a2d8..983aa342356a255636c3d1bd08b888d332de3151 100644 (file)
@@ -10,7 +10,6 @@ IF(ENABLE_TAR)
     bsdtar.h
     bsdtar_platform.h
     cmdline.c
-    getdate.c
     read.c
     subst.c
     util.c
index c1e71f1a8099e09638cb981685be08a106b8d970..0b646010d733624da76d625a3d1a9ab3686e470b 100644 (file)
@@ -118,9 +118,6 @@ need_report(void)
 }
 #endif
 
-/* External function to parse a date/time string */
-time_t get_date(time_t, const char *);
-
 static void             long_help(void);
 static void             only_mode(struct bsdtar *, const char *opt,
                             const char *valid);
@@ -140,7 +137,6 @@ main(int argc, char **argv)
        char                     option_o;
        char                     possible_help_request;
        char                     buff[16];
-       time_t                   now;
 
        /*
         * Use a pointer for consistency, but stack-allocated storage
@@ -192,8 +188,6 @@ main(int argc, char **argv)
                        lafe_progname = *argv;
        }
 
-       time(&now);
-
 #if HAVE_SETLOCALE
        if (setlocale(LC_ALL, "") == NULL)
                lafe_warnc(0, "Failed to set default locale");
@@ -400,8 +394,8 @@ main(int argc, char **argv)
                 * TODO: Add corresponding "older" options to reverse these.
                 */
                case OPTION_NEWER_CTIME: /* GNU tar */
-                       if (archive_matching_newer_ctime(bsdtar->matching,
-                           get_date(now, bsdtar->argument), 0) != ARCHIVE_OK)
+                       if (archive_matching_newer_ctime_str(bsdtar->matching,
+                           bsdtar->argument) != ARCHIVE_OK)
                                lafe_errc(1, 0, "Error : %s",
                                    archive_error_string(bsdtar->matching));
                        break;
@@ -412,8 +406,8 @@ main(int argc, char **argv)
                                    archive_error_string(bsdtar->matching));
                        break;
                case OPTION_NEWER_MTIME: /* GNU tar */
-                       if (archive_matching_newer_mtime(bsdtar->matching,
-                           get_date(now, bsdtar->argument), 0) != ARCHIVE_OK)
+                       if (archive_matching_newer_mtime_str(bsdtar->matching,
+                           bsdtar->argument) != ARCHIVE_OK)
                                lafe_errc(1, 0, "Error : %s",
                                    archive_error_string(bsdtar->matching));
                        break;
index cb738b6ebe87f81a2a3013f5d735c7cd6cd14a9a..067e7f6b995ca2da34616f5d615b1d5e478594bb 100644 (file)
@@ -5,14 +5,12 @@
 ############################################
 IF(ENABLE_TAR AND ENABLE_TEST)
   SET(bsdtar_test_SOURCES
-    ../getdate.c
     main.c
     test.h
     test_0.c
     test_basic.c
     test_copy.c
     test_empty_mtree.c
-    test_getdate.c
     test_help.c
     test_option_C_upper.c
     test_option_H_upper.c