Removed incorrect comment about -H, -P and -follow in HISTORY.
[findutils.git] / find / find.c
blob9dfcebc50d58ac2fb22b12fb8721015d78420fee
1 /* find -- search for files in a directory hierarchy
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA.*/
19 /* GNU find was written by Eric Decker <cire@cisco.com>,
20 with enhancements by David MacKenzie <djm@gnu.ai.mit.edu>,
21 Jay Plett <jay@silence.princeton.nj.us>,
22 and Tim Wood <axolotl!tim@toad.com>.
23 The idea for -print0 and xargs -0 came from
24 Dan Bernstein <brnstnd@kramden.acf.nyu.edu>. */
26 #include "defs.h"
28 #define USE_SAFE_CHDIR 1
30 #include <errno.h>
31 #include <assert.h>
34 #ifdef HAVE_FCNTL_H
35 #include <fcntl.h>
36 #else
37 #include <sys/file.h>
38 #endif
39 #include "../gnulib/lib/xalloc.h"
40 #include "../gnulib/lib/human.h"
41 #include "../gnulib/lib/canonicalize.h"
42 #include <modetype.h>
43 #include "../gnulib/lib/savedir.h"
45 #ifdef HAVE_LOCALE_H
46 #include <locale.h>
47 #endif
49 #if ENABLE_NLS
50 # include <libintl.h>
51 # define _(Text) gettext (Text)
52 #else
53 # define _(Text) Text
54 #define textdomain(Domain)
55 #define bindtextdomain(Package, Directory)
56 #endif
57 #ifdef gettext_noop
58 # define N_(String) gettext_noop (String)
59 #else
60 /* See locate.c for explanation as to why not use (String) */
61 # define N_(String) String
62 #endif
64 #define apply_predicate(pathname, stat_buf_ptr, node) \
65 (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
68 static void init_mounted_dev_list(void);
69 static void process_top_path PARAMS((char *pathname));
70 static int process_path PARAMS((char *pathname, char *name, boolean leaf, char *parent));
71 static void process_dir PARAMS((char *pathname, char *name, int pathlen, struct stat *statp, char *parent));
75 static boolean default_prints PARAMS((struct predicate *pred));
77 /* Name this program was run with. */
78 char *program_name;
80 /* All predicates for each path to process. */
81 struct predicate *predicates;
83 /* The last predicate allocated. */
84 struct predicate *last_pred;
86 /* The root of the evaluation tree. */
87 static struct predicate *eval_tree;
90 struct options options;
91 struct state state;
93 /* The full path of the initial working directory, or "." if
94 STARTING_DESC is nonnegative. */
95 char const *starting_dir = ".";
97 /* A file descriptor open to the initial working directory.
98 Doing it this way allows us to work when the i.w.d. has
99 unreadable parents. */
100 int starting_desc;
102 /* The stat buffer of the initial working directory. */
103 struct stat starting_stat_buf;
106 enum TraversalDirection
108 TraversingUp,
109 TraversingDown
113 static int
114 following_links(void)
116 switch (options.symlink_handling)
118 case SYMLINK_ALWAYS_DEREF:
119 return 1;
120 case SYMLINK_DEREF_ARGSONLY:
121 return (state.curdepth == 0);
122 case SYMLINK_NEVER_DEREF:
123 default:
124 return 0;
129 static int
130 fallback_stat(const char *name, struct stat *p, int prev_rv)
132 /* Our original stat() call failed. Perhaps we can't follow a
133 * symbolic link. If that might be the problem, lstat() the link.
134 * Otherwise, admit defeat.
136 switch (errno)
138 case ENOENT:
139 case ENOTDIR:
140 #ifdef DEBUG_STAT
141 fprintf(stderr, "fallback_stat(): stat(%s) failed; falling back on lstat()\n", name);
142 #endif
143 return lstat(name, p);
145 case EACCES:
146 case EIO:
147 case ELOOP:
148 case ENAMETOOLONG:
149 #ifdef EOVERFLOW
150 case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */
151 #endif
152 default:
153 return prev_rv;
158 /* optionh_stat() implements the stat operation when the -H option is
159 * in effect.
161 * If the item to be examined is a command-line argument, we follow
162 * symbolic links. If the stat() call fails on the command-line item,
163 * we fall back on the properties of the symbolic link.
165 * If the item to be examined is not a command-line argument, we
166 * examine the link itself.
168 int
169 optionh_stat(const char *name, struct stat *p)
171 if (0 == state.curdepth)
173 /* This file is from the command line; deference the link (if it
174 * is a link).
176 int rv = stat(name, p);
177 if (0 == rv)
178 return 0; /* success */
179 else
180 return fallback_stat(name, p, rv);
182 else
184 /* Not a file on the command line; do not derefernce the link.
186 return lstat(name, p);
190 /* optionl_stat() implements the stat operation when the -L option is
191 * in effect. That option makes us examine the thing the symbolic
192 * link points to, not the symbolic link itself.
194 int
195 optionl_stat(const char *name, struct stat *p)
197 int rv = stat(name, p);
198 if (0 == rv)
199 return 0; /* normal case. */
200 else
201 return fallback_stat(name, p, rv);
204 /* optionp_stat() implements the stat operation when the -P option is
205 * in effect (this is also the default). That option makes us examine
206 * the symbolic link itself, not the thing it points to.
208 int
209 optionp_stat(const char *name, struct stat *p)
211 return lstat(name, p);
214 #ifdef DEBUG_STAT
215 static uintmax_t stat_count = 0u;
217 static int
218 debug_stat (const char *file, struct stat *bufp)
220 ++stat_count;
221 fprintf (stderr, "debug_stat (%s)\n", file);
222 switch (options.symlink_handling)
224 case SYMLINK_ALWAYS_DEREF:
225 return optionl_stat(file, bufp);
226 case SYMLINK_DEREF_ARGSONLY:
227 return optionh_stat(file, bufp);
228 case SYMLINK_NEVER_DEREF:
229 return optionp_stat(file, bufp);
232 #endif /* DEBUG_STAT */
234 void
235 set_follow_state(enum SymlinkOption opt)
237 switch (opt)
239 case SYMLINK_ALWAYS_DEREF: /* -L */
240 options.xstat = optionl_stat;
241 options.no_leaf_check = true;
242 break;
244 case SYMLINK_NEVER_DEREF: /* -P (default) */
245 options.xstat = optionp_stat;
246 /* Can't turn no_leaf_check off because the user might have specified
247 * -noleaf anyway
249 break;
251 case SYMLINK_DEREF_ARGSONLY: /* -H */
252 options.xstat = optionh_stat;
253 options.no_leaf_check = true;
256 options.symlink_handling = opt;
258 /* For DBEUG_STAT, the choice is made at runtime within debug_stat()
259 * by checking the contents of the symlink_handling variable.
261 #if defined(DEBUG_STAT)
262 options.xstat = debug_stat;
263 #endif /* !DEBUG_STAT */
268 main (int argc, char **argv)
270 int i;
271 PFB parse_function; /* Pointer to the function which parses. */
272 struct predicate *cur_pred;
273 char *predicate_name; /* Name of predicate being parsed. */
274 int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
275 program_name = argv[0];
277 #ifdef HAVE_SETLOCALE
278 setlocale (LC_ALL, "");
279 #endif
280 bindtextdomain (PACKAGE, LOCALEDIR);
281 textdomain (PACKAGE);
283 if (isatty(0))
285 options.warnings = true;
287 else
289 options.warnings = false;
293 predicates = NULL;
294 last_pred = NULL;
295 options.do_dir_first = true;
296 options.maxdepth = options.mindepth = -1;
297 options.start_time = time (NULL);
298 options.cur_day_start = options.start_time - DAYSECS;
299 options.full_days = false;
300 options.stay_on_filesystem = false;
301 options.ignore_readdir_race = false;
303 state.exit_status = 0;
305 #if defined(DEBUG_STAT)
306 options.xstat = debug_stat;
307 #endif /* !DEBUG_STAT */
309 if (getenv("POSIXLY_CORRECT"))
310 options.output_block_size = 512;
311 else
312 options.output_block_size = 1024;
314 if (getenv("FIND_BLOCK_SIZE"))
316 error (1, 0, _("The environment variable FIND_BLOCK_SIZE is not supported, the only thing that affects the block size is the POSIXLY_CORRECT environment variable"));
319 options.no_leaf_check = false;
320 set_follow_state(SYMLINK_NEVER_DEREF); /* The default is equivalent to -P. */
322 init_mounted_dev_list();
324 #ifdef DEBUG
325 fprintf (stderr, "cur_day_start = %s", ctime (&options.cur_day_start));
326 #endif /* DEBUG */
328 /* Check for -P, -H or -L options. */
329 for (i=1; (end_of_leading_options = i) < argc; ++i)
331 if (0 == strcmp("-H", argv[i]))
333 /* Meaning: dereference symbolic links on command line, but nowhere else. */
334 set_follow_state(SYMLINK_DEREF_ARGSONLY);
336 else if (0 == strcmp("-L", argv[i]))
338 /* Meaning: dereference all symbolic links. */
339 set_follow_state(SYMLINK_ALWAYS_DEREF);
341 else if (0 == strcmp("-P", argv[i]))
343 /* Meaning: never dereference symbolic links (default). */
344 set_follow_state(SYMLINK_NEVER_DEREF);
346 else if (0 == strcmp("--", argv[i]))
348 /* -- signifies the end of options. */
349 end_of_leading_options = i+1; /* Next time start with the next option */
350 break;
352 else
354 /* Hmm, must be one of
355 * (a) A path name
356 * (b) A predicate
358 end_of_leading_options = i; /* Next time start with this option */
359 break;
363 /* We are now processing the part of the "find" command line
364 * after the -H/-L options (if any).
367 /* fprintf(stderr, "rest: optind=%ld\n", (long)optind); */
369 /* Find where in ARGV the predicates begin. */
370 for (i = end_of_leading_options; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
372 /* fprintf(stderr, "Looks like %s is not a predicate\n", argv[i]); */
373 /* Do nothing. */ ;
376 /* Enclose the expression in `( ... )' so a default -print will
377 apply to the whole expression. */
378 parse_open (argv, &argc);
379 /* Build the input order list. */
380 while (i < argc)
382 if (strchr ("-!(),", argv[i][0]) == NULL)
383 usage (_("paths must precede expression"));
384 predicate_name = argv[i];
385 parse_function = find_parser (predicate_name);
386 if (parse_function == NULL)
387 /* Command line option not recognized */
388 error (1, 0, _("invalid predicate `%s'"), predicate_name);
389 i++;
390 if (!(*parse_function) (argv, &i))
392 if (argv[i] == NULL)
393 /* Command line option requires an argument */
394 error (1, 0, _("missing argument to `%s'"), predicate_name);
395 else
396 error (1, 0, _("invalid argument `%s' to `%s'"),
397 argv[i], predicate_name);
400 if (predicates->pred_next == NULL)
402 /* No predicates that do something other than set a global variable
403 were given; remove the unneeded initial `(' and add `-print'. */
404 cur_pred = predicates;
405 predicates = last_pred = predicates->pred_next;
406 free ((char *) cur_pred);
407 parse_print (argv, &argc);
409 else if (!default_prints (predicates->pred_next))
411 /* One or more predicates that produce output were given;
412 remove the unneeded initial `('. */
413 cur_pred = predicates;
414 predicates = predicates->pred_next;
415 free ((char *) cur_pred);
417 else
419 /* `( user-supplied-expression ) -print'. */
420 parse_close (argv, &argc);
421 parse_print (argv, &argc);
424 #ifdef DEBUG
425 fprintf (stderr, _("Predicate List:\n"));
426 print_list (stderr, predicates);
427 #endif /* DEBUG */
429 /* Done parsing the predicates. Build the evaluation tree. */
430 cur_pred = predicates;
431 eval_tree = get_expr (&cur_pred, NO_PREC);
433 /* Check if we have any left-over predicates (this fixes
434 * Debian bug #185202).
436 if (cur_pred != NULL)
438 error (1, 0, _("unexpected extra predicate"));
441 #ifdef DEBUG
442 fprintf (stderr, _("Eval Tree:\n"));
443 print_tree (stderr, eval_tree, 0);
444 #endif /* DEBUG */
446 /* Rearrange the eval tree in optimal-predicate order. */
447 opt_expr (&eval_tree);
449 /* Determine the point, if any, at which to stat the file. */
450 mark_stat (eval_tree);
452 #ifdef DEBUG
453 fprintf (stderr, _("Optimized Eval Tree:\n"));
454 print_tree (stderr, eval_tree, 0);
455 fprintf (stderr, _("Optimized command line:\n"));
456 print_optlist(stderr, eval_tree);
457 fprintf(stderr, "\n");
458 #endif /* DEBUG */
460 starting_desc = open (".", O_RDONLY);
461 if (0 <= starting_desc && fchdir (starting_desc) != 0)
463 close (starting_desc);
464 starting_desc = -1;
466 if (starting_desc < 0)
468 starting_dir = xgetcwd ();
469 if (! starting_dir)
470 error (1, errno, _("cannot get current directory"));
472 if ((*options.xstat) (".", &starting_stat_buf) != 0)
473 error (1, errno, _("cannot get current directory"));
475 /* If no paths are given, default to ".". */
476 for (i = end_of_leading_options; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
478 process_top_path (argv[i]);
481 /* If there were no path arguments, default to ".". */
482 if (i == end_of_leading_options)
485 * We use a temporary variable here because some actions modify
486 * the path temporarily. Hence if we use a string constant,
487 * we get a coredump. The best example of this is if we say
488 * "find -printf %H" (note, not "find . -printf %H").
490 char defaultpath[2] = ".";
491 process_top_path (defaultpath);
494 return state.exit_status;
498 static char *
499 specific_dirname(const char *dir)
501 char dirname[1024];
503 if (0 == strcmp(".", dir))
505 /* OK, what's '.'? */
506 if (NULL != getcwd(dirname, sizeof(dirname)))
508 return strdup(dirname);
510 else
512 return strdup(dir);
515 else
517 char *result = canonicalize_filename_mode(dir, CAN_EXISTING);
518 if (NULL == result)
519 return strdup(dir);
520 else
521 return result;
525 static dev_t *mounted_devices = NULL;
526 static size_t num_mounted_devices = 0u;
529 static void
530 init_mounted_dev_list()
532 assert(NULL == mounted_devices);
533 assert(0 == num_mounted_devices);
534 mounted_devices = get_mounted_devices(&num_mounted_devices);
537 static void
538 refresh_mounted_dev_list(void)
540 if (mounted_devices)
542 free(mounted_devices);
543 mounted_devices = 0;
545 num_mounted_devices = 0u;
546 init_mounted_dev_list();
550 /* Search for device DEV in the array LIST, which is of size N. */
551 static int
552 dev_present(dev_t dev, const dev_t *list, size_t n)
554 if (list)
556 while (n-- > 0u)
558 if ( (*list++) == dev )
559 return 1;
562 return 0;
565 enum MountPointStateChange
567 MountPointRecentlyMounted,
568 MountPointRecentlyUnmounted,
569 MountPointStateUnchanged
574 static enum MountPointStateChange
575 get_mount_state(dev_t newdev)
577 int new_is_present, new_was_present;
579 new_was_present = dev_present(newdev, mounted_devices, num_mounted_devices);
580 refresh_mounted_dev_list();
581 new_is_present = dev_present(newdev, mounted_devices, num_mounted_devices);
583 if (new_was_present == new_is_present)
584 return MountPointStateUnchanged;
585 else if (new_is_present)
586 return MountPointRecentlyMounted;
587 else
588 return MountPointRecentlyUnmounted;
592 /* Return non-zero if FS is the name of a filesystem that is likely to
593 * be automounted
595 static int
596 fs_likely_to_be_automounted(const char *fs)
598 return ( (0==strcmp(fs, "nfs")) || (0==strcmp(fs, "autofs")));
601 enum WdSanityCheckFatality
603 FATAL_IF_SANITY_CHECK_FAILS,
604 NON_FATAL_IF_SANITY_CHECK_FAILS
608 /* Examine the results of the stat() of a directory from before we
609 * entered or left it, with the results of stat()ing it afterward. If
610 * these are different, the filesystem tree has been modified while we
611 * were traversing it. That might be an attempt to use a race
612 * condition to persuade find to do something it didn't intend
613 * (e.g. an attempt by an ordinary user to exploit the fact that root
614 * sometimes runs find on the whole filesystem). However, this can
615 * also happen if automount is running (certainly on Solaris). With
616 * automount, moving into a directory can cause a filesystem to be
617 * mounted there.
619 * To cope sensibly with this, we will raise an error if we see the
620 * device number change unless we are chdir()ing into a subdirectory,
621 * and the directory we moved into has been mounted or unmounted "recently".
622 * Here "recently" means since we started "find" or we last re-read
623 * the /etc/mnttab file.
625 * If the device number does not change but the inode does, that is a
626 * problem.
628 * If the device number and inode are both the same, we are happy.
630 * If a filesystem is (un)mounted as we chdir() into the directory, that
631 * may mean that we're now examining a section of the filesystem that might
632 * have been excluded from consideration (via -prune or -quit for example).
633 * Hence we print a warning message to indicate that the output of find
634 * might be inconsistent due to the change in the filesystem.
636 static boolean
637 wd_sanity_check(const char *thing_to_stat,
638 const char *program_name,
639 const char *what,
640 dev_t old_dev,
641 ino_t old_ino,
642 struct stat *newinfo,
643 int parent,
644 int line_no,
645 enum TraversalDirection direction,
646 enum WdSanityCheckFatality isfatal,
647 boolean *changed) /* output parameter */
649 const char *fstype;
650 char *specific_what = NULL;
651 int silent = 0;
653 *changed = false;
655 if ((*options.xstat) (".", newinfo) != 0)
656 error (1, errno, "%s", thing_to_stat);
658 if (old_dev != newinfo->st_dev)
660 *changed = true;
661 specific_what = specific_dirname(what);
662 fstype = filesystem_type(newinfo);
663 silent = fs_likely_to_be_automounted(fstype);
665 /* This condition is rare, so once we are here it is
666 * reasonable to perform an expensive computation to
667 * determine if we should continue or fail.
669 if (TraversingDown == direction)
671 /* We stat()ed a directory, chdir()ed into it (we know this
672 * since direction is TraversingDown), stat()ed it again,
673 * and noticed that the device numbers are different. Check
674 * if the filesystem was recently mounted.
676 * If it was, it looks like chdir()ing into the directory
677 * caused a filesystem to be mounted. Maybe automount is
678 * running. Anyway, that's probably OK - but it happens
679 * only when we are moving downward.
681 * We also allow for the possibility that a similar thing
682 * has happened with the unmounting of a filesystem. This
683 * is much rarer, as it relies on an automounter timeout
684 * occurring at exactly the wrong moment.
686 enum MountPointStateChange transition = get_mount_state(newinfo->st_dev);
687 switch (transition)
689 case MountPointRecentlyUnmounted:
690 isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
691 if (!silent)
693 error (0, 0,
694 _("Warning: filesystem %s has recently been unmounted."),
695 specific_what);
697 break;
699 case MountPointRecentlyMounted:
700 isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
701 if (!silent)
703 error (0, 0,
704 _("Warning: filesystem %s has recently been mounted."),
705 specific_what);
707 break;
709 case MountPointStateUnchanged:
710 /* leave isfatal as it is */
711 break;
715 if (FATAL_IF_SANITY_CHECK_FAILS == isfatal)
717 fstype = filesystem_type(newinfo);
718 error (1, 0,
719 _("%s%s changed during execution of %s (old device number %ld, new device number %ld, filesystem type is %s) [ref %ld]"),
720 specific_what,
721 parent ? "/.." : "",
722 program_name,
723 (long) old_dev,
724 (long) newinfo->st_dev,
725 fstype,
726 line_no);
727 /*NOTREACHED*/
728 return false;
730 else
732 /* Since the device has changed under us, the inode number
733 * will almost certainly also be different. However, we have
734 * already decided that this is not a problem. Hence we return
735 * without checking the inode number.
737 free(specific_what);
738 return true;
742 /* Device number was the same, check if the inode has changed. */
743 if (old_ino != newinfo->st_ino)
745 *changed = true;
746 specific_what = specific_dirname(what);
747 fstype = filesystem_type(newinfo);
749 error ((isfatal == FATAL_IF_SANITY_CHECK_FAILS) ? 1 : 0,
750 0, /* no relevant errno value */
751 _("%s%s changed during execution of %s (old inode number %ld, new inode number %ld, filesystem type is %s) [ref %ld]"),
752 specific_what,
753 parent ? "/.." : "",
754 program_name,
755 (long) old_ino,
756 (long) newinfo->st_ino,
757 fstype,
758 line_no);
759 free(specific_what);
760 return false;
763 return true;
766 enum SafeChdirStatus
768 SafeChdirOK,
769 SafeChdirFailSymlink,
770 SafeChdirFailNotDir,
771 SafeChdirFailStat,
772 SafeChdirFailWouldBeUnableToReturn,
773 SafeChdirFailChdirFailed,
774 SafeChdirFailNonexistent
777 /* Safely perform a change in directory.
780 static int
781 safely_chdir(const char *dest,
782 enum TraversalDirection direction,
783 struct stat *statbuf_dest)
785 struct stat statbuf_arrived;
786 int rv, dotfd=-1;
787 int saved_errno; /* specific_dirname() changes errno. */
788 char *name = NULL;
789 boolean rv_set = false;
791 saved_errno = errno = 0;
792 dotfd = open(".", O_RDONLY);
793 if (dotfd >= 0)
795 /* Stat the directory we're going to. */
796 if (0 == options.xstat(dest, statbuf_dest))
798 #ifdef S_ISLNK
799 if (!following_links() && S_ISLNK(statbuf_dest->st_mode))
801 rv = SafeChdirFailSymlink;
802 rv_set = true;
803 saved_errno = 0; /* silence the error message */
804 goto fail;
806 #endif
807 #ifdef S_ISDIR
808 /* Although the immediately following chdir() would detect
809 * the fact that this is not a directory for us, this would
810 * result in an extra system call that fails. Anybody
811 * examining the system-call trace should ideally not be
812 * concerned that something is actually failing.
814 if (!S_ISDIR(statbuf_dest->st_mode))
816 rv = SafeChdirFailNotDir;
817 rv_set = true;
818 saved_errno = 0; /* silence the error message */
819 goto fail;
821 #endif
822 if (0 == chdir(dest))
824 /* check we ended up where we wanted to go */
825 boolean changed = false;
826 wd_sanity_check(".", program_name, ".",
827 statbuf_dest->st_dev,
828 statbuf_dest->st_ino,
829 &statbuf_arrived,
830 0, __LINE__, direction,
831 FATAL_IF_SANITY_CHECK_FAILS,
832 &changed);
833 close(dotfd);
834 return SafeChdirOK;
836 else
838 saved_errno = errno;
839 if (ENOENT == saved_errno)
841 rv = SafeChdirFailNonexistent;
842 rv_set = true;
843 if (options.ignore_readdir_race)
844 errno = 0; /* don't issue err msg */
845 else
846 name = specific_dirname(dest);
848 else if (ENOTDIR == saved_errno)
850 /* This can happen if the we stat a directory,
851 * and then filesystem activity changes it into
852 * a non-directory.
854 saved_errno = 0; /* don't issue err msg */
855 rv = SafeChdirFailNotDir;
856 rv_set = true;
858 else
860 rv = SafeChdirFailChdirFailed;
861 rv_set = true;
862 name = specific_dirname(dest);
864 goto fail;
867 else
869 saved_errno = errno;
870 rv = SafeChdirFailStat;
871 rv_set = true;
872 name = specific_dirname(dest);
873 if ( (ENOENT == saved_errno) || (0 == state.curdepth))
874 saved_errno = 0; /* don't issue err msg */
875 goto fail;
878 else
880 /* We do not have read permissions on "." */
881 rv = SafeChdirFailWouldBeUnableToReturn;
882 rv_set = true;
883 goto fail;
886 saved_errno = 0;
888 /* We use the same exit path for successs or failure.
889 * which has occurred is recorded in RV.
891 fail:
892 if (saved_errno)
894 errno = saved_errno;
896 /* do not call error() as this would result in a duplicate error message
897 * when the caller does the same thing.
901 free(name);
902 name = NULL;
904 if (dotfd >= 0)
906 close(dotfd);
907 dotfd = -1;
909 assert(rv_set);
910 return rv;
914 /* Safely go back to the starting directory. */
915 static void
916 chdir_back (void)
918 struct stat stat_buf;
919 boolean dummy;
921 if (starting_desc < 0)
923 if (chdir (starting_dir) != 0)
924 error (1, errno, "%s", starting_dir);
926 wd_sanity_check(starting_dir,
927 program_name,
928 starting_dir,
929 starting_stat_buf.st_dev,
930 starting_stat_buf.st_ino,
931 &stat_buf, 0, __LINE__,
932 TraversingUp,
933 FATAL_IF_SANITY_CHECK_FAILS,
934 &dummy);
936 else
938 if (fchdir (starting_desc) != 0)
939 error (1, errno, "%s", starting_dir);
943 /* Descend PATHNAME, which is a command-line argument. */
944 static void
945 process_top_path (char *pathname)
947 state.curdepth = 0;
948 state.path_length = strlen (pathname);
949 process_path (pathname, pathname, false, ".");
953 /* Info on each directory in the current tree branch, to avoid
954 getting stuck in symbolic link loops. */
955 static struct dir_id *dir_ids = NULL;
956 /* Entries allocated in `dir_ids'. */
957 static int dir_alloc = 0;
958 /* Index in `dir_ids' of directory currently being searched.
959 This is always the last valid entry. */
960 static int dir_curr = -1;
961 /* (Arbitrary) number of entries to grow `dir_ids' by. */
962 #define DIR_ALLOC_STEP 32
966 /* We've detected a filesystem loop. This is caused by one of
967 * two things:
969 * 1. Option -L is in effect and we've hit a symbolic link that
970 * points to an ancestor. This is harmless. We won't traverse the
971 * symbolic link.
973 * 2. We have hit a real cycle in the directory hierarchy. In this
974 * case, we issue a diagnostic message (POSIX requires this) and we
975 * skip that directory entry.
977 static void
978 issue_loop_warning(const char *name, const char *pathname, int level)
980 struct stat stbuf_link;
981 if (lstat(name, &stbuf_link) != 0)
982 stbuf_link.st_mode = S_IFREG;
984 if (S_ISLNK(stbuf_link.st_mode))
986 error(0, 0,
987 _("Symbolic link `%s' is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
988 pathname);
990 else
992 int distance = 1 + (dir_curr-level);
993 /* We have found an infinite loop. POSIX requires us to
994 * issue a diagnostic. Usually we won't get to here
995 * because when the leaf optimisation is on, it will cause
996 * the subdirectory to be skipped. If /a/b/c/d is a hard
997 * link to /a/b, then the link count of /a/b/c is 2,
998 * because the ".." entry of /b/b/c/d points to /a, not
999 * to /a/b/c.
1001 error(0, 0,
1002 _("Filesystem loop detected; `%s' has the same device number and inode as a directory which is %d %s."),
1003 pathname,
1004 distance,
1005 (distance == 1 ?
1006 _("level higher in the filesystem hierarchy") :
1007 _("levels higher in the filesystem hierarchy")));
1011 /* Recursively descend path PATHNAME, applying the predicates.
1012 LEAF is true if PATHNAME is known to be in a directory that has no
1013 more unexamined subdirectories, and therefore it is not a directory.
1014 Knowing this allows us to avoid calling stat as long as possible for
1015 leaf files.
1017 NAME is PATHNAME relative to the current directory. We access NAME
1018 but print PATHNAME.
1020 PARENT is the path of the parent of NAME, relative to find's
1021 starting directory.
1023 Return nonzero iff PATHNAME is a directory. */
1025 static int
1026 process_path (char *pathname, char *name, boolean leaf, char *parent)
1028 struct stat stat_buf;
1029 static dev_t root_dev; /* Device ID of current argument pathname. */
1030 int i;
1032 /* Assume it is a non-directory initially. */
1033 stat_buf.st_mode = 0;
1035 state.rel_pathname = name;
1037 if (leaf)
1038 state.have_stat = false;
1039 else
1041 if ((*options.xstat) (name, &stat_buf) != 0)
1043 if (!options.ignore_readdir_race || (errno != ENOENT) )
1045 error (0, errno, "%s", pathname);
1046 state.exit_status = 1;
1048 return 0;
1050 state.have_stat = true;
1053 if (!S_ISDIR (stat_buf.st_mode))
1055 if (state.curdepth >= options.mindepth)
1056 apply_predicate (pathname, &stat_buf, eval_tree);
1057 return 0;
1060 /* From here on, we're working on a directory. */
1062 state.stop_at_current_level =
1063 options.maxdepth >= 0
1064 && state.curdepth >= options.maxdepth;
1066 /* If we've already seen this directory on this branch,
1067 don't descend it again. */
1068 for (i = 0; i <= dir_curr; i++)
1069 if (stat_buf.st_ino == dir_ids[i].ino &&
1070 stat_buf.st_dev == dir_ids[i].dev)
1072 state.stop_at_current_level = true;
1073 issue_loop_warning(name, pathname, i);
1076 if (dir_alloc <= ++dir_curr)
1078 dir_alloc += DIR_ALLOC_STEP;
1079 dir_ids = (struct dir_id *)
1080 xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id));
1082 dir_ids[dir_curr].ino = stat_buf.st_ino;
1083 dir_ids[dir_curr].dev = stat_buf.st_dev;
1085 if (options.stay_on_filesystem)
1087 if (state.curdepth == 0)
1088 root_dev = stat_buf.st_dev;
1089 else if (stat_buf.st_dev != root_dev)
1090 state.stop_at_current_level = true;
1093 if (options.do_dir_first && state.curdepth >= options.mindepth)
1094 apply_predicate (pathname, &stat_buf, eval_tree);
1096 #ifdef DEBUG
1097 fprintf(stderr, "pathname = %s, stop_at_current_level = %d\n",
1098 pathname, state.stop_at_current_level);
1099 #endif /* DEBUG */
1101 if (state.stop_at_current_level == false)
1102 /* Scan directory on disk. */
1103 process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
1105 if (options.do_dir_first == false && state.curdepth >= options.mindepth)
1107 state.rel_pathname = name;
1108 apply_predicate (pathname, &stat_buf, eval_tree);
1111 dir_curr--;
1113 return 1;
1116 /* Scan directory PATHNAME and recurse through process_path for each entry.
1118 PATHLEN is the length of PATHNAME.
1120 NAME is PATHNAME relative to the current directory.
1122 STATP is the results of *options.xstat on it.
1124 PARENT is the path of the parent of NAME, relative to find's
1125 starting directory. */
1127 static void
1128 process_dir (char *pathname, char *name, int pathlen, struct stat *statp, char *parent)
1130 char *name_space; /* Names of files in PATHNAME. */
1131 int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */
1132 struct stat stat_buf;
1134 subdirs_left = statp->st_nlink - 2; /* Account for name and ".". */
1136 errno = 0;
1137 name_space = savedir (name);
1138 if (name_space == NULL)
1140 assert(errno != 0);
1141 error (0, errno, "%s", pathname);
1142 state.exit_status = 1;
1144 else
1146 register char *namep; /* Current point in `name_space'. */
1147 char *cur_path; /* Full path of each file to process. */
1148 char *cur_name; /* Base name of each file to process. */
1149 unsigned cur_path_size; /* Bytes allocated for `cur_path'. */
1150 register unsigned file_len; /* Length of each path to process. */
1151 register unsigned pathname_len; /* PATHLEN plus trailing '/'. */
1153 if (pathname[pathlen - 1] == '/')
1154 pathname_len = pathlen + 1; /* For '\0'; already have '/'. */
1155 else
1156 pathname_len = pathlen + 2; /* For '/' and '\0'. */
1157 cur_path_size = 0;
1158 cur_path = NULL;
1160 #if USE_SAFE_CHDIR
1161 if (strcmp (name, "."))
1163 enum SafeChdirStatus status = safely_chdir (name, TraversingDown, &stat_buf);
1164 switch (status)
1166 case SafeChdirOK:
1167 /* If there had been a change but wd_sanity_check()
1168 * accepted it, we need to accept that on the
1169 * way back up as well, so modify our record
1170 * of what we think we should see later.
1171 * If there was no change, the assignments are a no-op.
1173 dir_ids[dir_curr].dev = stat_buf.st_dev;
1174 dir_ids[dir_curr].ino = stat_buf.st_ino;
1175 break;
1177 case SafeChdirFailNonexistent:
1178 case SafeChdirFailStat:
1179 case SafeChdirFailWouldBeUnableToReturn:
1180 case SafeChdirFailSymlink:
1181 case SafeChdirFailNotDir:
1182 case SafeChdirFailChdirFailed:
1183 error (0, errno, "%s", pathname);
1184 state.exit_status = 1;
1185 return;
1188 #else
1189 if (strcmp (name, ".") && chdir (name) < 0)
1191 error (0, errno, "%s", pathname);
1192 exit_status = 1;
1193 return;
1196 /* Check that we are where we should be. */
1197 if (1)
1199 boolean changed = false;
1200 wd_sanity_check(pathname,
1201 program_name,
1202 ".",
1203 dir_ids[dir_curr].dev,
1204 dir_ids[dir_curr].ino,
1205 &stat_buf, 0, __LINE__,
1206 TraversingDown,
1207 FATAL_IF_SANITY_CHECK_FAILS,
1208 &changed);
1209 if (changed)
1211 /* If there had been a change but wd_sanity_check()
1212 * accepted it, we need to accept that on the
1213 * way back up as well, so modify our record
1214 * of what we think we should see later.
1216 dir_ids[dir_curr].dev = stat_buf.st_dev;
1217 dir_ids[dir_curr].ino = stat_buf.st_ino;
1220 #endif
1222 for (namep = name_space; *namep; namep += file_len - pathname_len + 1)
1224 /* Append this directory entry's name to the path being searched. */
1225 file_len = pathname_len + strlen (namep);
1226 if (file_len > cur_path_size)
1228 while (file_len > cur_path_size)
1229 cur_path_size += 1024;
1230 if (cur_path)
1231 free (cur_path);
1232 cur_path = xmalloc (cur_path_size);
1233 strcpy (cur_path, pathname);
1234 cur_path[pathname_len - 2] = '/';
1236 cur_name = cur_path + pathname_len - 1;
1237 strcpy (cur_name, namep);
1239 state.curdepth++;
1240 if (!options.no_leaf_check)
1241 /* Normal case optimization.
1242 On normal Unix filesystems, a directory that has no
1243 subdirectories has two links: its name, and ".". Any
1244 additional links are to the ".." entries of its
1245 subdirectories. Once we have processed as many
1246 subdirectories as there are additional links, we know
1247 that the rest of the entries are non-directories --
1248 in other words, leaf files. */
1249 subdirs_left -= process_path (cur_path, cur_name,
1250 subdirs_left == 0, pathname);
1251 else
1252 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
1253 mounted, which don't have Unix-like directory link counts. */
1254 process_path (cur_path, cur_name, false, pathname);
1255 state.curdepth--;
1257 #if USE_SAFE_CHDIR
1258 if (strcmp (name, "."))
1260 enum SafeChdirStatus status;
1261 struct dir_id did;
1262 boolean changed = false;
1264 /* We could go back and do the next command-line arg
1265 instead, maybe using longjmp. */
1266 char const *dir;
1267 boolean deref = following_links() ? true : false;
1269 if ( (state.curdepth>0) && !deref)
1270 dir = "..";
1271 else
1273 chdir_back ();
1274 dir = parent;
1277 status = safely_chdir (dir, TraversingUp, &stat_buf);
1278 switch (status)
1280 case SafeChdirOK:
1281 break;
1283 case SafeChdirFailNonexistent:
1284 case SafeChdirFailStat:
1285 case SafeChdirFailWouldBeUnableToReturn:
1286 case SafeChdirFailSymlink:
1287 case SafeChdirFailNotDir:
1288 case SafeChdirFailChdirFailed:
1289 error (1, errno, "%s", pathname);
1290 return;
1293 if (dir_curr > 0)
1295 did.dev = dir_ids[dir_curr-1].dev;
1296 did.ino = dir_ids[dir_curr-1].ino;
1298 else
1300 did.dev = starting_stat_buf.st_dev;
1301 did.ino = starting_stat_buf.st_ino;
1304 wd_sanity_check(pathname,
1305 program_name,
1306 parent,
1307 did.dev,
1308 did.ino,
1309 &stat_buf,
1310 deref ? 1 : 0,
1311 __LINE__,
1312 TraversingUp,
1313 FATAL_IF_SANITY_CHECK_FAILS,
1314 &changed);
1316 #else
1317 if (strcmp (name, "."))
1319 /* We could go back and do the next command-line arg
1320 instead, maybe using longjmp. */
1321 char const *dir;
1322 boolean deref = following_links() ? true : false;
1324 if (!deref)
1325 dir = "..";
1326 else
1328 chdir_back ();
1329 dir = parent;
1332 if (chdir (dir) != 0)
1333 error (1, errno, "%s", parent);
1335 /* Check that we are where we should be. */
1336 if (1)
1338 boolean changed = false;
1339 struct stat tmp;
1340 int problem_is_with_parent;
1342 memset(&tmp, 0, sizeof(tmp));
1343 if (dir_curr > 0)
1345 tmp.st_dev = dir_ids[dir_curr-1].dev;
1346 tmp.st_ino = dir_ids[dir_curr-1].ino;
1348 else
1350 tmp.st_dev = starting_stat_buf.st_dev;
1351 tmp.st_ino = starting_stat_buf.st_ino;
1354 problem_is_with_parent = deref ? 1 : 0;
1355 wd_sanity_check(pathname,
1356 program_name,
1357 parent,
1358 tmp.st_dev,
1359 tmp.st_ino,
1360 &stat_buf,
1361 problem_is_with_parent, __LINE__,
1362 TraversingUp,
1363 FATAL_IF_SANITY_CHECK_FAILS,
1364 &changed);
1367 #endif
1369 if (cur_path)
1370 free (cur_path);
1371 free (name_space);
1375 /* Return true if there are no predicates with no_default_print in
1376 predicate list PRED, false if there are any.
1377 Returns true if default print should be performed */
1379 static boolean
1380 default_prints (struct predicate *pred)
1382 while (pred != NULL)
1384 if (pred->no_default_print)
1385 return (false);
1386 pred = pred->pred_next;
1388 return (true);