diff options
-rw-r--r-- | doc/gensquashfs.1 | 5 | ||||
-rw-r--r-- | doc/tar2sqfs.1 | 5 | ||||
-rw-r--r-- | include/fstree.h | 6 | ||||
-rw-r--r-- | lib/fstree/add_by_path.c | 1 | ||||
-rw-r--r-- | lib/fstree/fstree_from_dir.c | 14 | ||||
-rw-r--r-- | lib/fstree/fstree_from_file.c | 6 | ||||
-rw-r--r-- | lib/fstree/mknode.c | 1 | ||||
-rw-r--r-- | lib/fstree/node_stat.c | 3 | ||||
-rw-r--r-- | lib/sqfs/tree_node_from_inode.c | 1 | ||||
-rw-r--r-- | lib/sqfs/write_inode.c | 2 | ||||
-rw-r--r-- | mkfs/mkfs.c | 2 | ||||
-rw-r--r-- | mkfs/mkfs.h | 1 | ||||
-rw-r--r-- | mkfs/options.c | 12 | ||||
-rw-r--r-- | tar/tar2sqfs.c | 15 |
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; |