From c90c87217455f584090ab5c517ae6bf1468a5649 Mon Sep 17 00:00:00 2001 From: Morgan Weetman Date: Sat, 13 Dec 2014 20:14:05 +1100 Subject: [PATCH 3/8] find: -xattr now obeys -regextype * find/pred.c: removed regcomp call * find/parser.c: parse_xattr function altered to obey -regextype added insert_xattr function added parse_ixattr function * find/find.1: updated -xattr entry --- find/find.1 | 4 +++- find/parser.c | 57 ++++++++++++++++++++++++++++++++++++++++----------------- find/pred.c | 13 ++----------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/find/find.1 b/find/find.1 index 8c4c187..096a3ed 100644 --- a/find/find.1 +++ b/find/find.1 @@ -923,7 +923,9 @@ information held on the server. .IP "\-xattr \fIpattern\fR" Match extended attributes against the regular expression \fIpattern\fR. For example to search for files that have -capabilities set you could use '.*capa.*' +capabilities set you could use '.*capab.*'. This option +also takes advantage of +.B \-regextype .IP "\-xtype \fIc\fR" The same as diff --git a/find/parser.c b/find/parser.c index bb43286..16163f5 100644 --- a/find/parser.c +++ b/find/parser.c @@ -110,6 +110,7 @@ static bool parse_iname (const struct parser_table*, char *argv[], int * static bool parse_inum (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_ipath (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_iregex (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_ixattr (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_iwholename (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_links (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_lname (const struct parser_table*, char *argv[], int *arg_ptr); @@ -165,6 +166,9 @@ static bool insert_type (char **argv, int *arg_ptr, static bool insert_regex (char *argv[], int *arg_ptr, const struct parser_table *entry, int regex_options); +static bool insert_xattr (char *argv[], int *arg_ptr, + const struct parser_table *entry, + int regex_options); static bool insert_exec_ok (const char *action, const struct parser_table *entry, char *argv[], @@ -260,6 +264,7 @@ static struct parser_table const parse_table[] = PARSE_TEST ("inum", inum), /* GNU, Unix */ PARSE_TEST ("ipath", ipath), /* GNU, deprecated in favour of iwholename */ PARSE_TEST_NP ("iregex", iregex), /* GNU */ + PARSE_TEST_NP ("ixattr", ixattr), /* GNU */ PARSE_TEST_NP ("iwholename", iwholename), /* GNU */ PARSE_TEST ("links", links), /* POSIX */ PARSE_TEST ("lname", lname), /* GNU */ @@ -1384,6 +1389,12 @@ parse_iregex (const struct parser_table* entry, char **argv, int *arg_ptr) } static bool +parse_ixattr (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + return insert_xattr (argv, arg_ptr, entry, RE_ICASE|options.regex_options); +} + +static bool parse_links (const struct parser_table* entry, char **argv, int *arg_ptr) { struct predicate *p = insert_num (argv, arg_ptr, entry); @@ -2761,29 +2772,41 @@ parse_warn (const struct parser_table* entry, char **argv, int *arg_ptr) static bool parse_xattr (const struct parser_table* entry, char **argv, int *arg_ptr) { - const char *name; - const int saved_argc = *arg_ptr; + return insert_xattr (argv, arg_ptr, entry, options.regex_options); +} - if (collect_arg (argv, arg_ptr, &name)) +static bool +insert_xattr (char **argv, + int *arg_ptr, + const struct parser_table *entry, + int regex_options) +{ + const char *rx; + if (collect_arg (argv, arg_ptr, &rx)) { - fnmatch_sanitycheck (); - if (check_name_arg ("-xattr", name)) - { - struct predicate *our_pred = insert_primary (entry, name); - our_pred->need_stat = our_pred->need_type = false; - our_pred->args.str = name; - our_pred->est_success_rate = estimate_pattern_match_rate (name, 0); - return true; - } - else - { - *arg_ptr = saved_argc; /* don't consume the invalid argument. */ - } + struct re_pattern_buffer *re; + const char *error_message; + struct predicate *our_pred = insert_primary_withpred (entry, pred_xattr, rx); + our_pred->need_stat = our_pred->need_type = false; + re = xmalloc (sizeof (struct re_pattern_buffer)); + our_pred->args.regex = re; + re->allocated = 100; + re->buffer = xmalloc (re->allocated); + re->fastmap = NULL; + + re_set_syntax (regex_options); + re->syntax = regex_options; + re->translate = NULL; + + error_message = re_compile_pattern (rx, strlen (rx), re); + if (error_message) + error (EXIT_FAILURE, 0, "%s", error_message); + our_pred->est_success_rate = estimate_pattern_match_rate (rx, 1); + return true; } return false; } - static bool parse_xtype (const struct parser_table* entry, char **argv, int *arg_ptr) { diff --git a/find/pred.c b/find/pred.c index 048e263..37e9f0e 100644 --- a/find/pred.c +++ b/find/pred.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include /* for unlinkat() */ @@ -1160,14 +1161,12 @@ bool pred_xattr (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) { (void) pathname; - const char *re_string = pred_ptr->args.str; char empty[0]; char *list; char *substrings; ssize_t list_size; int i, j; bool ret = false; - regex_t re_pattern; // get size of xattr list for the given path by passing an empty list list_size = listxattr(pathname, empty, 0); @@ -1182,20 +1181,13 @@ pred_xattr (const char *pathname, struct stat *stat_buf, struct predicate *pred_ // retrieve the list of xattrs listxattr(pathname, list, list_size); - // compile regex pattern - if (regcomp(&re_pattern, re_string, REG_ICASE|REG_NOSUB|REG_NEWLINE) != 0) { - free(list); - free(substrings); - return(ret); - } - // break list into asciiz strings for (i = 0, j = 0; i < list_size; i++) { substrings[j] = list[i]; if (list[i] == 0) { // perform regex match against substring j = 0; - if (regexec(&re_pattern, substrings, (size_t) 0, NULL, 0) == 0) { + if (regexec(pred_ptr->args.regex, substrings, (size_t) 0, NULL, 0) == 0) { ret = true; } continue; @@ -1206,7 +1198,6 @@ pred_xattr (const char *pathname, struct stat *stat_buf, struct predicate *pred_ // clean up free(list); free(substrings); - regfree(&re_pattern); return(ret); } -- 1.9.3