diff options
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 | } |
