Fixed Savannah bug #3919: use mktemp instead of tempfile
[findutils.git] / find / find.c
blobf2af6d91d3c829658b66bfefbb420d882d6761aa
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 #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;
89 /* If true, process directory before contents. True unless -depth given. */
90 boolean do_dir_first;
92 /* If >=0, don't descend more than this many levels of subdirectories. */
93 int maxdepth;
95 /* If >=0, don't process files above this level. */
96 int mindepth;
98 /* Current depth; 0 means current path is a command line arg. */
99 int curdepth;
101 /* Output block size. */
102 int output_block_size;
104 /* Time at start of execution. */
105 time_t start_time;
107 /* Seconds between 00:00 1/1/70 and either one day before now
108 (the default), or the start of today (if -daystart is given). */
109 time_t cur_day_start;
111 /* If true, cur_day_start has been adjusted to the start of the day. */
112 boolean full_days;
114 /* If true, do not assume that files in directories with nlink == 2
115 are non-directories. */
116 boolean no_leaf_check;
118 /* If true, don't cross filesystem boundaries. */
119 boolean stay_on_filesystem;
121 /* If true, don't descend past current directory.
122 Can be set by -prune, -maxdepth, and -xdev/-mount. */
123 boolean stop_at_current_level;
125 /* The full path of the initial working directory, or "." if
126 STARTING_DESC is nonnegative. */
127 char const *starting_dir = ".";
129 /* A file descriptor open to the initial working directory.
130 Doing it this way allows us to work when the i.w.d. has
131 unreadable parents. */
132 int starting_desc;
134 /* The stat buffer of the initial working directory. */
135 struct stat starting_stat_buf;
137 /* If true, we have called stat on the current path. */
138 boolean have_stat;
140 /* The file being operated on, relative to the current directory.
141 Used for stat, readlink, remove, and opendir. */
142 char *rel_pathname;
144 /* Length of current path. */
145 int path_length;
147 /* true if following symlinks. Should be consistent with xstat. */
148 /* boolean dereference; */
149 enum SymlinkOption symlink_handling;
152 /* Pointer to the function used to stat files. */
153 int (*xstat) ();
155 /* Status value to return to system. */
156 int exit_status;
158 /* If true, we ignore the problem where we find that a directory entry
159 * no longer exists by the time we get around to processing it.
161 boolean ignore_readdir_race;
164 /* If true, we issue warning messages
166 boolean warnings;
169 enum TraversalDirection
171 TraversingUp,
172 TraversingDown
176 static int
177 following_links(void)
179 switch (symlink_handling)
181 case SYMLINK_ALWAYS_DEREF:
182 return 1;
183 case SYMLINK_DEREF_ARGSONLY:
184 return (curdepth == 0);
185 case SYMLINK_NEVER_DEREF:
186 default:
187 return 0;
192 static int
193 fallback_stat(const char *name, struct stat *p, int prev_rv)
195 /* Our original stat() call failed. Perhaps we can't follow a
196 * symbolic link. If that might be the problem, lstat() the link.
197 * Otherwise, admit defeat.
199 switch (errno)
201 case ENOENT:
202 case ENOTDIR:
203 return lstat(name, p);
205 case EACCES:
206 case EIO:
207 case ELOOP:
208 case ENAMETOOLONG:
209 case EOVERFLOW:
210 default:
211 return prev_rv;
216 /* optionh_stat() implements the stat operation when the -H option is
217 * in effect.
219 * If the item to be examined is a command-line argument, we follow
220 * symbolic links. If the stat() call fails on the command-line item,
221 * we fall back on the properties of the symbolic link.
223 * If the item to be examined is not a command-line argument, we
224 * examine the link itself.
226 int
227 optionh_stat(const char *name, struct stat *p)
229 if (0 == curdepth)
231 /* This file is from the command line; deference the link (if it
232 * is a link).
234 int rv = stat(name, p);
235 if (0 == rv)
236 return 0; /* success */
237 else
238 return fallback_stat(name, p, rv);
240 else
242 /* Not a file on the command line; do not derefernce the link.
244 return lstat(name, p);
248 /* optionl_stat() implements the stat operation when the -L option is
249 * in effect. That option makes us examine the thing the symbolic
250 * link points to, not the symbolic link itself.
252 int
253 optionl_stat(const char *name, struct stat *p)
255 int rv = stat(name, p);
256 if (0 == rv)
257 return 0; /* normal case. */
258 else
259 return fallback_stat(name, p, rv);
262 /* optionp_stat() implements the stat operation when the -P option is
263 * in effect (this is also the default). That option makes us examine
264 * the symbolic link itself, not the thing it points to.
266 int
267 optionp_stat(const char *name, struct stat *p)
269 return lstat(name, p);
272 #ifdef DEBUG_STAT
273 static int
274 debug_stat (const char *file, struct stat *bufp)
276 fprintf (stderr, "debug_stat (%s)\n", file);
277 switch (symlink_handling)
279 case SYMLINK_ALWAYS_DEREF:
280 return optionl_stat(file, bufp);
281 case SYMLINK_DEREF_ARGSONLY:
282 return optionh_stat(file, bufp);
283 case SYMLINK_NEVER_DEREF:
284 return optionp_stat(file, bufp);
287 #endif /* DEBUG_STAT */
289 void
290 set_follow_state(enum SymlinkOption opt)
292 switch (opt)
294 case SYMLINK_ALWAYS_DEREF: /* -L */
295 xstat = optionl_stat;
296 no_leaf_check = true;
297 break;
299 case SYMLINK_NEVER_DEREF: /* -P (default) */
300 xstat = optionp_stat;
301 /* Can't turn no_leaf_check off because the user might have specified
302 * -noleaf anyway
304 break;
306 case SYMLINK_DEREF_ARGSONLY: /* -H */
307 xstat = optionh_stat;
308 no_leaf_check = true;
311 symlink_handling = opt;
313 /* For DBEUG_STAT, the choice is made at runtime within debug_stat()
314 * by checking the contents of the symlink_handling variable.
316 #if defined(DEBUG_STAT)
317 xstat = debug_stat;
318 #endif /* !DEBUG_STAT */
323 main (int argc, char **argv)
325 int i;
326 PFB parse_function; /* Pointer to the function which parses. */
327 struct predicate *cur_pred;
328 char *predicate_name; /* Name of predicate being parsed. */
329 int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
330 program_name = argv[0];
332 #ifdef HAVE_SETLOCALE
333 setlocale (LC_ALL, "");
334 #endif
335 bindtextdomain (PACKAGE, LOCALEDIR);
336 textdomain (PACKAGE);
338 if (isatty(0))
340 warnings = true;
342 else
344 warnings = false;
348 predicates = NULL;
349 last_pred = NULL;
350 do_dir_first = true;
351 maxdepth = mindepth = -1;
352 start_time = time (NULL);
353 cur_day_start = start_time - DAYSECS;
354 full_days = false;
355 stay_on_filesystem = false;
356 ignore_readdir_race = false;
357 exit_status = 0;
359 #if defined(DEBUG_STAT)
360 xstat = debug_stat;
361 #endif /* !DEBUG_STAT */
363 #if 0
364 human_block_size (getenv ("FIND_BLOCK_SIZE"), 0, &output_block_size);
365 #else
366 if (getenv("POSIXLY_CORRECT"))
367 output_block_size = 512;
368 else
369 output_block_size = 1024;
371 if (getenv("FIND_BLOCK_SIZE"))
373 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"));
376 no_leaf_check = false;
377 set_follow_state(SYMLINK_NEVER_DEREF); /* The default is equivalent to -P. */
379 init_mounted_dev_list();
381 #endif
383 #ifdef DEBUG
384 printf ("cur_day_start = %s", ctime (&cur_day_start));
385 #endif /* DEBUG */
387 /* Check for -P, -H or -L options. */
388 for (i=1; (end_of_leading_options = i) < argc; ++i)
390 if (0 == strcmp("-H", argv[i]))
392 /* Meaning: dereference symbolic links on command line, but nowhere else. */
393 set_follow_state(SYMLINK_DEREF_ARGSONLY);
395 else if (0 == strcmp("-L", argv[i]))
397 /* Meaning: dereference all symbolic links. */
398 set_follow_state(SYMLINK_ALWAYS_DEREF);
400 else if (0 == strcmp("-P", argv[i]))
402 /* Meaning: never dereference symbolic links (default). */
403 set_follow_state(SYMLINK_NEVER_DEREF);
405 else if (0 == strcmp("--", argv[i]))
407 /* -- signifies the end of options. */
408 end_of_leading_options = i+1; /* Next time start with the next option */
409 break;
411 else
413 /* Hmm, must be one of
414 * (a) A path name
415 * (b) A predicate
417 end_of_leading_options = i; /* Next time start with this option */
418 break;
422 /* We are now processing the part of the "find" command line
423 * after the -H/-L options (if any).
426 /* fprintf(stderr, "rest: optind=%ld\n", (long)optind); */
428 /* Find where in ARGV the predicates begin. */
429 for (i = end_of_leading_options; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
431 /* fprintf(stderr, "Looks like %s is not a predicate\n", argv[i]); */
432 /* Do nothing. */ ;
435 /* Enclose the expression in `( ... )' so a default -print will
436 apply to the whole expression. */
437 parse_open (argv, &argc);
438 /* Build the input order list. */
439 while (i < argc)
441 if (strchr ("-!(),", argv[i][0]) == NULL)
442 usage (_("paths must precede expression"));
443 predicate_name = argv[i];
444 parse_function = find_parser (predicate_name);
445 if (parse_function == NULL)
446 /* Command line option not recognized */
447 error (1, 0, _("invalid predicate `%s'"), predicate_name);
448 i++;
449 if (!(*parse_function) (argv, &i))
451 if (argv[i] == NULL)
452 /* Command line option requires an argument */
453 error (1, 0, _("missing argument to `%s'"), predicate_name);
454 else
455 error (1, 0, _("invalid argument `%s' to `%s'"),
456 argv[i], predicate_name);
459 if (predicates->pred_next == NULL)
461 /* No predicates that do something other than set a global variable
462 were given; remove the unneeded initial `(' and add `-print'. */
463 cur_pred = predicates;
464 predicates = last_pred = predicates->pred_next;
465 free ((char *) cur_pred);
466 parse_print (argv, &argc);
468 else if (!default_prints (predicates->pred_next))
470 /* One or more predicates that produce output were given;
471 remove the unneeded initial `('. */
472 cur_pred = predicates;
473 predicates = predicates->pred_next;
474 free ((char *) cur_pred);
476 else
478 /* `( user-supplied-expression ) -print'. */
479 parse_close (argv, &argc);
480 parse_print (argv, &argc);
483 #ifdef DEBUG
484 printf (_("Predicate List:\n"));
485 print_list (predicates);
486 #endif /* DEBUG */
488 /* Done parsing the predicates. Build the evaluation tree. */
489 cur_pred = predicates;
490 eval_tree = get_expr (&cur_pred, NO_PREC);
492 /* Check if we have any left-over predicates (this fixes
493 * Debian bug #185202).
495 if (cur_pred != NULL)
497 error (1, 0, _("unexpected extra predicate"));
500 #ifdef DEBUG
501 printf (_("Eval Tree:\n"));
502 print_tree (eval_tree, 0);
503 #endif /* DEBUG */
505 /* Rearrange the eval tree in optimal-predicate order. */
506 opt_expr (&eval_tree);
508 /* Determine the point, if any, at which to stat the file. */
509 mark_stat (eval_tree);
511 #ifdef DEBUG
512 printf (_("Optimized Eval Tree:\n"));
513 print_tree (eval_tree, 0);
514 #endif /* DEBUG */
516 starting_desc = open (".", O_RDONLY);
517 if (0 <= starting_desc && fchdir (starting_desc) != 0)
519 close (starting_desc);
520 starting_desc = -1;
522 if (starting_desc < 0)
524 starting_dir = xgetcwd ();
525 if (! starting_dir)
526 error (1, errno, _("cannot get current directory"));
528 if ((*xstat) (".", &starting_stat_buf) != 0)
529 error (1, errno, _("cannot get current directory"));
531 /* If no paths are given, default to ".". */
532 for (i = end_of_leading_options; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
534 process_top_path (argv[i]);
537 /* If there were no path arguments, default to ".". */
538 if (i == end_of_leading_options)
541 * We use a temporary variable here because some actions modify
542 * the path temporarily. Hence if we use a string constant,
543 * we get a coredump. The best example of this is if we say
544 * "find -printf %H" (note, not "find . -printf %H").
546 char defaultpath[2] = ".";
547 process_top_path (defaultpath);
551 return exit_status;
555 static char *
556 specific_dirname(const char *dir)
558 char dirname[1024];
560 if (0 == strcmp(".", dir))
562 /* OK, what's '.'? */
563 if (NULL != getcwd(dirname, sizeof(dirname)))
565 return strdup(dirname);
567 else
569 return strdup(dir);
572 else
574 char *result = canonicalize_filename_mode(dir, CAN_EXISTING);
575 if (NULL == result)
576 return strdup(dir);
577 else
578 return result;
582 static dev_t *mounted_devices = NULL;
583 static size_t num_mounted_devices = 0u;
586 static void
587 init_mounted_dev_list()
589 assert(NULL == mounted_devices);
590 assert(0 == num_mounted_devices);
591 mounted_devices = get_mounted_devices(&num_mounted_devices);
594 static void
595 refresh_mounted_dev_list(void)
597 if (mounted_devices)
599 free(mounted_devices);
600 mounted_devices = 0;
602 num_mounted_devices = 0u;
603 init_mounted_dev_list();
607 /* Search for device DEV in the array LIST, which is of size N. */
608 static int
609 dev_present(dev_t dev, const dev_t *list, size_t n)
611 if (list)
613 while (n-- > 0u)
615 if ( (*list++) == dev )
616 return 1;
619 return 0;
622 enum MountPointStateChange
624 MountPointRecentlyMounted,
625 MountPointRecentlyUnmounted,
626 MountPointStateUnchanged
631 static enum MountPointStateChange
632 get_mount_state(dev_t newdev)
634 int new_is_present, new_was_present;
636 new_was_present = dev_present(newdev, mounted_devices, num_mounted_devices);
637 refresh_mounted_dev_list();
638 new_is_present = dev_present(newdev, mounted_devices, num_mounted_devices);
640 if (new_was_present == new_is_present)
641 return MountPointStateUnchanged;
642 else if (new_is_present)
643 return MountPointRecentlyMounted;
644 else
645 return MountPointRecentlyUnmounted;
649 /* Return non-zero if FS is the name of a filesystem that is likely to
650 * be automounted
652 static int
653 fs_likely_to_be_automounted(const char *fs)
655 return ( (0==strcmp(fs, "nfs")) || (0==strcmp(fs, "autofs")));
658 enum WdSanityCheckFatality
660 FATAL_IF_SANITY_CHECK_FAILS,
661 NON_FATAL_IF_SANITY_CHECK_FAILS
665 /* Examine the results of the stat() of a directory from before we
666 * entered or left it, with the results of stat()ing it afterward. If
667 * these are different, the filesystem tree has been modified while we
668 * were traversing it. That might be an attempt to use a race
669 * condition to persuade find to do something it didn't intend
670 * (e.g. an attempt by an ordinary user to exploit the fact that root
671 * sometimes runs find on the whole filesystem). However, this can
672 * also happen if automount is running (certainly on Solaris). With
673 * automount, moving into a directory can cause a filesystem to be
674 * mounted there.
676 * To cope sensibly with this, we will raise an error if we see the
677 * device number change unless we are chdir()ing into a subdirectory,
678 * and the directory we moved into has been mounted or unmounted "recently".
679 * Here "recently" means since we started "find" or we last re-read
680 * the /etc/mnttab file.
682 * If the device number does not change but the inode does, that is a
683 * problem.
685 * If the device number and inode are both the same, we are happy.
687 * If a filesystem is (un)mounted as we chdir() into the directory, that
688 * may mean that we're now examining a section of the filesystem that might
689 * have been excluded from consideration (via -prune or -quit for example).
690 * Hence we print a warning message to indicate that the output of find
691 * might be inconsistent due to the change in the filesystem.
693 static boolean
694 wd_sanity_check(const char *thing_to_stat,
695 const char *program_name,
696 const char *what,
697 dev_t old_dev,
698 ino_t old_ino,
699 struct stat *newinfo,
700 int parent,
701 int line_no,
702 enum TraversalDirection direction,
703 enum WdSanityCheckFatality isfatal,
704 boolean *changed) /* output parameter */
706 const char *fstype;
707 char *specific_what = NULL;
708 int silent = 0;
710 *changed = false;
712 if ((*xstat) (".", newinfo) != 0)
713 error (1, errno, "%s", thing_to_stat);
715 if (old_dev != newinfo->st_dev)
717 *changed = true;
718 specific_what = specific_dirname(what);
719 fstype = filesystem_type(thing_to_stat, ".", newinfo);
720 silent = fs_likely_to_be_automounted(fstype);
722 /* This condition is rare, so once we are here it is
723 * reasonable to perform an expensive computation to
724 * determine if we should continue or fail.
726 if (TraversingDown == direction)
728 /* We stat()ed a directory, chdir()ed into it (we know this
729 * since direction is TraversingDown), stat()ed it again,
730 * and noticed that the device numbers are different. Check
731 * if the filesystem was recently mounted.
733 * If it was, it looks like chdir()ing into the directory
734 * caused a filesystem to be mounted. Maybe automount is
735 * running. Anyway, that's probably OK - but it happens
736 * only when we are moving downward.
738 * We also allow for the possibility that a similar thing
739 * has happened with the unmounting of a filesystem. This
740 * is much rarer, as it relies on an automounter timeout
741 * occurring at exactly the wrong moment.
743 enum MountPointStateChange transition = get_mount_state(newinfo->st_dev);
744 switch (transition)
746 case MountPointRecentlyUnmounted:
747 isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
748 if (!silent)
750 error (0, 0,
751 _("Warning: filesystem %s has recently been unmounted."),
752 specific_what);
754 break;
756 case MountPointRecentlyMounted:
757 isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
758 if (!silent)
760 error (0, 0,
761 _("Warning: filesystem %s has recently been mounted."),
762 specific_what);
764 break;
766 case MountPointStateUnchanged:
767 /* leave isfatal as it is */
768 break;
772 if (FATAL_IF_SANITY_CHECK_FAILS == isfatal)
774 fstype = filesystem_type(thing_to_stat, ".", newinfo);
775 error (1, 0,
776 _("%s%s changed during execution of %s (old device number %ld, new device number %ld, filesystem type is %s) [ref %ld]"),
777 specific_what,
778 parent ? "/.." : "",
779 program_name,
780 (long) old_dev,
781 (long) newinfo->st_dev,
782 fstype,
783 line_no);
784 /*NOTREACHED*/
785 return false;
787 else
789 /* Since the device has changed under us, the inode number
790 * will almost certainly also be different. However, we have
791 * already decided that this is not a problem. Hence we return
792 * without checking the inode number.
794 free(specific_what);
795 return true;
799 /* Device number was the same, check if the inode has changed. */
800 if (old_ino != newinfo->st_ino)
802 *changed = true;
803 specific_what = specific_dirname(what);
804 fstype = filesystem_type(thing_to_stat, ".", newinfo);
806 error ((isfatal == FATAL_IF_SANITY_CHECK_FAILS) ? 1 : 0,
807 0, /* no relevant errno value */
808 _("%s%s changed during execution of %s (old inode number %ld, new inode number %ld, filesystem type is %s) [ref %ld]"),
809 specific_what,
810 parent ? "/.." : "",
811 program_name,
812 (long) old_ino,
813 (long) newinfo->st_ino,
814 fstype,
815 line_no);
816 free(specific_what);
817 return false;
820 return true;
823 enum SafeChdirStatus
825 SafeChdirOK,
826 SafeChdirFailSymlink,
827 SafeChdirFailNotDir,
828 SafeChdirFailStat,
829 SafeChdirFailWouldBeUnableToReturn,
830 SafeChdirFailChdirFailed,
831 SafeChdirFailNonexistent
834 /* Safely perform a change in directory.
837 static int
838 safely_chdir(const char *dest,
839 enum TraversalDirection direction,
840 struct stat *statbuf_dest)
842 struct stat statbuf_arrived;
843 int rv, dotfd=-1;
844 int saved_errno; /* specific_dirname() changes errno. */
845 char *name = NULL;
846 boolean rv_set = false;
848 saved_errno = errno = 0;
849 dotfd = open(".", O_RDONLY);
850 if (dotfd >= 0)
852 /* Stat the directory we're going to. */
853 if (0 == xstat(dest, statbuf_dest))
855 #ifdef S_ISLNK
856 if (!following_links() && S_ISLNK(statbuf_dest->st_mode))
858 rv = SafeChdirFailSymlink;
859 rv_set = true;
860 saved_errno = 0; /* silence the error message */
861 goto fail;
863 #endif
864 #ifdef S_ISDIR
865 /* Although the immediately following chdir() would detect
866 * the fact that this is not a directory for us, this would
867 * result in an extra system call that fails. Anybody
868 * examining the system-call trace should ideally not be
869 * concerned that something is actually failing.
871 if (!S_ISDIR(statbuf_dest->st_mode))
873 rv = SafeChdirFailNotDir;
874 rv_set = true;
875 saved_errno = 0; /* silence the error message */
876 goto fail;
878 #endif
879 if (0 == chdir(dest))
881 /* check we ended up where we wanted to go */
882 boolean changed = false;
883 wd_sanity_check(".", program_name, ".",
884 statbuf_dest->st_dev,
885 statbuf_dest->st_ino,
886 &statbuf_arrived,
887 0, __LINE__, direction,
888 FATAL_IF_SANITY_CHECK_FAILS,
889 &changed);
890 close(dotfd);
891 return SafeChdirOK;
893 else
895 saved_errno = errno;
896 if (ENOENT == saved_errno)
898 rv = SafeChdirFailNonexistent;
899 rv_set = true;
900 if (ignore_readdir_race)
901 errno = 0; /* don't issue err msg */
902 else
903 name = specific_dirname(dest);
905 else if (ENOTDIR == saved_errno)
907 /* This can happen if the we stat a directory,
908 * and then filesystem activity changes it into
909 * a non-directory.
911 saved_errno = 0; /* don't issue err msg */
912 rv = SafeChdirFailNotDir;
913 rv_set = true;
915 else
917 rv = SafeChdirFailChdirFailed;
918 rv_set = true;
920 goto fail;
923 else
925 saved_errno = errno;
926 rv = SafeChdirFailStat;
927 rv_set = true;
928 name = specific_dirname(dest);
929 if ( (ENOENT == saved_errno) || (0 == curdepth))
930 saved_errno = 0; /* don't issue err msg */
931 goto fail;
934 else
936 /* We do not have read permissions on "." */
937 rv = SafeChdirFailWouldBeUnableToReturn;
938 rv_set = true;
939 goto fail;
942 saved_errno = 0;
944 /* We use the same exit path for successs or failure.
945 * which has occurred is recorded in RV.
947 fail:
948 if (saved_errno)
950 if (NULL == name)
951 name = specific_dirname(".");
952 error(0, saved_errno, "%s", name);
955 free(name);
956 name = NULL;
958 if (dotfd >= 0)
960 close(dotfd);
961 dotfd = -1;
963 assert(rv_set);
964 return rv;
968 /* Safely go back to the starting directory. */
969 static void
970 chdir_back (void)
972 struct stat stat_buf;
973 boolean dummy;
975 if (starting_desc < 0)
977 if (chdir (starting_dir) != 0)
978 error (1, errno, "%s", starting_dir);
980 wd_sanity_check(starting_dir,
981 program_name,
982 starting_dir,
983 starting_stat_buf.st_dev,
984 starting_stat_buf.st_ino,
985 &stat_buf, 0, __LINE__,
986 TraversingUp,
987 FATAL_IF_SANITY_CHECK_FAILS,
988 &dummy);
990 else
992 if (fchdir (starting_desc) != 0)
993 error (1, errno, "%s", starting_dir);
997 /* Descend PATHNAME, which is a command-line argument. */
998 static void
999 process_top_path (char *pathname)
1001 process_path (pathname, pathname, false, ".");
1005 static void
1006 old_process_top_path (char *pathname)
1008 struct stat stat_buf, cur_stat_buf;
1009 boolean dummy;
1011 curdepth = 0;
1012 path_length = strlen (pathname);
1014 /* We stat each pathname given on the command-line twice --
1015 once here and once in process_path. It's not too bad, though,
1016 since the kernel can read the stat information out of its inode
1017 cache the second time. */
1018 #if USE_SAFE_CHDIR
1019 if ((*xstat) (pathname, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode))
1021 enum SafeChdirStatus rv = safely_chdir(pathname, TraversingDown, &stat_buf);
1023 switch (rv)
1025 case SafeChdirOK:
1026 process_path (pathname, ".", false, ".");
1027 chdir_back ();
1028 return;
1030 case SafeChdirFailNonexistent:
1031 case SafeChdirFailStat:
1032 case SafeChdirFailWouldBeUnableToReturn:
1033 case SafeChdirFailSymlink:
1034 case SafeChdirFailNotDir:
1035 case SafeChdirFailChdirFailed:
1036 if ((SafeChdirFailNonexistent==rv) && !ignore_readdir_race)
1038 error (0, errno, "%s", pathname);
1039 exit_status = 1;
1041 else
1043 process_path (pathname, pathname, false, ".");
1045 chdir_back ();
1046 return;
1049 else
1051 /* Not a directory */
1052 process_path (pathname, pathname, false, ".");
1054 #else
1055 if ((*xstat) (pathname, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode))
1057 if (chdir (pathname) < 0)
1059 if (!ignore_readdir_race || (errno != ENOENT) )
1061 error (0, errno, "%s", pathname);
1062 exit_status = 1;
1064 return;
1067 /* Check that we are where we should be. */
1068 wd_sanity_check(pathname, program_name,
1069 ".",
1070 stat_buf.st_dev,
1071 stat_buf.st_ino,
1072 &cur_stat_buf, 0, __LINE__,
1073 TraversingDown,
1074 FATAL_IF_SANITY_CHECK_FAILS,
1075 &dummy);
1077 process_path (pathname, ".", false, ".");
1078 chdir_back ();
1080 else
1082 process_path (pathname, pathname, false, ".");
1084 #endif
1087 /* Info on each directory in the current tree branch, to avoid
1088 getting stuck in symbolic link loops. */
1089 struct dir_id
1091 ino_t ino;
1092 dev_t dev;
1094 static struct dir_id *dir_ids = NULL;
1095 /* Entries allocated in `dir_ids'. */
1096 static int dir_alloc = 0;
1097 /* Index in `dir_ids' of directory currently being searched.
1098 This is always the last valid entry. */
1099 static int dir_curr = -1;
1100 /* (Arbitrary) number of entries to grow `dir_ids' by. */
1101 #define DIR_ALLOC_STEP 32
1105 /* We've detected a filesystem loop. This is caused by one of
1106 * two things:
1108 * 1. Option -L is in effect and we've hit a symbolic link that
1109 * points to an ancestor. This is harmless. We won't traverse the
1110 * symbolic link.
1112 * 2. We have hit a real cycle in the directory hierarchy. In this
1113 * case, we issue a diagnostic message (POSIX requires this) and we
1114 * skip that directory entry.
1116 static void
1117 issue_loop_warning(const char *name, const char *pathname, int level)
1119 struct stat stbuf_link;
1120 if (lstat(name, &stbuf_link) != 0)
1121 stbuf_link.st_mode = S_IFREG;
1123 if (S_ISLNK(stbuf_link.st_mode))
1125 error(0, 0,
1126 _("Symbolic link `%s' is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
1127 pathname);
1129 else
1131 int distance = 1 + (dir_curr-level);
1132 /* We have found an infinite loop. POSIX requires us to
1133 * issue a diagnostic. Usually we won't get to here
1134 * because when the leaf optimisation is on, it will cause
1135 * the subdirectory to be skipped. If /a/b/c/d is a hard
1136 * link to /a/b, then the link count of /a/b/c is 2,
1137 * because the ".." entry of /b/b/c/d points to /a, not
1138 * to /a/b/c.
1140 error(0, 0,
1141 _("Filesystem loop detected; `%s' has the same device number and inode as a directory which is %d %s."),
1142 pathname,
1143 distance,
1144 (distance == 1 ?
1145 _("level higher in the filesystem hierarchy") :
1146 _("levels higher in the filesystem hierarchy")));
1150 /* Recursively descend path PATHNAME, applying the predicates.
1151 LEAF is true if PATHNAME is known to be in a directory that has no
1152 more unexamined subdirectories, and therefore it is not a directory.
1153 Knowing this allows us to avoid calling stat as long as possible for
1154 leaf files.
1156 NAME is PATHNAME relative to the current directory. We access NAME
1157 but print PATHNAME.
1159 PARENT is the path of the parent of NAME, relative to find's
1160 starting directory.
1162 Return nonzero iff PATHNAME is a directory. */
1164 static int
1165 process_path (char *pathname, char *name, boolean leaf, char *parent)
1167 struct stat stat_buf;
1168 static dev_t root_dev; /* Device ID of current argument pathname. */
1169 int i;
1171 /* Assume it is a non-directory initially. */
1172 stat_buf.st_mode = 0;
1174 rel_pathname = name;
1176 if (leaf)
1177 have_stat = false;
1178 else
1180 if ((*xstat) (name, &stat_buf) != 0)
1182 if (!ignore_readdir_race || (errno != ENOENT) )
1184 error (0, errno, "%s", pathname);
1185 exit_status = 1;
1187 return 0;
1189 have_stat = true;
1192 if (!S_ISDIR (stat_buf.st_mode))
1194 if (curdepth >= mindepth)
1195 apply_predicate (pathname, &stat_buf, eval_tree);
1196 return 0;
1199 /* From here on, we're working on a directory. */
1201 stop_at_current_level = maxdepth >= 0 && curdepth >= maxdepth;
1203 /* If we've already seen this directory on this branch,
1204 don't descend it again. */
1205 for (i = 0; i <= dir_curr; i++)
1206 if (stat_buf.st_ino == dir_ids[i].ino &&
1207 stat_buf.st_dev == dir_ids[i].dev)
1209 stop_at_current_level = true;
1210 issue_loop_warning(name, pathname, i);
1213 if (dir_alloc <= ++dir_curr)
1215 dir_alloc += DIR_ALLOC_STEP;
1216 dir_ids = (struct dir_id *)
1217 xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id));
1219 dir_ids[dir_curr].ino = stat_buf.st_ino;
1220 dir_ids[dir_curr].dev = stat_buf.st_dev;
1222 if (stay_on_filesystem)
1224 if (curdepth == 0)
1225 root_dev = stat_buf.st_dev;
1226 else if (stat_buf.st_dev != root_dev)
1227 stop_at_current_level = true;
1230 if (do_dir_first && curdepth >= mindepth)
1231 apply_predicate (pathname, &stat_buf, eval_tree);
1233 #ifdef DEBUG
1234 fprintf(stderr, "pathname = %s, stop_at_current_level = %d\n",
1235 pathname, stop_at_current_level);
1236 #endif /* DEBUG */
1238 if (stop_at_current_level == false)
1239 /* Scan directory on disk. */
1240 process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
1242 if (do_dir_first == false && curdepth >= mindepth)
1244 rel_pathname = name;
1245 apply_predicate (pathname, &stat_buf, eval_tree);
1248 dir_curr--;
1250 return 1;
1253 /* Scan directory PATHNAME and recurse through process_path for each entry.
1255 PATHLEN is the length of PATHNAME.
1257 NAME is PATHNAME relative to the current directory.
1259 STATP is the results of *xstat on it.
1261 PARENT is the path of the parent of NAME, relative to find's
1262 starting directory. */
1264 static void
1265 process_dir (char *pathname, char *name, int pathlen, struct stat *statp, char *parent)
1267 char *name_space; /* Names of files in PATHNAME. */
1268 int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */
1269 struct stat stat_buf;
1271 subdirs_left = statp->st_nlink - 2; /* Account for name and ".". */
1273 errno = 0;
1274 name_space = savedir (name);
1275 if (name_space == NULL)
1277 assert(errno != 0);
1278 error (0, errno, "%s", pathname);
1279 exit_status = 1;
1281 else
1283 register char *namep; /* Current point in `name_space'. */
1284 char *cur_path; /* Full path of each file to process. */
1285 char *cur_name; /* Base name of each file to process. */
1286 unsigned cur_path_size; /* Bytes allocated for `cur_path'. */
1287 register unsigned file_len; /* Length of each path to process. */
1288 register unsigned pathname_len; /* PATHLEN plus trailing '/'. */
1290 if (pathname[pathlen - 1] == '/')
1291 pathname_len = pathlen + 1; /* For '\0'; already have '/'. */
1292 else
1293 pathname_len = pathlen + 2; /* For '/' and '\0'. */
1294 cur_path_size = 0;
1295 cur_path = NULL;
1297 #if USE_SAFE_CHDIR
1298 if (strcmp (name, "."))
1300 enum SafeChdirStatus status = safely_chdir (name, TraversingDown, &stat_buf);
1301 switch (status)
1303 case SafeChdirOK:
1304 /* If there had been a change but wd_sanity_check()
1305 * accepted it, we need to accept that on the
1306 * way back up as well, so modify our record
1307 * of what we think we should see later.
1308 * If there was no change, the assignments are a no-op.
1310 dir_ids[dir_curr].dev = stat_buf.st_dev;
1311 dir_ids[dir_curr].ino = stat_buf.st_ino;
1312 break;
1314 case SafeChdirFailNonexistent:
1315 case SafeChdirFailStat:
1316 case SafeChdirFailWouldBeUnableToReturn:
1317 case SafeChdirFailSymlink:
1318 case SafeChdirFailNotDir:
1319 case SafeChdirFailChdirFailed:
1320 error (0, errno, "%s", pathname);
1321 exit_status = 1;
1322 return;
1325 #else
1326 if (strcmp (name, ".") && chdir (name) < 0)
1328 error (0, errno, "%s", pathname);
1329 exit_status = 1;
1330 return;
1333 /* Check that we are where we should be. */
1334 if (1)
1336 boolean changed = false;
1337 wd_sanity_check(pathname,
1338 program_name,
1339 ".",
1340 dir_ids[dir_curr].dev,
1341 dir_ids[dir_curr].ino,
1342 &stat_buf, 0, __LINE__,
1343 TraversingDown,
1344 FATAL_IF_SANITY_CHECK_FAILS,
1345 &changed);
1346 if (changed)
1348 /* If there had been a change but wd_sanity_check()
1349 * accepted it, we need to accept that on the
1350 * way back up as well, so modify our record
1351 * of what we think we should see later.
1353 dir_ids[dir_curr].dev = stat_buf.st_dev;
1354 dir_ids[dir_curr].ino = stat_buf.st_ino;
1357 #endif
1359 for (namep = name_space; *namep; namep += file_len - pathname_len + 1)
1361 /* Append this directory entry's name to the path being searched. */
1362 file_len = pathname_len + strlen (namep);
1363 if (file_len > cur_path_size)
1365 while (file_len > cur_path_size)
1366 cur_path_size += 1024;
1367 if (cur_path)
1368 free (cur_path);
1369 cur_path = xmalloc (cur_path_size);
1370 strcpy (cur_path, pathname);
1371 cur_path[pathname_len - 2] = '/';
1373 cur_name = cur_path + pathname_len - 1;
1374 strcpy (cur_name, namep);
1376 curdepth++;
1377 if (!no_leaf_check)
1378 /* Normal case optimization.
1379 On normal Unix filesystems, a directory that has no
1380 subdirectories has two links: its name, and ".". Any
1381 additional links are to the ".." entries of its
1382 subdirectories. Once we have processed as many
1383 subdirectories as there are additional links, we know
1384 that the rest of the entries are non-directories --
1385 in other words, leaf files. */
1386 subdirs_left -= process_path (cur_path, cur_name,
1387 subdirs_left == 0, pathname);
1388 else
1389 /* There might be weird (e.g., CD-ROM or MS-DOS) filesystems
1390 mounted, which don't have Unix-like directory link counts. */
1391 process_path (cur_path, cur_name, false, pathname);
1392 curdepth--;
1394 #if USE_SAFE_CHDIR
1395 if (strcmp (name, "."))
1397 enum SafeChdirStatus status;
1398 struct dir_id did;
1399 boolean changed = false;
1401 /* We could go back and do the next command-line arg
1402 instead, maybe using longjmp. */
1403 char const *dir;
1404 boolean deref = following_links() ? true : false;
1406 if ( (curdepth>0) && !deref)
1407 dir = "..";
1408 else
1410 chdir_back ();
1411 dir = parent;
1414 status = safely_chdir (dir, TraversingUp, &stat_buf);
1415 switch (status)
1417 case SafeChdirOK:
1418 break;
1420 case SafeChdirFailNonexistent:
1421 case SafeChdirFailStat:
1422 case SafeChdirFailWouldBeUnableToReturn:
1423 case SafeChdirFailSymlink:
1424 case SafeChdirFailNotDir:
1425 case SafeChdirFailChdirFailed:
1426 error (1, errno, "%s", pathname);
1427 return;
1430 if (dir_curr > 0)
1432 did.dev = dir_ids[dir_curr-1].dev;
1433 did.ino = dir_ids[dir_curr-1].ino;
1435 else
1437 did.dev = starting_stat_buf.st_dev;
1438 did.ino = starting_stat_buf.st_ino;
1441 wd_sanity_check(pathname,
1442 program_name,
1443 parent,
1444 did.dev,
1445 did.ino,
1446 &stat_buf,
1447 deref ? 1 : 0,
1448 __LINE__,
1449 TraversingUp,
1450 FATAL_IF_SANITY_CHECK_FAILS,
1451 &changed);
1453 #else
1454 if (strcmp (name, "."))
1456 /* We could go back and do the next command-line arg
1457 instead, maybe using longjmp. */
1458 char const *dir;
1459 boolean deref = following_links() ? true : false;
1461 if (!deref)
1462 dir = "..";
1463 else
1465 chdir_back ();
1466 dir = parent;
1469 if (chdir (dir) != 0)
1470 error (1, errno, "%s", parent);
1472 /* Check that we are where we should be. */
1473 if (1)
1475 boolean changed = false;
1476 struct stat tmp;
1477 int problem_is_with_parent;
1479 memset(&tmp, 0, sizeof(tmp));
1480 if (dir_curr > 0)
1482 tmp.st_dev = dir_ids[dir_curr-1].dev;
1483 tmp.st_ino = dir_ids[dir_curr-1].ino;
1485 else
1487 tmp.st_dev = starting_stat_buf.st_dev;
1488 tmp.st_ino = starting_stat_buf.st_ino;
1491 problem_is_with_parent = deref ? 1 : 0;
1492 wd_sanity_check(pathname,
1493 program_name,
1494 parent,
1495 tmp.st_dev,
1496 tmp.st_ino,
1497 &stat_buf,
1498 problem_is_with_parent, __LINE__,
1499 TraversingUp,
1500 FATAL_IF_SANITY_CHECK_FAILS,
1501 &changed);
1504 #endif
1506 if (cur_path)
1507 free (cur_path);
1508 free (name_space);
1512 /* Return true if there are no predicates with no_default_print in
1513 predicate list PRED, false if there are any.
1514 Returns true if default print should be performed */
1516 static boolean
1517 default_prints (struct predicate *pred)
1519 while (pred != NULL)
1521 if (pred->no_default_print)
1522 return (false);
1523 pred = pred->pred_next;
1525 return (true);