aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-02 17:22:24 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-02 17:22:24 +0200
commit9940efe053263478c5f29367b11d6f7ed1276aa4 (patch)
tree99d1c9e9712c73ba4e6e8e145f007cb74294f12a
parent32eb57dd9a19254565a0792ab9b627a3dac319f9 (diff)
Move fstree CLI code to libcommon
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--bin/gensquashfs/Makemodule.am9
-rw-r--r--bin/gensquashfs/src/fstree_from_dir.c2
-rw-r--r--bin/gensquashfs/src/fstree_from_file.c2
-rw-r--r--bin/gensquashfs/test/fstree_from_dir.c11
-rw-r--r--bin/gensquashfs/test/fstree_from_file.c4
-rw-r--r--bin/gensquashfs/test/fstree_glob1.c9
-rw-r--r--bin/gensquashfs/test/sort_file.c4
-rw-r--r--bin/tar2sqfs/src/process_tarball.c2
-rw-r--r--include/common.h7
-rw-r--r--include/fstree.h18
-rw-r--r--lib/common/Makemodule.am12
-rw-r--r--lib/common/src/fstree_cli.c97
-rw-r--r--lib/common/src/writer/init.c8
-rw-r--r--lib/common/test/fstree_cli.c47
-rw-r--r--lib/fstree/Makemodule.am14
-rw-r--r--lib/fstree/src/fstree.c96
-rw-r--r--lib/fstree/src/get_by_path.c10
-rw-r--r--lib/fstree/test/add_by_path.c5
-rw-r--r--lib/fstree/test/fstree_init.c50
-rw-r--r--lib/fstree/test/fstree_sort.c7
-rw-r--r--lib/fstree/test/gen_inode_numbers.c7
-rw-r--r--lib/fstree/test/get_path.c5
22 files changed, 249 insertions, 177 deletions
diff --git a/bin/gensquashfs/Makemodule.am b/bin/gensquashfs/Makemodule.am
index 052f692..de9ea4c 100644
--- a/bin/gensquashfs/Makemodule.am
+++ b/bin/gensquashfs/Makemodule.am
@@ -35,7 +35,8 @@ test_fstree_from_file_SOURCES = bin/gensquashfs/test/fstree_from_file.c \
test_fstree_from_file_CPPFLAGS = $(AM_CPPFLAGS)
test_fstree_from_file_CPPFLAGS += -I$(top_srcdir)/bin/gensquashfs/src
test_fstree_from_file_CPPFLAGS += -DTESTPATH=$(GENDATADIR)/fstree1.txt
-test_fstree_from_file_LDADD = libfstree.a libio.a libutil.a libcompat.a
+test_fstree_from_file_LDADD = libcommon.a libfstree.a libio.a libutil.a \
+ libcompat.a
test_fstree_glob1_SOURCES = bin/gensquashfs/test/fstree_glob1.c \
bin/gensquashfs/src/fstree_from_file.c \
@@ -43,7 +44,7 @@ test_fstree_glob1_SOURCES = bin/gensquashfs/test/fstree_glob1.c \
bin/gensquashfs/src/mkfs.h
test_fstree_glob1_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
test_fstree_glob1_CPPFLAGS += -DTESTPATH=$(GENDATADIR)
-test_fstree_glob1_LDADD = libfstree.a libio.a libutil.a libcompat.a
+test_fstree_glob1_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a
test_fstree_from_dir_SOURCES = bin/gensquashfs/test/fstree_from_dir.c \
bin/gensquashfs/src/fstree_from_dir.c \
@@ -51,7 +52,7 @@ test_fstree_from_dir_SOURCES = bin/gensquashfs/test/fstree_from_dir.c \
test_fstree_from_dir_CPPFLAGS = $(AM_CPPFLAGS)
test_fstree_from_dir_CPPFLAGS += -I$(top_srcdir)/bin/gensquashfs/src
test_fstree_from_dir_CPPFLAGS += -DTESTPATH=$(GENDATADIR)/testdir
-test_fstree_from_dir_LDADD = libfstree.a libutil.a libcompat.a
+test_fstree_from_dir_LDADD = libcommon.a libfstree.a libutil.a libcompat.a
test_sort_file_SOURCES = bin/gensquashfs/test/sort_file.c \
bin/gensquashfs/src/fstree_from_file.c \
@@ -59,7 +60,7 @@ test_sort_file_SOURCES = bin/gensquashfs/test/sort_file.c \
bin/gensquashfs/src/sort_by_file.c \
bin/gensquashfs/src/mkfs.h
test_sort_file_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/bin/gensquashfs/src
-test_sort_file_LDADD = libfstree.a libio.a libutil.a libcompat.a
+test_sort_file_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a
fstree_fuzz_SOURCES = bin/gensquashfs/test/fstree_fuzz.c \
bin/gensquashfs/src/fstree_from_file.c \
diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c
index 5b3f003..820157c 100644
--- a/bin/gensquashfs/src/fstree_from_dir.c
+++ b/bin/gensquashfs/src/fstree_from_dir.c
@@ -382,7 +382,7 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root,
}
if (!(flags & DIR_SCAN_KEEP_TIME))
- sb.st_mtime = fs->defaults.st_mtime;
+ sb.st_mtime = fs->defaults.mtime;
if (S_ISDIR(sb.st_mode) && (flags & DIR_SCAN_NO_DIR)) {
n = fstree_get_node_by_path(fs, root, ent->d_name,
diff --git a/bin/gensquashfs/src/fstree_from_file.c b/bin/gensquashfs/src/fstree_from_file.c
index e26d4b1..d051737 100644
--- a/bin/gensquashfs/src/fstree_from_file.c
+++ b/bin/gensquashfs/src/fstree_from_file.c
@@ -507,7 +507,7 @@ static int handle_line(fstree_t *fs, const char *filename,
/* forward to callback */
memset(&sb, 0, sizeof(sb));
- sb.st_mtime = fs->defaults.st_mtime;
+ sb.st_mtime = fs->defaults.mtime;
sb.st_mode = mode | cb->mode;
sb.st_uid = uid;
sb.st_gid = gid;
diff --git a/bin/gensquashfs/test/fstree_from_dir.c b/bin/gensquashfs/test/fstree_from_dir.c
index 5e73fa4..d64934e 100644
--- a/bin/gensquashfs/test/fstree_from_dir.c
+++ b/bin/gensquashfs/test/fstree_from_dir.c
@@ -112,13 +112,16 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
int main(int argc, char **argv)
{
+ fstree_defaults_t fsd;
struct stat sb;
tree_node_t *n;
fstree_t fs;
(void)argc; (void)argv;
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+
/* recursively scan into root */
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
TEST_ASSERT(fstree_from_dir(&fs, fs.root, TEST_PATH,
NULL, NULL, 0) == 0);
@@ -127,7 +130,7 @@ int main(int argc, char **argv)
fstree_cleanup(&fs);
/* non-recursively scan into root */
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
TEST_ASSERT(fstree_from_dir(&fs, fs.root, TEST_PATH, NULL, NULL,
DIR_SCAN_NO_RECURSION) == 0);
@@ -139,7 +142,7 @@ int main(int argc, char **argv)
memset(&sb, 0, sizeof(sb));
sb.st_mode = S_IFDIR | 0755;
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
n = fstree_mknode(fs.root, "foodir", 6, NULL, &sb);
TEST_NOT_NULL(n);
@@ -158,7 +161,7 @@ int main(int argc, char **argv)
memset(&sb, 0, sizeof(sb));
sb.st_mode = S_IFDIR | 0755;
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
n = fstree_mknode(fs.root, "foodir", 6, NULL, &sb);
TEST_NOT_NULL(n);
diff --git a/bin/gensquashfs/test/fstree_from_file.c b/bin/gensquashfs/test/fstree_from_file.c
index 2a9ba1e..e526f2d 100644
--- a/bin/gensquashfs/test/fstree_from_file.c
+++ b/bin/gensquashfs/test/fstree_from_file.c
@@ -11,11 +11,13 @@
int main(int argc, char **argv)
{
+ fstree_defaults_t fsd;
tree_node_t *n;
fstree_t fs;
(void)argc; (void)argv;
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
TEST_ASSERT(fstree_from_file(&fs, TEST_PATH, NULL) == 0);
fstree_post_process(&fs);
diff --git a/bin/gensquashfs/test/fstree_glob1.c b/bin/gensquashfs/test/fstree_glob1.c
index 2d3cb80..dbe0e50 100644
--- a/bin/gensquashfs/test/fstree_glob1.c
+++ b/bin/gensquashfs/test/fstree_glob1.c
@@ -220,12 +220,15 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive)
int main(int argc, char **argv)
{
+ fstree_defaults_t fsd;
fstree_t fs;
int ret;
(void)argc; (void)argv;
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+
/* first test case, directory tree only */
- ret = fstree_init(&fs, NULL);
+ ret = fstree_init(&fs, &fsd);
TEST_EQUAL_I(ret, 0);
ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob1.txt", TEST_PATH);
@@ -236,7 +239,7 @@ int main(int argc, char **argv)
fstree_cleanup(&fs);
/* first test case, directory tree plus fnmatch()ed files */
- ret = fstree_init(&fs, NULL);
+ ret = fstree_init(&fs, &fsd);
TEST_EQUAL_I(ret, 0);
ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob2.txt", TEST_PATH);
@@ -247,7 +250,7 @@ int main(int argc, char **argv)
fstree_cleanup(&fs);
/* third test case, same as second, but entries directly at the root */
- ret = fstree_init(&fs, NULL);
+ ret = fstree_init(&fs, &fsd);
TEST_EQUAL_I(ret, 0);
ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob3.txt", TEST_PATH);
diff --git a/bin/gensquashfs/test/sort_file.c b/bin/gensquashfs/test/sort_file.c
index 6c6cce6..4b5caf8 100644
--- a/bin/gensquashfs/test/sort_file.c
+++ b/bin/gensquashfs/test/sort_file.c
@@ -150,6 +150,7 @@ static istream_t memstream = {
int main(int argc, char **argv)
{
+ fstree_defaults_t fsd;
file_info_t *fi;
fstree_t fs;
size_t i;
@@ -160,7 +161,8 @@ int main(int argc, char **argv)
memstream.buffer_offset = 0;
memstream.eof = false;
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
TEST_ASSERT(fstree_from_file_stream(&fs, &memstream, NULL) == 0);
fstree_post_process(&fs);
diff --git a/bin/tar2sqfs/src/process_tarball.c b/bin/tar2sqfs/src/process_tarball.c
index a4d5500..94ee71c 100644
--- a/bin/tar2sqfs/src/process_tarball.c
+++ b/bin/tar2sqfs/src/process_tarball.c
@@ -101,7 +101,7 @@ static int create_node_and_repack_data(istream_t *input_file,
}
if (!keep_time) {
- hdr->mtime = sqfs->fs.defaults.st_mtime;
+ hdr->mtime = sqfs->fs.defaults.mtime;
}
memset(&sb, 0, sizeof(sb));
diff --git a/include/common.h b/include/common.h
index 84ec3ca..30c30fe 100644
--- a/include/common.h
+++ b/include/common.h
@@ -69,4 +69,11 @@ ostream_t *data_writer_ostream_create(const char *filename,
sqfs_inode_generic_t **inode,
int flags);
+/*
+ Parse a comma separated list (e.g. "uid=...,gid=..." of defaults for
+ fstree nodes. Used for command line parsing. Returns 0 on success,
+ -1 on failure. Prints an error message to stderr on failure.
+ */
+int parse_fstree_defaults(fstree_defaults_t *out, char *str);
+
#endif /* COMMON_H */
diff --git a/include/fstree.h b/include/fstree.h
index 51e2fbc..653e180 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -37,6 +37,7 @@ enum {
#define FSTREE_MODE_HARD_LINK (0)
#define FSTREE_MODE_HARD_LINK_RESOLVED (1)
+typedef struct fstree_defaults_t fstree_defaults_t;
typedef struct tree_node_t tree_node_t;
typedef struct file_info_t file_info_t;
typedef struct dir_info_t dir_info_t;
@@ -120,9 +121,18 @@ struct tree_node_t {
sqfs_u8 payload[];
};
+/* Default settings for new nodes */
+struct fstree_defaults_t {
+ sqfs_u32 uid;
+ sqfs_u32 gid;
+ sqfs_u32 mtime;
+ sqfs_u16 mode;
+};
+
/* Encapsulates a file system tree */
struct fstree_t {
- struct stat defaults;
+ fstree_defaults_t defaults;
+
size_t unique_inode_count;
/* flat array of all nodes that have an inode number */
@@ -138,13 +148,9 @@ struct fstree_t {
Initializing means copying over the default values and creating a root node.
On error, an error message is written to stderr.
- The string `defaults` can specify default attributes (mode, uid, gid, mtime)
- as a comma separated 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, char *defaults);
+int fstree_init(fstree_t *fs, const fstree_defaults_t *defaults);
void fstree_cleanup(fstree_t *fs);
diff --git a/lib/common/Makemodule.am b/lib/common/Makemodule.am
index 74b924e..63fa602 100644
--- a/lib/common/Makemodule.am
+++ b/lib/common/Makemodule.am
@@ -6,7 +6,8 @@ libcommon_a_SOURCES = include/common.h include/simple_writer.h \
lib/common/src/data_writer_ostream.c lib/common/src/perror.c \
lib/common/src/parse_size.c lib/common/src/print_size.c \
lib/common/src/writer/init.c lib/common/src/writer/cleanup.c \
- lib/common/src/writer/serialize_fstree.c lib/common/src/writer/finish.c
+ lib/common/src/writer/serialize_fstree.c lib/common/src/writer/finish.c\
+ lib/common/src/fstree_cli.c
libcommon_a_CFLAGS = $(AM_CFLAGS) $(LZO_CFLAGS)
if WITH_LZO
@@ -14,3 +15,12 @@ libcommon_a_SOURCES += lib/common/src/comp_lzo.c
endif
noinst_LIBRARIES += libcommon.a
+
+test_fstree_cli_SOURCES = lib/common/test/fstree_cli.c
+test_fstree_cli_LDADD = libcommon.a libio.a libutil.a libcompat.a
+
+LIBCOMMON_TESTS = \
+ test_fstree_cli
+
+check_PROGRAMS += $(LIBCOMMON_TESTS)
+TESTS += $(LIBCOMMON_TESTS)
diff --git a/lib/common/src/fstree_cli.c b/lib/common/src/fstree_cli.c
new file mode 100644
index 0000000..179a1f5
--- /dev/null
+++ b/lib/common/src/fstree_cli.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * fstree_cli.c
+ *
+ * Copyright (C) 2023 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+#include "common.h"
+#include "util/util.h"
+
+#include <string.h>
+#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
+};
+
+int parse_fstree_defaults(fstree_defaults_t *sb, char *subopts)
+{
+ char *value;
+ long lval;
+ int i;
+
+ memset(sb, 0, sizeof(*sb));
+ sb->mode = S_IFDIR | 0755;
+ sb->mtime = get_source_date_epoch();
+
+ if (subopts == NULL)
+ return 0;
+
+ 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 > (long)INT32_MAX)
+ goto fail_ov;
+ sb->uid = lval;
+ break;
+ case DEF_GID:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > (long)INT32_MAX)
+ goto fail_ov;
+ sb->gid = lval;
+ break;
+ case DEF_MODE:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > 07777)
+ goto fail_ov;
+ sb->mode = S_IFDIR | (sqfs_u16)lval;
+ break;
+ case DEF_MTIME:
+ lval = strtol(value, NULL, 0);
+ if (lval < 0)
+ goto fail_uv;
+ if (lval > (long)UINT32_MAX)
+ goto fail_ov;
+ sb->mtime = 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;
+}
diff --git a/lib/common/src/writer/init.c b/lib/common/src/writer/init.c
index fe5fcc5..60d7a12 100644
--- a/lib/common/src/writer/init.c
+++ b/lib/common/src/writer/init.c
@@ -46,6 +46,7 @@ int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg)
{
sqfs_block_processor_desc_t blkdesc;
sqfs_compressor_config_t cfg;
+ fstree_defaults_t fsd;
int ret, flags;
sqfs->filename = wrcfg->filename;
@@ -62,7 +63,10 @@ int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg)
return -1;
}
- if (fstree_init(&sqfs->fs, wrcfg->fs_defaults))
+ if (parse_fstree_defaults(&fsd, wrcfg->fs_defaults))
+ goto fail_file;
+
+ if (fstree_init(&sqfs->fs, &fsd))
goto fail_file;
ret = sqfs_compressor_create(&cfg, &sqfs->cmp);
@@ -99,7 +103,7 @@ int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg)
}
ret = sqfs_super_init(&sqfs->super, wrcfg->block_size,
- sqfs->fs.defaults.st_mtime, wrcfg->comp_id);
+ sqfs->fs.defaults.mtime, wrcfg->comp_id);
if (ret) {
sqfs_perror(wrcfg->filename, "initializing super block", ret);
goto fail_uncmp;
diff --git a/lib/common/test/fstree_cli.c b/lib/common/test/fstree_cli.c
new file mode 100644
index 0000000..a582adb
--- /dev/null
+++ b/lib/common/test/fstree_cli.c
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * fstree_cli.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "common.h"
+#include "util/test.h"
+#include "util/util.h"
+
+int main(int argc, char **argv)
+{
+ fstree_defaults_t fs;
+ char *str;
+ (void)argc; (void)argv;
+
+ str = strdup("mtime=1337,uid=1000,gid=100,mode=0321");
+ TEST_NOT_NULL(str);
+ TEST_ASSERT(parse_fstree_defaults(&fs, str) == 0);
+ free(str);
+ TEST_EQUAL_UI(fs.mtime, 1337);
+ TEST_EQUAL_UI(fs.uid, 1000);
+ TEST_EQUAL_UI(fs.gid, 100);
+ TEST_EQUAL_UI(fs.mode, S_IFDIR | 0321);
+
+ TEST_ASSERT(parse_fstree_defaults(&fs, NULL) == 0);
+ if (fs.mtime != 0) {
+ TEST_EQUAL_UI(fs.mtime, get_source_date_epoch());
+ }
+ TEST_EQUAL_UI(fs.uid, 0);
+ TEST_EQUAL_UI(fs.gid, 0);
+ TEST_EQUAL_UI(fs.mode, S_IFDIR | 0755);
+
+ str = strdup("mode=07777");
+ TEST_NOT_NULL(str);
+ TEST_ASSERT(parse_fstree_defaults(&fs, str) == 0);
+ free(str);
+
+ str = strdup("mode=017777");
+ TEST_NOT_NULL(str);
+ TEST_ASSERT(parse_fstree_defaults(&fs, str) != 0);
+ free(str);
+
+ return EXIT_SUCCESS;
+}
diff --git a/lib/fstree/Makemodule.am b/lib/fstree/Makemodule.am
index e2d2ae7..4d553f4 100644
--- a/lib/fstree/Makemodule.am
+++ b/lib/fstree/Makemodule.am
@@ -18,25 +18,21 @@ test_mknode_dir_SOURCES = lib/fstree/test/mknode_dir.c
test_mknode_dir_LDADD = libfstree.a libcompat.a
test_gen_inode_numbers_SOURCES = lib/fstree/test/gen_inode_numbers.c
-test_gen_inode_numbers_LDADD = libfstree.a libutil.a libcompat.a
+test_gen_inode_numbers_LDADD = libcommon.a libfstree.a libutil.a libcompat.a
test_add_by_path_SOURCES = lib/fstree/test/add_by_path.c
-test_add_by_path_LDADD = libfstree.a libutil.a libcompat.a
+test_add_by_path_LDADD = libcommon.a libfstree.a libutil.a libcompat.a
test_get_path_SOURCES = lib/fstree/test/get_path.c
-test_get_path_LDADD = libfstree.a libutil.a libcompat.a
+test_get_path_LDADD = libcommon.a libfstree.a libutil.a libcompat.a
test_fstree_sort_SOURCES = lib/fstree/test/fstree_sort.c
-test_fstree_sort_LDADD = libfstree.a libio.a libutil.a libcompat.a
-
-test_fstree_init_SOURCES = lib/fstree/test/fstree_init.c
-test_fstree_init_LDADD = libfstree.a libio.a libutil.a libcompat.a
+test_fstree_sort_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a
FSTREE_TESTS = \
test_mknode_simple test_mknode_slink \
test_mknode_reg test_mknode_dir test_gen_inode_numbers \
- test_add_by_path test_get_path test_fstree_sort \
- test_fstree_init
+ test_add_by_path test_get_path test_fstree_sort
check_PROGRAMS += $(FSTREE_TESTS)
TESTS += $(FSTREE_TESTS)
diff --git a/lib/fstree/src/fstree.c b/lib/fstree/src/fstree.c
index d44a8ae..19bd997 100644
--- a/lib/fstree/src/fstree.c
+++ b/lib/fstree/src/fstree.c
@@ -7,89 +7,10 @@
#include "config.h"
#include "fstree.h"
-#include "util/util.h"
-
#include <string.h>
#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 > (long)INT32_MAX)
- goto fail_ov;
- sb->st_uid = lval;
- break;
- case DEF_GID:
- lval = strtol(value, NULL, 0);
- if (lval < 0)
- goto fail_uv;
- if (lval > (long)INT32_MAX)
- 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 | (sqfs_u16)lval;
- break;
- case DEF_MTIME:
- lval = strtol(value, NULL, 0);
- if (lval < 0)
- goto fail_uv;
- if (lval > (long)INT32_MAX)
- goto fail_ov;
- sb->st_mtime = 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;
@@ -106,17 +27,20 @@ static void free_recursive(tree_node_t *n)
free(n);
}
-int fstree_init(fstree_t *fs, char *defaults)
+int fstree_init(fstree_t *fs, const fstree_defaults_t *defaults)
{
+ struct stat sb;
+
memset(fs, 0, sizeof(*fs));
- fs->defaults.st_mode = S_IFDIR | 0755;
- fs->defaults.st_blksize = 512;
- fs->defaults.st_mtime = get_source_date_epoch();
+ fs->defaults = *defaults;
- if (defaults != NULL && process_defaults(&fs->defaults, defaults) != 0)
- return -1;
+ memset(&sb, 0, sizeof(sb));
+ sb.st_mode = S_IFDIR | (defaults->mode & 07777);
+ sb.st_uid = defaults->uid;
+ sb.st_gid = defaults->gid;
+ sb.st_mtime = defaults->mtime;
- fs->root = fstree_mknode(NULL, "", 0, NULL, &fs->defaults);
+ fs->root = fstree_mknode(NULL, "", 0, NULL, &sb);
if (fs->root == NULL) {
perror("initializing file system tree");
diff --git a/lib/fstree/src/get_by_path.c b/lib/fstree/src/get_by_path.c
index 8742892..f5e7374 100644
--- a/lib/fstree/src/get_by_path.c
+++ b/lib/fstree/src/get_by_path.c
@@ -56,12 +56,20 @@ tree_node_t *fstree_get_node_by_path(fstree_t *fs, tree_node_t *root,
n = child_by_name(root, path, len);
if (n == NULL) {
+ struct stat sb;
+
if (!create_implicitly) {
errno = ENOENT;
return NULL;
}
- n = fstree_mknode(root, path, len, NULL, &fs->defaults);
+ memset(&sb, 0, sizeof(sb));
+ sb.st_mode = S_IFDIR | (fs->defaults.mode & 07777);
+ sb.st_uid = fs->defaults.uid;
+ sb.st_gid = fs->defaults.gid;
+ sb.st_mtime = fs->defaults.mtime;
+
+ n = fstree_mknode(root, path, len, NULL, &sb);
if (n == NULL)
return NULL;
diff --git a/lib/fstree/test/add_by_path.c b/lib/fstree/test/add_by_path.c
index 97e5a60..76bae6d 100644
--- a/lib/fstree/test/add_by_path.c
+++ b/lib/fstree/test/add_by_path.c
@@ -7,10 +7,12 @@
#include "config.h"
#include "fstree.h"
+#include "common.h"
#include "util/test.h"
int main(int argc, char **argv)
{
+ fstree_defaults_t fsd;
tree_node_t *a, *b;
struct stat sb;
fstree_t fs;
@@ -18,8 +20,9 @@ int main(int argc, char **argv)
(void)argc; (void)argv;
opts = strdup("mode=0755,uid=21,gid=42");
- TEST_ASSERT(fstree_init(&fs, opts) == 0);
+ TEST_ASSERT(parse_fstree_defaults(&fsd, opts) == 0);
free(opts);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
memset(&sb, 0, sizeof(sb));
sb.st_mode = S_IFDIR | 0750;
diff --git a/lib/fstree/test/fstree_init.c b/lib/fstree/test/fstree_init.c
deleted file mode 100644
index 186f25b..0000000
--- a/lib/fstree/test/fstree_init.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * fstree_init.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "config.h"
-
-#include "fstree.h"
-#include "util/test.h"
-#include "util/util.h"
-
-int main(int argc, char **argv)
-{
- fstree_t fs;
- char *str;
- (void)argc; (void)argv;
-
- str = strdup("mtime=1337,uid=1000,gid=100,mode=0321");
- TEST_NOT_NULL(str);
- TEST_ASSERT(fstree_init(&fs, str) == 0);
- free(str);
- TEST_EQUAL_UI(fs.defaults.st_mtime, 1337);
- TEST_EQUAL_UI(fs.defaults.st_uid, 1000);
- TEST_EQUAL_UI(fs.defaults.st_gid, 100);
- TEST_EQUAL_UI(fs.defaults.st_mode, S_IFDIR | 0321);
- fstree_cleanup(&fs);
-
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
- if (fs.defaults.st_mtime != 0) {
- TEST_EQUAL_UI(fs.defaults.st_mtime, get_source_date_epoch());
- }
- TEST_EQUAL_UI(fs.defaults.st_uid, 0);
- TEST_EQUAL_UI(fs.defaults.st_gid, 0);
- TEST_EQUAL_UI(fs.defaults.st_mode, S_IFDIR | 0755);
- fstree_cleanup(&fs);
-
- str = strdup("mode=07777");
- TEST_NOT_NULL(str);
- TEST_ASSERT(fstree_init(&fs, str) == 0);
- free(str);
- fstree_cleanup(&fs);
-
- str = strdup("mode=017777");
- TEST_NOT_NULL(str);
- TEST_ASSERT(fstree_init(&fs, str) != 0);
- free(str);
-
- return EXIT_SUCCESS;
-}
diff --git a/lib/fstree/test/fstree_sort.c b/lib/fstree/test/fstree_sort.c
index 7df85f5..0d18ac7 100644
--- a/lib/fstree/test/fstree_sort.c
+++ b/lib/fstree/test/fstree_sort.c
@@ -7,11 +7,13 @@
#include "config.h"
#include "fstree.h"
+#include "common.h"
#include "util/test.h"
int main(int argc, char **argv)
{
tree_node_t *a, *b, *c, *d;
+ fstree_defaults_t fsd;
struct stat sb;
fstree_t fs;
int ret;
@@ -22,7 +24,8 @@ int main(int argc, char **argv)
sb.st_rdev = 1337;
/* in order */
- ret = fstree_init(&fs, NULL);
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+ ret = fstree_init(&fs, &fsd);
TEST_EQUAL_I(ret, 0);
a = fstree_mknode(fs.root, "a", 1, NULL, &sb);
@@ -54,7 +57,7 @@ int main(int argc, char **argv)
fstree_cleanup(&fs);
/* out-of-order */
- ret = fstree_init(&fs, NULL);
+ ret = fstree_init(&fs, &fsd);
TEST_EQUAL_I(ret, 0);
d = fstree_mknode(fs.root, "d", 1, NULL, &sb);
diff --git a/lib/fstree/test/gen_inode_numbers.c b/lib/fstree/test/gen_inode_numbers.c
index 5403580..bb8c976 100644
--- a/lib/fstree/test/gen_inode_numbers.c
+++ b/lib/fstree/test/gen_inode_numbers.c
@@ -7,6 +7,7 @@
#include "config.h"
#include "fstree.h"
+#include "common.h"
#include "util/test.h"
static tree_node_t *gen_node(tree_node_t *parent, const char *name)
@@ -47,18 +48,20 @@ static void check_children_continuous(tree_node_t *root)
int main(int argc, char **argv)
{
tree_node_t *a, *b, *c;
+ fstree_defaults_t fsd;
fstree_t fs;
(void)argc; (void)argv;
// inode table for the empty tree
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
fstree_post_process(&fs);
TEST_EQUAL_UI(fs.unique_inode_count, 1);
TEST_EQUAL_UI(fs.root->inode_num, 1);
fstree_cleanup(&fs);
// tree with 2 levels under root, fan out 3
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
a = gen_node(fs.root, "a");
b = gen_node(fs.root, "b");
diff --git a/lib/fstree/test/get_path.c b/lib/fstree/test/get_path.c
index 61001e9..572cde7 100644
--- a/lib/fstree/test/get_path.c
+++ b/lib/fstree/test/get_path.c
@@ -7,17 +7,20 @@
#include "config.h"
#include "fstree.h"
+#include "common.h"
#include "util/test.h"
int main(int argc, char **argv)
{
tree_node_t *a, *b, *c, *d;
+ fstree_defaults_t fsd;
struct stat sb;
fstree_t fs;
char *str;
(void)argc; (void)argv;
- TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(parse_fstree_defaults(&fsd, NULL) == 0);
+ TEST_ASSERT(fstree_init(&fs, &fsd) == 0);
memset(&sb, 0, sizeof(sb));
sb.st_mode = S_IFDIR | 0750;