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