Index: find/Makefile.am =================================================================== RCS file: /sources/findutils/findutils/find/Makefile.am,v retrieving revision 1.11 diff -u -r1.11 Makefile.am --- find/Makefile.am 7 Mar 2007 23:18:38 -0000 1.11 +++ find/Makefile.am 31 Mar 2007 12:11:33 -0000 @@ -26,7 +26,7 @@ EXTRA_DIST = defs.h $(man_MANS) INCLUDES = -I../gnulib/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCALEDIR=\"$(localedir)\" -LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ +LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ -lattr man_MANS = find.1 SUBDIRS = testsuite Index: find/defs.h =================================================================== RCS file: /sources/findutils/findutils/find/defs.h,v retrieving revision 1.65 diff -u -r1.65 defs.h --- find/defs.h 28 Mar 2007 10:23:23 -0000 1.65 +++ find/defs.h 31 Mar 2007 12:11:37 -0000 @@ -222,6 +222,12 @@ uintmax_t size; }; +struct nv_pair +{ + char* name; + char* value; +}; + enum xval { @@ -346,6 +352,7 @@ union { char *str; /* fstype [i]lname [i]name [i]path */ + struct nv_pair nv; /* name/value pair */ struct re_pattern_buffer *regex; /* regex */ struct exec_val exec_vec; /* exec ok */ struct long_val numinfo; /* gid inum links uid */ @@ -519,6 +526,7 @@ boolean pred_used PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)); boolean pred_user PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)); boolean pred_writable PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)); +boolean pred_xattr PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)); boolean pred_xtype PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)); Index: find/parser.c =================================================================== RCS file: /sources/findutils/findutils/find/parser.c,v retrieving revision 1.106 diff -u -r1.106 parser.c --- find/parser.c 28 Mar 2007 10:23:23 -0000 1.106 +++ find/parser.c 31 Mar 2007 12:12:00 -0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include "modechange.h" #include "modetype.h" #include "xstrtol.h" @@ -153,6 +154,7 @@ static boolean parse_ignore_race PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); static boolean parse_noignore_race PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); static boolean parse_warn PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); +static boolean parse_xattr PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); static boolean parse_xtype PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); static boolean parse_quit PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); @@ -293,6 +295,7 @@ PARSE_TEST_NP ("wholename", wholename), /* GNU, replaces -path */ {ARG_TEST, "writable", parse_accesscheck, pred_writable}, /* GNU, 4.3.0+ */ PARSE_OPTION ("xdev", xdev), + PARSE_TEST ("xattr", xattr), /* GNU */ PARSE_TEST ("xtype", xtype), /* GNU */ #ifdef UNIMPLEMENTED_UNIX /* It's pretty ugly for find to know about archive formats. @@ -350,7 +353,7 @@ *ret = get_stat_atime(p); return 1; case 'B': - *ret = get_stat_birthtime(p); + //*ret = get_stat_birthtime(p); return (ret->tv_nsec >= 0); case 'c': *ret = get_stat_ctime(p); @@ -2156,6 +2159,49 @@ } static boolean +parse_xattr (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + struct predicate *our_pred; + char *name, *value; + + if ((argv == NULL) || (argv[*arg_ptr] == NULL)) + return false; + if (!check_name_arg("-xattr", argv[*arg_ptr])) + return false; + + /*fnmatch_sanitycheck(); TODO -- when globbing */ + + /* XXX strsep is 4.4BSD */ + name = strsep(&(argv[*arg_ptr]), "="); + + value = argv[*arg_ptr]; + + if (name == NULL || *name == '\0') + { + error (0, 0, "missing attribute name (format: ATTR=VALUE)"); + state.exit_status = 1; + return (false); + } + + if (value == NULL) + { + error (0, 0, "missing attribute value (format: ATTR=VALUE)"); + state.exit_status = 1; + return (false); + } + + our_pred = insert_primary (entry); + + our_pred->args.nv.name = name; + our_pred->args.nv.value = value; + our_pred->need_stat = our_pred->need_type = false; + /*our_pred->est_success_rate = TODO */ + (*arg_ptr)++; + + return true; +} + +static boolean parse_xtype (const struct parser_table* entry, char **argv, int *arg_ptr) { (void) argv; Index: find/pred.c =================================================================== RCS file: /sources/findutils/findutils/find/pred.c,v retrieving revision 1.82 diff -u -r1.82 pred.c --- find/pred.c 28 Mar 2007 10:23:23 -0000 1.82 +++ find/pred.c 31 Mar 2007 12:12:22 -0000 @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "xalloc.h" #include "dirname.h" #include "human.h" @@ -223,6 +225,7 @@ {pred_used, "used "}, {pred_user, "user "}, {pred_writable, "writable "}, + {pred_xattr, "xattr "}, {pred_xtype, "xtype "}, {0, "none "} }; @@ -1610,6 +1613,34 @@ } boolean +pred_xattr (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) +{ + char* attrvalue = xmalloc(ATTR_MAX_VALUELEN+1); + int attrlen = ATTR_MAX_VALUELEN; + + (void) stat_buf; + + /* TODO: support root namespace, perhaps by an optional namespace specifier */ + /* TODO: support globbing */ + if (attr_get (pathname, pred_ptr->args.nv.name, attrvalue, &attrlen, 0) + == -1) + { + if (errno != ENOATTR) + error (0, errno, "failed to get attribute for %s", pathname); + return (false); + } + + if (strcmp (attrvalue, pred_ptr->args.nv.value) == 0) + { + free (attrvalue); + return (true); + } + + free (attrvalue); + return (false); +} + +boolean pred_xtype (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 */ Index: find/tree.c =================================================================== RCS file: /sources/findutils/findutils/find/tree.c,v retrieving revision 1.29 diff -u -r1.29 tree.c --- find/tree.c 7 Mar 2007 23:18:38 -0000 1.29 +++ find/tree.c 31 Mar 2007 12:12:29 -0000 @@ -1042,6 +1042,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;