aboutsummaryrefslogtreecommitdiff
path: root/findutils/find.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-08 10:52:28 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-08 10:52:28 +0000
commitbbd695d8010ab453a5a89ba6d7ebfe1a96b87b7d (patch)
tree98df39594da2e7f1fbe560aec04eeb09426947f0 /findutils/find.c
parentca3484103e6b99d0c433988f2f809840d780d88b (diff)
downloadbusybox-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.c68
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;))
70USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;)) 70USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;))
71USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;)) 71USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;))
72USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;)) 72USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;))
73USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned int *subst_count; int exec_argc;)) 73USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;))
74USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;)) 74USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;))
75USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) 75USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;))
76USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) 76USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;))
@@ -79,12 +79,12 @@ USE_FEATURE_FIND_PRUNE( ACTS(prune))
79 79
80static action ***actions; 80static action ***actions;
81static bool need_print = 1; 81static bool need_print = 1;
82static int recurse_flags = action_recurse; 82static int recurse_flags = ACTION_RECURSE;
83 83
84#if ENABLE_FEATURE_FIND_EXEC 84#if ENABLE_FEATURE_FIND_EXEC
85static unsigned int count_subst(const char *str) 85static 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
96static char* subst(const char *src, unsigned int count, const char* filename) 96static 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
115static int exec_actions(action ***appp, const char *fileName, struct stat *statbuf) 119static 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 */
270ACTF(prune) 282ACTF(prune)
271{ 283{
272 return SKIP; 284 return SKIP + TRUE;
273} 285}
274#endif 286#endif
275 287
@@ -284,7 +296,7 @@ ACTF(size)
284static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) 296static 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 */