aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dirtree.c39
-rw-r--r--lib/lib.h7
2 files changed, 23 insertions, 23 deletions
diff --git a/lib/dirtree.c b/lib/dirtree.c
index 8b9f2993..cc1ab90c 100644
--- a/lib/dirtree.c
+++ b/lib/dirtree.c
@@ -17,7 +17,7 @@ static int notdotdot(char *name)
int dirtree_notdotdot(struct dirtree *catch)
{
// Should we skip "." and ".."?
- return notdotdot(catch->name) ? DIRTREE_SAVE|DIRTREE_RECURSE : 0;
+ return notdotdot(catch->name)*(DIRTREE_SAVE|DIRTREE_RECURSE);
}
// Create a dirtree node from a path, with stat and symlink info.
@@ -96,21 +96,18 @@ int dirtree_parentfd(struct dirtree *node)
return node->parent ? node->parent->dirfd : AT_FDCWD;
}
-// Handle callback for a node in the tree. Returns saved node(s) or NULL.
-//
-// By default, allocates a tree of struct dirtree, not following symlinks
-// If callback==NULL, or callback always returns 0, allocate tree of struct
-// dirtree and return root of tree. Otherwise call callback(node) on each
-// hit, free structures after use, and return NULL.
-//
+// Handle callback for a node in the tree. Returns saved node(s) if
+// callback returns DIRTREE_SAVE, otherwise frees consumed nodes and
+// returns NULL. If !callback return top node unchanged.
+// If !new return DIRTREE_ABORTVAL
struct dirtree *dirtree_handle_callback(struct dirtree *new,
int (*callback)(struct dirtree *node))
{
int flags;
- if (!new) return 0;
- if (!callback) callback = dirtree_notdotdot;
+ if (!new) return DIRTREE_ABORTVAL;
+ if (!callback) return new;
flags = callback(new);
if (S_ISDIR(new->st.st_mode)) {
@@ -176,19 +173,21 @@ int dirtree_recurse(struct dirtree *node,
return flags;
}
-// Create dirtree root
-struct dirtree *dirtree_start(char *name, int symfollow)
+// Create dirtree from path, using callback to filter nodes. If !callback
+// return just the top node. Use dirtree_notdotdot callback to allocate a
+// tree of struct dirtree nodes and return pointer to root node for later
+// processing.
+// Returns DIRTREE_ABORTVAL if path didn't exist (use DIRTREE_SHUTUP to handle
+// error message yourself).
+
+struct dirtree *dirtree_flagread(char *path, int flags,
+ int (*callback)(struct dirtree *node))
{
- return dirtree_add_node(0, name, DIRTREE_SYMFOLLOW*!!symfollow);
+ return dirtree_handle_callback(dirtree_add_node(0, path, flags), callback);
}
-// Create dirtree from path, using callback to filter nodes.
-// If callback == NULL allocate a tree of struct dirtree nodes and return
-// pointer to root node.
-
+// Common case
struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node))
{
- struct dirtree *root = dirtree_start(path, 0);
-
- return root ? dirtree_handle_callback(root, callback) : DIRTREE_ABORTVAL;
+ return dirtree_flagread(path, 0, callback);
}
diff --git a/lib/lib.h b/lib/lib.h
index c8cff6ef..917be0c1 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -62,6 +62,8 @@ void get_optflags(void);
#define DIRTREE_SYMFOLLOW 8
// Don't warn about failure to stat
#define DIRTREE_SHUTUP 16
+// Breadth first traversal, conserves filehandles at the expense of memory
+#define DIRTREE_BREADTH 32
// Don't look at any more files in this directory.
#define DIRTREE_ABORT 256
@@ -77,15 +79,14 @@ struct dirtree {
char name[];
};
-struct dirtree *dirtree_start(char *name, int symfollow);
struct dirtree *dirtree_add_node(struct dirtree *p, char *name, int flags);
char *dirtree_path(struct dirtree *node, int *plen);
int dirtree_notdotdot(struct dirtree *catch);
int dirtree_parentfd(struct dirtree *node);
-struct dirtree *dirtree_handle_callback(struct dirtree *new,
- int (*callback)(struct dirtree *node));
int dirtree_recurse(struct dirtree *node, int (*callback)(struct dirtree *node),
int symfollow);
+struct dirtree *dirtree_flagread(char *path, int flags,
+ int (*callback)(struct dirtree *node));
struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node));
// help.c