summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/gensquashfs.15
-rw-r--r--doc/tar2sqfs.15
-rw-r--r--include/fstree.h6
-rw-r--r--lib/fstree/add_by_path.c1
-rw-r--r--lib/fstree/fstree_from_dir.c14
-rw-r--r--lib/fstree/fstree_from_file.c6
-rw-r--r--lib/fstree/mknode.c1
-rw-r--r--lib/fstree/node_stat.c3
-rw-r--r--lib/sqfs/tree_node_from_inode.c1
-rw-r--r--lib/sqfs/write_inode.c2
-rw-r--r--mkfs/mkfs.c2
-rw-r--r--mkfs/mkfs.h1
-rw-r--r--mkfs/options.c12
-rw-r--r--tar/tar2sqfs.c15
14 files changed, 62 insertions, 12 deletions
diff --git a/doc/gensquashfs.1 b/doc/gensquashfs.1
index a880453..d7b78a1 100644
--- a/doc/gensquashfs.1
+++ b/doc/gensquashfs.1
@@ -37,6 +37,11 @@ Defaults to 131072.
Device block size to padd the image to.
Defaults to 4096.
.TP
+\fB\-\-keep\-time\fR, \fB\-k\fR
+Whe using \fB\-\-pack\-dir\fR only, use the timestamps from the input files
+instead of setting defaults on all input paths. The root inode and the
+modification time on the SquashFS image itself will still be set to defaults.
+.TP
\fB\-\-defaults\fR, \fB\-d\fR <options>
A comma seperated list of default values for
implicitly created directories.
diff --git a/doc/tar2sqfs.1 b/doc/tar2sqfs.1
index 8c7d20d..a6646c6 100644
--- a/doc/tar2sqfs.1
+++ b/doc/tar2sqfs.1
@@ -31,6 +31,11 @@ Defaults to 131072.
Device block size to padd the image to.
Defaults to 4096.
.TP
+\fB\-\-keep\-time\fR, \fB\-k\fR
+Keep the same time stamps stored in the tar archive for the SquashFS instead of
+setting defaults on all files. The root inode and the modification time on the
+SquashFS image itself will still be set to defaults.
+.TP
\fB\-\-defaults\fR, \fB\-d\fR <options>
A comma seperated list of default values for
implicitly created directories.
diff --git a/include/fstree.h b/include/fstree.h
index 4efa9d5..1b25363 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -119,6 +119,8 @@ struct tree_node_t {
uint32_t uid;
uint32_t gid;
+ uint32_t inode_num;
+ uint32_t mod_time;
uint16_t mode;
/* SquashFS inode refernce number. 32 bit offset of the meta data
@@ -128,8 +130,6 @@ struct tree_node_t {
Generated on the fly when writing inodes. */
uint64_t inode_ref;
- uint32_t inode_num;
-
/* Type specific data. Pointers are into payload area blow. */
union {
dir_info_t *dir;
@@ -241,7 +241,7 @@ int fstree_from_file(fstree_t *fs, const char *filename, FILE *fp);
Returns 0 on success, prints errors to stderr.
*/
-int fstree_from_dir(fstree_t *fs, const char *path);
+int fstree_from_dir(fstree_t *fs, const char *path, bool keep_time_stamps);
/* Add labels from an SELinux labeling file to all tree nodes.
Returns 0 on success. Internally prints errors to stderr. */
diff --git a/lib/fstree/add_by_path.c b/lib/fstree/add_by_path.c
index eaa0925..7e0a4ce 100644
--- a/lib/fstree/add_by_path.c
+++ b/lib/fstree/add_by_path.c
@@ -77,6 +77,7 @@ tree_node_t *fstree_add_generic(fstree_t *fs, const char *path,
child->uid = sb->st_uid;
child->gid = sb->st_gid;
child->mode = sb->st_mode;
+ child->mod_time = sb->st_mtime;
child->data.dir->created_implicitly = false;
return child;
}
diff --git a/lib/fstree/fstree_from_dir.c b/lib/fstree/fstree_from_dir.c
index 29911f4..ad75006 100644
--- a/lib/fstree/fstree_from_dir.c
+++ b/lib/fstree/fstree_from_dir.c
@@ -43,7 +43,7 @@ fail:
return NULL;
}
-static int populate_dir(fstree_t *fs, tree_node_t *root)
+static int populate_dir(fstree_t *fs, tree_node_t *root, bool keep_time_stamps)
{
char *extra = NULL;
struct dirent *ent;
@@ -92,6 +92,12 @@ static int populate_dir(fstree_t *fs, tree_node_t *root)
goto fail;
}
+ if (!keep_time_stamps) {
+ sb.st_atim = fs->defaults.st_atim;
+ sb.st_mtim = fs->defaults.st_mtim;
+ sb.st_ctim = fs->defaults.st_ctim;
+ }
+
n = fstree_mknode(fs, root, ent->d_name, strlen(ent->d_name),
extra, &sb);
if (n == NULL) {
@@ -110,7 +116,7 @@ static int populate_dir(fstree_t *fs, tree_node_t *root)
if (pushd(n->name))
return -1;
- if (populate_dir(fs, n))
+ if (populate_dir(fs, n, keep_time_stamps))
return -1;
if (popd())
@@ -127,14 +133,14 @@ fail:
return -1;
}
-int fstree_from_dir(fstree_t *fs, const char *path)
+int fstree_from_dir(fstree_t *fs, const char *path, bool keep_time_stamps)
{
int ret;
if (pushd(path))
return -1;
- ret = populate_dir(fs, fs->root);
+ ret = populate_dir(fs, fs->root, keep_time_stamps);
if (popd())
ret = -1;
diff --git a/lib/fstree/fstree_from_file.c b/lib/fstree/fstree_from_file.c
index 901e431..91a922b 100644
--- a/lib/fstree/fstree_from_file.c
+++ b/lib/fstree/fstree_from_file.c
@@ -66,6 +66,9 @@ static int add_file(fstree_t *fs, const char *filename, size_t line_num,
sb.st_uid = basic->st_uid;
sb.st_gid = basic->st_gid;
sb.st_mode = basic->st_mode;
+ sb.st_atim = basic->st_atim;
+ sb.st_mtim = basic->st_mtim;
+ sb.st_ctim = basic->st_ctim;
return add_generic(fs, filename, line_num, path, &sb, extra);
}
@@ -119,6 +122,9 @@ static int handle_line(fstree_t *fs, const char *filename,
size_t i;
memset(&sb, 0, sizeof(sb));
+ sb.st_mtime = fs->defaults.st_mtime;
+ sb.st_atime = fs->defaults.st_atime;
+ sb.st_ctime = fs->defaults.st_ctime;
/* isolate keyword */
for (i = 0; isalpha(line[i]); ++i)
diff --git a/lib/fstree/mknode.c b/lib/fstree/mknode.c
index 4b4cdfd..7d09fbd 100644
--- a/lib/fstree/mknode.c
+++ b/lib/fstree/mknode.c
@@ -43,6 +43,7 @@ tree_node_t *fstree_mknode(fstree_t *fs, tree_node_t *parent, const char *name,
n->uid = sb->st_uid;
n->gid = sb->st_gid;
n->mode = sb->st_mode;
+ n->mod_time = sb->st_mtime;
switch (sb->st_mode & S_IFMT) {
case S_IFDIR:
diff --git a/lib/fstree/node_stat.c b/lib/fstree/node_stat.c
index 8f62a0f..a28cae8 100644
--- a/lib/fstree/node_stat.c
+++ b/lib/fstree/node_stat.c
@@ -13,6 +13,9 @@ void fstree_node_stat(fstree_t *fs, tree_node_t *node, struct stat *sb)
sb->st_nlink = 1;
sb->st_uid = node->uid;
sb->st_gid = node->gid;
+ sb->st_mtime = node->mod_time;
+ sb->st_atime = node->mod_time;
+ sb->st_ctime = node->mod_time;
switch (node->mode & S_IFMT) {
case S_IFDIR:
diff --git a/lib/sqfs/tree_node_from_inode.c b/lib/sqfs/tree_node_from_inode.c
index 0d46eed..1ee85e5 100644
--- a/lib/sqfs/tree_node_from_inode.c
+++ b/lib/sqfs/tree_node_from_inode.c
@@ -88,6 +88,7 @@ tree_node_t *tree_node_from_inode(sqfs_inode_generic_t *inode,
out->gid = idtbl->ids[inode->base.gid_idx];
out->mode = inode->base.mode;
out->inode_num = inode->base.inode_number;
+ out->mod_time = inode->base.mod_time;
out->name = (char *)out->payload;
switch (inode->base.type) {
diff --git a/lib/sqfs/write_inode.c b/lib/sqfs/write_inode.c
index a013d6f..6e11277 100644
--- a/lib/sqfs/write_inode.c
+++ b/lib/sqfs/write_inode.c
@@ -143,7 +143,7 @@ int meta_writer_write_inode(fstree_t *fs, id_table_t *idtbl, meta_writer_t *im,
base.mode = htole16(node->mode);
base.uid_idx = htole16(uid_idx);
base.gid_idx = htole16(gid_idx);
- base.mod_time = htole32(fs->defaults.st_mtime);
+ base.mod_time = htole32(node->mod_time);
base.inode_number = htole32(node->inode_num);
if (meta_writer_append(im, &base, sizeof(base))) {
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 91cb9bd..654534d 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -81,7 +81,7 @@ static int read_fstree(fstree_t *fs, options_t *opt)
int ret;
if (opt->infile == NULL)
- return fstree_from_dir(fs, opt->packdir);
+ return fstree_from_dir(fs, opt->packdir, opt->keep_time);
fp = fopen(opt->infile, "rb");
if (fp == NULL) {
diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h
index 70a2ed6..21a308b 100644
--- a/mkfs/mkfs.h
+++ b/mkfs/mkfs.h
@@ -29,6 +29,7 @@ typedef struct {
int outmode;
int blksz;
int devblksz;
+ bool keep_time;
bool exportable;
bool quiet;
const char *infile;
diff --git a/mkfs/options.c b/mkfs/options.c
index fe2bc69..f14e6ef 100644
--- a/mkfs/options.c
+++ b/mkfs/options.c
@@ -9,6 +9,7 @@ static struct option long_opts[] = {
{ "comp-extra", required_argument, NULL, 'X' },
{ "pack-file", required_argument, NULL, 'F' },
{ "pack-dir", required_argument, NULL, 'D' },
+ { "keep-time", required_argument, NULL, 'k' },
{ "exportable", no_argument, NULL, 'e' },
{ "force", no_argument, NULL, 'f' },
{ "quiet", no_argument, NULL, 'q' },
@@ -20,9 +21,9 @@ static struct option long_opts[] = {
};
#ifdef WITH_SELINUX
-static const char *short_opts = "s:F:D:X:c:b:B:d:efqhV";
+static const char *short_opts = "s:F:D:X:c:b:B:d:kefqhV";
#else
-static const char *short_opts = "F:D:X:c:b:B:d:efqhV";
+static const char *short_opts = "F:D:X:c:b:B:d:kefqhV";
#endif
extern char *__progname;
@@ -67,6 +68,9 @@ static const char *help_string =
" --selinux, -s <file> Specify an SELinux label file to get context\n"
" attributes from.\n"
#endif
+" --keep-time, -k When using --pack-dir only, use the timestamps\n"
+" from the input files instead of setting\n"
+" defaults on all input paths.\n"
" --exportable, -e Generate an export table for NFS support.\n"
" --force, -f Overwrite the output file if it exists.\n"
" --quiet, -q Do not print out progress reports.\n"
@@ -125,6 +129,7 @@ void process_command_line(options_t *opt, int argc, char **argv)
opt->compressor = compressor_get_default();
opt->blksz = SQFS_DEFAULT_BLOCK_SIZE;
opt->devblksz = SQFS_DEVBLK_SIZE;
+ opt->keep_time = false;
opt->exportable = false;
opt->quiet = false;
opt->infile = NULL;
@@ -169,6 +174,9 @@ void process_command_line(options_t *opt, int argc, char **argv)
case 'd':
opt->fs_defaults = optarg;
break;
+ case 'k':
+ opt->keep_time = true;
+ break;
case 'e':
opt->exportable = true;
break;
diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c
index f557f95..2493c3b 100644
--- a/tar/tar2sqfs.c
+++ b/tar/tar2sqfs.c
@@ -26,6 +26,7 @@ static struct option long_opts[] = {
{ "comp-extra", required_argument, NULL, 'X' },
{ "no-skip", no_argument, NULL, 's' },
{ "no-xattr", no_argument, NULL, 'x' },
+ { "keep-time", no_argument, NULL, 'k' },
{ "exportable", no_argument, NULL, 'e' },
{ "force", no_argument, NULL, 'f' },
{ "quiet", no_argument, NULL, 'q' },
@@ -33,7 +34,7 @@ static struct option long_opts[] = {
{ "version", no_argument, NULL, 'V' },
};
-static const char *short_opts = "c:b:B:d:X:sxefqhV";
+static const char *short_opts = "c:b:B:d:X:sxekfqhV";
static const char *usagestr =
"Usage: tar2sqfs [OPTIONS...] <sqfsfile>\n"
@@ -64,6 +65,8 @@ static const char *usagestr =
" --no-skip, -s Abort if a tar record cannot be read instead\n"
" of skipping it.\n"
" --no-xattr, -x Do not copy extended attributes from archive.\n"
+" --keep-time, -k Keep the time stamps stored in the archive\n"
+" instead of setting defaults on all files.\n"
" --exportable, -e Generate an export table for NFS support.\n"
" --force, -f Overwrite the output file if it exists.\n"
" --quiet, -q Do not print out progress reports.\n"
@@ -88,6 +91,7 @@ static char *fs_defaults = NULL;
static bool dont_skip = false;
static bool no_xattr = false;
static bool exportable = false;
+static bool keep_time = false;
static void process_args(int argc, char **argv)
{
@@ -137,6 +141,9 @@ static void process_args(int argc, char **argv)
case 'x':
no_xattr = true;
break;
+ case 'k':
+ keep_time = true;
+ break;
case 's':
dont_skip = true;
break;
@@ -234,6 +241,12 @@ static int create_node_and_repack_data(tar_header_decoded_t *hdr, fstree_t *fs,
{
tree_node_t *node;
+ if (!keep_time) {
+ hdr->sb.st_mtime = fs->defaults.st_mtime;
+ hdr->sb.st_ctime = fs->defaults.st_ctime;
+ hdr->sb.st_atime = fs->defaults.st_atime;
+ }
+
node = fstree_add_generic(fs, hdr->name, &hdr->sb, hdr->link_target);
if (node == NULL)
goto fail_errno;