15e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich/* $NetBSD */
25e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
35e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich/*	From OpenBSD: nftw.c,v 1.2 2003/07/21 21:15:32 millert Exp 	*/
45e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
55e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich/*
65e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
75e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich *
85e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * Permission to use, copy, modify, and distribute this software for any
95e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * purpose with or without fee is hereby granted, provided that the above
105e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * copyright notice and this permission notice appear in all copies.
115e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich *
125e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
135e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
145e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
155e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
165e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
175e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
185e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
195e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich *
205e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * Sponsored in part by the Defense Advanced Research Projects
215e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * Agency (DARPA) and Air Force Research Laboratory, Air Force
225e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich * Materiel Command, USAF, under agreement number F39502-99-1-0512.
235e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich */
245e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
255e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <sys/cdefs.h>
265e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
275e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#ifndef lint
285e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich__RCSID("$NetBSD: nftw.c,v 1.1 2005/12/30 23:07:32 agc Exp $");
295e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#endif
305e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
315e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <sys/types.h>
325e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <sys/stat.h>
335e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <errno.h>
345e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <fts.h>
355e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <ftw.h>
365e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <limits.h>
375e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
385e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevichint
395e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevichnftw(const char *path, int (*fn)(const char *, const struct stat *, int,
405e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich     struct FTW *), int nfds, int ftwflags)
415e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich{
425e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	/* LINTED */
435e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	char * const paths[2] = { __UNCONST(path), NULL };
445e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	struct FTW f;
455e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	FTSENT *cur;
465e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	FTS *ftsp;
475e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	int ftsflags, fnflag, error, postorder, sverrno;
485e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
495e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	/* XXX - nfds is currently unused */
505e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (nfds < 1 || nfds > OPEN_MAX) {
515e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		errno = EINVAL;
525e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		return (-1);
535e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	}
545e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
555e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	ftsflags = FTS_COMFOLLOW;
565e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (!(ftwflags & FTW_CHDIR))
575e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		ftsflags |= FTS_NOCHDIR;
585e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (ftwflags & FTW_MOUNT)
595e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		ftsflags |= FTS_XDEV;
605e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (ftwflags & FTW_PHYS)
615e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		ftsflags |= FTS_PHYSICAL;
625e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	postorder = (ftwflags & FTW_DEPTH) != 0;
635e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	ftsp = fts_open(paths, ftsflags, NULL);
645e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (ftsp == NULL)
655e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		return (-1);
665e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	error = 0;
675e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	while ((cur = fts_read(ftsp)) != NULL) {
685e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		switch (cur->fts_info) {
695e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_D:
705e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			if (postorder)
715e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich				continue;
725e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_D;
735e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
745e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DNR:
755e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_DNR;
765e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
775e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DP:
785e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			if (!postorder)
795e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich				continue;
805e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_DP;
815e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
825e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_F:
835e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DEFAULT:
845e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_F;
855e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
865e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_NS:
875e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_NSOK:
885e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_NS;
895e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
905e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_SL:
915e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_SL;
925e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
935e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_SLNONE:
945e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_SLN;
955e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
965e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DC:
975e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			errno = ELOOP;
985e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			/* FALLTHROUGH */
995e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		default:
1005e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			error = -1;
1015e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			goto done;
1025e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		}
1035e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		f.base = cur->fts_pathlen - cur->fts_namelen;
1045e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		f.level = cur->fts_level;
1055e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		error = fn(cur->fts_path, cur->fts_statp, fnflag, &f);
1065e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		if (error != 0)
1075e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
1085e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	}
1095e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevichdone:
1105e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	sverrno = errno;
1115e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	(void) fts_close(ftsp);
1125e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	errno = sverrno;
1135e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	return (error);
1145e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich}
115