Add ftw(), nftw(), associated header files and documentation.
authorSascha Wildner <saw@online.de>
Fri, 12 Dec 2008 23:21:50 +0000 (00:21 +0100)
committerSascha Wildner <saw@online.de>
Fri, 12 Dec 2008 23:23:53 +0000 (00:23 +0100)
It seems that security/prelude-manager in pkgsrc actually needs it.

Taken-from: FreeBSD
Tested-by: Rumko <rumcic@gmail.com>
include/Makefile
include/ftw.h [new file with mode: 0644]
lib/libc/gen/Makefile.inc
lib/libc/gen/ftw.3 [new file with mode: 0644]
lib/libc/gen/ftw.c [new file with mode: 0644]
lib/libc/gen/nftw.c [new file with mode: 0644]

index a93662d..0d1c07c 100644 (file)
@@ -12,8 +12,8 @@ SUBDIR= arpa protocols rpc rpcsvc
 INCS=  a.out.h ar.h assert.h bitstring.h complex.h cpio.h ctype.h db.h \
        dirent.h disktab.h \
        dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \
-       fts.h getopt.h glob.h grp.h histedit.h iconv.h ieeefp.h ifaddrs.h \
-       iso646.h inttypes.h \
+       fts.h ftw.h getopt.h glob.h grp.h histedit.h \
+       iconv.h ieeefp.h ifaddrs.h iso646.h inttypes.h \
        langinfo.h libgen.h limits.h link.h locale.h malloc.h math.h memory.h \
        mpool.h monetary.h ndbm.h netdb.h nl_types.h nlist.h objformat.h \
        paths.h pthread.h pthread_np.h pwd.h \
diff --git a/include/ftw.h b/include/ftw.h
new file mode 100644 (file)
index 0000000..9fc3ede
--- /dev/null
@@ -0,0 +1,62 @@
+/*     $OpenBSD: ftw.h,v 1.1 2003/07/21 21:13:18 millert Exp $ */
+
+/*
+ * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ *
+ * $FreeBSD: src/include/ftw.h,v 1.2 2004/08/24 13:00:54 tjr Exp $
+ */
+
+#ifndef        _FTW_H
+#define        _FTW_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/*
+ * Valid flags for the 3rd argument to the function that is passed as the
+ * second argument to ftw(3) and nftw(3).  Say it three times fast!
+ */
+#define        FTW_F           0       /* File.  */
+#define        FTW_D           1       /* Directory.  */
+#define        FTW_DNR         2       /* Directory without read permission.  */
+#define        FTW_DP          3       /* Directory with subdirectories visited.  */
+#define        FTW_NS          4       /* Unknown type; stat() failed.  */
+#define        FTW_SL          5       /* Symbolic link.  */
+#define        FTW_SLN         6       /* Sym link that names a nonexistent file.  */
+
+/*
+ * Flags for use as the 4th argument to nftw(3).  These may be ORed together.
+ */
+#define        FTW_PHYS        0x01    /* Physical walk, don't follow sym links.  */
+#define        FTW_MOUNT       0x02    /* The walk does not cross a mount point.  */
+#define        FTW_DEPTH       0x04    /* Subdirs visited before the dir itself. */
+#define        FTW_CHDIR       0x08    /* Change to a directory before reading it. */
+
+struct FTW {
+       int base;
+       int level;
+};
+
+__BEGIN_DECLS
+int    ftw(const char *, int (*)(const char *, const struct stat *, int), int);
+int    nftw(const char *, int (*)(const char *, const struct stat *, int,
+           struct FTW *), int, int);
+__END_DECLS
+
+#endif /* !_FTW_H */
index 82263c6..d022eb5 100644 (file)
@@ -11,7 +11,7 @@ SRCS+=  _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \
        ctermid.c ctype.c daemon.c devname.c dirname.c disklabel.c disktab.c \
        dlfcn.c drand48.c erand48.c err.c errlst.c \
        exec.c fmtcheck.c fmtmsg.c fnmatch.c fpclassifyd.c fpclassifyf.c \
-       fstab.c ftok.c fts.c getbootfile.c getbsize.c \
+       fstab.c ftok.c fts.c ftw.c getbootfile.c getbsize.c \
        getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
        gethostname.c getloadavg.c getlogin.c getmntinfo.c getmntvinfo.c \
        getnetgrent.c getobjformat.c getosreldate.c getpagesize.c \
