diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-08 10:52:28 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-08 10:52:28 +0000 |
commit | bbd695d8010ab453a5a89ba6d7ebfe1a96b87b7d (patch) | |
tree | 98df39594da2e7f1fbe560aec04eeb09426947f0 /findutils/find.c | |
parent | ca3484103e6b99d0c433988f2f809840d780d88b (diff) | |
download | busybox-w32-bbd695d8010ab453a5a89ba6d7ebfe1a96b87b7d.tar.gz busybox-w32-bbd695d8010ab453a5a89ba6d7ebfe1a96b87b7d.tar.bz2 busybox-w32-bbd695d8010ab453a5a89ba6d7ebfe1a96b87b7d.zip |
find: fix handling of -prune
recursive_actions: uppercase flag constants
Diffstat (limited to 'findutils/find.c')
-rw-r--r-- | findutils/find.c | 68 |
1 files changed, 39 insertions, 29 deletions
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;)) | |||
70 | USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;)) | 70 | USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;)) |
71 | USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;)) | 71 | USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;)) |
72 | USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;)) | 72 | USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;)) |
73 | USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned int *subst_count; int exec_argc;)) | 73 | USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) |
74 | USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;)) | 74 | USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;)) |
75 | USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) | 75 | USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) |
76 | USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) | 76 | USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) |
@@ -79,12 +79,12 @@ USE_FEATURE_FIND_PRUNE( ACTS(prune)) | |||
79 | 79 | ||
80 | static action ***actions; | 80 | static action ***actions; |
81 | static bool need_print = 1; | 81 | static bool need_print = 1; |
82 | static int recurse_flags = action_recurse; | 82 | static int recurse_flags = ACTION_RECURSE; |
83 | 83 | ||
84 | #if ENABLE_FEATURE_FIND_EXEC | 84 | #if ENABLE_FEATURE_FIND_EXEC |
85 | static unsigned int count_subst(const char *str) | 85 | static unsigned count_subst(const char *str) |
86 | { | 86 | { |
87 | unsigned int count = 0; | 87 | unsigned count = 0; |
88 | while ((str = strstr(str, "{}"))) { | 88 | while ((str = strstr(str, "{}"))) { |
89 | count++; | 89 | count++; |
90 | str++; | 90 | str++; |
@@ -93,7 +93,7 @@ static unsigned int count_subst(const char *str) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | 95 | ||
96 | static char* subst(const char *src, unsigned int count, const char* filename) | 96 | static char* subst(const char *src, unsigned count, const char* filename) |
97 | { | 97 | { |
98 | char *buf, *dst, *end; | 98 | char *buf, *dst, *end; |
99 | size_t flen = strlen(filename); | 99 | size_t flen = strlen(filename); |
@@ -111,6 +111,10 @@ static char* subst(const char *src, unsigned int count, const char* filename) | |||
111 | } | 111 | } |
112 | #endif | 112 | #endif |
113 | 113 | ||
114 | /* Return values of ACTFs ('action functions') are a bit mask: | ||
115 | * bit 1=1: prune (use SKIP constant for setting it) | ||
116 | * bit 0=1: matched successfully (TRUE) | ||
117 | */ | ||
114 | 118 | ||
115 | static int exec_actions(action ***appp, const char *fileName, struct stat *statbuf) | 119 | static int exec_actions(action ***appp, const char *fileName, struct stat *statbuf) |
116 | { | 120 | { |
@@ -121,24 +125,24 @@ static int exec_actions(action ***appp, const char *fileName, struct stat *statb | |||
121 | 125 | ||
122 | cur_group = -1; | 126 | cur_group = -1; |
123 | while ((app = appp[++cur_group])) { | 127 | while ((app = appp[++cur_group])) { |
128 | /* We invert TRUE bit (bit 0). Now 1 there means 'failure'. | ||
129 | * and bitwise OR in "rc |= TRUE ^ ap->f()" will: | ||
130 | * (1) make SKIP bit stick; and (2) detect 'failure' */ | ||
131 | rc = 0; /* 'success' so far */ | ||
124 | cur_action = -1; | 132 | cur_action = -1; |
125 | while (1) { | 133 | while (1) { |
126 | ap = app[++cur_action]; | 134 | ap = app[++cur_action]; |
127 | if (!ap) { | 135 | if (!ap) /* all actions in group were successful */ |
128 | /* all actions in group were successful */ | 136 | return rc ^ TRUE; |
129 | return rc; | 137 | rc |= TRUE ^ ap->f(fileName, statbuf, ap); |
130 | } | ||
131 | rc = ap->f(fileName, statbuf, ap); | ||
132 | #if ENABLE_FEATURE_FIND_NOT | 138 | #if ENABLE_FEATURE_FIND_NOT |
133 | if (ap->invert) rc = !rc; | 139 | if (ap->invert) rc ^= TRUE; |
134 | #endif | 140 | #endif |
135 | if (!rc) { | 141 | if (rc & TRUE) /* current group failed, try next */ |
136 | /* current group failed, try next */ | ||
137 | break; | 142 | break; |
138 | } | ||
139 | } | 143 | } |
140 | } | 144 | } |
141 | return rc; | 145 | return rc ^ TRUE; /* straighten things out */ |
142 | } | 146 | } |
143 | 147 | ||
144 | 148 | ||
@@ -147,8 +151,16 @@ ACTF(name) | |||
147 | const char *tmp = strrchr(fileName, '/'); | 151 | const char *tmp = strrchr(fileName, '/'); |
148 | if (tmp == NULL) | 152 | if (tmp == NULL) |
149 | tmp = fileName; | 153 | tmp = fileName; |
150 | else | 154 | else { |
151 | tmp++; | 155 | tmp++; |
156 | if (!*tmp) { /* "foo/bar/". Oh no... go back to 'b' */ | ||
157 | tmp--; | ||
158 | while (tmp != fileName && *--tmp != '/') | ||
159 | continue; | ||
160 | if (*tmp == '/') | ||
161 | tmp++; | ||
162 | } | ||
163 | } | ||
152 | return fnmatch(ap->pattern, tmp, FNM_PERIOD) == 0; | 164 | return fnmatch(ap->pattern, tmp, FNM_PERIOD) == 0; |
153 | } | 165 | } |
154 | #if ENABLE_FEATURE_FIND_TYPE | 166 | #if ENABLE_FEATURE_FIND_TYPE |
@@ -269,7 +281,7 @@ ACTF(paren) | |||
269 | */ | 281 | */ |
270 | ACTF(prune) | 282 | ACTF(prune) |
271 | { | 283 | { |
272 | return SKIP; | 284 | return SKIP + TRUE; |
273 | } | 285 | } |
274 | #endif | 286 | #endif |
275 | 287 | ||
@@ -284,7 +296,7 @@ ACTF(size) | |||
284 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) | 296 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) |
285 | { | 297 | { |
286 | int i; | 298 | int i; |
287 | #ifdef CONFIG_FEATURE_FIND_XDEV | 299 | #if ENABLE_FEATURE_FIND_XDEV |
288 | if (S_ISDIR(statbuf->st_mode) && xdev_count) { | 300 | if (S_ISDIR(statbuf->st_mode) && xdev_count) { |
289 | for (i = 0; i < xdev_count; i++) { | 301 | for (i = 0; i < xdev_count; i++) { |
290 | if (xdev_dev[i] != statbuf->st_dev) | 302 | if (xdev_dev[i] != statbuf->st_dev) |
@@ -294,11 +306,11 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* junk, in | |||
294 | #endif | 306 | #endif |
295 | i = exec_actions(actions, fileName, statbuf); | 307 | i = exec_actions(actions, fileName, statbuf); |
296 | /* Had no explicit -print[0] or -exec? then print */ | 308 | /* Had no explicit -print[0] or -exec? then print */ |
297 | if (i && need_print) | 309 | if ((i & TRUE) && need_print) |
298 | puts(fileName); | 310 | puts(fileName); |
299 | /* Cannot return 0: our caller, recursive_action(), | 311 | /* Cannot return 0: our caller, recursive_action(), |
300 | * will perror() and skip dirs (if called on dir) */ | 312 | * will perror() and skip dirs (if called on dir) */ |
301 | return i == 0 ? TRUE : i; | 313 | return (i & SKIP) ? SKIP : TRUE; |
302 | } | 314 | } |
303 | 315 | ||
304 | 316 | ||
@@ -386,8 +398,8 @@ static action*** parse_params(char **argv) | |||
386 | USE_FEATURE_FIND_GROUP( "-group" ,) | 398 | USE_FEATURE_FIND_GROUP( "-group" ,) |
387 | USE_FEATURE_FIND_DEPTH( "-depth" ,) | 399 | USE_FEATURE_FIND_DEPTH( "-depth" ,) |
388 | USE_FEATURE_FIND_PAREN( "(" ,) | 400 | USE_FEATURE_FIND_PAREN( "(" ,) |
389 | USE_FEATURE_FIND_SIZE( "-size" ,) | 401 | USE_FEATURE_FIND_SIZE( "-size" ,) |
390 | USE_FEATURE_FIND_PRUNE( "-prune" ,) | 402 | USE_FEATURE_FIND_PRUNE( "-prune" ,) |
391 | #if ENABLE_DESKTOP | 403 | #if ENABLE_DESKTOP |
392 | "-and" , | 404 | "-and" , |
393 | "-or" , | 405 | "-or" , |
@@ -486,8 +498,7 @@ static action*** parse_params(char **argv) | |||
486 | } | 498 | } |
487 | #endif | 499 | #endif |
488 | #if ENABLE_FEATURE_FIND_PERM | 500 | #if ENABLE_FEATURE_FIND_PERM |
489 | /* TODO: | 501 | /* -perm mode File's permission bits are exactly mode (octal or symbolic). |
490 | * -perm mode File's permission bits are exactly mode (octal or symbolic). | ||
491 | * Symbolic modes use mode 0 as a point of departure. | 502 | * Symbolic modes use mode 0 as a point of departure. |
492 | * -perm -mode All of the permission bits mode are set for the file. | 503 | * -perm -mode All of the permission bits mode are set for the file. |
493 | * -perm +mode Any of the permission bits mode are set for the file. | 504 | * -perm +mode Any of the permission bits mode are set for the file. |
@@ -554,7 +565,7 @@ static action*** parse_params(char **argv) | |||
554 | ap->exec_argv = ++argv; /* first arg after -exec */ | 565 | ap->exec_argv = ++argv; /* first arg after -exec */ |
555 | ap->exec_argc = 0; | 566 | ap->exec_argc = 0; |
556 | while (1) { | 567 | while (1) { |
557 | if (!*argv) /* did not see ';' util end */ | 568 | if (!*argv) /* did not see ';' until end */ |
558 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | 569 | bb_error_msg_and_die(bb_msg_requires_arg, arg); |
559 | if (LONE_CHAR(argv[0], ';')) | 570 | if (LONE_CHAR(argv[0], ';')) |
560 | break; | 571 | break; |
@@ -593,7 +604,7 @@ static action*** parse_params(char **argv) | |||
593 | #endif | 604 | #endif |
594 | #if ENABLE_FEATURE_FIND_DEPTH | 605 | #if ENABLE_FEATURE_FIND_DEPTH |
595 | else if (parm == PARM_depth) { | 606 | else if (parm == PARM_depth) { |
596 | recurse_flags |= action_depthFirst; | 607 | recurse_flags |= ACTION_DEPTHFIRST; |
597 | } | 608 | } |
598 | #endif | 609 | #endif |
599 | #if ENABLE_FEATURE_FIND_PAREN | 610 | #if ENABLE_FEATURE_FIND_PAREN |
@@ -652,7 +663,6 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) | |||
652 | NULL | 663 | NULL |
653 | }; | 664 | }; |
654 | 665 | ||
655 | bool dereference = FALSE; | ||
656 | char *arg; | 666 | char *arg; |
657 | char **argp; | 667 | char **argp; |
658 | int i, firstopt, status = EXIT_SUCCESS; | 668 | int i, firstopt, status = EXIT_SUCCESS; |
@@ -684,7 +694,7 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) | |||
684 | while ((arg = argp[0])) { | 694 | while ((arg = argp[0])) { |
685 | i = index_in_str_array(options, arg); | 695 | i = index_in_str_array(options, arg); |
686 | if (i == 0) { /* -follow */ | 696 | if (i == 0) { /* -follow */ |
687 | dereference = TRUE; | 697 | recurse_flags |= ACTION_FOLLOWLINKS; |
688 | argp[0] = (char*)"-a"; | 698 | argp[0] = (char*)"-a"; |
689 | } | 699 | } |
690 | #if ENABLE_FEATURE_FIND_XDEV | 700 | #if ENABLE_FEATURE_FIND_XDEV |
@@ -711,7 +721,7 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) | |||
711 | 721 | ||
712 | for (i = 1; i < firstopt; i++) { | 722 | for (i = 1; i < firstopt; i++) { |
713 | if (!recursive_action(argv[i], | 723 | if (!recursive_action(argv[i], |
714 | recurse_flags|(1<<dereference), /* flags */ | 724 | recurse_flags, /* flags */ |
715 | fileAction, /* file action */ | 725 | fileAction, /* file action */ |
716 | fileAction, /* dir action */ | 726 | fileAction, /* dir action */ |
717 | NULL, /* user data */ | 727 | NULL, /* user data */ |