15e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich/* $NetBSD: ftw.c,v 1.1 2005/12/30 23:07:32 agc Exp $ */
25e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
35e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich/*	From OpenBSD: ftw.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#include <sys/cdefs.h>
255e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
265e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#ifndef lint
275e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich__RCSID("$NetBSD: ftw.c,v 1.1 2005/12/30 23:07:32 agc Exp $");
285e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#endif
295e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
305e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <sys/types.h>
315e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <sys/stat.h>
325e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <errno.h>
335e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <fts.h>
345e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <ftw.h>
355e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich#include <limits.h>
365e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
375e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevichint
385e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevichftw(const char *path, int (*fn)(const char *, const struct stat *, int),
395e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich    int nfds)
405e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich{
415e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	/* LINTED */
425e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	char * const paths[2] = { __UNCONST(path), NULL };
435e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	FTSENT *cur;
445e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	FTS *ftsp;
455e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	int fnflag, error, sverrno;
465e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
475e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	/* XXX - nfds is currently unused */
485e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (nfds < 1 || nfds > OPEN_MAX) {
495e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		errno = EINVAL;
505e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		return (-1);
515e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	}
525e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich
535e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	ftsp = fts_open(paths, FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
545e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (ftsp == NULL)
555e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		return (-1);
565e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	error = 0;
575e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	while ((cur = fts_read(ftsp)) != NULL) {
585e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		switch (cur->fts_info) {
595e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_D:
605e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_D;
615e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
625e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DNR:
635e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_DNR;
645e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
655e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DP:
665e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			/* we only visit in preorder */
675e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			continue;
685e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_F:
695e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DEFAULT:
705e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_F;
715e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
725e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_NS:
735e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_NSOK:
745e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_SLNONE:
755e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_NS;
765e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
775e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_SL:
785e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			fnflag = FTW_SL;
795e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
805e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		case FTS_DC:
815e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			errno = ELOOP;
825e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			/* FALLTHROUGH */
835e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		default:
845e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			error = -1;
855e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			goto done;
865e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		}
875e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		error = fn(cur->fts_path, cur->fts_statp, fnflag);
885e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		if (error != 0)
895e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich			break;
905e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	}
915e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevichdone:
925e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	sverrno = errno;
935e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	if (fts_close(ftsp) != 0 && error == 0)
945e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		error = -1;
955e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	else
965e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich		errno = sverrno;
975e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich	return (error);
985e58ea07d47c175abf8285ff67e3e9bc0b3a9e8eNick Kralevich}
99