diff options
Diffstat (limited to 'lib/fstree')
-rw-r--r-- | lib/fstree/Makemodule.am | 2 | ||||
-rw-r--r-- | lib/fstree/add_by_path.c | 56 | ||||
-rw-r--r-- | lib/fstree/get_by_path.c | 76 |
3 files changed, 82 insertions, 52 deletions
diff --git a/lib/fstree/Makemodule.am b/lib/fstree/Makemodule.am index 31bcb31..751d7dc 100644 --- a/lib/fstree/Makemodule.am +++ b/lib/fstree/Makemodule.am @@ -2,7 +2,7 @@ libfstree_a_SOURCES = lib/fstree/fstree.c lib/fstree/fstree_from_file.c libfstree_a_SOURCES += lib/fstree/fstree_sort.c libfstree_a_SOURCES += lib/fstree/post_process.c lib/fstree/get_path.c libfstree_a_SOURCES += lib/fstree/mknode.c -libfstree_a_SOURCES += lib/fstree/add_by_path.c +libfstree_a_SOURCES += lib/fstree/add_by_path.c lib/fstree/get_by_path.c libfstree_a_SOURCES += include/fstree.h lib/fstree/internal.h libfstree_a_SOURCES += lib/fstree/source_date_epoch.c libfstree_a_SOURCES += lib/fstree/canonicalize_name.c diff --git a/lib/fstree/add_by_path.c b/lib/fstree/add_by_path.c index bd47a76..7c9063e 100644 --- a/lib/fstree/add_by_path.c +++ b/lib/fstree/add_by_path.c @@ -11,69 +11,23 @@ #include <string.h> #include <errno.h> -static tree_node_t *child_by_name(tree_node_t *root, const char *name, - size_t len) -{ - tree_node_t *n = root->data.dir.children; - - while (n != NULL) { - if (strncmp(n->name, name, len) == 0 && n->name[len] == '\0') - break; - - n = n->next; - } - - return n; -} - -static tree_node_t *get_parent_node(fstree_t *fs, tree_node_t *root, - const char *path) -{ - const char *end; - tree_node_t *n; - - for (;;) { - if (!S_ISDIR(root->mode)) { - errno = ENOTDIR; - return NULL; - } - - end = strchr(path, '/'); - if (end == NULL) - break; - - n = child_by_name(root, path, end - path); - - if (n == NULL) { - n = fstree_mknode(root, path, end - path, NULL, - &fs->defaults); - if (n == NULL) - return NULL; - - n->data.dir.created_implicitly = true; - } - - root = n; - path = end + 1; - } - - return root; -} - tree_node_t *fstree_add_generic(fstree_t *fs, const char *path, const struct stat *sb, const char *extra) { tree_node_t *child, *parent; const char *name; - parent = get_parent_node(fs, fs->root, path); + parent = fstree_get_node_by_path(fs, fs->root, path, true, true); if (parent == NULL) return NULL; name = strrchr(path, '/'); name = (name == NULL ? path : (name + 1)); - child = child_by_name(parent, name, strlen(name)); + child = parent->data.dir.children; + while (child != NULL && strcmp(child->name, name) != 0) + child = child->next; + if (child != NULL) { if (!S_ISDIR(child->mode) || !S_ISDIR(sb->st_mode) || !child->data.dir.created_implicitly) { diff --git a/lib/fstree/get_by_path.c b/lib/fstree/get_by_path.c new file mode 100644 index 0000000..8742892 --- /dev/null +++ b/lib/fstree/get_by_path.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * get_by_path.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" + +#include "fstree.h" + +#include <string.h> +#include <errno.h> + +static tree_node_t *child_by_name(tree_node_t *root, const char *name, + size_t len) +{ + tree_node_t *n = root->data.dir.children; + + while (n != NULL) { + if (strncmp(n->name, name, len) == 0 && n->name[len] == '\0') + break; + + n = n->next; + } + + return n; +} + +tree_node_t *fstree_get_node_by_path(fstree_t *fs, tree_node_t *root, + const char *path, bool create_implicitly, + bool stop_at_parent) +{ + const char *end; + tree_node_t *n; + size_t len; + + while (*path != '\0') { + while (*path == '/') + ++path; + + if (!S_ISDIR(root->mode)) { + errno = ENOTDIR; + return NULL; + } + + end = strchr(path, '/'); + if (end == NULL) { + if (stop_at_parent) + break; + + len = strlen(path); + } else { + len = end - path; + } + + n = child_by_name(root, path, len); + + if (n == NULL) { + if (!create_implicitly) { + errno = ENOENT; + return NULL; + } + + n = fstree_mknode(root, path, len, NULL, &fs->defaults); + if (n == NULL) + return NULL; + + n->data.dir.created_implicitly = true; + } + + root = n; + path = path + len; + } + + return root; +} |