| Summary: | New FIND(1) option | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Nils M Holm <nmh> | ||||
| Component: | bin | Assignee: | ru <ru> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.2-RELEASE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
Nils M Holm
2001-09-04 13:50:01 UTC
Nils M Holm <nmh@t3x.org> wrote: > >Description: > > I have added the -nt (newer than) option to FIND(1) which > allows to search for files with at least/at most a given age. > For example, > > find . -nt 5h30m > > will list files with an age of at least 5 hours and 30 minutes. > > I use this option for cleaning up spool directories. > > Man pages are updated. We have this in -current: -newer file True if the current file has a more recent last modification time than file. On Tue, Sep 04, 2001 at 02:45:11PM +0200, Nils M Holm wrote: > > I have added the -nt (newer than) option to FIND(1) which > allows to search for files with at least/at most a given age. > For example, > > find . -nt 5h30m > > will list files with an age of at least 5 hours and 30 minutes. > > I use this option for cleaning up spool directories. > > Man pages are updated. > What do you think of just extending the -mtime functionality so that it accepts time units in hours and minutes? Then the above would be equivalent to: find . ! -mtime +5h30m Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age Dima Dorfman <dima@unixfreak.org> wrote: > The following reply was made to PR bin/30309; it has been noted by GNATS. > > From: Dima Dorfman <dima@unixfreak.org> > To: nmh@t3x.org > Cc: FreeBSD-gnats-submit@freebsd.org > Subject: Re: bin/30309: New FIND(1) option > Date: Tue, 04 Sep 2001 05:58:10 -0700 > > Nils M Holm <nmh@t3x.org> wrote: > > >Description: > > > > I have added the -nt (newer than) option to FIND(1) which > > allows to search for files with at least/at most a given age. > > For example, > > > > find . -nt 5h30m > > > > will list files with an age of at least 5 hours and 30 minutes. > > > > I use this option for cleaning up spool directories. > > > > Man pages are updated. > > We have this in -current: > > -newer file > True if the current file has a more recent last modification time > than file. Actually, as ru@ pointed out, what you propose is more like -mtime, except that the latter doesn't support units. Sorry about that. On Tue, Sep 04, 2001 at 04:12:10PM +0300, Peter Pentchev wrote: > On Tue, Sep 04, 2001 at 06:10:01AM -0700, Ruslan Ermilov wrote: > > The following reply was made to PR bin/30309; it has been noted by GNATS. > > > > From: Ruslan Ermilov <ru@FreeBSD.ORG> > > To: Nils M Holm <nmh@t3x.org> > > Cc: FreeBSD-gnats-submit@FreeBSD.ORG > > Subject: Re: bin/30309: New FIND(1) option > > Date: Tue, 4 Sep 2001 15:59:30 +0300 > > > > On Tue, Sep 04, 2001 at 02:45:11PM +0200, Nils M Holm wrote: > > > > > > I have added the -nt (newer than) option to FIND(1) which > > > allows to search for files with at least/at most a given age. > > > For example, > > > > > > find . -nt 5h30m > > > > > > will list files with an age of at least 5 hours and 30 minutes. > > > > > > I use this option for cleaning up spool directories. > > > > > > Man pages are updated. > > > > > What do you think of just extending the -mtime functionality > > so that it accepts time units in hours and minutes? Then the > > above would be equivalent to: > > > > find . ! -mtime +5h30m > > I was considering such a reply; however, it would seem that > the semantics of the -[acm]time option are not quite the same > as those of the proposed -nt option; -[acm]time only returns > true if the time of the file is *exactly* so many days old; > -nt would return true if the file was *at most* so many days old. > Don't you see the plus (``+'') sign above? : All primaries which take a numeric argument allow the number : to be preceded by a plus sign (``+'') or a minus sign (``-''). : A preceding plus sign means ``more than n'', a preceding minus : sign means ``less than n'' and neither means ``exactly n''. -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age On Tue, 4 Sep 2001, Ruslan Ermilov wrote: > What do you think of just extending the -mtime functionality > so that it accepts time units in hours and minutes? Then the > above would be equivalent to: > > find . ! -mtime +5h30m Sounds like a good idea. I'll probably do that as soon as I find the time. Nils. -- Nils M Holm <nmh@t3x.org> -- http://www.t3x.org PLEASE ask before sending attachments >10K bytes. > On Tue, Sep 04, 2001 at 02:45:11PM +0200, Nils M Holm wrote: > [...] > What do you think of just extending the -mtime functionality > so that it accepts time units in hours and minutes? I have extended the -mtime (and -ctime, -atime) syntax to accept units, as suggested. In addition to hours and minutes, it also accepts seconds, days, weeks, months, and years. When no units are specified, the original semantics are used. Man pages are updated (but should be proof-read). I still haven't figured out how to send proper follow-up's to bug reports, so I send the new diff as a reply. Nils. -----[ diff follows ]----- diff -u /usr/src/usr.bin/find.old/find.1 /usr/src/usr.bin/find/find.1 --- /usr/src/usr.bin/find.old/find.1 Tue Sep 4 14:07:04 2001 +++ /usr/src/usr.bin/find/find.1 Thu Sep 6 15:04:54 2001 @@ -420,6 +420,40 @@ preceded by a plus sign (``+'') or a minus sign (``\-''). A preceding plus sign means ``more than n'', a preceding minus sign means ``less than n'' and neither means ``exactly n'' . +.Pp +The +.Ic -atime , +.Ic -ctime , +and +.Ic -mtime +primaries support the following units: +.Pp +.Bl -tag -width flag -offset indent -compact +.It Cm s +seconds +.It Cm m +minutes (60s) +.It Cm h +hours (60m) +.It Cm D +days (24h) +.It Cm W +weeks (7D) +.It Cm M +months (30D) +.It Cm Y +months (365Y) +.El +.Pp +When a unit is specified, the primaries do not round their argument +values. Hence +.Ic -mtime Ar +1 +is not euqal to +.Ic -mtime Ar +1D . +Units are most useful when used together with the ``+'' and ``-'' +modifiers. For example, +.Ic -mtime Ar +5m30s +is true for all files which are at least 5 minutes and 30 seconds old. .Sh OPERATORS The primaries may be combined using the following operators. The operators are listed in order of decreasing precedence. diff -u /usr/src/usr.bin/find.old/find.h /usr/src/usr.bin/find/find.h --- /usr/src/usr.bin/find.old/find.h Tue Sep 4 14:07:04 2001 +++ /usr/src/usr.bin/find/find.h Thu Sep 6 14:39:25 2001 @@ -64,6 +64,7 @@ #define F_ANY 2 /* perm */ int flags; /* private flags */ enum ntype type; /* plan node type */ + int t_units; /* time units flag */ union { gid_t _g_data; /* gid */ ino_t _i_data; /* inode */ diff -u /usr/src/usr.bin/find.old/function.c /usr/src/usr.bin/find/function.c --- /usr/src/usr.bin/find.old/function.c Tue Sep 4 14:07:04 2001 +++ /usr/src/usr.bin/find/function.c Thu Sep 6 14:52:09 2001 @@ -58,6 +58,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #include <unistd.h> #include "find.h" @@ -121,6 +122,86 @@ } /* + * find_parsetime -- + * Parse a string of the form [+-]([0-9][hmsYMWD])* and return the value. + */ +static time_t +find_parsetime(plan, option, vp) + PLAN *plan; + char *option, *vp; +{ + time_t nsec, a; + char *s; + + /* Determine comparison from leading + or -. */ + s = vp; + switch (*s) { + case '+': + ++s; + plan->flags = F_GREATER; + break; + case '-': + ++s; + plan->flags = F_LESSTHAN; + break; + default: + plan->flags = F_EQUAL; + break; + } + + if (!isdigit(*s)) + errx(1, "%s: %s: illegal time value", option, vp); + + plan->t_units = 0; + nsec = 0L; + a = 0L; + for (; *s; s++) { + if (isdigit(*s)) { + a = a*10L + *s-'0'; + } + else if (*s == 's') { /* seconds */ + nsec += a; + a = 0L; + plan->t_units = 1; + } + else if (*s == 'm') { /* minutes */ + nsec += a*60L; + a = 0L; + plan->t_units = 1; + } + else if (*s == 'h') { /* hours */ + nsec += a*3600L; + a = 0L; + plan->t_units = 1; + } + else if (*s == 'D') { /* days */ + nsec += a*86400L; + a = 0L; + plan->t_units = 1; + } + else if (*s == 'W') { /* weeks */ + nsec += a*604800L; + a = 0L; + plan->t_units = 1; + } + else if (*s == 'M') { /* months (30D)*/ + nsec += a*2592000L; + a = 0L; + plan->t_units = 1; + } + else if (*s == 'Y') { /* years (365D)*/ + nsec += a*31536000L; + a = 0L; + plan->t_units = 1; + } + else { + errx(1, "%s: %s: bad unit", option, vp); + } + } + return nsec+a; +} + +/* * 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 @@ -175,8 +256,13 @@ { extern time_t now; - COMPARE((now - entry->fts_statp->st_atime + - 86400 - 1) / 86400, plan->t_data); + if (plan->t_units) { + COMPARE(now - entry->fts_statp->st_atime, plan->t_data); + } + else { + COMPARE((now - entry->fts_statp->st_atime + + 86400 - 1) / 86400, plan->t_data); + } } PLAN * @@ -188,7 +274,7 @@ ftsoptions &= ~FTS_NOSTAT; new = palloc(N_ATIME, f_atime); - new->t_data = find_parsenum(new, "-atime", arg, NULL); + new->t_data = find_parsetime(new, "-atime", arg); TIME_CORRECT(new, N_ATIME); return (new); } @@ -238,8 +324,13 @@ { extern time_t now; - COMPARE((now - entry->fts_statp->st_ctime + - 86400 - 1) / 86400, plan->t_data); + if (plan->t_units) { + COMPARE(now - entry->fts_statp->st_ctime, plan->t_data); + } + else { + COMPARE((now - entry->fts_statp->st_ctime + + 86400 - 1) / 86400, plan->t_data); + } } PLAN * @@ -251,7 +342,7 @@ ftsoptions &= ~FTS_NOSTAT; new = palloc(N_CTIME, f_ctime); - new->t_data = find_parsenum(new, "-ctime", arg, NULL); + new->t_data = find_parsetime(new, "-ctime", arg); TIME_CORRECT(new, N_CTIME); return (new); } @@ -792,8 +883,13 @@ { extern time_t now; - COMPARE((now - entry->fts_statp->st_mtime + 86400 - 1) / - 86400, plan->t_data); + if (plan->t_units) { + COMPARE(now - entry->fts_statp->st_mtime, plan->t_data); + } + else { + COMPARE((now - entry->fts_statp->st_mtime + + 86400 - 1) / 86400, plan->t_data); + } } PLAN * @@ -805,7 +901,7 @@ ftsoptions &= ~FTS_NOSTAT; new = palloc(N_MTIME, f_mtime); - new->t_data = find_parsenum(new, "-mtime", arg, NULL); + new->t_data = find_parsetime(new, "-mtime", arg); TIME_CORRECT(new, N_MTIME); return (new); } -------------------------- -- Nils M Holm <nmh@t3x.org> -- http://www.t3x.org PLEASE ask before sending attachments >10K bytes. On Thu, Sep 06, 2001 at 03:17:48PM +0200, Nils M Holm wrote: > > On Tue, Sep 04, 2001 at 02:45:11PM +0200, Nils M Holm wrote: > > [...] > > What do you think of just extending the -mtime functionality > > so that it accepts time units in hours and minutes? > > I have extended the -mtime (and -ctime, -atime) syntax to accept units, > as suggested. In addition to hours and minutes, it also accepts seconds, > days, weeks, months, and years. > > When no units are specified, the original semantics are used. > Uh oh, this already applies to 4.2-RELEASE sources, which have since been heavily modified in -CURRENT and -STABLE. How about the following patch instead (without the manpage bit)? Index: find.h =================================================================== RCS file: /home/ncvs/src/usr.bin/find/find.h,v retrieving revision 1.12 diff -u -p -r1.12 find.h --- find.h 2001/09/04 16:09:01 1.12 +++ find.h 2001/09/06 17:04:29 @@ -69,6 +69,7 @@ typedef struct _plandata *creat_f(struct #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 { Index: function.c =================================================================== RCS file: /home/ncvs/src/usr.bin/find/function.c,v retrieving revision 1.33 diff -u -p -r1.33 function.c --- function.c 2001/09/04 16:09:01 1.33 +++ function.c 2001/09/06 17:04:31 @@ -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 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; } Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age On Thu, 6 Sep 2001, Ruslan Ermilov wrote: > Uh oh, this already applies to 4.2-RELEASE sources, which have > since been heavily modified in -CURRENT and -STABLE. I would have loved to patch the 4.3 sources instead, but I am still waiting for my CDROM from the subscription. Well, time for another complaint... > How about the following patch instead (without the manpage bit)? Looks good. Removing YM and replacing DW with dw is a nice idea. Nils. -- Nils M Holm <nmh@t3x.org> -- http://www.t3x.org PLEASE ask before sending attachments >10K bytes. On Thu, Sep 06, 2001 at 08:46:46PM +0200, Nils M Holm wrote: > On Thu, 6 Sep 2001, Ruslan Ermilov wrote: > > Uh oh, this already applies to 4.2-RELEASE sources, which have > > since been heavily modified in -CURRENT and -STABLE. > > I would have loved to patch the 4.3 sources instead, but I am still > waiting for my CDROM from the subscription. Well, time for another > complaint... > > > How about the following patch instead (without the manpage bit)? > > Looks good. Removing YM and replacing DW with dw is a nice idea. > I have removed Y and M because they are not exact. Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age On Fri, 7 Sep 2001, Ruslan Ermilov wrote: > I have removed Y and M because they are not exact. Good point, too. I may have removed them for esthetic reasons. Nils. -- Nils M Holm <nmh@t3x.org> -- http://www.t3x.org PLEASE ask before sending attachments >10K bytes. State Changed From-To: open->closed An adopted patch committed to 5.0-CURRENT, thanks! Responsible Changed From-To: freebsd-bugs->ru |