The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e4b646ce16105efc943bc8ac2242a2220dfe18d8

commit e4b646ce16105efc943bc8ac2242a2220dfe18d8
Author:     Ricardo Branco <rbra...@suse.de>
AuthorDate: 2024-01-21 19:53:05 +0000
Commit:     John Baldwin <j...@freebsd.org>
CommitDate: 2024-01-22 01:33:46 +0000

    find: Add -readable, -writable & -executable options
    
    Reviewed by:    jhb, Mina Galić
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1080
---
 usr.bin/find/extern.h   |  3 +++
 usr.bin/find/find.1     | 20 +++++++++++++++++++-
 usr.bin/find/function.c | 39 +++++++++++++++++++++++++++++++++++++++
 usr.bin/find/option.c   |  3 +++
 4 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h
index a1bd5e6d16a5..feb2e0202056 100644
--- a/usr.bin/find/extern.h
+++ b/usr.bin/find/extern.h
@@ -86,6 +86,7 @@ exec_f        f_delete;
 exec_f f_depth;
 exec_f f_empty;
 exec_f f_exec;
+exec_f f_executable;
 exec_f f_expr;
 exec_f f_false;
 exec_f f_flags;
@@ -107,11 +108,13 @@ exec_f    f_print;
 exec_f f_print0;
 exec_f f_prune;
 exec_f f_quit;
+exec_f f_readable;
 exec_f f_regex;
 exec_f f_size;
 exec_f f_sparse;
 exec_f f_type;
 exec_f f_user;
+exec_f f_writable;
 
 extern int ftsoptions, ignore_readdir_race, isdepth, isoutput;
 extern int issort, isxargs;
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 856961d02395..635d42656bad 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -28,7 +28,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 15, 2024
+.Dd January 21, 2024
 .Dt FIND 1
 .Os
 .Sh NAME
@@ -465,6 +465,12 @@ if at least one invocation of
 returns a non-zero exit status,
 .Nm
 will return a non-zero exit status.
+.It Ic -executable
+Matches files which are executable by the current user.
+This test makes use of the
+.Xr access 2
+system call, and so can be fooled by NFS servers which do UID mapping (or 
root-squashing).
+This is a GNU find extension.
 .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 ) .
@@ -829,6 +835,12 @@ option was specified.
 Causes
 .Nm
 to terminate immediately.
+.It Ic -readable
+Matches files which are readable by the current user.
+This test makes use of the
+.Xr access 2
+system call, and so can be fooled by NFS servers which do UID mapping (or 
root-squashing).
+This is a GNU find extension.
 .It Ic -regex Ar pattern
 True if the whole path of the file matches
 .Ar pattern
@@ -925,6 +937,12 @@ is treated as a user ID.
 The same thing as
 .Ic -path ,
 for GNU find compatibility.
+.It Ic -writable
+Matches files which are writable by the current user.
+This test makes use of the
+.Xr access 2
+system call, and so can be fooled by NFS servers which do UID mapping (or 
root-squashing).
+This is a GNU find extension.
 .El
 .Sh OPERATORS
 The primaries may be combined using the following operators.
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index f96a086cbda3..ef610903cc00 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -1808,3 +1808,42 @@ f_quit(PLAN *plan __unused, FTSENT *entry __unused)
 }
 
 /* c_quit == c_simple */
+
+/*
+ * -readable
+ *
+ *     File is readable
+ */
+int
+f_readable(PLAN *plan __unused, FTSENT *entry)
+{
+       return (access(entry->fts_path, R_OK) == 0);
+}
+
+/* c_readable == c_simple */
+
+/*
+ * -writable
+ *
+ *     File is writable
+ */
+int
+f_writable(PLAN *plan __unused, FTSENT *entry)
+{
+       return (access(entry->fts_path, W_OK) == 0);
+}
+
+/* c_writable == c_simple */
+
+/*
+ * -executable
+ *
+ *     File is executable
+ */
+int
+f_executable(PLAN *plan __unused, FTSENT *entry)
+{
+       return (access(entry->fts_path, X_OK) == 0);
+}
+
+/* c_executable == c_simple */
diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c
index 166fc75e9c51..99c67eed8cd9 100644
--- a/usr.bin/find/option.c
+++ b/usr.bin/find/option.c
@@ -75,6 +75,7 @@ static OPTION const options[] = {
        { "-empty",     c_empty,        f_empty,        0 },
        { "-exec",      c_exec,         f_exec,         0 },
        { "-execdir",   c_exec,         f_exec,         F_EXECDIR },
+       { "-executable", c_simple,      f_executable,   0 },
        { "-false",     c_simple,       f_false,        0 },
 #if HAVE_STRUCT_STAT_ST_FLAGS
        { "-flags",     c_flags,        f_flags,        0 },
@@ -149,6 +150,7 @@ static OPTION const options[] = {
 // -printf
        { "-prune",     c_simple,       f_prune,        0 },
        { "-quit",      c_simple,       f_quit,         0 },
+       { "-readable",  c_simple,       f_readable,     0 },
        { "-regex",     c_regex,        f_regex,        0 },
        { "-samefile",  c_samefile,     f_inum,         0 },
        { "-size",      c_size,         f_size,         0 },
@@ -158,6 +160,7 @@ static OPTION const options[] = {
        { "-uid",       c_user,         f_user,         0 },
        { "-user",      c_user,         f_user,         0 },
        { "-wholename", c_name,         f_path,         0 },
+       { "-writable",  c_simple,       f_writable,     0 },
        { "-xdev",      c_xdev,         f_always_true,  0 },
 // -xtype
 };

Reply via email to