|
|
1.1 ! root 1: /* Copyright (C) 1991, 1992 Free Software Foundation, Inc. ! 2: This file is part of the GNU C Library. ! 3: Contributed by Ian Lance Taylor ([email protected]). ! 4: ! 5: The GNU C Library is free software; you can redistribute it and/or ! 6: modify it under the terms of the GNU Library General Public License as ! 7: published by the Free Software Foundation; either version 2 of the ! 8: License, or (at your option) any later version. ! 9: ! 10: The GNU C Library is distributed in the hope that it will be useful, ! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 13: Library General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU Library General Public ! 16: License along with the GNU C Library; see the file COPYING.LIB. If ! 17: not, write to the Free Software Foundation, Inc., 675 Mass Ave, ! 18: Cambridge, MA 02139, USA. ! 19: ! 20: Modified by Ian Lanc Taylor for Taylor UUCP, June 1992. */ ! 21: ! 22: #include "uucp.h" ! 23: ! 24: #include "sysdep.h" ! 25: ! 26: #include <errno.h> ! 27: ! 28: #if HAVE_LIMITS_H ! 29: #include <limits.h> ! 30: #endif ! 31: ! 32: #if HAVE_SYS_PARAM_H ! 33: #include <sys/param.h> ! 34: #endif ! 35: ! 36: #if HAVE_OPENDIR ! 37: #if HAVE_DIRENT_H ! 38: #include <dirent.h> ! 39: #else /* ! HAVE_DIRENT_H */ ! 40: #include <sys/dir.h> ! 41: #define dirent direct ! 42: #endif /* ! HAVE_DIRENT_H */ ! 43: #endif /* HAVE_OPENDIR */ ! 44: ! 45: #if HAVE_FTW_H ! 46: #include <ftw.h> ! 47: #endif ! 48: ! 49: #ifndef PATH_MAX ! 50: #ifdef MAXPATHLEN ! 51: #define PATH_MAX MAXPATHLEN ! 52: #else ! 53: #define PATH_MAX 1024 ! 54: #endif ! 55: #endif ! 56: ! 57: /* Traverse one level of a directory tree. */ ! 58: ! 59: static int ! 60: ftw_dir (dirs, level, descriptors, dir, len, func) ! 61: DIR **dirs; ! 62: int level; ! 63: int descriptors; ! 64: char *dir; ! 65: size_t len; ! 66: int (*func) P((const char *file, const struct stat *status, int flag)); ! 67: { ! 68: int got; ! 69: struct dirent *entry; ! 70: ! 71: got = 0; ! 72: ! 73: errno = 0; ! 74: ! 75: while ((entry = readdir (dirs[level])) != NULL) ! 76: { ! 77: size_t namlen; ! 78: struct stat s; ! 79: int flag, ret, newlev; ! 80: ! 81: ++got; ! 82: ! 83: namlen = strlen (entry->d_name); ! 84: if (entry->d_name[0] == '.' ! 85: && (namlen == 1 || ! 86: (namlen == 2 && entry->d_name[1] == '.'))) ! 87: { ! 88: errno = 0; ! 89: continue; ! 90: } ! 91: ! 92: if (namlen + len + 1 > PATH_MAX) ! 93: { ! 94: #ifdef ENAMETOOLONG ! 95: errno = ENAMETOOLONG; ! 96: #else ! 97: errno = ENOMEM; ! 98: #endif ! 99: return -1; ! 100: } ! 101: ! 102: dir[len] = '/'; ! 103: memcpy ((dir + len + 1), entry->d_name, namlen + 1); ! 104: ! 105: if (stat (dir, &s) < 0) ! 106: { ! 107: if (errno != EACCES) ! 108: return -1; ! 109: flag = FTW_NS; ! 110: } ! 111: else if (S_ISDIR (s.st_mode)) ! 112: { ! 113: newlev = (level + 1) % descriptors; ! 114: ! 115: if (dirs[newlev] != NULL) ! 116: closedir (dirs[newlev]); ! 117: ! 118: dirs[newlev] = opendir (dir); ! 119: if (dirs[newlev] != NULL) ! 120: flag = FTW_D; ! 121: else ! 122: { ! 123: if (errno != EACCES) ! 124: return -1; ! 125: flag = FTW_DNR; ! 126: } ! 127: } ! 128: else ! 129: flag = FTW_F; ! 130: ! 131: ret = (*func) (dir, &s, flag); ! 132: ! 133: if (flag == FTW_D) ! 134: { ! 135: if (ret == 0) ! 136: ret = ftw_dir (dirs, newlev, descriptors, dir, ! 137: namlen + len + 1, func); ! 138: if (dirs[newlev] != NULL) ! 139: { ! 140: int save; ! 141: ! 142: save = errno; ! 143: closedir (dirs[newlev]); ! 144: errno = save; ! 145: dirs[newlev] = NULL; ! 146: } ! 147: } ! 148: ! 149: if (ret != 0) ! 150: return ret; ! 151: ! 152: if (dirs[level] == NULL) ! 153: { ! 154: int skip; ! 155: ! 156: dir[len] = '\0'; ! 157: dirs[level] = opendir (dir); ! 158: if (dirs[level] == NULL) ! 159: return -1; ! 160: skip = got; ! 161: while (skip-- != 0) ! 162: { ! 163: errno = 0; ! 164: if (readdir (dirs[level]) == NULL) ! 165: return errno == 0 ? 0 : -1; ! 166: } ! 167: } ! 168: ! 169: errno = 0; ! 170: } ! 171: ! 172: return errno == 0 ? 0 : -1; ! 173: } ! 174: ! 175: /* Call a function on every element in a directory tree. */ ! 176: ! 177: int ! 178: ftw (dir, func, descriptors) ! 179: const char *dir; ! 180: int (*func) P((const char *file, const struct stat *status, int flag)); ! 181: int descriptors; ! 182: { ! 183: DIR **dirs; ! 184: int c; ! 185: DIR **p; ! 186: size_t len; ! 187: char buf[PATH_MAX + 1]; ! 188: struct stat s; ! 189: int flag, ret; ! 190: ! 191: if (descriptors <= 0) ! 192: descriptors = 1; ! 193: ! 194: dirs = (DIR **) malloc (descriptors * sizeof (DIR *)); ! 195: if (dirs == NULL) ! 196: return -1; ! 197: c = descriptors; ! 198: p = dirs; ! 199: while (c-- != 0) ! 200: *p++ = NULL; ! 201: ! 202: len = strlen (dir); ! 203: memcpy (buf, dir, len + 1); ! 204: ! 205: if (stat (dir, &s) < 0) ! 206: { ! 207: if (errno != EACCES) ! 208: { ! 209: free ((pointer) dirs); ! 210: return -1; ! 211: } ! 212: flag = FTW_NS; ! 213: } ! 214: else if (S_ISDIR (s.st_mode)) ! 215: { ! 216: dirs[0] = opendir (dir); ! 217: if (dirs[0] != NULL) ! 218: flag = FTW_D; ! 219: else ! 220: { ! 221: if (errno != EACCES) ! 222: { ! 223: free ((pointer) dirs); ! 224: return -1; ! 225: } ! 226: flag = FTW_DNR; ! 227: } ! 228: } ! 229: else ! 230: flag = FTW_F; ! 231: ! 232: ret = (*func) (buf, &s, flag); ! 233: ! 234: if (flag == FTW_D) ! 235: { ! 236: if (ret == 0) ! 237: ret = ftw_dir (dirs, 0, descriptors, buf, len, func); ! 238: if (dirs[0] != NULL) ! 239: { ! 240: int save; ! 241: ! 242: save = errno; ! 243: closedir (dirs[0]); ! 244: errno = save; ! 245: } ! 246: } ! 247: ! 248: free ((pointer) dirs); ! 249: return ret; ! 250: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.