From 0a6c5d7fa2f276b8e155d69bea17650bad46f089 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 18 Dec 2019 19:57:22 +0100 Subject: Split the libfstree add_by_path tree traversal function out Signed-off-by: David Oberhollenzer --- lib/fstree/get_by_path.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lib/fstree/get_by_path.c (limited to 'lib/fstree/get_by_path.c') 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 + */ +#include "config.h" + +#include "fstree.h" + +#include +#include + +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; +} -- cgit v1.2.3