bin/106872: [patch] extattr support for usr.bin/find

Ryan Beasley ryanb at FreeBSD.org
Mon Dec 18 07:20:31 PST 2006


>Number:         106872
>Category:       bin
>Synopsis:       [patch] extattr support for usr.bin/find
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 18 15:20:19 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Ryan Beasley
>Release:        6.1-RELEASE
>Organization:
>Environment:
FreeBSD yuki.internal.goddamnbastard.org 6.1-RELEASE-p10 FreeBSD 6.1-RELEASE-p10 #2: Tue Oct  3 18:00:02 CDT 2006     ryanb at yuki.internal.goddamnbastard.org:/usr/obj/usr/src/sys/YUKI  i386
>Description:
Attached is a patch that allows find(1) to discriminate based on extended attributes (extattr(9)).

ATM, it's just hanging out in my p4 branch.  Does this seem useful to anyone else?  Would there be any interest in committing it (or something like it) to CVS?
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

Change 111894 by ryanb at ryanb_yuki on 2006/12/18 14:27:32

	Patch to find(1) that examines extended attributes.  See extattr(2)
	for more information.
	
	Usage:
	    -extattr <namespace> <attrname>
	    Returns true if file contains attribute attrname in namespace.
	
	    -extattrs <namespace>
	    Returns true if file contains -any- attributes in namespace.

Affected files ...

.. //depot/user/ryanb/src/usr.bin/find/extern.h#2 edit
.. //depot/user/ryanb/src/usr.bin/find/find.1#4 edit
.. //depot/user/ryanb/src/usr.bin/find/find.h#2 edit
.. //depot/user/ryanb/src/usr.bin/find/function.c#2 edit
.. //depot/user/ryanb/src/usr.bin/find/option.c#2 edit

Differences ...


---  usr.bin/find/extern.h.orig
+++  usr.bin/find/extern.h
@@ -59,6 +59,8 @@
 creat_f	c_depth;
 creat_f	c_empty;
 creat_f	c_exec;
+creat_f c_extattr;
+creat_f c_extattrs;
 creat_f	c_flags;
 creat_f	c_follow;
 creat_f	c_fstype;
@@ -90,6 +92,8 @@
 exec_f	f_empty;
 exec_f	f_exec;
 exec_f	f_expr;
+exec_f	f_extattr;
+exec_f	f_extattrs;
 exec_f	f_flags;
 exec_f	f_fstype;
 exec_f	f_group;


---  usr.bin/find/find.1.orig
+++  usr.bin/find/find.1
@@ -363,6 +363,24 @@
 the string
 .Dq Li {}
 is not qualified.
+.It Ic -extattr Ar namespace Ar attrname
+True if file contains extended attribute
+.Ar attrname
+in
+.Ar namespace .
+The
+.Ar namespace
+may be either
+.Dq system
+or
+.Dq user .
+See
+.Xr extattr 2  
+for more information on extended attributes.
+.It Ic -extattrs Ar namespace
+True if file contains any extended attributes in
+.Ar namespace .
+Please refer to the -extattrs description for more information.
 .It Ic -flags Oo Cm - Ns | Ns Cm + Oc Ns Ar flags , Ns Ar notflags
 The flags are specified using symbolic names (see
 .Xr chflags 1 ) .


---  usr.bin/find/find.h.orig
+++  usr.bin/find/find.h
@@ -110,6 +110,10 @@
 		char *_a_data[2];		/* array of char pointers */
 		char *_c_data;			/* char pointer */
 		regex_t *_re_data;		/* regex */
+		struct {
+			int _ea_ns;		/* extattr namespace */
+			char *_ea_attr;		/* extattr key */
+		} ea;
 	} p_un;
 } PLAN;
 #define	a_data	p_un._a_data
@@ -137,6 +141,8 @@
 #define e_pbsize p_un.ex._e_pbsize
 #define e_psizemax p_un.ex._e_psizemax
 #define e_next p_un.ex._e_next
