Forward port the sources to be able to compile with c99/gcc5

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Upstream-Status: Inappropriate

Index: fts/fts.c
===================================================================
--- fts.orig/fts.c
+++ fts/fts.c
@@ -51,16 +51,6 @@ static char sccsid[] = "@(#)fts.c	8.6 (B
 #include <string.h>
 #include <unistd.h>
 
-static FTSENT	*fts_alloc __P(FTS *, char *, int);
-static FTSENT	*fts_build __P(FTS *, int);
-static void	 fts_lfree __P(FTSENT *);
-static void	 fts_load __P(FTS *, FTSENT *);
-static size_t	 fts_maxarglen __P(char * const *);
-static void	 fts_padjust __P(FTS *, void *);
-static int	 fts_palloc __P(FTS *, size_t);
-static FTSENT	*fts_sort __P(FTS *, FTSENT *, int);
-static u_short	 fts_stat __P(FTS *, struct dirent *, FTSENT *, int);
-
 #define	ISDOT(a)	(a[0] == '.' && (!a[1] || a[1] == '.' && !a[2]))
 
 #define	ISSET(opt)	(sp->fts_options & opt)
@@ -73,119 +63,16 @@ static u_short	 fts_stat __P(FTS *, stru
 #define	BCHILD		1		/* fts_children */
 #define	BNAMES		2		/* fts_children, names only */
 #define	BREAD		3		/* fts_read */
-
-FTS *
-fts_open(argv, options, compar)
-	char * const *argv;
-	register int options;
-	int (*compar)();
-{
-	register FTS *sp;
-	register FTSENT *p, *root;
-	register int nitems;
-	FTSENT *parent, *tmp;
-	int len;
-
-	/* Options check. */
-	if (options & ~FTS_OPTIONMASK) {
-		errno = EINVAL;
-		return (NULL);
-	}
-
-	/* Allocate/initialize the stream */
-	if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
-		return (NULL);
-	memset(sp, 0, sizeof(FTS));
-	sp->fts_compar = compar;
-	sp->fts_options = options;
-
-	/* Logical walks turn on NOCHDIR; symbolic links are too hard. */
-	if (ISSET(FTS_LOGICAL))
-		SET(FTS_NOCHDIR);
-
-	/*
-	 * Start out with 1K of path space, and enough, in any case,
-	 * to hold the user's paths.
-	 */
-	if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
-		goto mem1;
-
-	/* Allocate/initialize root's parent. */
-	if ((parent = fts_alloc(sp, "", 0)) == NULL)
-		goto mem2;
-	parent->fts_level = FTS_ROOTPARENTLEVEL;
-
-	/* Allocate/initialize root(s). */
-	for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
-		/* Don't allow zero-length paths. */
-		if ((len = strlen(*argv)) == 0) {
-			errno = EINVAL;
-			goto mem3;
-		}
-
-		p = fts_alloc(sp, *argv, len);
-		p->fts_level = FTS_ROOTLEVEL;
-		p->fts_parent = parent;
-		p->fts_accpath = p->fts_name;
-		p->fts_info = fts_stat(sp, NULL, p, ISSET(FTS_COMFOLLOW));
-
-		/* Command-line "." and ".." are real directories. */
-		if (p->fts_info == FTS_DOT)
-			p->fts_info = FTS_D;
-
-		/*
-		 * If comparison routine supplied, traverse in sorted
-		 * order; otherwise traverse in the order specified.
-		 */
-		if (compar) {
-			p->fts_link = root;
-			root = p;
-		} else {
-			p->fts_link = NULL;
-			if (root == NULL)
-				tmp = root = p;
-			else {
-				tmp->fts_link = p;
-				tmp = p;
-			}
-		}
-	}
-	if (compar && nitems > 1)
-		root = fts_sort(sp, root, nitems);
-
-	/*
-	 * Allocate a dummy pointer and make fts_read think that we've just
-	 * finished the node before the root(s); set p->fts_info to FTS_INIT
-	 * so that everything about the "current" node is ignored.
-	 */
-	if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
-		goto mem3;
-	sp->fts_cur->fts_link = root;
-	sp->fts_cur->fts_info = FTS_INIT;
-
-	/*
-	 * If using chdir(2), grab a file descriptor pointing to dot to insure
-	 * that we can get back here; this could be avoided for some paths,
-	 * but almost certainly not worth the effort.  Slashes, symbolic links,
-	 * and ".." are all fairly nasty problems.  Note, if we can't get the
-	 * descriptor we run anyway, just more slowly.
-	 */
-	if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
-		SET(FTS_NOCHDIR);
-
-	return (sp);
-
-mem3:	fts_lfree(root);
-	free(parent);
-mem2:	free(sp->fts_path);
-mem1:	free(sp);
-	return (NULL);
-}
+/*
+ * Special case a root of "/" so that slashes aren't appended which would
+ * cause paths to be written as "//foo".
+ */
+#define	NAPPEND(p)							\
+	(p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 &&	\
+	    p->fts_path[0] == '/' ? 0 : p->fts_pathlen)
 
 static void
-fts_load(sp, p)
-	FTS *sp;
-	register FTSENT *p;
+fts_load(FTS *sp, register FTSENT *p)
 {
 	register int len;
 	register char *cp;
@@ -208,332 +95,214 @@ fts_load(sp, p)
 	sp->fts_dev = p->fts_dev;
 }
 
