From owner-freebsd-bugs@FreeBSD.ORG Mon Dec 18 15:20:31 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 0631216A47B for ; Mon, 18 Dec 2006 15:20:31 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9ECD443CA7 for ; Mon, 18 Dec 2006 15:20:21 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id kBIFKJmi020571 for ; Mon, 18 Dec 2006 15:20:19 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id kBIFKJvg020569; Mon, 18 Dec 2006 15:20:19 GMT (envelope-from gnats) Resent-Date: Mon, 18 Dec 2006 15:20:19 GMT Resent-Message-Id: <200612181520.kBIFKJvg020569@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ryan Beasley Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2470416A403 for ; Mon, 18 Dec 2006 15:12:35 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.FreeBSD.org (Postfix) with ESMTP id A59F743CA2 for ; Mon, 18 Dec 2006 15:12:34 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id kBIFCVt6032098 for ; Mon, 18 Dec 2006 15:12:31 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id kBIFCViO032097; Mon, 18 Dec 2006 15:12:31 GMT (envelope-from nobody) Message-Id: <200612181512.kBIFCViO032097@www.freebsd.org> Date: Mon, 18 Dec 2006 15:12:31 GMT From: Ryan Beasley To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: bin/106872: [patch] extattr support for usr.bin/find X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Dec 2006 15:20:31 -0000 >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@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@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 Returns true if file contains attribute attrname in namespace. -extattrs 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 #include #include +#include #include #include @@ -66,6 +67,7 @@ #include #include #include +#include #include "find.h" @@ -771,6 +773,109 @@ } } +/** + * @brief Setup for extended -extattr + * + * Searches for a specific extended attribute (key only, not value). + * Usage: + * -extattr + * 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 + * 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: