More timestamp changes: Set timestamp on extracted files
authorEric Biggers <ebiggers3@gmail.com>
Mon, 20 Aug 2012 23:40:53 +0000 (18:40 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 20 Aug 2012 23:40:53 +0000 (18:40 -0500)
src/dentry.c
src/extract.c
src/timestamp.h

index c31655446521b4bd2b5e3eb0bbfcf65c73049001..b62f53ae6d73e4dc46092e3170061e6a48ca390c 100644 (file)
  * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
 #include "wimlib_internal.h"
 #include "dentry.h"
 #include "io.h"
 #include "timestamp.h"
 #include "lookup_table.h"
 #include "sha1.h"
-#include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
 
 /*
  * 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"); 
index 121966022b77bcc7c089b059e87c97fcef156622..701d1294deb95db4d8d27e753f4b4f2078c2d45c 100644 (file)
@@ -27,6 +27,7 @@
 #include "wimlib_internal.h"
 #include "dentry.h"
 #include "lookup_table.h"
+#include "timestamp.h"
 #include "xml.h"
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -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;
 }
 
 
index 9c82c23e2081dab9d8f3212bfd6c8e5ba1286a92..6f08fc2e03fe641d993eabbedb684dee442212df 100644 (file)
@@ -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