-int
-fts_close(sp)
-	FTS *sp;
+static void
+fts_lfree(register FTSENT *head)
 {
-	register FTSENT *freep, *p;
-	int saved_errno;
+	register FTSENT *p;
 
-	/*
-	 * This still works if we haven't read anything -- the dummy structure
-	 * points to the root list, so we step through to the end of the root
-	 * list which has a valid parent pointer.
-	 */
-	if (sp->fts_cur) {
-		for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
-			freep = p;
-			p = p->fts_link ? p->fts_link : p->fts_parent;
-			free(freep);
-		}
+	/* Free a linked list of structures. */
+	while (p = head) {
+		head = head->fts_link;
 		free(p);
 	}
+}
 
-	/* Free up child linked list, sort array, path buffer. */
-	if (sp->fts_child)
-		fts_lfree(sp->fts_child);
-	if (sp->fts_array)
-		free(sp->fts_array);
-	free(sp->fts_path);
+static size_t
+fts_maxarglen(char * const *argv)
+{
+	size_t len, max;
 
-	/* Return to original directory, save errno if necessary. */
-	if (!ISSET(FTS_NOCHDIR)) {
-		saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
-		(void)close(sp->fts_rfd);
-	}
+	for (max = 0; *argv; ++argv)
+		if ((len = strlen(*argv)) > max)
+			max = len;
+	return (max);
+}
 
-	/* Free up the stream pointer. */
-	free(sp);
 
-	/* Set errno and return. */
-	if (!ISSET(FTS_NOCHDIR) && saved_errno) {
-		errno = saved_errno;
-		return (-1);
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+fts_padjust(FTS *sp, void *addr)
+{
+	FTSENT *p;
+
+#define	ADJUST(p) {							\
+	(p)->fts_accpath =						\
+	    (char *)addr + ((p)->fts_accpath - (p)->fts_path);		\
+	(p)->fts_path = addr;						\
+}
+	/* Adjust the current set of children. */
+	for (p = sp->fts_child; p; p = p->fts_link)
+		ADJUST(p);
+
+	/* Adjust the rest of the tree. */
+	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+		ADJUST(p);
+		p = p->fts_link ? p->fts_link : p->fts_parent;
 	}
-	return (0);
 }
 
 /*
- * Special case a root of "/" so that slashes aren't appended which would
- * cause paths to be written as "//foo".
+ * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
+ * Most systems will allow creation of paths much longer than MAXPATHLEN, even
+ * though the kernel won't resolve them.  Add the size (not just what's needed)
+ * plus 256 bytes so don't realloc the path 2 bytes at a time.
  */
-#define	NAPPEND(p)							\
-	(p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 &&	\
-	    p->fts_path[0] == '/' ? 0 : p->fts_pathlen)
+static int
+fts_palloc(FTS *sp, size_t more)
+{
+	sp->fts_pathlen += more + 256;
+	sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen);
+	return (sp->fts_path == NULL);
+}
 
-FTSENT *
-fts_read(sp)
-	register FTS *sp;
+static FTSENT *
+fts_alloc(FTS *sp, char *name, register int namelen)
 {
-	register FTSENT *p, *tmp;
-	register int instr;
-	register char *t;
-	int saved_errno;
+	register FTSENT *p;
+	size_t len;
 
-	/* If finished or unrecoverable error, return NULL. */
-	if (sp->fts_cur == NULL || ISSET(FTS_STOP))
+	/*
+	 * The file name is a variable length array and no stat structure is
+	 * necessary if the user has set the nostat bit.  Allocate the FTSENT
+	 * structure, the file name and the stat structure in one chunk, but
+	 * be careful that the stat structure is reasonably aligned.  Since the
+	 * fts_name field is declared to be of size 1, the fts_name pointer is
+	 * namelen + 2 before the first possible address of the stat structure.
+	 */
+	len = sizeof(FTSENT) + namelen;
+	if (!ISSET(FTS_NOSTAT))
+		len += sizeof(struct stat) + ALIGNBYTES;
+	if ((p = malloc(len)) == NULL)
 		return (NULL);
 
-	/* Set current node pointer. */
-	p = sp->fts_cur;
+	/* Copy the name plus the trailing NULL. */
+	memmove(p->fts_name, name, namelen + 1);
 
-	/* Save and zero out user instructions. */
-	instr = p->fts_instr;
+	if (!ISSET(FTS_NOSTAT))
+		p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
+	p->fts_namelen = namelen;
+	p->fts_path = sp->fts_path;
+	p->fts_errno = 0;
+	p->fts_flags = 0;
 	p->fts_instr = FTS_NOINSTR;
+	p->fts_number = 0;
+	p->fts_pointer = NULL;
+	return (p);
+}
 
-	/* Any type of file may be re-visited; re-stat and re-turn. */
-	if (instr == FTS_AGAIN) {
-		p->fts_info = fts_stat(sp, NULL, p, 0);
-		return (p);
-	}
 
+static u_short
+fts_stat(FTS *sp, register FTSENT *p, struct dirent *dp, int follow)
+{
+	register FTSENT *t;
+	register dev_t dev;
+	register ino_t ino;
+	struct stat *sbp, sb;
+	int saved_errno;
+
+	/* If user needs stat info, stat buffer already allocated. */
+	sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+
+#ifdef S_IFWHT
 	/*
-	 * Following a symlink -- SLNONE test allows application to see
-	 * SLNONE and recover.  If indirecting through a symlink, have
-	 * keep a pointer to current location.  If unable to get that
-	 * pointer, follow fails.
-	 */
-	if (instr == FTS_FOLLOW &&
-	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
-		p->fts_info = fts_stat(sp, NULL, p, 1);
-		if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR))
-			if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
-				p->fts_errno = errno;
-				p->fts_info = FTS_ERR;
-			} else
-				p->fts_flags |= FTS_SYMFOLLOW;
-		return (p);
+	 * Whited-out files don't really exist.  However, there's stat(2) file
+	 * mask for them, so we set it so that programs (i.e., find) don't have
+	 * to test FTS_W separately from other file types.
+	 */
+	if (dp != NULL && dp->d_type == DT_WHT) {
+		memset(sbp, 0, sizeof(struct stat));
+		sbp->st_mode = S_IFWHT;
+		return (FTS_W);
 	}
