1*bf198cc6Smillert /* $OpenBSD: ftw.c,v 1.6 2019/01/25 00:19:25 millert Exp $ */
29c72459dSmillert
39c72459dSmillert /*
4*bf198cc6Smillert * Copyright (c) 2003, 2004 Todd C. Miller <millert@openbsd.org>
59c72459dSmillert *
6f5f7ab2eSmillert * Permission to use, copy, modify, and distribute this software for any
7f5f7ab2eSmillert * purpose with or without fee is hereby granted, provided that the above
8f5f7ab2eSmillert * copyright notice and this permission notice appear in all copies.
99c72459dSmillert *
10f5f7ab2eSmillert * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11f5f7ab2eSmillert * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12f5f7ab2eSmillert * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13f5f7ab2eSmillert * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f5f7ab2eSmillert * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f5f7ab2eSmillert * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f5f7ab2eSmillert * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17f5f7ab2eSmillert *
18f5f7ab2eSmillert * Sponsored in part by the Defense Advanced Research Projects
19f5f7ab2eSmillert * Agency (DARPA) and Air Force Research Laboratory, Air Force
20f5f7ab2eSmillert * Materiel Command, USAF, under agreement number F39502-99-1-0512.
219c72459dSmillert */
229c72459dSmillert
239c72459dSmillert #include <sys/types.h>
249c72459dSmillert #include <sys/stat.h>
259c72459dSmillert #include <errno.h>
269c72459dSmillert #include <fts.h>
279c72459dSmillert #include <ftw.h>
289c72459dSmillert #include <limits.h>
299c72459dSmillert
309c72459dSmillert int
ftw(const char * path,int (* fn)(const char *,const struct stat *,int),int nfds)319c72459dSmillert ftw(const char *path, int (*fn)(const char *, const struct stat *, int),
329c72459dSmillert int nfds)
339c72459dSmillert {
34c1e28e31Smillert char * const paths[2] = { (char *)path, NULL };
359c72459dSmillert FTSENT *cur;
369c72459dSmillert FTS *ftsp;
37c1e28e31Smillert int error = 0, fnflag, sverrno;
389c72459dSmillert
399c72459dSmillert /* XXX - nfds is currently unused */
409c72459dSmillert if (nfds < 1 || nfds > OPEN_MAX) {
419c72459dSmillert errno = EINVAL;
429c72459dSmillert return (-1);
439c72459dSmillert }
449c72459dSmillert
45c1e28e31Smillert ftsp = fts_open(paths, FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
469c72459dSmillert if (ftsp == NULL)
479c72459dSmillert return (-1);
489c72459dSmillert while ((cur = fts_read(ftsp)) != NULL) {
499c72459dSmillert switch (cur->fts_info) {
509c72459dSmillert case FTS_D:
519c72459dSmillert fnflag = FTW_D;
529c72459dSmillert break;
539c72459dSmillert case FTS_DNR:
549c72459dSmillert fnflag = FTW_DNR;
559c72459dSmillert break;
569c72459dSmillert case FTS_DP:
579c72459dSmillert /* we only visit in preorder */
589c72459dSmillert continue;
599c72459dSmillert case FTS_F:
609c72459dSmillert case FTS_DEFAULT:
619c72459dSmillert fnflag = FTW_F;
629c72459dSmillert break;
639c72459dSmillert case FTS_NS:
649c72459dSmillert case FTS_NSOK:
659c72459dSmillert case FTS_SLNONE:
669c72459dSmillert fnflag = FTW_NS;
679c72459dSmillert break;
689c72459dSmillert case FTS_SL:
699c72459dSmillert fnflag = FTW_SL;
709c72459dSmillert break;
719c72459dSmillert case FTS_DC:
729c72459dSmillert errno = ELOOP;
739c72459dSmillert /* FALLTHROUGH */
749c72459dSmillert default:
759c72459dSmillert error = -1;
769c72459dSmillert goto done;
779c72459dSmillert }
789c72459dSmillert error = fn(cur->fts_path, cur->fts_statp, fnflag);
799c72459dSmillert if (error != 0)
809c72459dSmillert break;
819c72459dSmillert }
829c72459dSmillert done:
839c72459dSmillert sverrno = errno;
8419066a52Smillert if (fts_close(ftsp) != 0 && error == 0)
8519066a52Smillert error = -1;
8619066a52Smillert else
879c72459dSmillert errno = sverrno;
889c72459dSmillert return (error);
899c72459dSmillert }
90