X-Git-Url: https://git.saurik.com/apple/shell_cmds.git/blobdiff_plain/1c4c78a56f7d442a559d8f9b7b586d81c0bb891f..1e9ba8f296be091930a3581807af9427e985df37:/find/find.c diff --git a/find/find.c b/find/find.c index e5577ea..c59a75a 100644 --- a/find/find.c +++ b/find/find.c @@ -13,10 +13,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,11 +34,12 @@ #if 0 static char sccsid[] = "@(#)find.c 8.5 (Berkeley) 8/5/94"; #else -static const char rcsid[] = - "$FreeBSD: src/usr.bin/find/find.c,v 1.7.6.3 2001/05/06 09:53:22 phk Exp $"; #endif #endif /* not lint */ +#include +__FBSDID("$FreeBSD: src/usr.bin/find/find.c,v 1.23 2010/12/11 08:32:16 joel Exp $"); + #include #include @@ -51,13 +48,23 @@ static const char rcsid[] = #include #include #include -#include #include +#include + +#ifdef __APPLE__ +#include #include +#else +#define COMPAT_MODE(func, mode) 1 +#endif #include "find.h" -static int find_compare __P((const FTSENT **s1, const FTSENT **s2)); +#ifdef __APPLE__ +static int find_compare(const FTSENT **s1, const FTSENT **s2); +#else /* !__APPLE__ */ +static int find_compare(const FTSENT * const *s1, const FTSENT * const *s2); +#endif /* __APPLE__ */ /* * find_compare -- @@ -66,8 +73,11 @@ static int find_compare __P((const FTSENT **s1, const FTSENT **s2)); * order within each directory. */ static int -find_compare(s1, s2) - const FTSENT **s1, **s2; +#ifdef __APPLE__ +find_compare(const FTSENT **s1, const FTSENT **s2) +#else /* !__APPLE__ */ +find_compare(const FTSENT * const *s1, const FTSENT * const *s2) +#endif /* __APPLE__ */ { return (strcoll((*s1)->fts_name, (*s2)->fts_name)); @@ -79,8 +89,7 @@ find_compare(s1, s2) * command arguments. */ PLAN * -find_formplan(argv) - char **argv; +find_formplan(char *argv[]) { PLAN *plan, *tail, *new; @@ -118,23 +127,23 @@ find_formplan(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; } @@ -201,16 +210,14 @@ FTS *tree; /* pointer to top of FTS hierarchy */ * over all FTSENT's returned for the given search paths. */ int -find_execute(plan, paths) - PLAN *plan; /* search plan */ - char **paths; /* array of pathnames to traverse */ +find_execute(PLAN *plan, char *paths[]) { - register FTSENT *entry; + FTSENT *entry; PLAN *p; int rval; - char **myPaths; - int nonSearchableDirFound = 0; - int pathIndex; + char **myPaths; + int nonSearchableDirFound = 0; + int pathIndex; struct stat statInfo; /* special-case directories specified on command line - explicitly examine @@ -218,15 +225,28 @@ find_execute(plan, paths) * (whether or not it's empty). UNIX conformance... */ + int strict_symlinks = (ftsoptions & (FTS_COMFOLLOW|FTS_LOGICAL)) + && COMPAT_MODE("bin/find", "unix2003"); + myPaths = addPath(NULL, NULL); for (pathIndex = 0; paths[pathIndex] != NULL; ++pathIndex) { - /* retrieve mode bits, and examine "searchable" bit of directories */ - /* exempt root from POSIX conformance */ - if (getuid() && (stat(paths[pathIndex], &statInfo) == 0) && ((statInfo.st_mode & S_IFMT) == S_IFDIR)) { - if ((statInfo.st_mode & (S_IXUSR + S_IXGRP + S_IXOTH)) != 0) { + int stat_ret = stat(paths[pathIndex], &statInfo); + int stat_errno = errno; + if (strict_symlinks && stat_ret < 0) { + if (stat_errno == ELOOP) { + errx(1, "Symlink loop resolving %s", paths[pathIndex]); + } + } + + /* retrieve mode bits, and examine "searchable" bit of + directories, exempt root from POSIX conformance */ + if (COMPAT_MODE("bin/find", "unix2003") && getuid() + && stat_ret == 0 + && ((statInfo.st_mode & S_IFMT) == S_IFDIR)) { + if (access(paths[pathIndex], X_OK) == 0) { myPaths = addPath(myPaths, paths[pathIndex]); } else { - if (errno != ENAMETOOLONG) { /* if name is too long, just let existing logic handle it */ + if (stat_errno != ENAMETOOLONG) { /* if name is too long, just let existing logic handle it */ warnx("%s: Permission denied", paths[pathIndex]); nonSearchableDirFound = 1; } @@ -246,6 +266,11 @@ find_execute(plan, paths) err(1, "ftsopen"); for (rval = nonSearchableDirFound; (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) @@ -285,16 +310,14 @@ find_execute(plan, 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; - } + } + free (myPaths); + finish_execplus(); + if (execplus_error) { + exit(execplus_error); } if (errno) err(1, "fts_read"); - - free (myPaths); + fts_close(tree); return (rval); }