169921123SKonstantin Belousov /*
269921123SKonstantin Belousov * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
369921123SKonstantin Belousov *
469921123SKonstantin Belousov * Permission to use, copy, modify, and distribute this software for any
569921123SKonstantin Belousov * purpose with or without fee is hereby granted, provided that the above
669921123SKonstantin Belousov * copyright notice and this permission notice appear in all copies.
769921123SKonstantin Belousov *
869921123SKonstantin Belousov * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
969921123SKonstantin Belousov * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1069921123SKonstantin Belousov * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1169921123SKonstantin Belousov * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1269921123SKonstantin Belousov * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1369921123SKonstantin Belousov * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1469921123SKonstantin Belousov * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1569921123SKonstantin Belousov *
1669921123SKonstantin Belousov * Sponsored in part by the Defense Advanced Research Projects
1769921123SKonstantin Belousov * Agency (DARPA) and Air Force Research Laboratory, Air Force
1869921123SKonstantin Belousov * Materiel Command, USAF, under agreement number F39502-99-1-0512.
1969921123SKonstantin Belousov *
20*c1920558SJohn Baldwin * From: $OpenBSD: nftw.c,v 1.7 2006/03/31 19:41:44 millert Exp $
21*c1920558SJohn Baldwin * From: FreeBSD: head/lib/libc/gen/nftw.c 239160 2012-08-09 22:05:40Z jilles
2269921123SKonstantin Belousov */
2369921123SKonstantin Belousov
2469921123SKonstantin Belousov #include <sys/types.h>
2569921123SKonstantin Belousov #include <sys/stat.h>
2669921123SKonstantin Belousov #include <errno.h>
2769921123SKonstantin Belousov #include <fts.h>
2869921123SKonstantin Belousov #include <ftw.h>
2969921123SKonstantin Belousov
3069921123SKonstantin Belousov #include "fts-compat11.h"
3169921123SKonstantin Belousov
3269921123SKonstantin Belousov int
freebsd11_nftw(const char * path,int (* fn)(const char *,const struct freebsd11_stat *,int,struct FTW *),int nfds,int ftwflags)3369921123SKonstantin Belousov freebsd11_nftw(const char *path,
3469921123SKonstantin Belousov int (*fn)(const char *, const struct freebsd11_stat *, int, struct FTW *),
3569921123SKonstantin Belousov int nfds, int ftwflags)
3669921123SKonstantin Belousov {
3769921123SKonstantin Belousov char * const paths[2] = { (char *)path, NULL };
3869921123SKonstantin Belousov struct FTW ftw;
3969921123SKonstantin Belousov FTSENT11 *cur;
4069921123SKonstantin Belousov FTS11 *ftsp;
4169921123SKonstantin Belousov int error = 0, ftsflags, fnflag, postorder, sverrno;
4269921123SKonstantin Belousov
4369921123SKonstantin Belousov /* XXX - nfds is currently unused */
4469921123SKonstantin Belousov if (nfds < 1) {
4569921123SKonstantin Belousov errno = EINVAL;
4669921123SKonstantin Belousov return (-1);
4769921123SKonstantin Belousov }
4869921123SKonstantin Belousov
4969921123SKonstantin Belousov ftsflags = FTS_COMFOLLOW;
5069921123SKonstantin Belousov if (!(ftwflags & FTW_CHDIR))
5169921123SKonstantin Belousov ftsflags |= FTS_NOCHDIR;
5269921123SKonstantin Belousov if (ftwflags & FTW_MOUNT)
5369921123SKonstantin Belousov ftsflags |= FTS_XDEV;
5469921123SKonstantin Belousov if (ftwflags & FTW_PHYS)
5569921123SKonstantin Belousov ftsflags |= FTS_PHYSICAL;
5669921123SKonstantin Belousov else
5769921123SKonstantin Belousov ftsflags |= FTS_LOGICAL;
5869921123SKonstantin Belousov postorder = (ftwflags & FTW_DEPTH) != 0;
5969921123SKonstantin Belousov ftsp = freebsd11_fts_open(paths, ftsflags, NULL);
6069921123SKonstantin Belousov if (ftsp == NULL)
6169921123SKonstantin Belousov return (-1);
6269921123SKonstantin Belousov while ((cur = freebsd11_fts_read(ftsp)) != NULL) {
6369921123SKonstantin Belousov switch (cur->fts_info) {
6469921123SKonstantin Belousov case FTS_D:
6569921123SKonstantin Belousov if (postorder)
6669921123SKonstantin Belousov continue;
6769921123SKonstantin Belousov fnflag = FTW_D;
6869921123SKonstantin Belousov break;
6969921123SKonstantin Belousov case FTS_DC:
7069921123SKonstantin Belousov continue;
7169921123SKonstantin Belousov case FTS_DNR:
7269921123SKonstantin Belousov fnflag = FTW_DNR;
7369921123SKonstantin Belousov break;
7469921123SKonstantin Belousov case FTS_DP:
7569921123SKonstantin Belousov if (!postorder)
7669921123SKonstantin Belousov continue;
7769921123SKonstantin Belousov fnflag = FTW_DP;
7869921123SKonstantin Belousov break;
7969921123SKonstantin Belousov case FTS_F:
8069921123SKonstantin Belousov case FTS_DEFAULT:
8169921123SKonstantin Belousov fnflag = FTW_F;
8269921123SKonstantin Belousov break;
8369921123SKonstantin Belousov case FTS_NS:
8469921123SKonstantin Belousov case FTS_NSOK:
8569921123SKonstantin Belousov fnflag = FTW_NS;
8669921123SKonstantin Belousov break;
8769921123SKonstantin Belousov case FTS_SL:
8869921123SKonstantin Belousov fnflag = FTW_SL;
8969921123SKonstantin Belousov break;
9069921123SKonstantin Belousov case FTS_SLNONE:
9169921123SKonstantin Belousov fnflag = FTW_SLN;
9269921123SKonstantin Belousov break;
9369921123SKonstantin Belousov default:
9469921123SKonstantin Belousov error = -1;
9569921123SKonstantin Belousov goto done;
9669921123SKonstantin Belousov }
9769921123SKonstantin Belousov ftw.base = cur->fts_pathlen - cur->fts_namelen;
9869921123SKonstantin Belousov ftw.level = cur->fts_level;
9969921123SKonstantin Belousov error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw);
10069921123SKonstantin Belousov if (error != 0)
10169921123SKonstantin Belousov break;
10269921123SKonstantin Belousov }
10369921123SKonstantin Belousov done:
10469921123SKonstantin Belousov sverrno = errno;
10569921123SKonstantin Belousov if (freebsd11_fts_close(ftsp) != 0 && error == 0)
10669921123SKonstantin Belousov error = -1;
10769921123SKonstantin Belousov else
10869921123SKonstantin Belousov errno = sverrno;
10969921123SKonstantin Belousov return (error);
11069921123SKonstantin Belousov }
11169921123SKonstantin Belousov
11269921123SKonstantin Belousov __sym_compat(nftw, freebsd11_nftw, FBSD_1.0);
113