-
-	/* Directory in pre-order. */
-	if (p->fts_info == FTS_D) {
-		/* If skipped or crossed mount point, do post-order visit. */
-		if (instr == FTS_SKIP ||
-		    ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) {
-			if (p->fts_flags & FTS_SYMFOLLOW)
-				(void)close(p->fts_symfd);
-			if (sp->fts_child) {
-				fts_lfree(sp->fts_child);
-				sp->fts_child = NULL;
-			}
-			p->fts_info = FTS_DP;
-			return (p);
-		} 
-
-		/* Rebuild if only read the names and now traversing. */
-		if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) {
-			sp->fts_options &= ~FTS_NAMEONLY;
-			fts_lfree(sp->fts_child);
-			sp->fts_child = NULL;
-		}
-
-		/*
-		 * Cd to the subdirectory.
-		 *
-		 * If have already read and now fail to chdir, whack the list
-		 * to make the names come out right, and set the parent errno
-		 * so the application will eventually get an error condition.
-		 * Set the FTS_DONTCHDIR flag so that when we logically change
-		 * directories back to the parent we don't do a chdir.
-		 *
-		 * If haven't read do so.  If the read fails, fts_build sets
-		 * FTS_STOP or the fts_info field of the node.
-		 */
-		if (sp->fts_child) {
-			if (CHDIR(sp, p->fts_accpath)) {
-				p->fts_errno = errno;
-				p->fts_flags |= FTS_DONTCHDIR;
-				for (p = sp->fts_child; p; p = p->fts_link)
-					p->fts_accpath =
-					    p->fts_parent->fts_accpath;
-			}
-		} else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
-			if (ISSET(FTS_STOP))
-				return (NULL);
-			return (p);
+#endif
+
+	/*
+	 * If doing a logical walk, or application requested FTS_FOLLOW, do
+	 * a stat(2).  If that fails, check for a non-existent symlink.  If
+	 * fail, set the errno from the stat call.
+	 */
+	if (ISSET(FTS_LOGICAL) || follow) {
+		if (stat(p->fts_accpath, sbp)) {
+			saved_errno = errno;
+			if (!lstat(p->fts_accpath, sbp)) {
+				errno = 0;
+				return (FTS_SLNONE);
+			}
+			p->fts_errno = saved_errno;
+			goto err;
 		}
-		p = sp->fts_child;
-		sp->fts_child = NULL;
-		goto name;
+	} else if (lstat(p->fts_accpath, sbp)) {
+		p->fts_errno = errno;
+err:		memset(sbp, 0, sizeof(struct stat));
+		return (FTS_NS);
 	}
 
-	/* Move to the next node on this level. */
-next:	tmp = p;
-	if (p = p->fts_link) {
-		free(tmp);
-
-		/*
-		 * If reached the top, return to the original directory, and
-		 * load the paths for the next root.
-		 */
-		if (p->fts_level == FTS_ROOTLEVEL) {
-			if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) {
-				SET(FTS_STOP);
-				return (NULL);
-			}
-			fts_load(sp, p);
-			return (sp->fts_cur = p);
-		}
-
+	if (S_ISDIR(sbp->st_mode)) {
 		/*
-		 * User may have called fts_set on the node.  If skipped,
-		 * ignore.  If followed, get a file descriptor so we can
-		 * get back if necessary.
+		 * Set the device/inode.  Used to find cycles and check for
+		 * crossing mount points.  Also remember the link count, used
+		 * in fts_build to limit the number of stat calls.  It is
+		 * understood that these fields are only referenced if fts_info
+		 * is set to FTS_D.
 		 */
-		if (p->fts_instr == FTS_SKIP)
-			goto next;
-		if (p->fts_instr == FTS_FOLLOW) {
-			p->fts_info = fts_stat(sp, NULL, p, 1);
-			if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR))
-				if ((p->fts_symfd =
-				    open(".", O_RDONLY, 0)) < 0) {
-					p->fts_errno = errno;
-					p->fts_info = FTS_ERR;
-				} else
-					p->fts_flags |= FTS_SYMFOLLOW;
-			p->fts_instr = FTS_NOINSTR;
-		}
-
-name:		t = sp->fts_path + NAPPEND(p->fts_parent);
-		*t++ = '/';
-		memmove(t, p->fts_name, p->fts_namelen + 1);
-		return (sp->fts_cur = p);
-	}
+		dev = p->fts_dev = sbp->st_dev;
+		ino = p->fts_ino = sbp->st_ino;
+		p->fts_nlink = sbp->st_nlink;
 
-	/* Move up to the parent node. */
-	p = tmp->fts_parent;
-	free(tmp);
+		if (ISDOT(p->fts_name))
+			return (FTS_DOT);
 
