summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--unpack/options.c8
-rw-r--r--unpack/rdsquashfs.h1
-rw-r--r--unpack/restore_fstree.c51
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);