Annotation of coherent/g/usr/lib/uucp/tay104/unix/ftw.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.