-	if (p->fts_level == FTS_ROOTPARENTLEVEL) {
 		/*
-		 * Done; free everything up and set errno to 0 so the user
-		 * can distinguish between error and EOF.
+		 * Cycle detection is done by brute force when the directory
+		 * is first encountered.  If the tree gets deep enough or the
+		 * number of symbolic links to directories is high enough,
+		 * something faster might be worthwhile.
 		 */
-		free(p);
-		errno = 0;
-		return (sp->fts_cur = NULL);
-	}
-
-	/* Nul terminate the pathname. */
-	sp->fts_path[p->fts_pathlen] = '\0';
-
-	/*
-	 * Return to the parent directory.  If at a root node or came through
-	 * a symlink, go back through the file descriptor.  Otherwise, cd up
-	 * one directory.
-	 */
-	if (p->fts_level == FTS_ROOTLEVEL) {
-		if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) {
-			SET(FTS_STOP);
-			return (NULL);
-		}
-	} else if (p->fts_flags & FTS_SYMFOLLOW) {
-		if (FCHDIR(sp, p->fts_symfd)) {
-			saved_errno = errno;
-			(void)close(p->fts_symfd);
-			errno = saved_errno;
-			SET(FTS_STOP);
-			return (NULL);
-		}
-		(void)close(p->fts_symfd);
-	} else if (!(p->fts_flags & FTS_DONTCHDIR)) {
-		if (CHDIR(sp, "..")) {
-			SET(FTS_STOP);
-			return (NULL);
-		}
-	}
-	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
-	return (sp->fts_cur = p);
-}
-
-/*
- * Fts_set takes the stream as an argument although it's not used in this
- * implementation; it would be necessary if anyone wanted to add global
- * semantics to fts using fts_set.  An error return is allowed for similar
- * reasons.
- */
-/* ARGSUSED */
-int
-fts_set(sp, p, instr)
-	FTS *sp;
-	FTSENT *p;
-	int instr;
-{
-	if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
-	    instr != FTS_NOINSTR && instr != FTS_SKIP) {
-		errno = EINVAL;
-		return (1);
+		for (t = p->fts_parent;
+		    t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
+			if (ino == t->fts_ino && dev == t->fts_dev) {
+				p->fts_cycle = t;
+				return (FTS_DC);
+			}
+		return (FTS_D);
 	}
-	p->fts_instr = instr;
-	return (0);
+	if (S_ISLNK(sbp->st_mode))
+		return (FTS_SL);
+	if (S_ISREG(sbp->st_mode))
+		return (FTS_F);
+	return (FTS_DEFAULT);
 }
 
