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)
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. */
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
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
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>
60 # include <include/sys/stat.h>
62 # include <sys/stat.h>
74 # include <inttypes.h>
79 #if ULONG_MAX < ULLONG_MAX
80 # define LONGEST_MODIFIER "ll"
82 # define LONGEST_MODIFIER "l"
88 # define PRIuMAX LONGEST_MODIFIER "u"
93 # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
97 # define NAMLEN(dirent) strlen ((dirent)->d_name)
99 # define dirent direct
100 # define NAMLEN(dirent) (dirent)->d_namlen
102 # include <sys/ndir.h>
105 # include <sys/dir.h>
115 # define close __close
117 # define closedir __closedir
119 # define fchdir __fchdir
123 # define opendir __opendir
125 # define readdir __readdir
127 # undef internal_function
128 # define internal_function /* empty */
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
*);
137 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
141 # define __set_errno(Val) errno = (Val)
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))
155 static int fts_safe_changedir
__P((FTS
*, FTSENT
*, int, const char *))
159 # define MAX(a,b) ((a) > (b) ? (a) : (b))
163 # define SIZE_MAX ((size_t) -1)
167 # define O_DIRECTORY 0
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
189 bool fts_debug
= false;
191 # define Dprintf(x) do { if (fts_debug) printf x; } while (0)
196 #define ENTER_DIR(Fts, Ent, Tag) \
198 Dprintf ((" %s-entering: %s\n", Tag, (Ent)->fts_path)); \
202 #define LEAVE_DIR(Fts, Ent, Tag) \
204 Dprintf ((" %s-leaving: %s\n", Tag, (Ent)->fts_path)); \
208 /* Use these each of these to map a device/inode pair to an FTSENT. */
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
;
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
;
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
;
244 ad
->dev
= st
->st_dev
;
245 ad
->ino
= st
->st_ino
;
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
)
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
;
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. */
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
;
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
;
296 obj
.dev
= st
->st_dev
;
297 obj
.ino
= st
->st_ino
;
298 found
= hash_delete (fts
->active_dir_ht
, &obj
);
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. */
311 diropen (char const *dir
)
313 int fd
= open (dir
, O_RDONLY
| O_DIRECTORY
);
315 fd
= open (dir
, O_WRONLY
| O_DIRECTORY
);
320 fts_open(argv
, options
, compar
)
322 register int options
;
323 int (*compar
) __P((const FTSENT
**, const FTSENT
**));
326 register FTSENT
*p
, *root
;
327 register size_t nitems
;
328 FTSENT
*parent
, *tmp
= NULL
; /* pacify gcc */
332 if (options
& ~FTS_OPTIONMASK
) {
333 __set_errno (EINVAL
);
337 /* Allocate/initialize the stream */
338 if ((sp
= malloc(sizeof(FTS
))) == 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
))
349 * Start out with 1K of path space, and enough, in any case,
350 * to hold the user's paths.
353 # define MAXPATHLEN 1024
355 if (! fts_palloc(sp
, MAX(fts_maxarglen(argv
), MAXPATHLEN
)))
358 /* Allocate/initialize root's parent. */
359 if ((parent
= fts_alloc(sp
, "", 0)) == NULL
)
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
);
371 if ((p
= fts_alloc(sp
, *argv
, len
)) == NULL
)
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
)
383 * If comparison routine supplied, traverse in sorted
384 * order; otherwise traverse in the order specified.
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
)
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
,
417 if (sp
->active_dir_ht
== NULL
)
419 sp
->cycle_state
= malloc (sizeof *sp
->cycle_state
);
423 sp
->cycle_state
= malloc (sizeof *sp
->cycle_state
);
424 if (sp
->cycle_state
== NULL
)
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)
443 mem3
: fts_lfree(root
);
445 mem2
: free(sp
->fts_path
);
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])) {
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
;
481 register FTSENT
*freep
, *p
;
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.
490 for (p
= sp
->fts_cur
; p
->fts_level
>= FTS_ROOTLEVEL
;) {
492 p
= p
->fts_link
!= NULL
? p
->fts_link
: p
->fts_parent
;
498 /* Free up child linked list, sort array, path buffer. */
500 fts_lfree(sp
->fts_child
);
505 /* Return to original directory, save errno if necessary. */
506 if (!ISSET(FTS_NOCHDIR
)) {
507 if (fchdir(sp
->fts_rfd
))
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
);
516 free (sp
->cycle_state
);
518 /* Free up the stream pointer. */
521 /* Set errno and return. */
523 __set_errno (saved_errno
);
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".
535 (p->fts_path[p->fts_pathlen - 1] == '/' \
536 ? p->fts_pathlen - 1 : p->fts_pathlen)
542 register FTSENT
*p
, *tmp
;
543 register unsigned short int instr
;
547 /* If finished or unrecoverable error, return NULL. */
548 if (sp
->fts_cur
== NULL
|| ISSET(FTS_STOP
))
551 /* Set current node pointer. */
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);
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
;
580 p
->fts_flags
|= FTS_SYMFOLLOW
;
582 if (p
->fts_info
== FTS_D
)
583 ENTER_DIR (sp
, p
, "7");
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
);
595 fts_lfree(sp
->fts_child
);
596 sp
->fts_child
= NULL
;
598 p
->fts_info
= FTS_DP
;
599 LEAVE_DIR (sp
, p
, "1");
603 /* Rebuild if only read the names and now traversing. */
604 if (sp
->fts_child
!= NULL
&& ISSET(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
;
629 p
->fts_parent
->fts_accpath
;
631 } else if ((sp
->fts_child
= fts_build(sp
, BREAD
)) == 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. */
638 p
->fts_info
= FTS_ERR
;
639 /* FIXME: see if this should be in an else block */
640 LEAVE_DIR (sp
, p
, "2");
644 sp
->fts_child
= NULL
;
648 /* Move to the next node on this level. */
650 if ((p
= p
->fts_link
) != NULL
) {
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
)) {
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
)
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
;
682 p
->fts_flags
|= FTS_SYMFOLLOW
;
684 p
->fts_instr
= FTS_NOINSTR
;
687 name
: t
= sp
->fts_path
+ NAPPEND(p
->fts_parent
);
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. */
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.
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
717 if (p
->fts_level
== FTS_ROOTLEVEL
) {
718 if (FCHDIR(sp
, sp
->fts_rfd
)) {
719 p
->fts_errno
= errno
;
722 } else if (p
->fts_flags
& FTS_SYMFOLLOW
) {
723 if (FCHDIR(sp
, p
->fts_symfd
)) {
725 (void)close(p
->fts_symfd
);
726 __set_errno (saved_errno
);
727 p
->fts_errno
= errno
;
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
;
736 p
->fts_info
= p
->fts_errno
? FTS_ERR
: FTS_DP
;
737 if (p
->fts_errno
== 0)
738 LEAVE_DIR (sp
, p
, "3");
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
751 fts_set(sp
, p
, instr
)
756 if (instr
!= 0 && instr
!= FTS_AGAIN
&& instr
!= FTS_FOLLOW
&&
757 instr
!= FTS_NOINSTR
&& instr
!= FTS_SKIP
) {
758 __set_errno (EINVAL
);
761 p
->fts_instr
= instr
;
766 fts_children(sp
, instr
)
773 if (instr
!= 0 && instr
!= FTS_NAMEONLY
) {
774 __set_errno (EINVAL
);
778 /* Set current node pointer. */
782 * Errno set to 0 so user can distinguish empty directory from
787 /* Fatal errors stop here. */
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 */)
803 /* Free up any previous child list. */
804 if (sp
->fts_child
!= NULL
)
805 fts_lfree(sp
->fts_child
);
807 if (instr
== FTS_NAMEONLY
) {
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] == '/' ||
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
);
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.
855 register struct dirent
*dp
;
856 register FTSENT
*p
, *head
;
857 register size_t nitems
;
868 size_t len
, maxlen
, new_len
;
871 /* Set current node pointer. */
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
;
882 oflag
= DTF_HIDEW
|DTF_NODUP
|DTF_REWIND
;
884 # define __opendir2(path, flag) opendir(path)
886 if ((dirp
= __opendir2(cur
->fts_accpath
, oflag
)) == NULL
) {
888 cur
->fts_info
= FTS_DNR
;
889 cur
->fts_errno
= errno
;
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
) {
901 /* Be quiet about nostat, GCC. */
903 } else if (ISSET(FTS_NOSTAT
) && ISSET(FTS_PHYSICAL
)) {
904 nlinks
= cur
->fts_nlink
- (ISSET(FTS_SEEDOT
) ? 0 : 2);
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.
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
;
934 (void)closedir(dirp
);
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.
952 if (ISSET(FTS_NOCHDIR
)) {
953 cp
= sp
->fts_path
+ len
;
956 /* GCC, you're too verbose. */
960 maxlen
= sp
->fts_pathlen
- len
;
962 level
= cur
->fts_level
+ 1;
964 /* Read the directory, attaching each entry to the `link' pointer. */
966 for (head
= tail
= NULL
, nitems
= 0; dirp
&& (dp
= readdir(dirp
));) {
967 if (!ISSET(FTS_SEEDOT
) && ISDOT(dp
->d_name
))
970 if ((p
= fts_alloc(sp
, dp
->d_name
, NAMLEN (dp
))) == NULL
)
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
;
984 (void)closedir(dirp
);
985 cur
->fts_info
= FTS_ERR
;
987 __set_errno (saved_errno
);
990 /* Did realloc() change the pointer? */
991 if (oldaddr
!= sp
->fts_path
) {
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.
1009 (void)closedir(dirp
);
1010 cur
->fts_info
= FTS_ERR
;
1012 __set_errno (ENAMETOOLONG
);
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
;
1026 p
->fts_info
= FTS_NS
;
1027 p
->fts_errno
= cderrno
;
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
1034 dp
->d_type
!= DT_DIR
&& dp
->d_type
!= DT_UNKNOWN
)
1038 ISSET(FTS_NOCHDIR
) ? p
->fts_path
: p
->fts_name
;
1039 p
->fts_info
= FTS_NSOK
;
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);
1046 p
->fts_accpath
= p
->fts_name
;
1048 p
->fts_info
= fts_stat(sp
, p
, false);
1050 /* Decrement link count if applicable. */
1052 && (TYPE_SIGNED (nlink_t
) || nostat
)
1053 && (p
->fts_info
== FTS_D
||
1054 p
->fts_info
== FTS_DC
|| p
->fts_info
== FTS_DOT
))
1058 /* We walk in directory order so "ls -f" doesn't get upset. */
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.
1076 fts_padjust(sp
, head
);
1079 * If not changing directories, reset the path back to original
1082 if (ISSET(FTS_NOCHDIR
)) {
1083 if (len
== sp
->fts_pathlen
|| nitems
== 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
;
1104 /* If didn't find anything, return NULL. */
1107 cur
->fts_info
= FTS_DP
;
1111 /* Sort the entries. */
1112 if (sp
->fts_compar
&& nitems
> 1)
1113 head
= fts_sort(sp
, head
, nitems
);
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. */
1123 find_matching_ancestor (FTSENT
const *e_curr
, struct Active_dir
const *ad
)
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
)
1132 printf ("ERROR: tree dir, %s, not active\n", ad
->fts_ent
->fts_accpath
);
1133 printf ("active dirs:\n");
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
,
1141 (uintmax_t) ent
->fts_statp
->st_dev
,
1142 (uintmax_t) ent
->fts_statp
->st_ino
);
1146 fts_cross_check (FTS
const *sp
)
1148 FTSENT
const *ent
= sp
->fts_cur
;
1150 if ( ! ISSET (FTS_TIGHT_CYCLE_CHECK
))
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
);
1180 static unsigned short int
1182 fts_stat(FTS
*sp
, register FTSENT
*p
, bool follow
)
1184 struct stat
*sbp
= p
->fts_statp
;
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
;
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
)) {
1206 return (FTS_SLNONE
);
1208 p
->fts_errno
= saved_errno
;
1211 } else if (lstat(p
->fts_accpath
, sbp
)) {
1212 p
->fts_errno
= errno
;
1213 err
: memset(sbp
, 0, sizeof(struct stat
));
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
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
))
1234 if (S_ISLNK(sbp
->st_mode
))
1236 if (S_ISREG(sbp
->st_mode
))
1238 return (FTS_DEFAULT
);
1243 fts_sort(sp
, head
, nitems
)
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
) {
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
;
1271 for (ap
= sp
->fts_array
, p
= head
; p
; p
= p
->fts_link
)
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
;
1282 fts_alloc(sp
, name
, namelen
)
1285 register size_t namelen
;
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
)
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
;
1306 p
->fts_instr
= FTS_NOINSTR
;
1308 p
->fts_pointer
= NULL
;
1315 register FTSENT
*head
;
1319 /* Free a linked list of structures. */
1320 while ((p
= head
)) {
1321 head
= head
->fts_link
;
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.
1334 fts_palloc(sp
, more
)
1339 size_t new_len
= sp
->fts_pathlen
+ more
+ 256;
1342 * See if fts_pathlen would overflow.
1344 if (new_len
< sp
->fts_pathlen
) {
1347 sp
->fts_path
= NULL
;
1349 sp
->fts_path
= NULL
;
1350 __set_errno (ENAMETOOLONG
);
1353 sp
->fts_pathlen
= new_len
;
1354 p
= realloc(sp
->fts_path
, sp
->fts_pathlen
);
1357 sp
->fts_path
= NULL
;
1365 * When the path is realloc'd, have to fix all of the pointers in structures
1370 fts_padjust(sp
, head
)
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; \
1384 /* Adjust the current set of children. */
1385 for (p
= sp
->fts_child
; p
; p
= p
->fts_link
)
1388 /* Adjust the rest of the tree, including the current level. */
1389 for (p
= head
; p
->fts_level
>= FTS_ROOTLEVEL
;) {
1391 p
= p
->fts_link
? p
->fts_link
: p
->fts_parent
;
1402 for (max
= 0; *argv
; ++argv
)
1403 if ((len
= strlen(*argv
)) > max
)
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.
1415 fts_safe_changedir(sp
, p
, fd
, path
)
1421 int ret
, oerrno
, newfd
;
1425 if (ISSET(FTS_NOCHDIR
))
1427 if (fd
< 0 && (newfd
= diropen (path
)) < 0)
1429 if (fstat(newfd
, &sb
)) {
1433 if (p
->fts_dev
!= sb
.st_dev
|| p
->fts_ino
!= sb
.st_ino
) {
1434 __set_errno (ENOENT
); /* disinformation */
1438 ret
= fchdir(newfd
);
1443 __set_errno (oerrno
);