Partial merge with recent revisions[1] from FreeBSD.
authorChris Pressey <cpressey@dragonflybsd.org>
Sun, 13 Feb 2005 23:49:53 +0000 (23:49 +0000)
committerChris Pressey <cpressey@dragonflybsd.org>
Sun, 13 Feb 2005 23:49:53 +0000 (23:49 +0000)
Highlights:
- Use a larger field for the size in blocks; the current width
  (4 digits) is only good for 5 MB.
- Introduce a new primary `-depth n', which tests whether
  the depth of the current file relative to the starting
  point of the traversal is n. The usual +/- modifiers
  to the argument apply.
- Support SysV-style -exec args {} + function, required by SUSv3.
- Remove partial support for building on NetBSD.
- Lots of style(9) work.
- Update manual page.

Features not merged:
- The -acl option for locating files with extended ACLs.

Submitted-by: Alexander 'alxl' Lobachov <alxl_at_alxl_dot_info>
[1] Makefile:1.17 extern.h:1.22 find.1:1.71 find.c:1.17 find.h:1.17
    function.c:1.52 getdate.y:1.3 ls.c:1.17 main.c:1.15 misc.c:1.7
    operator.c:1.14 option.c:1.23

12 files changed:
usr.bin/find/Makefile
usr.bin/find/extern.h
usr.bin/find/find.1
usr.bin/find/find.c
usr.bin/find/find.h
usr.bin/find/function.c
usr.bin/find/getdate.y
usr.bin/find/ls.c
usr.bin/find/main.c
usr.bin/find/misc.c
usr.bin/find/operator.c
usr.bin/find/option.c

index 58af531..e16a345 100644 (file)
@@ -1,10 +1,12 @@
 #      @(#)Makefile    8.1 (Berkeley) 6/6/93
-# $FreeBSD: src/usr.bin/find/Makefile,v 1.8.2.5 2003/01/22 03:26:34 peter Exp $
-# $DragonFly: src/usr.bin/find/Makefile,v 1.2 2003/06/17 04:29:26 dillon Exp $
+# $FreeBSD: src/usr.bin/find/Makefile,v 1.17 2002/04/15 19:27:41 obrien Exp $
+# $DragonFly: src/usr.bin/find/Makefile,v 1.3 2005/02/13 23:49:53 cpressey Exp $
 
-CFLAGS+=-Wall
 PROG=  find
-SRCS=  find.c function.c ls.c main.c misc.c operator.c option.c getdate.y
+SRCS=  find.c function.c ls.c main.c misc.c operator.c option.c \
+       getdate.y
+WARNS?=2
+CFLAGS+= -DHAVE_SYS_TIMEB_H -I${.CURDIR}
 YFLAGS=
 
 .include <bsd.prog.mk>
index 4a97dc4..b59a021 100644 (file)
  * SUCH DAMAGE.
  *
  *     @(#)extern.h    8.3 (Berkeley) 4/16/94
- *     $FreeBSD: src/usr.bin/find/extern.h,v 1.9.2.4 2001/05/06 09:53:22 phk Exp $
- *     $DragonFly: src/usr.bin/find/extern.h,v 1.3 2003/11/03 19:31:29 eirikn Exp $
+ *     $FreeBSD: src/usr.bin/find/extern.h,v 1.22 2004/07/29 03:29:44 tjr Exp $
+ *     $DragonFly: src/usr.bin/find/extern.h,v 1.4 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/cdefs.h>
 
 void    brace_subst(char *, char **, char *, int);
-void   *emalloc(unsigned int);
 PLAN   *find_create(char ***);
 int     find_execute(PLAN *, char **);
 PLAN   *find_formplan(char **);
 PLAN   *not_squish(PLAN *);
 PLAN   *or_squish(PLAN *);
 PLAN   *paren_squish(PLAN *);
+struct timeb;
+time_t  get_date(char *, struct timeb *);
 struct stat;
 void    printlong(char *, char *, struct stat *);
 int     queryuser(char **);
-OPTION *option(char *);
+OPTION *lookup_option(const char *);
 
 creat_f        c_Xmin;
 creat_f        c_Xtime;
@@ -59,9 +60,7 @@ creat_f       c_empty;
 creat_f        c_exec;
 creat_f        c_flags;
 creat_f        c_follow;
-#if !defined(__NetBSD__)
 creat_f        c_fstype;
-#endif
 creat_f        c_group;
 creat_f        c_inum;
 creat_f        c_links;
@@ -85,6 +84,7 @@ exec_f        f_Xtime;
 exec_f f_always_true;
 exec_f f_closeparen;
 exec_f f_delete;
+exec_f f_depth;
 exec_f f_empty;
 exec_f f_exec;
 exec_f f_expr;
@@ -114,3 +114,6 @@ exec_f      f_user;
 extern int ftsoptions, isdeprecated, isdepth, isoutput, issort, isxargs;
 extern int mindepth, maxdepth;
 extern int regexp_flags;
+extern time_t now;
+extern int dotfd;
+extern FTS *tree;
index a8fde91..e535167 100644 (file)
@@ -1,3 +1,4 @@
+.\" Copyright (c) 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
 .\" This code is derived from software contributed to Berkeley by
@@ -32,8 +33,8 @@
 .\" SUCH DAMAGE.
 .\"
 .\"    @(#)find.1      8.7 (Berkeley) 5/9/95
-.\" $FreeBSD: src/usr.bin/find/find.1,v 1.23.2.20 2003/02/25 20:31:18 trhodes Exp $
-.\" $DragonFly: src/usr.bin/find/find.1,v 1.2 2003/06/17 04:29:26 dillon Exp $
+.\" $FreeBSD: src/usr.bin/find/find.1,v 1.71 2005/01/11 10:32:51 ru Exp $
+.\" $DragonFly: src/usr.bin/find/find.1,v 1.3 2005/02/13 23:49:53 cpressey Exp $
 .\"
 .Dd May 3, 2001
 .Dt FIND 1
@@ -90,6 +91,10 @@ returned for each symbolic link to be those of the file referenced by the
 link, not the link itself.
 If the referenced file does not exist, the file information and type will
 be for the link itself.
+.Pp
+This option is equivalent to the deprecated
+.Ic -follow
+primary.
 .It Fl P
 Cause the file information and file type (see
 .Xr stat 2 )
@@ -120,15 +125,28 @@ as an effective alternative.
 .It Fl d
 Cause
 .Nm
-to perform a depth\-first traversal, i.e., directories
-are visited in post\-order and all entries in a directory will be acted
+to perform a depth-first traversal, i.e., directories
+are visited in post-order and all entries in a directory will be acted
 on before the directory itself.
 By default,
 .Nm
-visits directories in pre\-order, i.e., before their contents.
+visits directories in pre-order, i.e., before their contents.
 Note, the default is
 .Em not
-a breadth\-first traversal.
+a breadth-first traversal.
+.Pp
+This option is equivalent to the
+.Ic -depth
+primary of
+.St -p1003.1-2001 .
+.Fl d
+can be useful when
+.Nm
+is used with
+.Xr cpio 1
+to process files that are contained in directories with unusual permissions.
+It ensures that you have write permission while you are placing files in a
+directory, then sets the directory's permissions as the last thing.
 .It Fl f
 Specify a file hierarchy for
 .Nm
@@ -150,6 +168,10 @@ Prevent
 .Nm
 from descending into directories that have a device number different
 than that of the file from which the descent began.
+.Pp
+This option is equivalent to the deprecated
+.Ic -xdev
+primary.
 .El
 .Sh PRIMARIES
 .Bl -tag -width indent
@@ -166,9 +188,9 @@ Same as
 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
+was started, rounded up to the next full 24-hour period, is
 .Ar n
-24\-hour periods.
+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
@@ -215,9 +237,9 @@ 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
+was started, rounded up to the next full 24-hour period, is
 .Ar n
-24\-hour periods.
+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
@@ -241,23 +263,19 @@ It will not attempt to delete a filename with a
 character in its pathname relative to
 .Dq Pa \&.
 for security reasons.
-Depth\-first traversal processing is implied by this option.
+Depth-first traversal processing is implied by this option.
 .It Ic -depth
 Always true;
 same as the
 .Fl d
 option.
-.Ic -depth
-can be useful when
-.Nm
-is used with
-.Xr cpio 1
-to process files that are contained in directories with unusual permissions.
-It ensures that you have write permission while you are placing files in a
-directory, then sets the directory's permissions as the last thing.
+.It Ic -depth Ar n
+True if the depth of the file relative to the starting point of the traversal
+is
+.Ar n .
 .It Ic -empty
 True if the current file or directory is empty.
-.It Ic -exec Ar utility Op Ar argument ... ;
+.It Ic -exec Ar utility Oo Ar argument ... Oc Li \&;
 True if the program named
 .Ar utility
 returns a zero value as its exit status.
@@ -266,6 +284,10 @@ Optional
 may be passed to the utility.
 The expression must be terminated by a semicolon
 .Pq Dq Li \&; .
+If you invoke
+.Nm
+from a shell you may need to quote the semicolon if the shell would
+otherwise treat it as a control operator.
 If the string
 .Dq Li {}
 appears anywhere in the utility name or the
@@ -279,7 +301,16 @@ and
 .Ar arguments
 are not subject to the further expansion of shell patterns
 and constructs.
-.It Ic -execdir Ar utility Op Ar argument ... ;
+.It Ic -exec Ar utility Oo Ar argument ... Oc Li {} +
+Same as
+.Ic -exec ,
+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 -execdir Ar utility Oo Ar argument ... Oc Li \&;
 The
 .Ic -execdir
 primary is identical to the
@@ -385,11 +416,11 @@ links.
 .It Ic -ls
 This primary always evaluates to true.
 The following information for the current file is written to standard output:
-its inode number, size in 512\-byte blocks, file permissions, number of hard
+its inode number, size in 512-byte blocks, file permissions, number of hard
 links, owner, group, size in bytes, last modification time, and pathname.
 If the file is a block or character special file, the major and minor numbers
 will be displayed instead of the size in bytes.
-If the file is a symbolic link, the pathname of the linked\-to file will be
+If the file is a symbolic link, the pathname of the linked-to file will be
 displayed preceded by
 .Dq Li -> .
 The format is identical to that produced by
@@ -397,11 +428,24 @@ The format is identical to that produced by
 .Nm ls Fl dgils .
 .Ek
 .It Ic -maxdepth Ar n
-True if the depth of the current file into the tree is less than or equal to
-.Ar n .
+Always true; descend at most
+.Ar n
+directory levels below the command line arguments.
+If any
+.Ic -maxdepth
+primary is specified, it applies to the entire expression even if it would
+not normally be evaluated.
+.Ic -maxdepth Li 0
+limits the whole search to the command line arguments.
 .It Ic -mindepth Ar n
-True if the depth of the current file into the tree is greater than or equal to
+Always true; do not apply any tests or actions at levels less than
 .Ar n .
+If any
+.Ic -mindepth
+primary is specified, it applies to the entire expression even if it would
+not normally be evaluated.
+.Ic -mindepth Li 1
+processes all but the command line arguments.
 .It Ic -mmin Ar n
 True if the difference between the file last modification time and the time
 .Nm
@@ -415,9 +459,9 @@ Same as
 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
+was started, rounded up to the next full 24-hour period, is
 .Ar n
-24\-hour periods.
+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
@@ -492,7 +536,7 @@ the command is not executed and the
 value of the
 .Ic -ok
 expression is false.
-.It Ic -okdir Ar utility Op Ar argument ... ;
+.It Ic -okdir Ar utility Oo Ar argument ... Oc Li \&;
 The
 .Ic -okdir
 primary is identical to the
@@ -597,7 +641,7 @@ but not
 or
 .Dq Li /foo/ .
 .It Ic -size Ar n Ns Op Cm c
-True if the file's size, rounded up, in 512\-byte blocks is
+True if the file's size, rounded up, in 512-byte blocks is
 .Ar n .
 If
 .Ar n
@@ -715,10 +759,34 @@ Print out a list of all the files that are either owned by
 .Dq wnj
 or that are newer than
 .Pa ttt .
-.It Li "find . -newerct '1 minute ago' -print"
+.It Li "find / -newerct '1 minute ago' -print"
 Print out a list of all the files whose inode change time is more
 recent than the current time minus one minute.
+.It Li "find / -type f -exec echo {} \e;"
+Use the
+.Xr echo 1
+command to print out a list of all the files.
+.It Li "find -L /usr/ports/packages -type l -delete"
+Delete all broken symbolic links in
+.Pa /usr/ports/packages .
+.It Li "find /usr/src -name CVS -prune -o -depth +6 -print"
+Find files and directories that are at least seven levels deep
+in the working directory
+.Pa /usr/src .
+.It Li "find /usr/src -name CVS -prune -o -mindepth 7 -print"
+Is not equivalent to the previous example, since
+.Ic -prune
+is not evaluated below level seven.
 .El
+.Sh COMPATIBILITY
+The
+.Ic -follow
+primary is deprecated; the
+.Fl L
+option should be used instead.
+See the
+.Sx STANDARDS
+section below for details.
 .Sh SEE ALSO
 .Xr chflags 1 ,
 .Xr chmod 1 ,
@@ -738,18 +806,22 @@ recent than the current time minus one minute.
 The
 .Nm
 utility syntax is a superset of the syntax specified by the
-.St -p1003.2
+.St -p1003.1-2001
 standard.
 .Pp
-All the single character options as well as the
+All the single character options except
+.Ic -H
+and
+.Ic -L
+as well as the
 .Ic -iname , -inum , -iregex , -print0 , -delete , -ls ,
 and
 .Ic -regex
 primaries are extensions to
-.St -p1003.2 .
+.St -p1003.1-2001 .
 .Pp
 Historically, the
-.Fl d , h
+.Fl d , L
 and
 .Fl x
 options were implemented using the primaries
@@ -791,10 +863,16 @@ it appears.
 .Pp
 The
 .Fl E
-option was implemented on the analogy of
+option was inspired by the equivalent
 .Xr grep 1
 and
-.Xr sed 1 .
+.Xr sed 1
+options.
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v1 .
 .Sh BUGS
 The special characters used by
 .Nm
@@ -830,8 +908,11 @@ The
 .Ic -delete
 primary does not interact well with other options that cause the file system
 tree traversal options to be changed.
-.Sh HISTORY
-A
-.Nm
-command appeared in
-.At v1 .
+.Pp
+The
+.Ic -mindepth
+and
+.Ic -maxdepth
+primaries are actually global options (as documented above).
+They should
+probably be replaced by options which look like options.
index ed27b21..0e79ce0 100644 (file)
@@ -34,8 +34,8 @@
  * SUCH DAMAGE.
  *
  * @(#)find.c  8.5 (Berkeley) 8/5/94
- * $FreeBSD: src/usr.bin/find/find.c,v 1.7.6.3 2001/05/06 09:53:22 phk Exp $
- * $DragonFly: src/usr.bin/find/find.c,v 1.3 2003/10/04 20:36:44 hmp Exp $
+ * $FreeBSD: src/usr.bin/find/find.c,v 1.17 2004/05/28 17:17:15 eik Exp $
+ * $DragonFly: src/usr.bin/find/find.c,v 1.4 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/types.h>
 #include <fts.h>
 #include <regex.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "find.h"
 
-static int     find_compare(const FTSENT **s1, const FTSENT **s2);
+static int find_compare(const FTSENT * const *s1, const FTSENT * const *s2);
 
 /*
  * find_compare --
@@ -60,7 +60,7 @@ static int    find_compare(const FTSENT **s1, const FTSENT **s2);
  *     order within each directory.
  */
 static int
-find_compare(const FTSENT **s1, const FTSENT **s2)
+find_compare(const FTSENT * const *s1, const FTSENT * const *s2)
 {
 
        return (strcoll((*s1)->fts_name, (*s2)->fts_name));
@@ -72,7 +72,7 @@ find_compare(const FTSENT **s1, const FTSENT **s2)
  *     command arguments.
  */
 PLAN *
-find_formplan(char **argv)
+find_formplan(char *argv[])
 {
        PLAN *plan, *tail, *new;
 
@@ -110,23 +110,23 @@ find_formplan(char **argv)
         */
        if (!isoutput) {
                OPTION *p;
-               char **argv = 0;
+               char **argv1 = 0;
 
                if (plan == NULL) {
-                       p = option("-print");
-                       new = (p->create)(p, &argv);
+                       p = lookup_option("-print");
+                       new = (p->create)(p, &argv1);
                        tail = plan = new;
                } else {
-                       p = option("(");
-                       new = (p->create)(p, &argv);
+                       p = lookup_option("(");
+                       new = (p->create)(p, &argv1);
                        new->next = plan;
                        plan = new;
-                       p = option(")");
-                       new = (p->create)(p, &argv);
+                       p = lookup_option(")");
+                       new = (p->create)(p, &argv1);
                        tail->next = new;
                        tail = new;
-                       p = option("-print");
-                       new = (p->create)(p, &argv);
+                       p = lookup_option("-print");
+                       new = (p->create)(p, &argv1);
                        tail->next = new;
                        tail = new;
                }
@@ -167,14 +167,11 @@ FTS *tree;                        /* pointer to top of FTS hierarchy */
  * find_execute --
  *     take a search plan and an array of search paths and executes the plan
  *     over all FTSENT's returned for the given search paths.
- *
- * plan: search plan
- * paths: array of pathnames to traverse
  */
 int
-find_execute(PLAN *plan, char **paths)
+find_execute(PLAN *plan, char *paths[])
 {
-       register FTSENT *entry;
+       FTSENT *entry;
        PLAN *p;
        int rval;
 
@@ -183,6 +180,11 @@ find_execute(PLAN *plan, char **paths)
                err(1, "ftsopen");
 
        for (rval = 0; (entry = fts_read(tree)) != NULL;) {
+               if (maxdepth != -1 && entry->fts_level >= maxdepth) {
+                       if (fts_set(tree, entry, FTS_SKIP))
+                               err(1, "%s", entry->fts_path);
+               }
+
                switch (entry->fts_info) {
                case FTS_D:
                        if (isdepth)
@@ -222,13 +224,11 @@ find_execute(PLAN *plan, char **paths)
                 * the work specified by the user on the command line.
                 */
                for (p = plan; p && (p->execute)(p, entry); p = p->next);
-
-               if (maxdepth != -1 && entry->fts_level >= maxdepth) {
-                       if (fts_set(tree, entry, FTS_SKIP))
-                       err(1, "%s", entry->fts_path);
-                       continue;
-               }
        }
+       /* Finish any pending -exec ... {} + functions. */
+       for (p = plan; p != NULL; p = p->next)
+               if (p->execute == f_exec && p->flags & F_EXECPLUS)
+                       (p->execute)(p, NULL);
        if (errno)
                err(1, "fts_read");
        return (rval);
index 2059f73..5c293a1 100644 (file)
@@ -34,8 +34,8 @@
  * SUCH DAMAGE.
  *
  *     @(#)find.h      8.1 (Berkeley) 6/6/93
- *     $FreeBSD: src/usr.bin/find/find.h,v 1.6.2.7 2002/11/15 11:38:15 sheldonh Exp $
- *     $DragonFly: src/usr.bin/find/find.h,v 1.3 2003/11/03 19:31:29 eirikn Exp $
+ *     $FreeBSD: src/usr.bin/find/find.h,v 1.17 2004/05/28 17:17:15 eik Exp $
+ *     $DragonFly: src/usr.bin/find/find.h,v 1.4 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <regex.h>
@@ -58,6 +58,7 @@ typedef       struct _plandata *creat_f(struct _option *, char ***);
 #define        F_TIME2_C       0x00000020      /* one of -newer?c */
 #define        F_TIME2_T       0x00000040      /* one of -newer?t */
 #define F_MAXDEPTH     F_TIME_A        /* maxdepth vs. mindepth */
+#define F_DEPTH                F_TIME_A        /* -depth n vs. -d */
 /* command line function modifiers */
 #define        F_EQUAL         0x00000000      /* [acm]min [acm]time inum links size */
 #define        F_LESSTHAN      0x00000100
@@ -68,8 +69,10 @@ typedef      struct _plandata *creat_f(struct _option *, char ***);
 #define        F_MTMASK        0x00003000
 #define        F_MTFLAG        0x00000000      /* fstype */
 #define        F_MTTYPE        0x00001000
+#define        F_MTUNKNOWN     0x00002000
 #define        F_IGNCASE       0x00010000      /* iname ipath iregex */
 #define        F_EXACTTIME     F_IGNCASE       /* -[acm]time units syntax */
+#define F_EXECPLUS     0x00020000      /* -exec ... {} + */
 
 /* node definition */
 typedef struct _plandata {
@@ -85,6 +88,7 @@ typedef struct _plandata {
                        u_long _f_notflags;
                } fl;
                nlink_t _l_data;                /* link count */
+               short _d_data;                  /* level depth (-1 to N) */
                off_t _o_data;                  /* file size */
                time_t _t_data;                 /* time value */
                uid_t _u_data;                  /* uid */
@@ -94,6 +98,12 @@ typedef struct _plandata {
                        char **_e_argv;         /* argv array */
                        char **_e_orig;         /* original strings */
                        int *_e_len;            /* allocated length */
+                       int _e_pbnum;           /* base num. of args. used */
+                       int _e_ppos;            /* number of arguments used */
+                       int _e_pnummax;         /* max. number of arguments */
+                       int _e_psize;           /* number of bytes of args. */
+                       int _e_pbsize;          /* base num. of bytes of args */
+                       int _e_psizemax;        /* max num. of bytes of args */
                } ex;
                char *_a_data[2];               /* array of char pointers */
                char *_c_data;                  /* char pointer */
@@ -102,6 +112,7 @@ typedef struct _plandata {
 } PLAN;
 #define        a_data  p_un._a_data
 #define        c_data  p_un._c_data
+#define        d_data  p_un._d_data
 #define fl_flags       p_un.fl._f_flags
 #define fl_notflags    p_un.fl._f_notflags
 #define        g_data  p_un._g_data
@@ -117,9 +128,15 @@ typedef struct _plandata {
 #define        e_argv  p_un.ex._e_argv
 #define        e_orig  p_un.ex._e_orig
 #define        e_len   p_un.ex._e_len
+#define e_pbnum        p_un.ex._e_pbnum
+#define e_ppos p_un.ex._e_ppos
+#define e_pnummax p_un.ex._e_pnummax
+#define e_psize p_un.ex._e_psize
+#define e_pbsize p_un.ex._e_pbsize
+#define e_psizemax p_un.ex._e_psizemax
 
 typedef struct _option {
-       char *name;                     /* option name */
+       const char *name;               /* option name */
        creat_f *create;                /* create function */
        exec_f *execute;                /* execute function */
        int flags;
index d75dd05..3bb8177 100644 (file)
  * SUCH DAMAGE.
  *
  * @(#)function.c  8.10 (Berkeley) 5/4/95
- * $FreeBSD: src/usr.bin/find/function.c,v 1.22.2.11 2002/11/15 11:38:15 sheldonh Exp $
- * $DragonFly: src/usr.bin/find/function.c,v 1.4 2004/11/28 21:17:07 liamfoy Exp $
+ * $FreeBSD: src/usr.bin/find/function.c,v 1.52 2004/07/29 03:33:55 tjr Exp $
+ * $DragonFly: src/usr.bin/find/function.c,v 1.5 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/param.h>
 #include <sys/ucred.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/mount.h>
 #include <sys/timeb.h>
 #include <fnmatch.h>
 #include <fts.h>
 #include <grp.h>
+#include <limits.h>
 #include <pwd.h>
 #include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <ctype.h>
 
 #include "find.h"
 
-time_t get_date (char *date, struct timeb *now);
+static PLAN *palloc(OPTION *);
+static long long find_parsenum(PLAN *, const char *, char *, char *);
+static long long find_parsetime(PLAN *, const char *, char *);
+static char *nextarg(OPTION *, char ***);
+
+extern char **environ;
 
 #define        COMPARE(a, b) do {                                              \
        switch (plan->flags & F_ELG_MASK) {                             \
@@ -93,7 +101,7 @@ palloc(OPTION *option)
  *     Parse a string of the form [+-]# and return the value.
  */
 static long long
-find_parsenum(PLAN *plan, char *option, char *vp, char *endch)
+find_parsenum(PLAN *plan, const char *option, char *vp, char *endch)
 {
        long long value;
        char *endchar, *str;    /* Pointer to character ending conversion. */
@@ -134,7 +142,7 @@ find_parsenum(PLAN *plan, char *option, char *vp, char *endch)
  *     Parse a string of the form [+-]([0-9]+[smhdw]?)+ and return the value.
  */
 static long long
-find_parsetime(PLAN *plan, char *option, char *vp)
+find_parsetime(PLAN *plan, const char *option, char *vp)
 {
        long long secs, value;
        char *str, *unit;       /* Pointer to character ending conversion. */
@@ -241,8 +249,6 @@ nextarg(OPTION *option, char ***argvp)
 int
 f_Xmin(PLAN *plan, FTSENT *entry)
 {
-       extern time_t now;
-
        if (plan->flags & F_TIME_C) {
                COMPARE((now - entry->fts_statp->st_ctime +
                    60 - 1) / 60, plan->t_data);
@@ -283,33 +289,19 @@ c_Xmin(OPTION *option, char ***argvp)
 int
 f_Xtime(PLAN *plan, FTSENT *entry)
 {
-       extern time_t now;
-       int exact_time;
+       time_t xtime;
 
-       exact_time = plan->flags & F_EXACTTIME;
+       if (plan->flags & F_TIME_A)
+               xtime = entry->fts_statp->st_atime;
+       else if (plan->flags & F_TIME_C)
+               xtime = entry->fts_statp->st_ctime;
+       else
+               xtime = entry->fts_statp->st_mtime;
 
-       if (plan->flags & F_TIME_C) {
-               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) {
-               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 {
-               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);
-       }
+       if (plan->flags & F_EXACTTIME)
+               COMPARE(now - xtime, plan->t_data);
+       else
+               COMPARE((now - xtime + 86400 - 1) / 86400, plan->t_data);
 }
 
 PLAN *
@@ -362,7 +354,7 @@ c_mXXdepth(OPTION *option, char ***argvp)
  *     True always.  Makes its best shot and continues on regardless.
  */
 int
-f_delete(PLAN *plan, FTSENT *entry)
+f_delete(PLAN *plan __unused, FTSENT *entry)
 {
        /* ignore these from fts */
        if (strcmp(entry->fts_accpath, ".") == 0 ||
@@ -402,7 +394,7 @@ f_delete(PLAN *plan, FTSENT *entry)
 }
 
 PLAN *
-c_delete(OPTION *option, char ***argvp)
+c_delete(OPTION *option, char ***argvp __unused)
 {
 
        ftsoptions &= ~FTS_NOSTAT;      /* no optimise */
@@ -416,33 +408,72 @@ c_delete(OPTION *option, char ***argvp)
 
 
 /*
- * -depth functions --
+ * always_true --
  *
- *     Always true, causes descent of the directory hierarchy to be done
- *     so that all entries in a directory are acted on before the directory
- *     itself.
+ *     Always true, used for -maxdepth, -mindepth, -xdev and -follow
  */
 int
-f_always_true(PLAN *plan, FTSENT *entry)
+f_always_true(PLAN *plan __unused, FTSENT *entry __unused)
 {
        return 1;
 }
 
+/*
+ * -depth functions --
+ *
+ *     With argument: True if the file is at level n.
+ *     Without argument: Always true, causes descent of the directory hierarchy
+ *     to be done so that all entries in a directory are acted on before the
+ *     directory itself.
+ */
+int
+f_depth(PLAN *plan, FTSENT *entry)
+{
+       if (plan->flags & F_DEPTH)
+               COMPARE(entry->fts_level, plan->d_data);
+       else
+               return 1;
+}
+
 PLAN *
 c_depth(OPTION *option, char ***argvp)
 {
-       isdepth = 1;
+       PLAN *new;
+       char *str;
 
-       return palloc(option);
-}
+       new = palloc(option);
+
+       str = **argvp;
+       if (str && !(new->flags & F_DEPTH)) {
+               /* skip leading + or - */
+               if (*str == '+' || *str == '-')
+                       str++;
+               /* skip sign */
+               if (*str == '+' || *str == '-')
+                       str++;
+               if (isdigit(*str))
+                       new->flags |= F_DEPTH;
+       }
+
+       if (new->flags & F_DEPTH) {     /* -depth n */
+               char *ndepth;
 
+               ndepth = nextarg(option, argvp);
+               new->d_data = find_parsenum(new, option->name, ndepth, NULL);
+       } else {                        /* -d */
+               isdepth = 1;
+       }
+
+       return new;
+}
 /*
  * -empty functions --
  *
  *     True if the file or directory is empty
  */
 int
-f_empty(PLAN *plan, FTSENT *entry)
+f_empty(PLAN *plan __unused, FTSENT *entry)
 {
        if (S_ISREG(entry->fts_statp->st_mode) &&
            entry->fts_statp->st_size == 0)
@@ -470,7 +501,7 @@ f_empty(PLAN *plan, FTSENT *entry)
 }
 
 PLAN *
-c_empty(OPTION *option, char ***argvp)
+c_empty(OPTION *option, char ***argvp __unused)
 {
        ftsoptions &= ~FTS_NOSTAT;
 
@@ -493,14 +524,20 @@ c_empty(OPTION *option, char ***argvp)
  *     of the user before executing the utility.
  */
 int
-f_exec(register PLAN *plan, FTSENT *entry)
+f_exec(PLAN *plan, FTSENT *entry)
 {
-       extern int dotfd;
-       register int cnt;
+       int cnt;
        pid_t pid;
        int status;
        char *file;
 
+       if (entry == NULL && plan->flags & F_EXECPLUS) {
+               if (plan->e_ppos == plan->e_pbnum)
+                       return (1);
+               plan->e_argv[plan->e_ppos] = NULL;
+               goto doexec;
+       }
+
        /* XXX - if file/dir ends in '/' this will not work -- can it? */
        if ((plan->flags & F_EXECDIR) && \
            (file = strrchr(entry->fts_path, '/')))
@@ -508,12 +545,24 @@ f_exec(register PLAN *plan, FTSENT *entry)
        else
                file = entry->fts_path;
 
-       for (cnt = 0; plan->e_argv[cnt]; ++cnt)
-               if (plan->e_len[cnt])
-                       brace_subst(plan->e_orig[cnt], &plan->e_argv[cnt],
-                           file, plan->e_len[cnt]);
+       if (plan->flags & F_EXECPLUS) {
+               if ((plan->e_argv[plan->e_ppos] = strdup(file)) == NULL)
+                       err(1, NULL);
+               plan->e_len[plan->e_ppos] = strlen(file);
+               plan->e_psize += plan->e_len[plan->e_ppos];
+               if (++plan->e_ppos < plan->e_pnummax &&
+                   plan->e_psize < plan->e_psizemax)
+                       return (1);
+               plan->e_argv[plan->e_ppos] = NULL;
+       } else {
+               for (cnt = 0; plan->e_argv[cnt]; ++cnt)
+                       if (plan->e_len[cnt])
+                               brace_subst(plan->e_orig[cnt],
+                                   &plan->e_argv[cnt], file,
+                                   plan->e_len[cnt]);
+       }
 
-       if ((plan->flags & F_NEEDOK) && !queryuser(plan->e_argv))
+doexec:        if ((plan->flags & F_NEEDOK) && !queryuser(plan->e_argv))
                return 0;
 
        /* make sure find output is interspersed correctly with subprocesses */
@@ -534,6 +583,12 @@ f_exec(register PLAN *plan, FTSENT *entry)
                warn("%s", plan->e_argv[0]);
                _exit(1);
        }
+       if (plan->flags & F_EXECPLUS) {
+               while (--plan->e_ppos >= plan->e_pbnum)
+                       free(plan->e_argv[plan->e_ppos]);
+               plan->e_ppos = plan->e_pbnum;
+               plan->e_psize = plan->e_pbsize;
+       }
        pid = waitpid(pid, &status, 0);
        return (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status));
 }
@@ -549,8 +604,9 @@ PLAN *
 c_exec(OPTION *option, char ***argvp)
 {
        PLAN *new;                      /* node returned */
-       register int cnt;
-       register char **argv, **ap, *p;
+       long argmax;
+       int cnt, i;
+       char **argv, **ap, **ep, *p;
 
        /* XXX - was in c_execdir, but seems unnecessary!?
        ftsoptions &= ~FTS_NOSTAT;
@@ -563,24 +619,54 @@ c_exec(OPTION *option, char ***argvp)
        for (ap = argv = *argvp;; ++ap) {
                if (!*ap)
                        errx(1,
-                           "%s: no terminating \";\"", option->name);
+                           "%s: no terminating \";\" or \"+\"", option->name);
                if (**ap == ';')
                        break;
+               if (**ap == '+' && ap != argv && strcmp(*(ap - 1), "{}") == 0) {
+                       new->flags |= F_EXECPLUS;
+                       break;
+               }
        }
 
        if (ap == argv)
                errx(1, "%s: no command specified", option->name);
 
        cnt = ap - *argvp + 1;
-       new->e_argv = (char **)emalloc((u_int)cnt * sizeof(char *));
-       new->e_orig = (char **)emalloc((u_int)cnt * sizeof(char *));
-       new->e_len = (int *)emalloc((u_int)cnt * sizeof(int));
+       if (new->flags & F_EXECPLUS) {
+               new->e_ppos = new->e_pbnum = cnt - 2;
+               if ((argmax = sysconf(_SC_ARG_MAX)) == -1) {
+                       warn("sysconf(_SC_ARG_MAX)");
+                       argmax = _POSIX_ARG_MAX;
+               }
+               argmax -= 1024;
+               for (ep = environ; *ep != NULL; ep++)
+                       argmax -= strlen(*ep) + 1 + sizeof(*ep);
+               argmax -= 1 + sizeof(*ep);
+               new->e_pnummax = argmax / 16;
+               argmax -= sizeof(char *) * new->e_pnummax;
+               if (argmax <= 0)
+                       errx(1, "no space for arguments");
+               new->e_psizemax = argmax;
+               new->e_pbsize = 0;
+               cnt += new->e_pnummax + 1;
+       }
+       if ((new->e_argv = malloc(cnt * sizeof(char *))) == NULL)
+               err(1, NULL);
+       if ((new->e_orig = malloc(cnt * sizeof(char *))) == NULL)
+               err(1, NULL);
+       if ((new->e_len = malloc(cnt * sizeof(int))) == NULL)
+               err(1, NULL);
 
        for (argv = *argvp, cnt = 0; argv < ap; ++argv, ++cnt) {
                new->e_orig[cnt] = *argv;
+               if (new->flags & F_EXECPLUS)
+                       new->e_pbsize += strlen(*argv) + 1;
                for (p = *argv; *p; ++p)
-                       if (p[0] == '{' && p[1] == '}') {
-                               new->e_argv[cnt] = emalloc((u_int)MAXPATHLEN);
+                       if (!(new->flags & F_EXECPLUS) && p[0] == '{' &&
+                           p[1] == '}') {
+                               if ((new->e_argv[cnt] =
+                                   malloc(MAXPATHLEN)) == NULL)
+                                       err(1, NULL);
                                new->e_len[cnt] = MAXPATHLEN;
                                break;
                        }
@@ -589,9 +675,20 @@ c_exec(OPTION *option, char ***argvp)
                        new->e_len[cnt] = 0;
                }
        }
+       if (new->flags & F_EXECPLUS) {
+               new->e_psize = new->e_pbsize;
+               cnt--;
+               for (i = 0; i < new->e_pnummax; i++) {
+                       new->e_argv[cnt] = NULL;
+                       new->e_len[cnt] = 0;
+                       cnt++;
+               }
+               argv = ap;
+               goto done;
+       }
        new->e_argv[cnt] = new->e_orig[cnt] = NULL;
 
-       *argvp = argv + 1;
+done:  *argvp = argv + 1;
        return new;
 }
 
@@ -646,7 +743,7 @@ c_flags(OPTION *option, char ***argvp)
  *     basis.
  */
 PLAN *
-c_follow(OPTION *option, char ***argvp)
+c_follow(OPTION *option, char ***argvp __unused)
 {
        ftsoptions &= ~FTS_PHYSICAL;
        ftsoptions |= FTS_LOGICAL;
@@ -668,12 +765,15 @@ f_fstype(PLAN *plan, FTSENT *entry)
        static int val_type, val_flags;
        char *p, save[2];
 
+       if ((plan->flags & F_MTMASK) == F_MTUNKNOWN)
+               return 0;
+
        /* Only check when we cross mount point. */
        if (first || curdev != entry->fts_statp->st_dev) {
                curdev = entry->fts_statp->st_dev;
 
                /*
-                * Statfs follows symlinks; find wants the link's file system,
+                * Statfs follows symlinks; find wants the link's filesystem,
                 * not where it points.
                 */
                if (entry->fts_info == FTS_SL ||
@@ -708,20 +808,19 @@ f_fstype(PLAN *plan, FTSENT *entry)
        }
        switch (plan->flags & F_MTMASK) {
        case F_MTFLAG:
-               return (val_flags & plan->mt_data) != 0;
+               return val_flags & plan->mt_data;
        case F_MTTYPE:
-               return (val_type == plan->mt_data);
+               return val_type == plan->mt_data;
        default:
                abort();
        }
 }
 
-#if !defined(__NetBSD__)
 PLAN *
 c_fstype(OPTION *option, char ***argvp)
 {
        char *fsname;
-       register PLAN *new;
+       PLAN *new;
        struct vfsconf vfc;
 
        fsname = nextarg(option, argvp);
@@ -755,10 +854,14 @@ c_fstype(OPTION *option, char ***argvp)
                break;
        }
 
-       errx(1, "%s: unknown file type", fsname);
-       /* NOTREACHED */
+       /*
+        * We need to make filesystem checks for filesystems
+        * that exists but aren't in the kernel work.
+        */
+       fprintf(stderr, "Warning: Unknown filesystem type %s\n", fsname);
+       new->flags |= F_MTUNKNOWN;
+       return new;
 }
-#endif /* __NetBSD__ */
 
 /*
  * -group gname functions --
@@ -853,14 +956,14 @@ c_links(OPTION *option, char ***argvp)
  *     Always true - prints the current entry to stdout in "ls" format.
  */
 int
-f_ls(PLAN *plan, FTSENT *entry)
+f_ls(PLAN *plan __unused, FTSENT *entry)
 {
        printlong(entry->fts_path, entry->fts_accpath, entry->fts_statp);
        return 1;
 }
 
 PLAN *
-c_ls(OPTION *option, char ***argvp)
+c_ls(OPTION *option, char ***argvp __unused)
 {
        ftsoptions &= ~FTS_NOSTAT;
        isoutput = 1;
@@ -947,13 +1050,13 @@ c_newer(OPTION *option, char ***argvp)
  *     of the getgrnam() 9.2.1 [POSIX.1] function returns NULL.
  */
 int
-f_nogroup(PLAN *plan, FTSENT *entry)
+f_nogroup(PLAN *plan __unused, FTSENT *entry)
 {
        return group_from_gid(entry->fts_statp->st_gid, 1) == NULL;
 }
 
 PLAN *
-c_nogroup(OPTION *option, char ***argvp)
+c_nogroup(OPTION *option, char ***argvp __unused)
 {
        ftsoptions &= ~FTS_NOSTAT;
 
@@ -967,13 +1070,13 @@ c_nogroup(OPTION *option, char ***argvp)
  *     of the getpwuid() 9.2.2 [POSIX.1] function returns NULL.
  */
 int
-f_nouser(PLAN *plan, FTSENT *entry)
+f_nouser(PLAN *plan __unused, FTSENT *entry)
 {
        return user_from_uid(entry->fts_statp->st_uid, 1) == NULL;
 }
 
 PLAN *
-c_nouser(OPTION *option, char ***argvp)
+c_nouser(OPTION *option, char ***argvp __unused)
 {
        ftsoptions &= ~FTS_NOSTAT;
 
@@ -1038,13 +1141,8 @@ c_perm(OPTION *option, char ***argvp)
                ++perm;
        }
 
-       errno = 0;
-       if ((set = setmode(perm)) == NULL) {
-               if (!errno) 
-                       errx(1, "%s: %s: illegal mode string", option->name, perm);
-               else
-                       err(1, "malloc failed");
-       }
+       if ((set = setmode(perm)) == NULL)
+               errx(1, "%s: %s: illegal mode string", option->name, perm);
 
        new->m_data = getmode(set, 0);
        free(set);
@@ -1054,18 +1152,18 @@ c_perm(OPTION *option, char ***argvp)
 /*
  * -print functions --
  *
- *     Always true, causes the current pathame to be written to
+ *     Always true, causes the current pathname to be written to
  *     standard output.
  */
 int
-f_print(PLAN *plan, FTSENT *entry)
+f_print(PLAN *plan __unused, FTSENT *entry)
 {
        (void)puts(entry->fts_path);
        return 1;
 }
 
 PLAN *
-c_print(OPTION *option, char ***argvp)
+c_print(OPTION *option, char ***argvp __unused)
 {
        isoutput = 1;
 
@@ -1075,11 +1173,11 @@ c_print(OPTION *option, char ***argvp)
 /*
  * -print0 functions --
  *
- *     Always true, causes the current pathame to be written to
+ *     Always true, causes the current pathname to be written to
  *     standard output followed by a NUL character
  */
 int
-f_print0(PLAN *plan, FTSENT *entry)
+f_print0(PLAN *plan __unused, FTSENT *entry)
 {
        fputs(entry->fts_path, stdout);
        fputc('\0', stdout);
@@ -1094,10 +1192,8 @@ f_print0(PLAN *plan, FTSENT *entry)
  *     Prune a portion of the hierarchy.
  */
 int
-f_prune(PLAN *plan, FTSENT *entry)
+f_prune(PLAN *plan __unused, FTSENT *entry)
 {
-       extern FTS *tree;
-
        if (fts_set(tree, entry, FTS_SKIP))
                err(1, "%s", entry->fts_path);
        return 1;
@@ -1115,7 +1211,7 @@ int
 f_regex(PLAN *plan, FTSENT *entry)
 {
        char *str;
-       size_t len;
+       int len;
        regex_t *pre;
        regmatch_t pmatch;
        int errcode;
@@ -1175,7 +1271,7 @@ c_regex(OPTION *option, char ***argvp)
 /* c_simple covers c_prune, c_openparen, c_closeparen, c_not, c_or */
 
 PLAN *
-c_simple(OPTION *option, char ***argvp)
+c_simple(OPTION *option, char ***argvp __unused)
 {
        return palloc(option);
 }
@@ -1318,11 +1414,11 @@ c_user(OPTION *option, char ***argvp)
 /*
  * -xdev functions --
  *
- *     Always true, causes find not to decend past directories that have a
+ *     Always true, causes find not to descend past directories that have a
  *     different device ID (st_dev, see stat() S5.6.2 [POSIX.1])
  */
 PLAN *
-c_xdev(OPTION *option, char ***argvp)
+c_xdev(OPTION *option, char ***argvp __unused)
 {
        ftsoptions |= FTS_XDEV;
 
@@ -1337,8 +1433,8 @@ c_xdev(OPTION *option, char ***argvp)
 int
 f_expr(PLAN *plan, FTSENT *entry)
 {
-       register PLAN *p;
-       register int state = 0;
+       PLAN *p;
+       int state = 0;
 
        for (p = plan->p_data[0];
            p && (state = (p->execute)(p, entry)); p = p->next);
@@ -1353,13 +1449,13 @@ f_expr(PLAN *plan, FTSENT *entry)
  */
 
 int
-f_openparen(PLAN *plan, FTSENT *entry)
+f_openparen(PLAN *plan __unused, FTSENT *entry __unused)
 {
        abort();
 }
 
 int
-f_closeparen(PLAN *plan, FTSENT *entry)
+f_closeparen(PLAN *plan __unused, FTSENT *entry __unused)
 {
        abort();
 }
@@ -1371,7 +1467,7 @@ f_closeparen(PLAN *plan, FTSENT *entry)
  * AND operator. Since AND is implicit, no node is allocated.
  */
 PLAN *
-c_and(OPTION *option, char ***argvp)
+c_and(OPTION *option __unused, char ***argvp __unused)
 {
        return NULL;
 }
@@ -1384,8 +1480,8 @@ c_and(OPTION *option, char ***argvp)
 int
 f_not(PLAN *plan, FTSENT *entry)
 {
-       register PLAN *p;
-       register int state = 0;
+       PLAN *p;
+       int state = 0;
 
        for (p = plan->p_data[0];
            p && (state = (p->execute)(p, entry)); p = p->next);
@@ -1403,8 +1499,8 @@ f_not(PLAN *plan, FTSENT *entry)
 int
 f_or(PLAN *plan, FTSENT *entry)
 {
-       register PLAN *p;
-       register int state = 0;
+       PLAN *p;
+       int state = 0;
 
        for (p = plan->p_data[0];
            p && (state = (p->execute)(p, entry)); p = p->next);
index bc89819..0ca6aeb 100644 (file)
@@ -12,8 +12,8 @@
 /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
 /* SUPPRESS 288 on yyerrlab *//* Label unused */
 
-/* $FreeBSD: src/usr.bin/find/getdate.y,v 1.2.4.1 2003/01/22 03:26:34 peter Exp $ */
-/* $DragonFly: src/usr.bin/find/getdate.y,v 1.2 2003/06/17 04:29:26 dillon Exp $ */
+/* $FreeBSD: src/usr.bin/find/getdate.y,v 1.3 2003/06/14 13:00:21 markm Exp $ */
+/* $DragonFly: src/usr.bin/find/getdate.y,v 1.3 2005/02/13 23:49:53 cpressey Exp $ */
 
 #include <stdio.h>
 #include <ctype.h>
    unportable getdate.c's), but that seems to cause as many problems
    as it solves.  */
 
-extern struct tm       *gmtime();
-extern struct tm       *localtime();
+#include <time.h>
 
 #define yyparse getdate_yyparse
 #define yylex getdate_yylex
 #define yyerror getdate_yyerror
 
-static int yyparse ();
-static int yylex ();
-static int yyerror ();
+static int yyparse(void);
+static int yylex(void);
+static int yyerror(const char *);
+
+time_t get_date(char *, struct timeb *);
 
 #define EPOCH          1970
 #define HOUR(x)                ((time_t)(x) * 60)
@@ -79,7 +80,7 @@ static int yyerror ();
 **  An entry in the lexical lookup table.
 */
 typedef struct _TABLE {
-    char       *name;
+    const char *name;
     int                type;
     time_t     value;
 } TABLE;
@@ -374,7 +375,7 @@ static TABLE const MonthDayTable[] = {
     { "thurs",         tDAY, 4 },
     { "friday",                tDAY, 5 },
     { "saturday",      tDAY, 6 },
-    { NULL }
+    { NULL,            0, 0 }
 };
 
 /* Time units table. */
@@ -389,7 +390,7 @@ static TABLE const UnitsTable[] = {
     { "min",           tMINUTE_UNIT,   1 },
     { "second",                tSEC_UNIT,      1 },
     { "sec",           tSEC_UNIT,      1 },
-    { NULL }
+    { NULL,            0,              0 }
 };
 
 /* Assorted relative-time words. */
@@ -413,8 +414,8 @@ static TABLE const OtherTable[] = {
     { "tenth",         tUNUMBER,       10 },
     { "eleventh",      tUNUMBER,       11 },
     { "twelfth",       tUNUMBER,       12 },
-    { "ago",           tAGO,   1 },
-    { NULL }
+    { "ago",           tAGO,           1 },
+    { NULL,            0,              0 }
 };
 
 /* The timezone table. */
@@ -499,7 +500,7 @@ static TABLE const TimezoneTable[] = {
     { "nzst",  tZONE,     -HOUR(12) }, /* New Zealand Standard */
     { "nzdt",  tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
     { "idle",  tZONE,     -HOUR(12) }, /* International Date Line East */
-    {  NULL  }
+    {  NULL,   0,         0 }
 };
 
 /* Military timezone table. */
@@ -529,7 +530,7 @@ static TABLE const MilitaryTable[] = {
     { "x",     tZONE,  HOUR(-11) },
     { "y",     tZONE,  HOUR(-12) },
     { "z",     tZONE,  HOUR(  0) },
-    { NULL }
+    { NULL,    0,      0 }
 };
 
 \f
@@ -537,19 +538,14 @@ static TABLE const MilitaryTable[] = {
 
 /* ARGSUSED */
 static int
-yyerror(s)
-    char       *s __unused;
+yyerror(const char *s __unused)
 {
   return 0;
 }
 
 
 static time_t
-ToSeconds(Hours, Minutes, Seconds, Meridian)
-    time_t     Hours;
-    time_t     Minutes;
-    time_t     Seconds;
-    MERIDIAN   Meridian;
+ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
 {
     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
        return -1;
@@ -582,15 +578,9 @@ ToSeconds(Hours, Minutes, Seconds, Meridian)
    * A number from 0 to 99, which means a year from 1900 to 1999, or
    * The actual year (>=100).  */
 static time_t
-Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
-    time_t     Month;
-    time_t     Day;
-    time_t     Year;
-    time_t     Hours;
-    time_t     Minutes;
-    time_t     Seconds;
-    MERIDIAN   Meridian;
-    DSTMODE    DSTmode;
+Convert(time_t Month, time_t Day, time_t Year,
+       time_t Hours, time_t Minutes, time_t Seconds,
+       MERIDIAN Meridian, DSTMODE DSTmode)
 {
     static int DaysInMonth[12] = {
        31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
@@ -632,9 +622,7 @@ Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
 
 
 static time_t
-DSTcorrect(Start, Future)
-    time_t     Start;
-    time_t     Future;
+DSTcorrect(time_t Start, time_t Future)
 {
     time_t     StartDay;
     time_t     FutureDay;
@@ -646,10 +634,7 @@ DSTcorrect(Start, Future)
 
 
 static time_t
-RelativeDate(Start, DayOrdinal, DayNumber)
-    time_t     Start;
-    time_t     DayOrdinal;
-    time_t     DayNumber;
+RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
 {
     struct tm  *tm;
     time_t     now;
@@ -663,9 +648,7 @@ RelativeDate(Start, DayOrdinal, DayNumber)
 
 
 static time_t
-RelativeMonth(Start, RelMonth)
-    time_t     Start;
-    time_t     RelMonth;
+RelativeMonth(time_t Start, time_t RelMonth)
 {
     struct tm  *tm;
     time_t     Month;
@@ -685,14 +668,13 @@ RelativeMonth(Start, RelMonth)
 
 
 static int
-LookupWord(buff)
-    char               *buff;
+LookupWord(char *buff)
 {
-    register char      *p;
-    register char      *q;
-    register const TABLE       *tp;
-    int                        i;
-    int                        abbrev;
+    char       *p;
+    char       *q;
+    const TABLE        *tp;
+    int                i;
+    int                abbrev;
 
     /* Make it lowercase. */
     for (p = buff; *p; p++)
@@ -792,13 +774,13 @@ LookupWord(buff)
 
 
 static int
-yylex()
+yylex(void)
 {
-    register char      c;
-    register char      *p;
-    char               buff[20];
-    int                        Count;
-    int                        sign;
+    char       c;
+    char       *p;
+    char       buff[20];
+    int                Count;
+    int                sign;
 
     for ( ; ; ) {
        while (isspace(*yyInput))
@@ -847,8 +829,7 @@ yylex()
 
 /* Yield A - B, measured in seconds.  */
 static long
-difftm (a, b)
-     struct tm *a, *b;
+difftm (struct tm *a, struct tm *b)
 {
   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
@@ -868,9 +849,7 @@ difftm (a, b)
 }
 
 time_t
-get_date(p, now)
-    char               *p;
-    struct timeb       *now;
+get_date(char *p, struct timeb *now)
 {
     struct tm          *tm, gmt;
     struct timeb       ftz;
@@ -968,9 +947,7 @@ get_date(p, now)
 
 /* ARGSUSED */
 int
-main(ac, av)
-    int                ac;
-    char       *av[];
+main(int ac, char *av[])
 {
     char       buff[128];
     time_t     d;
index f67d42b..d649d29 100644 (file)
@@ -31,8 +31,8 @@
  * SUCH DAMAGE.
  *
  * @(#)ls.c    8.1 (Berkeley) 6/6/93
- * $FreeBSD: src/usr.bin/find/ls.c,v 1.5.6.3 2002/03/12 19:34:50 phantom Exp $
- * $DragonFly: src/usr.bin/find/ls.c,v 1.3 2003/10/04 20:36:44 hmp Exp $
+ * $FreeBSD: src/usr.bin/find/ls.c,v 1.17 2004/01/20 09:27:03 des Exp $
+ * $DragonFly: src/usr.bin/find/ls.c,v 1.4 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/param.h>
 
 #include <err.h>
 #include <errno.h>
+#include <fts.h>
+#include <grp.h>
+#include <inttypes.h>
 #include <langinfo.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <utmp.h>
+
+#include "find.h"
 
 /* Derived from the print routines in the ls(1) source code. */
 
-static void printlink (char *);
-static void printtime (time_t);
+static void printlink(char *);
+static void printtime(time_t);
 
-/*
-name: filename to print
-accpath: current valid path to filename
-sb: stat buffer
-*/
 void
 printlong(char *name, char *accpath, struct stat *sb)
 {
-       char modep[15], *user_from_uid(), *group_from_gid();
+       char modep[15];
 
-       (void)printf("%6lu %4qd ", (u_long) sb->st_ino, sb->st_blocks);
+       (void)printf("%6lu %8"PRId64" ", (u_long) sb->st_ino, sb->st_blocks);
        (void)strmode(sb->st_mode, modep);
-       (void)printf("%s %3u %-*s %-*s ", modep, sb->st_nlink, UT_NAMESIZE,
-           user_from_uid(sb->st_uid, 0), UT_NAMESIZE,
+       (void)printf("%s %3u %-*s %-*s ", modep, sb->st_nlink, MAXLOGNAME - 1,
+           user_from_uid(sb->st_uid, 0), MAXLOGNAME - 1,
            group_from_gid(sb->st_gid, 0));
 
        if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode))
                (void)printf("%3d, %3d ", major(sb->st_rdev),
                    minor(sb->st_rdev));
        else
-               (void)printf("%8qd ", sb->st_size);
+               (void)printf("%8"PRId64" ", sb->st_size);
        printtime(sb->st_mtime);
        (void)printf("%s", name);
        if (S_ISLNK(sb->st_mode))
@@ -84,17 +84,17 @@ static void
 printtime(time_t ftime)
 {
        char longstring[80];
-       static time_t now;
+       static time_t lnow;
        const char *format;
        static int d_first = -1;
 
        if (d_first < 0)
                d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
-       if (now == 0)
-               now = time(NULL);
+       if (lnow == 0)
+               lnow = time(NULL);
 
 #define        SIXMONTHS       ((365 / 2) * 86400)
-       if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS)
+       if (ftime + SIXMONTHS > lnow && ftime < lnow + SIXMONTHS)
                /* mmm dd hh:mm || dd mmm hh:mm */
                format = d_first ? "%e %b %R " : "%b %e %R ";
        else
@@ -108,7 +108,7 @@ static void
 printlink(char *name)
 {
        int lnklen;
-       char path[MAXPATHLEN + 1];
+       char path[MAXPATHLEN];
 
        if ((lnklen = readlink(name, path, MAXPATHLEN - 1)) == -1) {
                warn("%s", name);
index 629c50c..d30250e 100644 (file)
@@ -35,8 +35,8 @@
  *
  * @(#) Copyright (c) 1990, 1993, 1994 The Regents of the University of California.  All rights reserved.
  * @(#)main.c  8.4 (Berkeley) 5/4/95
- * $FreeBSD: src/usr.bin/find/main.c,v 1.9.6.2 2001/02/25 21:56:59 knu Exp $
- * $DragonFly: src/usr.bin/find/main.c,v 1.3 2003/10/04 20:36:44 hmp Exp $
+ * $FreeBSD: src/usr.bin/find/main.c,v 1.15 2003/06/14 13:00:21 markm Exp $
+ * $DragonFly: src/usr.bin/find/main.c,v 1.4 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/types.h>
@@ -66,12 +66,12 @@ int isxargs;                        /* don't permit xargs delimiting chars */
 int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */
 int regexp_flags = REG_BASIC;  /* use the "basic" regexp by default*/
 
-static void usage (void);
+static void usage(void);
 
 int
-main(int argc, char **argv)
+main(int argc, char *argv[])
 {
-       register char **p, **start;
+       char **p, **start;
        int Hflag, Lflag, ch;
 
        (void)setlocale(LC_ALL, "");
index 73ac7b9..7439b06 100644 (file)
@@ -34,8 +34,8 @@
  * SUCH DAMAGE.
  *
  * @(#)misc.c  8.2 (Berkeley) 4/1/94
- * $FreeBSD: src/usr.bin/find/misc.c,v 1.2.12.1 2000/06/23 18:38:46 roberto Exp $
- * $DragonFly: src/usr.bin/find/misc.c,v 1.3 2003/10/04 20:36:44 hmp Exp $
+ * $FreeBSD: src/usr.bin/find/misc.c,v 1.7 2003/06/14 13:00:21 markm Exp $
+ * $DragonFly: src/usr.bin/find/misc.c,v 1.4 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/types.h>
@@ -57,8 +57,8 @@
 void
 brace_subst(char *orig, char **store, char *path, int len)
 {
-       register int plen;
-       register char ch, *p;
+       int plen;
+       char ch, *p;
 
        plen = strlen(path);
        for (p = *store; (ch = *orig) != '\0'; ++orig)
@@ -80,7 +80,7 @@ brace_subst(char *orig, char **store, char *path, int len)
  *     input. If the input is 'y' then 1 is returned.
  */
 int
-queryuser(register char **argv)
+queryuser(char *argv[])
 {
        int ch, first, nl;
 
@@ -107,17 +107,3 @@ queryuser(register char **argv)
        }
         return (first == 'y');
 }
-
-/*
- * emalloc --
- *     malloc with error checking.
- */
-void *
-emalloc(u_int len)
-{
-       void *p;
-
-       if ((p = malloc(len)) == NULL)
-               err(1, NULL);
-       return (p);
-}
index 35eb8e9..31d881c 100644 (file)
@@ -33,8 +33,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/usr.bin/find/operator.c,v 1.5.6.1 2001/05/06 09:53:22 phk Exp $
- * $DragonFly: src/usr.bin/find/operator.c,v 1.4 2004/07/09 19:11:20 drhodus Exp $
+ * $FreeBSD: src/usr.bin/find/operator.c,v 1.14 2003/06/14 13:00:21 markm Exp $
+ * $DragonFly: src/usr.bin/find/operator.c,v 1.5 2005/02/13 23:49:53 cpressey Exp $
  *
  * @(#)operator.c      8.1 (Berkeley) 6/6/93
  */
 
 #include "find.h"
 
+static PLAN *yanknode(PLAN **);
+static PLAN *yankexpr(PLAN **);
+
 /*
  * yanknode --
  *     destructively removes the top from the plan
  */
-/* planp: pointer to top of plan (modified) */
 static PLAN *
 yanknode(PLAN **planp)
 {
@@ -70,11 +72,10 @@ yanknode(PLAN **planp)
  *     paren_squish.  In comments below, an expression is either a
  *     simple node or a f_expr node containing a list of simple nodes.
  */
-/* planp: pointer to top of plan (modified) */
 static PLAN *
 yankexpr(PLAN **planp)
 {
-       register PLAN *next;    /* temp node holding subexpression results */
+       PLAN *next;             /* temp node holding subexpression results */
        PLAN *node;             /* pointer to returned node or expression */
        PLAN *tail;             /* pointer to tail of subplan */
        PLAN *subplan;          /* pointer to head of ( ) expression */
@@ -92,7 +93,7 @@ yankexpr(PLAN **planp)
        if (node->execute == f_openparen)
                for (tail = subplan = NULL;;) {
                        if ((next = yankexpr(planp)) == NULL)
-                               err(1, "(: missing closing ')'");
+                               errx(1, "(: missing closing ')'");
                        /*
                         * If we find a closing ')' we store the collected
                         * subplan in our '(' node and convert the node to
@@ -121,14 +122,13 @@ yankexpr(PLAN **planp)
 
 /*
  * paren_squish --
- *     replaces "parentheisized" plans in our search plan with "expr" nodes.
+ *     replaces "parenthesized" plans in our search plan with "expr" nodes.
  */
-/* plan: plan with ( ) nodes */
 PLAN *
 paren_squish(PLAN *plan)
 {
-       register PLAN *expr;    /* pointer to next expression */
-       register PLAN *tail;    /* pointer to tail of result plan */
+       PLAN *expr;             /* pointer to next expression */
+       PLAN *tail;             /* pointer to tail of result plan */
        PLAN *result;           /* pointer to head of result plan */
 
        result = tail = NULL;
@@ -161,13 +161,12 @@ paren_squish(PLAN *plan)
  * not_squish --
  *     compresses "!" expressions in our search plan.
  */
-/* plan: plan to process */
 PLAN *
 not_squish(PLAN *plan)
 {
-       register PLAN *next;    /* next node being processed */
-       register PLAN *node;    /* temporary node used in f_not processing */
-       register PLAN *tail;    /* pointer to tail of result plan */
+       PLAN *next;             /* next node being processed */
+       PLAN *node;             /* temporary node used in f_not processing */
+       PLAN *tail;             /* pointer to tail of result plan */
        PLAN *result;           /* pointer to head of result plan */
 
        tail = result = NULL;
@@ -225,12 +224,11 @@ not_squish(PLAN *plan)
  * or_squish --
  *     compresses -o expressions in our search plan.
  */
-/* plan: plan with ors to be squished */
 PLAN *
 or_squish(PLAN *plan)
 {
-       register PLAN *next;    /* next node being processed */
-       register PLAN *tail;    /* pointer to tail of result plan */
+       PLAN *next;             /* next node being processed */
+       PLAN *tail;             /* pointer to tail of result plan */
        PLAN *result;           /* pointer to head of result plan */
 
        tail = result = next = NULL;
index 7e991a0..a4acef8 100644 (file)
@@ -34,8 +34,8 @@
  * SUCH DAMAGE.
  *
  * @(#)option.c        8.2 (Berkeley) 4/16/94
- * $FreeBSD: src/usr.bin/find/option.c,v 1.9.2.6 2003/02/22 16:33:24 des Exp $
- * $DragonFly: src/usr.bin/find/option.c,v 1.4 2003/11/03 19:31:29 eirikn Exp $
+ * $FreeBSD: src/usr.bin/find/option.c,v 1.23 2004/07/29 03:29:44 tjr Exp $
+ * $DragonFly: src/usr.bin/find/option.c,v 1.5 2005/02/13 23:49:53 cpressey Exp $
  */
 
 #include <sys/types.h>
@@ -50,6 +50,8 @@
 
 #include "find.h"
 
+int typecompare(const void *, const void *);
+
 /* NB: the following table must be sorted lexically. */
 static OPTION const options[] = {
        { "!",          c_simple,       f_not,          0 },
@@ -64,20 +66,14 @@ static OPTION const options[] = {
        { "-cnewer",    c_newer,        f_newer,        F_TIME_C },
        { "-ctime",     c_Xtime,        f_Xtime,        F_TIME_C },
        { "-delete",    c_delete,       f_delete,       0 },
-       { "-depth",     c_depth,        f_always_true,  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 },
        { "-flags",     c_flags,        f_flags,        0 },
        { "-follow",    c_follow,       f_always_true,  0 },
-/*
- * NetBSD doesn't provide a getvfsbyname(), so this option
- * is not available if using a NetBSD kernel.
- */
-#if !defined(__NetBSD__)
        { "-fstype",    c_fstype,       f_fstype,       0 },
-#endif
        { "-group",     c_group,        f_group,        0 },
        { "-iname",     c_name,         f_name,         F_IGNCASE },
        { "-inum",      c_inum,         f_inum,         0 },
@@ -134,13 +130,13 @@ static OPTION const options[] = {
 PLAN *
 find_create(char ***argvp)
 {
-       register OPTION *p;
+       OPTION *p;
        PLAN *new;
        char **argv;
 
        argv = *argvp;
 
-       if ((p = option(*argv)) == NULL)
+       if ((p = lookup_option(*argv)) == NULL)
                errx(1, "%s: unknown option", *argv);
        ++argv;
 
@@ -150,10 +146,9 @@ find_create(char ***argvp)
 }
 
 OPTION *
-option(char *name)
+lookup_option(const char *name)
 {
        OPTION tmp;
-       int typecompare(const void *, const void *);
 
        tmp.name = name;
        return ((OPTION *)bsearch(&tmp, options,
@@ -163,5 +158,5 @@ option(char *name)
 int
 typecompare(const void *a, const void *b)
 {
-       return (strcmp(((OPTION *)a)->name, ((OPTION *)b)->name));
+       return (strcmp(((const OPTION *)a)->name, ((const OPTION *)b)->name));
 }