-FTSENT *
-fts_children(sp, instr)
-	register FTS *sp;
-	int instr;
+static FTSENT *
+fts_sort(FTS *sp, FTSENT *head, register int nitems)
 {
-	register FTSENT *p;
-	int fd;
-
-	if (instr && instr != FTS_NAMEONLY) {
-		errno = EINVAL;
-		return (NULL);
-	}
-
-	/* Set current node pointer. */
-	p = sp->fts_cur;
-
-	/*
-	 * Errno set to 0 so user can distinguish empty directory from
-	 * an error.
-	 */
-	errno = 0;
-
-	/* Fatal errors stop here. */
-	if (ISSET(FTS_STOP))
-		return (NULL);
-
-	/* Return logical hierarchy of user's arguments. */
-	if (p->fts_info == FTS_INIT)
-		return (p->fts_link);
-
-	/*
-	 * If not a directory being visited in pre-order, stop here.  Could
-	 * allow FTS_DNR, assuming the user has fixed the problem, but the
-	 * same effect is available with FTS_AGAIN.
-	 */
-	if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
-		return (NULL);
-
-	/* Free up any previous child list. */
-	if (sp->fts_child)
-		fts_lfree(sp->fts_child);
-
-	if (instr == FTS_NAMEONLY) {
-		sp->fts_options |= FTS_NAMEONLY;
-		instr = BNAMES;
-	} else 
-		instr = BCHILD;
+	register FTSENT **ap, *p;
 
 	/*
-	 * If using chdir on a relative path and called BEFORE fts_read does
-	 * its chdir to the root of a traversal, we can lose -- we need to
-	 * chdir into the subdirectory, and we don't know where the current
-	 * directory is, so we can't get back so that the upcoming chdir by
-	 * fts_read will work.
+	 * Construct an array of pointers to the structures and call qsort(3).
+	 * Reassemble the array in the order returned by qsort.  If unable to
+	 * sort for memory reasons, return the directory entries in their
+	 * current order.  Allocate enough space for the current needs plus
+	 * 40 so don't realloc one entry at a time.
 	 */
-	if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
-	    ISSET(FTS_NOCHDIR))
-		return (sp->fts_child = fts_build(sp, instr));
-
-	if ((fd = open(".", O_RDONLY, 0)) < 0)
-		return (NULL);
-	sp->fts_child = fts_build(sp, instr);
-	if (fchdir(fd))
-		return (NULL);
-	(void)close(fd);
-	return (sp->fts_child);
+	if (nitems > sp->fts_nitems) {
+		sp->fts_nitems = nitems + 40;
+		if ((sp->fts_array = realloc(sp->fts_array,
+		    (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
+			sp->fts_nitems = 0;
+			return (head);
+		}
+	}
+	for (ap = sp->fts_array, p = head; p; p = p->fts_link)
+		*ap++ = p;
+	qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
+	for (head = *(ap = sp->fts_array); --nitems; ++ap)
+		ap[0]->fts_link = ap[1];
+	ap[0]->fts_link = NULL;
+	return (head);
 }
 
 /*
@@ -551,9 +320,7 @@ fts_children(sp, instr)
  * been found, cutting the stat calls by about 2/3.
  */
 static FTSENT *
-fts_build(sp, type)
-	register FTS *sp;
-	int type;
+fts_build(register FTS *sp, int type)
 {
 	register struct dirent *dp;
 	register FTSENT *p, *head;
@@ -716,283 +483,479 @@ mem1:				saved_errno = errno;
 				--nlinks;
 		}
 
-		/* We walk in directory order so "ls -f" doesn't get upset. */
-		p->fts_link = NULL;
-		if (head == NULL)
-			head = tail = p;
-		else {
-			tail->fts_link = p;
-			tail = p;
+		/* We walk in directory order so "ls -f" doesn't get upset. */
+		p->fts_link = NULL;
+		if (head == NULL)
+			head = tail = p;
+		else {
+			tail->fts_link = p;
+			tail = p;
+		}
+		++nitems;
+	}
+	(void)closedir(dirp);
+
+	/*
+	 * If had to realloc the path, adjust the addresses for the rest
+	 * of the tree.
+	 */
+	if (adjaddr)
+		fts_padjust(sp, adjaddr);
+
+	/*
+	 * If not changing directories, reset the path back to original
+	 * state.
+	 */
+	if (ISSET(FTS_NOCHDIR)) {
+		if (cp - 1 > sp->fts_path)
+			--cp;
+		*cp = '\0';
+	}
+
+	/*
+	 * If descended after called from fts_children or after called from
+	 * fts_read and nothing found, get back.  At the root level we use
+	 * the saved fd; if one of fts_open()'s arguments is a relative path
+	 * to an empty directory, we wind up here with no other way back.  If
+	 * can't get back, we're done.
+	 */
+	if (descend && (type == BCHILD || !nitems) &&
+	    (cur->fts_level == FTS_ROOTLEVEL ?
+	    FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+		cur->fts_info = FTS_ERR;
+		SET(FTS_STOP);
+		return (NULL);
+	}
+
+	/* If didn't find anything, return NULL. */
+	if (!nitems) {
+		if (type == BREAD)
+			cur->fts_info = FTS_DP;
+		return (NULL);
+	}
+
+	/* Sort the entries. */
+	if (sp->fts_compar && nitems > 1)
+		head = fts_sort(sp, head, nitems);
+	return (head);
+}
+
+
+FTS *
+fts_open(char * const *argv, register int options, int (*compar)())
+{
+	register FTS *sp;
+	register FTSENT *p, *root;
+	register int nitems;
+	FTSENT *parent, *tmp;
+	int len;
+
+	/* Options check. */
+	if (options & ~FTS_OPTIONMASK) {
+		errno = EINVAL;
+		return (NULL);
+	}
+
+	/* Allocate/initialize the stream */
+	if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
+		return (NULL);
+	memset(sp, 0, sizeof(FTS));
+	sp->fts_compar = compar;
+	sp->fts_options = options;
+
+	/* Logical walks turn on NOCHDIR; symbolic links are too hard. */
+	if (ISSET(FTS_LOGICAL))
+		SET(FTS_NOCHDIR);
+
+	/*
+	 * Start out with 1K of path space, and enough, in any case,
+	 * to hold the user's paths.
+	 */
+	if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
+		goto mem1;
+
+	/* Allocate/initialize root's parent. */
+	if ((parent = fts_alloc(sp, "", 0)) == NULL)
+		goto mem2;
+	parent->fts_level = FTS_ROOTPARENTLEVEL;
+
+	/* Allocate/initialize root(s). */
+	for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
+		/* Don't allow zero-length paths. */
+		if ((len = strlen(*argv)) == 0) {
+			errno = EINVAL;
+			goto mem3;
+		}
+
+		p = fts_alloc(sp, *argv, len);
+		p->fts_level = FTS_ROOTLEVEL;
+		p->fts_parent = parent;
+		p->fts_accpath = p->fts_name;
+		p->fts_info = fts_stat(sp, NULL, p, ISSET(FTS_COMFOLLOW));
+
+		/* Command-line "." and ".." are real directories. */
+		if (p->fts_info == FTS_DOT)
+			p->fts_info = FTS_D;
+
+		/*
+		 * If comparison routine supplied, traverse in sorted
+		 * order; otherwise traverse in the order specified.
+		 */
+		if (compar) {
+			p->fts_link = root;
+			root = p;
+		} else {
+			p->fts_link = NULL;
+			if (root == NULL)
+				tmp = root = p;
+			else {
+				tmp->fts_link = p;
+				tmp = p;
+			}
 		}
-		++nitems;
 	}
-	(void)closedir(dirp);
-
-	/*
-	 * If had to realloc the path, adjust the addresses for the rest
-	 * of the tree.
-	 */
-	if (adjaddr)
-		fts_padjust(sp, adjaddr);
+	if (compar && nitems > 1)
+		root = fts_sort(sp, root, nitems);
 
 	/*
-	 * If not changing directories, reset the path back to original
-	 * state.
+	 * Allocate a dummy pointer and make fts_read think that we've just
+	 * finished the node before the root(s); set p->fts_info to FTS_INIT
+	 * so that everything about the "current" node is ignored.
 	 */
-	if (ISSET(FTS_NOCHDIR)) {
-		if (cp - 1 > sp->fts_path)
-			--cp;
-		*cp = '\0';
-	}
+	if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
+		goto mem3;
+	sp->fts_cur->fts_link = root;
+	sp->fts_cur->fts_info = FTS_INIT;
 
 	/*
-	 * If descended after called from fts_children or after called from
-	 * fts_read and nothing found, get back.  At the root level we use
-	 * the saved fd; if one of fts_open()'s arguments is a relative path
-	 * to an empty directory, we wind up here with no other way back.  If
-	 * can't get back, we're done.
+	 * If using chdir(2), grab a file descriptor pointing to dot to insure
+	 * that we can get back here; this could be avoided for some paths,
+	 * but almost certainly not worth the effort.  Slashes, symbolic links,
+	 * and ".." are all fairly nasty problems.  Note, if we can't get the
+	 * descriptor we run anyway, just more slowly.
 	 */
-	if (descend && (type == BCHILD || !nitems) &&
-	    (cur->fts_level == FTS_ROOTLEVEL ?
-	    FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
-		cur->fts_info = FTS_ERR;
-		SET(FTS_STOP);
-		return (NULL);
-	}
+	if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
+		SET(FTS_NOCHDIR);
 
-	/* If didn't find anything, return NULL. */
-	if (!nitems) {
-		if (type == BREAD)
-			cur->fts_info = FTS_DP;
-		return (NULL);
-	}
+	return (sp);
 
-	/* Sort the entries. */
-	if (sp->fts_compar && nitems > 1)
-		head = fts_sort(sp, head, nitems);
-	return (head);
+mem3:	fts_lfree(root);
+	free(parent);
+mem2:	free(sp->fts_path);
+mem1:	free(sp);
+	return (NULL);
 }
 
-static u_short
-fts_stat(sp, dp, p, follow)
-	FTS *sp;
-	register FTSENT *p;
-	struct dirent *dp;
-	int follow;
+FTSENT *
+fts_read(register FTS *sp)
 {
-	register FTSENT *t;
-	register dev_t dev;
-	register ino_t ino;
-	struct stat *sbp, sb;
+	register FTSENT *p, *tmp;
+	register int instr;
+	register char *t;
 	int saved_errno;
 
-	/* If user needs stat info, stat buffer already allocated. */
-	sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
+	/* If finished or unrecoverable error, return NULL. */
+	if (sp->fts_cur == NULL || ISSET(FTS_STOP))
+		return (NULL);
 
-#ifdef S_IFWHT
-	/*
-	 * Whited-out files don't really exist.  However, there's stat(2) file
-	 * mask for them, so we set it so that programs (i.e., find) don't have
-	 * to test FTS_W separately from other file types.
-	 */
-	if (dp != NULL && dp->d_type == DT_WHT) {
-		memset(sbp, 0, sizeof(struct stat));
-		sbp->st_mode = S_IFWHT;
-		return (FTS_W);
+	/* Set current node pointer. */
+	p = sp->fts_cur;
+
+	/* Save and zero out user instructions. */
+	instr = p->fts_instr;
+	p->fts_instr = FTS_NOINSTR;
+
+	/* Any type of file may be re-visited; re-stat and re-turn. */
+	if (instr == FTS_AGAIN) {
+		p->fts_info = fts_stat(sp, NULL, p, 0);
+		return (p);
 	}
-#endif
-	
+
 	/*
-	 * If doing a logical walk, or application requested FTS_FOLLOW, do
-	 * a stat(2).  If that fails, check for a non-existent symlink.  If
-	 * fail, set the errno from the stat call.
+	 * Following a symlink -- SLNONE test allows application to see
+	 * SLNONE and recover.  If indirecting through a symlink, have
+	 * keep a pointer to current location.  If unable to get that
+	 * pointer, follow fails.
 	 */
-	if (ISSET(FTS_LOGICAL) || follow) {
-		if (stat(p->fts_accpath, sbp)) {
-			saved_errno = errno;
-			if (!lstat(p->fts_accpath, sbp)) {
-				errno = 0;
-				return (FTS_SLNONE);
-			} 
-			p->fts_errno = saved_errno;
-			goto err;
+	if (instr == FTS_FOLLOW &&
+	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
+		p->fts_info = fts_stat(sp, NULL, p, 1);
+		if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR))
+			if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
+				p->fts_errno = errno;
+				p->fts_info = FTS_ERR;
+			} else
+				p->fts_flags |= FTS_SYMFOLLOW;
+		return (p);
+	}
+
+	/* Directory in pre-order. */
+	if (p->fts_info == FTS_D) {
+		/* If skipped or crossed mount point, do post-order visit. */
+		if (instr == FTS_SKIP ||
+		    ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) {
+			if (p->fts_flags & FTS_SYMFOLLOW)
+				(void)close(p->fts_symfd);
+			if (sp->fts_child) {
+				fts_lfree(sp->fts_child);
+				sp->fts_child = NULL;
+			}
+			p->fts_info = FTS_DP;
+			return (p);
 		}
-	} else if (lstat(p->fts_accpath, sbp)) {
-		p->fts_errno = errno;
-err:		memset(sbp, 0, sizeof(struct stat));
-		return (FTS_NS);
+
+		/* Rebuild if only read the names and now traversing. */
+		if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) {
+			sp->fts_options &= ~FTS_NAMEONLY;
+			fts_lfree(sp->fts_child);
+			sp->fts_child = NULL;
+		}
+
+		/*
+		 * Cd to the subdirectory.
+		 *
+		 * If have already read and now fail to chdir, whack the list
+		 * to make the names come out right, and set the parent errno
+		 * so the application will eventually get an error condition.
+		 * Set the FTS_DONTCHDIR flag so that when we logically change
+		 * directories back to the parent we don't do a chdir.
+		 *
+		 * If haven't read do so.  If the read fails, fts_build sets
+		 * FTS_STOP or the fts_info field of the node.
+		 */
+		if (sp->fts_child) {
+			if (CHDIR(sp, p->fts_accpath)) {
+				p->fts_errno = errno;
+				p->fts_flags |= FTS_DONTCHDIR;
+				for (p = sp->fts_child; p; p = p->fts_link)
+					p->fts_accpath =
+					    p->fts_parent->fts_accpath;
+			}
+		} else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
+			if (ISSET(FTS_STOP))
+				return (NULL);
+			return (p);
+		}
+		p = sp->fts_child;
+		sp->fts_child = NULL;
+		goto name;
 	}
 
-	if (S_ISDIR(sbp->st_mode)) {
+	/* Move to the next node on this level. */
+next:	tmp = p;
+	if (p = p->fts_link) {
+		free(tmp);
+
 		/*
-		 * Set the device/inode.  Used to find cycles and check for
-		 * crossing mount points.  Also remember the link count, used
-		 * in fts_build to limit the number of stat calls.  It is
-		 * understood that these fields are only referenced if fts_info
-		 * is set to FTS_D.
+		 * If reached the top, return to the original directory, and
+		 * load the paths for the next root.
 		 */
-		dev = p->fts_dev = sbp->st_dev;
-		ino = p->fts_ino = sbp->st_ino;
-		p->fts_nlink = sbp->st_nlink;
+		if (p->fts_level == FTS_ROOTLEVEL) {
+			if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) {
+				SET(FTS_STOP);
+				return (NULL);
+			}
+			fts_load(sp, p);
+			return (sp->fts_cur = p);
+		}
+
+		/*
+		 * User may have called fts_set on the node.  If skipped,
+		 * ignore.  If followed, get a file descriptor so we can
+		 * get back if necessary.
+		 */
+		if (p->fts_instr == FTS_SKIP)
+			goto next;
+		if (p->fts_instr == FTS_FOLLOW) {
+			p->fts_info = fts_stat(sp, NULL, p, 1);
+			if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR))
+				if ((p->fts_symfd =
+				    open(".", O_RDONLY, 0)) < 0) {
+					p->fts_errno = errno;
+					p->fts_info = FTS_ERR;
+				} else
+					p->fts_flags |= FTS_SYMFOLLOW;
+			p->fts_instr = FTS_NOINSTR;
+		}
 
