From 6902e811f60327dce35d2068d05d85a3c7a345c4 Mon Sep 17 00:00:00 2001 From: kientzle Date: Tue, 30 Sep 2008 03:53:03 +0000 Subject: MfP4: Support for storing birthtime in archive_entry objects. Submitted by: Pedro Giffuni MFC after: 30 days --- lib/libarchive/archive_entry.c | 34 ++++++++++++++++++++++++++++++++ lib/libarchive/archive_entry.h | 5 +++++ lib/libarchive/archive_entry_copy_stat.c | 6 ++++++ lib/libarchive/archive_entry_private.h | 3 +++ lib/libarchive/archive_entry_stat.c | 6 ++++++ lib/libarchive/config_freebsd.h | 2 ++ lib/libarchive/test/test_entry.c | 17 ++++++++++++++++ 7 files changed, 73 insertions(+) (limited to 'lib') diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c index aaf1c95..28054a9 100644 --- a/lib/libarchive/archive_entry.c +++ b/lib/libarchive/archive_entry.c @@ -461,6 +461,24 @@ archive_entry_atime_is_set(struct archive_entry *entry) } 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) { return (entry->ae_stat.aest_ctime); @@ -838,6 +856,22 @@ archive_entry_unset_atime(struct archive_entry *entry) } 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) { entry->stat_valid = 0; diff --git a/lib/libarchive/archive_entry.h b/lib/libarchive/archive_entry.h index 0505c21..4e78dbe 100644 --- a/lib/libarchive/archive_entry.h +++ b/lib/libarchive/archive_entry.h @@ -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); diff --git a/lib/libarchive/archive_entry_copy_stat.c b/lib/libarchive/archive_entry_copy_stat.c index 5b3d35e..bd88b74 100644 --- a/lib/libarchive/archive_entry_copy_stat.c +++ b/lib/libarchive/archive_entry_copy_stat.c @@ -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); diff --git a/lib/libarchive/archive_entry_private.h b/lib/libarchive/archive_entry_private.h index c7aa71d..4614a4f 100644 --- a/lib/libarchive/archive_entry_private.h +++ b/lib/libarchive/archive_entry_private.h @@ -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; @@ -142,6 +144,7 @@ struct archive_entry { #define AE_SET_ATIME 4 #define AE_SET_CTIME 8 #define AE_SET_MTIME 16 +#define AE_SET_BIRTHTIME 32 #define AE_SET_SIZE 64 /* diff --git a/lib/libarchive/archive_entry_stat.c b/lib/libarchive/archive_entry_stat.c index d06ee2c..9e5f0c2 100644 --- a/lib/libarchive/archive_entry_stat.c +++ b/lib/libarchive/archive_entry_stat.c @@ -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 diff --git a/lib/libarchive/config_freebsd.h b/lib/libarchive/config_freebsd.h index 3c25631..a11b0b8 100644 --- a/lib/libarchive/config_freebsd.h +++ b/lib/libarchive/config_freebsd.h @@ -89,6 +89,8 @@ #define HAVE_STRING_H 1 #define HAVE_STRRCHR 1 #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 +#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1 +#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1 #define HAVE_STRUCT_STAT_ST_FLAGS 1 #define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1 #define HAVE_SYS_ACL_H 1 diff --git a/lib/libarchive/test/test_entry.c b/lib/libarchive/test/test_entry.c index 2a1c901..31cb213 100644 --- a/lib/libarchive/test/test_entry.c +++ b/lib/libarchive/test/test_entry.c @@ -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); -- cgit v1.1