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