From 78aaef2a7ac9e852258e385ff3923353d78b8781 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 24 Jun 2012 18:35:49 -0500 Subject: Unify chown and chgrp, add support for -hHLP flags. --- lib/dirtree.c | 24 +++--------------------- lib/lib.h | 3 +-- 2 files changed, 4 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/lib/dirtree.c b/lib/dirtree.c index 53d51902..664588d8 100644 --- a/lib/dirtree.c +++ b/lib/dirtree.c @@ -84,21 +84,6 @@ int dirtree_parentfd(struct dirtree *node) return node->parent ? node->parent->data : AT_FDCWD; } -// get open filehandle for node in extra, giving caller the option of -// using DIRTREE_COMEAGAIN or not. -int dirtree_opennode(struct dirtree *try) -{ - if (!dirtree_notdotdot(try)) return 0; - if (S_ISDIR(try->st.st_mode)) { - if (!try->extra) { - try->extra = xdup(try->data); - return DIRTREE_COMEAGAIN; - } - } else try->extra = openat(dirtree_parentfd(try), try->name, 0); - - return DIRTREE_SAVE|DIRTREE_RECURSE; -} - // 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 @@ -114,18 +99,14 @@ struct dirtree *handle_callback(struct dirtree *new, if (!callback) callback = dirtree_notdotdot; - // Directory always has filehandle for examining contents. Whether or - // not we'll recurse into it gets decided later. - - if (dir) new->data = openat(dirtree_parentfd(new), new->name, 0); - flags = callback(new); if (dir) { if (flags & (DIRTREE_RECURSE|DIRTREE_COMEAGAIN)) { + new->data = openat(dirtree_parentfd(new), new->name, 0); dirtree_recurse(new, callback, flags & DIRTREE_SYMFOLLOW); if (flags & DIRTREE_COMEAGAIN) flags = callback(new); - } else close(new->data); + } } // If this had children, it was callback's job to free them already. @@ -180,6 +161,7 @@ void dirtree_recurse(struct dirtree *node, // 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. +// symfollow is just for the top of tree, callback return code controls children struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node)) { diff --git a/lib/lib.h b/lib/lib.h index a427640d..5ed06035 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -65,7 +65,7 @@ void get_optflags(void); struct dirtree { struct dirtree *next, *parent, *child; long extra; // place for user to store their stuff (can be pointer) - long data; // dirfd for directory, linklen for symlink + long data; // dirfd for directory, linklen for symlink, -1 = comeagain struct stat st; char *symlink; char name[]; @@ -75,7 +75,6 @@ struct dirtree *dirtree_add_node(int dirfd, char *name, int symfollow); char *dirtree_path(struct dirtree *node, int *plen); int dirtree_notdotdot(struct dirtree *catch); int dirtree_parentfd(struct dirtree *node); -int dirtree_opennode(struct dirtree *try); struct dirtree *handle_callback(struct dirtree *new, int (*callback)(struct dirtree *node)); void dirtree_recurse(struct dirtree *node, -- cgit v1.2.3