Merged our bugfixes with the 4.4BSD find from uunet.

This commit is contained in:
jtc 1993-12-30 21:15:18 +00:00
parent 4ffe868003
commit 3dfa59ec4a
10 changed files with 463 additions and 368 deletions

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,19 +30,19 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)extern.h 5.2 (Berkeley) 5/24/91
* $Id: extern.h,v 1.3 1993/10/27 17:52:30 jtc Exp $
* from: @(#)extern.h 8.1 (Berkeley) 6/6/93
* $Id: extern.h,v 1.4 1993/12/30 21:15:18 jtc Exp $
*/
#include <sys/cdefs.h>
void brace_subst __P((char *, char **, char *, int));
void *emalloc __P((unsigned int));
void err __P((const char *, ...));
PLAN *find_create __P((char ***));
void find_execute __P((PLAN *, char **));
PLAN *find_formplan __P((char **));
PLAN *not_squish __P((PLAN *));
OPTION *option __P((char *));
PLAN *or_squish __P((PLAN *));
PLAN *paren_squish __P((PLAN *));
struct stat;
@ -63,6 +63,7 @@ PLAN *c_name __P((char *));
PLAN *c_newer __P((char *));
PLAN *c_nogroup __P((void));
PLAN *c_nouser __P((void));
PLAN *c_path __P((char *));
PLAN *c_perm __P((char *));
PLAN *c_print __P((void));
PLAN *c_print0 __P((void));

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 1990 The Regents of the University of California.
.\" All rights reserved.
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, Inc.
@ -32,10 +32,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" from: @(#)find.1 6.29 (Berkeley) 7/29/91
.\" $Id: find.1,v 1.5 1993/12/29 22:22:44 jtc Exp $
.\" from: @(#)find.1 8.1 (Berkeley) 6/6/93
.\" $Id: find.1,v 1.6 1993/12/30 21:15:20 jtc Exp $
.\"
.Dd July 29, 1991
.Dd June 6, 1993
.Dt FIND 1
.Os
.Sh NAME
@ -43,7 +43,7 @@
.Nd walk a file hierarchy
.Sh SYNOPSIS
.Nm find
.Op Fl dsXx
.Op Fl HdhXx
.Op Fl f Ar file
.Op Ar file ...
.Ar expression
@ -56,14 +56,19 @@ listed, evaluating an
(composed of the ``primaries'' and ``operands'' listed below) in terms
of each file in the tree.
.Pp
If
.Ar file
is a symbolic link referencing an existing file, the directory tree
referenced by the link is descended instead of the link itself.
.Pp
The options are as follows:
.Pp
.Bl -tag -width Ds
.It Fl H
The
.Fl H
option causes the file information and file type (see
.Xr stat 2 ) ,
returned for each symbolic link encountered on the command line 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. File information of all symbolic links not on
the command line is that of the link itself.
.It Fl d
The
.Fl d
@ -86,9 +91,9 @@ option specifies a file hierarchy for
to traverse.
File hierarchies may also be specified as the operands immediately
following the options.
.It Fl s
.It Fl h
The
.Fl s
.Fl h
option causes the file information and file type (see
.Xr stat 2 ) ,
returned for each symbolic link to be those of the file referenced by the
@ -379,13 +384,13 @@ that are newer than ``ttt''.
.El
.Sh SEE ALSO
.Xr chmod 1 ,
.Xr sh 1 ,
.Xr test 1 ,
.Xr locate 1 ,
.Xr stat 2 ,
.Xr umask 2 ,
.Xr fts 3 ,
.Xr getpwent 3 ,
.Xr getgrent 3 ,
.Xr strmode 3
.Xr strmode 3 ,
.Xr symlink 7
.Sh STANDARDS
The
.Nm find

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Cimarron D. Taylor of the University of California, Berkeley.
@ -35,17 +35,20 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)find.c 5.3 (Berkeley) 5/25/91";*/
static char rcsid[] = "$Id: find.c,v 1.4 1993/12/30 20:09:51 jtc Exp $";
/*static char sccsid[] = "from: @(#)find.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: find.c,v 1.5 1993/12/30 21:15:21 jtc Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "find.h"
/*
@ -58,8 +61,6 @@ find_formplan(argv)
char **argv;
{
PLAN *plan, *tail, *new;
PLAN *c_print(), *find_create(), *not_squish(), *or_squish();
PLAN *paren_squish();
/*
* for each argument in the command line, determine what kind of node
@ -77,7 +78,7 @@ find_formplan(argv)
* by c_name() with an argument of foo and `-->' represents the
* plan->next pointer.
*/
for (plan = NULL; *argv;) {
for (plan = tail = NULL; *argv;) {
if (!(new = find_create(&argv)))
continue;
if (plan == NULL)
@ -130,7 +131,7 @@ find_formplan(argv)
plan = paren_squish(plan); /* ()'s */
plan = not_squish(plan); /* !'s */
plan = or_squish(plan); /* -o's */
return(plan);
return (plan);
}
FTS *tree; /* pointer to top of FTS hierarchy */
@ -149,7 +150,7 @@ find_execute(plan, paths)
PLAN *p;
if (!(tree = fts_open(paths, ftsoptions, (int (*)())NULL)))
err("ftsopen: %s", strerror(errno));
err(1, "ftsopen");
while (entry = fts_read(tree)) {
switch(entry->fts_info) {
@ -164,15 +165,14 @@ find_execute(plan, paths)
case FTS_DNR:
case FTS_ERR:
case FTS_NS:
(void)fprintf(stderr, "find: %s: %s\n",
entry->fts_path, strerror(entry->fts_errno));
(void)fflush(stdout);
warn("%s", entry->fts_path);
continue;
}
#define BADCH " \t\n\\'\""
if (isxargs && strpbrk(entry->fts_path, BADCH)) {
(void)fprintf(stderr,
"find: illegal path: %s\n", entry->fts_path);
(void)fflush(stdout);
warnx("%s: illegal path", entry->fts_path);
continue;
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Cimarron D. Taylor of the University of California, Berkeley.
@ -33,8 +33,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)find.h 5.8 (Berkeley) 5/24/91
* $Id: find.h,v 1.4 1993/10/27 17:52:39 jtc Exp $
* from: @(#)find.h 8.1 (Berkeley) 6/6/93
* $Id: find.h,v 1.5 1993/12/30 21:15:22 jtc Exp $
*/
/* node type */
@ -42,14 +42,22 @@ enum ntype {
N_AND = 1, /* must start > 0 */
N_ATIME, N_CLOSEPAREN, N_CTIME, N_DEPTH, N_EXEC, N_EXPR, N_FOLLOW,
N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MTIME, N_NAME, N_NEWER,
N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PERM, N_PRINT,
N_PRINT0, N_PRUNE, N_SIZE, N_TYPE, N_USER, N_XDEV,
N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PATH,
N_PERM, N_PRINT, N_PRINT0, N_PRUNE, N_SIZE, N_TYPE, N_USER, N_XDEV,
};
/* node definition */
typedef struct _plandata {
struct _plandata *next; /* next node */
int (*eval)(); /* node evaluation function */
int (*eval) /* node evaluation function */
__P((struct _plandata *, FTSENT *));
#define F_EQUAL 1 /* [acm]time inum links size */
#define F_LESSTHAN 2
#define F_GREATER 3
#define F_NEEDOK 1 /* exec ok */
#define F_MTFLAG 1 /* fstype */
#define F_MTTYPE 2
#define F_ATLEAST 1 /* perm */
int flags; /* private flags */
enum ntype type; /* plan node type */
union {
@ -60,6 +68,7 @@ typedef struct _plandata {
off_t _o_data; /* file size */
time_t _t_data; /* time value */
uid_t _u_data; /* uid */
short _mt_data; /* mount flags */
struct _plandata *_p_data[2]; /* PLAN trees */
struct _ex {
char **_e_argv; /* argv array */
@ -68,14 +77,15 @@ typedef struct _plandata {
} ex;
char *_a_data[2]; /* array of char pointers */
char *_c_data; /* char pointer */
int _m_flags; /* mount flage for fstype */
} p_un;
} PLAN;
#define a_data p_un._a_data
#define c_data p_un._c_data
#define i_data p_un._i_data
#define g_data p_un._g_data
#define l_data p_un._l_data
#define m_data p_un._m_data
#define mt_data p_un._mt_data
#define o_data p_un._o_data
#define p_data p_un._p_data
#define t_data p_un._t_data
@ -83,7 +93,16 @@ 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 m_flags p_un._m_flags
} PLAN;
typedef struct _option {
char *name; /* option name */
enum ntype token; /* token type */
PLAN *(*create)(); /* create function: DON'T PROTOTYPE! */
#define O_NONE 0x01 /* no call required */
#define O_ZERO 0x02 /* pass: nothing */
#define O_ARGV 0x04 /* pass: argv, increment argv */
#define O_ARGVP 0x08 /* pass: *argv, N_OK || N_EXEC */
int flags;
} OPTION;
#include "extern.h"

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Cimarron D. Taylor of the University of California, Berkeley.
@ -35,92 +35,105 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)function.c 5.17 (Berkeley) 5/24/91";*/
static char rcsid[] = "$Id: function.c,v 1.9 1993/10/27 17:52:41 jtc Exp $";
/*static char sccsid[] = "from: @(#)function.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: function.c,v 1.10 1993/12/30 21:15:24 jtc Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <err.h>
#include <errno.h>
#include <fnmatch.h>
#include <fts.h>
#include <grp.h>
#include <pwd.h>
#include <fts.h>
#include <unistd.h>
#include <tzfile.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fnmatch.h>
#include <tzfile.h>
#include <unistd.h>
#include "find.h"
#define FIND_EQUAL 0
#define FIND_LESSTHAN 1
#define FIND_GREATER 2
#define COMPARE(a, b) { \
switch(plan->flags) { \
case FIND_EQUAL: \
return(a == b); \
case FIND_LESSTHAN: \
return(a < b); \
case FIND_GREATER: \
return(a > b); \
} \
return(0); \
#define COMPARE(a, b) { \
switch (plan->flags) { \
case F_EQUAL: \
return (a == b); \
case F_LESSTHAN: \
return (a < b); \
case F_GREATER: \
return (a > b); \
default: \
abort(); \
} \
}
static PLAN *palloc __P((enum ntype, int (*)()));
static PLAN *palloc __P((enum ntype, int (*) __P((PLAN *, FTSENT *))));
/*
* find_parsenum --
* Parse a string of the form [+-]# and return the value.
*/
long
find_parsenum(plan, option, str, endch)
static long
find_parsenum(plan, option, vp, endch)
PLAN *plan;
char *option, *str, *endch;
char *option, *vp, *endch;
{
long value;
char *endchar; /* pointer to character ending conversion */
char *endchar, *str; /* Pointer to character ending conversion. */
/* determine comparison from leading + or - */
switch(*str) {
/* Determine comparison from leading + or -. */
str = vp;
switch (*str) {
case '+':
++str;
plan->flags = FIND_GREATER;
plan->flags = F_GREATER;
break;
case '-':
++str;
plan->flags = FIND_LESSTHAN;
plan->flags = F_LESSTHAN;
break;
default:
plan->flags = FIND_EQUAL;
plan->flags = F_EQUAL;
break;
}
/*
* convert the string with strtol(). Note, if strtol() returns zero
* Convert the string with strtol(). Note, if strtol() returns zero
* and endchar points to the beginning of the string we know we have
* a syntax error.
*/
value = strtol(str, &endchar, 10);
if (!value && endchar == str ||
endchar[0] && (!endch || endchar[0] != *endch))
err("%s: %s", option, "illegal numeric value");
if (value == 0 && endchar == str)
errx(1, "%s: %s: illegal numeric value", option, vp);
if (endchar[0] && (endch == NULL || endchar[0] != *endch))
errx(1, "%s: %s: illegal trailing character", option, vp);
if (endch)
*endch = endchar[0];
return(value);
return (value);
}
/*
* 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
* user wanted. Correct so that -1 is "less than 1".
*/
#define TIME_CORRECT(p, ttype) \
if ((p)->type == ttype && (p)->flags == F_LESSTHAN) \
++((p)->t_data);
/*
* -atime n functions --
*
* True if the difference between the file access time and the
* current time is n 24 hour periods.
*
*/
int
f_atime(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -141,7 +154,8 @@ c_atime(arg)
new = palloc(N_ATIME, f_atime);
new->t_data = find_parsenum(new, "-atime", arg, NULL);
return(new);
TIME_CORRECT(new, N_ATIME);
return (new);
}
/*
* -ctime n functions --
@ -149,6 +163,7 @@ c_atime(arg)
* True if the difference between the last change of file
* status information and the current time is n 24 hour periods.
*/
int
f_ctime(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -168,8 +183,9 @@ c_ctime(arg)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_CTIME, f_ctime);
new->t_data = find_parsenum(new, "-ctime", arg, (char *)NULL);
return(new);
new->t_data = find_parsenum(new, "-ctime", arg, NULL);
TIME_CORRECT(new, N_CTIME);
return (new);
}
/*
@ -179,12 +195,12 @@ c_ctime(arg)
* so that all entries in a directory are acted on before the directory
* itself.
*/
/* ARGSUSED */
int
f_always_true(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return(1);
return (1);
}
PLAN *
@ -192,7 +208,7 @@ c_depth()
{
isdepth = 1;
return(palloc(N_DEPTH, f_always_true));
return (palloc(N_DEPTH, f_always_true));
}
/*
@ -207,6 +223,7 @@ c_depth()
* The primary -ok is different in that it requests affirmation of the
* user before executing the utility.
*/
int
f_exec(plan, entry)
register PLAN *plan;
FTSENT *entry;
@ -221,26 +238,24 @@ f_exec(plan, entry)
brace_subst(plan->e_orig[cnt], &plan->e_argv[cnt],
entry->fts_path, plan->e_len[cnt]);
if (plan->flags && !queryuser(plan->e_argv))
return(0);
if (plan->flags == F_NEEDOK && !queryuser(plan->e_argv))
return (0);
switch(pid = vfork()) {
switch (pid = vfork()) {
case -1:
err("fork: %s", strerror(errno));
err(1, "fork");
/* NOTREACHED */
case 0:
if (fchdir(dotfd)) {
(void)fprintf(stderr,
"find: chdir: %s\n", strerror(errno));
warn("chdir");
_exit(1);
}
execvp(plan->e_argv[0], plan->e_argv);
(void)fprintf(stderr,
"find: %s: %s\n", plan->e_argv[0], strerror(errno));
warn("%s", plan->e_argv[0]);
_exit(1);
}
pid = waitpid(pid, &status, 0);
return(pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status));
return (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status));
}
/*
@ -262,12 +277,13 @@ c_exec(argvp, isok)
isoutput = 1;
new = palloc(N_EXEC, f_exec);
new->flags = isok;
if (isok)
new->flags = F_NEEDOK;
for (ap = argv = *argvp;; ++ap) {
if (!*ap)
err("%s: %s",
isok ? "-ok" : "-exec", "no terminating \";\"");
errx(1,
"%s: no terminating \";\"", isok ? "-ok" : "-exec");
if (**ap == ';')
break;
}
@ -293,7 +309,7 @@ c_exec(argvp, isok)
new->e_argv[cnt] = new->e_orig[cnt] = NULL;
*argvp = argv + 1;
return(new);
return (new);
}
/*
@ -308,7 +324,7 @@ c_follow()
ftsoptions &= ~FTS_PHYSICAL;
ftsoptions |= FTS_LOGICAL;
return(palloc(N_FOLLOW, f_always_true));
return (palloc(N_FOLLOW, f_always_true));
}
/*
@ -316,16 +332,18 @@ c_follow()
*
* True if the file is of a certain type.
*/
int
f_fstype(plan, entry)
PLAN *plan;
FTSENT *entry;
{
static dev_t curdev; /* need a guaranteed illegal dev value */
static int first = 1;
static struct statfs sb;
struct statfs sb;
static short val;
char *p, save[2];
/* only check when we cross mount point */
/* Only check when we cross mount point. */
if (first || curdev != entry->fts_statp->st_dev) {
curdev = entry->fts_statp->st_dev;
@ -335,7 +353,7 @@ f_fstype(plan, entry)
*/
if (entry->fts_info == FTS_SL ||
entry->fts_info == FTS_SLNONE) {
if (p = rindex(entry->fts_accpath, '/'))
if (p = strrchr(entry->fts_accpath, '/'))
++p;
else
p = entry->fts_accpath;
@ -348,7 +366,7 @@ f_fstype(plan, entry)
p = NULL;
if (statfs(entry->fts_accpath, &sb))
err("%s: %s", entry->fts_accpath, strerror(errno));
err(1, "%s", entry->fts_accpath);
if (p) {
p[0] = save[0];
@ -356,9 +374,25 @@ f_fstype(plan, entry)
}
first = 0;
switch (plan->flags) {
case F_MTFLAG:
val = sb.f_flags;
break;
case F_MTTYPE:
val = sb.f_type;
break;
default:
abort();
}
}
switch(plan->flags) {
case F_MTFLAG:
return (val & plan->mt_data);
case F_MTTYPE:
return (val == plan->mt_data);
default:
abort();
}
return(plan->flags == MOUNT_NONE ?
sb.f_flags & plan->m_flags : sb.f_type == plan->flags);
}
PLAN *
@ -370,71 +404,86 @@ c_fstype(arg)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_FSTYPE, f_fstype);
switch(*arg) {
switch (*arg) {
case 'f':
if (!strcmp(arg, "fdesc")) {
#ifdef MOUNT_FDESC
new->flags = MOUNT_FDESC;
return(new);
#else
err("unknown file type %s", arg);
#endif
if (!strcmp(arg, "fdesc")) {
new->flags = F_MTTYPE;
new->mt_data = MOUNT_FDESC;
return (new);
}
#endif
break;
case 'i':
#ifdef MOUNT_ISOFS
if (!strcmp(arg, "isofs")) {
new->flags = MOUNT_ISOFS;
return(new);
new->flags = F_MTTYPE;
new->mt_data = MOUNT_ISOFS;
return (new);
}
#endif
break;
case 'k':
if (!strcmp(arg, "kernfs")) {
#ifdef MOUNT_KERNFS
new->flags = MOUNT_KERNFS;
return(new);
#else
err("unknown file type %s", arg);
#endif
if (!strcmp(arg, "kernfs")) {
new->flags = F_MTTYPE;
new->mt_data = MOUNT_KERNFS;
return (new);
}
#endif
break;
case 'l':
if (!strcmp(arg, "local")) {
new->flags = MOUNT_NONE;
new->m_flags = MNT_LOCAL;
return(new);
new->flags = F_MTFLAG;
new->mt_data = MNT_LOCAL;
return (new);
}
break;
case 'm':
if (!strcmp(arg, "mfs")) {
new->flags = MOUNT_MFS;
return(new);
new->flags = F_MTTYPE;
new->mt_data = MOUNT_MFS;
return (new);
}
#ifdef MOUNT_MSDOS
if (!strcmp(arg, "msdos")) {
new->flags = MOUNT_MSDOS;
return(new);
new->flags = F_MTTYPE;
new->mt_data = MOUNT_MSDOS;
}
#endif
break;
case 'n':
if (!strcmp(arg, "nfs")) {
new->flags = MOUNT_NFS;
return(new);
new->flags = F_MTTYPE;
new->mt_data = MOUNT_NFS;
return (new);
}
break;
case 'p':
#ifdef MOUNT_PC
if (!strcmp(arg, "pc")) {
new->flags = F_MTTYPE;
new->mt_data = MOUNT_PC;
return (new);
}
#endif
break;
case 'r':
if (!strcmp(arg, "rdonly")) {
new->flags = MOUNT_NONE;
new->m_flags = MNT_RDONLY;
return(new);
new->flags = F_MTFLAG;
new->mt_data = MNT_RDONLY;
return (new);
}
break;
case 'u':
if (!strcmp(arg, "ufs")) {
new->flags = MOUNT_UFS;
return(new);
new->flags = F_MTTYPE;
new->mt_data = MOUNT_UFS;
return (new);
}
break;
}
err("unknown file type %s", arg);
errx(1, "%s: unknown file type", arg);
/* NOTREACHED */
}
@ -445,11 +494,12 @@ c_fstype(arg)
* an equivalent of the getgrnam() function does not return a valid group
* name, gname is taken as a group ID.
*/
int
f_group(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return(entry->fts_statp->st_gid == plan->g_data);
return (entry->fts_statp->st_gid == plan->g_data);
}
PLAN *
@ -466,13 +516,13 @@ c_group(gname)
if (g == NULL) {
gid = atoi(gname);
if (gid == 0 && gname[0] != '0')
err("%s: %s", "-group", "no such group");
errx(1, "-group: %s: no such group", gname);
} else
gid = g->gr_gid;
new = palloc(N_GROUP, f_group);
new->g_data = gid;
return(new);
return (new);
}
/*
@ -480,6 +530,7 @@ c_group(gname)
*
* True if the file has inode # n.
*/
int
f_inum(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -496,8 +547,8 @@ c_inum(arg)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_INUM, f_inum);
new->i_data = find_parsenum(new, "-inum", arg, (char *)NULL);
return(new);
new->i_data = find_parsenum(new, "-inum", arg, NULL);
return (new);
}
/*
@ -505,6 +556,7 @@ c_inum(arg)
*
* True if the file has n links.
*/
int
f_links(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -521,8 +573,8 @@ c_links(arg)
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_LINKS, f_links);
new->l_data = (nlink_t)find_parsenum(new, "-links", arg, (char *)NULL);
return(new);
new->l_data = (nlink_t)find_parsenum(new, "-links", arg, NULL);
return (new);
}
/*
@ -530,13 +582,13 @@ c_links(arg)
*
* Always true - prints the current entry to stdout in "ls" format.
*/
/* ARGSUSED */
int
f_ls(plan, entry)
PLAN *plan;
FTSENT *entry;
{
printlong(entry->fts_path, entry->fts_accpath, entry->fts_statp);
return(1);
return (1);
}
PLAN *
@ -545,7 +597,38 @@ c_ls()
ftsoptions &= ~FTS_NOSTAT;
isoutput = 1;
return(palloc(N_LS, f_ls));
return (palloc(N_LS, f_ls));
}
/*
* -mtime n functions --
*
* True if the difference between the file modification time and the
* current time is n 24 hour periods.
*/
int
f_mtime(plan, entry)
PLAN *plan;
FTSENT *entry;
{
extern time_t now;
COMPARE((now - entry->fts_statp->st_mtime + SECSPERDAY - 1) /
SECSPERDAY, plan->t_data);
}
PLAN *
c_mtime(arg)
char *arg;
{
PLAN *new;
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_MTIME, f_mtime);
new->t_data = find_parsenum(new, "-mtime", arg, NULL);
TIME_CORRECT(new, N_MTIME);
return (new);
}
/*
@ -554,11 +637,12 @@ c_ls()
* True if the basename of the filename being examined
* matches pattern using Pattern Matching Notation S3.14
*/
int
f_name(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return(!fnmatch(plan->c_data, entry->fts_name, 0));
return (!fnmatch(plan->c_data, entry->fts_name, 0));
}
PLAN *
@ -569,7 +653,7 @@ c_name(pattern)
new = palloc(N_NAME, f_name);
new->c_data = pattern;
return(new);
return (new);
}
/*
@ -579,11 +663,12 @@ c_name(pattern)
* then the modification time of the file named by the pathname
* file.
*/
int
f_newer(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return(entry->fts_statp->st_mtime > plan->t_data);
return (entry->fts_statp->st_mtime > plan->t_data);
}
PLAN *
@ -596,10 +681,10 @@ c_newer(filename)
ftsoptions &= ~FTS_NOSTAT;
if (stat(filename, &sb))
err("%s: %s", filename, strerror(errno));
err(1, "%s", filename);
new = palloc(N_NEWER, f_newer);
new->t_data = sb.st_mtime;
return(new);
return (new);
}
/*
@ -608,14 +693,14 @@ c_newer(filename)
* True if file belongs to a user ID for which the equivalent
* of the getgrnam() 9.2.1 [POSIX.1] function returns NULL.
*/
/* ARGSUSED */
int
f_nogroup(plan, entry)
PLAN *plan;
FTSENT *entry;
{
char *group_from_gid();
return(group_from_gid(entry->fts_statp->st_gid, 1) ? 1 : 0);
return (group_from_gid(entry->fts_statp->st_gid, 1) ? 1 : 0);
}
PLAN *
@ -623,7 +708,7 @@ c_nogroup()
{
ftsoptions &= ~FTS_NOSTAT;
return(palloc(N_NOGROUP, f_nogroup));
return (palloc(N_NOGROUP, f_nogroup));
}
/*
@ -632,14 +717,14 @@ c_nogroup()
* True if file belongs to a user ID for which the equivalent
* of the getpwuid() 9.2.2 [POSIX.1] function returns NULL.
*/
/* ARGSUSED */
int
f_nouser(plan, entry)
PLAN *plan;
FTSENT *entry;
{
char *user_from_uid();
return(user_from_uid(entry->fts_statp->st_uid, 1) ? 1 : 0);
return (user_from_uid(entry->fts_statp->st_uid, 1) ? 1 : 0);
}
PLAN *
@ -647,7 +732,32 @@ c_nouser()
{
ftsoptions &= ~FTS_NOSTAT;
return(palloc(N_NOUSER, f_nouser));
return (palloc(N_NOUSER, f_nouser));
}
/*
* -path functions --
*
* True if the path of the filename being examined
* matches pattern using Pattern Matching Notation S3.14
*/
int
f_path(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return (!fnmatch(plan->c_data, entry->fts_path, 0));
}
PLAN *
c_path(pattern)
char *pattern;
{
PLAN *new;
new = palloc(N_NAME, f_path);
new->c_data = pattern;
return (new);
}
/*
@ -657,6 +767,7 @@ c_nouser()
* with a leading digit, it's treated as an octal mode, otherwise as a
* symbolic mode.
*/
int
f_perm(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -665,10 +776,10 @@ f_perm(plan, entry)
mode = entry->fts_statp->st_mode &
(S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO);
if (plan->flags)
return((plan->m_data | mode) == mode);
if (plan->flags == F_ATLEAST)
return ((plan->m_data | mode) == mode);
else
return(mode == plan->m_data);
return (mode == plan->m_data);
/* NOTREACHED */
}
@ -684,15 +795,15 @@ c_perm(perm)
new = palloc(N_PERM, f_perm);
if (*perm == '-') {
new->flags = 1;
new->flags = F_ATLEAST;
++perm;
}
if ((set = setmode(perm)) == NULL)
err("%s: %s", "-perm", "illegal mode string");
err(1, "-perm: %s: illegal mode string", perm);
new->m_data = getmode(set, 0);
return(new);
return (new);
}
/*
@ -701,7 +812,7 @@ c_perm(perm)
* Always true, causes the current pathame to be written to
* standard output.
*/
/* ARGSUSED */
int
f_print(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -741,7 +852,7 @@ c_print0()
*
* Prune a portion of the hierarchy.
*/
/* ARGSUSED */
int
f_prune(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -749,14 +860,14 @@ f_prune(plan, entry)
extern FTS *tree;
if (fts_set(tree, entry, FTS_SKIP))
err("%s: %s", entry->fts_path, strerror(errno));
return(1);
err(1, "%s", entry->fts_path);
return (1);
}
PLAN *
c_prune()
{
return(palloc(N_PRUNE, f_prune));
return (palloc(N_PRUNE, f_prune));
}
/*
@ -769,6 +880,7 @@ c_prune()
#define FIND_SIZE 512
static int divsize = 1;
int
f_size(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -794,7 +906,7 @@ c_size(arg)
new->o_data = find_parsenum(new, "-size", arg, &endch);
if (endch == 'c')
divsize = 0;
return(new);
return (new);
}
/*
@ -804,11 +916,12 @@ c_size(arg)
* block special file, character special file, directory, FIFO, or
* regular file, respectively.
*/
int
f_type(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return((entry->fts_statp->st_mode & S_IFMT) == plan->m_data);
return ((entry->fts_statp->st_mode & S_IFMT) == plan->m_data);
}
PLAN *
@ -843,12 +956,12 @@ c_type(typestring)
mask = S_IFSOCK;
break;
default:
err("%s: %s", "-type", "unknown type");
errx(1, "-type: %s: unknown type", typestring);
}
new = palloc(N_TYPE, f_type);
new->m_data = mask;
return(new);
return (new);
}
/*
@ -858,11 +971,12 @@ c_type(typestring)
* an equivalent of the getpwnam() S9.2.2 [POSIX.1] function does not
* return a valid user name, uname is taken as a user ID.
*/
int
f_user(plan, entry)
PLAN *plan;
FTSENT *entry;
{
return(entry->fts_statp->st_uid == plan->u_data);
return (entry->fts_statp->st_uid == plan->u_data);
}
PLAN *
@ -879,13 +993,13 @@ c_user(username)
if (p == NULL) {
uid = atoi(username);
if (uid == 0 && username[0] != '0')
err("%s: %s", "-user", "no such user");
errx(1, "-user: %s: no such user", username);
} else
uid = p->pw_uid;
new = palloc(N_USER, f_user);
new->u_data = uid;
return(new);
return (new);
}
/*
@ -899,7 +1013,7 @@ c_xdev()
{
ftsoptions |= FTS_XDEV;
return(palloc(N_XDEV, f_always_true));
return (palloc(N_XDEV, f_always_true));
}
/*
@ -907,6 +1021,7 @@ c_xdev()
*
* True if expression is true.
*/
int
f_expr(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -916,7 +1031,7 @@ f_expr(plan, entry)
for (p = plan->p_data[0];
p && (state = (p->eval)(p, entry)); p = p->next);
return(state);
return (state);
}
/*
@ -927,49 +1042,21 @@ f_expr(plan, entry)
PLAN *
c_openparen()
{
return(palloc(N_OPENPAREN, (int (*)())-1));
return (palloc(N_OPENPAREN, (int (*)())-1));
}
PLAN *
c_closeparen()
{
return(palloc(N_CLOSEPAREN, (int (*)())-1));
return (palloc(N_CLOSEPAREN, (int (*)())-1));
}
/*
* -mtime n functions --
*
* True if the difference between the file modification time and the
* current time is n 24 hour periods.
*/
f_mtime(plan, entry)
PLAN *plan;
FTSENT *entry;
{
extern time_t now;
COMPARE((now - entry->fts_statp->st_mtime + SECSPERDAY - 1) /
SECSPERDAY, plan->t_data);
}
PLAN *
c_mtime(arg)
char *arg;
{
PLAN *new;
ftsoptions &= ~FTS_NOSTAT;
new = palloc(N_MTIME, f_mtime);
new->t_data = find_parsenum(new, "-mtime", arg, (char *)NULL);
return(new);
}
/*
* ! expression functions --
*
* Negation of a primary; the unary NOT operator.
*/
int
f_not(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -979,13 +1066,13 @@ f_not(plan, entry)
for (p = plan->p_data[0];
p && (state = (p->eval)(p, entry)); p = p->next);
return(!state);
return (!state);
}
PLAN *
c_not()
{
return(palloc(N_NOT, f_not));
return (palloc(N_NOT, f_not));
}
/*
@ -994,6 +1081,7 @@ c_not()
* Alternation of primaries; the OR operator. The second expression is
* not evaluated if the first expression is true.
*/
int
f_or(plan, entry)
PLAN *plan;
FTSENT *entry;
@ -1005,23 +1093,23 @@ f_or(plan, entry)
p && (state = (p->eval)(p, entry)); p = p->next);
if (state)
return(1);
return (1);
for (p = plan->p_data[1];
p && (state = (p->eval)(p, entry)); p = p->next);
return(state);
return (state);
}
PLAN *
c_or()
{
return(palloc(N_OR, f_or));
return (palloc(N_OR, f_or));
}
static PLAN *
palloc(t, f)
enum ntype t;
int (*f)();
int (*f) __P((PLAN *, FTSENT *));
{
PLAN *new;
@ -1030,8 +1118,8 @@ palloc(t, f)
new->eval = f;
new->flags = 0;
new->next = NULL;
return(new);
return (new);
}
err("%s", strerror(errno));
err(1, NULL);
/* NOTREACHED */
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -32,22 +32,27 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)ls.c 5.6 (Berkeley) 3/9/91";*/
static char rcsid[] = "$Id: ls.c,v 1.2 1993/08/01 18:16:13 mycroft Exp $";
/*static char sccsid[] = "from: @(#)ls.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: ls.c,v 1.3 1993/12/30 21:15:26 jtc Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <time.h>
#include <tzfile.h>
#include <err.h>
#include <errno.h>
#include <utmp.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <tzfile.h>
#include <unistd.h>
#include <utmp.h>
/* Derived from the print routines in the ls(1) source code. */
static void printlink __P((char *));
static void printtime __P((time_t));
void
printlong(name, accpath, sb)
char *name; /* filename to print */
@ -56,7 +61,7 @@ printlong(name, accpath, sb)
{
char modep[15], *user_from_uid(), *group_from_gid();
(void)printf("%6lu %4ld ", sb->st_ino, sb->st_blocks);
(void)printf("%6lu %4qd ", 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,
@ -66,7 +71,7 @@ printlong(name, accpath, sb)
(void)printf("%3d, %3d ", major(sb->st_rdev),
minor(sb->st_rdev));
else
(void)printf("%8ld ", sb->st_size);
(void)printf("%8qd ", sb->st_size);
printtime(sb->st_mtime);
(void)printf("%s", name);
if (S_ISLNK(sb->st_mode))
@ -74,6 +79,7 @@ printlong(name, accpath, sb)
(void)putchar('\n');
}
static void
printtime(ftime)
time_t ftime;
{
@ -97,6 +103,7 @@ printtime(ftime)
(void)putchar(' ');
}
static void
printlink(name)
char *name;
{
@ -104,8 +111,7 @@ printlink(name)
char path[MAXPATHLEN + 1];
if ((lnklen = readlink(name, path, MAXPATHLEN)) == -1) {
(void)fprintf(stderr,
"\nfind: %s: %s\n", name, strerror(errno));
warn("%s", name);
return;
}
path[lnklen] = '\0';

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -32,18 +32,21 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)main.c 5.9 (Berkeley) 5/24/91";*/
static char rcsid[] = "$Id: main.c,v 1.3 1993/12/29 22:00:13 jtc Exp $";
/*static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: main.c,v 1.4 1993/12/30 21:15:27 jtc Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <fts.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "find.h"
time_t now; /* time find was run */
@ -54,29 +57,32 @@ int isdepth; /* do directories on post-order visit */
int isoutput; /* user specified output operator */
int isxargs; /* don't permit xargs delimiting chars */
static void usage();
static void usage __P((void));
int
main(argc, argv)
int argc;
char **argv;
char *argv[];
{
register char **p, **start;
PLAN *find_formplan();
int ch;
(void)time(&now); /* initialize the time-of-day */
p = start = argv;
ftsoptions = FTS_NOSTAT|FTS_PHYSICAL;
while ((ch = getopt(argc, argv, "df:sXx")) != EOF)
while ((ch = getopt(argc, argv, "Hdf:hXx")) != EOF)
switch(ch) {
case 'H':
ftsoptions |= FTS_COMFOLLOW;
break;
case 'd':
isdepth = 1;
break;
case 'f':
*p++ = optarg;
break;
case 's':
case 'h':
ftsoptions &= ~FTS_PHYSICAL;
ftsoptions |= FTS_LOGICAL;
break;
@ -111,15 +117,16 @@ main(argc, argv)
*p = NULL;
if ((dotfd = open(".", O_RDONLY, 0)) < 0)
err(".: %s", strerror(errno));
err(1, ".:");
find_execute(find_formplan(argv), start);
exit(0);
}
static void
usage()
{
(void)fprintf(stderr,
"usage: find [-dsXx] [-f file] [file ...] expression\n");
"usage: find [-HdhXx] [-f file] [file ...] expression\n");
exit(1);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Cimarron D. Taylor of the University of California, Berkeley.
@ -35,16 +35,20 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)misc.c 5.8 (Berkeley) 5/24/91";*/
static char rcsid[] = "$Id: misc.c,v 1.2 1993/08/01 18:16:12 mycroft Exp $";
/*static char sccsid[] = "from: @(#)misc.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: misc.c,v 1.3 1993/12/30 21:15:28 jtc Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "find.h"
/*
@ -64,8 +68,8 @@ brace_subst(orig, store, path, len)
if (ch == '{' && orig[1] == '}') {
while ((p - *store) + plen > len)
if (!(*store = realloc(*store, len *= 2)))
err("%s", strerror(errno));
bcopy(path, p, plen);
err(1, NULL);
memmove(p, path, plen);
p += plen;
++orig;
} else
@ -78,6 +82,7 @@ brace_subst(orig, store, path, len)
* print a message to standard error and then read input from standard
* input. If the input is 'y' then 1 is returned.
*/
int
queryuser(argv)
register char **argv;
{
@ -104,7 +109,7 @@ queryuser(argv)
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
}
return(first == 'y');
return (first == 'y');
}
/*
@ -118,36 +123,6 @@ emalloc(len)
void *p;
if (p = malloc(len))
return(p);
err("%s", strerror(errno));
/* NOTREACHED */
}
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
void
#if __STDC__
err(const char *fmt, ...)
#else
err(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
(void)fprintf(stderr, "find: ");
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
(void)fprintf(stderr, "\n");
exit(1);
/* NOTREACHED */
return (p);
err(1, NULL);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Cimarron D. Taylor of the University of California, Berkeley.
@ -35,12 +35,16 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)operator.c 5.4 (Berkeley) 5/24/91";*/
static char rcsid[] = "$Id: operator.c,v 1.2 1993/08/01 18:16:10 mycroft Exp $";
/*static char sccsid[] = "from: @(#)operator.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: operator.c,v 1.3 1993/12/30 21:15:31 jtc Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <err.h>
#include <fts.h>
#include <stdio.h>
#include "find.h"
/*
@ -54,10 +58,10 @@ yanknode(planp)
PLAN *node; /* top node removed from the plan */
if ((node = (*planp)) == NULL)
return(NULL);
return (NULL);
(*planp) = (*planp)->next;
node->next = NULL;
return(node);
return (node);
}
/*
@ -78,7 +82,7 @@ yankexpr(planp)
/* first pull the top node from the plan */
if ((node = yanknode(planp)) == NULL)
return(NULL);
return (NULL);
/*
* If the node is an '(' then we recursively slurp up expressions
@ -89,7 +93,7 @@ yankexpr(planp)
if (node->type == N_OPENPAREN)
for (tail = subplan = NULL;;) {
if ((next = yankexpr(planp)) == NULL)
err("%s: %s", "(", "missing closing ')'");
err(1, "(: missing closing ')'");
/*
* If we find a closing ')' we store the collected
* subplan in our '(' node and convert the node to
@ -99,8 +103,7 @@ yankexpr(planp)
*/
if (next->type == N_CLOSEPAREN) {
if (subplan == NULL)
err("%s: %s",
"()", "empty inner expression");
errx(1, "(): empty inner expression");
node->p_data[0] = subplan;
node->type = N_EXPR;
node->eval = f_expr;
@ -115,7 +118,7 @@ yankexpr(planp)
tail->next = NULL;
}
}
return(node);
return (node);
}
/*
@ -142,7 +145,7 @@ paren_squish(plan)
* '(' someplace.
*/
if (expr->type == N_CLOSEPAREN)
err("%s: %s", ")", "no beginning '('");
errx(1, "): no beginning '('");
/* add the expression to our result plan */
if (result == NULL)
@ -153,7 +156,7 @@ paren_squish(plan)
}
tail->next = NULL;
}
return(result);
return (result);
}
/*
@ -193,9 +196,9 @@ not_squish(plan)
node = yanknode(&plan);
}
if (node == NULL)
err("%s: %s", "!", "no following expression");
errx(1, "!: no following expression");
if (node->type == N_OR)
err("%s: %s", "!", "nothing between ! and -o");
errx(1, "!: nothing between ! and -o");
if (notlevel % 2 != 1)
next = node;
else
@ -211,7 +214,7 @@ not_squish(plan)
}
tail->next = NULL;
}
return(result);
return (result);
}
/*
@ -247,12 +250,12 @@ or_squish(plan)
*/
if (next->type == N_OR) {
if (result == NULL)
err("%s: %s", "-o", "no expression before -o");
errx(1, "-o: no expression before -o");
next->p_data[0] = result;
next->p_data[1] = or_squish(plan);
if (next->p_data[1] == NULL)
err("%s: %s", "-o", "no expression after -o");
return(next);
errx(1, "-o: no expression after -o");
return (next);
}
/* add the node to our result plan */
@ -264,5 +267,5 @@ or_squish(plan)
}
tail->next = NULL;
}
return(result);
return (result);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Cimarron D. Taylor of the University of California, Berkeley.
@ -35,61 +35,55 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)option.c 5.8 (Berkeley) 6/4/91";*/
static char rcsid[] = "$Id: option.c,v 1.4 1993/10/27 17:52:44 jtc Exp $";
/*static char sccsid[] = "from: @(#)option.c 8.1 (Berkeley) 6/6/93";*/
static char rcsid[] = "$Id: option.c,v 1.5 1993/12/30 21:15:32 jtc Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "find.h"
typedef struct _option {
char *name; /* option name */
enum ntype token; /* token type */
PLAN *(*create)(); /* create function */
#define O_NONE 0x01 /* no call required */
#define O_ZERO 0x02 /* pass: nothing */
#define O_ARGV 0x04 /* pass: argv, increment argv */
#define O_ARGVP 0x08 /* pass: *argv, N_OK || N_EXEC */
int flags;
} OPTION;
OPTION options[] = {
"!", N_NOT, c_not, O_ZERO,
"(", N_OPENPAREN, c_openparen, O_ZERO,
")", N_CLOSEPAREN, c_closeparen, O_ZERO,
"-a", N_AND, NULL, O_NONE,
"-and", N_AND, NULL, O_NONE,
"-atime", N_ATIME, c_atime, O_ARGV,
"-ctime", N_CTIME, c_ctime, O_ARGV,
"-depth", N_DEPTH, c_depth, O_ZERO,
"-exec", N_EXEC, c_exec, O_ARGVP,
"-follow", N_FOLLOW, c_follow, O_ZERO,
"-fstype", N_FSTYPE, c_fstype, O_ARGV,
"-group", N_GROUP, c_group, O_ARGV,
"-inum", N_INUM, c_inum, O_ARGV,
"-links", N_LINKS, c_links, O_ARGV,
"-ls", N_LS, c_ls, O_ZERO,
"-mtime", N_MTIME, c_mtime, O_ARGV,
"-name", N_NAME, c_name, O_ARGV,
"-newer", N_NEWER, c_newer, O_ARGV,
"-nogroup", N_NOGROUP, c_nogroup, O_ZERO,
"-nouser", N_NOUSER, c_nouser, O_ZERO,
"-o", N_OR, c_or, O_ZERO,
"-ok", N_OK, c_exec, O_ARGVP,
"-or", N_OR, c_or, O_ZERO,
"-perm", N_PERM, c_perm, O_ARGV,
"-print", N_PRINT, c_print, O_ZERO,
"-print0", N_PRINT0, c_print0, O_ZERO,
"-prune", N_PRUNE, c_prune, O_ZERO,
"-size", N_SIZE, c_size, O_ARGV,
"-type", N_TYPE, c_type, O_ARGV,
"-user", N_USER, c_user, O_ARGV,
"-xdev", N_XDEV, c_xdev, O_ZERO,
/* NB: the following table must be sorted lexically. */
static OPTION options[] = {
{ "!", N_NOT, c_not, O_ZERO },
{ "(", N_OPENPAREN, c_openparen, O_ZERO },
{ ")", N_CLOSEPAREN, c_closeparen, O_ZERO },
{ "-a", N_AND, NULL, O_NONE },
{ "-and", N_AND, NULL, O_NONE },
{ "-atime", N_ATIME, c_atime, O_ARGV },
{ "-ctime", N_CTIME, c_ctime, O_ARGV },
{ "-depth", N_DEPTH, c_depth, O_ZERO },
{ "-exec", N_EXEC, c_exec, O_ARGVP },
{ "-follow", N_FOLLOW, c_follow, O_ZERO },
{ "-fstype", N_FSTYPE, c_fstype, O_ARGV },
{ "-group", N_GROUP, c_group, O_ARGV },
{ "-inum", N_INUM, c_inum, O_ARGV },
{ "-links", N_LINKS, c_links, O_ARGV },
{ "-ls", N_LS, c_ls, O_ZERO },
{ "-mtime", N_MTIME, c_mtime, O_ARGV },
{ "-name", N_NAME, c_name, O_ARGV },
{ "-newer", N_NEWER, c_newer, O_ARGV },
{ "-nogroup", N_NOGROUP, c_nogroup, O_ZERO },
{ "-nouser", N_NOUSER, c_nouser, O_ZERO },
{ "-o", N_OR, c_or, O_ZERO },
{ "-ok", N_OK, c_exec, O_ARGVP },
{ "-or", N_OR, c_or, O_ZERO },
{ "-path", N_PATH, c_path, O_ARGV },
{ "-perm", N_PERM, c_perm, O_ARGV },
{ "-print", N_PRINT, c_print, O_ZERO },
{ "-print0", N_PRINT0, c_print0, O_ZERO },
{ "-prune", N_PRUNE, c_prune, O_ZERO },
{ "-size", N_SIZE, c_size, O_ARGV },
{ "-type", N_TYPE, c_type, O_ARGV },
{ "-user", N_USER, c_user, O_ARGV },
{ "-xdev", N_XDEV, c_xdev, O_ZERO },
};
/*
@ -107,20 +101,14 @@ find_create(argvp)
register OPTION *p;
PLAN *new;
char **argv;
OPTION *option();
argv = *argvp;
if ((p = option(*argv)) == NULL) {
(void)fprintf(stderr, "find: unknown option %s.\n", *argv);
exit(1);
}
if ((p = option(*argv)) == NULL)
errx(1, "%s: unknown option", *argv);
++argv;
if (p->flags & (O_ARGV|O_ARGVP) && !*argv) {
(void)fprintf(stderr,
"find: %s requires additional arguments.\n", *--argv);
exit(1);
}
if (p->flags & (O_ARGV|O_ARGVP) && !*argv)
errx(1, "%s: requires additional arguments", *--argv);
switch(p->flags) {
case O_NONE:
@ -135,9 +123,11 @@ find_create(argvp)
case O_ARGVP:
new = (p->create)(&argv, p->token == N_OK);
break;
default:
abort();
}
*argvp = argv;
return(new);
return (new);
}
OPTION *
@ -148,12 +138,13 @@ option(name)
int typecompare __P((const void *, const void *));
tmp.name = name;
return((OPTION *)bsearch(&tmp, options,
return ((OPTION *)bsearch(&tmp, options,
sizeof(options)/sizeof(OPTION), sizeof(OPTION), typecompare));
}
int
typecompare(a, b)
const void *a, *b;
{
return(strcmp(((OPTION *)a)->name, ((OPTION *)b)->name));
return (strcmp(((OPTION *)a)->name, ((OPTION *)b)->name));
}