diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-23 02:19:27 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-23 02:39:57 +0200 |
commit | 73dec828ad61d046d10648ddca5c89ce70352a7a (patch) | |
tree | f9c6ac79c1a97736d9c39a282f78dca4ef4ec04d /lib/fstree/fstree.c | |
parent | 0b22d6ad0ebed2af239259dbfa36cd9920c6f4a2 (diff) |
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 <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/fstree/fstree.c')
-rw-r--r-- | lib/fstree/fstree.c | 94 |
1 files changed, 84 insertions, 10 deletions
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; |