summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/find/find.167
-rw-r--r--usr.bin/find/find.h1
-rw-r--r--usr.bin/find/function.c116
3 files changed, 166 insertions, 18 deletions
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 5945d58e7bee..0c7d3d2cd720 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -170,12 +170,44 @@ minutes.
.It Ic -anewer Ar file
Same as
.Ic -neweram .
-.It Ic -atime Ar n
-True if the difference between the file last access time and the time
+.It Ic -atime Ar n Ns Op Cm smhdw
+If no units are specified, this primary evaluates to
+true if the difference between the file last access time and the time
.Nm
was started, rounded up to the next full 24\-hour period, is
.Ar n
24\-hour periods.
+.Pp
+If units are specified, this primary evaluates to
+true if the difference between the file last access time and the time
+.Nm
+was started is exactly
+.Ar n
+units.
+Possible time units are as follows:
+.Pp
+.Bl -tag -width indent -compact
+.It Cm s
+second
+.It Cm m
+minute (60 seconds)
+.It Cm h
+hour (60 minutes)
+.It Cm d
+day (24 hours)
+.It Cm w
+week (7 days)
+.El
+.Pp
+Any number of units may be combined in one
+.Ic -atime
+argument, for example,
+.Dq Li "-atime -1h30m" .
+Units are probably only useful when used in conjunction with the
+.Cm +
+or
+.Cm -
+modifier.
.It Ic -cmin Ar n
True if the difference between the time of last change of file status
information and the time
@@ -186,13 +218,25 @@ minutes.
.It Ic -cnewer Ar file
Same as
.Ic -newercm .
-.It Ic -ctime Ar n
-True if the difference between the time of last change of file status
+.It Ic -ctime Ar n Ns Op Cm smhdw
+If no units are specified, this primary evaluates to
+true if the difference between the time of last change of file status
information and the time
.Nm
was started, rounded up to the next full 24\-hour period, is
.Ar n
24\-hour periods.
+.Pp
+If units are specified, this primary evaluates to
+true if the difference between the time of last change of file status
+information and the time
+.Nm
+was started is exactly
+.Ar n
+units.
+Please refer to the
+.Ic -atime
+primary description for information on supported time units.
.It Ic -delete
Delete found files and/or directories.
Always returns true.
@@ -362,12 +406,23 @@ minutes.
.It Ic -mnewer Ar file
Same as
.Ic -newer .
-.It Ic -mtime Ar n
-True if the difference between the file last modification time and the time
+.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
.Nm
was started, rounded up to the next full 24\-hour period, is
.Ar n
24\-hour periods.
+.Pp
+If units are specified, this primary evaluates to
+true if the difference between the file last modification time and the time
+.Nm
+was started is exactly
+.Ar n
+units.
+Please refer to the
+.Ic -atime
+primary description for information on supported time units.
.It Ic -name Ar pattern
True if the last component of the pathname being examined matches
.Ar pattern .
diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h
index b2c73c305875..77b37a7ee83e 100644
--- a/usr.bin/find/find.h
+++ b/usr.bin/find/find.h
@@ -69,6 +69,7 @@ typedef struct _plandata *creat_f(struct _option *, char ***);
#define F_MTTYPE 0x00001000
#define F_MTUNKNOWN 0x00002000
#define F_IGNCASE 0x00010000 /* iname ipath iregex */
+#define F_EXACTTIME F_IGNCASE /* -[acm]time units syntax */
/* node definition */
typedef struct _plandata {
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index a729ca7ef59f..b477f20cf5e5 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -67,7 +67,7 @@ static const char rcsid[] =
time_t get_date __P((char *date, struct timeb *now));
-#define COMPARE(a, b) { \
+#define COMPARE(a, b) do { \
switch (plan->flags & F_ELG_MASK) { \
case F_EQUAL: \
return (a == b); \
@@ -78,7 +78,7 @@ time_t get_date __P((char *date, struct timeb *now));
default: \
abort(); \
} \
-}
+} while(0)
static PLAN *
palloc(option)
@@ -138,6 +138,82 @@ find_parsenum(plan, option, vp, endch)
}
/*
+ * find_parsetime --
+ * Parse a string of the form [+-]([0-9]+[smhdw]?)+ and return the value.
+ */
+static long long
+find_parsetime(plan, option, vp)
+ PLAN *plan;
+ char *option, *vp;
+{
+ long long secs, value;
+ char *str, *unit; /* Pointer to character ending conversion. */
+
+ /* Determine comparison from leading + or -. */
+ str = vp;
+ switch (*str) {
+ case '+':
+ ++str;
+ plan->flags |= F_GREATER;
+ break;
+ case '-':
+ ++str;
+ plan->flags |= F_LESSTHAN;
+ break;
+ default:
+ plan->flags |= F_EQUAL;
+ break;
+ }
+
+ value = strtoq(str, &unit, 10);
+ if (value == 0 && unit == str) {
+ errx(1, "%s: %s: illegal time value", option, vp);
+ /* NOTREACHED */
+ }
+ if (*unit == '\0')
+ return value;
+
+ /* Units syntax. */
+ secs = 0;
+ for (;;) {
+ switch(*unit) {
+ case 's': /* seconds */
+ secs += value;
+ break;
+ case 'm': /* minutes */
+ secs += value * 60;
+ break;
+ case 'h': /* hours */
+ secs += value * 3600;
+ break;
+ case 'd': /* days */
+ secs += value * 86400;
+ break;
+ case 'w': /* weeks */
+ secs += value * 604800;
+ break;
+ default:
+ errx(1, "%s: %s: bad unit '%c'", option, vp, *unit);
+ /* NOTREACHED */
+ }
+ str = unit + 1;
+ if (*str == '\0') /* EOS */
+ break;
+ value = strtoq(str, &unit, 10);
+ if (value == 0 && unit == str) {
+ errx(1, "%s: %s: illegal time value", option, vp);
+ /* NOTREACHED */
+ }
+ if (*unit == '\0') {
+ errx(1, "%s: %s: missing trailing unit", option, vp);
+ /* NOTREACHED */
+ }
+ }
+ plan->flags |= F_EXACTTIME;
+ return secs;
+}
+
+/*
* nextarg --
* Check that another argument still exists, return a pointer to it,
* and increment the argument vector pointer.
@@ -226,16 +302,31 @@ f_Xtime(plan, entry)
FTSENT *entry;
{
extern time_t now;
+ int exact_time;
+
+ exact_time = plan->flags & F_EXACTTIME;
if (plan->flags & F_TIME_C) {
- COMPARE((now - entry->fts_statp->st_ctime +
- 86400 - 1) / 86400, plan->t_data);
+ if (exact_time)
+ COMPARE(now - entry->fts_statp->st_ctime,
+ plan->t_data);
+ else
+ COMPARE((now - entry->fts_statp->st_ctime +
+ 86400 - 1) / 86400, plan->t_data);
} else if (plan->flags & F_TIME_A) {
- COMPARE((now - entry->fts_statp->st_atime +
- 86400 - 1) / 86400, plan->t_data);
+ if (exact_time)
+ COMPARE(now - entry->fts_statp->st_atime,
+ plan->t_data);
+ else
+ COMPARE((now - entry->fts_statp->st_atime +
+ 86400 - 1) / 86400, plan->t_data);
} else {
- COMPARE((now - entry->fts_statp->st_mtime +
- 86400 - 1) / 86400, plan->t_data);
+ if (exact_time)
+ COMPARE(now - entry->fts_statp->st_mtime,
+ plan->t_data);
+ else
+ COMPARE((now - entry->fts_statp->st_mtime +
+ 86400 - 1) / 86400, plan->t_data);
}
}
@@ -244,15 +335,16 @@ c_Xtime(option, argvp)
OPTION *option;
char ***argvp;
{
- char *ndays;
+ char *value;
PLAN *new;
- ndays = nextarg(option, argvp);
+ value = nextarg(option, argvp);
ftsoptions &= ~FTS_NOSTAT;
new = palloc(option);
- new->t_data = find_parsenum(new, option->name, ndays, NULL);
- TIME_CORRECT(new);
+ new->t_data = find_parsetime(new, option->name, value);
+ if (!(new->flags & F_EXACTTIME))
+ TIME_CORRECT(new);
return new;
}