diff options
author | Ron Yorston <rmy@pobox.com> | 2016-11-29 11:26:45 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-11-29 11:26:45 +0000 |
commit | bb8d79eadbba1942dbdb9f9cee5c47833afe269f (patch) | |
tree | b8c517e9ca895d60d7227aef7177b6291df5e2cd /findutils | |
parent | 9fa1e4990e655a85025c9d270a1606983e375e47 (diff) | |
parent | 7d877fc9312a742b06125927bb1d34bd35398c6c (diff) | |
download | busybox-w32-bb8d79eadbba1942dbdb9f9cee5c47833afe269f.tar.gz busybox-w32-bb8d79eadbba1942dbdb9f9cee5c47833afe269f.tar.bz2 busybox-w32-bb8d79eadbba1942dbdb9f9cee5c47833afe269f.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'findutils')
-rw-r--r-- | findutils/find.c | 46 | ||||
-rw-r--r-- | findutils/grep.c | 52 |
2 files changed, 59 insertions, 39 deletions
diff --git a/findutils/find.c b/findutils/find.c index d71c69782..27698e537 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -502,26 +502,54 @@ static char *strcpy_upcase(char *dst, const char *src) | |||
502 | 502 | ||
503 | ACTF(name) | 503 | ACTF(name) |
504 | { | 504 | { |
505 | int r; | ||
505 | const char *tmp = bb_basename(fileName); | 506 | const char *tmp = bb_basename(fileName); |
506 | if (tmp != fileName && *tmp == '\0') { | 507 | /* GNU findutils: find DIR/ -name DIR |
507 | /* "foo/bar/". Oh no... go back to 'b' */ | 508 | * prints "DIR/" (DIR// prints "DIR//" etc). |
508 | tmp--; | 509 | * Need to strip trailing "/". |
509 | while (tmp != fileName && *--tmp != '/') | 510 | * Such names can come only from top-level names, but |
510 | continue; | 511 | * we can't do this before recursive_action() call, |
511 | if (*tmp == '/') | 512 | * since then "find FILE/ -name FILE" |
512 | tmp++; | 513 | * would also work (on non-directories), which is wrong. |
514 | */ | ||
515 | char *trunc_slash = NULL; | ||
516 | |||
517 | if (*tmp == '\0') { | ||
518 | /* "foo/bar/[//...]" */ | ||
519 | while (tmp != fileName && tmp[-1] == '/') | ||
520 | tmp--; | ||
521 | if (tmp == fileName) { /* entire fileName is "//.."? */ | ||
522 | /* yes, convert "//..." to "/" | ||
523 | * Testcases: | ||
524 | * find / -maxdepth 1 -name /: prints / | ||
525 | * find // -maxdepth 1 -name /: prints // | ||
526 | * find / -maxdepth 1 -name //: prints nothing | ||
527 | * find // -maxdepth 1 -name //: prints nothing | ||
528 | */ | ||
529 | if (tmp[1]) | ||
530 | trunc_slash = (char*)tmp + 1; | ||
531 | } else { | ||
532 | /* no, it's "foo/bar/[//...]", go back to 'b' */ | ||
533 | trunc_slash = (char*)tmp; | ||
534 | while (tmp != fileName && tmp[-1] != '/') | ||
535 | tmp--; | ||
536 | } | ||
513 | } | 537 | } |
538 | |||
514 | /* Was using FNM_PERIOD flag too, | 539 | /* Was using FNM_PERIOD flag too, |
515 | * but somewhere between 4.1.20 and 4.4.0 GNU find stopped using it. | 540 | * but somewhere between 4.1.20 and 4.4.0 GNU find stopped using it. |
516 | * find -name '*foo' should match .foo too: | 541 | * find -name '*foo' should match .foo too: |
517 | */ | 542 | */ |
543 | if (trunc_slash) *trunc_slash = '\0'; | ||
518 | #if FNM_CASEFOLD | 544 | #if FNM_CASEFOLD |
519 | return fnmatch(ap->pattern, tmp, (ap->iname ? FNM_CASEFOLD : 0)) == 0; | 545 | r = fnmatch(ap->pattern, tmp, (ap->iname ? FNM_CASEFOLD : 0)); |
520 | #else | 546 | #else |
521 | if (ap->iname) | 547 | if (ap->iname) |
522 | tmp = strcpy_upcase(alloca(strlen(tmp) + 1), tmp); | 548 | tmp = strcpy_upcase(alloca(strlen(tmp) + 1), tmp); |
523 | return fnmatch(ap->pattern, tmp, 0) == 0; | 549 | r = fnmatch(ap->pattern, tmp, 0); |
524 | #endif | 550 | #endif |
551 | if (trunc_slash) *trunc_slash = '/'; | ||
552 | return r == 0; | ||
525 | } | 553 | } |
526 | 554 | ||
527 | #if ENABLE_FEATURE_FIND_PATH | 555 | #if ENABLE_FEATURE_FIND_PATH |
diff --git a/findutils/grep.c b/findutils/grep.c index 94bcb6002..9f84d529b 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -18,45 +18,41 @@ | |||
18 | * (C) 2006 Jac Goudsmit added -o option | 18 | * (C) 2006 Jac Goudsmit added -o option |
19 | */ | 19 | */ |
20 | 20 | ||
21 | //applet:IF_GREP(APPLET(grep, BB_DIR_BIN, BB_SUID_DROP)) | ||
22 | //applet:IF_FEATURE_GREP_EGREP_ALIAS(APPLET_ODDNAME(egrep, grep, BB_DIR_BIN, BB_SUID_DROP, egrep)) | ||
23 | //applet:IF_FEATURE_GREP_FGREP_ALIAS(APPLET_ODDNAME(fgrep, grep, BB_DIR_BIN, BB_SUID_DROP, fgrep)) | ||
24 | |||
25 | //kbuild:lib-$(CONFIG_GREP) += grep.o | ||
26 | |||
27 | //config:config GREP | 21 | //config:config GREP |
28 | //config: bool "grep" | 22 | //config: bool "grep" |
29 | //config: default y | 23 | //config: default y |
30 | //config: help | 24 | //config: help |
31 | //config: grep is used to search files for a specified pattern. | 25 | //config: grep is used to search files for a specified pattern. |
32 | //config: | 26 | //config: |
33 | //config:config FEATURE_GREP_EGREP_ALIAS | 27 | //config:config EGREP |
34 | //config: bool "Enable extended regular expressions (egrep & grep -E)" | 28 | //config: bool "egrep" |
35 | //config: default y | 29 | //config: default y |
36 | //config: depends on GREP | ||
37 | //config: help | 30 | //config: help |
38 | //config: Enabled support for extended regular expressions. Extended | 31 | //config: Alias to "grep -E" |
39 | //config: regular expressions allow for alternation (foo|bar), grouping, | ||
40 | //config: and various repetition operators. | ||
41 | //config: | 32 | //config: |
42 | //config:config FEATURE_GREP_FGREP_ALIAS | 33 | //config:config FGREP |
43 | //config: bool "Alias fgrep to grep -F" | 34 | //config: bool "fgrep" |
44 | //config: default y | 35 | //config: default y |
45 | //config: depends on GREP | ||
46 | //config: help | 36 | //config: help |
47 | //config: fgrep sees the search pattern as a normal string rather than | 37 | //config: Alias to "grep -F" |
48 | //config: regular expressions. | ||
49 | //config: grep -F always works, this just creates the fgrep alias. | ||
50 | //config: | 38 | //config: |
51 | //config:config FEATURE_GREP_CONTEXT | 39 | //config:config FEATURE_GREP_CONTEXT |
52 | //config: bool "Enable before and after context flags (-A, -B and -C)" | 40 | //config: bool "Enable before and after context flags (-A, -B and -C)" |
53 | //config: default y | 41 | //config: default y |
54 | //config: depends on GREP | 42 | //config: depends on GREP || EGREP |
55 | //config: help | 43 | //config: help |
56 | //config: Print the specified number of leading (-B) and/or trailing (-A) | 44 | //config: Print the specified number of leading (-B) and/or trailing (-A) |
57 | //config: context surrounding our matching lines. | 45 | //config: context surrounding our matching lines. |
58 | //config: Print the specified number of context lines (-C). | 46 | //config: Print the specified number of context lines (-C). |
59 | 47 | ||
48 | //applet:IF_GREP(APPLET(grep, BB_DIR_BIN, BB_SUID_DROP)) | ||
49 | //applet:IF_EGREP(APPLET_ODDNAME(egrep, grep, BB_DIR_BIN, BB_SUID_DROP, egrep)) | ||
50 | //applet:IF_FGREP(APPLET_ODDNAME(fgrep, grep, BB_DIR_BIN, BB_SUID_DROP, fgrep)) | ||
51 | |||
52 | //kbuild:lib-$(CONFIG_GREP) += grep.o | ||
53 | //kbuild:lib-$(CONFIG_EGREP) += grep.o | ||
54 | //kbuild:lib-$(CONFIG_FGREP) += grep.o | ||
55 | |||
60 | #include "libbb.h" | 56 | #include "libbb.h" |
61 | #include "common_bufsiz.h" | 57 | #include "common_bufsiz.h" |
62 | #include "xregex.h" | 58 | #include "xregex.h" |
@@ -64,9 +60,7 @@ | |||
64 | 60 | ||
65 | /* options */ | 61 | /* options */ |
66 | //usage:#define grep_trivial_usage | 62 | //usage:#define grep_trivial_usage |
67 | //usage: "[-HhnlLoqvsriw" | 63 | //usage: "[-HhnlLoqvsriwFE" |
68 | //usage: "F" | ||
69 | //usage: IF_FEATURE_GREP_EGREP_ALIAS("E") | ||
70 | //usage: IF_EXTRA_COMPAT("z") | 64 | //usage: IF_EXTRA_COMPAT("z") |
71 | //usage: "] [-m N] " | 65 | //usage: "] [-m N] " |
72 | //usage: IF_FEATURE_GREP_CONTEXT("[-A/B/C N] ") | 66 | //usage: IF_FEATURE_GREP_CONTEXT("[-A/B/C N] ") |
@@ -88,9 +82,7 @@ | |||
88 | //usage: "\n -w Match whole words only" | 82 | //usage: "\n -w Match whole words only" |
89 | //usage: "\n -x Match whole lines only" | 83 | //usage: "\n -x Match whole lines only" |
90 | //usage: "\n -F PATTERN is a literal (not regexp)" | 84 | //usage: "\n -F PATTERN is a literal (not regexp)" |
91 | //usage: IF_FEATURE_GREP_EGREP_ALIAS( | ||
92 | //usage: "\n -E PATTERN is an extended regexp" | 85 | //usage: "\n -E PATTERN is an extended regexp" |
93 | //usage: ) | ||
94 | //usage: IF_EXTRA_COMPAT( | 86 | //usage: IF_EXTRA_COMPAT( |
95 | //usage: "\n -z Input is NUL terminated" | 87 | //usage: "\n -z Input is NUL terminated" |
96 | //usage: ) | 88 | //usage: ) |
@@ -117,7 +109,7 @@ | |||
117 | #define OPTSTR_GREP \ | 109 | #define OPTSTR_GREP \ |
118 | "lnqvscFiHhe:*f:*Lorm:+wx" \ | 110 | "lnqvscFiHhe:*f:*Lorm:+wx" \ |
119 | IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \ | 111 | IF_FEATURE_GREP_CONTEXT("A:+B:+C:+") \ |
120 | IF_FEATURE_GREP_EGREP_ALIAS("E") \ | 112 | "E" \ |
121 | IF_EXTRA_COMPAT("z") \ | 113 | IF_EXTRA_COMPAT("z") \ |
122 | "aI" | 114 | "aI" |
123 | /* ignored: -a "assume all files to be text" */ | 115 | /* ignored: -a "assume all files to be text" */ |
@@ -144,7 +136,7 @@ enum { | |||
144 | IF_FEATURE_GREP_CONTEXT( OPTBIT_A ,) /* -A NUM: after-match context */ | 136 | IF_FEATURE_GREP_CONTEXT( OPTBIT_A ,) /* -A NUM: after-match context */ |
145 | IF_FEATURE_GREP_CONTEXT( OPTBIT_B ,) /* -B NUM: before-match context */ | 137 | IF_FEATURE_GREP_CONTEXT( OPTBIT_B ,) /* -B NUM: before-match context */ |
146 | IF_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */ | 138 | IF_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */ |
147 | IF_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */ | 139 | OPTBIT_E, /* extended regexp */ |
148 | IF_EXTRA_COMPAT( OPTBIT_z ,) /* input is NUL terminated */ | 140 | IF_EXTRA_COMPAT( OPTBIT_z ,) /* input is NUL terminated */ |
149 | OPT_l = 1 << OPTBIT_l, | 141 | OPT_l = 1 << OPTBIT_l, |
150 | OPT_n = 1 << OPTBIT_n, | 142 | OPT_n = 1 << OPTBIT_n, |
@@ -167,7 +159,7 @@ enum { | |||
167 | OPT_A = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_A)) + 0, | 159 | OPT_A = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_A)) + 0, |
168 | OPT_B = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_B)) + 0, | 160 | OPT_B = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_B)) + 0, |
169 | OPT_C = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0, | 161 | OPT_C = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0, |
170 | OPT_E = IF_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0, | 162 | OPT_E = 1 << OPTBIT_E, |
171 | OPT_z = IF_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0, | 163 | OPT_z = IF_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0, |
172 | }; | 164 | }; |
173 | 165 | ||
@@ -752,7 +744,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |||
752 | } | 744 | } |
753 | } | 745 | } |
754 | 746 | ||
755 | if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') | 747 | if (ENABLE_FGREP && applet_name[0] == 'f') |
756 | option_mask32 |= OPT_F; | 748 | option_mask32 |= OPT_F; |
757 | 749 | ||
758 | #if !ENABLE_EXTRA_COMPAT | 750 | #if !ENABLE_EXTRA_COMPAT |
@@ -760,8 +752,8 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |||
760 | reflags = REG_NOSUB; | 752 | reflags = REG_NOSUB; |
761 | #endif | 753 | #endif |
762 | 754 | ||
763 | if (ENABLE_FEATURE_GREP_EGREP_ALIAS | 755 | if ((ENABLE_EGREP && applet_name[0] == 'e') |
764 | && (applet_name[0] == 'e' || (option_mask32 & OPT_E)) | 756 | || (option_mask32 & OPT_E) |
765 | ) { | 757 | ) { |
766 | reflags |= REG_EXTENDED; | 758 | reflags |= REG_EXTENDED; |
767 | } | 759 | } |