aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fstree.h8
-rw-r--r--lib/fstree/fstree.c94
-rw-r--r--mkfs/mkfs.c24
-rw-r--r--mkfs/mkfs.h5
-rw-r--r--mkfs/options.c59
-rw-r--r--tar/tar2sqfs.c10
-rw-r--r--tests/add_by_path.c5
-rw-r--r--tests/fstree_from_file.c2
-rw-r--r--tests/gen_inode_table.c4
-rw-r--r--tests/get_path.c2
10 files changed, 113 insertions, 100 deletions
diff --git a/include/fstree.h b/include/fstree.h
index 784364e..040136e 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -158,11 +158,13 @@ struct fstree_t {
`block_size` is the the data block size for regular files.
+ The string `defaults` can specify default attributes (mode, uid, gid, mtime)
+ as a comma seperated list of key value paris (<key>=<value>[,...]). The string
+ is passed to getsubopt and will be altered.
+
Returns 0 on success.
*/
-int fstree_init(fstree_t *fs, size_t block_size, uint32_t mtime,
- uint16_t default_mode, uint32_t default_uid,
- uint32_t default_gid);
+int fstree_init(fstree_t *fs, size_t block_size, char *defaults);
void fstree_cleanup(fstree_t *fs);
diff --git a/lib/fstree/fstree.c b/lib/fstree/fstree.c
index a976dda..29dd66b 100644
--- a/lib/fstree/fstree.c
+++ b/lib/fstree/fstree.c
@@ -5,6 +5,85 @@
#include <stdlib.h>
#include <stdio.h>
+enum {
+ DEF_UID = 0,
+ DEF_GID,
+ DEF_MODE,
+ DEF_MTIME,
+};
+
+static const char *defaults[] = {
+ [DEF_UID] = "uid",
+ [DEF_GID] = "gid",
+ [DEF_MODE] = "mode",
+ [DEF_MTIME] = "mtime",
+ NULL
+};
+
+static int process_defaults(struct stat *sb, char *subopts)
+{
+ char *value;
+ long lval;
+ int i;
+
+ while (*subopts != '\0') {
+ i = getsubopt(&subopts, (char *const *)defaults, &value);
+
+ if (value == NULL) {
+ fprintf(stderr, "Missing value for option %s\n",
+ defaults[i]);
+ return -1;
+ }
+
+ switch (i) {
+ case DEF_UID:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > 0xFFFFFFFFL)
+ goto fail_ov;
+ sb->st_uid = lval;
+ break;
+ case DEF_GID:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > 0xFFFFFFFFL)
+ goto fail_ov;
+ sb->st_gid = lval;
+ break;
+ case DEF_MODE:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > 07777)
+ goto fail_ov;
+ sb->st_mode = S_IFDIR | (uint16_t)lval;
+ break;
+ case DEF_MTIME:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > 0xFFFFFFFFL)
+ goto fail_ov;
+ sb->st_mtime = lval;
+ sb->st_atime = lval;
+ sb->st_ctime = lval;
+ break;
+ default:
+ fprintf(stderr, "Unknown option '%s'\n", value);
+ return -1;
+ }
+ }
+ return 0;
+fail_uv:
+ fprintf(stderr, "%s: value must be positive\n", defaults[i]);
+ return -1;
+fail_ov:
+ fprintf(stderr, "%s: value too large\n", defaults[i]);
+ return -1;
+}
+
static void free_recursive(tree_node_t *n)
{
tree_node_t *it;
@@ -21,21 +100,16 @@ static void free_recursive(tree_node_t *n)
free(n);
}
-int fstree_init(fstree_t *fs, size_t block_size, uint32_t mtime,
- uint16_t default_mode, uint32_t default_uid,
- uint32_t default_gid)
+int fstree_init(fstree_t *fs, size_t block_size, char *defaults)
{
memset(fs, 0, sizeof(*fs));
-
- fs->defaults.st_uid = default_uid;
- fs->defaults.st_gid = default_gid;
- fs->defaults.st_mode = S_IFDIR | (default_mode & 07777);
- fs->defaults.st_mtime = mtime;
- fs->defaults.st_ctime = mtime;
- fs->defaults.st_atime = mtime;
+ fs->defaults.st_mode = S_IFDIR | 0755;
fs->defaults.st_blksize = block_size;
fs->block_size = block_size;
+ if (defaults != NULL && process_defaults(&fs->defaults, defaults) != 0)
+ return -1;
+
if (str_table_init(&fs->xattr_keys, FSTREE_XATTR_KEY_BUCKETS))
return -1;
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 371c578..e72b669 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -117,11 +117,16 @@ int main(int argc, char **argv)
process_command_line(&opt, argc, argv);
- if (sqfs_super_init(&super, opt.blksz, opt.def_mtime, opt.compressor))
+ if (fstree_init(&fs, opt.blksz, opt.fs_defaults))
return EXIT_FAILURE;
+ if (sqfs_super_init(&super, opt.blksz, fs.defaults.st_mtime,
+ opt.compressor)) {
+ goto out_fstree;
+ }
+
if (id_table_init(&idtbl))
- return EXIT_FAILURE;
+ goto out_fstree;
outfd = open(opt.outfile, opt.outmode, 0644);
if (outfd < 0) {
@@ -132,25 +137,20 @@ int main(int argc, char **argv)
if (sqfs_super_write(&super, outfd))
goto out_outfd;
- if (fstree_init(&fs, opt.blksz, opt.def_mtime, opt.def_mode,
- opt.def_uid, opt.def_gid)) {
- goto out_outfd;
- }
-
if (read_fstree(&fs, &opt))
- goto out_fstree;
+ goto out_outfd;
tree_node_sort_recursive(fs.root);
if (fstree_gen_inode_table(&fs))
- goto out_fstree;
+ goto out_outfd;
super.inode_count = fs.inode_tbl_size - 2;
#ifdef WITH_SELINUX
if (opt.selinux != NULL) {
if (fstree_relabel_selinux(&fs, opt.selinux))
- goto out_fstree;
+ goto out_outfd;
}
#endif
@@ -202,11 +202,11 @@ out_data:
data_writer_destroy(data);
out_cmp:
cmp->destroy(cmp);
-out_fstree:
- fstree_cleanup(&fs);
out_outfd:
close(outfd);
out_idtbl:
id_table_cleanup(&idtbl);
+out_fstree:
+ fstree_cleanup(&fs);
return status;
}
diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h
index 4a39eb5..4031c74 100644
--- a/mkfs/mkfs.h
+++ b/mkfs/mkfs.h
@@ -24,11 +24,8 @@
#include <ctype.h>
typedef struct {
- unsigned int def_uid;
- unsigned int def_gid;
- unsigned int def_mode;
- unsigned int def_mtime;
E_SQFS_COMPRESSOR compressor;
+ char *fs_defaults;
int outmode;
int blksz;
int devblksz;
diff --git a/mkfs/options.c b/mkfs/options.c
index e298a6c..8d724a8 100644
--- a/mkfs/options.c
+++ b/mkfs/options.c
@@ -24,21 +24,6 @@ static const char *short_opts = "s:F:D:X:c:b:B:d:fqhV";
static const char *short_opts = "F:D:X:c:b:B:d:fqhV";
#endif
-enum {
- DEF_UID = 0,
- DEF_GID,
- DEF_MODE,
- DEF_MTIME,
-};
-
-static const char *defaults[] = {
- [DEF_UID] = "uid",
- [DEF_GID] = "gid",
- [DEF_MODE] = "mode",
- [DEF_MTIME] = "mtime",
- NULL
-};
-
extern char *__progname;
static const char *help_string =
@@ -142,53 +127,11 @@ static long read_number(const char *name, const char *str, long min, long max)
return result;
}
-static void process_defaults(options_t *opt, char *subopts)
-{
- char *value;
- int i;
-
- while (*subopts != '\0') {
- i = getsubopt(&subopts, (char *const *)defaults, &value);
-
- if (value == NULL) {
- fprintf(stderr, "Missing value for option %s\n",
- defaults[i]);
- exit(EXIT_FAILURE);
- }
-
- switch (i) {
- case DEF_UID:
- opt->def_uid = read_number("Default user ID", value,
- 0, 0xFFFFFFFF);
- break;
- case DEF_GID:
- opt->def_gid = read_number("Default group ID", value,
- 0, 0xFFFFFFFF);
- break;
- case DEF_MODE:
- opt->def_mode = read_number("Default permissions",
- value, 0, 0xFFFFFFFF);
- break;
- case DEF_MTIME:
- opt->def_mtime = read_number("Default mtime", value,
- 0, 0xFFFFFFFF);
- break;
- default:
- fprintf(stderr, "Unknown option '%s'\n", value);
- exit(EXIT_FAILURE);
- }
- }
-}
-
void process_command_line(options_t *opt, int argc, char **argv)
{
bool have_compressor;
int i;
- opt->def_uid = 0;
- opt->def_gid = 0;
- opt->def_mode = 0755;
- opt->def_mtime = 0;
opt->outmode = O_WRONLY | O_CREAT | O_EXCL;
opt->compressor = compressor_get_default();
opt->blksz = SQFS_DEFAULT_BLOCK_SIZE;
@@ -230,7 +173,7 @@ void process_command_line(options_t *opt, int argc, char **argv)
4096, 0xFFFFFFFF);
break;
case 'd':
- process_defaults(opt, optarg);
+ opt->fs_defaults = optarg;
break;
case 'f':
opt->outmode = O_WRONLY | O_CREAT | O_TRUNC;
diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c
index b8952a9..c3fdb45 100644
--- a/tar/tar2sqfs.c
+++ b/tar/tar2sqfs.c
@@ -49,10 +49,6 @@ static const char *usagestr =
static const char *filename;
static int block_size = SQFS_DEFAULT_BLOCK_SIZE;
-static uint32_t def_mtime = 0;
-static uint16_t def_mode = 0755;
-static uint32_t def_uid = 0;
-static uint32_t def_gid = 0;
static size_t devblksize = SQFS_DEVBLK_SIZE;
static bool quiet = false;
static int outmode = O_WRONLY | O_CREAT | O_EXCL;
@@ -188,10 +184,8 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
- if (fstree_init(&fs, block_size, def_mtime, def_mode,
- def_uid, def_gid)) {
+ if (fstree_init(&fs, block_size, NULL))
goto out_fd;
- }
comp_id = compressor_get_default();
@@ -201,7 +195,7 @@ int main(int argc, char **argv)
goto out_fs;
}
- if (sqfs_super_init(&super, block_size, def_mtime, comp_id))
+ if (sqfs_super_init(&super, block_size, fs.defaults.st_mtime, comp_id))
goto out_cmp;
if (sqfs_super_write(&super, outfd))
diff --git a/tests/add_by_path.c b/tests/add_by_path.c
index 0023e0a..740e732 100644
--- a/tests/add_by_path.c
+++ b/tests/add_by_path.c
@@ -11,8 +11,11 @@ int main(void)
tree_node_t *a, *b;
struct stat sb;
fstree_t fs;
+ char *opts;
- assert(fstree_init(&fs, 512, 1337, 0755, 21, 42) == 0);
+ opts = strdup("mode=0755,uid=21,gid=42");
+ assert(fstree_init(&fs, 512, opts) == 0);
+ free(opts);
memset(&sb, 0, sizeof(sb));
sb.st_mode = S_IFDIR | 0750;
diff --git a/tests/fstree_from_file.c b/tests/fstree_from_file.c
index f9a9e28..2728397 100644
--- a/tests/fstree_from_file.c
+++ b/tests/fstree_from_file.c
@@ -29,7 +29,7 @@ int main(void)
fp = fmemopen(ptr, strlen(ptr), "r");
assert(fp != NULL);
- assert(fstree_init(&fs, 512, 0, 0755, 0, 0) == 0);
+ assert(fstree_init(&fs, 512, NULL) == 0);
assert(fstree_from_file(&fs, "testfile", fp) == 0);
tree_node_sort_recursive(fs.root);
diff --git a/tests/gen_inode_table.c b/tests/gen_inode_table.c
index 12b3bb5..d2c694c 100644
--- a/tests/gen_inode_table.c
+++ b/tests/gen_inode_table.c
@@ -48,7 +48,7 @@ int main(void)
fstree_t fs;
// inode table for the empty tree
- assert(fstree_init(&fs, 0, 0, 0, 0, 0) == 0);
+ assert(fstree_init(&fs, 0, NULL) == 0);
assert(fstree_gen_inode_table(&fs) == 0);
assert(fs.inode_tbl_size == 3);
assert(fs.root->inode_num == 2);
@@ -58,7 +58,7 @@ int main(void)
fstree_cleanup(&fs);
// tree with 2 levels under root, fan out 3
- assert(fstree_init(&fs, 0, 0, 0, 0, 0) == 0);
+ assert(fstree_init(&fs, 0, NULL) == 0);
a = gen_node(&fs, fs.root, "a");
b = gen_node(&fs, fs.root, "b");
diff --git a/tests/get_path.c b/tests/get_path.c
index 39d3431..5d2027a 100644
--- a/tests/get_path.c
+++ b/tests/get_path.c
@@ -12,7 +12,7 @@ int main(void)
fstree_t fs;
char *str;
- assert(fstree_init(&fs, 512, 1337, 0755, 21, 42) == 0);
+ assert(fstree_init(&fs, 512, NULL) == 0);
memset(&sb, 0, sizeof(sb));
sb.st_mode = S_IFDIR | 0750;