Hi list,
I was recently reading up on 'capabilies' and noticed that find has no support
for locating files based on extended attributes or capabilities, I thought this
was a valid use case but maybe that's just me?
I wrote a couple of standalone utilities to get some functional code and then
tried to follow the instructions in README-hacking but failed during 'sh
import-gnulib.sh' with the following error:
autopoint: *** Missing version: please specify in configure.ac through a line
'AM_GNU_GETTEXT_VERSION(x.yy.zz)' the gettext version the package is using
autopoint: *** Stop.
FAILED
I wasn't able to resolve this so played with the findutils-4.5.11 tarball
instead, the xattr code seems to work but I'm not confident that I understand
the architecture or that I'm doing things the Right Way. I'm a sys admin and
usually use python so any pointers (no pun intended) on my c coding would be
appreciated. The xattr patch is attached here for your review, below is example
output from a standalone utility and the patched version of find:
[killboy@host find]$ cd ~/Documents/progs/c
[killboy@host c]$ ./list_xattr filecap '.*'
security.capability
security.selinux
[killboy@host c]$ ./get_cap_regex filecap '.*'
= cap_setgid,cap_setuid+ep
[killboy@host c]$ ~/Downloads/findutils-4.5.11/find/find . -xattr '.*cap.*'
./filecap
I'd like to fix any issues with the xattr function before working on adding the
capability function so any feedback will be greatly appreciated, even just to
resolve the autopoint issue (I'm on Fedora 20)
thanks
Morgan
diff -ur -x .deps a/find/defs.h b/find/defs.h
--- a/find/defs.h 2013-02-03 00:32:14.000000000 +1100
+++ b/find/defs.h 2014-10-27 15:34:07.319579457 +1100
@@ -457,6 +457,7 @@
PREDICATEFUNCTION pred_used;
PREDICATEFUNCTION pred_user;
PREDICATEFUNCTION pred_writable;
+PREDICATEFUNCTION pred_xattr;
PREDICATEFUNCTION pred_xtype;
PREDICATEFUNCTION pred_context;
diff -ur -x .deps a/find/parser.c b/find/parser.c
--- a/find/parser.c 2012-11-18 00:57:51.000000000 +1100
+++ b/find/parser.c 2014-11-03 23:12:53.891966306 +1100
@@ -149,6 +149,7 @@
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 @@
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.
@@ -2820,6 +2822,32 @@
}
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 -ur -x .deps a/find/pred.c b/find/pred.c
--- a/find/pred.c 2012-11-18 00:57:51.000000000 +1100
+++ b/find/pred.c 2014-11-03 22:34:26.691824507 +1100
@@ -141,6 +141,7 @@
{pred_used, "used "},
{pred_user, "user "},
{pred_writable, "writable "},
+ {pred_xattr, "xattr "},
{pred_xtype, "xtype "},
{pred_context, "context"},
{0, "none "}
@@ -1153,6 +1154,61 @@
}
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 -ur -x .deps a/find/tree.c b/find/tree.c
--- a/find/tree.c 2012-11-18 00:57:51.000000000 +1100
+++ b/find/tree.c 2014-11-03 23:18:10.610186916 +1100
@@ -1001,6 +1001,7 @@
{ 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;
_______________________________________________
Findutils-patches mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/findutils-patches