aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-03-25 14:23:58 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-03-25 14:35:39 +0100
commitb0b88d26c9df6d336167f87ce926bba9b56f6af0 (patch)
tree39733ee0a0127380bc7b4c93cd67f6a15afc74e4
parentbd87f7c8a46cabe6d4c71d9cea74329898da31a7 (diff)
libfstree: Allow / as argument for "glob" and "dir" commands
This allows putting globbed files & directories into the filesystem root, as well as explicitly setting attributes of the root directory from the file lisiting. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--lib/fstree/add_by_path.c7
-rw-r--r--lib/fstree/fstree.c1
-rw-r--r--lib/fstree/fstree_from_file.c26
-rw-r--r--tests/libfstree/Makemodule.am1
-rw-r--r--tests/libfstree/fstree1.txt1
-rw-r--r--tests/libfstree/fstree_from_file.c3
-rw-r--r--tests/libfstree/fstree_glob1.c59
-rw-r--r--tests/libfstree/fstree_glob3.txt2
8 files changed, 71 insertions, 29 deletions
diff --git a/lib/fstree/add_by_path.c b/lib/fstree/add_by_path.c
index 7c9063e..8918efc 100644
--- a/lib/fstree/add_by_path.c
+++ b/lib/fstree/add_by_path.c
@@ -17,6 +17,11 @@ tree_node_t *fstree_add_generic(fstree_t *fs, const char *path,
tree_node_t *child, *parent;
const char *name;
+ if (*path == '\0') {
+ child = fs->root;
+ goto out;
+ }
+
parent = fstree_get_node_by_path(fs, fs->root, path, true, true);
if (parent == NULL)
return NULL;
@@ -27,7 +32,7 @@ tree_node_t *fstree_add_generic(fstree_t *fs, const char *path,
child = parent->data.dir.children;
while (child != NULL && strcmp(child->name, name) != 0)
child = child->next;
-
+out:
if (child != NULL) {
if (!S_ISDIR(child->mode) || !S_ISDIR(sb->st_mode) ||
!child->data.dir.created_implicitly) {
diff --git a/lib/fstree/fstree.c b/lib/fstree/fstree.c
index b2e199d..7c00755 100644
--- a/lib/fstree/fstree.c
+++ b/lib/fstree/fstree.c
@@ -120,6 +120,7 @@ int fstree_init(fstree_t *fs, char *defaults)
return -1;
}
+ fs->root->data.dir.created_implicitly = true;
return 0;
}
diff --git a/lib/fstree/fstree_from_file.c b/lib/fstree/fstree_from_file.c
index dd7ca22..3bf8cd1 100644
--- a/lib/fstree/fstree_from_file.c
+++ b/lib/fstree/fstree_from_file.c
@@ -344,19 +344,20 @@ static const struct callback_t {
unsigned int mode;
bool need_extra;
bool is_glob;
+ bool allow_root;
int (*callback)(fstree_t *fs, const char *filename, size_t line_num,
const char *path, struct stat *sb,
const char *basepath, unsigned int glob_flags,
const char *extra);
} file_list_hooks[] = {
- { "dir", S_IFDIR, false, false, add_generic },
- { "slink", S_IFLNK, true, false, add_generic },
- { "link", 0, true, false, add_hard_link },
- { "nod", 0, true, false, add_device },
- { "pipe", S_IFIFO, false, false, add_generic },
- { "sock", S_IFSOCK, false, false, add_generic },
- { "file", S_IFREG, false, false, add_file },
- { "glob", 0, true, true, glob_files },
+ { "dir", S_IFDIR, false, false, true, add_generic },
+ { "slink", S_IFLNK, true, false, false, add_generic },
+ { "link", 0, true, false, false, add_hard_link },
+ { "nod", 0, true, false, false, add_device },
+ { "pipe", S_IFIFO, false, false, false, add_generic },
+ { "sock", S_IFSOCK, false, false, false, add_generic },
+ { "file", S_IFREG, false, false, false, add_file },
+ { "glob", 0, true, true, true, glob_files },
};
#define NUM_HOOKS (sizeof(file_list_hooks) / sizeof(file_list_hooks[0]))
@@ -456,9 +457,12 @@ static int handle_line(fstree_t *fs, const char *filename,
if ((line = read_str(line, &path)) == NULL)
goto fail_ent;
- if (canonicalize_name(path) || *path == '\0')
+ if (canonicalize_name(path))
goto fail_ent;
+ if (*path == '\0' && !cb->allow_root)
+ goto fail_root;
+
if (cb->is_glob && *line == '*') {
++line;
mode = 0;
@@ -507,6 +511,10 @@ static int handle_line(fstree_t *fs, const char *filename,
return cb->callback(fs, filename, line_num, path,
&sb, basepath, glob_flags, extra);
+fail_root:
+ fprintf(stderr, "%s: " PRI_SZ ": cannot use / as argument for %s.\n",
+ filename, line_num, cb->keyword);
+ return -1;
fail_no_extra:
fprintf(stderr, "%s: " PRI_SZ ": missing argument for %s.\n",
filename, line_num, cb->keyword);
diff --git a/tests/libfstree/Makemodule.am b/tests/libfstree/Makemodule.am
index 4dc6da1..8248f5c 100644
--- a/tests/libfstree/Makemodule.am
+++ b/tests/libfstree/Makemodule.am
@@ -74,3 +74,4 @@ endif
EXTRA_DIST += $(FSTDATADIR)/fstree1.txt
EXTRA_DIST += $(FSTDATADIR)/fstree_glob1.txt $(FSTDATADIR)/fstree_glob2.txt
+EXTRA_DIST += $(FSTDATADIR)/fstree_glob3.txt
diff --git a/tests/libfstree/fstree1.txt b/tests/libfstree/fstree1.txt
index 090aff9..95ee469 100644
--- a/tests/libfstree/fstree1.txt
+++ b/tests/libfstree/fstree1.txt
@@ -4,6 +4,7 @@ dir /dir 0755 4 5
nod /chardev 0600 6 7 c 13 37
nod /blkdev 0600 8 9 b 42 21
pipe /pipe 0644 10 11
+dir / 0755 1000 100
dir "/foo bar" 0755 0 0
dir "/foo bar/ test \"/" 0755 0 0
sock /sock 0555 12 13 \ No newline at end of file
diff --git a/tests/libfstree/fstree_from_file.c b/tests/libfstree/fstree_from_file.c
index c8816e6..5d37960 100644
--- a/tests/libfstree/fstree_from_file.c
+++ b/tests/libfstree/fstree_from_file.c
@@ -21,6 +21,9 @@ int main(void)
n = fs.root->data.dir.children;
TEST_EQUAL_UI(fs.root->link_count, 9);
+ TEST_EQUAL_UI(fs.root->mode, S_IFDIR | 0755);
+ TEST_EQUAL_UI(fs.root->uid, 1000);
+ TEST_EQUAL_UI(fs.root->gid, 100);
TEST_EQUAL_UI(n->mode, S_IFBLK | 0600);
TEST_EQUAL_UI(n->uid, 8);
diff --git a/tests/libfstree/fstree_glob1.c b/tests/libfstree/fstree_glob1.c
index 592180b..708b0e8 100644
--- a/tests/libfstree/fstree_glob1.c
+++ b/tests/libfstree/fstree_glob1.c
@@ -9,22 +9,32 @@
#include "fstree.h"
#include "../test.h"
-static void check_hierarchy(tree_node_t *root, bool recursive)
+static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive)
{
- tree_node_t *n, *m;
-
- n = root->data.dir.children;
- TEST_NOT_NULL(n);
- TEST_STR_EQUAL(n->name, "tarcorpus");
- TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root);
- TEST_NULL(n->next);
+ tree_node_t *n, *m, *parentdir;
+
+ if (subdir) {
+ n = root->data.dir.children;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "tarcorpus");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_ASSERT(n->parent == root);
+ TEST_NULL(n->next);
+ } else {
+ n = root;
+ TEST_NOT_NULL(n);
+ TEST_STR_EQUAL(n->name, "");
+ TEST_ASSERT(S_ISDIR(n->mode));
+ TEST_NULL(n->parent);
+ TEST_NULL(n->next);
+ }
+ parentdir = n;
n = n->data.dir.children;
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "file-size");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -43,7 +53,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "format-acceptance");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -68,7 +78,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "large-mtime");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -87,7 +97,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "long-paths");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -106,7 +116,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "negative-mtime");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -125,7 +135,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "sparse-files");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -168,7 +178,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "user-group-largenum");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
if (recursive) {
m = n->data.dir.children;
@@ -187,7 +197,7 @@ static void check_hierarchy(tree_node_t *root, bool recursive)
TEST_NOT_NULL(n);
TEST_STR_EQUAL(n->name, "xattr");
TEST_ASSERT(S_ISDIR(n->mode));
- TEST_ASSERT(n->parent == root->data.dir.children);
+ TEST_ASSERT(n->parent == parentdir);
TEST_NULL(n->data.dir.children);
n = n->next;
@@ -207,7 +217,7 @@ int main(void)
TEST_EQUAL_I(ret, 0);
fstree_post_process(&fs);
- check_hierarchy(fs.root, false);
+ check_hierarchy(fs.root, true, false);
fstree_cleanup(&fs);
/* first test case, directory tree plus fnmatch()ed files */
@@ -218,7 +228,18 @@ int main(void)
TEST_EQUAL_I(ret, 0);
fstree_post_process(&fs);
- check_hierarchy(fs.root, true);
+ check_hierarchy(fs.root, true, true);
+ fstree_cleanup(&fs);
+
+ /* third test case, same as second, but entries directly at the root */
+ ret = fstree_init(&fs, NULL);
+ TEST_EQUAL_I(ret, 0);
+
+ ret = fstree_from_file(&fs, TEST_PATH "/fstree_glob3.txt", TEST_PATH);
+ TEST_EQUAL_I(ret, 0);
+
+ fstree_post_process(&fs);
+ check_hierarchy(fs.root, false, true);
fstree_cleanup(&fs);
return EXIT_SUCCESS;
}
diff --git a/tests/libfstree/fstree_glob3.txt b/tests/libfstree/fstree_glob3.txt
new file mode 100644
index 0000000..35090e4
--- /dev/null
+++ b/tests/libfstree/fstree_glob3.txt
@@ -0,0 +1,2 @@
+glob / 0755 0 0 -type d ../libtar/data
+glob / 0644 0 0 -type f -name "*gnu*.tar" -- ../libtar/data