diff options
Diffstat (limited to 'findutils/find.c')
-rw-r--r-- | findutils/find.c | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/findutils/find.c b/findutils/find.c index 5e8193ffa..ff239dbdd 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -62,9 +62,6 @@ | |||
62 | /* This is a NOEXEC applet. Be very careful! */ | 62 | /* This is a NOEXEC applet. Be very careful! */ |
63 | 63 | ||
64 | 64 | ||
65 | IF_FEATURE_FIND_XDEV(static dev_t *xdev_dev;) | ||
66 | IF_FEATURE_FIND_XDEV(static int xdev_count;) | ||
67 | |||
68 | typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *) FAST_FUNC; | 65 | typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *) FAST_FUNC; |
69 | 66 | ||
70 | typedef struct { | 67 | typedef struct { |
@@ -100,9 +97,24 @@ IF_FEATURE_FIND_DELETE( ACTS(delete)) | |||
100 | IF_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) | 97 | IF_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) |
101 | IF_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) | 98 | IF_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) |
102 | 99 | ||
103 | static action ***actions; | 100 | struct globals { |
104 | static bool need_print = 1; | 101 | IF_FEATURE_FIND_XDEV(dev_t *xdev_dev;) |
105 | static int recurse_flags = ACTION_RECURSE; | 102 | IF_FEATURE_FIND_XDEV(int xdev_count;) |
103 | action ***actions; | ||
104 | bool need_print; | ||
105 | recurse_flags_t recurse_flags; | ||
106 | }; | ||
107 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
108 | #define INIT_G() do { \ | ||
109 | struct G_sizecheck { \ | ||
110 | char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ | ||
111 | }; \ | ||
112 | IF_FEATURE_FIND_XDEV(G.xdev_dev = NULL;) \ | ||
113 | IF_FEATURE_FIND_XDEV(G.xdev_count = 0;) \ | ||
114 | G.actions = NULL; \ | ||
115 | G.need_print = 1; \ | ||
116 | G.recurse_flags = ACTION_RECURSE; \ | ||
117 | } while (0) | ||
106 | 118 | ||
107 | #if ENABLE_FEATURE_FIND_EXEC | 119 | #if ENABLE_FEATURE_FIND_EXEC |
108 | static unsigned count_subst(const char *str) | 120 | static unsigned count_subst(const char *str) |
@@ -363,7 +375,7 @@ ACTF(context) | |||
363 | security_context_t con; | 375 | security_context_t con; |
364 | int rc; | 376 | int rc; |
365 | 377 | ||
366 | if (recurse_flags & ACTION_FOLLOWLINKS) { | 378 | if (G.recurse_flags & ACTION_FOLLOWLINKS) { |
367 | rc = getfilecon(fileName, &con); | 379 | rc = getfilecon(fileName, &con); |
368 | } else { | 380 | } else { |
369 | rc = lgetfilecon(fileName, &con); | 381 | rc = lgetfilecon(fileName, &con); |
@@ -392,18 +404,18 @@ static int FAST_FUNC fileAction(const char *fileName, | |||
392 | #endif | 404 | #endif |
393 | 405 | ||
394 | #if ENABLE_FEATURE_FIND_XDEV | 406 | #if ENABLE_FEATURE_FIND_XDEV |
395 | if (S_ISDIR(statbuf->st_mode) && xdev_count) { | 407 | if (S_ISDIR(statbuf->st_mode) && G.xdev_count) { |
396 | for (i = 0; i < xdev_count; i++) { | 408 | for (i = 0; i < G.xdev_count; i++) { |
397 | if (xdev_dev[i] == statbuf->st_dev) | 409 | if (G.xdev_dev[i] == statbuf->st_dev) |
398 | break; | 410 | break; |
399 | } | 411 | } |
400 | if (i == xdev_count) | 412 | if (i == G.xdev_count) |
401 | return SKIP; | 413 | return SKIP; |
402 | } | 414 | } |
403 | #endif | 415 | #endif |
404 | i = exec_actions(actions, fileName, statbuf); | 416 | i = exec_actions(G.actions, fileName, statbuf); |
405 | /* Had no explicit -print[0] or -exec? then print */ | 417 | /* Had no explicit -print[0] or -exec? then print */ |
406 | if ((i & TRUE) && need_print) | 418 | if ((i & TRUE) && G.need_print) |
407 | puts(fileName); | 419 | puts(fileName); |
408 | /* Cannot return 0: our caller, recursive_action(), | 420 | /* Cannot return 0: our caller, recursive_action(), |
409 | * will perror() and skip dirs (if called on dir) */ | 421 | * will perror() and skip dirs (if called on dir) */ |
@@ -431,7 +443,7 @@ static int find_type(const char *type) | |||
431 | else if (*type == 's') | 443 | else if (*type == 's') |
432 | mask = S_IFSOCK; | 444 | mask = S_IFSOCK; |
433 | 445 | ||
434 | if (mask == 0 || *(type + 1) != '\0') | 446 | if (mask == 0 || type[1] != '\0') |
435 | bb_error_msg_and_die(bb_msg_invalid_arg, type, "-type"); | 447 | bb_error_msg_and_die(bb_msg_invalid_arg, type, "-type"); |
436 | 448 | ||
437 | return mask; | 449 | return mask; |
@@ -592,21 +604,21 @@ static action*** parse_params(char **argv) | |||
592 | 604 | ||
593 | /* --- Tests and actions --- */ | 605 | /* --- Tests and actions --- */ |
594 | else if (parm == PARM_print) { | 606 | else if (parm == PARM_print) { |
595 | need_print = 0; | 607 | G.need_print = 0; |
596 | /* GNU find ignores '!' here: "find ! -print" */ | 608 | /* GNU find ignores '!' here: "find ! -print" */ |
597 | IF_FEATURE_FIND_NOT( invert_flag = 0; ) | 609 | IF_FEATURE_FIND_NOT( invert_flag = 0; ) |
598 | (void) ALLOC_ACTION(print); | 610 | (void) ALLOC_ACTION(print); |
599 | } | 611 | } |
600 | #if ENABLE_FEATURE_FIND_PRINT0 | 612 | #if ENABLE_FEATURE_FIND_PRINT0 |
601 | else if (parm == PARM_print0) { | 613 | else if (parm == PARM_print0) { |
602 | need_print = 0; | 614 | G.need_print = 0; |
603 | IF_FEATURE_FIND_NOT( invert_flag = 0; ) | 615 | IF_FEATURE_FIND_NOT( invert_flag = 0; ) |
604 | (void) ALLOC_ACTION(print0); | 616 | (void) ALLOC_ACTION(print0); |
605 | } | 617 | } |
606 | #endif | 618 | #endif |
607 | #if ENABLE_FEATURE_FIND_DEPTH | 619 | #if ENABLE_FEATURE_FIND_DEPTH |
608 | else if (parm == PARM_depth) { | 620 | else if (parm == PARM_depth) { |
609 | recurse_flags |= ACTION_DEPTHFIRST; | 621 | G.recurse_flags |= ACTION_DEPTHFIRST; |
610 | } | 622 | } |
611 | #endif | 623 | #endif |
612 | #if ENABLE_FEATURE_FIND_PRUNE | 624 | #if ENABLE_FEATURE_FIND_PRUNE |
@@ -617,8 +629,8 @@ static action*** parse_params(char **argv) | |||
617 | #endif | 629 | #endif |
618 | #if ENABLE_FEATURE_FIND_DELETE | 630 | #if ENABLE_FEATURE_FIND_DELETE |
619 | else if (parm == PARM_delete) { | 631 | else if (parm == PARM_delete) { |
620 | need_print = 0; | 632 | G.need_print = 0; |
621 | recurse_flags |= ACTION_DEPTHFIRST; | 633 | G.recurse_flags |= ACTION_DEPTHFIRST; |
622 | (void) ALLOC_ACTION(delete); | 634 | (void) ALLOC_ACTION(delete); |
623 | } | 635 | } |
624 | #endif | 636 | #endif |
@@ -626,7 +638,7 @@ static action*** parse_params(char **argv) | |||
626 | else if (parm == PARM_exec) { | 638 | else if (parm == PARM_exec) { |
627 | int i; | 639 | int i; |
628 | action_exec *ap; | 640 | action_exec *ap; |
629 | need_print = 0; | 641 | G.need_print = 0; |
630 | IF_FEATURE_FIND_NOT( invert_flag = 0; ) | 642 | IF_FEATURE_FIND_NOT( invert_flag = 0; ) |
631 | ap = ALLOC_ACTION(exec); | 643 | ap = ALLOC_ACTION(exec); |
632 | ap->exec_argv = ++argv; /* first arg after -exec */ | 644 | ap->exec_argv = ++argv; /* first arg after -exec */ |
@@ -834,6 +846,8 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) | |||
834 | #define minmaxdepth NULL | 846 | #define minmaxdepth NULL |
835 | #endif | 847 | #endif |
836 | 848 | ||
849 | INIT_G(); | ||
850 | |||
837 | for (firstopt = 1; firstopt < argc; firstopt++) { | 851 | for (firstopt = 1; firstopt < argc; firstopt++) { |
838 | if (argv[firstopt][0] == '-') | 852 | if (argv[firstopt][0] == '-') |
839 | break; | 853 | break; |
@@ -861,21 +875,21 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) | |||
861 | while ((arg = argp[0])) { | 875 | while ((arg = argp[0])) { |
862 | int opt = index_in_strings(options, arg); | 876 | int opt = index_in_strings(options, arg); |
863 | if (opt == OPT_FOLLOW) { | 877 | if (opt == OPT_FOLLOW) { |
864 | recurse_flags |= ACTION_FOLLOWLINKS; | 878 | G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK; |
865 | argp[0] = (char*)"-a"; | 879 | argp[0] = (char*)"-a"; |
866 | } | 880 | } |
867 | #if ENABLE_FEATURE_FIND_XDEV | 881 | #if ENABLE_FEATURE_FIND_XDEV |
868 | if (opt == OPT_XDEV) { | 882 | if (opt == OPT_XDEV) { |
869 | struct stat stbuf; | 883 | struct stat stbuf; |
870 | if (!xdev_count) { | 884 | if (!G.xdev_count) { |
871 | xdev_count = firstopt - 1; | 885 | G.xdev_count = firstopt - 1; |
872 | xdev_dev = xmalloc(xdev_count * sizeof(dev_t)); | 886 | G.xdev_dev = xmalloc(G.xdev_count * sizeof(dev_t)); |
873 | for (i = 1; i < firstopt; i++) { | 887 | for (i = 1; i < firstopt; i++) { |
874 | /* not xstat(): shouldn't bomb out on | 888 | /* not xstat(): shouldn't bomb out on |
875 | * "find not_exist exist -xdev" */ | 889 | * "find not_exist exist -xdev" */ |
876 | if (stat(argv[i], &stbuf)) | 890 | if (stat(argv[i], &stbuf)) |
877 | stbuf.st_dev = -1L; | 891 | stbuf.st_dev = -1L; |
878 | xdev_dev[i-1] = stbuf.st_dev; | 892 | G.xdev_dev[i-1] = stbuf.st_dev; |
879 | } | 893 | } |
880 | } | 894 | } |
881 | argp[0] = (char*)"-a"; | 895 | argp[0] = (char*)"-a"; |
@@ -894,11 +908,11 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) | |||
894 | argp++; | 908 | argp++; |
895 | } | 909 | } |
896 | 910 | ||
897 | actions = parse_params(&argv[firstopt]); | 911 | G.actions = parse_params(&argv[firstopt]); |
898 | 912 | ||
899 | for (i = 1; i < firstopt; i++) { | 913 | for (i = 1; i < firstopt; i++) { |
900 | if (!recursive_action(argv[i], | 914 | if (!recursive_action(argv[i], |
901 | recurse_flags, /* flags */ | 915 | G.recurse_flags,/* flags */ |
902 | fileAction, /* file action */ | 916 | fileAction, /* file action */ |
903 | fileAction, /* dir action */ | 917 | fileAction, /* dir action */ |
904 | #if ENABLE_FEATURE_FIND_MAXDEPTH | 918 | #if ENABLE_FEATURE_FIND_MAXDEPTH |