@@ -21,7 +21,7 @@ SRCS+=  _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \
        isatty.c isctype.c isfinited.c isfinitef.c isinfd.c isinff.c \
        isnand.c isnanf.c jrand48.c lcong48.c \
        lockf.c lrand48.c mrand48.c msgctl.c \
-       msgget.c msgrcv.c msgsnd.c nice.c \
+       msgget.c msgrcv.c msgsnd.c nftw.c nice.c \
        nlist.c nrand48.c ntp_gettime.c opendir.c \
        pause.c pmadvise.c popen.c posixshm.c \
        psignal.c pthread_fake.c pwcache.c \
@@ -51,7 +51,7 @@ MAN+= alarm.3 arc4random.3 clock.3 \
        devname.3 directory.3 dirname.3 \
        dladdr.3 dlinfo.3 dlopen.3 \
        err.3 exec.3 \
-       fmtcheck.3 fmtmsg.3 fnmatch.3 fpclassify.3 frexp.3 ftok.3 fts.3 \
+       fmtcheck.3 fmtmsg.3 fnmatch.3 fpclassify.3 frexp.3 ftok.3 fts.3 ftw.3 \
        getbootfile.3 getbsize.3 getcap.3 getcontext.3 getcwd.3 \
        getdiskbyname.3 getdisktabbyname.3 getdomainname.3 getfsent.3 \
        getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
@@ -86,6 +86,7 @@ MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 exect.3 \
        exec.3 execv.3 exec.3 execvp.3
 MLINKS+=fts.3 fts_children.3 fts.3 fts_close.3 fts.3 fts_open.3 \
        fts.3 fts_read.3 fts.3 fts_set.3
+MLINKS+=ftw.3 nftw.3
 MLINKS+=getcap.3 cgetcap.3 getcap.3 cgetclose.3 getcap.3 cgetent.3 \
        getcap.3 cgetfirst.3 getcap.3 cgetmatch.3 getcap.3 cgetnext.3 \
        getcap.3 cgetnum.3 getcap.3 cgetset.3 getcap.3 cgetstr.3 \
