From 73dec828ad61d046d10648ddca5c89ce70352a7a Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 23 Jun 2019 02:19:27 +0200 Subject: Move fstree default option processing to fstree code Instead of decomposing a default string in gensquashfs option processing, move that to fstree_init instead and pass the option string directly to fstree_init. Signed-off-by: David Oberhollenzer --- include/fstree.h | 8 +++-- lib/fstree/fstree.c | 94 ++++++++++++++++++++++++++++++++++++++++++------ mkfs/mkfs.c | 24 ++++++------- mkfs/mkfs.h | 5 +-- mkfs/options.c | 59 +----------------------------- tar/tar2sqfs.c | 10 ++---- tests/add_by_path.c | 5 ++- tests/fstree_from_file.c | 2 +- tests/gen_inode_table.c | 4 +-- tests/get_path.c | 2 +- 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 (=[,...]). 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 #include +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 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; -- cgit v1.2.3