From 14c65f15f708c27dc434db1f0d112fad2a0b007c Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 20 Aug 2012 18:40:53 -0500 Subject: [PATCH] More timestamp changes: Set timestamp on extracted files --- src/dentry.c | 34 ++++++++++++++++++++++++++-------- src/extract.c | 19 ++++++++++++++++--- src/timestamp.h | 8 ++++++++ 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/dentry.c b/src/dentry.c index c3165544..b62f53ae 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -30,15 +30,17 @@ * along with wimlib; if not, see http://www.gnu.org/licenses/. */ +#include +#include +#include +#include + #include "wimlib_internal.h" #include "dentry.h" #include "io.h" #include "timestamp.h" #include "lookup_table.h" #include "sha1.h" -#include -#include -#include /* * Returns true if @dentry has the UTF-8 file name @name that has length @@ -78,6 +80,10 @@ void stbuf_to_dentry(const struct stat *stbuf, struct dentry *dentry) else dentry->hard_link = (u64)stbuf->st_ino | ((u64)stbuf->st_dev << (sizeof(ino_t) * 8)); + /* Set timestamps */ + dentry->creation_time = timespec_to_wim_timestamp(&stbuf->st_mtim); + dentry->last_write_time = timespec_to_wim_timestamp(&stbuf->st_mtim); + dentry->last_access_time = timespec_to_wim_timestamp(&stbuf->st_atim); } @@ -423,11 +429,23 @@ int print_dentry(struct dentry *dentry, void *lookup_table) file_attr_flags[i].name); printf("Security ID = %d\n", dentry->security_id); printf("Subdir offset = %"PRIu64"\n", dentry->subdir_offset); - /*printf("Unused1 = 0x%"PRIu64"\n", dentry->unused1);*/ - /*printf("Unused2 = %"PRIu64"\n", dentry->unused2);*/ - printf("Creation Time = 0x%"PRIx64"\n", dentry->creation_time); - printf("Last Access Time = 0x%"PRIx64"\n", dentry->last_access_time); - printf("Last Write Time = 0x%"PRIx64"\n", dentry->last_write_time); +#if 0 + printf("Unused1 = 0x%"PRIu64"\n", dentry->unused1); + printf("Unused2 = %"PRIu64"\n", dentry->unused2); +#endif +#if 0 + printf("Creation Time = 0x%"PRIx64"\n"); + printf("Last Access Time = 0x%"PRIx64"\n"); + printf("Last Write Time = 0x%"PRIx64"\n"); +#endif + + time_t creat_time = wim_timestamp_to_unix(dentry->creation_time); + time_t access_time = wim_timestamp_to_unix(dentry->last_access_time); + time_t mod_time = wim_timestamp_to_unix(dentry->last_write_time); + printf("Creation Time = %s", asctime(localtime(&creat_time))); + printf("Last Access Time = %s", asctime(localtime(&access_time))); + printf("Last Write Time = %s", asctime(localtime(&mod_time))); + hash = dentry_stream_hash(dentry, 0); if (hash) { printf("Hash = 0x"); diff --git a/src/extract.c b/src/extract.c index 12196602..701d1294 100644 --- a/src/extract.c +++ b/src/extract.c @@ -27,6 +27,7 @@ #include "wimlib_internal.h" #include "dentry.h" #include "lookup_table.h" +#include "timestamp.h" #include "xml.h" #include #include @@ -293,6 +294,7 @@ static int extract_dentry(struct dentry *dentry, void *arg) int extract_flags = args->extract_flags; size_t len = strlen(args->output_dir); char output_path[len + dentry->full_path_utf8_len + 1]; + int ret; if (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE) { wimlib_assert(dentry->full_path_utf8); @@ -304,12 +306,23 @@ static int extract_dentry(struct dentry *dentry, void *arg) output_path[len + dentry->full_path_utf8_len] = '\0'; if (dentry_is_symlink(dentry)) - return extract_symlink(dentry, output_path, w); + ret = extract_symlink(dentry, output_path, w); else if (dentry_is_directory(dentry)) - return extract_directory(output_path); + ret = extract_directory(output_path); else - return extract_regular_file(w, dentry, args->output_dir, + ret = extract_regular_file(w, dentry, args->output_dir, output_path, extract_flags); + if (ret != 0) + return ret; + + struct timeval tv[2]; + wim_timestamp_to_timeval(dentry->last_access_time, &tv[0]); + wim_timestamp_to_timeval(dentry->last_write_time, &tv[1]); + if (lutimes(output_path, tv) != 0) { + WARNING("Failed to set timestamp on file `%s': %s", + output_path, strerror(errno)); + } + return 0; } diff --git a/src/timestamp.h b/src/timestamp.h index 9c82c23e..6f08fc2e 100644 --- a/src/timestamp.h +++ b/src/timestamp.h @@ -36,6 +36,13 @@ static inline u64 timeval_to_wim_timestamp(const struct timeval *tv) + (u64)tv->tv_usec * intervals_per_microsecond; } +static inline void wim_timestamp_to_timeval(u64 timestamp, struct timeval *tv) +{ + tv->tv_sec = (timestamp - intervals_1601_to_1970) / intervals_per_second; + tv->tv_usec = ((timestamp - intervals_1601_to_1970) / + intervals_per_microsecond) % 1000000; +} + static inline u64 timespec_to_wim_timestamp(const struct timespec *ts) { return intervals_1601_to_1970 @@ -43,6 +50,7 @@ static inline u64 timespec_to_wim_timestamp(const struct timespec *ts) + (u64)ts->tv_nsec / nanoseconds_per_interval; } + extern u64 get_wim_timestamp(); #endif -- 2.43.0