diff --git a/lib/libc/gen/ftw.3 b/lib/libc/gen/ftw.3
new file mode 100644 (file)
index 0000000..9c8dbeb
--- /dev/null
@@ -0,0 +1,218 @@
+.\"    $OpenBSD: ftw.3,v 1.5 2004/01/25 14:48:32 jmc Exp $
+.\"
+.\" Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/ftw.3,v 1.3 2005/11/23 15:41:36 ru Exp $
+.\"
+.Dd December 13, 2008
+.Dt FTW 3
+.Os
+.Sh NAME
+.Nm ftw , nftw
+.Nd traverse (walk) a file tree
+.Sh SYNOPSIS
+.In ftw.h
+.Ft int
+.Fo ftw
+.Fa "const char *path"
+.Fa "int \*[lp]*fn\*[rp]\*[lp]const char *, const struct stat *, int\*[rp]"
+.Fa "int maxfds"
+.Fc
+.Ft int
+.Fo nftw
+.Fa "const char *path"
+.Fa "int \*[lp]*fn\*[rp]\*[lp]const char *, const struct stat *, int, struct FTW *\*[rp]"
+.Fa "int maxfds"
+.Fa "int flags"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn ftw
+and
+.Fn nftw
+functions traverse (walk) the directory hierarchy rooted in
+.Fa path .
+For each object in the hierarchy, these functions call the function
+pointed to by
+.Fa fn .
+The
+.Fn ftw
+function passes this function a pointer to a
+.Dv NUL Ns
+-terminated string containing
+the name of the object, a pointer to a
+.Vt stat
+structure corresponding to the
+object, and an integer flag.
+The
+.Fn nftw
+function passes the aforementioned arguments plus a pointer to a
+.Vt FTW
+structure as defined by
+.In ftw.h
+(shown below):
+.Bd -literal
+struct FTW {
+    int base;  /* offset of basename into pathname */
+    int level; /* directory depth relative to starting point */
+};
+.Ed
+.Pp
+Possible values for the flag passed to
+.Fa fn
+are:
+.Bl -tag -width ".Dv FTW_DNR"
+.It Dv FTW_F
+A regular file.
+.It Dv FTW_D
+A directory being visited in pre-order.
+.It Dv FTW_DNR
+A directory which cannot be read.
+The directory will not be descended into.
+.It Dv FTW_DP
+A directory being visited in post-order
+.Fn ( nftw
+only).
+.It Dv FTW_NS
+A file for which no
+.Xr stat 2
+information was available.
+The contents of the
+.Vt stat
+structure are undefined.
+.It Dv FTW_SL
+A symbolic link.
+.It Dv FTW_SLN
+A symbolic link with a non-existent target
+.Fn ( nftw
+only).
+.El
+.Pp
+The
+.Fn ftw
+function traverses the tree in pre-order.
+That is, it processes the directory before the directory's contents.
+.Pp
+The
+.Fa maxfds
+argument specifies the maximum number of file descriptors
+to keep open while traversing the tree.
+It has no effect in this implementation.
+.Pp
+The
+.Fn nftw
+function has an additional
+.Fa flags
+argument with the following possible values:
+.Bl -tag -width ".Dv FTW_MOUNT"
+.It Dv FTW_PHYS
+Physical walk, do not follow symbolic links.
+.It Dv FTW_MOUNT
+The walk will not cross a mount point.
+.It FTW_DEPTH
+Process directories in post-order.
+Contents of a directory are visited before the directory itself.
+By default,
+.Fn nftw
+traverses the tree in pre-order.
+.It FTW_CHDIR
+Change to a directory before reading it.
+By default,
+.Fn nftw
+will change its starting directory.
+The current working directory will be restored to its original value before
+.Fn nftw
+returns.
+.El
+.Sh RETURN VALUES
+If the tree was traversed successfully, the
+.Fn ftw
+and
+.Fn nftw
+functions return 0.
+If the function pointed to by
+.Fa fn
+returns a non-zero value,
+.Fn ftw
+and
+.Fn nftw
+will stop processing the tree and return the value from
+.Fa fn .
+Both functions return \-1 if an error is detected.
+.Sh ERRORS
+The
+.Fn ftw
+and
+.Fn nftw
+functions may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr close 2 ,
+.Xr open 2 ,
+.Xr stat 2 ,
+.Xr malloc 3 ,
+.Xr opendir 3
+and
+.Xr readdir 3 .
+If the
+.Dv FTW_CHDIR
+flag is set, the
+.Fn nftw
+function may fail and set
+.Va errno
+for any of the errors specified for
+.Xr chdir 2 .
+In addition, either function may fail and set
+.Va errno
+as follows:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa maxfds
+argument is less than 1.
+.El
+.Sh SEE ALSO
+.Xr chdir 2 ,
+.Xr close 2 ,
+.Xr open 2 ,
+.Xr stat 2 ,
+.Xr fts 3 ,
+.Xr malloc 3 ,
+.Xr opendir 3 ,
+.Xr readdir 3
+.Sh STANDARDS
+The
+.Fn ftw
+and
+.Fn nftw
+functions conform to
+.St -p1003.1-2001 .
+.Sh HISTORY
+These functions first appeared in
+.At V.3 .
+Their first
+.Fx
+appearance was in
+.Fx 5.3 .
+They were imported into
+.Dx 2.1 .
+.Sh BUGS
+The
+.Fa maxfds
+argument is currently ignored.
diff --git a/lib/libc/gen/ftw.c b/lib/libc/gen/ftw.c
new file mode 100644 (file)
index 0000000..9c7b97d
--- /dev/null
@@ -0,0 +1,91 @@
+/*     $OpenBSD: ftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $ */
+
+/*
+ * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ *
+ * $FreeBSD: src/lib/libc/gen/ftw.c,v 1.4 2004/08/24 13:00:55 tjr Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fts.h>
+#include <ftw.h>
+#include <limits.h>
+
+int
+ftw(const char *path, int (*fn)(const char *, const struct stat *, int),
+    int nfds)
+{
+       char * const paths[2] = { (char *)path, NULL };
+       FTSENT *cur;
+       FTS *ftsp;
+       int error = 0, fnflag, sverrno;
+
+       /* XXX - nfds is currently unused */
+       if (nfds < 1 || nfds > OPEN_MAX) {
+               errno = EINVAL;
+               return (-1);
+       }
+
+       ftsp = fts_open(paths, FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
+       if (ftsp == NULL)
+               return (-1);
+       while ((cur = fts_read(ftsp)) != NULL) {
+               switch (cur->fts_info) {
+               case FTS_D:
+                       fnflag = FTW_D;
+                       break;
+               case FTS_DNR:
+                       fnflag = FTW_DNR;
+                       break;
+               case FTS_DP:
+                       /* we only visit in preorder */
+                       continue;
+               case FTS_F:
+               case FTS_DEFAULT:
+                       fnflag = FTW_F;
+                       break;
+               case FTS_NS:
+               case FTS_NSOK:
+               case FTS_SLNONE:
+                       fnflag = FTW_NS;
+                       break;
+               case FTS_SL:
+                       fnflag = FTW_SL;
+                       break;
+               case FTS_DC:
+                       errno = ELOOP;
+                       /* FALLTHROUGH */
+               default:
+                       error = -1;
+                       goto done;
+               }
+               error = fn(cur->fts_path, cur->fts_statp, fnflag);
+               if (error != 0)
+                       break;
+       }
+done:
+       sverrno = errno;
+       if (fts_close(ftsp) != 0 && error == 0)
+               error = -1;
+       else
+               errno = sverrno;
+       return (error);
+}
diff --git a/lib/libc/gen/nftw.c b/lib/libc/gen/nftw.c
new file mode 100644 (file)
index 0000000..da5c1c0
--- /dev/null
@@ -0,0 +1,110 @@
+/*     $OpenBSD: nftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $        */
+
+/*
+ * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ *
+ * $FreeBSD: src/lib/libc/gen/nftw.c,v 1.1 2004/08/24 13:00:55 tjr Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fts.h>
+#include <ftw.h>
+#include <limits.h>
+
+int
+nftw(const char *path, int (*fn)(const char *, const struct stat *, int,
+     struct FTW *), int nfds, int ftwflags)
+{
+       char * const paths[2] = { (char *)path, NULL };
+       struct FTW ftw;
+       FTSENT *cur;
+       FTS *ftsp;
+       int error = 0, ftsflags, fnflag, postorder, sverrno;
+
+       /* XXX - nfds is currently unused */
+       if (nfds < 1 || nfds > OPEN_MAX) {
+               errno = EINVAL;
+               return (-1);
+       }
+
+       ftsflags = FTS_COMFOLLOW;
+       if (!(ftwflags & FTW_CHDIR))
+               ftsflags |= FTS_NOCHDIR;
+       if (ftwflags & FTW_MOUNT)
+               ftsflags |= FTS_XDEV;
+       if (ftwflags & FTW_PHYS)
+               ftsflags |= FTS_PHYSICAL;
+       else
+               ftsflags |= FTS_LOGICAL;
+       postorder = (ftwflags & FTW_DEPTH) != 0;
+       ftsp = fts_open(paths, ftsflags, NULL);
+       if (ftsp == NULL)
+               return (-1);
+       while ((cur = fts_read(ftsp)) != NULL) {
+               switch (cur->fts_info) {
+               case FTS_D:
+                       if (postorder)
+                               continue;
+                       fnflag = FTW_D;
+                       break;
+               case FTS_DNR:
+                       fnflag = FTW_DNR;
+                       break;
+               case FTS_DP:
+                       if (!postorder)
+                               continue;
+                       fnflag = FTW_DP;
+                       break;
+               case FTS_F:
+               case FTS_DEFAULT:
+                       fnflag = FTW_F;
+                       break;
+               case FTS_NS:
+               case FTS_NSOK:
+                       fnflag = FTW_NS;
+                       break;
+               case FTS_SL:
+                       fnflag = FTW_SL;
+                       break;
+               case FTS_SLNONE:
+                       fnflag = FTW_SLN;
+                       break;
+               case FTS_DC:
+                       errno = ELOOP;
+                       /* FALLTHROUGH */
+               default:
+                       error = -1;
+                       goto done;
+               }
+               ftw.base = cur->fts_pathlen - cur->fts_namelen;
+               ftw.level = cur->fts_level;
+               error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw);
+               if (error != 0)
+                       break;
+       }
+done:
+       sverrno = errno;
+       if (fts_close(ftsp) != 0 && error == 0)
+               error = -1;
+       else
+               errno = sverrno;
+       return (error);
+}