New files, from coreutils.
[pspp] / lib / fts.c
1 /* Traverse a file hierarchy.
2
3    Copyright (C) 2004, 2005 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 2, or (at your option)
8    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, write to the Free Software Foundation,
17    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18
19 /*-
20  * Copyright (c) 1990, 1993, 1994
21  *      The Regents of the University of California.  All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 4. Neither the name of the University nor the names of its contributors
32  *    may be used to endorse or promote products derived from this software
33  *    without specific prior written permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45  * SUCH DAMAGE.
46  */
47
48 #ifdef HAVE_CONFIG_H
49 # include <config.h>
50 #endif
51
52 #if defined(LIBC_SCCS) && !defined(lint)
53 static char sccsid[] = "@(#)fts.c       8.6 (Berkeley) 8/14/94";
54 #endif /* LIBC_SCCS and not lint */
55
56 #if HAVE_SYS_PARAM_H || defined _LIBC
57 # include <sys/param.h>
58 #endif
59 #ifdef _LIBC
60 # include <include/sys/stat.h>
61 #else
62 # include <sys/stat.h>
63 #endif
64 #include <fcntl.h>
65 #include <errno.h>
66 #include "dirfd.h"
67 #include "fts_.h"
68 #include "intprops.h"
69 #include "unistd-safer.h"
70 #include <stdlib.h>
71 #include <string.h>
72 #include <unistd.h>
73 #if HAVE_INTTYPES_H
74 # include <inttypes.h>
75 #endif
76 #if HAVE_STDINT_H
77 # include <stdint.h>
78 #endif
79 #if ULONG_MAX < ULLONG_MAX
80 # define LONGEST_MODIFIER "ll"
81 #else
82 # define LONGEST_MODIFIER "l"
83 #endif
84 #if PRI_MACROS_BROKEN
85 # undef PRIuMAX
86 #endif
87 #ifndef PRIuMAX
88 # define PRIuMAX LONGEST_MODIFIER "u"
89 #endif
90
91 #if defined _LIBC
92 # include <dirent.h>
93 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
94 #else
95 # if HAVE_DIRENT_H
96 #  include <dirent.h>
97 #  define NAMLEN(dirent) strlen ((dirent)->d_name)
98 # else
99 #  define dirent direct
100 #  define NAMLEN(dirent) (dirent)->d_namlen
101 #  if HAVE_SYS_NDIR_H
102 #   include <sys/ndir.h>
103 #  endif
104 #  if HAVE_SYS_DIR_H
105 #   include <sys/dir.h>
106 #  endif
107 #  if HAVE_NDIR_H
108 #   include <ndir.h>
109 #  endif
110 # endif
111 #endif
112
113 #ifdef _LIBC
114 # undef close
115 # define close __close
116 # undef closedir
117 # define closedir __closedir
118 # undef fchdir
119 # define fchdir __fchdir
120 # undef open
121 # define open __open
122 # undef opendir
123 # define opendir __opendir
124 # undef readdir
125 # define readdir __readdir
126 #else
127 # undef internal_function
128 # define internal_function /* empty */
129 #endif
130
131 /* Arrange to make lstat calls go through the wrapper function
132    on systems with an lstat function that does not dereference symlinks
133    that are specified with a trailing slash.  */
134 #if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
135 int rpl_lstat (const char *, struct stat *);
136 # undef lstat
137 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
138 #endif
139
140 #ifndef __set_errno
141 # define __set_errno(Val) errno = (Val)
142 #endif
143
144 #ifndef __attribute__
145 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
146 #  define __attribute__(x) /* empty */
147 # endif
148 #endif
149
150 #ifndef ATTRIBUTE_UNUSED
151 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
152 #endif
153
154
155 static FTSENT   *fts_alloc (FTS *, const char *, size_t) internal_function;
156 static FTSENT   *fts_build (FTS *, int) internal_function;
157 static void      fts_lfree (FTSENT *) internal_function;
158 static void      fts_load (FTS *, FTSENT *) internal_function;
159 static size_t    fts_maxarglen (char * const *) internal_function;
160 static void      fts_padjust (FTS *, FTSENT *) internal_function;
161 static bool      fts_palloc (FTS *, size_t) internal_function;
162 static FTSENT   *fts_sort (FTS *, FTSENT *, size_t) internal_function;
163 static unsigned short int fts_stat (FTS *, FTSENT *, bool) internal_function;
164 static int      fts_safe_changedir (FTS *, FTSENT *, int, const char *)
165      internal_function;
166
167 #ifndef MAX
168 # define MAX(a,b) ((a) > (b) ? (a) : (b))
169 #endif
170
171 #ifndef SIZE_MAX
172 # define SIZE_MAX ((size_t) -1)
173 #endif
174
175 #ifndef O_DIRECTORY
176 # define O_DIRECTORY 0
177 #endif
178
179 #define ISDOT(a)        (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
180
181 #define CLR(opt)        (sp->fts_options &= ~(opt))
182 #define ISSET(opt)      (sp->fts_options & (opt))
183 #define SET(opt)        (sp->fts_options |= (opt))
184
185 #define FCHDIR(sp, fd)  (!ISSET(FTS_NOCHDIR) && fchdir(fd))
186
187 /* fts_build flags */
188 #define BCHILD          1               /* fts_children */
189 #define BNAMES          2               /* fts_children, names only */
190 #define BREAD           3               /* fts_read */
191
192 #define HT_INITIAL_SIZE 31
193
194 #if FTS_DEBUG
195 bool fts_debug = false;
196 # include <stdio.h>
197 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
198 #else
199 # define Dprintf(x)
200 #endif
201
202 #define ENTER_DIR(Fts, Ent, Tag)                                \
203   do {                                                          \
204       Dprintf (("  %s-entering: %s\n", Tag, (Ent)->fts_path));  \
205       enter_dir (sp, p);                                        \
206     } while (0)
207
208 #define LEAVE_DIR(Fts, Ent, Tag)                                \
209   do {                                                          \
210       Dprintf (("  %s-leaving: %s\n", Tag, (Ent)->fts_path));   \
211       leave_dir (sp, p);                                        \
212     } while (0)
213
214 /* Use these each of these to map a device/inode pair to an FTSENT.  */
215 struct Active_dir
216 {
217   dev_t dev;
218   ino_t ino;
219   FTSENT *fts_ent;
220 };
221
222 static bool
223 AD_compare (void const *x, void const *y)
224 {
225   struct Active_dir const *ax = x;
226   struct Active_dir const *ay = y;
227   return ax->ino == ay->ino
228       && ax->dev == ay->dev;
229 }
230
231 static size_t
232 AD_hash (void const *x, size_t table_size)
233 {
234   struct Active_dir const *ax = x;
235   return (uintmax_t) ax->ino % table_size;
236 }
237
238 static void
239 enter_dir (FTS *fts, FTSENT *ent)
240 {
241   if (fts->active_dir_ht)
242     {
243       struct stat const *st = ent->fts_statp;
244       struct Active_dir *ad = malloc (sizeof (struct Active_dir));
245       struct Active_dir *ad_from_table;
246
247       if (ad == NULL)
248         goto give_up;
249
250       ad->dev = st->st_dev;
251       ad->ino = st->st_ino;
252       ad->fts_ent = ent;
253
254       /* See if we've already encountered this directory.
255          This can happen when following symlinks as well as
256          with a corrupted directory hierarchy. */
257       ad_from_table = hash_insert (fts->active_dir_ht, ad);
258
259       if (ad_from_table == NULL)
260         {
261         give_up:
262           /* Insertion failed due to lack of memory.  Free the hash
263              table and turn off this sort of cycle detection.  */
264           hash_free (fts->active_dir_ht);
265           fts->active_dir_ht = NULL;
266           return;
267         }
268
269       if (ad_from_table != ad)
270         {
271           /* There was an entry with matching dev/inode already in the table.
272              Record the fact that we've found a cycle.  */
273           ent->fts_cycle = ad_from_table->fts_ent;
274           ent->fts_info = FTS_DC;
275
276           /* ad was not inserted, so free it.  */
277           free (ad);
278         }
279     }
280   else if (fts->cycle_state)
281     {
282       if (cycle_check (fts->cycle_state, ent->fts_statp))
283         {
284           /* FIXME: setting fts_cycle like this isn't proper.
285              To do what the documentation requires, we'd have to
286              go around the cycle again and find the right entry.
287              But no callers in coreutils use the fts_cycle member. */
288           ent->fts_cycle = ent;
289           ent->fts_info = FTS_DC;
290         }
291     }
292 }
293
294 static void
295 leave_dir (FTS *fts, FTSENT *ent)
296 {
297   if (fts->active_dir_ht)
298     {
299       struct stat const *st = ent->fts_statp;
300       struct Active_dir obj;
301       void *found;
302       obj.dev = st->st_dev;
303       obj.ino = st->st_ino;
304       found = hash_delete (fts->active_dir_ht, &obj);
305       if (!found)
306         abort ();
307       free (found);
308     }
309 }
310
311 /* Open the directory DIR if possible, and return a file
312    descriptor.  Return -1 and set errno on failure.  It doesn't matter
313    whether the file descriptor has read or write access.  */
314
315 static int
316 internal_function
317 diropen (char const *dir)
318 {
319   int fd = open (dir, O_RDONLY | O_DIRECTORY);
320   if (fd < 0)
321     fd = open (dir, O_WRONLY | O_DIRECTORY);
322   return fd;
323 }
324
325 FTS *
326 fts_open (char * const *argv,
327           register int options,
328           int (*compar) (FTSENT const **, FTSENT const **))
329 {
330         register FTS *sp;
331         register FTSENT *p, *root;
332         register size_t nitems;
333         FTSENT *parent, *tmp = NULL;    /* pacify gcc */
334         size_t len;
335
336         /* Options check. */
337         if (options & ~FTS_OPTIONMASK) {
338                 __set_errno (EINVAL);
339                 return (NULL);
340         }
341
342         /* Allocate/initialize the stream */
343         if ((sp = malloc(sizeof(FTS))) == NULL)
344                 return (NULL);
345         memset(sp, 0, sizeof(FTS));
346         sp->fts_compar = compar;
347         sp->fts_options = options;
348
349         /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
350         if (ISSET(FTS_LOGICAL))
351                 SET(FTS_NOCHDIR);
352
353         /*
354          * Start out with 1K of path space, and enough, in any case,
355          * to hold the user's paths.
356          */
357 #ifndef MAXPATHLEN
358 # define MAXPATHLEN 1024
359 #endif
360         if (! fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
361                 goto mem1;
362
363         /* Allocate/initialize root's parent. */
364         if ((parent = fts_alloc(sp, "", 0)) == NULL)
365                 goto mem2;
366         parent->fts_level = FTS_ROOTPARENTLEVEL;
367
368         /* Allocate/initialize root(s). */
369         for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
370                 /* Don't allow zero-length paths. */
371                 if ((len = strlen(*argv)) == 0) {
372                         __set_errno (ENOENT);
373                         goto mem3;
374                 }
375
376                 if ((p = fts_alloc(sp, *argv, len)) == NULL)
377                         goto mem3;
378                 p->fts_level = FTS_ROOTLEVEL;
379                 p->fts_parent = parent;
380                 p->fts_accpath = p->fts_name;
381                 p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW) != 0);
382
383                 /* Command-line "." and ".." are real directories. */
384                 if (p->fts_info == FTS_DOT)
385                         p->fts_info = FTS_D;
386
387                 /*
388                  * If comparison routine supplied, traverse in sorted
389                  * order; otherwise traverse in the order specified.
390                  */
391                 if (compar) {
392                         p->fts_link = root;
393                         root = p;
394                 } else {
395                         p->fts_link = NULL;
396                         if (root == NULL)
397                                 tmp = root = p;
398                         else {
399                                 tmp->fts_link = p;
400                                 tmp = p;
401                         }
402                 }
403         }
404         if (compar && nitems > 1)
405                 root = fts_sort(sp, root, nitems);
406
407         /*
408          * Allocate a dummy pointer and make fts_read think that we've just
409          * finished the node before the root(s); set p->fts_info to FTS_INIT
410          * so that everything about the "current" node is ignored.
411          */
412         if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
413                 goto mem3;
414         sp->fts_cur->fts_link = root;
415         sp->fts_cur->fts_info = FTS_INIT;
416
417         if (ISSET (FTS_TIGHT_CYCLE_CHECK))
418           {
419             sp->active_dir_ht = hash_initialize (HT_INITIAL_SIZE,
420                                                  NULL, AD_hash,
421                                                  AD_compare, free);
422             if (sp->active_dir_ht == NULL)
423               goto mem3;
424             sp->cycle_state = malloc (sizeof *sp->cycle_state);
425           }
426         else
427           {
428             sp->cycle_state = malloc (sizeof *sp->cycle_state);
429             if (sp->cycle_state == NULL)
430               goto mem3;
431             cycle_check_init (sp->cycle_state);
432             sp->active_dir_ht = NULL;
433           }
434
435         /*
436          * If using chdir(2), grab a file descriptor pointing to dot to ensure
437          * that we can get back here; this could be avoided for some paths,
438          * but almost certainly not worth the effort.  Slashes, symbolic links,
439          * and ".." are all fairly nasty problems.  Note, if we can't get the
440          * descriptor we run anyway, just more slowly.
441          */
442         if (!ISSET(FTS_NOCHDIR)
443             && (sp->fts_rfd = diropen (".")) < 0)
444                 SET(FTS_NOCHDIR);
445
446         return (sp);
447
448 mem3:   fts_lfree(root);
449         free(parent);
450 mem2:   free(sp->fts_path);
451 mem1:   free(sp);
452         return (NULL);
453 }
454
455 static void
456 internal_function
457 fts_load (FTS *sp, register FTSENT *p)
458 {
459         register size_t len;
460         register char *cp;
461
462         /*
463          * Load the stream structure for the next traversal.  Since we don't
464          * actually enter the directory until after the preorder visit, set
465          * the fts_accpath field specially so the chdir gets done to the right
466          * place and the user can access the first node.  From fts_open it's
467          * known that the path will fit.
468          */
469         len = p->fts_pathlen = p->fts_namelen;
470         memmove(sp->fts_path, p->fts_name, len + 1);
471         if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
472                 len = strlen(++cp);
473                 memmove(p->fts_name, cp, len + 1);
474                 p->fts_namelen = len;
475         }
476         p->fts_accpath = p->fts_path = sp->fts_path;
477         sp->fts_dev = p->fts_statp->st_dev;
478 }
479
480 int
481 fts_close (FTS *sp)
482 {
483         register FTSENT *freep, *p;
484         int saved_errno = 0;
485
486         /*
487          * This still works if we haven't read anything -- the dummy structure
488          * points to the root list, so we step through to the end of the root
489          * list which has a valid parent pointer.
490          */
491         if (sp->fts_cur) {
492                 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
493                         freep = p;
494                         p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
495                         free(freep);
496                 }
497                 free(p);
498         }
499
500         /* Free up child linked list, sort array, path buffer. */
501         if (sp->fts_child)
502                 fts_lfree(sp->fts_child);
503         if (sp->fts_array)
504                 free(sp->fts_array);
505         free(sp->fts_path);
506
507         /* Return to original directory, save errno if necessary. */
508         if (!ISSET(FTS_NOCHDIR)) {
509                 if (fchdir(sp->fts_rfd))
510                         saved_errno = errno;
511                 (void)close(sp->fts_rfd);
512         }
513
514         /* Free any memory used for cycle detection.  */
515         if (sp->active_dir_ht)
516           hash_free (sp->active_dir_ht);
517         if (sp->cycle_state)
518           free (sp->cycle_state);
519
520         /* Free up the stream pointer. */
521         free(sp);
522
523         /* Set errno and return. */
524         if (saved_errno) {
525                 __set_errno (saved_errno);
526                 return (-1);
527         }
528
529         return (0);
530 }
531
532 /*
533  * Special case of "/" at the end of the path so that slashes aren't
534  * appended which would cause paths to be written as "....//foo".
535  */
536 #define NAPPEND(p)                                                      \
537         (p->fts_path[p->fts_pathlen - 1] == '/'                         \
538             ? p->fts_pathlen - 1 : p->fts_pathlen)
539
540 FTSENT *
541 fts_read (register FTS *sp)
542 {
543         register FTSENT *p, *tmp;
544         register unsigned short int instr;
545         register char *t;
546         int saved_errno;
547
548         /* If finished or unrecoverable error, return NULL. */
549         if (sp->fts_cur == NULL || ISSET(FTS_STOP))
550                 return (NULL);
551
552         /* Set current node pointer. */
553         p = sp->fts_cur;
554
555         /* Save and zero out user instructions. */
556         instr = p->fts_instr;
557         p->fts_instr = FTS_NOINSTR;
558
559         /* Any type of file may be re-visited; re-stat and re-turn. */
560         if (instr == FTS_AGAIN) {
561                 p->fts_info = fts_stat(sp, p, false);
562                 return (p);
563         }
564         Dprintf (("fts_read: p=%s\n",
565                   p->fts_info == FTS_INIT ? "" : p->fts_path));
566
567         /*
568          * Following a symlink -- SLNONE test allows application to see
569          * SLNONE and recover.  If indirecting through a symlink, have
570          * keep a pointer to current location.  If unable to get that
571          * pointer, follow fails.
572          */
573         if (instr == FTS_FOLLOW &&
574             (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
575                 p->fts_info = fts_stat(sp, p, true);
576                 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
577                         if ((p->fts_symfd = diropen (".")) < 0) {
578                                 p->fts_errno = errno;
579                                 p->fts_info = FTS_ERR;
580                         } else
581                                 p->fts_flags |= FTS_SYMFOLLOW;
582                 }
583                 if (p->fts_info == FTS_D)
584                         ENTER_DIR (sp, p, "7");
585                 return (p);
586         }
587
588         /* Directory in pre-order. */
589         if (p->fts_info == FTS_D) {
590                 /* If skipped or crossed mount point, do post-order visit. */
591                 if (instr == FTS_SKIP ||
592                     (ISSET(FTS_XDEV) && p->fts_statp->st_dev != sp->fts_dev)) {
593                         if (p->fts_flags & FTS_SYMFOLLOW)
594                                 (void)close(p->fts_symfd);
595                         if (sp->fts_child) {
596                                 fts_lfree(sp->fts_child);
597                                 sp->fts_child = NULL;
598                         }
599                         p->fts_info = FTS_DP;
600                         LEAVE_DIR (sp, p, "1");
601                         return (p);
602                 }
603
604                 /* Rebuild if only read the names and now traversing. */
605                 if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
606                         CLR(FTS_NAMEONLY);
607                         fts_lfree(sp->fts_child);
608                         sp->fts_child = NULL;
609                 }
610
611                 /*
612                  * Cd to the subdirectory.
613                  *
614                  * If have already read and now fail to chdir, whack the list
615                  * to make the names come out right, and set the parent errno
616                  * so the application will eventually get an error condition.
617                  * Set the FTS_DONTCHDIR flag so that when we logically change
618                  * directories back to the parent we don't do a chdir.
619                  *
620                  * If haven't read do so.  If the read fails, fts_build sets
621                  * FTS_STOP or the fts_info field of the node.
622                  */
623                 if (sp->fts_child != NULL) {
624                         if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
625                                 p->fts_errno = errno;
626                                 p->fts_flags |= FTS_DONTCHDIR;
627                                 for (p = sp->fts_child; p != NULL;
628                                      p = p->fts_link)
629                                         p->fts_accpath =
630                                             p->fts_parent->fts_accpath;
631                         }
632                 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
633                         if (ISSET(FTS_STOP))
634                                 return (NULL);
635                         /* If fts_build's call to fts_safe_changedir failed
636                            because it was not able to fchdir into a
637                            subdirectory, tell the caller.  */
638                         if (p->fts_errno)
639                                 p->fts_info = FTS_ERR;
640                         /* FIXME: see if this should be in an else block */
641                         LEAVE_DIR (sp, p, "2");
642                         return (p);
643                 }
644                 p = sp->fts_child;
645                 sp->fts_child = NULL;
646                 goto name;
647         }
648
649         /* Move to the next node on this level. */
650 next:   tmp = p;
651         if ((p = p->fts_link) != NULL) {
652                 free(tmp);
653
654                 /*
655                  * If reached the top, return to the original directory (or
656                  * the root of the tree), and load the paths for the next root.
657                  */
658                 if (p->fts_level == FTS_ROOTLEVEL) {
659                         if (FCHDIR(sp, sp->fts_rfd)) {
660                                 SET(FTS_STOP);
661                                 return (NULL);
662                         }
663                         fts_load(sp, p);
664                         if (p->fts_info == FTS_D)
665                                 ENTER_DIR (sp, p, "8");
666                         return (sp->fts_cur = p);
667                 }
668
669                 /*
670                  * User may have called fts_set on the node.  If skipped,
671                  * ignore.  If followed, get a file descriptor so we can
672                  * get back if necessary.
673                  */
674                 if (p->fts_instr == FTS_SKIP)
675                         goto next;
676                 if (p->fts_instr == FTS_FOLLOW) {
677                         p->fts_info = fts_stat(sp, p, true);
678                         if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
679                                 if ((p->fts_symfd = diropen (".")) < 0) {
680                                         p->fts_errno = errno;
681                                         p->fts_info = FTS_ERR;
682                                 } else
683                                         p->fts_flags |= FTS_SYMFOLLOW;
684                         }
685                         p->fts_instr = FTS_NOINSTR;
686                 }
687
688 name:           t = sp->fts_path + NAPPEND(p->fts_parent);
689                 *t++ = '/';
690                 memmove(t, p->fts_name, p->fts_namelen + 1);
691                 if (p->fts_info == FTS_D)
692                         ENTER_DIR (sp, p, "9");
693                 return (sp->fts_cur = p);
694         }
695
696         /* Move up to the parent node. */
697         p = tmp->fts_parent;
698         free(tmp);
699
700         if (p->fts_level == FTS_ROOTPARENTLEVEL) {
701                 /*
702                  * Done; free everything up and set errno to 0 so the user
703                  * can distinguish between error and EOF.
704                  */
705                 free(p);
706                 __set_errno (0);
707                 return (sp->fts_cur = NULL);
708         }
709
710         /* NUL terminate the pathname. */
711         sp->fts_path[p->fts_pathlen] = '\0';
712
713         /*
714          * Return to the parent directory.  If at a root node or came through
715          * a symlink, go back through the file descriptor.  Otherwise, cd up
716          * one directory.
717          */
718         if (p->fts_level == FTS_ROOTLEVEL) {
719                 if (FCHDIR(sp, sp->fts_rfd)) {
720                         p->fts_errno = errno;
721                         SET(FTS_STOP);
722                 }
723         } else if (p->fts_flags & FTS_SYMFOLLOW) {
724                 if (FCHDIR(sp, p->fts_symfd)) {
725                         saved_errno = errno;
726                         (void)close(p->fts_symfd);
727                         __set_errno (saved_errno);
728                         p->fts_errno = errno;
729                         SET(FTS_STOP);
730                 }
731                 (void)close(p->fts_symfd);
732         } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
733                    fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
734                 p->fts_errno = errno;
735                 SET(FTS_STOP);
736         }
737         p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
738         if (p->fts_errno == 0)
739                 LEAVE_DIR (sp, p, "3");
740         sp->fts_cur = p;
741         return ISSET(FTS_STOP) ? NULL : p;
742 }
743
744 /*
745  * Fts_set takes the stream as an argument although it's not used in this
746  * implementation; it would be necessary if anyone wanted to add global
747  * semantics to fts using fts_set.  An error return is allowed for similar
748  * reasons.
749  */
750 /* ARGSUSED */
751 int
752 fts_set(FTS *sp ATTRIBUTE_UNUSED, FTSENT *p, int instr)
753 {
754         if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
755             instr != FTS_NOINSTR && instr != FTS_SKIP) {
756                 __set_errno (EINVAL);
757                 return (1);
758         }
759         p->fts_instr = instr;
760         return (0);
761 }
762
763 FTSENT *
764 fts_children (register FTS *sp, int instr)
765 {
766         register FTSENT *p;
767         int fd;
768
769         if (instr != 0 && instr != FTS_NAMEONLY) {
770                 __set_errno (EINVAL);
771                 return (NULL);
772         }
773
774         /* Set current node pointer. */
775         p = sp->fts_cur;
776
777         /*
778          * Errno set to 0 so user can distinguish empty directory from
779          * an error.
780          */
781         __set_errno (0);
782
783         /* Fatal errors stop here. */
784         if (ISSET(FTS_STOP))
785                 return (NULL);
786
787         /* Return logical hierarchy of user's arguments. */
788         if (p->fts_info == FTS_INIT)
789                 return (p->fts_link);
790
791         /*
792          * If not a directory being visited in pre-order, stop here.  Could
793          * allow FTS_DNR, assuming the user has fixed the problem, but the
794          * same effect is available with FTS_AGAIN.
795          */
796         if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
797                 return (NULL);
798
799         /* Free up any previous child list. */
800         if (sp->fts_child != NULL)
801                 fts_lfree(sp->fts_child);
802
803         if (instr == FTS_NAMEONLY) {
804                 SET(FTS_NAMEONLY);
805                 instr = BNAMES;
806         } else
807                 instr = BCHILD;
808
809         /*
810          * If using chdir on a relative path and called BEFORE fts_read does
811          * its chdir to the root of a traversal, we can lose -- we need to
812          * chdir into the subdirectory, and we don't know where the current
813          * directory is, so we can't get back so that the upcoming chdir by
814          * fts_read will work.
815          */
816         if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
817             ISSET(FTS_NOCHDIR))
818                 return (sp->fts_child = fts_build(sp, instr));
819
820         if ((fd = diropen (".")) < 0)
821                 return (sp->fts_child = NULL);
822         sp->fts_child = fts_build(sp, instr);
823         if (fchdir(fd)) {
824                 (void)close(fd);
825                 return (NULL);
826         }
827         (void)close(fd);
828         return (sp->fts_child);
829 }
830
831 /*
832  * This is the tricky part -- do not casually change *anything* in here.  The
833  * idea is to build the linked list of entries that are used by fts_children
834  * and fts_read.  There are lots of special cases.
835  *
836  * The real slowdown in walking the tree is the stat calls.  If FTS_NOSTAT is
837  * set and it's a physical walk (so that symbolic links can't be directories),
838  * we can do things quickly.  First, if it's a 4.4BSD file system, the type
839  * of the file is in the directory entry.  Otherwise, we assume that the number
840  * of subdirectories in a node is equal to the number of links to the parent.
841  * The former skips all stat calls.  The latter skips stat calls in any leaf
842  * directories and for any files after the subdirectories in the directory have
843  * been found, cutting the stat calls by about 2/3.
844  */
845 static FTSENT *
846 internal_function
847 fts_build (register FTS *sp, int type)
848 {
849         register struct dirent *dp;
850         register FTSENT *p, *head;
851         register size_t nitems;
852         FTSENT *cur, *tail;
853         DIR *dirp;
854         void *oldaddr;
855         int cderrno;
856         int saved_errno;
857         bool descend;
858         bool doadjust;
859         ptrdiff_t level;
860         nlink_t nlinks;
861         bool nostat;
862         size_t len, maxlen, new_len;
863         char *cp;
864
865         /* Set current node pointer. */
866         cur = sp->fts_cur;
867
868         /*
869          * Open the directory for reading.  If this fails, we're done.
870          * If being called from fts_read, set the fts_info field.
871          */
872 #if defined FTS_WHITEOUT && 0
873         if (ISSET(FTS_WHITEOUT))
874                 oflag = DTF_NODUP|DTF_REWIND;
875         else
876                 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
877 #else
878 # define __opendir2(path, flag) opendir(path)
879 #endif
880        if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
881                 if (type == BREAD) {
882                         cur->fts_info = FTS_DNR;
883                         cur->fts_errno = errno;
884                 }
885                 return (NULL);
886         }
887
888         /*
889          * Nlinks is the number of possible entries of type directory in the
890          * directory if we're cheating on stat calls, 0 if we're not doing
891          * any stat calls at all, (nlink_t) -1 if we're statting everything.
892          */
893         if (type == BNAMES) {
894                 nlinks = 0;
895                 /* Be quiet about nostat, GCC. */
896                 nostat = false;
897         } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
898                 nlinks = (cur->fts_statp->st_nlink
899                           - (ISSET(FTS_SEEDOT) ? 0 : 2));
900                 nostat = true;
901         } else {
902                 nlinks = -1;
903                 nostat = false;
904         }
905
906         /*
907          * If we're going to need to stat anything or we want to descend
908          * and stay in the directory, chdir.  If this fails we keep going,
909          * but set a flag so we don't chdir after the post-order visit.
910          * We won't be able to stat anything, but we can still return the
911          * names themselves.  Note, that since fts_read won't be able to
912          * chdir into the directory, it will have to return different path
913          * names than before, i.e. "a/b" instead of "b".  Since the node
914          * has already been visited in pre-order, have to wait until the
915          * post-order visit to return the error.  There is a special case
916          * here, if there was nothing to stat then it's not an error to
917          * not be able to stat.  This is all fairly nasty.  If a program
918          * needed sorted entries or stat information, they had better be
919          * checking FTS_NS on the returned nodes.
920          */
921         cderrno = 0;
922         if (nlinks || type == BREAD) {
923                 if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
924                         if (nlinks && type == BREAD)
925                                 cur->fts_errno = errno;
926                         cur->fts_flags |= FTS_DONTCHDIR;
927                         descend = false;
928                         cderrno = errno;
929                         (void)closedir(dirp);
930                         dirp = NULL;
931                 } else
932                         descend = true;
933         } else
934                 descend = false;
935
936         /*
937          * Figure out the max file name length that can be stored in the
938          * current path -- the inner loop allocates more path as necessary.
939          * We really wouldn't have to do the maxlen calculations here, we
940          * could do them in fts_read before returning the path, but it's a
941          * lot easier here since the length is part of the dirent structure.
942          *
943          * If not changing directories set a pointer so that can just append
944          * each new name into the path.
945          */
946         len = NAPPEND(cur);
947         if (ISSET(FTS_NOCHDIR)) {
948                 cp = sp->fts_path + len;
949                 *cp++ = '/';
950         } else {
951                 /* GCC, you're too verbose. */
952                 cp = NULL;
953         }
954         len++;
955         maxlen = sp->fts_pathlen - len;
956
957         level = cur->fts_level + 1;
958
959         /* Read the directory, attaching each entry to the `link' pointer. */
960         doadjust = false;
961         for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
962                 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
963                         continue;
964
965                 if ((p = fts_alloc(sp, dp->d_name, NAMLEN (dp))) == NULL)
966                         goto mem1;
967                 if (NAMLEN (dp) >= maxlen) {/* include space for NUL */
968                         oldaddr = sp->fts_path;
969                         if (! fts_palloc(sp, NAMLEN (dp) + len + 1)) {
970                                 /*
971                                  * No more memory for path or structures.  Save
972                                  * errno, free up the current structure and the
973                                  * structures already allocated.
974                                  */
975 mem1:                           saved_errno = errno;
976                                 if (p)
977                                         free(p);
978                                 fts_lfree(head);
979                                 (void)closedir(dirp);
980                                 cur->fts_info = FTS_ERR;
981                                 SET(FTS_STOP);
982                                 __set_errno (saved_errno);
983                                 return (NULL);
984                         }
985                         /* Did realloc() change the pointer? */
986                         if (oldaddr != sp->fts_path) {
987                                 doadjust = true;
988                                 if (ISSET(FTS_NOCHDIR))
989                                         cp = sp->fts_path + len;
990                         }
991                         maxlen = sp->fts_pathlen - len;
992                 }
993
994                 new_len = len + NAMLEN (dp);
995                 if (new_len < len) {
996                         /*
997                          * In the unlikely even that we would end up
998                          * with a path longer than SIZE_MAX, free up
999                          * the current structure and the structures already
1000                          * allocated, then error out with ENAMETOOLONG.
1001                          */
1002                         free(p);
1003                         fts_lfree(head);
1004                         (void)closedir(dirp);
1005                         cur->fts_info = FTS_ERR;
1006                         SET(FTS_STOP);
1007                         __set_errno (ENAMETOOLONG);
1008                         return (NULL);
1009                 }
1010                 p->fts_level = level;
1011                 p->fts_parent = sp->fts_cur;
1012                 p->fts_pathlen = new_len;
1013
1014 #if defined FTS_WHITEOUT && 0
1015                 if (dp->d_type == DT_WHT)
1016                         p->fts_flags |= FTS_ISW;
1017 #endif
1018
1019                 if (cderrno) {
1020                         if (nlinks) {
1021                                 p->fts_info = FTS_NS;
1022                                 p->fts_errno = cderrno;
1023                         } else
1024                                 p->fts_info = FTS_NSOK;
1025                         p->fts_accpath = cur->fts_accpath;
1026                 } else if (nlinks == 0
1027 #if HAVE_STRUCT_DIRENT_D_TYPE
1028                            || (nostat &&
1029                                dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
1030 #endif
1031                     ) {
1032                         p->fts_accpath =
1033                             ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
1034                         p->fts_info = FTS_NSOK;
1035                 } else {
1036                         /* Build a file name for fts_stat to stat. */
1037                         if (ISSET(FTS_NOCHDIR)) {
1038                                 p->fts_accpath = p->fts_path;
1039                                 memmove(cp, p->fts_name, p->fts_namelen + 1);
1040                         } else
1041                                 p->fts_accpath = p->fts_name;
1042                         /* Stat it. */
1043                         p->fts_info = fts_stat(sp, p, false);
1044
1045                         /* Decrement link count if applicable. */
1046                         if (nlinks > 0
1047                             && (TYPE_SIGNED (nlink_t) || nostat)
1048                             && (p->fts_info == FTS_D ||
1049                             p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
1050                                 --nlinks;
1051                 }
1052
1053                 /* We walk in directory order so "ls -f" doesn't get upset. */
1054                 p->fts_link = NULL;
1055                 if (head == NULL)
1056                         head = tail = p;
1057                 else {
1058                         tail->fts_link = p;
1059                         tail = p;
1060                 }
1061                 ++nitems;
1062         }
1063         if (dirp)
1064                 (void)closedir(dirp);
1065
1066         /*
1067          * If realloc() changed the address of the path, adjust the
1068          * addresses for the rest of the tree and the dir list.
1069          */
1070         if (doadjust)
1071                 fts_padjust(sp, head);
1072
1073         /*
1074          * If not changing directories, reset the path back to original
1075          * state.
1076          */
1077         if (ISSET(FTS_NOCHDIR)) {
1078                 if (len == sp->fts_pathlen || nitems == 0)
1079                         --cp;
1080                 *cp = '\0';
1081         }
1082
1083         /*
1084          * If descended after called from fts_children or after called from
1085          * fts_read and nothing found, get back.  At the root level we use
1086          * the saved fd; if one of fts_open()'s arguments is a relative path
1087          * to an empty directory, we wind up here with no other way back.  If
1088          * can't get back, we're done.
1089          */
1090         if (descend && (type == BCHILD || !nitems) &&
1091             (cur->fts_level == FTS_ROOTLEVEL ?
1092              FCHDIR(sp, sp->fts_rfd) :
1093              fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
1094                 cur->fts_info = FTS_ERR;
1095                 SET(FTS_STOP);
1096                 return (NULL);
1097         }
1098
1099         /* If didn't find anything, return NULL. */
1100         if (!nitems) {
1101                 if (type == BREAD)
1102                         cur->fts_info = FTS_DP;
1103                 return (NULL);
1104         }
1105
1106         /* Sort the entries. */
1107         if (sp->fts_compar && nitems > 1)
1108                 head = fts_sort(sp, head, nitems);
1109         return (head);
1110 }
1111
1112 #if FTS_DEBUG
1113
1114 /* Walk ->fts_parent links starting at E_CURR, until the root of the
1115    current hierarchy.  There should be a directory with dev/inode
1116    matching those of AD.  If not, print a lot of diagnostics.  */
1117 static void
1118 find_matching_ancestor (FTSENT const *e_curr, struct Active_dir const *ad)
1119 {
1120   FTSENT const *ent;
1121   for (ent = e_curr; ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1122     {
1123       if (ad->ino == ent->fts_statp->st_ino
1124           && ad->dev == ent->fts_statp->st_dev)
1125         return;
1126     }
1127   printf ("ERROR: tree dir, %s, not active\n", ad->fts_ent->fts_accpath);
1128   printf ("active dirs:\n");
1129   for (ent = e_curr;
1130        ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1131     printf ("  %s(%"PRIuMAX"/%"PRIuMAX") to %s(%"PRIuMAX"/%"PRIuMAX")...\n",
1132             ad->fts_ent->fts_accpath,
1133             (uintmax_t) ad->dev,
1134             (uintmax_t) ad->ino,
1135             ent->fts_accpath,
1136             (uintmax_t) ent->fts_statp->st_dev,
1137             (uintmax_t) ent->fts_statp->st_ino);
1138 }
1139
1140 void
1141 fts_cross_check (FTS const *sp)
1142 {
1143   FTSENT const *ent = sp->fts_cur;
1144   FTSENT const *t;
1145   if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK))
1146     return;
1147
1148   Dprintf (("fts-cross-check cur=%s\n", ent->fts_path));
1149   /* Make sure every parent dir is in the tree.  */
1150   for (t = ent->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1151     {
1152       struct Active_dir ad;
1153       ad.ino = t->fts_statp->st_ino;
1154       ad.dev = t->fts_statp->st_dev;
1155       if ( ! hash_lookup (sp->active_dir_ht, &ad))
1156         printf ("ERROR: active dir, %s, not in tree\n", t->fts_path);
1157     }
1158
1159   /* Make sure every dir in the tree is an active dir.
1160      But ENT is not necessarily a directory.  If so, just skip this part. */
1161   if (ent->fts_parent->fts_level >= FTS_ROOTLEVEL
1162       && (ent->fts_info == FTS_DP
1163           || ent->fts_info == FTS_D))
1164     {
1165       struct Active_dir *ad;
1166       for (ad = hash_get_first (sp->active_dir_ht); ad != NULL;
1167            ad = hash_get_next (sp->active_dir_ht, ad))
1168         {
1169           find_matching_ancestor (ent, ad);
1170         }
1171     }
1172 }
1173 #endif
1174
1175 static unsigned short int
1176 internal_function
1177 fts_stat(FTS *sp, register FTSENT *p, bool follow)
1178 {
1179         struct stat *sbp = p->fts_statp;
1180         int saved_errno;
1181
1182 #if defined FTS_WHITEOUT && 0
1183         /* check for whiteout */
1184         if (p->fts_flags & FTS_ISW) {
1185                 memset(sbp, '\0', sizeof (*sbp));
1186                 sbp->st_mode = S_IFWHT;
1187                 return (FTS_W);
1188        }
1189 #endif
1190
1191         /*
1192          * If doing a logical walk, or application requested FTS_FOLLOW, do
1193          * a stat(2).  If that fails, check for a non-existent symlink.  If
1194          * fail, set the errno from the stat call.
1195          */
1196         if (ISSET(FTS_LOGICAL) || follow) {
1197                 if (stat(p->fts_accpath, sbp)) {
1198                         saved_errno = errno;
1199                         if (!lstat(p->fts_accpath, sbp)) {
1200                                 __set_errno (0);
1201                                 return (FTS_SLNONE);
1202                         }
1203                         p->fts_errno = saved_errno;
1204                         goto err;
1205                 }
1206         } else if (lstat(p->fts_accpath, sbp)) {
1207                 p->fts_errno = errno;
1208 err:            memset(sbp, 0, sizeof(struct stat));
1209                 return (FTS_NS);
1210         }
1211
1212         if (S_ISDIR(sbp->st_mode)) {
1213                 if (ISDOT(p->fts_name))
1214                         return (FTS_DOT);
1215                 return (FTS_D);
1216         }
1217         if (S_ISLNK(sbp->st_mode))
1218                 return (FTS_SL);
1219         if (S_ISREG(sbp->st_mode))
1220                 return (FTS_F);
1221         return (FTS_DEFAULT);
1222 }
1223
1224 static int
1225 fts_compar (void const *a, void const *b)
1226 {
1227   /* Convert A and B to the correct types, to pacify the compiler, and
1228      for portability to bizarre hosts where "void const *" and "FTSENT
1229      const **" differ in runtime representation.  The comparison
1230      function cannot modify *a and *b, but there is no compile-time
1231      check for this.  */
1232   FTSENT const **pa = (FTSENT const **) a;
1233   FTSENT const **pb = (FTSENT const **) b;
1234   return pa[0]->fts_fts->fts_compar (pa, pb);
1235 }
1236
1237 static FTSENT *
1238 internal_function
1239 fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
1240 {
1241         register FTSENT **ap, *p;
1242
1243         /* On most modern hosts, void * and FTSENT ** have the same
1244            run-time representation, and one can convert sp->fts_compar to
1245            the type qsort expects without problem.  Use the heuristic that
1246            this is OK if the two pointer types are the same size, and if
1247            converting FTSENT ** to long int is the same as converting
1248            FTSENT ** to void * and then to long int.  This heuristic isn't
1249            valid in general but we don't know of any counterexamples.  */
1250         FTSENT *dummy;
1251         int (*compare) (void const *, void const *) =
1252           ((sizeof &dummy == sizeof (void *)
1253             && (long int) &dummy == (long int) (void *) &dummy)
1254            ? (int (*) (void const *, void const *)) sp->fts_compar
1255            : fts_compar);
1256
1257         /*
1258          * Construct an array of pointers to the structures and call qsort(3).
1259          * Reassemble the array in the order returned by qsort.  If unable to
1260          * sort for memory reasons, return the directory entries in their
1261          * current order.  Allocate enough space for the current needs plus
1262          * 40 so don't realloc one entry at a time.
1263          */
1264         if (nitems > sp->fts_nitems) {
1265                 struct _ftsent **a;
1266
1267                 sp->fts_nitems = nitems + 40;
1268                 if (SIZE_MAX / sizeof *a < sp->fts_nitems
1269                     || ! (a = realloc (sp->fts_array,
1270                                        sp->fts_nitems * sizeof *a))) {
1271                         free(sp->fts_array);
1272                         sp->fts_array = NULL;
1273                         sp->fts_nitems = 0;
1274                         return (head);
1275                 }
1276                 sp->fts_array = a;
1277         }
1278         for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1279                 *ap++ = p;
1280         qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
1281         for (head = *(ap = sp->fts_array); --nitems; ++ap)
1282                 ap[0]->fts_link = ap[1];
1283         ap[0]->fts_link = NULL;
1284         return (head);
1285 }
1286
1287 static FTSENT *
1288 internal_function
1289 fts_alloc (FTS *sp, const char *name, register size_t namelen)
1290 {
1291         register FTSENT *p;
1292         size_t len;
1293
1294         /*
1295          * The file name is a variable length array.  Allocate the FTSENT
1296          * structure and the file name in one chunk.
1297          */
1298         len = sizeof(FTSENT) + namelen;
1299         if ((p = malloc(len)) == NULL)
1300                 return (NULL);
1301
1302         /* Copy the name and guarantee NUL termination. */
1303         memmove(p->fts_name, name, namelen);
1304         p->fts_name[namelen] = '\0';
1305
1306         p->fts_namelen = namelen;
1307         p->fts_fts = sp;
1308         p->fts_path = sp->fts_path;
1309         p->fts_errno = 0;
1310         p->fts_flags = 0;
1311         p->fts_instr = FTS_NOINSTR;
1312         p->fts_number = 0;
1313         p->fts_pointer = NULL;
1314         return (p);
1315 }
1316
1317 static void
1318 internal_function
1319 fts_lfree (register FTSENT *head)
1320 {
1321         register FTSENT *p;
1322
1323         /* Free a linked list of structures. */
1324         while ((p = head)) {
1325                 head = head->fts_link;
1326                 free(p);
1327         }
1328 }
1329
1330 /*
1331  * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1332  * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1333  * though the kernel won't resolve them.  Add the size (not just what's needed)
1334  * plus 256 bytes so don't realloc the path 2 bytes at a time.
1335  */
1336 static bool
1337 internal_function
1338 fts_palloc (FTS *sp, size_t more)
1339 {
1340         char *p;
1341         size_t new_len = sp->fts_pathlen + more + 256;
1342
1343         /*
1344          * See if fts_pathlen would overflow.
1345          */
1346         if (new_len < sp->fts_pathlen) {
1347                 if (sp->fts_path) {
1348                         free(sp->fts_path);
1349                         sp->fts_path = NULL;
1350                 }
1351                 sp->fts_path = NULL;
1352                 __set_errno (ENAMETOOLONG);
1353                 return false;
1354         }
1355         sp->fts_pathlen = new_len;
1356         p = realloc(sp->fts_path, sp->fts_pathlen);
1357         if (p == NULL) {
1358                 free(sp->fts_path);
1359                 sp->fts_path = NULL;
1360                 return false;
1361         }
1362         sp->fts_path = p;
1363         return true;
1364 }
1365
1366 /*
1367  * When the path is realloc'd, have to fix all of the pointers in structures
1368  * already returned.
1369  */
1370 static void
1371 internal_function
1372 fts_padjust (FTS *sp, FTSENT *head)
1373 {
1374         FTSENT *p;
1375         char *addr = sp->fts_path;
1376
1377 #define ADJUST(p) do {                                                  \
1378         if ((p)->fts_accpath != (p)->fts_name) {                        \
1379                 (p)->fts_accpath =                                      \
1380                     (char *)addr + ((p)->fts_accpath - (p)->fts_path);  \
1381         }                                                               \
1382         (p)->fts_path = addr;                                           \
1383 } while (0)
1384         /* Adjust the current set of children. */
1385         for (p = sp->fts_child; p; p = p->fts_link)
1386                 ADJUST(p);
1387
1388         /* Adjust the rest of the tree, including the current level. */
1389         for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
1390                 ADJUST(p);
1391                 p = p->fts_link ? p->fts_link : p->fts_parent;
1392         }
1393 }
1394
1395 static size_t
1396 internal_function
1397 fts_maxarglen (char * const *argv)
1398 {
1399         size_t len, max;
1400
1401         for (max = 0; *argv; ++argv)
1402                 if ((len = strlen(*argv)) > max)
1403                         max = len;
1404         return (max + 1);
1405 }
1406
1407 /*
1408  * Change to dir specified by fd or path without getting
1409  * tricked by someone changing the world out from underneath us.
1410  * Assumes p->fts_statp->st_dev and p->fts_statp->st_ino are filled in.
1411  */
1412 static int
1413 internal_function
1414 fts_safe_changedir (FTS *sp, FTSENT *p, int fd, char const *path)
1415 {
1416         int ret, oerrno, newfd;
1417         struct stat sb;
1418
1419         newfd = fd;
1420         if (ISSET(FTS_NOCHDIR))
1421                 return (0);
1422         if (fd < 0 && (newfd = fd_safer (diropen (path))) < 0)
1423                 return (-1);
1424         if (fstat(newfd, &sb)) {
1425                 ret = -1;
1426                 goto bail;
1427         }
1428         if (p->fts_statp->st_dev != sb.st_dev
1429             || p->fts_statp->st_ino != sb.st_ino) {
1430                 __set_errno (ENOENT);           /* disinformation */
1431                 ret = -1;
1432                 goto bail;
1433         }
1434         ret = fchdir(newfd);
1435 bail:
1436         oerrno = errno;
1437         if (fd < 0)
1438                 (void)close(newfd);
1439         __set_errno (oerrno);
1440         return (ret);
1441 }