aboutsummaryrefslogtreecommitdiff
path: root/lib/fstree
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-06 14:53:49 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-06 18:07:59 +0200
commitc42e4fbbc6b175f843c4d0eeaaa9ead2d0e746b6 (patch)
treeadf2e61d9acdf5e18321d6ba0277dd3428de8fe3 /lib/fstree
parent23fab1d2b8164a99c5536581bb80769a620c65c0 (diff)
Cleanup: libfstree: move all the hardlink related code to hardlink.c
For some reason, the recursive hardlink resolution ended up in post process, calling into the non recrusive one in hardlink.c that wasn't used elsewhere. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/fstree')
-rw-r--r--lib/fstree/src/hardlink.c99
-rw-r--r--lib/fstree/src/post_process.c47
2 files changed, 76 insertions, 70 deletions
diff --git a/lib/fstree/src/hardlink.c b/lib/fstree/src/hardlink.c
index 2165b5f..9686219 100644
--- a/lib/fstree/src/hardlink.c
+++ b/lib/fstree/src/hardlink.c
@@ -11,32 +11,10 @@
#include <string.h>
#include <stdlib.h>
+#include <assert.h>
#include <errno.h>
-tree_node_t *fstree_add_hard_link(fstree_t *fs, const char *path,
- const char *target)
-{
- struct stat sb;
- tree_node_t *n;
-
- memset(&sb, 0, sizeof(sb));
- sb.st_mode = S_IFLNK | 0777;
-
- n = fstree_add_generic(fs, path, &sb, target);
- if (n != NULL) {
- if (canonicalize_name(n->data.target)) {
- free(n);
- errno = EINVAL;
- return NULL;
- }
-
- n->mode = FSTREE_MODE_HARD_LINK;
- }
-
- return n;
-}
-
-int fstree_resolve_hard_link(fstree_t *fs, tree_node_t *node)
+static int resolve_link(fstree_t *fs, tree_node_t *node)
{
tree_node_t *start = node;
@@ -74,3 +52,76 @@ int fstree_resolve_hard_link(fstree_t *fs, tree_node_t *node)
node->link_count++;
return 0;
}
+
+static int resolve_hard_links_dfs(fstree_t *fs, tree_node_t *n)
+{
+ tree_node_t *it;
+
+ if (n->mode == FSTREE_MODE_HARD_LINK) {
+ if (resolve_link(fs, n))
+ goto fail_link;
+
+ assert(n->mode == FSTREE_MODE_HARD_LINK_RESOLVED);
+ it = n->data.target_node;
+
+ if (S_ISDIR(it->mode) && it->data.dir.visited)
+ goto fail_link_loop;
+ } else if (S_ISDIR(n->mode)) {
+ n->data.dir.visited = true;
+
+ for (it = n->data.dir.children; it != NULL; it = it->next) {
+ if (resolve_hard_links_dfs(fs, it))
+ return -1;
+ }
+
+ n->data.dir.visited = false;
+ }
+
+ return 0;
+fail_link: {
+ char *path = fstree_get_path(n);
+ fprintf(stderr, "Resolving hard link '%s' -> '%s': %s\n",
+ path == NULL ? n->name : path, n->data.target,
+ strerror(errno));
+ free(path);
+}
+ return -1;
+fail_link_loop: {
+ char *npath = fstree_get_path(n);
+ char *tpath = fstree_get_path(it);
+ fprintf(stderr, "Hard link loop detected in '%s' -> '%s'\n",
+ npath == NULL ? n->name : npath,
+ tpath == NULL ? it->name : tpath);
+ free(npath);
+ free(tpath);
+}
+ return -1;
+}
+
+tree_node_t *fstree_add_hard_link(fstree_t *fs, const char *path,
+ const char *target)
+{
+ struct stat sb;
+ tree_node_t *n;
+
+ memset(&sb, 0, sizeof(sb));
+ sb.st_mode = S_IFLNK | 0777;
+
+ n = fstree_add_generic(fs, path, &sb, target);
+ if (n != NULL) {
+ if (canonicalize_name(n->data.target)) {
+ free(n);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ n->mode = FSTREE_MODE_HARD_LINK;
+ }
+
+ return n;
+}
+
+int fstree_resolve_hard_links(fstree_t *fs)
+{
+ return resolve_hard_links_dfs(fs, fs->root);
+}
diff --git a/lib/fstree/src/post_process.c b/lib/fstree/src/post_process.c
index 088916b..940f93d 100644
--- a/lib/fstree/src/post_process.c
+++ b/lib/fstree/src/post_process.c
@@ -56,51 +56,6 @@ fail_ov:
return -1;
}
-static int resolve_hard_links_dfs(fstree_t *fs, tree_node_t *n)
-{
- tree_node_t *it;
-
- if (n->mode == FSTREE_MODE_HARD_LINK) {
- if (fstree_resolve_hard_link(fs, n))
- goto fail_link;
-
- assert(n->mode == FSTREE_MODE_HARD_LINK_RESOLVED);
- it = n->data.target_node;
-
- if (S_ISDIR(it->mode) && it->data.dir.visited)
- goto fail_link_loop;
- } else if (S_ISDIR(n->mode)) {
- n->data.dir.visited = true;
-
- for (it = n->data.dir.children; it != NULL; it = it->next) {
- if (resolve_hard_links_dfs(fs, it))
- return -1;
- }
-
- n->data.dir.visited = false;
- }
-
- return 0;
-fail_link: {
- char *path = fstree_get_path(n);
- fprintf(stderr, "Resolving hard link '%s' -> '%s': %s\n",
- path == NULL ? n->name : path, n->data.target,
- strerror(errno));
- free(path);
-}
- return -1;
-fail_link_loop: {
- char *npath = fstree_get_path(n);
- char *tpath = fstree_get_path(it);
- fprintf(stderr, "Hard link loop detected in '%s' -> '%s'\n",
- npath == NULL ? n->name : npath,
- tpath == NULL ? it->name : tpath);
- free(npath);
- free(tpath);
-}
- return -1;
-}
-
static file_info_t *file_list_dfs(tree_node_t *n)
{
if (S_ISREG(n->mode)) {
@@ -187,7 +142,7 @@ int fstree_post_process(fstree_t *fs)
{
size_t inum;
- if (resolve_hard_links_dfs(fs, fs->root))
+ if (fstree_resolve_hard_links(fs))
return -1;
fs->unique_inode_count = 0;