]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
archive_entry support for storing and managing birthtime data
authorTim Kientzle <kientzle@gmail.com>
Wed, 17 Sep 2008 22:04:52 +0000 (18:04 -0400)
committerTim Kientzle <kientzle@gmail.com>
Wed, 17 Sep 2008 22:04:52 +0000 (18:04 -0400)
Submitted by: Pedro Giffuni

SVN-Revision: 209

configure.ac
libarchive/archive_entry.c
libarchive/archive_entry.h
libarchive/archive_entry_copy_stat.c
libarchive/archive_entry_private.h
libarchive/archive_entry_stat.c
libarchive/test/test_entry.c

index 75cb4d1434906786ac102f5a6b40a7f74499a28f..b49b00bc340867da34912f92de8f96f0a1aeec29 100644 (file)
@@ -191,7 +191,12 @@ AC_CHECK_TYPE(off_t, [long long])
 AC_TYPE_SIZE_T
 AC_CHECK_TYPE(id_t, [unsigned long])
 AC_CHECK_TYPE(uintptr_t, [unsigned int])
+
+# Check for birthtime in struct stat
+AC_CHECK_MEMBERS([struct stat.st_birthtime])
+
 # Check for high-resolution timestamps in struct stat
+AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec])
 AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec])
 AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
 # Check for block size support in struct stat
index 9c870f28f3098ed010b1336725193250f2c65d1f..1ea0b9469164601cbcf479eff9d2bcdbbcd753fc 100644 (file)
@@ -460,6 +460,24 @@ archive_entry_atime_is_set(struct archive_entry *entry)
        return (entry->ae_set & AE_SET_ATIME);
 }
 
+time_t
+archive_entry_birthtime(struct archive_entry *entry)
+{
+       return (entry->ae_stat.aest_birthtime);
+}
+
+long
+archive_entry_birthtime_nsec(struct archive_entry *entry)
+{
+       return (entry->ae_stat.aest_birthtime_nsec);
+}
+
+int
+archive_entry_birthtime_is_set(struct archive_entry *entry)
+{
+       return (entry->ae_set & AE_SET_BIRTHTIME);
+}
+
 time_t
 archive_entry_ctime(struct archive_entry *entry)
 {
@@ -837,6 +855,22 @@ archive_entry_unset_atime(struct archive_entry *entry)
        entry->ae_set &= ~AE_SET_ATIME;
 }
 
