Whamcloud - gitweb
7b02a7f3ef410f9b2e06c9a2d2fbd287ab63688e
[tools/e2fsprogs.git] / lib / e2p / iod.c
1 /*
2  * iod.c                - Iterate a function on each entry of a directory
3  *
4  * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
5  *                           Laboratoire MASI, Institut Blaise Pascal
6  *                           Universite Pierre et Marie Curie (Paris VI)
7  *
8  * This file can be redistributed under the terms of the GNU Library General
9  * Public License
10  */
11
12 /*
13  * History:
14  * 93/10/30     - Creation
15  */
16
17 #include "e2p.h"
18
19 int iterate_on_dir (const char * dir_name,
20                     int (*func) (const char *, struct dirent *, void *),
21                     void * private)
22 {
23         DIR * dir;
24 #if HAVE_DIRENT_NAMELEN
25         /* Declare DE_BUF with some extra room for the name.  */
26         char de_buf[sizeof (struct dirent) + 32];
27         struct dirent *de = (struct dirent *)&de_buf;
28 #else
29         struct dirent de_buf, *de = &de_buf;
30 #endif
31         struct dirent *dep;
32
33         dir = opendir (dir_name);
34         if (dir == NULL)
35                 return -1;
36         while ((dep = readdir (dir)))
37         {
38 #if HAVE_DIRENT_NAMELEN
39           /* See if there's enough room for this entry in DE, and grow if
40              not.  */
41           if (de_len < dep->d_reclen)
42             {
43               de_len = dep->d_reclen + 32;
44               de =
45                 (de == (struct dirent *)&de_buf
46                  ? malloc (de_len)
47                  : realloc (de, de_len));
48               if (de == NULL)
49                 {
50                   errno = ENOMEM;
51                   return -1;
52                 }
53             }
54           memcpy (de, dep, dep->d_reclen);
55 #else
56           *de = *dep;
57 #endif
58           (*func) (dir_name, de, private);
59         }
60 #if HAVE_DIRENT_NAMELEN
61         if (de != (struct dirent *)&de_buf)
62           free (de);
63 #endif
64         closedir (dir);
65         return 0;
66 }