tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Possible enhancement to find(1)
On Sat, 11 Jun 2016, Paul Goyette wrote:
On Sat, 11 Jun 2016, Robert Elz wrote:
...
If you were also to add
{ "-newerat", N_ASINCE, c_asince, 1 }, /* gnu find
compat */
{ "-newerct", N_CSINCE, c_csince, 1 },
{ "-newermt", N_SINCE, c_since, 1 }, /* ung */
in the appropriate place, you'd have something that was command line
compatible with gnu findutils, so scripts written for that find, which
only use facilities actually implemented here, would work.
Would that really be such an evil thing?
For me, yes. I will not implement the ugly gnu stuff, neither in its
entirety nor partially.
Well, I've been convinced by several off-list exchanges that it's really
not so bad to implement the gnu stuff after all.
We only have to implement gnu-equivalents for the functionality that we
already have - so we don't have to implement comparisons of differing
attributes (ie, a found file's atime vs the reference file's mtime).
The man-page for findutils clearly states that not all combinations need
to be provided.
I've restructured the existing code a bit, so that the parsing code
provides each option's argument parser with the actual option name;
this allows us to use the same argument parsing routines for the "alias"
options as for the "real" options.
New diffs are attached. These include lists of the findutils -newerXY
options which remain unimplemented.
Comments are welcomed - even though I might at first reject them, I do
eventually consider them. :)
+------------------+--------------------------+------------------------+
| Paul Goyette | PGP Key fingerprint: | E-mail addresses: |
| (Retired) | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org |
+------------------+--------------------------+------------------------+
Index: extern.h
===================================================================
RCS file: /cvsroot/src/usr.bin/find/extern.h,v
retrieving revision 1.28
diff -u -p -r1.28 extern.h
--- extern.h 19 Jul 2007 07:49:30 -0000 1.28
+++ extern.h 12 Jun 2016 00:30:16 -0000
@@ -47,53 +47,56 @@ void printlong(char *, char *, struct s
int queryuser(char **);
void show_path(int);
-PLAN *c_amin(char ***, int);
-PLAN *c_anewer(char ***, int);
-PLAN *c_atime(char ***, int);
-PLAN *c_cmin(char ***, int);
-PLAN *c_cnewer(char ***, int);
-PLAN *c_ctime(char ***, int);
-PLAN *c_delete(char ***, int);
-PLAN *c_depth(char ***, int);
-PLAN *c_empty(char ***, int);
-PLAN *c_exec(char ***, int);
-PLAN *c_execdir(char ***, int);
-PLAN *c_exit(char ***, int);
-PLAN *c_false(char ***, int);
-PLAN *c_flags(char ***, int);
-PLAN *c_follow(char ***, int);
-PLAN *c_fprint(char ***, int);
-PLAN *c_fstype(char ***, int);
-PLAN *c_group(char ***, int);
-PLAN *c_iname(char ***, int);
-PLAN *c_inum(char ***, int);
-PLAN *c_iregex(char ***, int);
-PLAN *c_links(char ***, int);
-PLAN *c_ls(char ***, int);
-PLAN *c_maxdepth(char ***, int);
-PLAN *c_mindepth(char ***, int);
-PLAN *c_mmin(char ***, int);
-PLAN *c_mtime(char ***, int);
-PLAN *c_name(char ***, int);
-PLAN *c_newer(char ***, int);
-PLAN *c_nogroup(char ***, int);
-PLAN *c_nouser(char ***, int);
-PLAN *c_path(char ***, int);
-PLAN *c_perm(char ***, int);
-PLAN *c_print(char ***, int);
-PLAN *c_print0(char ***, int);
-PLAN *c_printx(char ***, int);
-PLAN *c_prune(char ***, int);
-PLAN *c_regex(char ***, int);
-PLAN *c_size(char ***, int);
-PLAN *c_type(char ***, int);
-PLAN *c_user(char ***, int);
-PLAN *c_xdev(char ***, int);
-PLAN *c_openparen(char ***, int);
-PLAN *c_closeparen(char ***, int);
-PLAN *c_not(char ***, int);
-PLAN *c_or(char ***, int);
-PLAN *c_null(char ***, int);
+PLAN *c_amin(char ***, int, char *);
+PLAN *c_anewer(char ***, int, char *);
+PLAN *c_asince(char ***, int, char *);
+PLAN *c_atime(char ***, int, char *);
+PLAN *c_cmin(char ***, int, char *);
+PLAN *c_cnewer(char ***, int, char *);
+PLAN *c_csince(char ***, int, char *);
+PLAN *c_ctime(char ***, int, char *);
+PLAN *c_delete(char ***, int, char *);
+PLAN *c_depth(char ***, int, char *);
+PLAN *c_empty(char ***, int, char *);
+PLAN *c_exec(char ***, int, char *);
+PLAN *c_execdir(char ***, int, char *);
+PLAN *c_exit(char ***, int, char *);
+PLAN *c_false(char ***, int, char *);
+PLAN *c_flags(char ***, int, char *);
+PLAN *c_follow(char ***, int, char *);
+PLAN *c_fprint(char ***, int, char *);
+PLAN *c_fstype(char ***, int, char *);
+PLAN *c_group(char ***, int, char *);
+PLAN *c_iname(char ***, int, char *);
+PLAN *c_inum(char ***, int, char *);
+PLAN *c_iregex(char ***, int, char *);
+PLAN *c_links(char ***, int, char *);
+PLAN *c_ls(char ***, int, char *);
+PLAN *c_maxdepth(char ***, int, char *);
+PLAN *c_mindepth(char ***, int, char *);
+PLAN *c_mmin(char ***, int, char *);
+PLAN *c_mtime(char ***, int, char *);
+PLAN *c_name(char ***, int, char *);
+PLAN *c_newer(char ***, int, char *);
+PLAN *c_nogroup(char ***, int, char *);
+PLAN *c_nouser(char ***, int, char *);
+PLAN *c_path(char ***, int, char *);
+PLAN *c_perm(char ***, int, char *);
+PLAN *c_print(char ***, int, char *);
+PLAN *c_print0(char ***, int, char *);
+PLAN *c_printx(char ***, int, char *);
+PLAN *c_prune(char ***, int, char *);
+PLAN *c_regex(char ***, int, char *);
+PLAN *c_since(char ***, int, char *);
+PLAN *c_size(char ***, int, char *);
+PLAN *c_type(char ***, int, char *);
+PLAN *c_user(char ***, int, char *);
+PLAN *c_xdev(char ***, int, char *);
+PLAN *c_openparen(char ***, int, char *);
+PLAN *c_closeparen(char ***, int, char *);
+PLAN *c_not(char ***, int, char *);
+PLAN *c_or(char ***, int, char *);
+PLAN *c_null(char ***, int, char *);
extern int ftsoptions, isdeprecated, isdepth, isoutput, issort, isxargs,
regcomp_flags;
Index: find.1
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.1,v
retrieving revision 1.81
diff -u -p -r1.81 find.1
--- find.1 17 May 2014 11:31:40 -0000 1.81
+++ find.1 12 Jun 2016 00:30:16 -0000
@@ -32,7 +32,7 @@
.\"
.\" from: @(#)find.1 8.7 (Berkeley) 5/9/95
.\"
-.Dd May 17, 2014
+.Dd June 10, 2016
.Dt FIND 1
.Os
.Sh NAME
@@ -171,6 +171,12 @@ a preceding minus sign means
and neither means
.Dq exactly Ar n .
.Pp
+For primaries which take a
+.Ar timestamp
+argument, the argument must be valid input to
+.Xr parsedate 3 .
+If the argument contains multiple words, enclose the argument in quotes.
+.Pp
.Bl -tag -width Ds -compact
.It Ic -amin Ar n
True if the difference between the file last access time and the time
@@ -183,6 +189,10 @@ minutes.
True if the current file has a more recent last access time than
.Ar file .
.Pp
+.It Ic -asince Ar "timestamp"
+True if the file last access time is greater than the specified
+.Ar timestamp .
+.Pp
.It Ic -atime Ar n
True if the difference between the file last access time and the time
.Nm
@@ -202,6 +212,10 @@ minutes.
True if the current file has a more recent last change time than
.Ar file .
.Pp
+.It Ic -csince Ar "timestamp"
+True if the file last status change time is greater than the specified
+.Ar timestamp .
+.Pp
.It Ic -ctime Ar n
True if the difference between the time of last change of file status
information and the time
@@ -525,6 +539,21 @@ backslash
True if the current file has a more recent last modification time than
.Ar file .
.Pp
+.It Ic -newerXY Ar reference
+For compatability with Gnu findutils.
+.Bl -column -offset indent ".Sy findutils" ".Sy equivalent"
+.It Sy findutils Ta Sy find
+.It Sy option Ta Sy equivalent
+.It -neweraa Ta -anewer
+.It -newerat Ta -asince
+.It -newercc Ta -cnewer
+.It -newerct Ta -csince
+.It -newermm Ta -newer
+.It -newermt Ta -since
+.El
+.Pp
+Other option variants from findutils are not implemented.
+.Pp
.It Ic -nouser
True if the file belongs to an unknown user.
.Pp
@@ -637,6 +666,10 @@ basic regular expression
This is a match on the whole path, not a search for the regular expression
within the path.
.Pp
+.It Ic -since Ar "timestamp"
+True if the file last modification time is more recent than
+.Ar timestamp .
+.Pp
.It Ic -size Ar n Ns Op Cm c
True if the file's size, rounded up, in 512-byte blocks is
.Ar n .
@@ -809,8 +842,10 @@ standard.
The options and the
.Ic -amin ,
.Ic -anewer ,
+.Ic -asince ,
.Ic -cmin ,
.Ic -cnewer ,
+.Ic -csince ,
.Ic -delete ,
.Ic -empty ,
.Ic -execdir ,
@@ -828,8 +863,9 @@ The options and the
.Ic -print0 ,
.Ic -printx ,
.Ic -regex ,
+.Ic -rm ,
and
-.Ic -rm
+.Ic -since
primaries are extensions to
.St -p1003.2 .
.Pp
Index: find.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.c,v
retrieving revision 1.29
diff -u -p -r1.29 find.c
--- find.c 20 Mar 2012 20:34:57 -0000 1.29
+++ find.c 12 Jun 2016 00:30:16 -0000
@@ -102,16 +102,16 @@ find_formplan(char **argv)
*/
if (!isoutput) {
if (plan == NULL) {
- new = c_print(NULL, 0);
+ new = c_print(NULL, 0, NULL);
tail = plan = new;
} else {
- new = c_openparen(NULL, 0);
+ new = c_openparen(NULL, 0, NULL);
new->next = plan;
plan = new;
- new = c_closeparen(NULL, 0);
+ new = c_closeparen(NULL, 0, NULL);
tail->next = new;
tail = new;
- new = c_print(NULL, 0);
+ new = c_print(NULL, 0, NULL);
tail->next = new;
tail = new;
}
Index: find.h
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.h,v
retrieving revision 1.25
diff -u -p -r1.25 find.h
--- find.h 4 May 2013 06:29:32 -0000 1.25
+++ find.h 12 Jun 2016 00:30:16 -0000
@@ -40,13 +40,13 @@
/* node type */
enum ntype {
N_AND = 1, /* must start > 0 */
- N_AMIN, N_ANEWER, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CNEWER, N_CTIME,
- N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR, N_EXIT, N_EXPR, N_FALSE, N_FLAGS,
- N_FOLLOW, N_FPRINT, N_FSTYPE, N_GROUP,
+ N_AMIN, N_ANEWER, N_ASINCE, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CNEWER,
+ N_CSINCE, N_CTIME, N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR, N_EXIT,
+ N_EXPR, N_FALSE, N_FLAGS, N_FOLLOW, N_FPRINT, N_FSTYPE, N_GROUP,
N_INAME, N_INUM, N_IREGEX, N_LINKS, N_LS, N_MINDEPTH, N_MAXDEPTH,
N_MMIN, N_MTIME, N_NAME, N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK,
N_OPENPAREN, N_OR, N_PATH, N_PERM, N_PRINT, N_PRINT0, N_PRINTX,
- N_PRUNE, N_REGEX, N_SIZE, N_TYPE, N_USER, N_XDEV, N_DELETE
+ N_PRUNE, N_REGEX, N_SINCE, N_SIZE, N_TYPE, N_USER, N_XDEV, N_DELETE
};
/* node definition */
@@ -129,10 +129,10 @@ typedef struct _plandata {
#define fprint_file p_un._fprint_file
typedef struct _option {
- const char *name; /* option name */
- enum ntype token; /* token type */
- PLAN *(*create)(char ***, int); /* create function */
- int arg; /* function needs arg */
+ const char *name; /* option name */
+ enum ntype token; /* token type */
+ PLAN *(*create)(char ***, int, char *); /* create function */
+ int arg; /* function needs arg */
} OPTION;
#include "extern.h"
Index: function.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/function.c,v
retrieving revision 1.72
diff -u -p -r1.72 function.c
--- function.c 4 May 2013 06:29:32 -0000 1.72
+++ function.c 12 Jun 2016 00:30:16 -0000
@@ -83,9 +83,11 @@ static void run_f_exec(PLAN *);
int f_always_true(PLAN *, FTSENT *);
int f_amin(PLAN *, FTSENT *);
int f_anewer(PLAN *, FTSENT *);
+ int f_asince(PLAN *, FTSENT *);
int f_atime(PLAN *, FTSENT *);
int f_cmin(PLAN *, FTSENT *);
int f_cnewer(PLAN *, FTSENT *);
+ int f_csince(PLAN *, FTSENT *);
int f_ctime(PLAN *, FTSENT *);
int f_delete(PLAN *, FTSENT *);
int f_empty(PLAN *, FTSENT *);
@@ -106,6 +108,25 @@ static void run_f_exec(PLAN *);
int f_mtime(PLAN *, FTSENT *);
int f_name(PLAN *, FTSENT *);
int f_newer(PLAN *, FTSENT *);
+/*
+ * Unimplemented Gnu findutils options
+ *
+ int f_newerBB(PLAN *, FTSENT *);
+ int f_newerBa(PLAN *, FTSENT *);
+ int f_newerBc(PLAN *, FTSENT *);
+ int f_newerBm(PLAN *, FTSENT *);
+ int f_newerBt(PLAN *, FTSENT *);
+ int f_neweraB(PLAN *, FTSENT *);
+ int f_newerac(PLAN *, FTSENT *);
+ int f_neweram(PLAN *, FTSENT *);
+ int f_newerca(PLAN *, FTSENT *);
+ int f_newercm(PLAN *, FTSENT *);
+ int f_newercB(PLAN *, FTSENT *);
+ int f_newermB(PLAN *, FTSENT *);
+ int f_newerma(PLAN *, FTSENT *);
+ int f_newermc(PLAN *, FTSENT *);
+ *
+ */
int f_nogroup(PLAN *, FTSENT *);
int f_nouser(PLAN *, FTSENT *);
int f_path(PLAN *, FTSENT *);
@@ -115,6 +136,7 @@ static void run_f_exec(PLAN *);
int f_printx(PLAN *, FTSENT *);
int f_prune(PLAN *, FTSENT *);
int f_regex(PLAN *, FTSENT *);
+ int f_since(PLAN *, FTSENT *);
int f_size(PLAN *, FTSENT *);
int f_type(PLAN *, FTSENT *);
int f_user(PLAN *, FTSENT *);
@@ -170,6 +192,23 @@ find_parsenum(PLAN *plan, const char *op
}
/*
+ * find_parsedate --
+ *
+ * Validate the timestamp argument or report an error
+ */
+static time_t
+find_parsedate(PLAN *plan, const char *option, const char *vp)
+{
+ time_t timestamp;
+
+ errno = 0;
+ timestamp = parsedate(vp, NULL, NULL);
+ if (timestamp == -1 && errno != 0)
+ errx(1, "%s: %s: invalid timestamp value", option, vp);
+ return timestamp;
+}
+
+/*
* The value of n for the inode times (atime, ctime, and mtime) is a range,
* i.e. n matches from (n - 1) to n 24 hour periods. This interacts with
* -n, such that "-mtime -1" would be less than 0 days, which isn't what the
@@ -193,7 +232,7 @@ f_amin(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_amin(char ***argvp, int isok)
+c_amin(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -202,7 +241,7 @@ c_amin(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_AMIN, f_amin);
- new->t_data = find_parsenum(new, "-amin", arg, NULL);
+ new->t_data = find_parsenum(new, opt, arg, NULL);
TIME_CORRECT(new, N_AMIN);
return (new);
}
@@ -222,7 +261,7 @@ f_anewer(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_anewer(char ***argvp, int isok)
+c_anewer(char ***argvp, int isok, char *opt)
{
char *filename = **argvp;
PLAN *new;
@@ -232,13 +271,39 @@ c_anewer(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
if (stat(filename, &sb))
- err(1, "%s", filename);
+ err(1, "%s: %s:", opt, filename);
new = palloc(N_ANEWER, f_anewer);
new->ts_data = sb.st_atim;
return (new);
}
/*
+ * -asince "timestamp" functions --
+ *
+ * True if the file access time is greater than the timestamp value
+ */
+int
+f_asince(PLAN *plan, FTSENT *entry)
+{
+ COMPARE(entry->fts_statp->st_atime, plan->t_data);
+}
+
+PLAN *
+c_asince(char ***argvp, int isok, char *opt)
+{
+ char *arg = **argvp;
+ PLAN *new;
+
+ (*argvp)++;
+ ftsoptions &= ~FTS_NOSTAT;
+
+ new = palloc(N_ASINCE, f_asince);
+ new->t_data = find_parsedate(new, opt, arg);
+ new->flags = F_GREATER;
+ return (new);
+}
+
+/*
* -atime n functions --
*
* True if the difference between the file access time and the
@@ -252,7 +317,7 @@ f_atime(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_atime(char ***argvp, int isok)
+c_atime(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -261,7 +326,7 @@ c_atime(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_ATIME, f_atime);
- new->t_data = find_parsenum(new, "-atime", arg, NULL);
+ new->t_data = find_parsenum(new, opt, arg, NULL);
TIME_CORRECT(new, N_ATIME);
return (new);
}
@@ -280,7 +345,7 @@ f_cmin(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_cmin(char ***argvp, int isok)
+c_cmin(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -289,7 +354,7 @@ c_cmin(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_CMIN, f_cmin);
- new->t_data = find_parsenum(new, "-cmin", arg, NULL);
+ new->t_data = find_parsenum(new, opt, arg, NULL);
TIME_CORRECT(new, N_CMIN);
return (new);
}
@@ -309,7 +374,7 @@ f_cnewer(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_cnewer(char ***argvp, int isok)
+c_cnewer(char ***argvp, int isok, char *opt)
{
char *filename = **argvp;
PLAN *new;
@@ -319,13 +384,39 @@ c_cnewer(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
if (stat(filename, &sb))
- err(1, "%s", filename);
+ err(1, "%s: %s: ", opt, filename);
new = palloc(N_CNEWER, f_cnewer);
new->ts_data = sb.st_ctim;
return (new);
}
/*
+ * -csince "timestamp" functions --
+ *
+ * True if the file status change time is greater than the timestamp value
+ */
+int
+f_csince(PLAN *plan, FTSENT *entry)
+{
+ COMPARE(entry->fts_statp->st_ctime, plan->t_data);
+}
+
+PLAN *
+c_csince(char ***argvp, int isok, char *opt)
+{
+ char *arg = **argvp;
+ PLAN *new;
+
+ (*argvp)++;
+ ftsoptions &= ~FTS_NOSTAT;
+
+ new = palloc(N_CSINCE, f_csince);
+ new->t_data = find_parsedate(new, opt, arg);
+ new->flags = F_GREATER;
+ return (new);
+}
+
+/*
* -ctime n functions --
*
* True if the difference between the last change of file
@@ -339,7 +430,7 @@ f_ctime(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_ctime(char ***argvp, int isok)
+c_ctime(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -348,7 +439,7 @@ c_ctime(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_CTIME, f_ctime);
- new->t_data = find_parsenum(new, "-ctime", arg, NULL);
+ new->t_data = find_parsenum(new, opt, arg, NULL);
TIME_CORRECT(new, N_CTIME);
return (new);
}
@@ -399,7 +490,7 @@ f_delete(PLAN *plan __unused, FTSENT *en
}
PLAN *
-c_delete(char ***argvp __unused, int isok)
+c_delete(char ***argvp __unused, int isok, char *opt)
{
ftsoptions &= ~FTS_NOSTAT; /* no optimize */
@@ -426,7 +517,7 @@ f_always_true(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_depth(char ***argvp, int isok)
+c_depth(char ***argvp, int isok, char *opt)
{
isdepth = 1;
@@ -467,7 +558,7 @@ f_empty(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_empty(char ***argvp, int isok)
+c_empty(char ***argvp, int isok, char *opt)
{
ftsoptions &= ~FTS_NOSTAT;
@@ -624,7 +715,7 @@ run_f_exec(PLAN *plan)
* discussion), and then allocate ARG_MAX - 4K of space for args.
*/
PLAN *
-c_exec(char ***argvp, int isok)
+c_exec(char ***argvp, int isok, char *opt)
{
PLAN *new; /* node returned */
size_t cnt;
@@ -644,8 +735,7 @@ c_exec(char ***argvp, int isok)
*/
for (ap = argv = *argvp, brace = 0;; ++ap) {
if (!*ap)
- errx(1, "%s: no terminating \";\" or \"+\"",
- isok ? "-ok" : "-exec");
+ errx(1, "%s: no terminating \";\" or \"+\"", opt);
lastbrace = brace;
brace = 0;
if (strcmp(*ap, "{}") == 0)
@@ -663,7 +753,7 @@ c_exec(char ***argvp, int isok)
* not make much sense anyway.
*/
if (new->flags & F_NEEDOK && new->flags & F_PLUSSET)
- errx(1, "-ok: terminating \"+\" not permitted.");
+ errx(1, "%s: terminating \"+\" not permitted.", opt);
if (new->flags & F_PLUSSET) {
size_t c, bufsize;
@@ -780,7 +870,7 @@ f_execdir(PLAN *plan, FTSENT *entry)
* strings, but also flags meaning that the string has to be massaged.
*/
PLAN *
-c_execdir(char ***argvp, int isok)
+c_execdir(char ***argvp, int isok, char *opt)
{
PLAN *new; /* node returned */
size_t cnt;
@@ -793,8 +883,7 @@ c_execdir(char ***argvp, int isok)
for (ap = argv = *argvp;; ++ap) {
if (!*ap)
- errx(1,
- "-execdir: no terminating \";\"");
+ errx(1, "%s: no terminating \";\"", opt);
if (**ap == ';')
break;
}
@@ -824,7 +913,7 @@ c_execdir(char ***argvp, int isok)
}
PLAN *
-c_exit(char ***argvp, int isok)
+c_exit(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -836,7 +925,7 @@ c_exit(char ***argvp, int isok)
if (arg) {
(*argvp)++;
- new->exit_val = find_parsenum(new, "-exit", arg, NULL);
+ new->exit_val = find_parsenum(new, opt, arg, NULL);
} else
new->exit_val = 0;
@@ -855,7 +944,7 @@ f_false(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_false(char ***argvp, int isok)
+c_false(char ***argvp, int isok, char *opt)
{
return (palloc(N_FALSE, f_false));
}
@@ -878,7 +967,7 @@ f_flags(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_flags(char ***argvp, int isok)
+c_flags(char ***argvp, int isok, char *opt)
{
char *flags = **argvp;
PLAN *new;
@@ -897,7 +986,7 @@ c_flags(char ***argvp, int isok)
flagset = 0;
if ((strcmp(flags, "none") != 0) &&
(string_to_flags(&flags, &flagset, NULL) != 0))
- errx(1, "-flags: %s: illegal flags string", flags);
+ errx(1, "%s: %s: illegal flags string", opt, flags);
new->f_data = flagset;
return (new);
}
@@ -909,7 +998,7 @@ c_flags(char ***argvp, int isok)
* basis.
*/
PLAN *
-c_follow(char ***argvp, int isok)
+c_follow(char ***argvp, int isok, char *opt)
{
ftsoptions &= ~FTS_PHYSICAL;
ftsoptions |= FTS_LOGICAL;
@@ -935,7 +1024,7 @@ f_fprint(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_fprint(char ***argvp, int isok)
+c_fprint(char ***argvp, int isok, char *opt)
{
PLAN *new;
@@ -944,7 +1033,7 @@ c_fprint(char ***argvp, int isok)
new = palloc(N_FPRINT, f_fprint);
if (NULL == (new->fprint_file = fopen(**argvp, "w")))
- err(1, "-fprint: %s: cannot create file", **argvp);
+ err(1, "%s: %s: cannot create file", opt, **argvp);
(*argvp)++;
return (new);
@@ -1017,7 +1106,7 @@ f_fstype(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_fstype(char ***argvp, int isok)
+c_fstype(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1064,7 +1153,7 @@ f_group(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_group(char ***argvp, int isok)
+c_group(char ***argvp, int isok, char *opt)
{
char *gname = **argvp;
PLAN *new;
@@ -1078,7 +1167,7 @@ c_group(char ***argvp, int isok)
if (g == NULL) {
gid = atoi(gname);
if (gid == 0 && gname[0] != '0')
- errx(1, "-group: %s: no such group", gname);
+ errx(1, "%s: %s: no such group", opt, gname);
} else
gid = g->gr_gid;
@@ -1100,7 +1189,7 @@ f_inum(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_inum(char ***argvp, int isok)
+c_inum(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1109,7 +1198,7 @@ c_inum(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_INUM, f_inum);
- new->i_data = find_parsenum(new, "-inum", arg, NULL);
+ new->i_data = find_parsenum(new, opt, arg, NULL);
return (new);
}
@@ -1126,7 +1215,7 @@ f_links(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_links(char ***argvp, int isok)
+c_links(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1135,7 +1224,7 @@ c_links(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_LINKS, f_links);
- new->l_data = (nlink_t)find_parsenum(new, "-links", arg, NULL);
+ new->l_data = (nlink_t)find_parsenum(new, opt, arg, NULL);
return (new);
}
@@ -1153,7 +1242,7 @@ f_ls(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_ls(char ***argvp, int isok)
+c_ls(char ***argvp, int isok, char *opt)
{
ftsoptions &= ~FTS_NOSTAT;
@@ -1179,7 +1268,7 @@ f_maxdepth(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_maxdepth(char ***argvp, int isok)
+c_maxdepth(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1203,7 +1292,7 @@ f_mindepth(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_mindepth(char ***argvp, int isok)
+c_mindepth(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1228,7 +1317,7 @@ f_mmin(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_mmin(char ***argvp, int isok)
+c_mmin(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1237,7 +1326,7 @@ c_mmin(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_MMIN, f_mmin);
- new->t_data = find_parsenum(new, "-mmin", arg, NULL);
+ new->t_data = find_parsenum(new, opt, arg, NULL);
TIME_CORRECT(new, N_MMIN);
return (new);
}
@@ -1256,7 +1345,7 @@ f_mtime(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_mtime(char ***argvp, int isok)
+c_mtime(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1265,7 +1354,7 @@ c_mtime(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_MTIME, f_mtime);
- new->t_data = find_parsenum(new, "-mtime", arg, NULL);
+ new->t_data = find_parsenum(new, opt, arg, NULL);
TIME_CORRECT(new, N_MTIME);
return (new);
}
@@ -1284,7 +1373,7 @@ f_name(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_name(char ***argvp, int isok)
+c_name(char ***argvp, int isok, char *opt)
{
char *pattern = **argvp;
PLAN *new;
@@ -1308,7 +1397,7 @@ f_iname(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_iname(char ***argvp, int isok)
+c_iname(char ***argvp, int isok, char *opt)
{
char *pattern = **argvp;
PLAN *new;
@@ -1334,7 +1423,7 @@ f_newer(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_newer(char ***argvp, int isok)
+c_newer(char ***argvp, int isok, char *opt)
{
char *filename = **argvp;
PLAN *new;
@@ -1344,7 +1433,7 @@ c_newer(char ***argvp, int isok)
ftsoptions &= ~FTS_NOSTAT;
if (stat(filename, &sb))
- err(1, "%s", filename);
+ err(1, "%s: %s", opt, filename);
new = palloc(N_NEWER, f_newer);
new->ts_data = sb.st_mtim;
return (new);
@@ -1364,7 +1453,7 @@ f_nogroup(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_nogroup(char ***argvp, int isok)
+c_nogroup(char ***argvp, int isok, char *opt)
{
ftsoptions &= ~FTS_NOSTAT;
@@ -1385,7 +1474,7 @@ f_nouser(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_nouser(char ***argvp, int isok)
+c_nouser(char ***argvp, int isok, char *opt)
{
ftsoptions &= ~FTS_NOSTAT;
@@ -1406,7 +1495,7 @@ f_path(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_path(char ***argvp, int isok)
+c_path(char ***argvp, int isok, char *opt)
{
char *pattern = **argvp;
PLAN *new;
@@ -1439,7 +1528,7 @@ f_perm(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_perm(char ***argvp, int isok)
+c_perm(char ***argvp, int isok, char *opt)
{
char *perm = **argvp;
PLAN *new;
@@ -1456,7 +1545,7 @@ c_perm(char ***argvp, int isok)
}
if ((set = setmode(perm)) == NULL)
- err(1, "-perm: Cannot set file mode `%s'", perm);
+ err(1, "%s: Cannot set file mode `%s'", opt, perm);
new->m_data = getmode(set, 0);
free(set);
@@ -1505,7 +1594,7 @@ f_printx(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_print(char ***argvp, int isok)
+c_print(char ***argvp, int isok, char *opt)
{
isoutput = 1;
@@ -1514,7 +1603,7 @@ c_print(char ***argvp, int isok)
}
PLAN *
-c_print0(char ***argvp, int isok)
+c_print0(char ***argvp, int isok, char *opt)
{
isoutput = 1;
@@ -1523,7 +1612,7 @@ c_print0(char ***argvp, int isok)
}
PLAN *
-c_printx(char ***argvp, int isok)
+c_printx(char ***argvp, int isok, char *opt)
{
isoutput = 1;
@@ -1545,7 +1634,7 @@ f_prune(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_prune(char ***argvp, int isok)
+c_prune(char ***argvp, int isok, char *opt)
{
return (palloc(N_PRUNE, f_prune));
@@ -1599,20 +1688,46 @@ c_regex_common(char ***argvp, int isok,
}
PLAN *
-c_regex(char ***argvp, int isok)
+c_regex(char ***argvp, int isok, char *opt)
{
return (c_regex_common(argvp, isok, N_REGEX, false));
}
PLAN *
-c_iregex(char ***argvp, int isok)
+c_iregex(char ***argvp, int isok, char *opt)
{
return (c_regex_common(argvp, isok, N_IREGEX, true));
}
/*
+ * -since "timestamp" functions --
+ *
+ * True if the file modification time is greater than the timestamp value
+ */
+int
+f_since(PLAN *plan, FTSENT *entry)
+{
+ COMPARE(entry->fts_statp->st_mtime, plan->t_data);
+}
+
+PLAN *
+c_since(char ***argvp, int isok, char *opt)
+{
+ char *arg = **argvp;
+ PLAN *new;
+
+ (*argvp)++;
+ ftsoptions &= ~FTS_NOSTAT;
+
+ new = palloc(N_SINCE, f_since);
+ new->t_data = find_parsedate(new, opt, arg);
+ new->flags = F_GREATER;
+ return (new);
+}
+
+/*
* -size n[c] functions --
*
* True if the file size in bytes, divided by an implementation defined
@@ -1633,7 +1748,7 @@ f_size(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_size(char ***argvp, int isok)
+c_size(char ***argvp, int isok, char *opt)
{
char *arg = **argvp;
PLAN *new;
@@ -1644,7 +1759,7 @@ c_size(char ***argvp, int isok)
new = palloc(N_SIZE, f_size);
endch = 'c';
- new->o_data = find_parsenum(new, "-size", arg, &endch);
+ new->o_data = find_parsenum(new, opt, arg, &endch);
if (endch == 'c')
divsize = 0;
return (new);
@@ -1665,7 +1780,7 @@ f_type(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_type(char ***argvp, int isok)
+c_type(char ***argvp, int isok, char *opt)
{
char *typestring = **argvp;
PLAN *new;
@@ -1706,7 +1821,7 @@ c_type(char ***argvp, int isok)
break;
#endif /* S_IFWHT */
default:
- errx(1, "-type: %s: unknown type", typestring);
+ errx(1, "%s: %s: unknown type", opt, typestring);
}
new = palloc(N_TYPE, f_type);
@@ -1729,7 +1844,7 @@ f_user(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_user(char ***argvp, int isok)
+c_user(char ***argvp, int isok, char *opt)
{
char *username = **argvp;
PLAN *new;
@@ -1744,8 +1859,8 @@ c_user(char ***argvp, int isok)
if (p == NULL) {
if (atoi(username) == 0 && username[0] != '0' &&
strcmp(username, "+0") && strcmp(username, "-0"))
- errx(1, "-user: %s: no such user", username);
- uid = find_parsenum(new, "-user", username, NULL);
+ errx(1, "%s: %s: no such user", opt, username);
+ uid = find_parsenum(new, opt, username, NULL);
} else {
new->flags = F_EQUAL;
@@ -1763,7 +1878,7 @@ c_user(char ***argvp, int isok)
* different device ID (st_dev, see stat() S5.6.2 [POSIX.1])
*/
PLAN *
-c_xdev(char ***argvp, int isok)
+c_xdev(char ***argvp, int isok, char *opt)
{
ftsoptions |= FTS_XDEV;
@@ -1793,14 +1908,14 @@ f_expr(PLAN *plan, FTSENT *entry)
* to a N_EXPR node containing the expression and the ')' node is discarded.
*/
PLAN *
-c_openparen(char ***argvp, int isok)
+c_openparen(char ***argvp, int isok, char *opt)
{
return (palloc(N_OPENPAREN, (int (*)(PLAN *, FTSENT *))-1));
}
PLAN *
-c_closeparen(char ***argvp, int isok)
+c_closeparen(char ***argvp, int isok, char *opt)
{
return (palloc(N_CLOSEPAREN, (int (*)(PLAN *, FTSENT *))-1));
@@ -1824,7 +1939,7 @@ f_not(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_not(char ***argvp, int isok)
+c_not(char ***argvp, int isok, char *opt)
{
return (palloc(N_NOT, f_not));
@@ -1855,14 +1970,14 @@ f_or(PLAN *plan, FTSENT *entry)
}
PLAN *
-c_or(char ***argvp, int isok)
+c_or(char ***argvp, int isok, char *opt)
{
return (palloc(N_OR, f_or));
}
PLAN *
-c_null(char ***argvp, int isok)
+c_null(char ***argvp, int isok, char *opt)
{
return (NULL);
Index: option.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/option.c,v
retrieving revision 1.26
diff -u -p -r1.26 option.c
--- option.c 6 Feb 2007 15:33:22 -0000 1.26
+++ option.c 12 Jun 2016 00:30:16 -0000
@@ -64,9 +64,11 @@ static OPTION const options[] = {
{ "-amin", N_AMIN, c_amin, 1 },
{ "-and", N_AND, c_null, 0 },
{ "-anewer", N_ANEWER, c_anewer, 1 },
+ { "-asince", N_ASINCE, c_asince, 1 },
{ "-atime", N_ATIME, c_atime, 1 },
{ "-cmin", N_CMIN, c_cmin, 1 },
{ "-cnewer", N_CNEWER, c_cnewer, 1 },
+ { "-csince", N_CSINCE, c_csince, 1 },
{ "-ctime", N_CTIME, c_ctime, 1 },
{ "-delete", N_DELETE, c_delete, 0 },
{ "-depth", N_DEPTH, c_depth, 0 },
@@ -91,6 +93,38 @@ static OPTION const options[] = {
{ "-mtime", N_MTIME, c_mtime, 1 },
{ "-name", N_NAME, c_name, 1 },
{ "-newer", N_NEWER, c_newer, 1 },
+
+/* Aliases for compatability with Gnu findutils */
+ { "-neweraa", N_ANEWER, c_anewer, 1 },
+ { "-newerat", N_ASINCE, c_asince, 1 },
+ { "-newercc", N_CNEWER, c_cnewer, 1 },
+ { "-newerct", N_CSINCE, c_csince, 1 },
+ { "-newermm", N_NEWER, c_newer, 1 },
+ { "-newermt", N_SINCE, c_since, 1 },
+
+/*
+ * Unimplemented Gnu findutils options
+ *
+ * If you implement any of these, be sure to re-sort the table
+ * in ascii(7) order!
+ *
+ { "-newerBB", N_UNIMPL, c_unimpl, 1 },
+ { "-newerBa", N_UNIMPL, c_unimpl, 1 },
+ { "-newerBc", N_UNIMPL, c_unimpl, 1 },
+ { "-newerBm", N_UNIMPL, c_unimpl, 1 },
+ { "-newerBt", N_UNIMPL, c_unimpl, 1 },
+ { "-neweraB", N_UNIMPL, c_unimpl, 1 },
+ { "-newerac", N_UNIMPL, c_unimpl, 1 },
+ { "-neweram", N_UNIMPL, c_unimpl, 1 },
+ { "-newerca", N_UNIMPL, c_unimpl, 1 },
+ { "-newercm", N_UNIMPL, c_unimpl, 1 },
+ { "-newercB", N_UNIMPL, c_unimpl, 1 },
+ { "-newermB", N_UNIMPL, c_unimpl, 1 },
+ { "-newerma", N_UNIMPL, c_unimpl, 1 },
+ { "-newermc", N_UNIMPL, c_unimpl, 1 },
+ *
+ */
+
{ "-nogroup", N_NOGROUP, c_nogroup, 0 },
{ "-nouser", N_NOUSER, c_nouser, 0 },
{ "-o", N_OR, c_or, 0 },
@@ -104,6 +138,7 @@ static OPTION const options[] = {
{ "-prune", N_PRUNE, c_prune, 0 },
{ "-regex", N_REGEX, c_regex, 1 },
{ "-rm", N_DELETE, c_delete, 0 },
+ { "-since", N_SINCE, c_since, 1 },
{ "-size", N_SIZE, c_size, 1 },
{ "-type", N_TYPE, c_type, 1 },
{ "-user", N_USER, c_user, 1 },
@@ -124,16 +159,18 @@ find_create(char ***argvp)
OPTION *p;
PLAN *new;
char **argv;
+ char *opt;
argv = *argvp;
+ opt = *argv;
- if ((p = option(*argv)) == NULL)
- errx(1, "%s: unknown option", *argv);
+ if ((p = option(opt)) == NULL)
+ errx(1, "%s: unknown option", opt);
++argv;
if (p->arg && !*argv)
- errx(1, "%s: requires additional arguments", *--argv);
+ errx(1, "%s: requires additional arguments", opt);
- new = (p->create)(&argv, p->token == N_OK);
+ new = (p->create)(&argv, p->token == N_OK, opt);
*argvp = argv;
return (new);
Home |
Main Index |
Thread Index |
Old Index