diff options
-rw-r--r-- | unpack/options.c | 8 | ||||
-rw-r--r-- | unpack/rdsquashfs.h | 1 | ||||
-rw-r--r-- | unpack/restore_fstree.c | 51 |
3 files changed, 41 insertions, 19 deletions
diff --git a/unpack/options.c b/unpack/options.c index 594b610..e880656 100644 --- a/unpack/options.c +++ b/unpack/options.c @@ -21,6 +21,7 @@ static struct option long_opts[] = { #ifdef HAVE_SYS_XATTR_H { "set-xattr", no_argument, NULL, 'X' }, #endif + { "set-times", no_argument, NULL, 'T' }, { "jobs", required_argument, NULL, 'j' }, { "describe", no_argument, NULL, 'd' }, { "chmod", no_argument, NULL, 'C' }, @@ -31,7 +32,7 @@ static struct option long_opts[] = { }; static const char *short_opts = - "l:c:u:p:x:DSFLCOEZj:dqhV" + "l:c:u:p:x:DSFLCOEZTj:dqhV" #ifdef HAVE_SYS_XATTR_H "X" #endif @@ -71,6 +72,8 @@ static const char *help_string = " --set-xattr, -X When unpacking files to disk, set the extended\n" " attributes from the squashfs image.\n" #endif +" --set-times, -T When unpacking files to disk, set the create\n" +" and modify timestamps from the squashfs image.\n" " --jobs, -j <count> Number of parallel unpacking jobs to start.\n" " --chmod, -C Change permission flags of unpacked files to\n" " those store in the squashfs image.\n" @@ -153,6 +156,9 @@ void process_command_line(options_t *opt, int argc, char **argv) opt->rdtree_flags |= RDTREE_READ_XATTR; break; #endif + case 'T': + opt->flags |= UNPACK_SET_TIMES; + break; case 'j': for (j = 0; optarg[j] != '\0'; ++j) { if (j > 6 || !isdigit(optarg[j])) diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h index ca4825b..cfc359c 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -41,6 +41,7 @@ enum UNPACK_FLAGS { UNPACK_QUIET = 0x04, UNPACK_NO_SPARSE = 0x08, UNPACK_SET_XATTR = 0x10, + UNPACK_SET_TIMES = 0x20, }; enum { diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 5681e0a..2ee4c08 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -109,23 +109,6 @@ static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) return -1; } - if (flags & UNPACK_CHOWN) { - if (fchownat(AT_FDCWD, n->name, n->uid, n->gid, - AT_SYMLINK_NOFOLLOW)) { - fprintf(stderr, "chown %s: %s\n", - n->name, strerror(errno)); - return -1; - } - } - - if (flags & UNPACK_CHMOD) { - if (fchmodat(AT_FDCWD, n->name, n->mode, - AT_SYMLINK_NOFOLLOW)) { - fprintf(stderr, "chmod %s: %s\n", - n->name, strerror(errno)); - return -1; - } - } #ifdef HAVE_SYS_XATTR_H if ((flags & UNPACK_SET_XATTR) && n->xattr != NULL) { size_t i, len, kidx, vidx; @@ -150,6 +133,38 @@ static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) #else (void)fs; #endif + + if (flags & UNPACK_SET_TIMES) { + struct timespec times[2]; + + memset(times, 0, sizeof(times)); + times[0].tv_sec = n->mod_time; + times[1].tv_sec = n->mod_time; + + if (utimensat(AT_FDCWD, n->name, times, AT_SYMLINK_NOFOLLOW)) { + fprintf(stderr, "setting timestamp on %s: %s\n", + n->name, strerror(errno)); + return -1; + } + } + + if (flags & UNPACK_CHOWN) { + if (fchownat(AT_FDCWD, n->name, n->uid, n->gid, + AT_SYMLINK_NOFOLLOW)) { + fprintf(stderr, "chown %s: %s\n", + n->name, strerror(errno)); + return -1; + } + } + + if (flags & UNPACK_CHMOD) { + if (fchmodat(AT_FDCWD, n->name, n->mode, + AT_SYMLINK_NOFOLLOW)) { + fprintf(stderr, "chmod %s: %s\n", + n->name, strerror(errno)); + return -1; + } + } return 0; } @@ -177,7 +192,7 @@ int restore_fstree(tree_node_t *root, int flags) int update_tree_attribs(fstree_t *fs, tree_node_t *root, int flags) { - if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD)) == 0) + if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD | UNPACK_SET_TIMES)) == 0) return 0; return set_attribs(fs, root, flags); |