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;
pgpI8vnLcnSYS.pgp
Description: PGP signature
_______________________________________________ Bug-findutils mailing list [email protected] http://lists.gnu.org/mailman/listinfo/bug-findutils
