Imported Upstream version 4.5.14
[platform/upstream/findutils.git] / find / find.c
1 /* find -- search for files in a directory hierarchy
2    Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 2004, 2005,
3    2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 /* GNU find was written by Eric Decker <cire@soe.ucsc.edu>,
19    with enhancements by David MacKenzie <djm@gnu.org>,
20    Jay Plett <jay@silence.princeton.nj.us>,
21    and Tim Wood <axolotl!tim@toad.com>.
22    The idea for -print0 and xargs -0 came from
23    Dan Bernstein <brnstnd@kramden.acf.nyu.edu>.
24    Improvements have been made by James Youngman <jay@gnu.org>.
25 */
26
27 /* config.h must be included first. */
28 #include <config.h>
29
30 /* system headers. */
31 #include <assert.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <locale.h>
35 #include <sys/stat.h>
36
37 /* gnulib headers. */
38 #include "canonicalize.h"
39 #include "closein.h"
40 #include "dirent-safer.h"
41 #include "dirname.h"
42 #include "error.h"
43 #include "fcntl--.h"
44 #include "gettext.h"
45 #include "human.h"
46 #include "progname.h"
47 #include "save-cwd.h"
48 #include "xalloc.h"
49 #include "xgetcwd.h"
50
51
52 /* find headers. */
53 #include "buildcmd.h"
54 #include "defs.h"
55 #include "fdleak.h"
56
57 #undef  STAT_MOUNTPOINTS
58
59 #ifdef CLOSEDIR_VOID
60 /* Fake a return value. */
61 # define CLOSEDIR(d) (closedir (d), 0)
62 #else
63 # define CLOSEDIR(d) closedir (d)
64 #endif
65
66 enum
67 {
68   NOT_AN_INODE_NUMBER = 0
69 };
70
71 #ifdef D_INO_IN_DIRENT
72 # define D_INO(dp) (dp)->d_ino
73 #else
74 /* Some systems don't have inodes, so fake them to avoid lots of ifdefs.  */
75 # define D_INO(dp) NOT_AN_INODE_NUMBER
76 #endif
77
78 #if ENABLE_NLS
79 # include <libintl.h>
80 # define _(Text) gettext (Text)
81 #else
82 # define _(Text) Text
83 #define textdomain(Domain)
84 #define bindtextdomain(Package, Directory)
85 #define ngettext(singular,plural,n) ((1==n) ? singular : plural)
86 #endif
87 #ifdef gettext_noop
88 # define N_(String) gettext_noop (String)
89 #else
90 /* See locate.c for explanation as to why not use (String) */
91 # define N_(String) String
92 #endif
93
94 #ifdef STAT_MOUNTPOINTS
95 static void init_mounted_dev_list (int mandatory);
96 #endif
97
98 static void process_top_path (char *pathname, mode_t mode, ino_t inum);
99 static int process_path (char *pathname, char *name, bool leaf, char *parent, mode_t type, ino_t inum);
100 static void process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent);
101
102
103
104 /* A file descriptor open to the initial working directory.
105    Doing it this way allows us to work when the i.w.d. has
106    unreadable parents.  */
107 extern int starting_desc;
108
109 /* The stat buffer of the initial working directory. */
110 static struct stat starting_stat_buf;
111
112 enum ChdirSymlinkHandling
113   {
114     SymlinkHandleDefault,       /* Normally the right choice */
115     SymlinkFollowOk             /* see comment in process_top_path() */
116   };
117
118
119 enum TraversalDirection
120   {
121     TraversingUp,
122     TraversingDown
123   };
124
125 enum WdSanityCheckFatality
126   {
127     FATAL_IF_SANITY_CHECK_FAILS,
128     RETRY_IF_SANITY_CHECK_FAILS,
129     NON_FATAL_IF_SANITY_CHECK_FAILS
130   };
131
132 #if defined HAVE_STRUCT_DIRENT_D_TYPE
133 /* Convert the value of struct dirent.d_type into a value for
134  * struct stat.st_mode (at least the file type bits), or zero
135  * if the type is DT_UNKNOWN or is a value we don't know about.
136  */
137 static mode_t
138 type_to_mode (unsigned type)
139 {
140   switch (type)
141     {
142 #ifdef DT_FIFO
143     case DT_FIFO: return S_IFIFO;
144 #endif
145 #ifdef DT_CHR
146     case DT_CHR:  return S_IFCHR;
147 #endif
148 #ifdef DT_DIR
149     case DT_DIR:  return S_IFDIR;
150 #endif
151 #ifdef DT_BLK
152     case DT_BLK:  return S_IFBLK;
153 #endif
154 #ifdef DT_REG
155     case DT_REG:  return S_IFREG;
156 #endif
157 #ifdef DT_LNK
158     case DT_LNK:  return S_IFLNK;
159 #endif
160 #ifdef DT_SOCK
161     case DT_SOCK: return S_IFSOCK;
162 #endif
163     default:
164       return 0;                 /* Unknown. */
165     }
166 }
167 #endif
168
169
170 int
171 get_current_dirfd (void)
172 {
173   return AT_FDCWD;
174 }
175
176
177 int
178 main (int argc, char **argv)
179 {
180   int i;
181   int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
182   struct predicate *eval_tree;
183
184   if (argv[0])
185     set_program_name (argv[0]);
186   else
187     set_program_name ("find");
188
189   state.exit_status = 0;
190
191   if (fd_leak_check_is_enabled ())
192     {
193       remember_non_cloexec_fds ();
194     }
195
196   record_initial_cwd ();
197
198   state.already_issued_stat_error_msg = false;
199   state.shared_files = sharefile_init ("w");
200   if (NULL == state.shared_files)
201     {
202       error (EXIT_FAILURE, errno,
203              _("Failed to initialize shared-file hash table"));
204     }
205
206   /* Set the option defaults before we do the locale
207    * initialisation as check_nofollow () needs to be executed in the
208    * POSIX locale.
209    */
210   set_option_defaults (&options);
211
212 #ifdef HAVE_SETLOCALE
213   setlocale (LC_ALL, "");
214 #endif
215   bindtextdomain (PACKAGE, LOCALEDIR);
216   textdomain (PACKAGE);
217   if (atexit (close_stdin))
218     {
219       error (EXIT_FAILURE, errno, _("The atexit library function failed"));
220     }
221
222   /* Check for -P, -H or -L options. */
223   end_of_leading_options = process_leading_options (argc, argv);
224
225   if (options.debug_options & DebugStat)
226     options.xstat = debug_stat;
227
228 #ifdef DEBUG
229   fprintf (stderr, "cur_day_start = %s", ctime (&options.cur_day_start));
230 #endif /* DEBUG */
231
232   /* state.cwd_dir_fd has to be initialized before we call build_expression_tree ()
233    * because command-line parsing may lead us to stat some files.
234    */
235   state.cwd_dir_fd = AT_FDCWD;
236
237   /* We are now processing the part of the "find" command line
238    * after the -H/-L options (if any).
239    */
240   eval_tree = build_expression_tree (argc, argv, end_of_leading_options);
241
242
243   /* safely_chdir () needs to check that it has ended up in the right place.
244    * To avoid bailing out when something gets automounted, it checks if
245    * the target directory appears to have had a directory mounted on it as
246    * we chdir ()ed.  The problem with this is that in order to notice that
247    * a file system was mounted, we would need to lstat () all the mount points.
248    * That strategy loses if our machine is a client of a dead NFS server.
249    *
250    * Hence if safely_chdir () and wd_sanity_check () can manage without needing
251    * to know the mounted device list, we do that.
252    */
253   if (!options.open_nofollow_available)
254     {
255 #ifdef STAT_MOUNTPOINTS
256       init_mounted_dev_list (0);
257 #endif
258     }
259
260
261   set_stat_placeholders (&starting_stat_buf);
262   if ((*options.xstat) (".", &starting_stat_buf) != 0)
263     error (EXIT_FAILURE, errno, _("cannot stat current directory"));
264
265   /* If no paths are given, default to ".".  */
266   for (i = end_of_leading_options; i < argc && !looks_like_expression (argv[i], true); i++)
267     {
268       process_top_path (argv[i], 0, starting_stat_buf.st_ino);
269     }
270
271   /* If there were no path arguments, default to ".". */
272   if (i == end_of_leading_options)
273     {
274       /*
275        * We use a temporary variable here because some actions modify
276        * the path temporarily.  Hence if we use a string constant,
277        * we get a coredump.  The best example of this is if we say
278        * "find -printf %H" (note, not "find . -printf %H").
279        */
280       char defaultpath[2] = ".";
281       process_top_path (defaultpath, 0, starting_stat_buf.st_ino);
282     }
283
284   /* If "-exec ... {} +" has been used, there may be some
285    * partially-full command lines which have been built,
286    * but which are not yet complete.   Execute those now.
287    */
288   show_success_rates (eval_tree);
289   cleanup ();
290   return state.exit_status;
291 }
292
293 bool is_fts_enabled (int *ftsoptions)
294 {
295   /* this version of find (i.e. this main ()) does not use fts. */
296   *ftsoptions = 0;
297   return false;
298 }
299
300
301 static char *
302 specific_dirname (const char *dir)
303 {
304   char dirbuf[1024];
305
306   if (0 == strcmp (".", dir))
307     {
308       /* OK, what's '.'? */
309       if (NULL != getcwd (dirbuf, sizeof (dirbuf)))
310         {
311           return strdup (dirbuf);
312         }
313       else
314         {
315           return strdup (dir);
316         }
317     }
318   else
319     {
320       char *result = canonicalize_filename_mode (dir, CAN_EXISTING);
321       if (NULL == result)
322         return strdup (dir);
323       else
324         return result;
325     }
326 }
327
328
329
330 /* Return non-zero if FS is the name of a file system that is likely to
331  * be automounted
332  */
333 static int
334 fs_likely_to_be_automounted (const char *fs)
335 {
336   return ( (0==strcmp (fs, "nfs")) || (0==strcmp (fs, "autofs")) || (0==strcmp (fs, "subfs")));
337 }
338
339
340
341 #ifdef STAT_MOUNTPOINTS
342 static dev_t *mounted_devices = NULL;
343 static size_t num_mounted_devices = 0u;
344
345
346 static void
347 init_mounted_dev_list (int mandatory)
348 {
349   assert (NULL == mounted_devices);
350   assert (0 == num_mounted_devices);
351   mounted_devices = get_mounted_devices (&num_mounted_devices);
352   if (mandatory && (NULL == mounted_devices))
353     {
354       error (EXIT_FAILURE, 0, _("Cannot read list of mounted devices."));
355     }
356 }
357
358 static void
359 refresh_mounted_dev_list (void)
360 {
361   if (mounted_devices)
362     {
363       free (mounted_devices);
364       mounted_devices = 0;
365     }
366   num_mounted_devices = 0u;
367   init_mounted_dev_list (1);
368 }
369
370
371 /* Search for device DEV in the array LIST, which is of size N. */
372 static int
373 dev_present (dev_t dev, const dev_t *list, size_t n)
374 {
375   if (list)
376     {
377       while (n-- > 0u)
378         {
379           if ( (*list++) == dev )
380             return 1;
381         }
382     }
383   return 0;
384 }
385
386 enum MountPointStateChange
387   {
388     MountPointRecentlyMounted,
389     MountPointRecentlyUnmounted,
390     MountPointStateUnchanged
391   };
392
393
394
395 static enum MountPointStateChange
396 get_mount_state (dev_t newdev)
397 {
398   int new_is_present, new_was_present;
399
400   new_was_present = dev_present (newdev, mounted_devices, num_mounted_devices);
401   refresh_mounted_dev_list ();
402   new_is_present  = dev_present (newdev, mounted_devices, num_mounted_devices);
403
404   if (new_was_present == new_is_present)
405     return MountPointStateUnchanged;
406   else if (new_is_present)
407     return MountPointRecentlyMounted;
408   else
409     return MountPointRecentlyUnmounted;
410 }
411
412
413
414 /* We stat()ed a directory, chdir()ed into it (we know this
415  * since direction is TraversingDown), stat()ed it again,
416  * and noticed that the device numbers are different.  Check
417  * if the file system was recently mounted.
418  *
419  * If it was, it looks like chdir()ing into the directory
420  * caused a file system to be mounted.  Maybe automount is
421  * running.  Anyway, that's probably OK - but it happens
422  * only when we are moving downward.
423  *
424  * We also allow for the possibility that a similar thing
425  * has happened with the unmounting of a file system.  This
426  * is much rarer, as it relies on an automounter timeout
427  * occurring at exactly the wrong moment.
428  */
429 static enum WdSanityCheckFatality
430 dirchange_is_fatal (const char *specific_what,
431                     enum WdSanityCheckFatality isfatal,
432                     int silent,
433                     struct stat *newinfo)
434 {
435   enum MountPointStateChange transition = get_mount_state (newinfo->st_dev);
436   switch (transition)
437     {
438     case MountPointRecentlyUnmounted:
439       isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
440       if (!silent)
441         {
442           error (0, 0,
443                  _("WARNING: file system %s has recently been unmounted."),
444                  safely_quote_err_filename (0, specific_what));
445         }
446       break;
447
448     case MountPointRecentlyMounted:
449       isfatal = NON_FATAL_IF_SANITY_CHECK_FAILS;
450       if (!silent)
451         {
452           error (0, 0,
453                  _("WARNING: file system %s has recently been mounted."),
454                  safely_quote_err_filename (0, specific_what));
455         }
456       break;
457
458     case MountPointStateUnchanged:
459       /* leave isfatal as it is */
460       break;
461     }
462
463   return isfatal;
464 }
465
466
467 #endif
468
469
470
471 /* Examine the results of the stat() of a directory from before we
472  * entered or left it, with the results of stat()ing it afterward.  If
473  * these are different, the file system tree has been modified while we
474  * were traversing it.  That might be an attempt to use a race
475  * condition to persuade find to do something it didn't intend
476  * (e.g. an attempt by an ordinary user to exploit the fact that root
477  * sometimes runs find on the whole file system).  However, this can
478  * also happen if automount is running (certainly on Solaris).  With
479  * automount, moving into a directory can cause a file system to be
480  * mounted there.
481  *
482  * To cope sensibly with this, we will raise an error if we see the
483  * device number change unless we are chdir()ing into a subdirectory,
484  * and the directory we moved into has been mounted or unmounted "recently".
485  * Here "recently" means since we started "find" or we last re-read
486  * the /etc/mnttab file.
487  *
488  * If the device number does not change but the inode does, that is a
489  * problem.
490  *
491  * If the device number and inode are both the same, we are happy.
492  *
493  * If a file system is (un)mounted as we chdir() into the directory, that
494  * may mean that we're now examining a section of the file system that might
495  * have been excluded from consideration (via -prune or -quit for example).
496  * Hence we print a warning message to indicate that the output of find
497  * might be inconsistent due to the change in the file system.
498  */
499 static bool
500 wd_sanity_check (const char *thing_to_stat,
501                 const char *progname,
502                 const char *what,
503                 dev_t old_dev,
504                 ino_t old_ino,
505                 struct stat *newinfo,
506                 int parent,
507                 int line_no,
508                 enum TraversalDirection direction,
509                 enum WdSanityCheckFatality isfatal,
510                 bool *changed) /* output parameter */
511 {
512   const char *fstype;
513   char *specific_what = NULL;
514   int silent = 0;
515   const char *current_dir = ".";
516
517   *changed = false;
518
519   set_stat_placeholders (newinfo);
520   if ((*options.xstat) (current_dir, newinfo) != 0)
521     fatal_target_file_error (errno, thing_to_stat);
522
523   if (old_dev != newinfo->st_dev)
524     {
525       *changed = true;
526       specific_what = specific_dirname (what);
527       fstype = filesystem_type (newinfo, current_dir);
528       silent = fs_likely_to_be_automounted (fstype);
529
530       /* This condition is rare, so once we are here it is
531        * reasonable to perform an expensive computation to
532        * determine if we should continue or fail.
533        */
534       if (TraversingDown == direction)
535         {
536 #ifdef STAT_MOUNTPOINTS
537           isfatal = dirchange_is_fatal (specific_what,isfatal,silent,newinfo);
538 #else
539           (void) silent;
540           isfatal = RETRY_IF_SANITY_CHECK_FAILS;
541 #endif
542         }
543
544       switch (isfatal)
545         {
546         case FATAL_IF_SANITY_CHECK_FAILS:
547           {
548             fstype = filesystem_type (newinfo, current_dir);
549             error (EXIT_FAILURE, 0,
550                    _("%s%s changed during execution of %s (old device number %ld, new device number %ld, file system type is %s) [ref %ld]"),
551                    safely_quote_err_filename (0, specific_what),
552                    parent ? "/.." : "",
553                    safely_quote_err_filename (1, progname),
554                    (long) old_dev,
555                    (long) newinfo->st_dev,
556                    fstype,
557                    (long)line_no);
558             /*NOTREACHED*/
559             return false;
560           }
561
562         case NON_FATAL_IF_SANITY_CHECK_FAILS:
563           {
564             /* Since the device has changed under us, the inode number
565              * will almost certainly also be different. However, we have
566              * already decided that this is not a problem.  Hence we return
567              * without checking the inode number.
568              */
569             free (specific_what);
570             return true;
571           }
572
573         case RETRY_IF_SANITY_CHECK_FAILS:
574           return false;
575         }
576     }
577
578   /* Device number was the same, check if the inode has changed. */
579   if (old_ino != newinfo->st_ino)
580     {
581       *changed = true;
582       specific_what = specific_dirname (what);
583       fstype = filesystem_type (newinfo, current_dir);
584
585       error ((isfatal == FATAL_IF_SANITY_CHECK_FAILS) ? 1 : 0,
586              0,                 /* no relevant errno value */
587              _("%s%s changed during execution of %s "
588                "(old inode number %" PRIuMAX ", new inode number %" PRIuMAX
589                ", file system type is %s) [ref %ld]"),
590              safely_quote_err_filename (0, specific_what),
591              parent ? "/.." : "",
592              safely_quote_err_filename (1, progname),
593              (uintmax_t) old_ino,
594              (uintmax_t) newinfo->st_ino,
595              fstype,
596              (long)line_no);
597       free (specific_what);
598       return false;
599     }
600
601   return true;
602 }
603
604 enum SafeChdirStatus
605   {
606     SafeChdirOK,
607     SafeChdirFailSymlink,
608     SafeChdirFailNotDir,
609     SafeChdirFailStat,
610     SafeChdirFailWouldBeUnableToReturn,
611     SafeChdirFailChdirFailed,
612     SafeChdirFailNonexistent,
613     SafeChdirFailDestUnreadable
614   };
615
616 /* Safely perform a change in directory.  We do this by calling
617  * lstat() on the subdirectory, using chdir() to move into it, and
618  * then lstat()ing ".".  We compare the results of the two stat calls
619  * to see if they are consistent.  If not, we sound the alarm.
620  *
621  * If following_links() is true, we do follow symbolic links.
622  */
623 static enum SafeChdirStatus
624 safely_chdir_lstat (const char *dest,
625                     enum TraversalDirection direction,
626                     struct stat *statbuf_dest,
627                     enum ChdirSymlinkHandling symlink_follow_option,
628                     bool *did_stat)
629 {
630   struct stat statbuf_arrived;
631   int rv, dotfd=-1;
632   int saved_errno;              /* specific_dirname() changes errno. */
633   bool rv_set = false;
634   bool statflag = false;
635   int tries = 0;
636   enum WdSanityCheckFatality isfatal = RETRY_IF_SANITY_CHECK_FAILS;
637
638   saved_errno = errno = 0;
639
640   dotfd = open_cloexec (".", O_RDONLY
641 #if defined O_LARGEFILE
642                         |O_LARGEFILE
643 #endif
644                         );
645
646   /* We jump back to here if wd_sanity_check()
647    * recoverably triggers an alert.
648    */
649  retry:
650   ++tries;
651
652   if (dotfd >= 0)
653     {
654       /* Stat the directory we're going to. */
655       set_stat_placeholders (statbuf_dest);
656       if (0 == options.xstat (dest, statbuf_dest))
657         {
658           statflag = true;
659
660 #ifdef S_ISLNK
661           /* symlink_follow_option might be set to SymlinkFollowOk, which
662            * would allow us to chdir() into a symbolic link.  This is
663            * only useful for the case where the directory we're
664            * chdir()ing into is the basename of a command line
665            * argument, for example where "foo/bar/baz" is specified on
666            * the command line.  When -P is in effect (the default),
667            * baz will not be followed if it is a symlink, but if bar
668            * is a symlink, it _should_ be followed.  Hence we need the
669            * ability to override the policy set by following_links().
670            */
671           if (!following_links () && S_ISLNK(statbuf_dest->st_mode))
672             {
673               /* We're not supposed to be following links, but this is
674                * a link.  Check symlink_follow_option to see if we should
675                * make a special exception.
676                */
677               if (symlink_follow_option == SymlinkFollowOk)
678                 {
679                   /* We need to re-stat() the file so that the
680                    * sanity check can pass.
681                    */
682                   if (0 != stat (dest, statbuf_dest))
683                     {
684                       rv = SafeChdirFailNonexistent;
685                       rv_set = true;
686                       saved_errno = errno;
687                       goto fail;
688                     }
689                   statflag = true;
690                 }
691               else
692                 {
693                   /* Not following symlinks, so the attempt to
694                    * chdir() into a symlink should be prevented.
695                    */
696                   rv = SafeChdirFailSymlink;
697                   rv_set = true;
698                   saved_errno = 0;      /* silence the error message */
699                   goto fail;
700                 }
701             }
702 #endif
703 #ifdef S_ISDIR
704           /* Although the immediately following chdir() would detect
705            * the fact that this is not a directory for us, this would
706            * result in an extra system call that fails.  Anybody
707            * examining the system-call trace should ideally not be
708            * concerned that something is actually failing.
709            */
710           if (!S_ISDIR(statbuf_dest->st_mode))
711             {
712               rv = SafeChdirFailNotDir;
713               rv_set = true;
714               saved_errno = 0;  /* silence the error message */
715               goto fail;
716             }
717 #endif
718
719           if (options.debug_options & DebugSearch)
720             fprintf (stderr, "safely_chdir(): chdir(\"%s\")\n", dest);
721
722           if (0 == chdir (dest))
723             {
724               /* check we ended up where we wanted to go */
725               bool changed = false;
726               if (!wd_sanity_check (".", program_name, ".",
727                                     statbuf_dest->st_dev,
728                                     statbuf_dest->st_ino,
729                                     &statbuf_arrived,
730                                     0, __LINE__, direction,
731                                     isfatal,
732                                     &changed))
733                 {
734                   /* Only allow one failure. */
735                   if (RETRY_IF_SANITY_CHECK_FAILS == isfatal)
736                     {
737                       if (0 == fchdir (dotfd))
738                         {
739                           isfatal = FATAL_IF_SANITY_CHECK_FAILS;
740                           goto retry;
741                         }
742                       else
743                         {
744                           /* Failed to return to original directory,
745                            * but we know that the current working
746                            * directory is not the one that we intend
747                            * to be in.  Since fchdir() failed, we
748                            * can't recover from this and so this error
749                            * is fatal.
750                            */
751                           error (EXIT_FAILURE, errno,
752                                  _("failed to return to parent directory"));
753                         }
754                     }
755                   else
756                     {
757                       /* XXX: not sure what to use as an excuse here. */
758                       rv = SafeChdirFailNonexistent;
759                       rv_set = true;
760                       saved_errno = 0;
761                       goto fail;
762                     }
763                 }
764
765               close (dotfd);
766               return SafeChdirOK;
767             }
768           else
769             {
770               saved_errno = errno;
771               if (ENOENT == saved_errno)
772                 {
773                   rv = SafeChdirFailNonexistent;
774                   rv_set = true;
775                   if (options.ignore_readdir_race)
776                     errno = 0;  /* don't issue err msg */
777                 }
778               else if (ENOTDIR == saved_errno)
779                 {
780                   /* This can happen if the we stat a directory,
781                    * and then file system activity changes it into
782                    * a non-directory.
783                    */
784                   saved_errno = 0;      /* don't issue err msg */
785                   rv = SafeChdirFailNotDir;
786                   rv_set = true;
787                 }
788               else
789                 {
790                   rv = SafeChdirFailChdirFailed;
791                   rv_set = true;
792                 }
793               goto fail;
794             }
795         }
796       else
797         {
798           saved_errno = errno;
799           rv = SafeChdirFailStat;
800           rv_set = true;
801
802           if ( (ENOENT == saved_errno) || (0 == state.curdepth))
803             saved_errno = 0;    /* don't issue err msg */
804           goto fail;
805         }
806     }
807   else
808     {
809       /* We do not have read permissions on "." */
810       rv = SafeChdirFailWouldBeUnableToReturn;
811       rv_set = true;
812       goto fail;
813     }
814
815   /* This is the success path, so we clear errno.  The caller probably
816    * won't be calling error() anyway.
817    */
818   saved_errno = 0;
819
820   /* We use the same exit path for success or failure.
821    * which has occurred is recorded in RV.
822    */
823  fail:
824   /* We do not call error() as this would result in a duplicate error
825    * message when the caller does the same thing.
826    */
827   if (saved_errno)
828     errno = saved_errno;
829
830   if (dotfd >= 0)
831     {
832       close (dotfd);
833       dotfd = -1;
834     }
835
836   *did_stat = statflag;
837   assert (rv_set);
838   return rv;
839 }
840
841 /* Safely change working directory to the specified subdirectory.  If
842  * we are not allowed to follow symbolic links, we use open() with
843  * O_NOFOLLOW, followed by fchdir().  This ensures that we don't
844  * follow symbolic links (of course, we do follow them if the -L
845  * option is in effect).
846  */
847 static enum SafeChdirStatus
848 safely_chdir_nofollow (const char *dest,
849                        enum TraversalDirection direction,
850                        struct stat *statbuf_dest,
851                        enum ChdirSymlinkHandling symlink_follow_option,
852                        bool *did_stat)
853 {
854   int extraflags, fd;
855
856   (void) direction;
857   (void) statbuf_dest;
858
859   extraflags = 0;
860   *did_stat = false;
861
862   switch (symlink_follow_option)
863     {
864     case SymlinkFollowOk:
865       extraflags = 0;
866       break;
867
868     case SymlinkHandleDefault:
869       if (following_links ())
870         extraflags = 0;
871       else
872         extraflags = O_NOFOLLOW; /* ... which may still be 0. */
873       break;
874     }
875
876   errno = 0;
877   fd = open (dest, O_RDONLY
878 #if defined O_LARGEFILE
879             |O_LARGEFILE
880 #endif
881 #if defined O_CLOEXEC
882             |O_CLOEXEC
883 #endif
884             |extraflags);
885   if (fd < 0)
886     {
887       switch (errno)
888         {
889         case ELOOP:
890           return SafeChdirFailSymlink; /* This is why we use O_NOFOLLOW */
891         case ENOENT:
892           return SafeChdirFailNonexistent;
893         default:
894           return SafeChdirFailDestUnreadable;
895         }
896     }
897
898   errno = 0;
899   if (0 == fchdir (fd))
900     {
901       close (fd);
902       return SafeChdirOK;
903     }
904   else
905     {
906       int saved_errno = errno;
907       close (fd);
908       errno = saved_errno;
909
910       switch (errno)
911         {
912         case ENOTDIR:
913           return SafeChdirFailNotDir;
914
915         case EACCES:
916         case EBADF:             /* Shouldn't happen */
917         case EINTR:
918         case EIO:
919         default:
920           return SafeChdirFailChdirFailed;
921         }
922     }
923 }
924
925 static enum SafeChdirStatus
926 safely_chdir (const char *dest,
927               enum TraversalDirection direction,
928               struct stat *statbuf_dest,
929               enum ChdirSymlinkHandling symlink_follow_option,
930               bool *did_stat)
931 {
932   enum SafeChdirStatus result;
933
934   /* We're about to leave a directory.  If there are any -execdir
935    * argument lists which have been built but have not yet been
936    * processed, do them now because they must be done in the same
937    * directory.
938    */
939   complete_pending_execdirs ();
940
941   /* gnulib defines O_NOFOLLOW to 0 if the OS doesn't have it. */
942   options.open_nofollow_available = !!O_NOFOLLOW;
943   if (options.open_nofollow_available)
944     {
945       result = safely_chdir_nofollow (dest, direction, statbuf_dest,
946                                      symlink_follow_option, did_stat);
947       if (SafeChdirFailDestUnreadable != result)
948         {
949           return result;
950         }
951       else
952         {
953           /* Savannah bug #15384: fall through to use safely_chdir_lstat
954            * if the directory is not readable.
955            */
956           /* Do nothing. */
957         }
958     }
959   /* Even if O_NOFOLLOW is available, we may need to use the alternative
960    * method, since parent of the start point may be executable but not
961    * readable.
962    */
963   return safely_chdir_lstat (dest, direction, statbuf_dest,
964                              symlink_follow_option, did_stat);
965 }
966
967
968
969 /* Safely go back to the starting directory. */
970 static void
971 chdir_back (void)
972 {
973   if (options.debug_options & DebugSearch)
974     fprintf (stderr, "chdir_back(): chdir to start point\n");
975
976   restore_cwd (initial_wd);
977 }
978
979 /* Move to the parent of a given directory and then call a function,
980  * restoring the cwd.  Don't bother changing directory if the
981  * specified directory is a child of "." or is the root directory.
982  */
983 static void
984 at_top (char *pathname,
985         mode_t mode,
986         ino_t inum,
987         struct stat *pstat,
988         void (*action)(char *pathname,
989                        char *basename,
990                        int mode,
991                        ino_t inum,
992                        struct stat *pstat))
993 {
994   int dirchange;
995   char *parent_dir = dir_name (pathname);
996   char *base = last_component (pathname);
997
998   state.curdepth = 0;
999   state.starting_path_length = strlen (pathname);
1000
1001   if (0 == *base
1002       || 0 == strcmp (parent_dir, "."))
1003     {
1004       dirchange = 0;
1005       base = pathname;
1006     }
1007   else
1008     {
1009       enum TraversalDirection direction;
1010       enum SafeChdirStatus chdir_status;
1011       struct stat st;
1012       bool did_stat = false;
1013
1014       dirchange = 1;
1015       if (0 == strcmp (base, ".."))
1016         direction = TraversingUp;
1017       else
1018         direction = TraversingDown;
1019
1020       /* We pass SymlinkFollowOk to safely_chdir(), which allows it to
1021        * chdir() into a symbolic link.  This is only useful for the
1022        * case where the directory we're chdir()ing into is the
1023        * basename of a command line argument, for example where
1024        * "foo/bar/baz" is specified on the command line.  When -P is
1025        * in effect (the default), baz will not be followed if it is a
1026        * symlink, but if bar is a symlink, it _should_ be followed.
1027        * Hence we need the ability to override the policy set by
1028        * following_links().
1029        */
1030       chdir_status = safely_chdir (parent_dir, direction, &st, SymlinkFollowOk, &did_stat);
1031       if (SafeChdirOK != chdir_status)
1032         {
1033           const char *what = (SafeChdirFailWouldBeUnableToReturn == chdir_status) ? "." : parent_dir;
1034           if (errno)
1035             error (0, errno, "%s",
1036                    safely_quote_err_filename (0, what));
1037           else
1038             error (0, 0, _("Failed to safely change directory into %s"),
1039                    safely_quote_err_filename (0, parent_dir));
1040
1041           /* We can't process this command-line argument. */
1042           state.exit_status = 1;
1043           return;
1044         }
1045     }
1046
1047   free (parent_dir);
1048   parent_dir = NULL;
1049
1050   action (pathname, base, mode, inum, pstat);
1051
1052   if (dirchange)
1053     {
1054       chdir_back ();
1055     }
1056 }
1057
1058
1059 static void do_process_top_dir (char *pathname,
1060                                 char *base,
1061                                 int mode,
1062                                 ino_t inum,
1063                                 struct stat *pstat)
1064 {
1065   (void) pstat;
1066
1067   process_path (pathname, base, false, ".", mode, inum);
1068   complete_pending_execdirs ();
1069 }
1070
1071 static void
1072 do_process_predicate (char *pathname,
1073                       char *base,
1074                       int mode,
1075                       ino_t inum,
1076                       struct stat *pstat)
1077 {
1078   (void) mode;
1079   (void) inum;
1080   state.rel_pathname = base;    /* cwd_dir_fd was already set by safely_chdir */
1081   apply_predicate (pathname, pstat, get_eval_tree ());
1082 }
1083
1084
1085
1086
1087 /* Descend PATHNAME, which is a command-line argument.
1088
1089    Actions like -execdir assume that we are in the
1090    parent directory of the file we're examining,
1091    and on entry to this function our working directory
1092    is whatever it was when find was invoked.  Therefore
1093    If PATHNAME is "." we just leave things as they are.
1094    Otherwise, we figure out what the parent directory is,
1095    and move to that.
1096 */
1097 static void
1098 process_top_path (char *pathname, mode_t mode, ino_t inum)
1099 {
1100   at_top (pathname, mode, inum, NULL, do_process_top_dir);
1101 }
1102
1103
1104 /* Info on each directory in the current tree branch, to avoid
1105    getting stuck in symbolic link loops.  */
1106 static struct dir_id *dir_ids = NULL;
1107 /* Entries allocated in `dir_ids'.  */
1108 static int dir_alloc = 0;
1109 /* Index in `dir_ids' of directory currently being searched.
1110    This is always the last valid entry.  */
1111 static int dir_curr = -1;
1112 /* (Arbitrary) number of entries to grow `dir_ids' by.  */
1113 #define DIR_ALLOC_STEP 32
1114
1115
1116
1117 /* We've detected a file system loop.   This is caused by one of
1118  * two things:
1119  *
1120  * 1. Option -L is in effect and we've hit a symbolic link that
1121  *    points to an ancestor.  This is harmless.  We won't traverse the
1122  *    symbolic link.
1123  *
1124  * 2. We have hit a real cycle in the directory hierarchy.  In this
1125  *    case, we issue a diagnostic message (POSIX requires this) and we
1126  *    skip that directory entry.
1127  */
1128 static void
1129 issue_loop_warning (const char *name, const char *pathname, int level)
1130 {
1131   struct stat stbuf_link;
1132   if (lstat (name, &stbuf_link) != 0)
1133     stbuf_link.st_mode = S_IFREG;
1134
1135   if (S_ISLNK(stbuf_link.st_mode))
1136     {
1137       error (0, 0,
1138              _("Symbolic link %s is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
1139              safely_quote_err_filename (0, pathname));
1140       /* XXX: POSIX appears to require that the exit status be non-zero if a
1141        * diagnostic is issued.
1142        */
1143     }
1144   else
1145     {
1146       int distance = 1 + (dir_curr-level);
1147       /* We have found an infinite loop.  POSIX requires us to
1148        * issue a diagnostic.  Usually we won't get to here
1149        * because when the leaf optimisation is on, it will cause
1150        * the subdirectory to be skipped.  If /a/b/c/d is a hard
1151        * link to /a/b, then the link count of /a/b/c is 2,
1152        * because the ".." entry of /b/b/c/d points to /a, not
1153        * to /a/b/c.
1154        */
1155       error (0, 0,
1156              ngettext (
1157                        "Filesystem loop detected; %s has the same device number and inode as "
1158                        "a directory which is %d level higher in the file system hierarchy",
1159                        "Filesystem loop detected; %s has the same device number and inode as "
1160                        "a directory which is %d levels higher in the file system hierarchy",
1161                        (long)distance),
1162              safely_quote_err_filename (0, pathname),
1163              distance);
1164     }
1165 }
1166
1167
1168
1169 /* Recursively descend path PATHNAME, applying the predicates.
1170    LEAF is true if PATHNAME is known to be in a directory that has no
1171    more unexamined subdirectories, and therefore it is not a directory.
1172    Knowing this allows us to avoid calling stat as long as possible for
1173    leaf files.
1174
1175    NAME is PATHNAME relative to the current directory.  We access NAME
1176    but print PATHNAME.
1177
1178    PARENT is the path of the parent of NAME, relative to find's
1179    starting directory.
1180
1181    Return nonzero iff PATHNAME is a directory. */
1182
1183 static int
1184 process_path (char *pathname, char *name, bool leaf, char *parent,
1185               mode_t mode, ino_t inum)
1186 {
1187   struct stat stat_buf;
1188   static dev_t root_dev;        /* Device ID of current argument pathname. */
1189   int i;
1190   struct predicate *eval_tree;
1191
1192   eval_tree = get_eval_tree ();
1193   /* Assume it is a non-directory initially. */
1194   stat_buf.st_mode = 0;
1195
1196   /* The caller usually knows the inode number, either from readdir or
1197    * a *stat call.  We use that value (the caller passes 0 to indicate
1198    * ignorance of the inode number).
1199    */
1200   stat_buf.st_ino = inum;
1201
1202   state.rel_pathname = name;
1203   state.type = 0;
1204   state.have_stat = false;
1205   state.have_type = false;
1206   state.already_issued_stat_error_msg = false;
1207
1208   if (!digest_mode (&mode, pathname, name, &stat_buf, leaf))
1209     return 0;
1210
1211   if (!S_ISDIR (state.type))
1212     {
1213       if (state.curdepth >= options.mindepth)
1214         apply_predicate (pathname, &stat_buf, eval_tree);
1215       return 0;
1216     }
1217
1218   /* From here on, we're working on a directory.  */
1219
1220
1221   /* Now we really need to stat the directory, even if we know the
1222    * type, because we need information like struct stat.st_rdev.
1223    */
1224   if (get_statinfo (pathname, name, &stat_buf) != 0)
1225     return 0;
1226
1227   state.have_stat = true;
1228   mode = state.type = stat_buf.st_mode; /* use full info now that we have it. */
1229   state.stop_at_current_level =
1230     options.maxdepth >= 0
1231     && state.curdepth >= options.maxdepth;
1232
1233   /* If we've already seen this directory on this branch,
1234      don't descend it again.  */
1235   for (i = 0; i <= dir_curr; i++)
1236     if (stat_buf.st_ino == dir_ids[i].ino &&
1237         stat_buf.st_dev == dir_ids[i].dev)
1238       {
1239         state.stop_at_current_level = true;
1240         issue_loop_warning (name, pathname, i);
1241       }
1242
1243   if (dir_alloc <= ++dir_curr)
1244     {
1245       dir_alloc += DIR_ALLOC_STEP;
1246       dir_ids = (struct dir_id *)
1247         xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id));
1248     }
1249   dir_ids[dir_curr].ino = stat_buf.st_ino;
1250   dir_ids[dir_curr].dev = stat_buf.st_dev;
1251
1252   if (options.stay_on_filesystem)
1253     {
1254       if (state.curdepth == 0)
1255         root_dev = stat_buf.st_dev;
1256       else if (stat_buf.st_dev != root_dev)
1257         state.stop_at_current_level = true;
1258     }
1259
1260   if (options.do_dir_first && state.curdepth >= options.mindepth)
1261     apply_predicate (pathname, &stat_buf, eval_tree);
1262
1263   if (options.debug_options & DebugSearch)
1264     fprintf (stderr, "pathname = %s, stop_at_current_level = %d\n",
1265              pathname, state.stop_at_current_level);
1266
1267   if (state.stop_at_current_level == false)
1268     {
1269       /* Scan directory on disk. */
1270       process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
1271     }
1272
1273   if (options.do_dir_first == false && state.curdepth >= options.mindepth)
1274     {
1275       /* The fields in 'state' are now out of date.  Correct them.
1276        */
1277       if (!digest_mode (&mode, pathname, name, &stat_buf, leaf))
1278         return 0;
1279
1280       if (0 == dir_curr)
1281         {
1282           at_top (pathname, mode, stat_buf.st_ino, &stat_buf,
1283                   do_process_predicate);
1284         }
1285       else
1286         {
1287           do_process_predicate (pathname, name, mode, stat_buf.st_ino,
1288                                 &stat_buf);
1289         }
1290     }
1291
1292   dir_curr--;
1293
1294   return 1;
1295 }
1296
1297
1298 /* Scan directory PATHNAME and recurse through process_path for each entry.
1299
1300    PATHLEN is the length of PATHNAME.
1301
1302    NAME is PATHNAME relative to the current directory.
1303
1304    STATP is the results of *options.xstat on it.
1305
1306    PARENT is the path of the parent of NAME, relative to find's
1307    starting directory.  */
1308
1309 static void
1310 process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent)
1311 {
1312   int subdirs_left;             /* Number of unexamined subdirs in PATHNAME. */
1313   bool subdirs_unreliable;      /* if true, cannot use dir link count as subdir limif (if false, it may STILL be unreliable) */
1314   struct stat stat_buf;
1315   size_t dircount = 0u;
1316   DIR *dirp;
1317
1318   if (statp->st_nlink < 2)
1319     {
1320       subdirs_unreliable = true;
1321       subdirs_left = 0;
1322     }
1323   else
1324     {
1325       subdirs_unreliable = false; /* not necessarily right */
1326       subdirs_left = statp->st_nlink - 2; /* Account for name and ".". */
1327     }
1328
1329   errno = 0;
1330   dirp = opendir_safer (name);
1331
1332   if (dirp == NULL)
1333     {
1334       assert (errno != 0);
1335       error (0, errno, "%s", safely_quote_err_filename (0, pathname));
1336       state.exit_status = 1;
1337     }
1338   else
1339     {
1340       char *cur_path;           /* Full path of each file to process. */
1341       char *cur_name;           /* Base name of each file to process. */
1342       unsigned cur_path_size;   /* Bytes allocated for `cur_path'. */
1343       register unsigned file_len; /* Length of each path to process. */
1344       register unsigned pathname_len; /* PATHLEN plus trailing '/'. */
1345       bool did_stat = false;
1346
1347       if (pathname[pathlen - 1] == '/')
1348         pathname_len = pathlen + 1; /* For '\0'; already have '/'. */
1349       else
1350         pathname_len = pathlen + 2; /* For '/' and '\0'. */
1351       cur_path_size = 0;
1352       cur_path = NULL;
1353
1354       /* We're about to leave the directory.  If there are any
1355        * -execdir argument lists which have been built but have not
1356        * yet been processed, do them now because they must be done in
1357        * the same directory.
1358        */
1359       complete_pending_execdirs ();
1360
1361       if (strcmp (name, "."))
1362         {
1363           enum SafeChdirStatus status = safely_chdir (name, TraversingDown, &stat_buf, SymlinkHandleDefault, &did_stat);
1364           switch (status)
1365             {
1366             case SafeChdirOK:
1367               /* If there had been a change but wd_sanity_check()
1368                * accepted it, we need to accept that on the
1369                * way back up as well, so modify our record
1370                * of what we think we should see later.
1371                * If there was no change, the assignments are a no-op.
1372                *
1373                * However, before performing the assignment, we need to
1374                * check that we have the stat information.   If O_NOFOLLOW
1375                * is available, safely_chdir() will not have needed to use
1376                * stat(), and so stat_buf will just contain random data.
1377                */
1378               if (!did_stat)
1379                 {
1380                   /* If there is a link we need to follow it.  Hence
1381                    * the direct call to stat() not through (options.xstat)
1382                    */
1383                   set_stat_placeholders (&stat_buf);
1384                   if (0 != stat (".", &stat_buf))
1385                     break;      /* skip the assignment. */
1386                 }
1387               dir_ids[dir_curr].dev = stat_buf.st_dev;
1388               dir_ids[dir_curr].ino = stat_buf.st_ino;
1389
1390               break;
1391
1392             case SafeChdirFailWouldBeUnableToReturn:
1393               error (0, errno, ".");
1394               state.exit_status = 1;
1395               break;
1396
1397             case SafeChdirFailNonexistent:
1398             case SafeChdirFailDestUnreadable:
1399             case SafeChdirFailStat:
1400             case SafeChdirFailNotDir:
1401             case SafeChdirFailChdirFailed:
1402               error (0, errno, "%s",
1403                      safely_quote_err_filename (0, pathname));
1404               state.exit_status = 1;
1405               return;
1406
1407             case SafeChdirFailSymlink:
1408               error (0, 0,
1409                      _("warning: not following the symbolic link %s"),
1410                      safely_quote_err_filename (0, pathname));
1411               state.exit_status = 1;
1412               return;
1413             }
1414         }
1415
1416       while (1)
1417         {
1418           const char *namep;
1419           mode_t mode = 0;
1420           const struct dirent *dp;
1421
1422           /* We reset errno here to distinguish between end-of-directory and an error */
1423           errno = 0;
1424           dp = readdir (dirp);
1425           if (NULL == dp)
1426             {
1427               if (errno)
1428                 {
1429                   /* an error occurred, but we are not yet at the end
1430                      of the directory stream. */
1431                   error (0, errno, "%s", safely_quote_err_filename (0, pathname));
1432                   continue;
1433                 }
1434               else
1435                 {
1436                   break;        /* End of the directory stream. */
1437                 }
1438             }
1439           else
1440             {
1441               namep = dp->d_name;
1442               /* Skip "", ".", and "..".  "" is returned by at least one buggy
1443                  implementation: Solaris 2.4 readdir on NFS file systems.  */
1444               if (!namep[0] || (namep[0] == '.' && (namep[1] == '.' || namep[1] == 0)))
1445                 continue;
1446             }
1447
1448 #if defined HAVE_STRUCT_DIRENT_D_TYPE
1449           if (dp->d_type != DT_UNKNOWN)
1450             mode = type_to_mode (dp->d_type);
1451 #endif
1452
1453           /* Append this directory entry's name to the path being searched. */
1454           file_len = pathname_len + strlen (namep);
1455           if (file_len > cur_path_size)
1456             {
1457               while (file_len > cur_path_size)
1458                 cur_path_size += 1024;
1459               free (cur_path);
1460               cur_path = xmalloc (cur_path_size);
1461               strcpy (cur_path, pathname);
1462               cur_path[pathname_len - 2] = '/';
1463             }
1464           cur_name = cur_path + pathname_len - 1;
1465           strcpy (cur_name, namep);
1466
1467           state.curdepth++;
1468           if (!options.no_leaf_check && !subdirs_unreliable)
1469             {
1470               if (mode && S_ISDIR(mode) && (subdirs_left == 0))
1471                 {
1472                   /* This is a subdirectory, but the number of directories we
1473                    * have found now exceeds the number we would expect given
1474                    * the hard link count on the parent.   This is likely to be
1475                    * a bug in the file system driver (e.g. Linux's
1476                    * /proc file system) or may just be a fact that the OS
1477                    * doesn't really handle hard links with Unix semantics.
1478                    * In the latter case, -noleaf should be used routinely.
1479                    */
1480                   error (0, 0, _("WARNING: Hard link count is wrong for %s (saw only st_nlink=%" PRIuMAX  " but we already saw %" PRIuMAX " subdirectories): this may be a bug in your file system driver.  Automatically turning on find's -noleaf option.  Earlier results may have failed to include directories that should have been searched."),
1481                          safely_quote_err_filename(0, pathname),
1482                          (uintmax_t) statp->st_nlink,
1483                          (uintmax_t) dircount);
1484                   state.exit_status = 1; /* We know the result is wrong, now */
1485                   options.no_leaf_check = true; /* Don't make same
1486                                                    mistake again */
1487                   subdirs_unreliable = 1;
1488                   subdirs_left = 1; /* band-aid for this iteration. */
1489                 }
1490
1491               /* Normal case optimization.  On normal Unix
1492                  file systems, a directory that has no subdirectories
1493                  has two links: its name, and ".".  Any additional
1494                  links are to the ".." entries of its subdirectories.
1495                  Once we have processed as many subdirectories as
1496                  there are additional links, we know that the rest of
1497                  the entries are non-directories -- in other words,
1498                  leaf files. */
1499               {
1500                 int count;
1501                 count = process_path (cur_path, cur_name,
1502                                       subdirs_left == 0, pathname,
1503                                       mode, D_INO(dp));
1504                 subdirs_left -= count;
1505                 dircount += count;
1506               }
1507             }
1508           else
1509             {
1510               /* There might be weird (e.g., CD-ROM or MS-DOS) file systems
1511                  mounted, which don't have Unix-like directory link counts. */
1512               process_path (cur_path, cur_name, false, pathname, mode,
1513                             D_INO(dp));
1514             }
1515
1516           state.curdepth--;
1517         }
1518
1519
1520       /* We're about to leave the directory.  If there are any
1521        * -execdir argument lists which have been built but have not
1522        * yet been processed, do them now because they must be done in
1523        * the same directory.
1524        */
1525       complete_pending_execdirs ();
1526
1527       if (strcmp (name, "."))
1528         {
1529           enum SafeChdirStatus status;
1530
1531           /* We could go back and do the next command-line arg
1532              instead, maybe using longjmp.  */
1533           char const *dir;
1534           bool deref = following_links () ? true : false;
1535
1536           if ( (state.curdepth>0) && !deref)
1537             dir = "..";
1538           else
1539             {
1540               chdir_back ();
1541               dir = parent;
1542             }
1543
1544           did_stat = false;
1545           status = safely_chdir (dir, TraversingUp, &stat_buf, SymlinkHandleDefault, &did_stat);
1546           switch (status)
1547             {
1548             case SafeChdirOK:
1549               break;
1550
1551             case SafeChdirFailWouldBeUnableToReturn:
1552               error (EXIT_FAILURE, errno, ".");
1553               return;
1554
1555             case SafeChdirFailNonexistent:
1556             case SafeChdirFailDestUnreadable:
1557             case SafeChdirFailStat:
1558             case SafeChdirFailSymlink:
1559             case SafeChdirFailNotDir:
1560             case SafeChdirFailChdirFailed:
1561               error (EXIT_FAILURE, errno,
1562                      "%s", safely_quote_err_filename (0, pathname));
1563               return;
1564             }
1565         }
1566
1567       free (cur_path);
1568       CLOSEDIR (dirp);
1569     }
1570
1571   if (subdirs_unreliable)
1572     {
1573       /* Make sure we hasn't used the variable subdirs_left if we knew
1574        * we shouldn't do so.
1575        */
1576       assert (0 == subdirs_left || options.no_leaf_check);
1577     }
1578 }