-		if (ISDOT(p->fts_name))
-			return (FTS_DOT);
+name:		t = sp->fts_path + NAPPEND(p->fts_parent);
+		*t++ = '/';
+		memmove(t, p->fts_name, p->fts_namelen + 1);
+		return (sp->fts_cur = p);
+	}
 
+	/* Move up to the parent node. */
+	p = tmp->fts_parent;
+	free(tmp);
+
+	if (p->fts_level == FTS_ROOTPARENTLEVEL) {
 		/*
-		 * Cycle detection is done by brute force when the directory
-		 * is first encountered.  If the tree gets deep enough or the
-		 * number of symbolic links to directories is high enough,
-		 * something faster might be worthwhile.
+		 * Done; free everything up and set errno to 0 so the user
+		 * can distinguish between error and EOF.
 		 */
-		for (t = p->fts_parent;
-		    t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
-			if (ino == t->fts_ino && dev == t->fts_dev) {
-				p->fts_cycle = t;
-				return (FTS_DC);
-			}
-		return (FTS_D);
+		free(p);
+		errno = 0;
+		return (sp->fts_cur = NULL);
 	}
-	if (S_ISLNK(sbp->st_mode))
-		return (FTS_SL);
-	if (S_ISREG(sbp->st_mode))
-		return (FTS_F);
-	return (FTS_DEFAULT);
-}
 
