diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-08 14:52:28 +0400 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-08 14:52:28 +0400 |
commit | bbd695d8010ab453a5a89ba6d7ebfe1a96b87b7d (patch) | |
tree | 98df39594da2e7f1fbe560aec04eeb09426947f0 | |
parent | ca3484103e6b99d0c433988f2f809840d780d88b (diff) |
find: fix handling of -prune
recursive_actions: uppercase flag constants
-rw-r--r-- | archival/tar.c | 4 | ||||
-rw-r--r-- | coreutils/chown.c | 4 | ||||
-rw-r--r-- | coreutils/diff.c | 2 | ||||
-rw-r--r-- | debianutils/run_parts.c | 2 | ||||
-rw-r--r-- | findutils/find.c | 68 | ||||
-rw-r--r-- | findutils/grep.c | 6 | ||||
-rw-r--r-- | include/libbb.h | 26 | ||||
-rw-r--r-- | libbb/recursive_action.c | 14 | ||||
-rw-r--r-- | modutils/insmod.c | 4 |
9 files changed, 71 insertions, 59 deletions
diff --git a/archival/tar.c b/archival/tar.c index 5a6ef60db..6552d6c57 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -562,8 +562,8 @@ 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, (action_recurse | - dereferenceFlag ? action_followLinks : 0), + if (!recursive_action(include->data, ACTION_RECURSE | + (dereferenceFlag ? ACTION_FOLLOWLINKS : 0), writeFileToTarball, writeFileToTarball, &tbInfo, 0)) { errorFlag = TRUE; diff --git a/coreutils/chown.c b/coreutils/chown.c index 09b1a595b..e64a39c3e 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -92,8 +92,8 @@ int chown_main(int argc, char **argv) } if (!recursive_action(arg, - (OPT_RECURSE ? action_recurse : 0 | /* recurse */ - OPT_TRAVERSE ? action_followLinks : 0),/* follow links if -L */ + (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 */ diff --git a/coreutils/diff.c b/coreutils/diff.c index 75557187c..09cacbde6 100644 --- a/coreutils/diff.c +++ b/coreutils/diff.c @@ -1079,7 +1079,7 @@ static char **get_dir(char *path) * add_to_dirlist then removes root dir prefix. */ if (option_mask32 & FLAG_r) { - recursive_action(path, action_recurse|action_followLinks, + recursive_action(path, ACTION_RECURSE|ACTION_FOLLOWLINKS, add_to_dirlist, NULL, (void*)(strlen(path)+1), 0); } else { diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index c67072730..873263a22 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -138,7 +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], - action_recurse|action_followLinks, + ACTION_RECURSE|ACTION_FOLLOWLINKS, act, /* file action */ act, /* dir action */ NULL, /* user data */ diff --git a/findutils/find.c b/findutils/find.c index 43120250b..3eea53db0 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -70,7 +70,7 @@ USE_FEATURE_FIND_MTIME( ACTS(mtime, char mtime_char; unsigned mtime_days;)) USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;)) USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;)) USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;)) -USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned int *subst_count; int exec_argc;)) +USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;)) USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) @@ -79,12 +79,12 @@ USE_FEATURE_FIND_PRUNE( ACTS(prune)) static action ***actions; static bool need_print = 1; -static int recurse_flags = action_recurse; +static int recurse_flags = ACTION_RECURSE; #if ENABLE_FEATURE_FIND_EXEC -static unsigned int count_subst(const char *str) +static unsigned count_subst(const char *str) { - unsigned int count = 0; + unsigned count = 0; while ((str = strstr(str, "{}"))) { count++; str++; @@ -93,7 +93,7 @@ static unsigned int count_subst(const char *str) } -static char* subst(const char *src, unsigned int count, const char* filename) +static char* subst(const char *src, unsigned count, const char* filename) { char *buf, *dst, *end; size_t flen = strlen(filename); @@ -111,6 +111,10 @@ static char* subst(const char *src, unsigned int count, const char* filename) } #endif +/* Return values of ACTFs ('action functions') are a bit mask: + * bit 1=1: prune (use SKIP constant for setting it) + * bit 0=1: matched successfully (TRUE) + */ static int exec_actions(action ***appp, const char *fileName, struct stat *statbuf) { @@ -121,24 +125,24 @@ static int exec_actions(action ***appp, const char *fileName, struct stat *statb cur_group = -1; while ((app = appp[++cur_group])) { + /* We invert TRUE bit (bit 0). Now 1 there means 'failure'. + * and bitwise OR in "rc |= TRUE ^ ap->f()" will: + * (1) make SKIP bit stick; and (2) detect 'failure' */ + rc = 0; /* 'success' so far */ cur_action = -1; while (1) { ap = app[++cur_action]; - if (!ap) { - /* all actions in group were successful */ - return rc; - } - rc = ap->f(fileName, statbuf, ap); + if (!ap) /* all actions in group were successful */ + return rc ^ TRUE; + rc |= TRUE ^ ap->f(fileName, statbuf, ap); #if ENABLE_FEATURE_FIND_NOT - if (ap->invert) rc = !rc; + if (ap->invert) rc ^= TRUE; #endif - if (!rc) { - /* current group failed, try next */ + if (rc & TRUE) /* current group failed, try next */ break; - } } } - return rc; + return rc ^ TRUE; /* straighten things out */ } @@ -147,8 +151,16 @@ ACTF(name) const char *tmp = strrchr(fileName, '/'); if (tmp == NULL) tmp = fileName; - else + else { tmp++; + if (!*tmp) { /* "foo/bar/". Oh no... go back to 'b' */ + tmp--; + while (tmp != fileName && *--tmp != '/') + continue; + if (*tmp == '/') + tmp++; + } + } return fnmatch(ap->pattern, tmp, FNM_PERIOD) == 0; } #if ENABLE_FEATURE_FIND_TYPE @@ -269,7 +281,7 @@ ACTF(paren) */ ACTF(prune) { - return SKIP; + return SKIP + TRUE; } #endif @@ -284,7 +296,7 @@ ACTF(size) static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) { int i; -#ifdef CONFIG_FEATURE_FIND_XDEV +#if ENABLE_FEATURE_FIND_XDEV if (S_ISDIR(statbuf->st_mode) && xdev_count) { for (i = 0; i < xdev_count; i++) { if (xdev_dev[i] != statbuf->st_dev) @@ -294,11 +306,11 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* junk, in #endif i = exec_actions(actions, fileName, statbuf); /* Had no explicit -print[0] or -exec? then print */ - if (i && need_print) + if ((i & TRUE) && need_print) puts(fileName); /* Cannot return 0: our caller, recursive_action(), * will perror() and skip dirs (if called on dir) */ - return i == 0 ? TRUE : i; + return (i & SKIP) ? SKIP : TRUE; } @@ -386,8 +398,8 @@ static action*** parse_params(char **argv) USE_FEATURE_FIND_GROUP( "-group" ,) USE_FEATURE_FIND_DEPTH( "-depth" ,) USE_FEATURE_FIND_PAREN( "(" ,) - USE_FEATURE_FIND_SIZE( "-size" ,) - USE_FEATURE_FIND_PRUNE( "-prune" ,) + USE_FEATURE_FIND_SIZE( "-size" ,) + USE_FEATURE_FIND_PRUNE( "-prune" ,) #if ENABLE_DESKTOP "-and" , "-or" , @@ -486,8 +498,7 @@ static action*** parse_params(char **argv) } #endif #if ENABLE_FEATURE_FIND_PERM -/* TODO: - * -perm mode File's permission bits are exactly mode (octal or symbolic). +/* -perm mode File's permission bits are exactly mode (octal or symbolic). * Symbolic modes use mode 0 as a point of departure. * -perm -mode All of the permission bits mode are set for the file. * -perm +mode Any of the permission bits mode are set for the file. @@ -554,7 +565,7 @@ static action*** parse_params(char **argv) ap->exec_argv = ++argv; /* first arg after -exec */ ap->exec_argc = 0; while (1) { - if (!*argv) /* did not see ';' util end */ + if (!*argv) /* did not see ';' until end */ bb_error_msg_and_die(bb_msg_requires_arg, arg); if (LONE_CHAR(argv[0], ';')) break; @@ -593,7 +604,7 @@ static action*** parse_params(char **argv) #endif #if ENABLE_FEATURE_FIND_DEPTH else if (parm == PARM_depth) { - recurse_flags |= action_depthFirst; + recurse_flags |= ACTION_DEPTHFIRST; } #endif #if ENABLE_FEATURE_FIND_PAREN @@ -652,7 +663,6 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) NULL }; - bool dereference = FALSE; char *arg; char **argp; int i, firstopt, status = EXIT_SUCCESS; @@ -684,7 +694,7 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) while ((arg = argp[0])) { i = index_in_str_array(options, arg); if (i == 0) { /* -follow */ - dereference = TRUE; + recurse_flags |= ACTION_FOLLOWLINKS; argp[0] = (char*)"-a"; } #if ENABLE_FEATURE_FIND_XDEV @@ -711,7 +721,7 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) for (i = 1; i < firstopt; i++) { if (!recursive_action(argv[i], - recurse_flags|(1<<dereference), /* flags */ + recurse_flags, /* flags */ fileAction, /* file action */ fileAction, /* dir action */ NULL, /* user data */ diff --git a/findutils/grep.c b/findutils/grep.c index 370b753d7..2ca4a3a0a 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= */ action_recurse | - /* followLinks= */ /* no. 0 | */ - /* depthFirst= */ action_depthFirst, + /* recurse=yes */ ACTION_RECURSE | + /* followLinks=no */ + /* depthFirst=yes */ ACTION_DEPTHFIRST, /* fileAction= */ file_action_grep, /* dirAction= */ NULL, /* userData= */ &matched, diff --git a/include/libbb.h b/include/libbb.h index 764d707b8..6956aaf7b 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -178,7 +178,7 @@ struct hwtype { /* buffer allocation schemes */ #if ENABLE_FEATURE_BUFFERS_GO_ON_STACK -#define RESERVE_CONFIG_BUFFER(buffer,len) char buffer[len] +#define RESERVE_CONFIG_BUFFER(buffer,len) char buffer[len] #define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char buffer[len] #define RELEASE_CONFIG_BUFFER(buffer) ((void)0) #else @@ -187,9 +187,9 @@ struct hwtype { #define RESERVE_CONFIG_UBUFFER(buffer,len) static unsigned char buffer[len] #define RELEASE_CONFIG_BUFFER(buffer) ((void)0) #else -#define RESERVE_CONFIG_BUFFER(buffer,len) char *buffer=xmalloc(len) -#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char *buffer=xmalloc(len) -#define RELEASE_CONFIG_BUFFER(buffer) free (buffer) +#define RESERVE_CONFIG_BUFFER(buffer,len) char *buffer = xmalloc(len) +#define RESERVE_CONFIG_UBUFFER(buffer,len) unsigned char *buffer = xmalloc(len) +#define RELEASE_CONFIG_BUFFER(buffer) free(buffer) #endif #endif @@ -219,7 +219,7 @@ struct sysinfo { unsigned int mem_unit; /* Memory unit size in bytes */ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */ }; -extern int sysinfo(struct sysinfo* info); +int sysinfo(struct sysinfo* info); extern void chomp(char *s); @@ -232,10 +232,12 @@ 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); -#define action_recurse (1<<0) -#define action_followLinks (1<<1) -#define action_depthFirst (1<<2) -#define action_reverse (1<<3) +enum { + ACTION_RECURSE = (1 << 0), + ACTION_FOLLOWLINKS = (1 << 1), + ACTION_DEPTHFIRST = (1 << 2), + /*ACTION_REVERSE = (1 << 3), - unused */ +}; 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), @@ -260,13 +262,12 @@ int ndelay_off(int fd); void xmove_fd(int, int); -extern DIR *xopendir(const char *path); -extern DIR *warn_opendir(const char *path); +DIR *xopendir(const char *path); +DIR *warn_opendir(const char *path); char *xrealloc_getcwd_or_warn(char *cwd); char *xmalloc_readlink_or_warn(const char *path); char *xmalloc_realpath(const char *path); -extern void xstat(const char *filename, struct stat *buf); /* Unlike waitpid, waits ONLY for one process, * It's safe to pass negative 'pids' from failed [v]fork - @@ -299,6 +300,7 @@ void xsetuid(uid_t uid); void xchdir(const char *path); void xsetenv(const char *key, const char *value); void xunlink(const char *pathname); +void xstat(const char *pathname, struct stat *buf); int xopen(const char *pathname, int flags); int xopen3(const char *pathname, int flags, int mode); off_t xlseek(int fd, off_t offset, int whence); diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index 0c0531575..be2a700f5 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c @@ -55,12 +55,12 @@ int recursive_action(const char *fileName, if (!fileAction) fileAction = true_action; if (!dirAction) dirAction = true_action; - status = (flags & action_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, flags & action_followLinks, TRUE); + status, flags & ACTION_FOLLOWLINKS, TRUE); #endif goto done_nak_warn; } @@ -68,7 +68,7 @@ int recursive_action(const char *fileName, /* 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 ( /* (!(flags & action_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); @@ -76,11 +76,11 @@ int recursive_action(const char *fileName, /* It's a directory (or a link to one, and followLinks is set) */ - if (!(flags & action_recurse)) { + if (!(flags & ACTION_RECURSE)) { return dirAction(fileName, &statbuf, userData, depth); } - if (!(flags & action_depthFirst)) { + if (!(flags & ACTION_DEPTHFIRST)) { status = dirAction(fileName, &statbuf, userData, depth); if (!status) { goto done_nak_warn; @@ -104,14 +104,14 @@ int recursive_action(const char *fileName, if (nextFile == NULL) continue; /* now descend into it, forcing recursion. */ - if (!recursive_action(nextFile, flags | action_recurse, + if (!recursive_action(nextFile, flags | ACTION_RECURSE, fileAction, dirAction, userData, depth+1)) { status = FALSE; } free(nextFile); } closedir(dir); - if (flags & action_depthFirst && + if ((flags & ACTION_DEPTHFIRST) && !dirAction(fileName, &statbuf, userData, depth)) { goto done_nak_warn; } diff --git a/modutils/insmod.c b/modutils/insmod.c index 075969dcb..d4575e03b 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, action_recurse, + 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, action_recurse, + if (!recursive_action(module_dir, ACTION_RECURSE, check_module_name_match, 0, m_fullName, 0) ) { if (m_filename == 0 |