diff options
-rw-r--r-- | findutils/Config.in | 19 | ||||
-rw-r--r-- | findutils/find.c | 148 | ||||
-rw-r--r-- | include/usage.h | 68 |
3 files changed, 151 insertions, 84 deletions
diff --git a/findutils/Config.in b/findutils/Config.in index a32e98922..bcdc02446 100644 --- a/findutils/Config.in +++ b/findutils/Config.in | |||
@@ -57,8 +57,14 @@ config FEATURE_FIND_XDEV | |||
57 | default y | 57 | default y |
58 | depends on FIND | 58 | depends on FIND |
59 | help | 59 | help |
60 | This option will allow find to restrict searches to a single | 60 | This option allows find to restrict searches to a single filesystem. |
61 | filesystem. | 61 | |
62 | config FEATURE_FIND_MAXDEPTH | ||
63 | bool "Enable -maxdepth N option" | ||
64 | default y | ||
65 | depends on FIND | ||
66 | help | ||
67 | This option enables -maxdepth N option. | ||
62 | 68 | ||
63 | config FEATURE_FIND_NEWER | 69 | config FEATURE_FIND_NEWER |
64 | bool "Enable -newer option for comparing file mtimes" | 70 | bool "Enable -newer option for comparing file mtimes" |
@@ -149,7 +155,14 @@ config FEATURE_FIND_PATH | |||
149 | default y | 155 | default y |
150 | depends on FIND | 156 | depends on FIND |
151 | help | 157 | help |
152 | The -path option matches whole pathnames instead of just filenames. | 158 | The -path option matches whole pathname instead of just filename. |
159 | |||
160 | config FEATURE_FIND_REGEX | ||
161 | bool "Enable -regex: match pathname to regex" | ||
162 | default y | ||
163 | depends on FIND | ||
164 | help | ||
165 | The -regex option matches whole pathname against regular expression. | ||
153 | 166 | ||
154 | config GREP | 167 | config GREP |
155 | bool "grep" | 168 | bool "grep" |
diff --git a/findutils/find.c b/findutils/find.c index 2d271d27e..386bc54ad 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -47,6 +47,9 @@ | |||
47 | 47 | ||
48 | #include <fnmatch.h> | 48 | #include <fnmatch.h> |
49 | #include "libbb.h" | 49 | #include "libbb.h" |
50 | #if ENABLE_FEATURE_FIND_REGEX | ||
51 | #include "xregex.h" | ||
52 | #endif | ||
50 | 53 | ||
51 | /* This is a NOEXEC applet. Be very careful! */ | 54 | /* This is a NOEXEC applet. Be very careful! */ |
52 | 55 | ||
@@ -66,6 +69,8 @@ typedef struct { | |||
66 | #define ACTF(name) static int func_##name(const char *fileName, struct stat *statbuf, action_##name* ap) | 69 | #define ACTF(name) static int func_##name(const char *fileName, struct stat *statbuf, action_##name* ap) |
67 | ACTS(print) | 70 | ACTS(print) |
68 | ACTS(name, const char *pattern;) | 71 | ACTS(name, const char *pattern;) |
72 | USE_FEATURE_FIND_PATH( ACTS(path, const char *pattern;)) | ||
73 | USE_FEATURE_FIND_REGEX( ACTS(regex, regex_t compiled_pattern;)) | ||
69 | USE_FEATURE_FIND_PRINT0(ACTS(print0)) | 74 | USE_FEATURE_FIND_PRINT0(ACTS(print0)) |
70 | USE_FEATURE_FIND_TYPE( ACTS(type, int type_mask;)) | 75 | USE_FEATURE_FIND_TYPE( ACTS(type, int type_mask;)) |
71 | USE_FEATURE_FIND_PERM( ACTS(perm, char perm_char; mode_t perm_mask;)) | 76 | USE_FEATURE_FIND_PERM( ACTS(perm, char perm_char; mode_t perm_mask;)) |
@@ -80,7 +85,6 @@ USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) | |||
80 | USE_FEATURE_FIND_SIZE( ACTS(size, off_t size;)) | 85 | USE_FEATURE_FIND_SIZE( ACTS(size, off_t size;)) |
81 | USE_FEATURE_FIND_PRUNE( ACTS(prune)) | 86 | USE_FEATURE_FIND_PRUNE( ACTS(prune)) |
82 | USE_FEATURE_FIND_DELETE(ACTS(delete)) | 87 | USE_FEATURE_FIND_DELETE(ACTS(delete)) |
83 | USE_FEATURE_FIND_PATH( ACTS(path, const char *pattern;)) | ||
84 | 88 | ||
85 | static action ***actions; | 89 | static action ***actions; |
86 | static bool need_print = 1; | 90 | static bool need_print = 1; |
@@ -182,6 +186,25 @@ ACTF(name) | |||
182 | } | 186 | } |
183 | return fnmatch(ap->pattern, tmp, FNM_PERIOD) == 0; | 187 | return fnmatch(ap->pattern, tmp, FNM_PERIOD) == 0; |
184 | } | 188 | } |
189 | #if ENABLE_FEATURE_FIND_PATH | ||
190 | ACTF(path) | ||
191 | { | ||
192 | return fnmatch(ap->pattern, fileName, 0) == 0; | ||
193 | } | ||
194 | #endif | ||
195 | #if ENABLE_FEATURE_FIND_REGEX | ||
196 | ACTF(regex) | ||
197 | { | ||
198 | regmatch_t match; | ||
199 | if (regexec(&ap->compiled_pattern, fileName, 1, &match, 0 /*eflags*/)) | ||
200 | return 0; /* no match */ | ||
201 | if (match.rm_so) | ||
202 | return 0; /* match doesn't start at pos 0 */ | ||
203 | if (fileName[match.rm_eo]) | ||
204 | return 0; /* match doesn't end exactly at end of pathname */ | ||
205 | return 1; | ||
206 | } | ||
207 | #endif | ||
185 | #if ENABLE_FEATURE_FIND_TYPE | 208 | #if ENABLE_FEATURE_FIND_TYPE |
186 | ACTF(type) | 209 | ACTF(type) |
187 | { | 210 | { |
@@ -258,21 +281,18 @@ ACTF(exec) | |||
258 | return rc == 0; /* return 1 if exitcode 0 */ | 281 | return rc == 0; /* return 1 if exitcode 0 */ |
259 | } | 282 | } |
260 | #endif | 283 | #endif |
261 | |||
262 | #if ENABLE_FEATURE_FIND_USER | 284 | #if ENABLE_FEATURE_FIND_USER |
263 | ACTF(user) | 285 | ACTF(user) |
264 | { | 286 | { |
265 | return (statbuf->st_uid == ap->uid); | 287 | return (statbuf->st_uid == ap->uid); |
266 | } | 288 | } |
267 | #endif | 289 | #endif |
268 | |||
269 | #if ENABLE_FEATURE_FIND_GROUP | 290 | #if ENABLE_FEATURE_FIND_GROUP |
270 | ACTF(group) | 291 | ACTF(group) |
271 | { | 292 | { |
272 | return (statbuf->st_gid == ap->gid); | 293 | return (statbuf->st_gid == ap->gid); |
273 | } | 294 | } |
274 | #endif | 295 | #endif |
275 | |||
276 | #if ENABLE_FEATURE_FIND_PRINT0 | 296 | #if ENABLE_FEATURE_FIND_PRINT0 |
277 | ACTF(print0) | 297 | ACTF(print0) |
278 | { | 298 | { |
@@ -280,20 +300,23 @@ ACTF(print0) | |||
280 | return TRUE; | 300 | return TRUE; |
281 | } | 301 | } |
282 | #endif | 302 | #endif |
283 | |||
284 | ACTF(print) | 303 | ACTF(print) |
285 | { | 304 | { |
286 | puts(fileName); | 305 | puts(fileName); |
287 | return TRUE; | 306 | return TRUE; |
288 | } | 307 | } |
289 | |||
290 | #if ENABLE_FEATURE_FIND_PAREN | 308 | #if ENABLE_FEATURE_FIND_PAREN |
291 | ACTF(paren) | 309 | ACTF(paren) |
292 | { | 310 | { |
293 | return exec_actions(ap->subexpr, fileName, statbuf); | 311 | return exec_actions(ap->subexpr, fileName, statbuf); |
294 | } | 312 | } |
295 | #endif | 313 | #endif |
296 | 314 | #if ENABLE_FEATURE_FIND_SIZE | |
315 | ACTF(size) | ||
316 | { | ||
317 | return statbuf->st_size == ap->size; | ||
318 | } | ||
319 | #endif | ||
297 | #if ENABLE_FEATURE_FIND_PRUNE | 320 | #if ENABLE_FEATURE_FIND_PRUNE |
298 | /* | 321 | /* |
299 | * -prune: if -depth is not given, return true and do not descend | 322 | * -prune: if -depth is not given, return true and do not descend |
@@ -306,7 +329,6 @@ ACTF(prune) | |||
306 | return SKIP + TRUE; | 329 | return SKIP + TRUE; |
307 | } | 330 | } |
308 | #endif | 331 | #endif |
309 | |||
310 | #if ENABLE_FEATURE_FIND_DELETE | 332 | #if ENABLE_FEATURE_FIND_DELETE |
311 | ACTF(delete) | 333 | ACTF(delete) |
312 | { | 334 | { |
@@ -322,24 +344,16 @@ ACTF(delete) | |||
322 | } | 344 | } |
323 | #endif | 345 | #endif |
324 | 346 | ||
325 | #if ENABLE_FEATURE_FIND_PATH | ||
326 | ACTF(path) | ||
327 | { | ||
328 | return fnmatch(ap->pattern, fileName, 0) == 0; | ||
329 | } | ||
330 | #endif | ||
331 | 347 | ||
332 | #if ENABLE_FEATURE_FIND_SIZE | 348 | static int fileAction(const char *fileName, struct stat *statbuf, void *userData, int depth) |
333 | ACTF(size) | ||
334 | { | 349 | { |
335 | return statbuf->st_size == ap->size; | 350 | int i; |
336 | } | 351 | #if ENABLE_FEATURE_FIND_MAXDEPTH |
337 | #endif | 352 | int maxdepth = (int)(ptrdiff_t)userData; |
338 | 353 | ||
354 | if (depth > maxdepth) return SKIP; | ||
355 | #endif | ||
339 | 356 | ||
340 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) | ||
341 | { | ||
342 | int i; | ||
343 | #if ENABLE_FEATURE_FIND_XDEV | 357 | #if ENABLE_FEATURE_FIND_XDEV |
344 | if (S_ISDIR(statbuf->st_mode) && xdev_count) { | 358 | if (S_ISDIR(statbuf->st_mode) && xdev_count) { |
345 | for (i = 0; i < xdev_count; i++) { | 359 | for (i = 0; i < xdev_count; i++) { |
@@ -404,6 +418,8 @@ static action*** parse_params(char **argv) | |||
404 | PARM_print , | 418 | PARM_print , |
405 | USE_FEATURE_FIND_PRINT0(PARM_print0 ,) | 419 | USE_FEATURE_FIND_PRINT0(PARM_print0 ,) |
406 | PARM_name , | 420 | PARM_name , |
421 | USE_FEATURE_FIND_PATH( PARM_path ,) | ||
422 | USE_FEATURE_FIND_REGEX( PARM_regex ,) | ||
407 | USE_FEATURE_FIND_TYPE( PARM_type ,) | 423 | USE_FEATURE_FIND_TYPE( PARM_type ,) |
408 | USE_FEATURE_FIND_PERM( PARM_perm ,) | 424 | USE_FEATURE_FIND_PERM( PARM_perm ,) |
409 | USE_FEATURE_FIND_MTIME( PARM_mtime ,) | 425 | USE_FEATURE_FIND_MTIME( PARM_mtime ,) |
@@ -418,7 +434,6 @@ static action*** parse_params(char **argv) | |||
418 | USE_FEATURE_FIND_SIZE( PARM_size ,) | 434 | USE_FEATURE_FIND_SIZE( PARM_size ,) |
419 | USE_FEATURE_FIND_PRUNE( PARM_prune ,) | 435 | USE_FEATURE_FIND_PRUNE( PARM_prune ,) |
420 | USE_FEATURE_FIND_DELETE(PARM_delete ,) | 436 | USE_FEATURE_FIND_DELETE(PARM_delete ,) |
421 | USE_FEATURE_FIND_PATH( PARM_path ,) | ||
422 | #if ENABLE_DESKTOP | 437 | #if ENABLE_DESKTOP |
423 | PARM_and , | 438 | PARM_and , |
424 | PARM_or , | 439 | PARM_or , |
@@ -433,6 +448,8 @@ static action*** parse_params(char **argv) | |||
433 | "-print" , | 448 | "-print" , |
434 | USE_FEATURE_FIND_PRINT0("-print0",) | 449 | USE_FEATURE_FIND_PRINT0("-print0",) |
435 | "-name" , | 450 | "-name" , |
451 | USE_FEATURE_FIND_PATH( "-path" ,) | ||
452 | USE_FEATURE_FIND_REGEX( "-regex" ,) | ||
436 | USE_FEATURE_FIND_TYPE( "-type" ,) | 453 | USE_FEATURE_FIND_TYPE( "-type" ,) |
437 | USE_FEATURE_FIND_PERM( "-perm" ,) | 454 | USE_FEATURE_FIND_PERM( "-perm" ,) |
438 | USE_FEATURE_FIND_MTIME( "-mtime" ,) | 455 | USE_FEATURE_FIND_MTIME( "-mtime" ,) |
@@ -447,7 +464,6 @@ static action*** parse_params(char **argv) | |||
447 | USE_FEATURE_FIND_SIZE( "-size" ,) | 464 | USE_FEATURE_FIND_SIZE( "-size" ,) |
448 | USE_FEATURE_FIND_PRUNE( "-prune" ,) | 465 | USE_FEATURE_FIND_PRUNE( "-prune" ,) |
449 | USE_FEATURE_FIND_DELETE("-delete",) | 466 | USE_FEATURE_FIND_DELETE("-delete",) |
450 | USE_FEATURE_FIND_PATH( "-path" ,) | ||
451 | #if ENABLE_DESKTOP | 467 | #if ENABLE_DESKTOP |
452 | "-and" , | 468 | "-and" , |
453 | "-or" , | 469 | "-or" , |
@@ -536,6 +552,24 @@ static action*** parse_params(char **argv) | |||
536 | ap = ALLOC_ACTION(name); | 552 | ap = ALLOC_ACTION(name); |
537 | ap->pattern = arg1; | 553 | ap->pattern = arg1; |
538 | } | 554 | } |
555 | #if ENABLE_FEATURE_FIND_PATH | ||
556 | else if (parm == PARM_path) { | ||
557 | action_path *ap; | ||
558 | if (!*++argv) | ||
559 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
560 | ap = ALLOC_ACTION(path); | ||
561 | ap->pattern = arg1; | ||
562 | } | ||
563 | #endif | ||
564 | #if ENABLE_FEATURE_FIND_REGEX | ||
565 | else if (parm == PARM_regex) { | ||
566 | action_regex *ap; | ||
567 | if (!*++argv) | ||
568 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
569 | ap = ALLOC_ACTION(regex); | ||
570 | xregcomp(&ap->compiled_pattern, arg1, 0 /*cflags*/); | ||
571 | } | ||
572 | #endif | ||
539 | #if ENABLE_FEATURE_FIND_TYPE | 573 | #if ENABLE_FEATURE_FIND_TYPE |
540 | else if (parm == PARM_type) { | 574 | else if (parm == PARM_type) { |
541 | action_type *ap; | 575 | action_type *ap; |
@@ -678,6 +712,15 @@ static action*** parse_params(char **argv) | |||
678 | argv = endarg; | 712 | argv = endarg; |
679 | } | 713 | } |
680 | #endif | 714 | #endif |
715 | #if ENABLE_FEATURE_FIND_SIZE | ||
716 | else if (parm == PARM_size) { | ||
717 | action_size *ap; | ||
718 | if (!*++argv) | ||
719 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
720 | ap = ALLOC_ACTION(size); | ||
721 | ap->size = XATOOFF(arg1); | ||
722 | } | ||
723 | #endif | ||
681 | #if ENABLE_FEATURE_FIND_PRUNE | 724 | #if ENABLE_FEATURE_FIND_PRUNE |
682 | else if (parm == PARM_prune) { | 725 | else if (parm == PARM_prune) { |
683 | USE_FEATURE_FIND_NOT( invert_flag = 0; ) | 726 | USE_FEATURE_FIND_NOT( invert_flag = 0; ) |
@@ -691,26 +734,10 @@ static action*** parse_params(char **argv) | |||
691 | (void) ALLOC_ACTION(delete); | 734 | (void) ALLOC_ACTION(delete); |
692 | } | 735 | } |
693 | #endif | 736 | #endif |
694 | #if ENABLE_FEATURE_FIND_PATH | 737 | else { |
695 | else if (parm == PARM_path) { | 738 | bb_error_msg("unrecognized: %s", arg); |
696 | action_path *ap; | ||
697 | if (!*++argv) | ||
698 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
699 | ap = ALLOC_ACTION(path); | ||
700 | ap->pattern = arg1; | ||
701 | } | ||
702 | #endif | ||
703 | #if ENABLE_FEATURE_FIND_SIZE | ||
704 | else if (parm == PARM_size) { | ||
705 | action_size *ap; | ||
706 | if (!*++argv) | ||
707 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
708 | ap = ALLOC_ACTION(size); | ||
709 | ap->size = XATOOFF(arg1); | ||
710 | } | ||
711 | #endif | ||
712 | else | ||
713 | bb_show_usage(); | 739 | bb_show_usage(); |
740 | } | ||
714 | argv++; | 741 | argv++; |
715 | } | 742 | } |
716 | return appp; | 743 | return appp; |
@@ -721,15 +748,24 @@ static action*** parse_params(char **argv) | |||
721 | int find_main(int argc, char **argv); | 748 | int find_main(int argc, char **argv); |
722 | int find_main(int argc, char **argv) | 749 | int find_main(int argc, char **argv) |
723 | { | 750 | { |
724 | static const char * const options[] = { | 751 | static const char *const options[] = { |
725 | "-follow", | 752 | "-follow", |
726 | USE_FEATURE_FIND_XDEV( "-xdev", ) | 753 | USE_FEATURE_FIND_XDEV( "-xdev" ,) |
754 | USE_FEATURE_FIND_MAXDEPTH("-maxdepth",) | ||
727 | NULL | 755 | NULL |
728 | }; | 756 | }; |
757 | enum { | ||
758 | OPT_FOLLOW, | ||
759 | USE_FEATURE_FIND_XDEV( OPT_XDEV ,) | ||
760 | USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,) | ||
761 | }; | ||
729 | 762 | ||
730 | char *arg; | 763 | char *arg; |
731 | char **argp; | 764 | char **argp; |
732 | int i, firstopt, status = EXIT_SUCCESS; | 765 | int i, firstopt, status = EXIT_SUCCESS; |
766 | #if ENABLE_FEATURE_FIND_MAXDEPTH | ||
767 | int maxdepth = INT_MAX; | ||
768 | #endif | ||
733 | 769 | ||
734 | for (firstopt = 1; firstopt < argc; firstopt++) { | 770 | for (firstopt = 1; firstopt < argc; firstopt++) { |
735 | if (argv[firstopt][0] == '-') | 771 | if (argv[firstopt][0] == '-') |
@@ -750,19 +786,19 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) | |||
750 | /* All options always return true. They always take effect | 786 | /* All options always return true. They always take effect |
751 | * rather than being processed only when their place in the | 787 | * rather than being processed only when their place in the |
752 | * expression is reached. | 788 | * expression is reached. |
753 | * We implement: -follow, -xdev | 789 | * We implement: -follow, -xdev, -maxdepth |
754 | */ | 790 | */ |
755 | /* Process options, and replace then with -a */ | 791 | /* Process options, and replace then with -a */ |
756 | /* (-a will be ignored by recursive parser later) */ | 792 | /* (-a will be ignored by recursive parser later) */ |
757 | argp = &argv[firstopt]; | 793 | argp = &argv[firstopt]; |
758 | while ((arg = argp[0])) { | 794 | while ((arg = argp[0])) { |
759 | i = index_in_str_array(options, arg); | 795 | int opt = index_in_str_array(options, arg); |
760 | if (i == 0) { /* -follow */ | 796 | if (opt == OPT_FOLLOW) { |
761 | recurse_flags |= ACTION_FOLLOWLINKS; | 797 | recurse_flags |= ACTION_FOLLOWLINKS; |
762 | argp[0] = (char*)"-a"; | 798 | argp[0] = (char*)"-a"; |
763 | } | 799 | } |
764 | #if ENABLE_FEATURE_FIND_XDEV | 800 | #if ENABLE_FEATURE_FIND_XDEV |
765 | else if (i == 1) { /* -xdev */ | 801 | if (opt == OPT_XDEV) { |
766 | struct stat stbuf; | 802 | struct stat stbuf; |
767 | if (!xdev_count) { | 803 | if (!xdev_count) { |
768 | xdev_count = firstopt - 1; | 804 | xdev_count = firstopt - 1; |
@@ -778,6 +814,16 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) | |||
778 | argp[0] = (char*)"-a"; | 814 | argp[0] = (char*)"-a"; |
779 | } | 815 | } |
780 | #endif | 816 | #endif |
817 | #if ENABLE_FEATURE_FIND_MAXDEPTH | ||
818 | if (opt == OPT_MAXDEPTH) { | ||
819 | if (!argp[1]) | ||
820 | bb_show_usage(); | ||
821 | maxdepth = xatoi_u(argp[1]); | ||
822 | argp[0] = (char*)"-a"; | ||
823 | argp[1] = (char*)"-a"; | ||
824 | argp++; | ||
825 | } | ||
826 | #endif | ||
781 | argp++; | 827 | argp++; |
782 | } | 828 | } |
783 | 829 | ||
@@ -788,7 +834,11 @@ USE_FEATURE_FIND_XDEV( "-xdev", ) | |||
788 | recurse_flags, /* flags */ | 834 | recurse_flags, /* flags */ |
789 | fileAction, /* file action */ | 835 | fileAction, /* file action */ |
790 | fileAction, /* dir action */ | 836 | fileAction, /* dir action */ |
837 | #if ENABLE_FEATURE_FIND_MAXDEPTH | ||
838 | (void*)maxdepth,/* user data */ | ||
839 | #else | ||
791 | NULL, /* user data */ | 840 | NULL, /* user data */ |
841 | #endif | ||
792 | 0)) /* depth */ | 842 | 0)) /* depth */ |
793 | status = EXIT_FAILURE; | 843 | status = EXIT_FAILURE; |
794 | } | 844 | } |
diff --git a/include/usage.h b/include/usage.h index 0c02d2501..8c438e285 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -943,46 +943,50 @@ | |||
943 | "the current directory, default EXPRESSION is '-print'\n" \ | 943 | "the current directory, default EXPRESSION is '-print'\n" \ |
944 | "\nEXPRESSION may consist of:" \ | 944 | "\nEXPRESSION may consist of:" \ |
945 | "\n -follow Dereference symlinks" \ | 945 | "\n -follow Dereference symlinks" \ |
946 | USE_FEATURE_FIND_XDEV( \ | ||
947 | "\n -xdev Don't descend directories on other filesystems") \ | ||
948 | USE_FEATURE_FIND_MAXDEPTH( \ | ||
949 | "\n -maxdepth N Descend at most N levels. -maxdepth 0 applies" \ | ||
950 | "\n tests/actions to command line arguments only") \ | ||
946 | "\n -name PATTERN File name (leading directories removed) matches PATTERN" \ | 951 | "\n -name PATTERN File name (leading directories removed) matches PATTERN" \ |
947 | "\n -print Print (default and assumed)" \ | 952 | "\n -print Print (default and assumed)" \ |
948 | USE_FEATURE_FIND_PRINT0( \ | 953 | USE_FEATURE_FIND_PRINT0( \ |
949 | "\n -print0 Delimit output with null characters rather than" \ | 954 | "\n -print0 Delimit output with null characters rather than" \ |
950 | "\n newlines" \ | 955 | "\n newlines") \ |
951 | ) USE_FEATURE_FIND_TYPE( \ | 956 | USE_FEATURE_FIND_TYPE( \ |
952 | "\n -type X Filetype matches X (where X is one of: f,d,l,b,c,...)" \ | 957 | "\n -type X Filetype matches X (where X is one of: f,d,l,b,c,...)") \ |
953 | ) USE_FEATURE_FIND_PERM( \ | 958 | USE_FEATURE_FIND_PERM( \ |
954 | "\n -perm PERMS Permissions match any of (+NNN), all of (-NNN)," \ | 959 | "\n -perm PERMS Permissions match any of (+NNN), all of (-NNN)," \ |
955 | "\n or exactly (NNN)" \ | 960 | "\n or exactly (NNN)") \ |
956 | ) USE_FEATURE_FIND_MTIME( \ | 961 | USE_FEATURE_FIND_MTIME( \ |
957 | "\n -mtime DAYS Modified time is greater than (+N), less than (-N)," \ | 962 | "\n -mtime DAYS Modified time is greater than (+N), less than (-N)," \ |
958 | "\n or exactly (N) days" \ | 963 | "\n or exactly (N) days") \ |
959 | ) USE_FEATURE_FIND_MMIN( \ | 964 | USE_FEATURE_FIND_MMIN( \ |
960 | "\n -mmin MINS Modified time is greater than (+N), less than (-N)," \ | 965 | "\n -mmin MINS Modified time is greater than (+N), less than (-N)," \ |
961 | "\n or exactly (N) minutes" \ | 966 | "\n or exactly (N) minutes") \ |
962 | ) USE_FEATURE_FIND_NEWER( \ | 967 | USE_FEATURE_FIND_NEWER( \ |
963 | "\n -newer FILE Modified time is more recent than FILE's" \ | 968 | "\n -newer FILE Modified time is more recent than FILE's") \ |
964 | ) USE_FEATURE_FIND_INUM( \ | 969 | USE_FEATURE_FIND_INUM( \ |
965 | "\n -inum N File has inode number N" \ | 970 | "\n -inum N File has inode number N") \ |
966 | ) USE_FEATURE_FIND_EXEC( \ | 971 | USE_FEATURE_FIND_EXEC( \ |
967 | "\n -exec CMD Execute CMD with all instances of {} replaced by the" \ | 972 | "\n -exec CMD Execute CMD with all instances of {} replaced by the" \ |
968 | "\n files matching EXPRESSION" \ | 973 | "\n files matching EXPRESSION") \ |
969 | ) USE_FEATURE_FIND_USER( \ | 974 | USE_FEATURE_FIND_USER( \ |
970 | "\n -user NAME File is owned by user NAME (numeric user ID allowed)" \ | 975 | "\n -user NAME File is owned by user NAME (numeric user ID allowed)") \ |
971 | ) USE_FEATURE_FIND_GROUP( \ | 976 | USE_FEATURE_FIND_GROUP( \ |
972 | "\n -group NAME File belongs to group NAME (numeric group ID allowed)" \ | 977 | "\n -group NAME File belongs to group NAME (numeric group ID allowed)") \ |
973 | ) USE_FEATURE_FIND_DEPTH( \ | 978 | USE_FEATURE_FIND_DEPTH( \ |
974 | "\n -depth Process directory after traversing it" \ | 979 | "\n -depth Process directory after traversing it") \ |
975 | ) USE_FEATURE_FIND_SIZE( \ | 980 | USE_FEATURE_FIND_SIZE( \ |
976 | "\n -size N File size is N" \ | 981 | "\n -size N File size is N") \ |
977 | ) USE_FEATURE_FIND_PRUNE( \ | 982 | USE_FEATURE_FIND_PRUNE( \ |
978 | "\n -prune Stop traversing current subtree" \ | 983 | "\n -prune Stop traversing current subtree") \ |
979 | ) USE_FEATURE_FIND_DELETE( \ | 984 | USE_FEATURE_FIND_DELETE( \ |
980 | "\n -delete Delete files, turns on -depth option" \ | 985 | "\n -delete Delete files, turns on -depth option") \ |
981 | ) USE_FEATURE_FIND_PATH( \ | 986 | USE_FEATURE_FIND_PATH( \ |
982 | "\n -path Path matches PATTERN" \ | 987 | "\n -path Path matches PATTERN") \ |
983 | ) USE_FEATURE_FIND_PAREN( \ | 988 | USE_FEATURE_FIND_PAREN( \ |
984 | "\n (EXPR) Group an expression" \ | 989 | "\n (EXPR) Group an expression") \ |
985 | ) | ||
986 | 990 | ||
987 | #define find_example_usage \ | 991 | #define find_example_usage \ |
988 | "$ find / -name passwd\n" \ | 992 | "$ find / -name passwd\n" \ |