*** empty log message ***
[coreutils.git] / lib / fts.c
blob00be3d2cc9e383e0c28e88abe9cd0248d0d0bb40
1 /* Traverse a file hierarchy.
3 Copyright (C) 2004 Free Software Foundation, Inc.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 /*-
20 * Copyright (c) 1990, 1993, 1994
21 * The Regents of the University of California. All rights reserved.
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.
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.
48 #ifdef HAVE_CONFIG_H
49 # include <config.h>
50 #endif
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 */
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 # undef __P
64 # define __P(x) x
65 #endif
66 #include <fcntl.h>
67 #include <errno.h>
68 #include "dirfd.h"
69 #include "fts_.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
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
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
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
140 #ifndef __set_errno
141 # define __set_errno(Val) errno = (Val)
142 #endif
145 static FTSENT *fts_alloc __P((FTS *, const char *, size_t)) internal_function;
146 static FTSENT *fts_build __P((FTS *, int)) internal_function;
147 static void fts_lfree __P((FTSENT *)) internal_function;
148 static void fts_load __P((FTS *, FTSENT *)) internal_function;
149 static size_t fts_maxarglen __P((char * const *)) internal_function;
150 static void fts_padjust __P((FTS *, FTSENT *)) internal_function;
151 static bool fts_palloc __P((FTS *, size_t)) internal_function;
152 static FTSENT *fts_sort __P((FTS *, FTSENT *, size_t)) internal_function;
153 static unsigned short int fts_stat __P((FTS *, FTSENT *, bool))
154 internal_function;
155 static int fts_safe_changedir __P((FTS *, FTSENT *, int, const char *))
156 internal_function;
158 #ifndef MAX
159 # define MAX(a,b) ((a) > (b) ? (a) : (b))
160 #endif
162 #ifndef SIZE_MAX
163 # define SIZE_MAX ((size_t) -1)
164 #endif
166 #ifndef O_DIRECTORY
167 # define O_DIRECTORY 0
168 #endif
170 /* The extra casts work around common compiler bugs. */
171 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
173 #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
175 #define CLR(opt) (sp->fts_options &= ~(opt))
176 #define ISSET(opt) (sp->fts_options & (opt))
177 #define SET(opt) (sp->fts_options |= (opt))
179 #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
181 /* fts_build flags */
182 #define BCHILD 1 /* fts_children */
183 #define BNAMES 2 /* fts_children, names only */
184 #define BREAD 3 /* fts_read */
186 #define HT_INITIAL_SIZE 31
188 #if FTS_DEBUG
189 bool fts_debug = false;
190 # include <stdio.h>
191 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
192 #else
193 # define Dprintf(x)
194 #endif
196 #define ENTER_DIR(Fts, Ent, Tag) \
197 do { \
198 Dprintf ((" %s-entering: %s\n", Tag, (Ent)->fts_path)); \
199 enter_dir (sp, p); \
200 } while (0)
202 #define LEAVE_DIR(Fts, Ent, Tag) \
203 do { \
204 Dprintf ((" %s-leaving: %s\n", Tag, (Ent)->fts_path)); \
205 leave_dir (sp, p); \
206 } while (0)
208 /* Use these each of these to map a device/inode pair to an FTSENT. */
209 struct Active_dir
211 dev_t dev;
212 ino_t ino;
213 FTSENT *fts_ent;
216 static bool
217 AD_compare (void const *x, void const *y)
219 struct Active_dir const *ax = x;
220 struct Active_dir const *ay = y;
221 return ax->ino == ay->ino
222 && ax->dev == ay->dev;
225 static size_t
226 AD_hash (void const *x, size_t table_size)
228 struct Active_dir const *ax = x;
229 return (uintmax_t) ax->ino % table_size;
232 static void
233 enter_dir (FTS *fts, FTSENT *ent)
235 if (fts->active_dir_ht)
237 struct stat const *st = ent->fts_statp;
238 struct Active_dir *ad = malloc (sizeof (struct Active_dir));
239 struct Active_dir *ad_from_table;
241 if (ad == NULL)
242 goto give_up;
244 ad->dev = st->st_dev;
245 ad->ino = st->st_ino;
246 ad->fts_ent = ent;
248 /* See if we've already encountered this directory.
249 This can happen when following symlinks as well as
250 with a corrupted directory hierarchy. */
251 ad_from_table = hash_insert (fts->active_dir_ht, ad);
253 if (ad_from_table == NULL)
255 give_up:
256 /* Insertion failed due to lack of memory. Free the hash
257 table and turn off this sort of cycle detection. */
258 hash_free (fts->active_dir_ht);
259 fts->active_dir_ht = NULL;
260 return;
263 if (ad_from_table != ad)
265 /* There was an entry with matching dev/inode already in the table.
266 Record the fact that we've found a cycle. */
267 ent->fts_cycle = ad_from_table->fts_ent;
268 ent->fts_info = FTS_DC;
270 /* ad was not inserted, so free it. */
271 free (ad);
274 else if (fts->cycle_state)
276 if (cycle_check (fts->cycle_state, ent->fts_statp))
278 /* FIXME: setting fts_cycle like this isn't proper.
279 To do what the documentation requires, we'd have to
280 go around the cycle again and find the right entry.
281 But no callers in coreutils use the fts_cycle member. */
282 ent->fts_cycle = ent;
283 ent->fts_info = FTS_DC;
288 static void
289 leave_dir (FTS *fts, FTSENT *ent)
291 if (fts->active_dir_ht)
293 struct stat const *st = ent->fts_statp;
294 struct Active_dir obj;
295 void *found;
296 obj.dev = st->st_dev;
297 obj.ino = st->st_ino;
298 found = hash_delete (fts->active_dir_ht, &obj);
299 if (!found)
300 abort ();
301 free (found);
305 /* Open the directory DIR if possible, and return a file
306 descriptor. Return -1 and set errno on failure. It doesn't matter
307 whether the file descriptor has read or write access. */
309 static int
310 internal_function
311 diropen (char const *dir)
313 int fd = open (dir, O_RDONLY | O_DIRECTORY);
314 if (fd < 0)
315 fd = open (dir, O_WRONLY | O_DIRECTORY);
316 return fd;
319 FTS *
320 fts_open(argv, options, compar)
321 char * const *argv;
322 register int options;
323 int (*compar) __P((const FTSENT **, const FTSENT **));
325 register FTS *sp;
326 register FTSENT *p, *root;
327 register size_t nitems;
328 FTSENT *parent, *tmp = NULL; /* pacify gcc */
329 size_t len;
331 /* Options check. */
332 if (options & ~FTS_OPTIONMASK) {
333 __set_errno (EINVAL);
334 return (NULL);
337 /* Allocate/initialize the stream */
338 if ((sp = malloc(sizeof(FTS))) == NULL)
339 return (NULL);
340 memset(sp, 0, sizeof(FTS));
341 sp->fts_compar = (int (*) __P((const void *, const void *))) compar;
342 sp->fts_options = options;
344 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
345 if (ISSET(FTS_LOGICAL))
346 SET(FTS_NOCHDIR);
349 * Start out with 1K of path space, and enough, in any case,
350 * to hold the user's paths.
352 #ifndef MAXPATHLEN
353 # define MAXPATHLEN 1024
354 #endif
355 if (! fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
356 goto mem1;
358 /* Allocate/initialize root's parent. */
359 if ((parent = fts_alloc(sp, "", 0)) == NULL)
360 goto mem2;
361 parent->fts_level = FTS_ROOTPARENTLEVEL;
363 /* Allocate/initialize root(s). */
364 for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
365 /* Don't allow zero-length paths. */
366 if ((len = strlen(*argv)) == 0) {
367 __set_errno (ENOENT);
368 goto mem3;
371 if ((p = fts_alloc(sp, *argv, len)) == NULL)
372 goto mem3;
373 p->fts_level = FTS_ROOTLEVEL;
374 p->fts_parent = parent;
375 p->fts_accpath = p->fts_name;
376 p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW) != 0);
378 /* Command-line "." and ".." are real directories. */
379 if (p->fts_info == FTS_DOT)
380 p->fts_info = FTS_D;
383 * If comparison routine supplied, traverse in sorted
384 * order; otherwise traverse in the order specified.
386 if (compar) {
387 p->fts_link = root;
388 root = p;
389 } else {
390 p->fts_link = NULL;
391 if (root == NULL)
392 tmp = root = p;
393 else {
394 tmp->fts_link = p;
395 tmp = p;
399 if (compar && nitems > 1)
400 root = fts_sort(sp, root, nitems);
403 * Allocate a dummy pointer and make fts_read think that we've just
404 * finished the node before the root(s); set p->fts_info to FTS_INIT
405 * so that everything about the "current" node is ignored.
407 if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
408 goto mem3;
409 sp->fts_cur->fts_link = root;
410 sp->fts_cur->fts_info = FTS_INIT;
412 if (ISSET (FTS_TIGHT_CYCLE_CHECK))
414 sp->active_dir_ht = hash_initialize (HT_INITIAL_SIZE,
415 NULL, AD_hash,
416 AD_compare, free);
417 if (sp->active_dir_ht == NULL)
418 goto mem3;
419 sp->cycle_state = malloc (sizeof *sp->cycle_state);
421 else
423 sp->cycle_state = malloc (sizeof *sp->cycle_state);
424 if (sp->cycle_state == NULL)
425 goto mem3;
426 cycle_check_init (sp->cycle_state);
427 sp->active_dir_ht = NULL;
431 * If using chdir(2), grab a file descriptor pointing to dot to ensure
432 * that we can get back here; this could be avoided for some paths,
433 * but almost certainly not worth the effort. Slashes, symbolic links,
434 * and ".." are all fairly nasty problems. Note, if we can't get the
435 * descriptor we run anyway, just more slowly.
437 if (!ISSET(FTS_NOCHDIR)
438 && (sp->fts_rfd = diropen (".")) < 0)
439 SET(FTS_NOCHDIR);
441 return (sp);
443 mem3: fts_lfree(root);
444 free(parent);
445 mem2: free(sp->fts_path);
446 mem1: free(sp);
447 return (NULL);
450 static void
451 internal_function
452 fts_load(sp, p)
453 FTS *sp;
454 register FTSENT *p;
456 register size_t len;
457 register char *cp;
460 * Load the stream structure for the next traversal. Since we don't
461 * actually enter the directory until after the preorder visit, set
462 * the fts_accpath field specially so the chdir gets done to the right
463 * place and the user can access the first node. From fts_open it's
464 * known that the path will fit.
466 len = p->fts_pathlen = p->fts_namelen;
467 memmove(sp->fts_path, p->fts_name, len + 1);
468 if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
469 len = strlen(++cp);
470 memmove(p->fts_name, cp, len + 1);
471 p->fts_namelen = len;
473 p->fts_accpath = p->fts_path = sp->fts_path;
474 sp->fts_dev = p->fts_dev;
478 fts_close(sp)
479 FTS *sp;
481 register FTSENT *freep, *p;
482 int saved_errno = 0;
485 * This still works if we haven't read anything -- the dummy structure
486 * points to the root list, so we step through to the end of the root
487 * list which has a valid parent pointer.
489 if (sp->fts_cur) {
490 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
491 freep = p;
492 p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
493 free(freep);
495 free(p);
498 /* Free up child linked list, sort array, path buffer. */
499 if (sp->fts_child)
500 fts_lfree(sp->fts_child);
501 if (sp->fts_array)
502 free(sp->fts_array);
503 free(sp->fts_path);
505 /* Return to original directory, save errno if necessary. */
506 if (!ISSET(FTS_NOCHDIR)) {
507 if (fchdir(sp->fts_rfd))
508 saved_errno = errno;
509 (void)close(sp->fts_rfd);
512 /* Free any memory used for cycle detection. */
513 if (sp->active_dir_ht)
514 hash_free (sp->active_dir_ht);
515 if (sp->cycle_state)
516 free (sp->cycle_state);
518 /* Free up the stream pointer. */
519 free(sp);
521 /* Set errno and return. */
522 if (saved_errno) {
523 __set_errno (saved_errno);
524 return (-1);
527 return (0);
531 * Special case of "/" at the end of the path so that slashes aren't
532 * appended which would cause paths to be written as "....//foo".
534 #define NAPPEND(p) \
535 (p->fts_path[p->fts_pathlen - 1] == '/' \
536 ? p->fts_pathlen - 1 : p->fts_pathlen)
538 FTSENT *
539 fts_read(sp)
540 register FTS *sp;
542 register FTSENT *p, *tmp;
543 register unsigned short int instr;
544 register char *t;
545 int saved_errno;
547 /* If finished or unrecoverable error, return NULL. */
548 if (sp->fts_cur == NULL || ISSET(FTS_STOP))
549 return (NULL);
551 /* Set current node pointer. */
552 p = sp->fts_cur;
554 /* Save and zero out user instructions. */
555 instr = p->fts_instr;
556 p->fts_instr = FTS_NOINSTR;
558 /* Any type of file may be re-visited; re-stat and re-turn. */
559 if (instr == FTS_AGAIN) {
560 p->fts_info = fts_stat(sp, p, false);
561 return (p);
563 Dprintf (("fts_read: p=%s\n",
564 p->fts_info == FTS_INIT ? "" : p->fts_path));
567 * Following a symlink -- SLNONE test allows application to see
568 * SLNONE and recover. If indirecting through a symlink, have
569 * keep a pointer to current location. If unable to get that
570 * pointer, follow fails.
572 if (instr == FTS_FOLLOW &&
573 (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
574 p->fts_info = fts_stat(sp, p, true);
575 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
576 if ((p->fts_symfd = diropen (".")) < 0) {
577 p->fts_errno = errno;
578 p->fts_info = FTS_ERR;
579 } else
580 p->fts_flags |= FTS_SYMFOLLOW;
582 if (p->fts_info == FTS_D)
583 ENTER_DIR (sp, p, "7");
584 return (p);
587 /* Directory in pre-order. */
588 if (p->fts_info == FTS_D) {
589 /* If skipped or crossed mount point, do post-order visit. */
590 if (instr == FTS_SKIP ||
591 (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
592 if (p->fts_flags & FTS_SYMFOLLOW)
593 (void)close(p->fts_symfd);
594 if (sp->fts_child) {
595 fts_lfree(sp->fts_child);
596 sp->fts_child = NULL;
598 p->fts_info = FTS_DP;
599 LEAVE_DIR (sp, p, "1");
600 return (p);
603 /* Rebuild if only read the names and now traversing. */
604 if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
605 CLR(FTS_NAMEONLY);
606 fts_lfree(sp->fts_child);
607 sp->fts_child = NULL;
611 * Cd to the subdirectory.
613 * If have already read and now fail to chdir, whack the list
614 * to make the names come out right, and set the parent errno
615 * so the application will eventually get an error condition.
616 * Set the FTS_DONTCHDIR flag so that when we logically change
617 * directories back to the parent we don't do a chdir.
619 * If haven't read do so. If the read fails, fts_build sets
620 * FTS_STOP or the fts_info field of the node.
622 if (sp->fts_child != NULL) {
623 if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
624 p->fts_errno = errno;
625 p->fts_flags |= FTS_DONTCHDIR;
626 for (p = sp->fts_child; p != NULL;
627 p = p->fts_link)
628 p->fts_accpath =
629 p->fts_parent->fts_accpath;
631 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
632 if (ISSET(FTS_STOP))
633 return (NULL);
634 /* If fts_build's call to fts_safe_changedir failed
635 because it was not able to fchdir into a
636 subdirectory, tell the caller. */
637 if (p->fts_errno)
638 p->fts_info = FTS_ERR;
639 /* FIXME: see if this should be in an else block */
640 LEAVE_DIR (sp, p, "2");
641 return (p);
643 p = sp->fts_child;
644 sp->fts_child = NULL;
645 goto name;
648 /* Move to the next node on this level. */
649 next: tmp = p;
650 if ((p = p->fts_link) != NULL) {
651 free(tmp);
654 * If reached the top, return to the original directory (or
655 * the root of the tree), and load the paths for the next root.
657 if (p->fts_level == FTS_ROOTLEVEL) {
658 if (FCHDIR(sp, sp->fts_rfd)) {
659 SET(FTS_STOP);
660 return (NULL);
662 fts_load(sp, p);
663 if (p->fts_info == FTS_D)
664 ENTER_DIR (sp, p, "8");
665 return (sp->fts_cur = p);
669 * User may have called fts_set on the node. If skipped,
670 * ignore. If followed, get a file descriptor so we can
671 * get back if necessary.
673 if (p->fts_instr == FTS_SKIP)
674 goto next;
675 if (p->fts_instr == FTS_FOLLOW) {
676 p->fts_info = fts_stat(sp, p, true);
677 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
678 if ((p->fts_symfd = diropen (".")) < 0) {
679 p->fts_errno = errno;
680 p->fts_info = FTS_ERR;
681 } else
682 p->fts_flags |= FTS_SYMFOLLOW;
684 p->fts_instr = FTS_NOINSTR;
687 name: t = sp->fts_path + NAPPEND(p->fts_parent);
688 *t++ = '/';
689 memmove(t, p->fts_name, p->fts_namelen + 1);
690 if (p->fts_info == FTS_D)
691 ENTER_DIR (sp, p, "9");
692 return (sp->fts_cur = p);
695 /* Move up to the parent node. */
696 p = tmp->fts_parent;
697 free(tmp);
699 if (p->fts_level == FTS_ROOTPARENTLEVEL) {
701 * Done; free everything up and set errno to 0 so the user
702 * can distinguish between error and EOF.
704 free(p);
705 __set_errno (0);
706 return (sp->fts_cur = NULL);
709 /* NUL terminate the pathname. */
710 sp->fts_path[p->fts_pathlen] = '\0';
713 * Return to the parent directory. If at a root node or came through
714 * a symlink, go back through the file descriptor. Otherwise, cd up
715 * one directory.
717 if (p->fts_level == FTS_ROOTLEVEL) {
718 if (FCHDIR(sp, sp->fts_rfd)) {
719 p->fts_errno = errno;
720 SET(FTS_STOP);
722 } else if (p->fts_flags & FTS_SYMFOLLOW) {
723 if (FCHDIR(sp, p->fts_symfd)) {
724 saved_errno = errno;
725 (void)close(p->fts_symfd);
726 __set_errno (saved_errno);
727 p->fts_errno = errno;
728 SET(FTS_STOP);
730 (void)close(p->fts_symfd);
731 } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
732 fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
733 p->fts_errno = errno;
734 SET(FTS_STOP);
736 p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
737 if (p->fts_errno == 0)
738 LEAVE_DIR (sp, p, "3");
739 sp->fts_cur = p;
740 return ISSET(FTS_STOP) ? NULL : p;
744 * Fts_set takes the stream as an argument although it's not used in this
745 * implementation; it would be necessary if anyone wanted to add global
746 * semantics to fts using fts_set. An error return is allowed for similar
747 * reasons.
749 /* ARGSUSED */
751 fts_set(sp, p, instr)
752 FTS *sp;
753 FTSENT *p;
754 int instr;
756 if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
757 instr != FTS_NOINSTR && instr != FTS_SKIP) {
758 __set_errno (EINVAL);
759 return (1);
761 p->fts_instr = instr;
762 return (0);
765 FTSENT *
766 fts_children(sp, instr)
767 register FTS *sp;
768 int instr;
770 register FTSENT *p;
771 int fd;
773 if (instr != 0 && instr != FTS_NAMEONLY) {
774 __set_errno (EINVAL);
775 return (NULL);
778 /* Set current node pointer. */
779 p = sp->fts_cur;
782 * Errno set to 0 so user can distinguish empty directory from
783 * an error.
785 __set_errno (0);
787 /* Fatal errors stop here. */
788 if (ISSET(FTS_STOP))
789 return (NULL);
791 /* Return logical hierarchy of user's arguments. */
792 if (p->fts_info == FTS_INIT)
793 return (p->fts_link);
796 * If not a directory being visited in pre-order, stop here. Could
797 * allow FTS_DNR, assuming the user has fixed the problem, but the
798 * same effect is available with FTS_AGAIN.
800 if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
801 return (NULL);
803 /* Free up any previous child list. */
804 if (sp->fts_child != NULL)
805 fts_lfree(sp->fts_child);
807 if (instr == FTS_NAMEONLY) {
808 SET(FTS_NAMEONLY);
809 instr = BNAMES;
810 } else
811 instr = BCHILD;
814 * If using chdir on a relative path and called BEFORE fts_read does
815 * its chdir to the root of a traversal, we can lose -- we need to
816 * chdir into the subdirectory, and we don't know where the current
817 * directory is, so we can't get back so that the upcoming chdir by
818 * fts_read will work.
820 if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
821 ISSET(FTS_NOCHDIR))
822 return (sp->fts_child = fts_build(sp, instr));
824 if ((fd = diropen (".")) < 0)
825 return (sp->fts_child = NULL);
826 sp->fts_child = fts_build(sp, instr);
827 if (fchdir(fd)) {
828 (void)close(fd);
829 return (NULL);
831 (void)close(fd);
832 return (sp->fts_child);
836 * This is the tricky part -- do not casually change *anything* in here. The
837 * idea is to build the linked list of entries that are used by fts_children
838 * and fts_read. There are lots of special cases.
840 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
841 * set and it's a physical walk (so that symbolic links can't be directories),
842 * we can do things quickly. First, if it's a 4.4BSD file system, the type
843 * of the file is in the directory entry. Otherwise, we assume that the number
844 * of subdirectories in a node is equal to the number of links to the parent.
845 * The former skips all stat calls. The latter skips stat calls in any leaf
846 * directories and for any files after the subdirectories in the directory have
847 * been found, cutting the stat calls by about 2/3.
849 static FTSENT *
850 internal_function
851 fts_build(sp, type)
852 register FTS *sp;
853 int type;
855 register struct dirent *dp;
856 register FTSENT *p, *head;
857 register size_t nitems;
858 FTSENT *cur, *tail;
859 DIR *dirp;
860 void *oldaddr;
861 int cderrno;
862 int saved_errno;
863 bool descend;
864 bool doadjust;
865 ptrdiff_t level;
866 nlink_t nlinks;
867 bool nostat;
868 size_t len, maxlen, new_len;
869 char *cp;
871 /* Set current node pointer. */
872 cur = sp->fts_cur;
875 * Open the directory for reading. If this fails, we're done.
876 * If being called from fts_read, set the fts_info field.
878 #if defined FTS_WHITEOUT && 0
879 if (ISSET(FTS_WHITEOUT))
880 oflag = DTF_NODUP|DTF_REWIND;
881 else
882 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
883 #else
884 # define __opendir2(path, flag) opendir(path)
885 #endif
886 if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
887 if (type == BREAD) {
888 cur->fts_info = FTS_DNR;
889 cur->fts_errno = errno;
891 return (NULL);
895 * Nlinks is the number of possible entries of type directory in the
896 * directory if we're cheating on stat calls, 0 if we're not doing
897 * any stat calls at all, (nlink_t) -1 if we're statting everything.
899 if (type == BNAMES) {
900 nlinks = 0;
901 /* Be quiet about nostat, GCC. */
902 nostat = false;
903 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
904 nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
905 nostat = true;
906 } else {
907 nlinks = -1;
908 nostat = false;
912 * If we're going to need to stat anything or we want to descend
913 * and stay in the directory, chdir. If this fails we keep going,
914 * but set a flag so we don't chdir after the post-order visit.
915 * We won't be able to stat anything, but we can still return the
916 * names themselves. Note, that since fts_read won't be able to
917 * chdir into the directory, it will have to return different path
918 * names than before, i.e. "a/b" instead of "b". Since the node
919 * has already been visited in pre-order, have to wait until the
920 * post-order visit to return the error. There is a special case
921 * here, if there was nothing to stat then it's not an error to
922 * not be able to stat. This is all fairly nasty. If a program
923 * needed sorted entries or stat information, they had better be
924 * checking FTS_NS on the returned nodes.
926 cderrno = 0;
927 if (nlinks || type == BREAD) {
928 if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
929 if (nlinks && type == BREAD)
930 cur->fts_errno = errno;
931 cur->fts_flags |= FTS_DONTCHDIR;
932 descend = false;
933 cderrno = errno;
934 (void)closedir(dirp);
935 dirp = NULL;
936 } else
937 descend = true;
938 } else
939 descend = false;
942 * Figure out the max file name length that can be stored in the
943 * current path -- the inner loop allocates more path as necessary.
944 * We really wouldn't have to do the maxlen calculations here, we
945 * could do them in fts_read before returning the path, but it's a
946 * lot easier here since the length is part of the dirent structure.
948 * If not changing directories set a pointer so that can just append
949 * each new name into the path.
951 len = NAPPEND(cur);
952 if (ISSET(FTS_NOCHDIR)) {
953 cp = sp->fts_path + len;
954 *cp++ = '/';
955 } else {
956 /* GCC, you're too verbose. */
957 cp = NULL;
959 len++;
960 maxlen = sp->fts_pathlen - len;
962 level = cur->fts_level + 1;
964 /* Read the directory, attaching each entry to the `link' pointer. */
965 doadjust = false;
966 for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
967 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
968 continue;
970 if ((p = fts_alloc(sp, dp->d_name, NAMLEN (dp))) == NULL)
971 goto mem1;
972 if (NAMLEN (dp) >= maxlen) {/* include space for NUL */
973 oldaddr = sp->fts_path;
974 if (! fts_palloc(sp, NAMLEN (dp) + len + 1)) {
976 * No more memory for path or structures. Save
977 * errno, free up the current structure and the
978 * structures already allocated.
980 mem1: saved_errno = errno;
981 if (p)
982 free(p);
983 fts_lfree(head);
984 (void)closedir(dirp);
985 cur->fts_info = FTS_ERR;
986 SET(FTS_STOP);
987 __set_errno (saved_errno);
988 return (NULL);
990 /* Did realloc() change the pointer? */
991 if (oldaddr != sp->fts_path) {
992 doadjust = true;
993 if (ISSET(FTS_NOCHDIR))
994 cp = sp->fts_path + len;
996 maxlen = sp->fts_pathlen - len;
999 new_len = len + NAMLEN (dp);
1000 if (new_len < len) {
1002 * In the unlikely even that we would end up
1003 * with a path longer than SIZE_MAX, free up
1004 * the current structure and the structures already
1005 * allocated, then error out with ENAMETOOLONG.
1007 free(p);
1008 fts_lfree(head);
1009 (void)closedir(dirp);
1010 cur->fts_info = FTS_ERR;
1011 SET(FTS_STOP);
1012 __set_errno (ENAMETOOLONG);
1013 return (NULL);
1015 p->fts_level = level;
1016 p->fts_parent = sp->fts_cur;
1017 p->fts_pathlen = new_len;
1019 #if defined FTS_WHITEOUT && 0
1020 if (dp->d_type == DT_WHT)
1021 p->fts_flags |= FTS_ISW;
1022 #endif
1024 if (cderrno) {
1025 if (nlinks) {
1026 p->fts_info = FTS_NS;
1027 p->fts_errno = cderrno;
1028 } else
1029 p->fts_info = FTS_NSOK;
1030 p->fts_accpath = cur->fts_accpath;
1031 } else if (nlinks == 0
1032 # if HAVE_STRUCT_DIRENT_D_TYPE
1033 || (nostat &&
1034 dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
1035 #endif
1037 p->fts_accpath =
1038 ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
1039 p->fts_info = FTS_NSOK;
1040 } else {
1041 /* Build a file name for fts_stat to stat. */
1042 if (ISSET(FTS_NOCHDIR)) {
1043 p->fts_accpath = p->fts_path;
1044 memmove(cp, p->fts_name, p->fts_namelen + 1);
1045 } else
1046 p->fts_accpath = p->fts_name;
1047 /* Stat it. */
1048 p->fts_info = fts_stat(sp, p, false);
1050 /* Decrement link count if applicable. */
1051 if (nlinks > 0
1052 && (TYPE_SIGNED (nlink_t) || nostat)
1053 && (p->fts_info == FTS_D ||
1054 p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
1055 --nlinks;
1058 /* We walk in directory order so "ls -f" doesn't get upset. */
1059 p->fts_link = NULL;
1060 if (head == NULL)
1061 head = tail = p;
1062 else {
1063 tail->fts_link = p;
1064 tail = p;
1066 ++nitems;
1068 if (dirp)
1069 (void)closedir(dirp);
1072 * If realloc() changed the address of the path, adjust the
1073 * addresses for the rest of the tree and the dir list.
1075 if (doadjust)
1076 fts_padjust(sp, head);
1079 * If not changing directories, reset the path back to original
1080 * state.
1082 if (ISSET(FTS_NOCHDIR)) {
1083 if (len == sp->fts_pathlen || nitems == 0)
1084 --cp;
1085 *cp = '\0';
1089 * If descended after called from fts_children or after called from
1090 * fts_read and nothing found, get back. At the root level we use
1091 * the saved fd; if one of fts_open()'s arguments is a relative path
1092 * to an empty directory, we wind up here with no other way back. If
1093 * can't get back, we're done.
1095 if (descend && (type == BCHILD || !nitems) &&
1096 (cur->fts_level == FTS_ROOTLEVEL ?
1097 FCHDIR(sp, sp->fts_rfd) :
1098 fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
1099 cur->fts_info = FTS_ERR;
1100 SET(FTS_STOP);
1101 return (NULL);
1104 /* If didn't find anything, return NULL. */
1105 if (!nitems) {
1106 if (type == BREAD)
1107 cur->fts_info = FTS_DP;
1108 return (NULL);
1111 /* Sort the entries. */
1112 if (sp->fts_compar && nitems > 1)
1113 head = fts_sort(sp, head, nitems);
1114 return (head);
1117 #if FTS_DEBUG
1119 /* Walk ->fts_parent links starting at E_CURR, until the root of the
1120 current hierarchy. There should be a directory with dev/inode
1121 matching those of AD. If not, print a lot of diagnostics. */
1122 static void
1123 find_matching_ancestor (FTSENT const *e_curr, struct Active_dir const *ad)
1125 FTSENT const *ent;
1126 for (ent = e_curr; ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1128 if (ad->ino == ent->fts_statp->st_ino
1129 && ad->dev == ent->fts_statp->st_dev)
1130 return;
1132 printf ("ERROR: tree dir, %s, not active\n", ad->fts_ent->fts_accpath);
1133 printf ("active dirs:\n");
1134 for (ent = e_curr;
1135 ent->fts_level >= FTS_ROOTLEVEL; ent = ent->fts_parent)
1136 printf (" %s(%"PRIuMAX"/%"PRIuMAX") to %s(%"PRIuMAX"/%"PRIuMAX")...\n",
1137 ad->fts_ent->fts_accpath,
1138 (uintmax_t) ad->dev,
1139 (uintmax_t) ad->ino,
1140 ent->fts_accpath,
1141 (uintmax_t) ent->fts_statp->st_dev,
1142 (uintmax_t) ent->fts_statp->st_ino);
1145 void
1146 fts_cross_check (FTS const *sp)
1148 FTSENT const *ent = sp->fts_cur;
1149 FTSENT const *t;
1150 if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK))
1151 return;
1153 Dprintf (("fts-cross-check cur=%s\n", ent->fts_path));
1154 /* Make sure every parent dir is in the tree. */
1155 for (t = ent->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1157 struct Active_dir ad;
1158 ad.ino = t->fts_statp->st_ino;
1159 ad.dev = t->fts_statp->st_dev;
1160 if ( ! hash_lookup (sp->active_dir_ht, &ad))
1161 printf ("ERROR: active dir, %s, not in tree\n", t->fts_path);
1164 /* Make sure every dir in the tree is an active dir.
1165 But ENT is not necessarily a directory. If so, just skip this part. */
1166 if (ent->fts_parent->fts_level >= FTS_ROOTLEVEL
1167 && (ent->fts_info == FTS_DP
1168 || ent->fts_info == FTS_D))
1170 struct Active_dir *ad;
1171 for (ad = hash_get_first (sp->active_dir_ht); ad != NULL;
1172 ad = hash_get_next (sp->active_dir_ht, ad))
1174 find_matching_ancestor (ent, ad);
1178 #endif
1180 static unsigned short int
1181 internal_function
1182 fts_stat(FTS *sp, register FTSENT *p, bool follow)
1184 struct stat *sbp = p->fts_statp;
1185 int saved_errno;
1187 #if defined FTS_WHITEOUT && 0
1188 /* check for whiteout */
1189 if (p->fts_flags & FTS_ISW) {
1190 memset(sbp, '\0', sizeof (*sbp));
1191 sbp->st_mode = S_IFWHT;
1192 return (FTS_W);
1194 #endif
1197 * If doing a logical walk, or application requested FTS_FOLLOW, do
1198 * a stat(2). If that fails, check for a non-existent symlink. If
1199 * fail, set the errno from the stat call.
1201 if (ISSET(FTS_LOGICAL) || follow) {
1202 if (stat(p->fts_accpath, sbp)) {
1203 saved_errno = errno;
1204 if (!lstat(p->fts_accpath, sbp)) {
1205 __set_errno (0);
1206 return (FTS_SLNONE);
1208 p->fts_errno = saved_errno;
1209 goto err;
1211 } else if (lstat(p->fts_accpath, sbp)) {
1212 p->fts_errno = errno;
1213 err: memset(sbp, 0, sizeof(struct stat));
1214 return (FTS_NS);
1217 if (S_ISDIR(sbp->st_mode)) {
1219 * Set the device/inode. Used to find cycles and check for
1220 * crossing mount points. Also remember the link count, used
1221 * in fts_build to limit the number of stat calls. It is
1222 * understood that these fields are only referenced if fts_info
1223 * is set to FTS_D.
1225 p->fts_dev = sbp->st_dev;
1226 p->fts_ino = sbp->st_ino;
1227 p->fts_nlink = sbp->st_nlink;
1229 if (ISDOT(p->fts_name))
1230 return (FTS_DOT);
1232 return (FTS_D);
1234 if (S_ISLNK(sbp->st_mode))
1235 return (FTS_SL);
1236 if (S_ISREG(sbp->st_mode))
1237 return (FTS_F);
1238 return (FTS_DEFAULT);
1241 static FTSENT *
1242 internal_function
1243 fts_sort(sp, head, nitems)
1244 FTS *sp;
1245 FTSENT *head;
1246 register size_t nitems;
1248 register FTSENT **ap, *p;
1251 * Construct an array of pointers to the structures and call qsort(3).
1252 * Reassemble the array in the order returned by qsort. If unable to
1253 * sort for memory reasons, return the directory entries in their
1254 * current order. Allocate enough space for the current needs plus
1255 * 40 so don't realloc one entry at a time.
1257 if (nitems > sp->fts_nitems) {
1258 struct _ftsent **a;
1260 sp->fts_nitems = nitems + 40;
1261 if (SIZE_MAX / sizeof *a < sp->fts_nitems
1262 || ! (a = realloc (sp->fts_array,
1263 sp->fts_nitems * sizeof *a))) {
1264 free(sp->fts_array);
1265 sp->fts_array = NULL;
1266 sp->fts_nitems = 0;
1267 return (head);
1269 sp->fts_array = a;
1271 for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1272 *ap++ = p;
1273 qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
1274 for (head = *(ap = sp->fts_array); --nitems; ++ap)
1275 ap[0]->fts_link = ap[1];
1276 ap[0]->fts_link = NULL;
1277 return (head);
1280 static FTSENT *
1281 internal_function
1282 fts_alloc(sp, name, namelen)
1283 FTS *sp;
1284 const char *name;
1285 register size_t namelen;
1287 register FTSENT *p;
1288 size_t len;
1291 * The file name is a variable length array. Allocate the FTSENT
1292 * structure and the file name in one chunk.
1294 len = sizeof(FTSENT) + namelen;
1295 if ((p = malloc(len)) == NULL)
1296 return (NULL);
1298 /* Copy the name and guarantee NUL termination. */
1299 memmove(p->fts_name, name, namelen);
1300 p->fts_name[namelen] = '\0';
1302 p->fts_namelen = namelen;
1303 p->fts_path = sp->fts_path;
1304 p->fts_errno = 0;
1305 p->fts_flags = 0;
1306 p->fts_instr = FTS_NOINSTR;
1307 p->fts_number = 0;
1308 p->fts_pointer = NULL;
1309 return (p);
1312 static void
1313 internal_function
1314 fts_lfree(head)
1315 register FTSENT *head;
1317 register FTSENT *p;
1319 /* Free a linked list of structures. */
1320 while ((p = head)) {
1321 head = head->fts_link;
1322 free(p);
1327 * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1328 * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1329 * though the kernel won't resolve them. Add the size (not just what's needed)
1330 * plus 256 bytes so don't realloc the path 2 bytes at a time.
1332 static bool
1333 internal_function
1334 fts_palloc(sp, more)
1335 FTS *sp;
1336 size_t more;
1338 char *p;
1339 size_t new_len = sp->fts_pathlen + more + 256;
1342 * See if fts_pathlen would overflow.
1344 if (new_len < sp->fts_pathlen) {
1345 if (sp->fts_path) {
1346 free(sp->fts_path);
1347 sp->fts_path = NULL;
1349 sp->fts_path = NULL;
1350 __set_errno (ENAMETOOLONG);
1351 return false;
1353 sp->fts_pathlen = new_len;
1354 p = realloc(sp->fts_path, sp->fts_pathlen);
1355 if (p == NULL) {
1356 free(sp->fts_path);
1357 sp->fts_path = NULL;
1358 return false;
1360 sp->fts_path = p;
1361 return true;
1365 * When the path is realloc'd, have to fix all of the pointers in structures
1366 * already returned.
1368 static void
1369 internal_function
1370 fts_padjust(sp, head)
1371 FTS *sp;
1372 FTSENT *head;
1374 FTSENT *p;
1375 char *addr = sp->fts_path;
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); \
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);
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;
1395 static size_t
1396 internal_function
1397 fts_maxarglen(argv)
1398 char * const *argv;
1400 size_t len, max;
1402 for (max = 0; *argv; ++argv)
1403 if ((len = strlen(*argv)) > max)
1404 max = len;
1405 return (max + 1);
1409 * Change to dir specified by fd or path without getting
1410 * tricked by someone changing the world out from underneath us.
1411 * Assumes p->fts_dev and p->fts_ino are filled in.
1413 static int
1414 internal_function
1415 fts_safe_changedir(sp, p, fd, path)
1416 FTS *sp;
1417 FTSENT *p;
1418 int fd;
1419 const char *path;
1421 int ret, oerrno, newfd;
1422 struct stat sb;
1424 newfd = fd;
1425 if (ISSET(FTS_NOCHDIR))
1426 return (0);
1427 if (fd < 0 && (newfd = diropen (path)) < 0)
1428 return (-1);
1429 if (fstat(newfd, &sb)) {
1430 ret = -1;
1431 goto bail;
1433 if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
1434 __set_errno (ENOENT); /* disinformation */
1435 ret = -1;
1436 goto bail;
1438 ret = fchdir(newfd);
1439 bail:
1440 oerrno = errno;
1441 if (fd < 0)
1442 (void)close(newfd);
1443 __set_errno (oerrno);
1444 return (ret);