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)
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,
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>. */
37 #include "../gnulib/lib/xalloc.h"
38 #include "../gnulib/lib/human.h"
39 #include "../gnulib/lib/canonicalize.h"
41 #include "../gnulib/lib/savedir.h"
49 # define _(Text) gettext (Text)
52 #define textdomain(Domain)
53 #define bindtextdomain(Package, Directory)
56 # define N_(String) gettext_noop (String)
58 /* See locate.c for explanation as to why not use (String) */
59 # define N_(String) String
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. */
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. */
90 /* If >=0, don't descend more than this many levels of subdirectories. */
93 /* If >=0, don't process files above this level. */
96 /* Current depth; 0 means current path is a command line arg. */
99 /* Output block size. */
100 int output_block_size
;
102 /* Time at start of execution. */
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. */
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. */
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. */
138 /* The file being operated on, relative to the current directory.
139 Used for stat, readlink, remove, and opendir. */
142 /* Length of current path. */
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. */
153 /* Status value to return to system. */
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
167 enum TraversalDirection
175 following_links(void)
177 switch (symlink_handling
)
179 case SYMLINK_ALWAYS_DEREF
:
181 case SYMLINK_DEREF_ARGSONLY
:
182 return (curdepth
== 0);
183 case SYMLINK_NEVER_DEREF
:
190 /* optionh_stat() implements the stat operation when the -H option is
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.
201 optionh_stat(const char *name
, struct stat
*p
)
205 /* This file is from the command line; deference the link (if it
208 if (0 == stat(name
, p
))
215 /* fallback - return the information for the link itself. */
216 return lstat(name
, p
);
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.
232 optionl_stat(const char *name
, struct stat
*p
)
234 if (0 == stat(name
, p
))
236 return 0; /* normal case. */
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.
249 optionp_stat(const char *name
, struct stat
*p
)
251 return lstat(name
, p
);
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 */
272 set_follow_state(enum SymlinkOption opt
)
276 case SYMLINK_ALWAYS_DEREF
: /* -L */
277 xstat
= optionl_stat
;
278 no_leaf_check
= false;
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
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)
300 #endif /* !DEBUG_STAT */
305 main (int argc
, char **argv
)
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
, "");
317 bindtextdomain (PACKAGE
, LOCALEDIR
);
318 textdomain (PACKAGE
);
333 maxdepth
= mindepth
= -1;
334 start_time
= time (NULL
);
335 cur_day_start
= start_time
- DAYSECS
;
337 no_leaf_check
= false;
338 stay_on_filesystem
= false;
339 ignore_readdir_race
= false;
342 #if defined(DEBUG_STAT)
344 #endif /* !DEBUG_STAT */
347 human_block_size (getenv ("FIND_BLOCK_SIZE"), 0, &output_block_size
);
349 if (getenv("POSIXLY_CORRECT"))
350 output_block_size
= 512;
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();
366 printf ("cur_day_start = %s", ctime (&cur_day_start
));
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 */
395 /* Hmm, must be one of
399 end_of_leading_options
= i
; /* Next time start with this option */
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]); */
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. */
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
);
431 if (!(*parse_function
) (argv
, &i
))
434 /* Command line option requires an argument */
435 error (1, 0, _("missing argument to `%s'"), predicate_name
);
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
);
460 /* `( user-supplied-expression ) -print'. */
461 parse_close (argv
, &argc
);
462 parse_print (argv
, &argc
);
466 printf (_("Predicate List:\n"));
467 print_list (predicates
);
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"));
483 printf (_("Eval Tree:\n"));
484 print_tree (eval_tree
, 0);
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
);
494 printf (_("Optimized Eval Tree:\n"));
495 print_tree (eval_tree
, 0);
498 starting_desc
= open (".", O_RDONLY
);
499 if (0 <= starting_desc
&& fchdir (starting_desc
) != 0)
501 close (starting_desc
);
504 if (starting_desc
< 0)
506 starting_dir
= xgetcwd ();
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
);
538 specific_dirname(const char *dir
)
542 if (0 == strcmp(".", dir
))
544 /* OK, what's '.'? */
545 if (NULL
!= getcwd(dirname
, sizeof(dirname
)))
547 return strdup(dirname
);
556 const char *result
= canonicalize_filename_mode(dir
, CAN_EXISTING
);
564 static dev_t
*mounted_devices
= NULL
;
565 static size_t num_mounted_devices
= 0u;
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
);
577 refresh_mounted_dev_list(void)
581 free(mounted_devices
);
584 num_mounted_devices
= 0u;
585 init_mounted_dev_list();
589 /* Search for device DEV in the array LIST, which is of size N. */
591 dev_present(dev_t dev
, const dev_t
*list
, size_t n
)
597 if ( (*list
++) == dev
)
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
;
627 return MountPointRecentlyUnmounted
;
631 /* Return non-zero if FS is the name of a filesystem that is likely to
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
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
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.
676 wd_sanity_check(const char *thing_to_stat
,
677 const char *program_name
,
681 struct stat
*newinfo
,
684 enum TraversalDirection direction
,
685 enum WdSanityCheckFatality isfatal
,
686 boolean
*changed
) /* output parameter */
689 char *specific_what
= NULL
;
694 if ((*xstat
) (".", newinfo
) != 0)
695 error (1, errno
, "%s", thing_to_stat
);
697 if (old_dev
!= newinfo
->st_dev
)
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
);
728 case MountPointRecentlyUnmounted
:
729 isfatal
= NON_FATAL_IF_SANITY_CHECK_FAILS
;
733 _("Warning: filesystem %s has recently been unmounted."),
738 case MountPointRecentlyMounted
:
739 isfatal
= NON_FATAL_IF_SANITY_CHECK_FAILS
;
743 _("Warning: filesystem %s has recently been mounted."),
748 case MountPointStateUnchanged
:
749 /* leave isfatal as it is */
754 if (FATAL_IF_SANITY_CHECK_FAILS
== isfatal
)
756 fstype
= filesystem_type(thing_to_stat
, ".", newinfo
);
758 _("%s%s changed during execution of %s (old device number %ld, new device number %ld, filesystem type is %s) [ref %ld]"),
763 (long) newinfo
->st_dev
,
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.
781 /* Device number was the same, check if the inode has changed. */
782 if (old_ino
!= newinfo
->st_ino
)
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]"),
795 (long) newinfo
->st_ino
,
808 SafeChdirFailSymlink
,
811 SafeChdirFailWouldBeUnableToReturn
,
812 SafeChdirFailChdirFailed
,
813 SafeChdirFailNonexistent
816 /* Safely perform a change in directory.
820 safely_chdir(const char *dest
, enum TraversalDirection direction
)
822 struct stat statbuf_dest
, statbuf_arrived
;
824 int saved_errno
; /* specific_dirname() changes errno. */
826 boolean rv_set
= false;
828 saved_errno
= errno
= 0;
829 dotfd
= open(".", O_RDONLY
);
832 /* Stat the directory we're going to. */
833 if (0 == xstat(dest
, &statbuf_dest
))
836 if (!following_links() && S_ISLNK(statbuf_dest
.st_mode
))
838 rv
= SafeChdirFailSymlink
;
840 saved_errno
= 0; /* silence the error message */
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
;
855 saved_errno
= 0; /* silence the error message */
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
, ".",
867 0, __LINE__
, direction
,
868 FATAL_IF_SANITY_CHECK_FAILS
,
876 if (ENOENT
== saved_errno
)
878 rv
= SafeChdirFailNonexistent
;
880 if (ignore_readdir_race
)
881 errno
= 0; /* don't issue err msg */
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
891 saved_errno
= 0; /* don't issue err msg */
892 rv
= SafeChdirFailNotDir
;
897 rv
= SafeChdirFailChdirFailed
;
906 rv
= SafeChdirFailStat
;
908 name
= specific_dirname(dest
);
909 if ( (ENOENT
== saved_errno
) || (0 == curdepth
))
910 saved_errno
= 0; /* don't issue err msg */
916 /* We do not have read permissions on "." */
917 rv
= SafeChdirFailWouldBeUnableToReturn
;
924 /* We use the same exit path for successs or failure.
925 * which has occurred is recorded in RV.
931 name
= specific_dirname(".");
932 error(0, saved_errno
, "%s", name
);
948 /* Safely go back to the starting directory. */
952 struct stat stat_buf
;
955 if (starting_desc
< 0)
957 if (chdir (starting_dir
) != 0)
958 error (1, errno
, "%s", starting_dir
);
960 wd_sanity_check(starting_dir
,
963 starting_stat_buf
.st_dev
,
964 starting_stat_buf
.st_ino
,
965 &stat_buf
, 0, __LINE__
,
967 FATAL_IF_SANITY_CHECK_FAILS
,
972 if (fchdir (starting_desc
) != 0)
973 error (1, errno
, "%s", starting_dir
);
977 /* Descend PATHNAME, which is a command-line argument. */
980 process_top_path (char *pathname
)
982 struct stat stat_buf
, cur_stat_buf
;
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. */
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
);
1005 /* Check that we are where we should be. */
1006 wd_sanity_check(pathname
, program_name
,
1010 &cur_stat_buf
, 0, __LINE__
,
1012 FATAL_IF_SANITY_CHECK_FAILS
,
1015 process_path (pathname
, ".", false, ".");
1020 process_path (pathname
, pathname
, false, ".");
1023 enum SafeChdirStatus rv
= safely_chdir(pathname
, TraversingDown
);
1028 process_path (pathname
, ".", false, ".");
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
);
1045 process_path (pathname
, pathname
, false, ".");
1053 /* Info on each directory in the current tree branch, to avoid
1054 getting stuck in symbolic link loops. */
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
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
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.
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
1101 _("Filesystem loop detected; `%s' has the same device number and inode as a directory which is %d %s."),
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
1116 NAME is PATHNAME relative to the current directory. We access NAME
1119 PARENT is the path of the parent of NAME, relative to find's
1122 Return nonzero iff PATHNAME is a directory. */
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. */
1131 /* Assume it is a non-directory initially. */
1132 stat_buf
.st_mode
= 0;
1134 rel_pathname
= name
;
1140 if ((*xstat
) (name
, &stat_buf
) != 0)
1142 if (!ignore_readdir_race
|| (errno
!= ENOENT
) )
1144 error (0, errno
, "%s", pathname
);
1152 if (!S_ISDIR (stat_buf
.st_mode
))
1154 if (curdepth
>= mindepth
)
1155 apply_predicate (pathname
, &stat_buf
, eval_tree
);
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
)
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
);
1194 fprintf(stderr
, "pathname = %s, stop_at_current_level = %d\n",
1195 pathname
, stop_at_current_level
);
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
);
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. */
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 ".". */
1234 name_space
= savedir (name
);
1235 if (name_space
== NULL
)
1239 error (0, errno
, "%s", pathname
);
1243 error (1, 0, _("virtual memory exhausted"));
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 '/'. */
1257 pathname_len
= pathlen
+ 2; /* For '/' and '\0'. */
1261 if (strcmp (name
, ".") && chdir (name
) < 0)
1263 error (0, errno
, "%s", pathname
);
1268 /* Check that we are where we should be. */
1271 boolean changed
= false;
1272 wd_sanity_check(pathname
,
1275 dir_ids
[dir_curr
].dev
,
1276 dir_ids
[dir_curr
].ino
,
1277 &stat_buf
, 0, __LINE__
,
1279 FATAL_IF_SANITY_CHECK_FAILS
,
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;
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
);
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
);
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
);
1329 if (strcmp (name
, "."))
1331 /* We could go back and do the next command-line arg
1332 instead, maybe using longjmp. */
1334 boolean deref
= following_links() ? true : false;
1344 if (chdir (dir
) != 0)
1345 error (1, errno
, "%s", parent
);
1347 /* Check that we are where we should be. */
1350 boolean changed
= false;
1352 int problem_is_with_parent
;
1354 memset(&tmp
, 0, sizeof(tmp
));
1357 tmp
.st_dev
= dir_ids
[dir_curr
-1].dev
;
1358 tmp
.st_ino
= dir_ids
[dir_curr
-1].ino
;
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
,
1373 problem_is_with_parent
, __LINE__
,
1375 FATAL_IF_SANITY_CHECK_FAILS
,
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 */
1391 default_prints (struct predicate
*pred
)
1393 while (pred
!= NULL
)
1395 if (pred
->no_default_print
)
1397 pred
= pred
->pred_next
;