1 | /* $OpenBSD: nftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $ */
|
---|
2 |
|
---|
3 | /*
|
---|
4 | * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
|
---|
5 | *
|
---|
6 | * Permission to use, copy, modify, and distribute this software for any
|
---|
7 | * purpose with or without fee is hereby granted, provided that the above
|
---|
8 | * copyright notice and this permission notice appear in all copies.
|
---|
9 | *
|
---|
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
---|
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
---|
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
---|
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
---|
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
---|
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
---|
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
---|
17 | *
|
---|
18 | * Sponsored in part by the Defense Advanced Research Projects
|
---|
19 | * Agency (DARPA) and Air Force Research Laboratory, Air Force
|
---|
20 | * Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
---|
21 | */
|
---|
22 |
|
---|
23 | #if 0
|
---|
24 | #if defined(LIBC_SCCS) && !defined(lint)
|
---|
25 | static const char rcsid[] = "$OpenBSD: nftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $";
|
---|
26 | #endif /* LIBC_SCCS and not lint */
|
---|
27 | #endif
|
---|
28 |
|
---|
29 | #include <sys/cdefs.h>
|
---|
30 | __FBSDID("$FreeBSD: src/lib/libc/gen/nftw.c,v 1.1 2004/08/24 13:00:55 tjr Exp $");
|
---|
31 |
|
---|
32 | #include <sys/types.h>
|
---|
33 | #include <sys/stat.h>
|
---|
34 | #include <errno.h>
|
---|
35 | #include <fts.h>
|
---|
36 | #include <ftw.h>
|
---|
37 | #include <limits.h>
|
---|
38 |
|
---|
39 | int
|
---|
40 | nftw(const char *path, int (*fn)(const char *, const struct stat *, int,
|
---|
41 | struct FTW *), int nfds, int ftwflags)
|
---|
42 | {
|
---|
43 | char * const paths[2] = { (char *)path, NULL };
|
---|
44 | struct FTW ftw;
|
---|
45 | FTSENT *cur;
|
---|
46 | FTS *ftsp;
|
---|
47 | int error = 0, ftsflags, fnflag, postorder, sverrno;
|
---|
48 |
|
---|
49 | /* XXX - nfds is currently unused */
|
---|
50 | if (nfds < 1 || nfds > OPEN_MAX) {
|
---|
51 | errno = EINVAL;
|
---|
52 | return (-1);
|
---|
53 | }
|
---|
54 |
|
---|
55 | ftsflags = FTS_COMFOLLOW;
|
---|
56 | if (!(ftwflags & FTW_CHDIR))
|
---|
57 | ftsflags |= FTS_NOCHDIR;
|
---|
58 | if (ftwflags & FTW_MOUNT)
|
---|
59 | ftsflags |= FTS_XDEV;
|
---|
60 | if (ftwflags & FTW_PHYS)
|
---|
61 | ftsflags |= FTS_PHYSICAL;
|
---|
62 | else
|
---|
63 | ftsflags |= FTS_LOGICAL;
|
---|
64 | postorder = (ftwflags & FTW_DEPTH) != 0;
|
---|
65 | ftsp = fts_open(paths, ftsflags, NULL);
|
---|
66 | if (ftsp == NULL)
|
---|
67 | return (-1);
|
---|
68 | while ((cur = fts_read(ftsp)) != NULL) {
|
---|
69 | switch (cur->fts_info) {
|
---|
70 | case FTS_D:
|
---|
71 | if (postorder)
|
---|
72 | continue;
|
---|
73 | fnflag = FTW_D;
|
---|
74 | break;
|
---|
75 | case FTS_DNR:
|
---|
76 | fnflag = FTW_DNR;
|
---|
77 | break;
|
---|
78 | case FTS_DP:
|
---|
79 | if (!postorder)
|
---|
80 | continue;
|
---|
81 | fnflag = FTW_DP;
|
---|
82 | break;
|
---|
83 | case FTS_F:
|
---|
84 | case FTS_DEFAULT:
|
---|
85 | fnflag = FTW_F;
|
---|
86 | break;
|
---|
87 | case FTS_NS:
|
---|
88 | case FTS_NSOK:
|
---|
89 | fnflag = FTW_NS;
|
---|
90 | break;
|
---|
91 | case FTS_SL:
|
---|
92 | fnflag = FTW_SL;
|
---|
93 | break;
|
---|
94 | case FTS_SLNONE:
|
---|
95 | fnflag = FTW_SLN;
|
---|
96 | break;
|
---|
97 | case FTS_DC:
|
---|
98 | errno = ELOOP;
|
---|
99 | /* FALLTHROUGH */
|
---|
100 | default:
|
---|
101 | error = -1;
|
---|
102 | goto done;
|
---|
103 | }
|
---|
104 | ftw.base = cur->fts_pathlen - cur->fts_namelen;
|
---|
105 | ftw.level = cur->fts_level;
|
---|
106 | error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw);
|
---|
107 | if (error != 0)
|
---|
108 | break;
|
---|
109 | }
|
---|
110 | done:
|
---|
111 | sverrno = errno;
|
---|
112 | if (fts_close(ftsp) != 0 && error == 0)
|
---|
113 | error = -1;
|
---|
114 | else
|
---|
115 | errno = sverrno;
|
---|
116 | return (error);
|
---|
117 | }
|
---|