+void
+archive_entry_set_birthtime(struct archive_entry *entry, time_t m, long ns)
+{
+       entry->stat_valid = 0;
+       entry->ae_set |= AE_SET_BIRTHTIME;
+       entry->ae_stat.aest_birthtime = m;
+       entry->ae_stat.aest_birthtime_nsec = ns;
+}
+
+void
+archive_entry_unset_birthtime(struct archive_entry *entry)
+{
+       archive_entry_set_birthtime(entry, 0, 0);
+       entry->ae_set &= ~AE_SET_BIRTHTIME;
+}
+
 void
 archive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns)
 {
index 88f4ad857f5d907c61d64978d424d1438205c07d..25a136ac689226d5675c278a6c1c1c0c3a3b5fb2 100644 (file)
@@ -174,6 +174,9 @@ __LA_DECL struct archive_entry      *archive_entry_new(void);
 __LA_DECL time_t        archive_entry_atime(struct archive_entry *);
 __LA_DECL long          archive_entry_atime_nsec(struct archive_entry *);
 __LA_DECL int           archive_entry_atime_is_set(struct archive_entry *);
+__LA_DECL time_t        archive_entry_birthtime(struct archive_entry *);
+__LA_DECL long          archive_entry_birthtime_nsec(struct archive_entry *);
+__LA_DECL int           archive_entry_birthtime_is_set(struct archive_entry *);
 __LA_DECL time_t        archive_entry_ctime(struct archive_entry *);
 __LA_DECL long          archive_entry_ctime_nsec(struct archive_entry *);
 __LA_DECL int           archive_entry_ctime_is_set(struct archive_entry *);
@@ -224,6 +227,8 @@ __LA_DECL const wchar_t     *archive_entry_uname_w(struct archive_entry *);
 
 __LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
 __LA_DECL void  archive_entry_unset_atime(struct archive_entry *);
+__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
+__LA_DECL void  archive_entry_unset_birthtime(struct archive_entry *);
 __LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
 __LA_DECL void  archive_entry_unset_ctime(struct archive_entry *);
 __LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
index 514db02743b4f8ae713aafe51d9754ad7bbbd2e0..ba8812a9fbbba587bad7eaec3a834b1756db0097 100644 (file)
@@ -47,6 +47,12 @@ archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
        archive_entry_set_atime(entry, st->st_atime, 0);
        archive_entry_set_ctime(entry, st->st_ctime, 0);
        archive_entry_set_mtime(entry, st->st_mtime, 0);
+#if HAVE_STRUCT_STAT_ST_BIRTHTIME
+       archive_entry_set_birthtime(entry, st->st_birthtime, 0);
+#endif
+#endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+       archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
 #endif
        archive_entry_set_dev(entry, st->st_dev);
        archive_entry_set_gid(entry, st->st_gid);
index 9b3e7f5782f8030409b7aecaa9fb005578b9190c..622fd236581db74a9fa1e32ea18fdfce30381c0b 100644 (file)
@@ -112,6 +112,8 @@ struct archive_entry {
                uint32_t        aest_ctime_nsec;
                int64_t         aest_mtime;
                uint32_t        aest_mtime_nsec;
+               int64_t         aest_birthtime;
+               uint32_t        aest_birthtime_nsec;
                gid_t           aest_gid;
                ino_t           aest_ino;
                mode_t          aest_mode;
index 6ef5b37287f5066cc8ecd1d68fd5897493fb6622..5a627d7d8a64d259e389f37dbfff33596cf9cb07 100644 (file)
@@ -64,6 +64,9 @@ archive_entry_stat(struct archive_entry *entry)
         * the appropriate conversions get invoked.
         */
        st->st_atime = archive_entry_atime(entry);
+#if HAVE_STRUCT_STAT_ST_BIRTHTIME
+       st->st_birthtime = archive_entry_birthtime(entry);
+#endif
        st->st_ctime = archive_entry_ctime(entry);
        st->st_mtime = archive_entry_mtime(entry);
        st->st_dev = archive_entry_dev(entry);
@@ -88,6 +91,9 @@ archive_entry_stat(struct archive_entry *entry)
        st->st_ctim.tv_nsec = archive_entry_ctime_nsec(entry);
        st->st_mtim.tv_nsec = archive_entry_mtime_nsec(entry);
 #endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+       st->st_birthtimespec.tv_nsec = archive_entry_birthtime_nsec(entry);
+#endif
 
        /*
         * TODO: On Linux, store 32 or 64 here depending on whether
index 9891b06693ff8203f6eef7bd18c5df661a379c0e..8b9cb8b3c5dc826630a8e461df72cd84e1220111 100644 (file)
@@ -79,6 +79,15 @@ DEFINE_TEST(test_entry)
        assertEqualInt(archive_entry_atime_nsec(e), 0);
        assert(!archive_entry_atime_is_set(e));
 
+       /* birthtime */
+       archive_entry_set_birthtime(e, 17579, 24990);
+       assertEqualInt(archive_entry_birthtime(e), 17579);
+       assertEqualInt(archive_entry_birthtime_nsec(e), 24990);
+       archive_entry_unset_birthtime(e);
+       assertEqualInt(archive_entry_birthtime(e), 0);
+       assertEqualInt(archive_entry_birthtime_nsec(e), 0);
+       assert(!archive_entry_birthtime_is_set(e));
+
        /* ctime */
        archive_entry_set_ctime(e, 13580, 24681);
        assertEqualInt(archive_entry_ctime(e), 13580);
@@ -312,6 +321,7 @@ DEFINE_TEST(test_entry)
        /* Set values in 'e' */
        archive_entry_clear(e);
        archive_entry_set_atime(e, 13579, 24680);
+       archive_entry_set_birthtime(e, 13779, 24990);
        archive_entry_set_ctime(e, 13580, 24681);
 #if ARCHIVE_VERSION_NUMBER >= 1009000
        archive_entry_set_dev(e, 235);
@@ -348,6 +358,8 @@ DEFINE_TEST(test_entry)
        /* Clone should have same contents. */
        assertEqualInt(archive_entry_atime(e2), 13579);
        assertEqualInt(archive_entry_atime_nsec(e2), 24680);
+       assertEqualInt(archive_entry_birthtime(e2), 13779);
+       assertEqualInt(archive_entry_birthtime_nsec(e2), 24990);
        assertEqualInt(archive_entry_ctime(e2), 13580);
        assertEqualInt(archive_entry_ctime_nsec(e2), 24681);
 #if ARCHIVE_VERSION_NUMBER >= 1009000
@@ -435,6 +447,7 @@ DEFINE_TEST(test_entry)
 
        /* Change the original */
        archive_entry_set_atime(e, 13580, 24690);
+       archive_entry_set_birthtime(e, 13980, 24999);
        archive_entry_set_ctime(e, 13590, 24691);
 #if ARCHIVE_VERSION_NUMBER >= 1009000
        archive_entry_set_dev(e, 245);
@@ -468,6 +481,8 @@ DEFINE_TEST(test_entry)
        /* Clone should still have same contents. */
        assertEqualInt(archive_entry_atime(e2), 13579);
        assertEqualInt(archive_entry_atime_nsec(e2), 24680);
+       assertEqualInt(archive_entry_birthtime(e2), 13779);
+       assertEqualInt(archive_entry_birthtime_nsec(e2), 24990);
        assertEqualInt(archive_entry_ctime(e2), 13580);
        assertEqualInt(archive_entry_ctime_nsec(e2), 24681);
 #if ARCHIVE_VERSION_NUMBER >= 1009000
@@ -561,6 +576,8 @@ DEFINE_TEST(test_entry)
        archive_entry_clear(e);
        assertEqualInt(archive_entry_atime(e), 0);
        assertEqualInt(archive_entry_atime_nsec(e), 0);
+       assertEqualInt(archive_entry_birthtime(e), 0);
+       assertEqualInt(archive_entry_birthtime_nsec(e), 0);
        assertEqualInt(archive_entry_ctime(e), 0);
        assertEqualInt(archive_entry_ctime_nsec(e), 0);
        assertEqualInt(archive_entry_dev(e), 0);