aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/tar.c5
-rw-r--r--coreutils/chmod.c2
-rw-r--r--coreutils/chown.c13
-rw-r--r--coreutils/diff.c3
-rw-r--r--debianutils/run_parts.c4
-rw-r--r--findutils/find.c14
-rw-r--r--findutils/grep.c6
-rw-r--r--include/libbb.h9
-rw-r--r--libbb/recursive_action.c41
-rw-r--r--modutils/insmod.c4
-rw-r--r--selinux/chcon.c4
11 files changed, 50 insertions, 55 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 176a7e22d..5a6ef60db 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -562,8 +562,9 @@ static int writeTarFile(const int tar_fd, const int verboseFlag,
/* Read the directory/files and iterate over them one at a time */
while (include) {
- if (!recursive_action(include->data, TRUE, dereferenceFlag,
- FALSE, writeFileToTarball, writeFileToTarball, &tbInfo, 0))
+ if (!recursive_action(include->data, (action_recurse |
+ dereferenceFlag ? action_followLinks : 0),
+ writeFileToTarball, writeFileToTarball, &tbInfo, 0))
{
errorFlag = TRUE;
}
diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index 11c6731a1..9a73218a1 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -101,8 +101,6 @@ int chmod_main(int argc, char **argv)
do {
if (!recursive_action(*argv,
OPT_RECURSE, // recurse
- FALSE, // follow links: coreutils doesn't
- FALSE, // depth first
fileAction, // file action
fileAction, // dir action
smode, // user data
diff --git a/coreutils/chown.c b/coreutils/chown.c
index f92299e36..09b1a595b 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -92,13 +92,12 @@ int chown_main(int argc, char **argv)
}
if (!recursive_action(arg,
- OPT_RECURSE, // recurse
- OPT_TRAVERSE, // follow links if -L
- FALSE, // depth first
- fileAction, // file action
- fileAction, // dir action
- chown_func, // user data
- 0) // depth
+ (OPT_RECURSE ? action_recurse : 0 | /* recurse */
+ OPT_TRAVERSE ? action_followLinks : 0),/* follow links if -L */
+ fileAction, /* file action */
+ fileAction, /* dir action */
+ chown_func, /* user data */
+ 0) /* depth */
) {
retval = EXIT_FAILURE;
}
diff --git a/coreutils/diff.c b/coreutils/diff.c
index 911bfcf4d..1903bb151 100644
--- a/coreutils/diff.c
+++ b/coreutils/diff.c
@@ -1079,7 +1079,8 @@ static char **get_dir(char *path)
* add_to_dirlist then removes root dir prefix. */
if (option_mask32 & FLAG_r) {
- recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL,
+ recursive_action(path, action_recurse|action_followLinks,
+ add_to_dirlist, NULL,
(void*)(strlen(path)+1), 0);
} else {
DIR *dp;
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index b41045a36..c67072730 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -138,9 +138,7 @@ int run_parts_main(int argc, char **argv)
G.cmd[tmp] = arg_list->data;
/* G.cmd[tmp] = NULL; - G is already zeroed out */
if (!recursive_action(argv[argc - 1],
- TRUE, /* recurse */
- TRUE, /* follow links */
- FALSE, /* depth first */
+ action_recurse|action_followLinks,
act, /* file action */
act, /* dir action */
NULL, /* user data */
diff --git a/findutils/find.c b/findutils/find.c
index e98d995a4..c043fbc7d 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -574,7 +574,7 @@ static action*** parse_params(char **argv)
int find_main(int argc, char **argv);
int find_main(int argc, char **argv)
{
- int dereference = FALSE;
+ bool dereference = FALSE;
char *arg;
char **argp;
int i, firstopt, status = EXIT_SUCCESS;
@@ -632,13 +632,11 @@ int find_main(int argc, char **argv)
for (i = 1; i < firstopt; i++) {
if (!recursive_action(argv[i],
- TRUE, // recurse
- dereference, // follow links
- FALSE, // depth first
- fileAction, // file action
- fileAction, // dir action
- NULL, // user data
- 0)) // depth
+ action_recurse|(1<<dereference), /* flags */
+ fileAction, /* file action */
+ fileAction, /* dir action */
+ NULL, /* user data */
+ 0)) /* depth */
status = EXIT_FAILURE;
}
return status;
diff --git a/findutils/grep.c b/findutils/grep.c
index f6ea54ed2..43810ea84 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -336,9 +336,9 @@ static int grep_dir(const char *dir)
{
int matched = 0;
recursive_action(dir,
- /* recurse= */ 1,
- /* followLinks= */ 0,
- /* depthFirst= */ 1,
+ /* recurse= */ action_recurse |
+ /* followLinks= */ /* no. 0 | */
+ /* depthFirst= */ action_depthFirst,
/* fileAction= */ file_action_grep,
/* dirAction= */ NULL,
/* userData= */ &matched,
diff --git a/include/libbb.h b/include/libbb.h
index d734abed6..7f0ad2c25 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -231,11 +231,14 @@ extern const char *bb_mode_string(mode_t mode);
extern int is_directory(const char *name, int followLinks, struct stat *statBuf);
extern int remove_file(const char *path, int flags);
extern int copy_file(const char *source, const char *dest, int flags);
-extern int recursive_action(const char *fileName, int recurse,
- int followLinks, int depthFirst,
+#define action_recurse (1<<0)
+#define action_followLinks (1<<1)
+#define action_depthFirst (1<<2)
+#define action_reverse (1<<3)
+extern int recursive_action(const char *fileName, unsigned flags,
int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
- void* userData, int depth);
+ void* userData, const unsigned depth);
extern int device_open(const char *device, int mode);
extern int get_console_fd(void);
extern char *find_block_device(const char *path);
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c
index 25a87b88e..0c0531575 100644
--- a/libbb/recursive_action.c
+++ b/libbb/recursive_action.c
@@ -22,7 +22,8 @@
* is so stinking huge.
*/
-static int true_action(const char *fileName, struct stat *statbuf, void* userData, int depth)
+static int true_action(const char *fileName, struct stat *statbuf,
+ void* userData, int depth)
{
return TRUE;
}
@@ -41,11 +42,11 @@ static int true_action(const char *fileName, struct stat *statbuf, void* userDat
*/
int recursive_action(const char *fileName,
- int recurse, int followLinks, int depthFirst,
+ unsigned flags,
int (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
int (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
void* userData,
- int depth)
+ const unsigned depth)
{
struct stat statbuf;
int status;
@@ -54,22 +55,20 @@ int recursive_action(const char *fileName,
if (!fileAction) fileAction = true_action;
if (!dirAction) dirAction = true_action;
-
- status = (followLinks ? stat : lstat)(fileName, &statbuf);
+ status = (flags & action_followLinks ? stat : lstat)(fileName, &statbuf);
if (status < 0) {
#ifdef DEBUG_RECURS_ACTION
bb_error_msg("status=%d followLinks=%d TRUE=%d",
- status, followLinks, TRUE);
+ status, flags & action_followLinks, TRUE);
#endif
- bb_perror_msg("%s", fileName);
- return FALSE;
+ goto done_nak_warn;
}
/* If S_ISLNK(m), then we know that !S_ISDIR(m).
* Then we can skip checking first part: if it is true, then
* (!dir) is also true! */
- if ( /* (!followLinks && S_ISLNK(statbuf.st_mode)) || */
+ if ( /* (!(flags & action_followLinks) && S_ISLNK(statbuf.st_mode)) || */
!S_ISDIR(statbuf.st_mode)
) {
return fileAction(fileName, &statbuf, userData, depth);
@@ -77,15 +76,14 @@ int recursive_action(const char *fileName,
/* It's a directory (or a link to one, and followLinks is set) */
- if (!recurse) {
+ if (!(flags & action_recurse)) {
return dirAction(fileName, &statbuf, userData, depth);
}
- if (!depthFirst) {
+ if (!(flags & action_depthFirst)) {
status = dirAction(fileName, &statbuf, userData, depth);
if (!status) {
- bb_perror_msg("%s", fileName);
- return FALSE;
+ goto done_nak_warn;
}
if (status == SKIP)
return TRUE;
@@ -96,8 +94,7 @@ int recursive_action(const char *fileName,
/* findutils-4.1.20 reports this */
/* (i.e. it doesn't silently return with exit code 1) */
/* To trigger: "find -exec rm -rf {} \;" */
- bb_perror_msg("%s", fileName);
- return FALSE;
+ goto done_nak_warn;
}
status = TRUE;
while ((next = readdir(dir)) != NULL) {
@@ -106,21 +103,23 @@ int recursive_action(const char *fileName,
nextFile = concat_subpath_file(fileName, next->d_name);
if (nextFile == NULL)
continue;
- if (!recursive_action(nextFile, TRUE, followLinks, depthFirst,
+ /* now descend into it, forcing recursion. */
+ if (!recursive_action(nextFile, flags | action_recurse,
fileAction, dirAction, userData, depth+1)) {
status = FALSE;
}
free(nextFile);
}
closedir(dir);
- if (depthFirst) {
- if (!dirAction(fileName, &statbuf, userData, depth)) {
- bb_perror_msg("%s", fileName);
- return FALSE;
- }
+ if (flags & action_depthFirst &&
+ !dirAction(fileName, &statbuf, userData, depth)) {
+ goto done_nak_warn;
}
if (!status)
return FALSE;
return TRUE;
+done_nak_warn:
+ bb_perror_msg("%s", fileName);
+ return FALSE;
}
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 57092f79a..075969dcb 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -4044,7 +4044,7 @@ int insmod_main( int argc, char **argv)
module_dir = tmdn;
else
module_dir = real_module_dir;
- recursive_action(module_dir, TRUE, FALSE, FALSE,
+ recursive_action(module_dir, action_recurse,
check_module_name_match, 0, m_fullName, 0);
free(tmdn);
}
@@ -4059,7 +4059,7 @@ int insmod_main( int argc, char **argv)
strcpy(module_dir, _PATH_MODULES);
/* No module found under /lib/modules/`uname -r`, this
* time cast the net a bit wider. Search /lib/modules/ */
- if (!recursive_action(module_dir, TRUE, FALSE, FALSE,
+ if (!recursive_action(module_dir, action_recurse,
check_module_name_match, 0, m_fullName, 0)
) {
if (m_filename == 0
diff --git a/selinux/chcon.c b/selinux/chcon.c
index 72cfa93c3..0eab6864e 100644
--- a/selinux/chcon.c
+++ b/selinux/chcon.c
@@ -163,9 +163,7 @@ int chcon_main(int argc, char *argv[])
fname[fname_len] = '\0';
if (recursive_action(fname,
- option_mask32 & OPT_RECURSIVE,
- FALSE, /* followLinks */
- FALSE, /* depthFirst */
+ 1<<option_mask32 & OPT_RECURSIVE,
change_filedir_context,
change_filedir_context,
NULL, 0) != TRUE)