diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h index b2597579f9b5..67a8e3be4e50 100644 --- a/usr.bin/find/extern.h +++ b/usr.bin/find/extern.h @@ -52,6 +52,7 @@ OPTION *lookup_option(const char *); creat_f c_Xmin; creat_f c_Xtime; +creat_f c_acl; creat_f c_and; creat_f c_delete; creat_f c_depth; @@ -82,6 +83,7 @@ creat_f c_xdev; exec_f f_Xmin; exec_f f_Xtime; +exec_f f_acl; exec_f f_always_true; exec_f f_closeparen; exec_f f_delete; diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index 3ba755517fdb..72bf8aae6f65 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -351,6 +353,55 @@ c_mXXdepth(OPTION *option, char ***argvp) return new; } +/* + * -acl function -- + * + * Show files with EXTENDED ACL attributes. + */ +int +f_acl(PLAN *plan__unused, FTSENT *entry) +{ + int match, entries; + acl_entry_t ae; + acl_t facl; + + if (S_ISLNK(entry->fts_statp->st_mode)) + return 0; + if ((match = pathconf(entry->fts_accpath, _PC_ACL_EXTENDED)) <= 0) { + if (match < 0 && errno != EINVAL) + warn("%s", entry->fts_accpath); + else + return 0; + } + match = 0; + if ((facl = acl_get_file(entry->fts_accpath,ACL_TYPE_ACCESS)) != NULL) { + if (acl_get_entry(facl, ACL_FIRST_ENTRY, &ae) == 1) { + /* + * POSIX.1e requires that ACLs of type ACL_TYPE_ACCESS + * must have at least three entries (owner, group, + * other). + */ + entries = 1; + while (acl_get_entry(facl, ACL_NEXT_ENTRY, &ae) == 1) { + if (++entries > 3) { + match = 1; + break; + } + } + } + acl_free(facl); + } else + warn("%s", entry->fts_accpath); + return match; +} + +PLAN * +c_acl(OPTION *option, char ***argvp__unused) +{ + ftsoptions &= ~FTS_NOSTAT; + return (palloc(option)); +} + /* * -delete functions -- * diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c index 9e10e500aeaf..2f3ca3afeaea 100644 --- a/usr.bin/find/option.c +++ b/usr.bin/find/option.c @@ -63,6 +63,7 @@ static OPTION const options[] = { { "(", c_simple, f_openparen, 0 }, { ")", c_simple, f_closeparen, 0 }, { "-a", c_and, NULL, 0 }, + { "-acl", c_acl, f_acl, 0 }, { "-amin", c_Xmin, f_Xmin, F_TIME_A }, { "-and", c_and, NULL, 0 }, { "-anewer", c_newer, f_newer, F_TIME_A },