+#define ea_ns	p_un.ea._ea_ns
+#define ea_attr	p_un.ea._ea_attr
 
 typedef struct _option {
 	const char *name;		/* option name */


---  usr.bin/find/function.c.orig
+++  usr.bin/find/function.c
@@ -51,6 +51,7 @@
 #include <sys/wait.h>
 #include <sys/mount.h>
 #include <sys/timeb.h>
+#include <sys/extattr.h>
 
 #include <dirent.h>
 #include <err.h>
@@ -66,6 +67,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <libutil.h>
 
 #include "find.h"
 
@@ -771,6 +773,109 @@
 	}
 }
 
+/**
+ * @brief Setup for extended -extattr
+ *
+ * Searches for a specific extended attribute (key only, not value).
+ * Usage:
+ *   -extattr <namespace> <attr>
+ * where namespace = system or user.
+ */
+PLAN *
+c_extattr(OPTION *option, char ***argvp)
+{
+	PLAN *plan;
+	char *arg;
+
+	/* Behavior varies if target is symlink, so demand stat() */
+	ftsoptions &= ~FTS_NOSTAT;
+
+	plan = palloc(option);
+
+	/* Record desired namespace */
+	arg = nextarg(option, argvp);
+
+	/* Record attribute key */
+	plan->ea_attr = nextarg(option, argvp);
+
+	/* Validate namespace */
+	if (extattr_string_to_namespace(arg, &plan->ea_ns) == -1)
+		errx(1, "%s: invalid namespace", arg);
+
+	return(plan);
+}
+
+/**
+ * @brief Search for a specific extended attribute
+ *
+ * @return 0 for no match, non-zero otherwise
+ */
+int
+f_extattr(PLAN *plan, FTSENT *entry)
+{
+	int match = 0;
+
+	if (S_ISLNK(entry->fts_statp->st_mode))
+		match = extattr_get_link(entry->fts_accpath, plan->ea_ns, plan->ea_attr, NULL, 0);
+	else
+		match = extattr_get_file(entry->fts_accpath, plan->ea_ns, plan->ea_attr, NULL, 0);
+
+	if (match == -1) {
+		if (errno != ENOATTR)
+			warn("%s", entry->fts_accpath);
+		match = 0;
+	}
+
+	return match;
+}
+
+/**
+ * @brief Setup for -extattrs (match if file has extattrs)
+ *
+ * Usage: -extattrs <namespace>
+ * 	where namespace = system or user
+ */
+PLAN *
+c_extattrs(OPTION *option, char ***argvp)
+{
+	PLAN *plan;
+	char *arg;
+
+	/* Behavior varies if target is symlink, so demand stat() */
+	ftsoptions &= ~FTS_NOSTAT;
+
+	plan = palloc(option);
+
+	/* Record & validate namespace */
+	arg = nextarg(option, argvp);
+
+	if (extattr_string_to_namespace(arg, &plan->ea_ns) == -1)
+		errx(1, "%s: invalid namespace", arg);
+
+	return(plan);
+}
+
+/**
+ * @brief Search for presence of -any- extattrs (system & user namespaces)
+ */
+int
+f_extattrs(PLAN *plan, FTSENT *entry)
+{
+	int match = 0;
+
+	if (S_ISLNK(entry->fts_statp->st_mode))
+		match = extattr_list_link(entry->fts_accpath, plan->ea_ns, NULL, 0);
+	else
+		match = extattr_list_file(entry->fts_accpath, plan->ea_ns, NULL, 0);
+
+	if (match == -1) {
+		warn("%s", entry->fts_accpath);
+		match = 0;
+	}
+
+	return match;
+}
+
 int
 f_flags(PLAN *plan, FTSENT *entry)
 {


---  usr.bin/find/option.c.orig
+++  usr.bin/find/option.c
@@ -79,6 +79,8 @@
 	{ "-empty",	c_empty,	f_empty,	0 },
 	{ "-exec",	c_exec,		f_exec,		0 },
 	{ "-execdir",	c_exec,		f_exec,		F_EXECDIR },
+	{ "-extattr",	c_extattr,	f_extattr,	0 },
+	{ "-extattrs",	c_extattrs,	f_extattrs,	0 },
 	{ "-false",	c_simple,	f_not,		0 },
 	{ "-flags",	c_flags,	f_flags,	0 },
 	{ "-follow",	c_follow,	f_always_true,	0 },

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list