Removed some unused code.
[findutils.git] / find / find.c
blob9d77558bec3a2c76fa43b43c6c0535d253627547
1 /* find -- search for files in a directory hierarchy
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003 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 #include <errno.h>
29 #include <assert.h>
32 #ifdef HAVE_FCNTL_H
33 #include <fcntl.h>
34 #else
35 #include <sys/file.h>
36 #endif
37 #include "../gnulib/lib/xalloc.h"
38 #include "../gnulib/lib/human.h"
39 #include "../gnulib/lib/canonicalize.h"
40 #include <modetype.h>
41 #include "../gnulib/lib/savedir.h"
43 #ifdef HAVE_LOCALE_H
44 #include <locale.h>
45 #endif
47 #if ENABLE_NLS
48 # include <libintl.h>
49 # define _(Text) gettext (Text)
50 #else
51 # define _(Text) Text
52 #define textdomain(Domain)
53 #define bindtextdomain(Package, Directory)
54 #endif
55 #ifdef gettext_noop
56 # define N_(String) gettext_noop (String)
57 #else
58 /* See locate.c for explanation as to why not use (String) */
59 # define N_(String) String
60 #endif
62 #define apply_predicate(pathname, stat_buf_ptr, node) \
63 (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
66 static void init_mounted_dev_list(void);
67 static void process_top_path PARAMS((char *pathname));
68 static int process_path PARAMS((char *pathname, char *name, boolean leaf, char *parent));
69 static void process_dir PARAMS((char *pathname, char *name, int pathlen, struct stat *statp, char *parent));
73 static boolean default_prints PARAMS((struct predicate *pred));
75 /* Name this program was run with. */
76 char *program_name;
78 /* All predicates for each path to process. */
79 struct predicate *predicates;
81 /* The last predicate allocated. */
82 struct predicate *last_pred;
84 /* The root of the evaluation tree. */
85 static struct predicate *eval_tree;
87 /* If true, process directory before contents. True unless -depth given. */
88 boolean do_dir_first;
90 /* If >=0, don't descend more than this many levels of subdirectories. */
91 int maxdepth;
93 /* If >=0, don't process files above this level. */
94 int mindepth;
96 /* Current depth; 0 means current path is a command line arg. */
97 int curdepth;
99 /* Output block size. */
100 int output_block_size;
102 /* Time at start of execution. */
103 time_t start_time;
105 /* Seconds between 00:00 1/1/70 and either one day before now
106 (the default), or the start of today (if -daystart is given). */
107 time_t cur_day_start;
109 /* If true, cur_day_start has been adjusted to the start of the day. */
110 boolean full_days;
112 /* If true, do not assume that files in directories with nlink == 2
113 are non-directories. */
114 boolean no_leaf_check;
116 /* If true, don't cross filesystem boundaries. */
117 boolean stay_on_filesystem;
119 /* If true, don't descend past current directory.
120 Can be set by -prune, -maxdepth, and -xdev/-mount. */
121 boolean stop_at_current_level;
123 /* The full path of the initial working directory, or "." if
124 STARTING_DESC is nonnegative. */
125 char const *starting_dir = ".";
127 /* A file descriptor open to the initial working directory.
128 Doing it this way allows us to work when the i.w.d. has
129 unreadable parents. */
130 int starting_desc;
132 /* The stat buffer of the initial working directory. */
133 struct stat starting_stat_buf;
135 /* If true, we have called stat on the current path. */
136 boolean have_stat;
138 /* The file being operated on, relative to the current directory.
139 Used for stat, readlink, remove, and opendir. */
140 char *rel_pathname;
142 /* Length of current path. */
143 int path_length;
145 /* true if following symlinks. Should be consistent with xstat. */
146 /* boolean dereference; */
147 enum SymlinkOption symlink_handling;
150 /* Pointer to the function used to stat files. */
151 int (*xstat) ();
153 /* Status value to return to system. */
154 int exit_status;
156 /* If true, we ignore the problem where we find that a directory entry
157 * no longer exists by the time we get around to processing it.
159 boolean ignore_readdir_race;
162 /* If true, we issue warning messages
164 boolean warnings;
167 enum TraversalDirection
169 TraversingUp,
170 TraversingDown
174 static int
175 following_links(void)
177 switch (symlink_handling)
179 case SYMLINK_ALWAYS_DEREF:
180 return 1;
181 case SYMLINK_DEREF_ARGSONLY:
182 return (curdepth == 0);
183 case SYMLINK_NEVER_DEREF:
184 default:
185 return 0;
190 /* optionh_stat() implements the stat operation when the -H option is
191 * in effect.
193 * If the item to be examined is a command-line argument, we follow
194 * symbolic links. If the stat() call fails on the command-line item,
195 * we fall back on the properties of the symbolic link.
197 * If the item to be examined is not a command-line argument, we
198 * examine the link itself.
200 int
201 optionh_stat(const char *name, struct stat *p)
203 if (0 == curdepth)
205 /* This file is from the command line; deference the link (if it
206 * is a link).
208 if (0 == stat(name, p))
210 /* success */
211 return 0;
213 else
215 /* fallback - return the information for the link itself. */
216 return lstat(name, p);
219 else
221 /* Not a file on the command line; do not derefernce the link.
223 return lstat(name, p);
227 /* optionl_stat() implements the stat operation when the -L option is
228 * in effect. That option makes us examine the thing the symbolic
229 * link points to, not the symbolic link itself.
231 int
232 optionl_stat(const char *name, struct stat *p)
234 if (0 == stat(name, p))
236 return 0; /* normal case. */
238 else
240 return lstat(name, p); /* can't follow link, return the link itself. */
244 /* optionp_stat() implements the stat operation when the -P option is
245 * in effect (this is also the default). That option makes us examine
246 * the symbolic link itself, not the thing it points to.
248 int
249 optionp_stat(const char *name, struct stat *p)
251 return lstat(name, p);
254 #ifdef DEBUG_STAT
255 static int
256 debug_stat (const char *file, struct stat *bufp)
258 fprintf (stderr, "debug_stat (%s)\n", file);
259 switch (symlink_handling)
261 case SYMLINK_ALWAYS_DEREF:
262 return optionl_stat(file, bufp);
263 case SYMLINK_DEREF_ARGSONLY:
264 return optionh_stat(file, bufp);
265 case SYMLINK_NEVER_DEREF:
266 return optionp_stat(file, bufp);
269 #endif /* DEBUG_STAT */
271 void
272 set_follow_state(enum SymlinkOption opt)
274 switch (opt)
276 case SYMLINK_ALWAYS_DEREF: /* -L */
277 xstat = optionl_stat;
278 no_leaf_check = false;
279 break;
281 case SYMLINK_NEVER_DEREF: /* -P (default) */
282 xstat = optionp_stat;
283 /* Can't turn on no_leaf_check because the user might have specified
284 * -noleaf anyway
286 break;
288 case SYMLINK_DEREF_ARGSONLY: /* -H */
289 xstat = optionh_stat;
290 no_leaf_check = true;
293 symlink_handling = opt;
295 /* For DBEUG_STAT, the choice is made at runtime within debug_stat()
296 * by checking the contents of the symlink_handling variable.
298 #if defined(DEBUG_STAT)
299 xstat = debug_stat;
300 #endif /* !DEBUG_STAT */
305 main (int argc, char **argv)
307 int i;
308 PFB parse_function; /* Pointer to the function which parses. */
309 struct predicate *cur_pred;
310 char *predicate_name; /* Name of predicate being parsed. */
311 int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
312 program_name = argv[0];
314 #ifdef HAVE_SETLOCALE
315 setlocale (LC_ALL, "");
316 #endif
317 bindtextdomain (PACKAGE, LOCALEDIR);
318 textdomain (PACKAGE);
320 if (isatty(0))
322 warnings = true;
324 else
326 warnings = false;
330 predicates = NULL;
331 last_pred = NULL;
332 do_dir_first = true;
333 maxdepth = mindepth = -1;
334 start_time = time (NULL);
335 cur_day_start = start_time - DAYSECS;
336 full_days = false;
337 no_leaf_check = false;
338 stay_on_filesystem = false;
339 ignore_readdir_race = false;
340 exit_status = 0;
342 #if defined(DEBUG_STAT)
343 xstat = debug_stat;
344 #endif /* !DEBUG_STAT */
346 #if 0
347 human_block_size (getenv ("FIND_BLOCK_SIZE"), 0, &output_block_size);
348 #else
349 if (getenv("POSIXLY_CORRECT"))
350 output_block_size = 512;
351 else
352 output_block_size = 1024;
354 if (getenv("FIND_BLOCK_SIZE"))
356 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"));
359 set_follow_state(SYMLINK_NEVER_DEREF); /* The default is equivalent to -P. */
361 init_mounted_dev_list();
363 #endif
365 #ifdef DEBUG
366 printf ("cur_day_start = %s", ctime (&cur_day_start));
367 #endif /* DEBUG */
369 /* Check for -P, -H or -L options. */
370 for (i=1; (end_of_leading_options = i) < argc; ++i)
372 if (0 == strcmp("-H", argv[i]))
374 /* Meaning: dereference symbolic links on command line, but nowhere else. */
375 set_follow_state(SYMLINK_DEREF_ARGSONLY);
377 else if (0 == strcmp("-L", argv[i]))
379 /* Meaning: dereference all symbolic links. */
380 set_follow_state(SYMLINK_ALWAYS_DEREF);
382 else if (0 == strcmp("-P", argv[i]))
384 /* Meaning: never dereference symbolic links (default). */
385 set_follow_state(SYMLINK_NEVER_DEREF);
387 else if (0 == strcmp("--", argv[i]))
389 /* -- signifies the end of options. */
390 end_of_leading_options = i+1; /* Next time start with the next option */
391 break;
393 else
395 /* Hmm, must be one of
396 * (a) A path name
397 * (b) A predicate
399 end_of_leading_options = i; /* Next time start with this option */
400 break;
404 /* We are now processing the part of the "find" command line
405 * after the -H/-L options (if any).
408 /* fprintf(stderr, "rest: optind=%ld\n", (long)optind); */
410 /* Find where in ARGV the predicates begin. */
411 for (i = end_of_leading_options; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
413 /* fprintf(stderr, "Looks like %s is not a predicate\n", argv[i]); */
414 /* Do nothing. */ ;
417 /* Enclose the expression in `( ... )' so a default -print will
418 apply to the whole expression. */
419 parse_open (argv, &argc);
420 /* Build the input order list. */
421 while (i < argc)
423 if (strchr ("-!(),", argv[i][0]) == NULL)
424 usage (_("paths must precede expression"));
425 predicate_name = argv[i];
426 parse_function = find_parser (predicate_name);
427 if (parse_function == NULL)
428 /* Command line option not recognized */
429 error (1, 0, _("invalid predicate `%s'"), predicate_name);
430 i++;
431 if (!(*parse_function) (argv, &i))
433 if (argv[i] == NULL)
434 /* Command line option requires an argument */
435 error (1, 0, _("missing argument to `%s'"), predicate_name);
436 else
437 error (1, 0, _("invalid argument `%s' to `%s'"),
438 argv[i], predicate_name);
441 if (predicates->pred_next == NULL)
443 /* No predicates that do something other than set a global variable
444 were given; remove the unneeded initial `(' and add `-print'. */
445 cur_pred = predicates;
446 predicates = last_pred = predicates->pred_next;
447 free ((char *) cur_pred);
448 parse_print (argv, &argc);
450 else if (!default_prints (predicates->pred_next))
452 /* One or more predicates that produce output were given;
453 remove the unneeded initial `('. */
454 cur_pred = predicates;
455 predicates = predicates->pred_next;
456 free ((char *) cur_pred);
458 else
460 /* `( user-supplied-expression ) -print'. */
461 parse_close (argv, &argc);
462 parse_print (argv, &argc);
465 #ifdef DEBUG
466 printf (_("Predicate List:\n"));
467 print_list (predicates);
468 #endif /* DEBUG */
470 /* Done parsing the predicates. Build the evaluation tree. */
471 cur_pred = predicates;
472 eval_tree = get_expr (&cur_pred, NO_PREC);
474 /* Check if we have any left-over predicates (this fixes
475 * Debian bug #185202).
477 if (cur_pred != NULL)
479 error (1, 0, _("unexpected extra predicate"));
482 #ifdef DEBUG
483 printf (_("Eval Tree:\n"));
484 print_tree (eval_tree, 0);
485 #endif /* DEBUG */
487 /* Rearrange the eval tree in optimal-predicate order. */
488 opt_expr (&eval_tree);
490 /* Determine the point, if any, at which to stat the file. */
491 mark_stat (eval_tree);
493 #ifdef DEBUG
494 printf (_("Optimized Eval Tree:\n"));
495 print_tree (eval_tree, 0);
496 #endif /* DEBUG */
498 starting_desc = open (".", O_RDONLY);
499 if (0 <= starting_desc && fchdir (starting_desc) != 0)
501 close (starting_desc);
502 starting_desc = -1;
504 if (starting_desc < 0)
506 starting_dir = xgetcwd ();
507 if (! starting_dir)
508 error (1, errno, _("cannot get current directory"));
510 if ((*xstat) (".", &starting_stat_buf) != 0)
511 error (1, errno, _("cannot get current directory"));
513 /* If no paths are given, default to ".". */
514 for (i = end_of_leading_options; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
516 process_top_path (argv[i]);
519 /* If there were no path arguments, default to ".". */
520 if (i == end_of_leading_options)
523 * We use a temporary variable here because some actions modify
524 * the path temporarily. Hence if we use a string constant,
525 * we get a coredump. The best example of this is if we say
526 * "find -printf %H" (note, not "find . -printf %H").
528 char defaultpath[2] = ".";
529 process_top_path (defaultpath);
533 return exit_status;
537 static char *
538 specific_dirname(const char *dir)
540 char dirname[1024];
542 if (0 == strcmp(".", dir))
544 /* OK, what's '.'? */
545 if (NULL != getcwd(dirname, sizeof(dirname)))
547 return strdup(dirname);
549 else
551 return strdup(dir);
554 else
556 const char *result = canonicalize_filename_mode(dir, CAN_EXISTING);
557 if (NULL == result)
558 return strdup(dir);
559 else
560 return result;
564 static dev_t *mounted_devices = NULL;
565 static size_t num_mounted_devices = 0u;
568 static void
569 init_mounted_dev_list()
571 assert(NULL == mounted_devices);
572 assert(0 == num_mounted_devices);
573 mounted_devices = get_mounted_devices(&num_mounted_devices);
576 static void
577 refresh_mounted_dev_list(void)
579 if (mounted_devices)
581 free(mounted_devices);
582 mounted_devices = 0;
584 num_mounted_devices = 0u;
585 init_mounted_dev_list();
589 /* Search for device DEV in the array LIST, which is of size N. */
590 static int
591 dev_present(dev_t dev, const dev_t *list, size_t n)
593 if (list)
595 while (n-- > 0u)
597 if ( (*list++) == dev )
598 return 1;
601 return 0;
604 enum MountPointStateChange
606 MountPointRecentlyMounted,
607 MountPointRecentlyUnmounted,
608 MountPointStateUnchanged
613 static enum MountPointStateChange
614 get_mount_state(dev_t newdev)
616 int new_is_present, new_was_present;
618 new_was_present = dev_present(newdev, mounted_devices, num_mounted_devices);
619 refresh_mounted_dev_list();
620 new_is_present = dev_present(newdev, mounted_devices, num_mounted_devices);
622 if (new_was_present == new_is_present)
623 return MountPointStateUnchanged;
624 else if (new_is_present)
625 return MountPointRecentlyMounted;
626 else
627 return MountPointRecentlyUnmounted;
631 /* Return non-zero if FS is the name of a filesystem that is likely to
632 * be automounted
634 static int
635 fs_likely_to_be_automounted(const char *fs)
637 return ( (0==strcmp(fs, "nfs")) || (0==strcmp(fs, "autofs")));
640 enum WdSanityCheckFatality
642 FATAL_IF_SANITY_CHECK_FAILS,
643 NON_FATAL_IF_SANITY_CHECK_FAILS
647 /* Examine the results of the stat() of a directory from before we
648 * entered or left it, with the results of stat()ing it afterward. If
649 * these are different, the filesystem tree has been modified while we
650 * were traversing it. That might be an attempt to use a race
651 * condition to persuade find to do something it didn't intend
652 * (e.g. an attempt by an ordinary user to exploit the fact that root
653 * sometimes runs find on the whole filesystem). However, this can
654 * also happen if automount is running (certainly on Solaris). With
655 * automount, moving into a directory can cause a filesystem to be
656 * mounted there.
658 * To cope sensibly with this, we will raise an error if we see the
659 * device number change unless we are chdir()ing into a subdirectory,
660 * and the directory we moved into has been mounted or unmounted "recently".
661 * Here "recently" means since we started "find" or we last re-read
662 * the /etc/mnttab file.
664 * If the device number does not change but the inode does, that is a
665 * problem.
667 * If the device number and inode are both the same, we are happy.
669 * If a filesystem is (un)mounted as we chdir() into the directory, that
670 * may mean that we're now examining a section of the filesystem that might
671 * have been excluded from consideration (via -prune or -quit for example).
672 * Hence we print a warning message to indicate that the output of find
673 * might be inconsistent due to the change in the filesystem.
675 static boolean
676 wd_sanity_check(const char *thing_to_stat,
677 const char *program_name,
678 const char *what,
679 dev_t old_dev,
680 ino_t old_ino,
681 struct stat *newinfo,
682 int parent,
683 int line_no,
684 enum TraversalDirection direction,
685 enum WdSanityCheckFatality isfatal,
686 boolean *changed) /* output parameter */
688 const char *fstype;
689 char *specific_what = NULL;
690 int silent = 0;
692 *changed = false;
694 if ((*xstat) (".", newinfo) != 0)
695 error (1, errno, "%s", thing_to_stat);
697 if (old_dev != newinfo->st_dev)
699 *changed = true;
700 specific_what = specific_dirname(what);
701 fstype = filesystem_type(thing_to_stat, ".", newinfo);
702 silent = fs_likely_to_be_automounted(fstype);
704 /* This condition is rare, so once we are here it is
705 * reasonable to perform an expensive computation to
706 * determine if we should continue or fail.
708 if (TraversingDown == direction)
710 /* We stat()ed a directory, chdir()ed into it (we know this
711 * since direction is TraversingDown), stat()ed it again,
712 * and noticed that the device numbers are different. Check
713 * if the filesystem was recently mounted.
715 * If it was, it looks like chdir()ing into the directory
716 * caused a filesystem to be mounted. Maybe automount is
717 * running. Anyway, that's probably OK - but it happens
718 * only when we are moving downward.
720 * We also allow for the possibility that a similar thing
721 * has happened with the unmounting of a filesystem. This
722 * is much rarer, as it relies on an automounter timeout
723 * occurring at exactly the wrong moment.
725 enum MountPointStateChange transition = get_mount_state(newinfo->st_dev);
726 switch (transition)
728 case MountPointRecentlyUnmounted:
729 isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
730 if (!silent)
732 error (0, 0,
733 _("Warning: filesystem %s has recently been unmounted."),
734 specific_what);
736 break;
738 case MountPointRecentlyMounted:
739 isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
740 if (!silent)
742 error (0, 0,
743 _("Warning: filesystem %s has recently been mounted."),
744 specific_what);
746 break;
748 case MountPointStateUnchanged:
749 /* leave isfatal as it is */
750 break;
754 if (FATAL_IF_SANITY_CHECK_FAILS == isfatal)
756 fstype = filesystem_type(thing_to_stat, ".", newinfo);
757 error (1, 0,
758 _("%s%s changed during execution of %s (old device number %ld, new device number %ld, filesystem type is %s) [ref %ld]"),
759 specific_what,
760 parent ? "/.." : "",
761 program_name,
762 (long) old_dev,
763 (long) newinfo->st_dev,
764 fstype,
765 line_no);
766 /*NOTREACHED*/
767 return false;
769 else
771 /* Since the device has changed under us, the inode number
772 * will almost certainly also be different. However, we have
773 * already decided that this is not a problem. Hence we return
774 * without checking the inode number.
776 free(specific_what);
777 return true;
781 /* Device number was the same, check if the inode has changed. */
782 if (old_ino != newinfo->st_ino)
784 *changed = true;
785 specific_what = specific_dirname(what);
786 fstype = filesystem_type(thing_to_stat, ".", newinfo);
788 error ((isfatal == FATAL_IF_SANITY_CHECK_FAILS) ? 1 : 0,
789 0, /* no relevant errno value */
790 _("%s%s changed during execution of %s (old inode number %ld, new inode number %ld, filesystem type is %s) [ref %ld]"),
791 specific_what,
792 parent ? "/.." : "",
793 program_name,
794 (long) old_ino,
795 (long) newinfo->st_ino,
796 fstype,
797 line_no);
798 free(specific_what);
799 return false;
802 return true;
805 enum SafeChdirStatus
807 SafeChdirOK,
808 SafeChdirFailSymlink,
809 SafeChdirFailNotDir,
810 SafeChdirFailStat,
811 SafeChdirFailWouldBeUnableToReturn,
812 SafeChdirFailChdirFailed,
813 SafeChdirFailNonexistent
816 /* Safely perform a change in directory.
819 static int
820 safely_chdir(const char *dest, enum TraversalDirection direction)
822 struct stat statbuf_dest, statbuf_arrived;
823 int rv, dotfd=-1;
824 int saved_errno; /* specific_dirname() changes errno. */
825 char *name = NULL;
826 boolean rv_set = false;
828 saved_errno = errno = 0;
829 dotfd = open(".", O_RDONLY);
830 if (dotfd >= 0)
832 /* Stat the directory we're going to. */
833 if (0 == xstat(dest, &statbuf_dest))
835 #ifdef S_ISLNK
836 if (!following_links() && S_ISLNK(statbuf_dest.st_mode))
838 rv = SafeChdirFailSymlink;
839 rv_set = true;
840 saved_errno = 0; /* silence the error message */
841 goto fail;
843 #endif
844 #ifdef S_ISDIR
845 /* Although the immediately following chdir() would detect
846 * the fact that this is not a directory for us, this would
847 * result in an extra system call that fails. Anybody
848 * examining the system-call trace should ideally not be
849 * concerned that something is actually failing.
851 if (!S_ISDIR(statbuf_dest.st_mode))
853 rv = SafeChdirFailNotDir;
854 rv_set = true;
855 saved_errno = 0; /* silence the error message */
856 goto fail;
858 #endif
859 if (0 == chdir(dest))
861 /* check we ended up where we wanted to go */
862 boolean changed = false;
863 wd_sanity_check(".", program_name, ".",
864 statbuf_dest.st_dev,
865 statbuf_dest.st_ino,
866 &statbuf_arrived,
867 0, __LINE__, direction,
868 FATAL_IF_SANITY_CHECK_FAILS,
869 &changed);
870 close(dotfd);
871 return SafeChdirOK;
873 else
875 saved_errno = errno;
876 if (ENOENT == saved_errno)
878 rv = SafeChdirFailNonexistent;
879 rv_set = true;
880 if (ignore_readdir_race)
881 errno = 0; /* don't issue err msg */
882 else
883 name = specific_dirname(dest);
885 else if (ENOTDIR == saved_errno)
887 /* This can happen if the we stat a directory,
888 * and then filesystem activity changes it into
889 * a non-directory.
891 saved_errno = 0; /* don't issue err msg */
892 rv = SafeChdirFailNotDir;
893 rv_set = true;
895 else
897 rv = SafeChdirFailChdirFailed;
898 rv_set = true;
900 goto fail;
903 else
905 saved_errno = errno;
906 rv = SafeChdirFailStat;
907 rv_set = true;
908 name = specific_dirname(dest);
909 if ( (ENOENT == saved_errno) || (0 == curdepth))
910 saved_errno = 0; /* don't issue err msg */
911 goto fail;
914 else
916 /* We do not have read permissions on "." */
917 rv = SafeChdirFailWouldBeUnableToReturn;
918 rv_set = true;
919 goto fail;
922 saved_errno = 0;
924 /* We use the same exit path for successs or failure.
925 * which has occurred is recorded in RV.
927 fail:
928 if (saved_errno)
930 if (NULL == name)
931 name = specific_dirname(".");
932 error(0, saved_errno, "%s", name);
935 free(name);
936 name = NULL;
938 if (dotfd >= 0)
940 close(dotfd);
941 dotfd = -1;
943 assert(rv_set);
944 return rv;
948 /* Safely go back to the starting directory. */
949 static void
950 chdir_back (void)
952 struct stat stat_buf;
953 boolean dummy;
955 if (starting_desc < 0)
957 if (chdir (starting_dir) != 0)
958 error (1, errno, "%s", starting_dir);
960 wd_sanity_check(starting_dir,
961 program_name,
962 starting_dir,
963 starting_stat_buf.st_dev,
964 starting_stat_buf.st_ino,
965 &stat_buf, 0, __LINE__,
966 TraversingUp,
967 FATAL_IF_SANITY_CHECK_FAILS,
968 &dummy);
970 else
972 if (fchdir (starting_desc) != 0)
973 error (1, errno, "%s", starting_dir);
977 /* Descend PATHNAME, which is a command-line argument. */
979 static void
980 process_top_path (char *pathname)
982 struct stat stat_buf, cur_stat_buf;
983 boolean dummy;
985 curdepth = 0;
986 path_length = strlen (pathname);
988 /* We stat each pathname given on the command-line twice --
989 once here and once in process_path. It's not too bad, though,
990 since the kernel can read the stat information out of its inode
991 cache the second time. */
992 #if 0
993 if ((*xstat) (pathname, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode))
995 if (chdir (pathname) < 0)
997 if (!ignore_readdir_race || (errno != ENOENT) )
999 error (0, errno, "%s", pathname);
1000 exit_status = 1;
1002 return;
1005 /* Check that we are where we should be. */
1006 wd_sanity_check(pathname, program_name,
1007 ".",
1008 stat_buf.st_dev,
1009 stat_buf.st_ino,
1010 &cur_stat_buf, 0, __LINE__,
1011 TraversingDown,
1012 FATAL_IF_SANITY_CHECK_FAILS,
1013 &dummy);
1015 process_path (pathname, ".", false, ".");
1016 chdir_back ();
1018 else
1020 process_path (pathname, pathname, false, ".");
1022 #else
1023 enum SafeChdirStatus rv = safely_chdir(pathname, TraversingDown);
1025 switch (rv)
1027 case SafeChdirOK:
1028 process_path (pathname, ".", false, ".");
1029 chdir_back ();
1030 return;
1032 case SafeChdirFailNonexistent:
1033 case SafeChdirFailStat:
1034 case SafeChdirFailWouldBeUnableToReturn:
1035 case SafeChdirFailSymlink:
1036 case SafeChdirFailNotDir:
1037 case SafeChdirFailChdirFailed:
1038 if ((SafeChdirFailNonexistent==rv) && !ignore_readdir_race)
1040 error (0, errno, "%s", pathname);
1041 exit_status = 1;
1043 else
1045 process_path (pathname, pathname, false, ".");
1047 chdir_back ();
1048 return;
1050 #endif
1053 /* Info on each directory in the current tree branch, to avoid
1054 getting stuck in symbolic link loops. */
1055 struct dir_id
1057 ino_t ino;
1058 dev_t dev;
1060 static struct dir_id *dir_ids = NULL;
1061 /* Entries allocated in `dir_ids'. */
1062 static int dir_alloc = 0;
1063 /* Index in `dir_ids' of directory currently being searched.
1064 This is always the last valid entry. */
1065 static int dir_curr = -1;
1066 /* (Arbitrary) number of entries to grow `dir_ids' by. */
1067 #define DIR_ALLOC_STEP 32
1071 /* We've detected a filesystem loop. This is caused by one of
1072 * two things:
1074 * 1. Option -L is in effect and we've hit a symbolic link that
1075 * points to an ancestor. This is harmless. We won't traverse the
1076 * symbolic link.
1078 * 2. We have hit a real cycle in the directory hierarchy. In this
1079 * case, we issue a diagnostic message (POSIX requires this) and we
1080 * skip that directory entry.
1082 static void
1083 issue_loop_warning(const char *name, const char *pathname, int level)
1085 struct stat stbuf_link;
1086 if (lstat(name, &stbuf_link) != 0)
1087 stbuf_link.st_mode = S_IFREG;
1089 if (!S_ISLNK(stbuf_link.st_mode))
1091 int distance = 1 + (dir_curr-level);
1092 /* We have found an infinite loop. POSIX requires us to
1093 * issue a diagnostic. Usually we won't get to here
1094 * because when the leaf optimisation is on, it will cause
1095 * the subdirectory to be skipped. If /a/b/c/d is a hard
1096 * link to /a/b, then the link count of /a/b/c is 2,
1097 * because the ".." entry of /b/b/c/d points to /a, not
1098 * to /a/b/c.
1100 error(0, 0,
1101 _("Filesystem loop detected; `%s' has the same device number and inode as a directory which is %d %s."),
1102 pathname,
1103 distance,
1104 (distance == 1 ?
1105 _("level higher in the filesystem hierarchy") :
1106 _("levels higher in the filesystem hierarchy")));
1110 /* Recursively descend path PATHNAME, applying the predicates.
1111 LEAF is true if PATHNAME is known to be in a directory that has no
1112 more unexamined subdirectories, and therefore it is not a directory.
1113 Knowing this allows us to avoid calling stat as long as possible for
1114 leaf files.
1116 NAME is PATHNAME relative to the current directory. We access NAME
1117 but print PATHNAME.
1119 PARENT is the path of the parent of NAME, relative to find's
1120 starting directory.
1122 Return nonzero iff PATHNAME is a directory. */
1124 static int
1125 process_path (char *pathname, char *name, boolean leaf, char *parent)
1127 struct stat stat_buf;
1128 static dev_t root_dev; /* Device ID of current argument pathname. */
1129 int i;
1131 /* Assume it is a non-directory initially. */
1132 stat_buf.st_mode = 0;
1134 rel_pathname = name;
1136 if (leaf)
1137 have_stat = false;
1138 else
1140 if ((*xstat) (name, &stat_buf) != 0)
1142 if (!ignore_readdir_race || (errno != ENOENT) )
1144 error (0, errno, "%s", pathname);
1145 exit_status = 1;
1147 return 0;
1149 have_stat = true;
1152 if (!S_ISDIR (stat_buf.st_mode))
1154 if (curdepth >= mindepth)
1155 apply_predicate (pathname, &stat_buf, eval_tree);
1156 return 0;
1159 /* From here on, we're working on a directory. */
1161 stop_at_current_level = maxdepth >= 0 && curdepth >= maxdepth;
1163 /* If we've already seen this directory on this branch,
1164 don't descend it again. */
1165 for (i = 0; i <= dir_curr; i++)
1166 if (stat_buf.st_ino == dir_ids[i].ino &&
1167 stat_buf.st_dev == dir_ids[i].dev)
1169 stop_at_current_level = true;
1170 issue_loop_warning(name, pathname, i);
1173 if (dir_alloc <= ++dir_curr)
1175 dir_alloc += DIR_ALLOC_STEP;
1176 dir_ids = (struct dir_id *)
1177 xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id));
1179 dir_ids[dir_curr].ino = stat_buf.st_ino;
1180 dir_ids[dir_curr].dev = stat_buf.st_dev;
1182 if (stay_on_filesystem)
1184 if (curdepth == 0)
1185 root_dev = stat_buf.st_dev;
1186 else if (stat_buf.st_dev != root_dev)
1187 stop_at_current_level = true;
1190 if (do_dir_first && curdepth >= mindepth)
1191 apply_predicate (pathname, &stat_buf, eval_tree);
1193 #ifdef DEBUG
1194 fprintf(stderr, "pathname = %s, stop_at_current_level = %d\n",
1195 pathname, stop_at_current_level);
1196 #endif /* DEBUG */
1198 if (stop_at_current_level == false)
1199 /* Scan directory on disk. */
1200 process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
1202 if (do_dir_first == false && curdepth >= mindepth)
1204 rel_pathname = name;
1205 apply_predicate (pathname, &stat_buf, eval_tree);
1208 dir_curr--;
1210 return 1;
1213 /* Scan directory PATHNAME and recurse through process_path for each entry.
1215 PATHLEN is the length of PATHNAME.
1217 NAME is PATHNAME relative to the current directory.
1219 STATP is the results of *xstat on it.
1221 PARENT is the path of the parent of NAME, relative to find's
1222 starting directory. */
1224 static void
1225 process_dir (char *pathname, char *name, int pathlen, struct stat *statp, char *parent)
1227 char *name_space; /* Names of files in PATHNAME. */
1228 int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */
1229 struct stat stat_buf;
1231 subdirs_left = statp->st_nlink - 2; /* Account for name and ".". */
1233 errno = 0;
1234 name_space = savedir (name);
1235 if (name_space == NULL)
1237 if (errno)
1239 error (0, errno, "%s", pathname);
1240 exit_status = 1;
1242 else
1243 error (1, 0, _("virtual memory exhausted"));
1245 else
1247 register char *namep; /* Current point in `name_space'. */
1248 char *cur_path; /* Full path of each file to process. */
1249 char *cur_name; /* Base name of each file to process. */
1250 unsigned cur_path_size; /* Bytes allocated for `cur_path'. */
1251 register unsigned file_len; /* Length of each path to process. */
1252 register unsigned pathname_len; /* PATHLEN plus trailing '/'. */
1254 if (pathname[pathlen - 1] == '/')
1255 pathname_len = pathlen + 1; /* For '\0'; already have '/'. */
1256 else
1257 pathname_len = pathlen + 2; /* For '/' and '\0'. */
1258 cur_path_size = 0;
1259 cur_path = NULL;
1261 if (strcmp (name, ".") && chdir (name) < 0)
1263 error (0, errno, "%s", pathname);
1264 exit_status = 1;
1265 return;
1268 /* Check that we are where we should be. */
1269 if (1)
1271 boolean changed = false;
1272 wd_sanity_check(pathname,
1273 program_name,
1274 ".",
1275 dir_ids[dir_curr].dev,
1276 dir_ids[dir_curr].ino,
1277 &stat_buf, 0, __LINE__,
1278 TraversingDown,
1279 FATAL_IF_SANITY_CHECK_FAILS,
1280 &changed);
1281 if (changed)
1283 /* If there had been a change but wd_sanity_check()
1284 * accepted it, we need to accept that on the
1285 * way back up as well, so modify our record
1286 * of what we think we should see later.
1288 dir_ids[dir_curr].dev = stat_buf.st_dev;
1289 dir_ids[dir_curr].ino = stat_buf.st_ino;
1293 for (namep = name_space; *namep; namep += file_len - pathname_len + 1)
1295 /* Append this directory entry's name to the path being searched. */
1296 file_len = pathname_len + strlen (namep);
1297 if (file_len > cur_path_size)
1299 while (file_len > cur_path_size)
1300 cur_path_size += 1024;
1301 if (cur_path)
1302 free (cur_path);
1303 cur_path = xmalloc (cur_path_size);
1304 strcpy (cur_path, pathname);
1305 cur_path[pathname_len - 2] = '/';
1307 cur_name = cur_path + pathname_len - 1;
1308 strcpy (cur_name, namep);
1310 curdepth++;
1311 if (!no_leaf_check)
1312 /* Normal case optimization.
1313 On normal Unix filesystems, a directory that has no
1314 subdirectories has two links: its name, and ".". Any
1315 additional links are to the ".." entries of its
1316 subdirectories. Once we have processed as many
1317 subdirectories as there are additional links, we know
1318 that the rest of the entries are non-directories --
1319 in other words, leaf files. */
1320 subdirs_left -= process_path (cur_path, cur_name,
1321 subdirs_left == 0, pathname);
1322 else
1323 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
1324 mounted, which don't have Unix-like directory link counts. */
1325 process_path (cur_path, cur_name, false, pathname);
1326 curdepth--;
1329 if (strcmp (name, "."))
1331 /* We could go back and do the next command-line arg
1332 instead, maybe using longjmp. */
1333 char const *dir;
1334 boolean deref = following_links() ? true : false;
1336 if (!deref)
1337 dir = "..";
1338 else
1340 chdir_back ();
1341 dir = parent;
1344 if (chdir (dir) != 0)
1345 error (1, errno, "%s", parent);
1347 /* Check that we are where we should be. */
1348 if (1)
1350 boolean changed = false;
1351 struct stat tmp;
1352 int problem_is_with_parent;
1354 memset(&tmp, 0, sizeof(tmp));
1355 if (dir_curr > 0)
1357 tmp.st_dev = dir_ids[dir_curr-1].dev;
1358 tmp.st_ino = dir_ids[dir_curr-1].ino;
1360 else
1362 tmp.st_dev = starting_stat_buf.st_dev;
1363 tmp.st_ino = starting_stat_buf.st_ino;
1366 problem_is_with_parent = deref ? 1 : 0;
1367 wd_sanity_check(pathname,
1368 program_name,
1369 parent,
1370 tmp.st_dev,
1371 tmp.st_ino,
1372 &stat_buf,
1373 problem_is_with_parent, __LINE__,
1374 TraversingUp,
1375 FATAL_IF_SANITY_CHECK_FAILS,
1376 &changed);
1380 if (cur_path)
1381 free (cur_path);
1382 free (name_space);
1386 /* Return true if there are no predicates with no_default_print in
1387 predicate list PRED, false if there are any.
1388 Returns true if default print should be performed */
1390 static boolean
1391 default_prints (struct predicate *pred)
1393 while (pred != NULL)
1395 if (pred->no_default_print)
1396 return (false);
1397 pred = pred->pred_next;
1399 return (true);