Morgan Weetman Consultant Red Hat Consulting http://www.apac.redhat.com/products/consulting/
From b6c74c78f20929fff5c92e5277ea0a6dc0f4bc7f Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Fri, 7 Nov 2014 18:59:45 +1100 Subject: [PATCH 1/8] find: added extended attribute predicate
* find/defs.h (typedef PREDICATEFUNCTION): added pred_xattr * find/parser.c (parse_xattr): added function, added an entry to parse_table[] * find/pred.c (pred_xattr): added function, added an entry to pred_table[] * find/tree.c (costlookup[]): added pred_xattr entry --- find/defs.h | 1 + find/parser.c | 28 ++++++++++++++++++++++++++++ find/pred.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ find/tree.c | 1 + 4 files changed, 86 insertions(+) diff --git a/find/defs.h b/find/defs.h index caccd2b..4ab1bb1 100644 --- a/find/defs.h +++ b/find/defs.h @@ -457,6 +457,7 @@ PREDICATEFUNCTION pred_uid; PREDICATEFUNCTION pred_used; PREDICATEFUNCTION pred_user; PREDICATEFUNCTION pred_writable; +PREDICATEFUNCTION pred_xattr; PREDICATEFUNCTION pred_xtype; PREDICATEFUNCTION pred_context; diff --git a/find/parser.c b/find/parser.c index dc6c47c..bb43286 100644 --- a/find/parser.c +++ b/find/parser.c @@ -149,6 +149,7 @@ static bool parse_xdev (const struct parser_table*, char *argv[], int * static bool parse_ignore_race (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_noignore_race (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_warn (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_xattr (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_xtype (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_quit (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_context (const struct parser_table*, char *argv[], int *arg_ptr); @@ -306,6 +307,7 @@ static struct parser_table const parse_table[] = PARSE_TEST_NP ("wholename", wholename), /* GNU, replaced -path, but anyway -path will soon be in POSIX */ {ARG_TEST, "writable", parse_accesscheck, pred_writable}, /* GNU, 4.3.0+ */ PARSE_OPTION ("xdev", xdev), /* POSIX */ + PARSE_TEST ("xattr", xattr), /* GNU */ PARSE_TEST ("xtype", xtype), /* GNU */ #ifdef UNIMPLEMENTED_UNIX /* It's pretty ugly for find to know about archive formats. @@ -2757,6 +2759,32 @@ 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; + + if (collect_arg (argv, arg_ptr, &name)) + { + 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. */ + } + } + return false; +} + + +static bool parse_xtype (const struct parser_table* entry, char **argv, int *arg_ptr) { return insert_type (argv, arg_ptr, entry, pred_xtype); diff --git a/find/pred.c b/find/pred.c index 3a89679..048e263 100644 --- a/find/pred.c +++ b/find/pred.c @@ -141,6 +141,7 @@ struct pred_assoc pred_table[] = {pred_used, "used "}, {pred_user, "user "}, {pred_writable, "writable "}, + {pred_xattr, "xattr "}, {pred_xtype, "xtype "}, {pred_context, "context"}, {0, "none "} @@ -1156,6 +1157,61 @@ pred_user (const char *pathname, struct stat *stat_buf, struct predicate *pred_p } 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); + + // allocate just enough memory to hold all xattrs + list = malloc(list_size); + + // used to hold individual attributes (substrings) + // allocate same size as list just in case there's only one xattr + substrings = malloc(list_size); + + // 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) { + ret = true; + } + continue; + } + j++; + } + + // clean up + free(list); + free(substrings); + regfree(&re_pattern); + return(ret); + +} + +bool pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) { struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */ diff --git a/find/tree.c b/find/tree.c index 026dead..2dba99d 100644 --- a/find/tree.c +++ b/find/tree.c @@ -1001,6 +1001,7 @@ static struct pred_cost_lookup costlookup[] = { pred_used , NeedsStatInfo }, { pred_user , NeedsStatInfo }, { pred_writable , NeedsAccessInfo }, + { pred_xattr , NeedsNothing }, { pred_xtype , NeedsType } /* roughly correct unless most files are symlinks */ }; static int pred_table_sorted = 0; -- 1.9.3
From 0e3fadc728a35265002379220a4ae5423a0075ca Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Tue, 9 Dec 2014 23:52:24 +1100 Subject: [PATCH 2/8] find: updated man page with xattr information * find/find.1: added extended attribute predicate information --- find/find.1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/find/find.1 b/find/find.1 index f49218e..8c4c187 100644 --- a/find/find.1 +++ b/find/find.1 @@ -920,6 +920,11 @@ mapping (or root-squashing), since many systems implement in the client's kernel and so cannot make use of the UID mapping 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.*' + .IP "\-xtype \fIc\fR" The same as .B \-type -- 1.9.3
From c90c87217455f584090ab5c517ae6bf1468a5649 Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> 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 <stdarg.h> #include <sys/stat.h> #include <sys/types.h> +#include <attr/xattr.h> #include <sys/wait.h> #include <unistd.h> /* 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
From f017b99a77032d7da6ac3de854d9ac7185cb8f0c Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Tue, 6 Jan 2015 13:54:49 +1100 Subject: [PATCH 4/8] find: -xattr now obeys symlink handling options * find/pred.c (pred_xattr): added tests for options.symlink_handling --- find/pred.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/find/pred.c b/find/pred.c index 37e9f0e..ddf9917 100644 --- a/find/pred.c +++ b/find/pred.c @@ -1169,7 +1169,11 @@ pred_xattr (const char *pathname, struct stat *stat_buf, struct predicate *pred_ bool ret = false; // get size of xattr list for the given path by passing an empty list - list_size = listxattr(pathname, empty, 0); + if (options.symlink_handling == SYMLINK_NEVER_DEREF) { + list_size = llistxattr(pathname, empty, 0); + } else { + list_size = listxattr(pathname, empty, 0); + } // allocate just enough memory to hold all xattrs list = malloc(list_size); @@ -1179,7 +1183,11 @@ pred_xattr (const char *pathname, struct stat *stat_buf, struct predicate *pred_ substrings = malloc(list_size); // retrieve the list of xattrs - listxattr(pathname, list, list_size); + if (options.symlink_handling == SYMLINK_NEVER_DEREF) { + llistxattr(pathname, list, list_size); + } else { + listxattr(pathname, list, list_size); + } // break list into asciiz strings for (i = 0, j = 0; i < list_size; i++) { -- 1.9.3
From 6fe70075fe7ebc5d0e457831bc65fd1d8538610d Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Wed, 7 Jan 2015 15:31:55 +1100 Subject: [PATCH 5/8] find: added capability predicate * find/defs.h (typedef PREDICATEFUNCTION): added pred_cap * find/parser.c: added parse_cap function added parse_icap function added insert_cap function added an entry to parse_table * find/pred.c (pred_cap): added function, added an entry to pred_table[] * find/tree.c (costlookup[]): added pred_cap entry * find/find.1: added -cap and -icap entries --- find/defs.h | 1 + find/find.1 | 12 ++++++++++++ find/parser.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ find/pred.c | 29 +++++++++++++++++++++++++++++ find/tree.c | 1 + 5 files changed, 95 insertions(+) diff --git a/find/defs.h b/find/defs.h index 4ab1bb1..cd57544 100644 --- a/find/defs.h +++ b/find/defs.h @@ -405,6 +405,7 @@ PREDICATEFUNCTION pred_and; PREDICATEFUNCTION pred_anewer; PREDICATEFUNCTION pred_atime; PREDICATEFUNCTION pred_closeparen; +PREDICATEFUNCTION pred_cap; PREDICATEFUNCTION pred_cmin; PREDICATEFUNCTION pred_cnewer; PREDICATEFUNCTION pred_comma; diff --git a/find/find.1 b/find/find.1 index 096a3ed..6d03d85 100644 --- a/find/find.1 +++ b/find/find.1 @@ -521,6 +521,13 @@ a file has to have been accessed at least .I two days ago. +.IP "\-cap \fIpattern\fR" +Match file capabilities against the regular expression +\fIpattern\fR. For example to search for files that have +CAP_SETUID you could use '.*setuid.*'. This option +also takes advantage of +.B \-regextype + .IP "\-cmin \fIn\fR" File's status was last changed \fIn\fR minutes ago. @@ -577,6 +584,11 @@ File's numeric group ID is \fIn\fR. .IP "\-group \fIgname\fR" File belongs to group \fIgname\fR (numeric group ID allowed). +.IP "\-icap \fIpattern\fR" +Like +.BR \-cap , +but the match is case insensitive. + .IP "\-ilname \fIpattern\fR" Like .BR \-lname , diff --git a/find/parser.c b/find/parser.c index 16163f5..d5b5731 100644 --- a/find/parser.c +++ b/find/parser.c @@ -85,6 +85,7 @@ static bool parse_accesscheck (const struct parser_table*, char *argv[], int * static bool parse_amin (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_and (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_anewer (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_cap (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_cmin (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_cnewer (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_comma (const struct parser_table*, char *argv[], int *arg_ptr); @@ -105,6 +106,7 @@ static bool parse_fstype (const struct parser_table*, char *argv[], int * static bool parse_gid (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_group (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_help (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_icap (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_ilname (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_iname (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_inum (const struct parser_table*, char *argv[], int *arg_ptr); @@ -169,6 +171,9 @@ static bool insert_regex (char *argv[], int *arg_ptr, static bool insert_xattr (char *argv[], int *arg_ptr, const struct parser_table *entry, int regex_options); +static bool insert_cap (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[], @@ -238,6 +243,7 @@ static struct parser_table const parse_table[] = PARSE_PUNCTUATION("and", and), /* GNU */ PARSE_TEST ("anewer", anewer), /* GNU */ {ARG_TEST, "atime", parse_time, pred_atime}, /* POSIX */ + PARSE_TEST ("cap", cap), /* GNU */ PARSE_TEST ("cmin", cmin), /* GNU */ PARSE_TEST ("cnewer", cnewer), /* GNU */ {ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */ @@ -258,6 +264,7 @@ static struct parser_table const parse_table[] = PARSE_TEST ("fstype", fstype), /* GNU, Unix */ PARSE_TEST ("gid", gid), /* GNU */ PARSE_TEST ("group", group), /* POSIX */ + PARSE_TEST_NP ("icap", icap), /* GNU */ PARSE_OPTION ("ignore_readdir_race", ignore_race), /* GNU */ PARSE_TEST ("ilname", ilname), /* GNU */ PARSE_TEST ("iname", iname), /* GNU */ @@ -797,6 +804,12 @@ parse_anewer (const struct parser_table* entry, char **argv, int *arg_ptr) return false; } +static bool +parse_cap (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + return insert_cap (argv, arg_ptr, entry, options.regex_options); +} + bool parse_closeparen (const struct parser_table* entry, char **argv, int *arg_ptr) { @@ -1277,6 +1290,12 @@ estimate_pattern_match_rate (const char *pattern, int is_regex) } static bool +parse_icap (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + return insert_cap (argv, arg_ptr, entry, RE_ICASE|options.regex_options); +} + +static bool parse_ilname (const struct parser_table* entry, char **argv, int *arg_ptr) { const char *name; @@ -2924,6 +2943,39 @@ insert_type (char **argv, int *arg_ptr, return false; } +static bool +insert_cap (char **argv, + int *arg_ptr, + const struct parser_table *entry, + int regex_options) +{ + const char *rx; + if (collect_arg (argv, arg_ptr, &rx)) + { + struct re_pattern_buffer *re; + const char *error_message; + struct predicate *our_pred = insert_primary_withpred (entry, pred_cap, rx); + our_pred->need_stat = true; + 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; +} + /* Return true if the file accessed via FP is a terminal. */ diff --git a/find/pred.c b/find/pred.c index ddf9917..83c8286 100644 --- a/find/pred.c +++ b/find/pred.c @@ -36,6 +36,7 @@ #include <attr/xattr.h> #include <sys/wait.h> #include <unistd.h> /* for unlinkat() */ +#include <sys/capability.h> /* for pred_cap() */ /* gnulib headers. */ #include "areadlink.h" @@ -90,6 +91,7 @@ struct pred_assoc pred_table[] = {pred_and, "and "}, {pred_anewer, "anewer "}, {pred_atime, "atime "}, + {pred_cap, "cap "}, {pred_closeparen, ") "}, {pred_cmin, "cmin "}, {pred_cnewer, "cnewer "}, @@ -261,6 +263,33 @@ pred_atime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ } bool +pred_cap (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) +{ + (void) pathname; + char *cap_str; + cap_t caps; + bool ret = false; + + // get capabilities + caps = cap_get_file(pathname); + cap_str = cap_to_text(caps, NULL); + if ( cap_str == NULL ) { + cap_free(caps); + return(ret); + } + + // perform regex match + if (regexec(pred_ptr->args.regex, cap_str, (size_t) 0, NULL, 0) == 0) + ret = true; + + // clean up + cap_free(caps); + cap_free(cap_str); + return(ret); + +} + +bool pred_closeparen (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) { (void) &pathname; diff --git a/find/tree.c b/find/tree.c index 2dba99d..d91b080 100644 --- a/find/tree.c +++ b/find/tree.c @@ -947,6 +947,7 @@ static struct pred_cost_lookup costlookup[] = { pred_and , NeedsNothing, }, { pred_anewer , NeedsStatInfo, }, { pred_atime , NeedsStatInfo, }, + { pred_cap , NeedsNothing, }, { pred_closeparen, NeedsNothing }, { pred_cmin , NeedsStatInfo, }, { pred_cnewer , NeedsStatInfo, }, -- 1.9.3
From 8ba406c43244415504c1831e849d3ff3be07bf1e Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Wed, 7 Jan 2015 15:44:37 +1100 Subject: [PATCH 6/8] find: added -ixattr entry to the man page --- find/find.1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/find/find.1 b/find/find.1 index 6d03d85..2e3979c 100644 --- a/find/find.1 +++ b/find/find.1 @@ -628,6 +628,11 @@ but the match is case insensitive. See \-ipath. This alternative is less portable than .BR \-ipath . +.IP "\-ixattr \fIpattern\fR" +Like +.BR \-xattr , +but the match is case insensitive. + .IP "\-links \fIn\fR" File has \fIn\fR links. -- 1.9.3
From 27a798d0eb1cbde2f418252c9e0dcac1e112e47d Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Wed, 7 Jan 2015 15:49:33 +1100 Subject: [PATCH 7/8] find: added xattr and cap to excuses.txt * find/testsuite/excuses.txt: xattr and cap require root privileges to test, may require some planning --- find/testsuite/excuses.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/find/testsuite/excuses.txt b/find/testsuite/excuses.txt index 07dd8dc..0ea2a74 100644 --- a/find/testsuite/excuses.txt +++ b/find/testsuite/excuses.txt @@ -23,18 +23,20 @@ g ## Things that are hard to test because they rely on features of ## the environment +"cap", cap), /* GNU */ "gid", gid), /* GNU */ -"uid", uid), /* GNU */ -"user", user), "group", group), +"ignore_readdir_race", ignore_race), /* GNU */ "mount", xdev), /* Unix */ "nogroup", nogroup), "nouser", nouser), "ok", ok), -"xdev", xdev), -"ignore_readdir_race", ignore_race), /* GNU */ "noignore_readdir_race", noignore_race), /* GNU */ "noleaf", noleaf), /* GNU */ +"uid", uid), /* GNU */ +"user", user), +"xattr", xattr), /* GNU */ +"xdev", xdev), ## Things that might be testable but which I have not yet thought ## about enough. -- 1.9.3
From f7c7fd8233aaaac1b002376821998384958049e6 Mon Sep 17 00:00:00 2001 From: Morgan Weetman <mweet...@redhat.com> Date: Wed, 7 Jan 2015 23:11:59 +1100 Subject: [PATCH 8/8] find: updated find/Makefile.am to include libcap for -cap --- find/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/find/Makefile.am b/find/Makefile.am index 30eba1d..0782d7c 100644 --- a/find/Makefile.am +++ b/find/Makefile.am @@ -4,6 +4,8 @@ localedir = $(datadir)/locale # noinst_PROGRAMS = regexprops # regexprops_SOURCES = regexprops.c +LIBCAP = -lcap + noinst_LIBRARIES = libfindtools.a libfindtools_a_SOURCES = finddata.c fstype.c parser.c pred.c exec.c tree.c util.c sharefile.c print.c @@ -30,7 +32,7 @@ endif # man_MANS is not always the same, we want to distribute all of those files. EXTRA_DIST = defs.h sharefile.h print.h find.1 ftsfind.1 oldfind.1 AM_CPPFLAGS = -I../gl/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gl/lib -I../intl -DLOCALEDIR=\"$(localedir)\" -LDADD = ./libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX) $(LIB_CLOSE) $(MODF_LIBM) $(FINDLIBS) $(GETHOSTNAME_LIB) $(LIB_EACCESS) +LDADD = ./libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBCAP) $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX) $(LIB_CLOSE) $(MODF_LIBM) $(FINDLIBS) $(GETHOSTNAME_LIB) $(LIB_EACCESS) # gnulib advises we link against <first> because we use <second>: # $(GETHOSTNAME_LIB) uname # $(LIB_CLOCK_GETTIME) (some inditrect dependency) -- 1.9.3