summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2008-02-23 16:29:04 +0000
committerimp <imp@FreeBSD.org>2008-02-23 16:29:04 +0000
commitc9f2fe69375b9322a4807902a05490c15a796ca4 (patch)
treeee010da56d55fa2b0774f2a16755933c4b58ba74 /usr.bin
parent2ac60d247a21d72d191d61bb23efb19e4f99f631 (diff)
downloadFreeBSD-src-c9f2fe69375b9322a4807902a05490c15a796ca4.zip
FreeBSD-src-c9f2fe69375b9322a4807902a05490c15a796ca4.tar.gz
Implement a number of primaries present in GNU find, but not present
in our find. The following are nops because they aren't relevant to our find: -ignore_readdir_race -noignore_readdir_race -noleaf The following aliaes were created: -gid -> -group [2] -uid -> -user [2] -wholename -> -path -iwholename -> ipath -mount -> -xdev -d -> -depth [1] The following new primaries were created: -lname like -name, but matches symbolic links only) -ilname like -lname but case insensitive -quit exit(0) -samefile returns true for hard links to the specified file -true Always true I changed one primary to match GNU find since I think our use of it violates POLA -false Always false (was an alias for -not!) Also, document the '+' modifier for -execdir, as well as all of the above. This was previously implemented. Document the remaining 7 primaries that are in GNU find, but aren't yet implemented in find(1) [1] This was done in GNU find for compatibility with FreeBSD, yet they mixed up command line args and primary args. [2] -uid/-gid in GNU find ONLY takes a numeric arg, but that arg does the normal range thing that. GNU find -user and -uid also take a numberic arg, but don't do the range processing. find(1) does both for -user and -group, so making -uid and -gid aliases is compatible for all non-error cases used in GNU find. While not perfect emulation, this seems a reasonable thing for us.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/find/extern.h3
-rw-r--r--usr.bin/find/find.176
-rw-r--r--usr.bin/find/find.h1
-rw-r--r--usr.bin/find/function.c60
-rw-r--r--usr.bin/find/option.c24
5 files changed, 159 insertions, 5 deletions
diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h
index a6f09f4..716c1f5 100644
--- a/usr.bin/find/extern.h
+++ b/usr.bin/find/extern.h
@@ -74,6 +74,7 @@ creat_f c_nouser;
creat_f c_perm;
creat_f c_print;
creat_f c_regex;
+creat_f c_samefile;
creat_f c_simple;
creat_f c_size;
creat_f c_type;
@@ -90,6 +91,7 @@ exec_f f_depth;
exec_f f_empty;
exec_f f_exec;
exec_f f_expr;
+exec_f f_false;
exec_f f_flags;
exec_f f_fstype;
exec_f f_group;
@@ -108,6 +110,7 @@ exec_f f_perm;
exec_f f_print;
exec_f f_print0;
exec_f f_prune;
+exec_f f_quit;
exec_f f_regex;
exec_f f_size;
exec_f f_type;
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index d8376d8..9393f9d 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -293,6 +293,12 @@ units.
Please refer to the
.Ic -atime
primary description for information on supported time units.
+.It Ic -d
+Same as
+.Ic depth .
+GNU find implements this as a primary in mistaken emulation of
+.Fx
+.Xr find 1 .
.It Ic -delete
Delete found files and/or directories.
Always returns true.
@@ -365,6 +371,15 @@ The filename substituted for
the string
.Dq Li {}
is not qualified.
+.It Ic -execdir Ar utility Oo Ar argument ... Oc Li {} +
+Same as
+.Ic -execdir ,
+except that
+.Dq Li {}
+is replaced with as many pathnames as possible for each invocation of
+.Ar utility .
+This behaviour is similar to that of
+.Xr xargs 1 .
.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 ) .
@@ -428,6 +443,15 @@ the
.Nm
is being executed and the latter matches any file system which is
mounted read-only.
+.It Ic -gid Ar gname
+The same thing as
+.Ar -group Ar gname
+for compatibility with GNU find.
+GNU find imposes a restriction that
+.Ar gname
+is numeric, while
+.Xr find 1
+does not.
.It Ic -group Ar gname
True if the file belongs to the group
.Ar gname .
@@ -436,6 +460,12 @@ If
is numeric and there is no such group name, then
.Ar gname
is treated as a group ID.
+.It Ic -ignore_readdir_race
+This option is for GNU find compatibility and is ignored.
+.It Ic -ilname Ar pattern
+Like
+.Ic -lname ,
+but the match is case insensitive.
.It Ic -iname Ar pattern
Like
.Ic -name ,
@@ -451,10 +481,18 @@ but the match is case insensitive.
Like
.Ic -regex ,
but the match is case insensitive.
+.It Ic -iwholename Ar pattern
+The same thing as
+.Ic -ipath ,
+for GNU find compatibility.
.It Ic -links Ar n
True if the file has
.Ar n
links.
+.It Ic -lname Ar pattern
+Like
+.Ic -name ,
+but the matched file must also be a symbolic link.
.It Ic -ls
This primary always evaluates to true.
The following information for the current file is written to standard output:
@@ -497,6 +535,10 @@ minutes.
.It Ic -mnewer Ar file
Same as
.Ic -newer .
+.It Ic -mount
+The same thing as
+.Ic -xdev ,
+for GNU find compatibility.
.It Ic -mtime Ar n Ns Op Cm smhdw
If no units are specified, this primary evaluates to
true if the difference between the file last modification time and the time
@@ -563,6 +605,13 @@ is equivalent to
.Ic -newer .
.It Ic -nogroup
True if the file belongs to an unknown group.
+.It Ic -noignore_readdir_race
+This option is for GNU find compatibility and is ignored.
+.It Ic -noleaf
+This option is for GNU find compatibility.
+In GNU find it disables an optimization not relevant to
+.Xr find 1 ,
+so it is ignored.
.It Ic -nouser
True if the file belongs to an unknown user.
.It Ic -ok Ar utility Oo Ar argument ... Oc Li \&;
@@ -690,6 +739,14 @@ but not
.Dq Li xyzzy
or
.Dq Li /foo/ .
+.It Ic -samefile Ar name
+True if the file is a hard link to
+.Ar name .
+If the command option
+.Ic -L
+is specified, it is also true if the file is a symbolic link and
+points to
+.Ar name .
.It Ic -size Ar n Ns Op Cm ckMGTP
True if the file's size, rounded up, in 512-byte blocks is
.Ar n .
@@ -739,6 +796,15 @@ FIFO
.It Cm s
socket
.El
+.It Ic -uid Ar uname
+The same thing as
+.Ar -user Ar uname
+for compatibility with GNU find.
+GNU find imposes a restriction that
+.Ar uname
+is numeric, while
+.Xr find 1
+does not.
.It Ic -user Ar uname
True if the file belongs to the user
.Ar uname .
@@ -747,6 +813,10 @@ If
is numeric and there is no such user name, then
.Ar uname
is treated as a user ID.
+.It Ic -wholename Ar pattern
+The same thing as
+.Ic -path ,
+for GNU find compatibility.
.El
.Pp
All primaries which take a numeric argument allow the number to be
@@ -770,13 +840,17 @@ This evaluates to true if the parenthesized expression evaluates to
true.
.Pp
.It Cm \&! Ar expression
-.It Cm -false Ar expression
.It Cm -not Ar expression
This is the unary
.Tn NOT
operator.
It evaluates to true if the expression is false.
.Pp
+.It Cm -false
+Always false.
+.It Cm -true
+Always true.
+.Pp
.It Ar expression Cm -and Ar expression
.It Ar expression expression
The
diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h
index c7366fa..5a465f1 100644
--- a/usr.bin/find/find.h
+++ b/usr.bin/find/find.h
@@ -74,6 +74,7 @@ typedef struct _plandata *creat_f(struct _option *, char ***);
#define F_EXECPLUS 0x00020000 /* -exec ... {} + */
#define F_TIME_B 0x00040000 /* one of -Btime, -Bnewer, -newerB* */
#define F_TIME2_B 0x00080000 /* one of -newer?B */
+#define F_LINK 0x00100000 /* lname or ilname */
/* node definition */
typedef struct _plandata {
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index 5de9db0..4f823a2 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -474,7 +474,7 @@ c_delete(OPTION *option, char ***argvp __unused)
/*
* always_true --
*
- * Always true, used for -maxdepth, -mindepth, -xdev and -follow
+ * Always true, used for -maxdepth, -mindepth, -xdev, -follow, and -true
*/
int
f_always_true(PLAN *plan __unused, FTSENT *entry __unused)
@@ -970,7 +970,7 @@ c_group(OPTION *option, char ***argvp)
g = getgrnam(gname);
if (g == NULL) {
char* cp = gname;
- if( gname[0] == '-' || gname[0] == '+' )
+ if (gname[0] == '-' || gname[0] == '+')
gname++;
gid = atoi(gname);
if (gid == 0 && gname[0] != '0')
@@ -1009,6 +1009,30 @@ c_inum(OPTION *option, char ***argvp)
}
/*
+ * -samefile FN
+ *
+ * True if the file has the same inode (eg hard link) FN
+ */
+
+/* f_samefile is just f_inum */
+PLAN *
+c_samefile(OPTION *option, char ***argvp)
+{
+ char *fn;
+ PLAN *new;
+ struct stat sb;
+
+ fn = nextarg(option, argvp);
+ ftsoptions &= ~FTS_NOSTAT;
+
+ new = palloc(option);
+ if (stat(fn, &sb))
+ err(1, "%s", fn);
+ new->i_data = sb.st_ino;
+ return new;
+}
+
+/*
* -links n functions --
*
* True if the file has n links.
@@ -1063,6 +1087,8 @@ c_ls(OPTION *option, char ***argvp __unused)
int
f_name(PLAN *plan, FTSENT *entry)
{
+ if ((plan->flags & F_LINK) && !S_ISLNK(entry->fts_statp->st_mode))
+ return 0;
return !fnmatch(plan->c_data, entry->fts_name,
plan->flags & F_IGNCASE ? FNM_CASEFOLD : 0);
}
@@ -1076,6 +1102,8 @@ c_name(OPTION *option, char ***argvp)
pattern = nextarg(option, argvp);
new = palloc(option);
new->c_data = pattern;
+ if (new->flags & F_LINK)
+ ftsoptions &= ~FTS_NOSTAT;
return new;
}
@@ -1353,7 +1381,7 @@ c_regex(OPTION *option, char ***argvp)
return new;
}
-/* c_simple covers c_prune, c_openparen, c_closeparen, c_not, c_or */
+/* c_simple covers c_prune, c_openparen, c_closeparen, c_not, c_or, c_true, c_false */
PLAN *
c_simple(OPTION *option, char ***argvp __unused)
@@ -1635,3 +1663,29 @@ f_or(PLAN *plan, FTSENT *entry)
}
/* c_or == c_simple */
+
+/*
+ * -false
+ *
+ * Always false.
+ */
+int
+f_false(PLAN *plan __unused, FTSENT *entry __unused)
+{
+ return 0;
+}
+
+/* c_false == c_simple */
+
+/*
+ * -quit
+ *
+ * Exits the program
+ */
+int
+f_quit(PLAN *plan __unused, FTSENT *entry __unused)
+{
+ exit(0);
+}
+
+/* c_quit == c_simple */
diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c
index c1c59ea..7d06c91 100644
--- a/usr.bin/find/option.c
+++ b/usr.bin/find/option.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
int typecompare(const void *, const void *);
/* NB: the following table must be sorted lexically. */
+/* Options listed with C++ comments are in gnu find, but not our find */
static OPTION const options[] = {
{ "!", c_simple, f_not, 0 },
{ "(", c_simple, f_openparen, 0 },
@@ -74,26 +75,38 @@ static OPTION const options[] = {
{ "-cmin", c_Xmin, f_Xmin, F_TIME_C },
{ "-cnewer", c_newer, f_newer, F_TIME_C },
{ "-ctime", c_Xtime, f_Xtime, F_TIME_C },
+ { "-d", c_depth, f_depth, 0 },
+// -daystart
{ "-delete", c_delete, f_delete, 0 },
{ "-depth", c_depth, f_depth, 0 },
{ "-empty", c_empty, f_empty, 0 },
{ "-exec", c_exec, f_exec, 0 },
{ "-execdir", c_exec, f_exec, F_EXECDIR },
- { "-false", c_simple, f_not, 0 },
+ { "-false", c_simple, f_false, 0 },
{ "-flags", c_flags, f_flags, 0 },
+// -fls
{ "-follow", c_follow, f_always_true, 0 },
+// -fprint
+// -fprint0
+// -fprintf
{ "-fstype", c_fstype, f_fstype, 0 },
+ { "-gid", c_group, f_group, 0 },
{ "-group", c_group, f_group, 0 },
+ { "-ignore_readdir_race",c_simple, f_always_true,0 },
+ { "-ilname", c_name, f_name, F_LINK | F_IGNCASE },
{ "-iname", c_name, f_name, F_IGNCASE },
{ "-inum", c_inum, f_inum, 0 },
{ "-ipath", c_name, f_path, F_IGNCASE },
{ "-iregex", c_regex, f_regex, F_IGNCASE },
+ { "-iwholename",c_name, f_path, F_IGNCASE },
{ "-links", c_links, f_links, 0 },
+ { "-lname", c_name, f_name, F_LINK },
{ "-ls", c_ls, f_ls, 0 },
{ "-maxdepth", c_mXXdepth, f_always_true, F_MAXDEPTH },
{ "-mindepth", c_mXXdepth, f_always_true, 0 },
{ "-mmin", c_Xmin, f_Xmin, 0 },
{ "-mnewer", c_newer, f_newer, 0 },
+ { "-mount", c_xdev, f_always_true, 0 },
{ "-mtime", c_Xtime, f_Xtime, 0 },
{ "-name", c_name, f_name, 0 },
{ "-newer", c_newer, f_newer, 0 },
@@ -118,6 +131,8 @@ static OPTION const options[] = {
{ "-newermm", c_newer, f_newer, 0 },
{ "-newermt", c_newer, f_newer, F_TIME2_T },
{ "-nogroup", c_nogroup, f_nogroup, 0 },
+ { "-noignore_readdir_race",c_simple, f_always_true,0 },
+ { "-noleaf", c_simple, f_always_true, 0 },
{ "-not", c_simple, f_not, 0 },
{ "-nouser", c_nouser, f_nouser, 0 },
{ "-o", c_simple, f_or, 0 },
@@ -128,12 +143,19 @@ static OPTION const options[] = {
{ "-perm", c_perm, f_perm, 0 },
{ "-print", c_print, f_print, 0 },
{ "-print0", c_print, f_print0, 0 },
+// -printf
{ "-prune", c_simple, f_prune, 0 },
+ { "-quit", c_simple, f_quit, 0 },
{ "-regex", c_regex, f_regex, 0 },
+ { "-samefile", c_samefile, f_inum, 0 },
{ "-size", c_size, f_size, 0 },
+ { "-true", c_simple, f_always_true, 0 },
{ "-type", c_type, f_type, 0 },
+ { "-uid", c_user, f_user, 0 },
{ "-user", c_user, f_user, 0 },
+ { "-wholename", c_name, f_path, 0 },
{ "-xdev", c_xdev, f_always_true, 0 },
+// -xtype
};
/*
OpenPOWER on IntegriCloud