-static FTSENT *
-fts_sort(sp, head, nitems)
-	FTS *sp;
-	FTSENT *head;
-	register int nitems;
-{
-	register FTSENT **ap, *p;
+	/* Nul terminate the pathname. */
+	sp->fts_path[p->fts_pathlen] = '\0';
 
 	/*
-	 * Construct an array of pointers to the structures and call qsort(3).
-	 * Reassemble the array in the order returned by qsort.  If unable to
-	 * sort for memory reasons, return the directory entries in their
-	 * current order.  Allocate enough space for the current needs plus
-	 * 40 so don't realloc one entry at a time.
+	 * Return to the parent directory.  If at a root node or came through
+	 * a symlink, go back through the file descriptor.  Otherwise, cd up
+	 * one directory.
 	 */
-	if (nitems > sp->fts_nitems) {
-		sp->fts_nitems = nitems + 40;
-		if ((sp->fts_array = realloc(sp->fts_array,
-		    (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
-			sp->fts_nitems = 0;
-			return (head);
+	if (p->fts_level == FTS_ROOTLEVEL) {
+		if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) {
+			SET(FTS_STOP);
+			return (NULL);
+		}
+	} else if (p->fts_flags & FTS_SYMFOLLOW) {
+		if (FCHDIR(sp, p->fts_symfd)) {
+			saved_errno = errno;
+			(void)close(p->fts_symfd);
+			errno = saved_errno;
+			SET(FTS_STOP);
+			return (NULL);
+		}
+		(void)close(p->fts_symfd);
+	} else if (!(p->fts_flags & FTS_DONTCHDIR)) {
+		if (CHDIR(sp, "..")) {
+			SET(FTS_STOP);
+			return (NULL);
 		}
 	}
-	for (ap = sp->fts_array, p = head; p; p = p->fts_link)
-		*ap++ = p;
-	qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
-	for (head = *(ap = sp->fts_array); --nitems; ++ap)
-		ap[0]->fts_link = ap[1];
-	ap[0]->fts_link = NULL;
-	return (head);
+	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
+	return (sp->fts_cur = p);
 }
 
-static FTSENT *
-fts_alloc(sp, name, namelen)
-	FTS *sp;
-	char *name;
-	register int namelen;
+/*
+ * Fts_set takes the stream as an argument although it's not used in this
+ * implementation; it would be necessary if anyone wanted to add global
+ * semantics to fts using fts_set.  An error return is allowed for similar
+ * reasons.
+ */
+/* ARGSUSED */
+int
+fts_set(FTS *sp, FTSENT *p, int instr)
+{
+	if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
+	    instr != FTS_NOINSTR && instr != FTS_SKIP) {
+		errno = EINVAL;
+		return (1);
+	}
+	p->fts_instr = instr;
+	return (0);
+}
+
+FTSENT *
+fts_children(register FTS *sp, int instr)
 {
 	register FTSENT *p;
-	size_t len;
+	int fd;
+
+	if (instr && instr != FTS_NAMEONLY) {
+		errno = EINVAL;
+		return (NULL);
+	}
+
+	/* Set current node pointer. */
+	p = sp->fts_cur;
 
 	/*
-	 * The file name is a variable length array and no stat structure is
-	 * necessary if the user has set the nostat bit.  Allocate the FTSENT
-	 * structure, the file name and the stat structure in one chunk, but
-	 * be careful that the stat structure is reasonably aligned.  Since the
-	 * fts_name field is declared to be of size 1, the fts_name pointer is
-	 * namelen + 2 before the first possible address of the stat structure.
+	 * Errno set to 0 so user can distinguish empty directory from
+	 * an error.
 	 */
-	len = sizeof(FTSENT) + namelen;
-	if (!ISSET(FTS_NOSTAT))
-		len += sizeof(struct stat) + ALIGNBYTES;
-	if ((p = malloc(len)) == NULL)
+	errno = 0;
+
+	/* Fatal errors stop here. */
+	if (ISSET(FTS_STOP))
 		return (NULL);
 
-	/* Copy the name plus the trailing NULL. */
-	memmove(p->fts_name, name, namelen + 1);
+	/* Return logical hierarchy of user's arguments. */
+	if (p->fts_info == FTS_INIT)
+		return (p->fts_link);
 
-	if (!ISSET(FTS_NOSTAT))
-		p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
-	p->fts_namelen = namelen;
-	p->fts_path = sp->fts_path;
-	p->fts_errno = 0;
-	p->fts_flags = 0;
-	p->fts_instr = FTS_NOINSTR;
-	p->fts_number = 0;
-	p->fts_pointer = NULL;
-	return (p);
+	/*
+	 * If not a directory being visited in pre-order, stop here.  Could
+	 * allow FTS_DNR, assuming the user has fixed the problem, but the
+	 * same effect is available with FTS_AGAIN.
+	 */
+	if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
+		return (NULL);
+
+	/* Free up any previous child list. */
+	if (sp->fts_child)
+		fts_lfree(sp->fts_child);
+
+	if (instr == FTS_NAMEONLY) {
+		sp->fts_options |= FTS_NAMEONLY;
+		instr = BNAMES;
+	} else
+		instr = BCHILD;
+
+	/*
+	 * If using chdir on a relative path and called BEFORE fts_read does
+	 * its chdir to the root of a traversal, we can lose -- we need to
+	 * chdir into the subdirectory, and we don't know where the current
+	 * directory is, so we can't get back so that the upcoming chdir by
+	 * fts_read will work.
+	 */
+	if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
+	    ISSET(FTS_NOCHDIR))
+		return (sp->fts_child = fts_build(sp, instr));
+
+	if ((fd = open(".", O_RDONLY, 0)) < 0)
+		return (NULL);
+	sp->fts_child = fts_build(sp, instr);
+	if (fchdir(fd))
+		return (NULL);
+	(void)close(fd);
+	return (sp->fts_child);
 }
 
-static void
-fts_lfree(head)
-	register FTSENT *head;
+int
+fts_close(FTS *sp)
 {
-	register FTSENT *p;
+	register FTSENT *freep, *p;
+	int saved_errno;
 
-	/* Free a linked list of structures. */
-	while (p = head) {
-		head = head->fts_link;
+	/*
+	 * This still works if we haven't read anything -- the dummy structure
+	 * points to the root list, so we step through to the end of the root
+	 * list which has a valid parent pointer.
+	 */
+	if (sp->fts_cur) {
+		for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
+			freep = p;
+			p = p->fts_link ? p->fts_link : p->fts_parent;
+			free(freep);
+		}
 		free(p);
 	}
-}
 
-/*
- * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
- * Most systems will allow creation of paths much longer than MAXPATHLEN, even
- * though the kernel won't resolve them.  Add the size (not just what's needed)
- * plus 256 bytes so don't realloc the path 2 bytes at a time. 
- */
-static int
-fts_palloc(sp, more)
-	FTS *sp;
-	size_t more;
-{
-	sp->fts_pathlen += more + 256;
-	sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen);
-	return (sp->fts_path == NULL);
-}
+	/* Free up child linked list, sort array, path buffer. */
+	if (sp->fts_child)
+		fts_lfree(sp->fts_child);
+	if (sp->fts_array)
+		free(sp->fts_array);
+	free(sp->fts_path);
 
-/*
- * When the path is realloc'd, have to fix all of the pointers in structures
- * already returned.
- */
-static void
-fts_padjust(sp, addr)
-	FTS *sp;
-	void *addr;
-{
-	FTSENT *p;
+	/* Return to original directory, save errno if necessary. */
+	if (!ISSET(FTS_NOCHDIR)) {
+		saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
+		(void)close(sp->fts_rfd);
+	}
 
-#define	ADJUST(p) {							\
-	(p)->fts_accpath =						\
-	    (char *)addr + ((p)->fts_accpath - (p)->fts_path);		\
-	(p)->fts_path = addr;						\
-}
-	/* Adjust the current set of children. */
-	for (p = sp->fts_child; p; p = p->fts_link)
-		ADJUST(p);
+	/* Free up the stream pointer. */
+	free(sp);
 
-	/* Adjust the rest of the tree. */
-	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
-		ADJUST(p);
-		p = p->fts_link ? p->fts_link : p->fts_parent;
+	/* Set errno and return. */
+	if (!ISSET(FTS_NOCHDIR) && saved_errno) {
+		errno = saved_errno;
+		return (-1);
 	}
+	return (0);
 }
 
-static size_t
-fts_maxarglen(argv)
-	char * const *argv;
-{
-	size_t len, max;
-
-	for (max = 0; *argv; ++argv)
-		if ((len = strlen(*argv)) > max)
-			max = len;
-	return (max);
-}
