Hello James,

  the attached patch includes the guts for extended attributes support
in find.

  Not yet included:

    * wildcard matching attributes with fnmatch()
    * success rate estimation
    * checks in configure.ac for attr headers and libraries
    * documentation changes

  Open questions:

    * tests -- will only work when the file system supports extended
      attributes

Let me know what you think of it :)

  Leslie

-- 
NEW homepage: https://viridian.dnsalias.net/~sky/homepage/
gpg --keyserver pgp.mit.edu --recv-keys DD4EBF83
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 <pwd.h>
 #include <grp.h>
 #include <fnmatch.h>
+#include <attr/attributes.h>
 #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 <assert.h>
 #include <fcntl.h>
 #include <locale.h>
+#include <attr/attributes.h>
+#include <attr/xattr.h>
 #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;

Attachment: pgpI8vnLcnSYS.pgp
Description: PGP signature

_______________________________________________
Bug-findutils mailing list
Bug-findutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-findutils

Reply via email to