5
|
1 /* savedir.c -- save the list of files in a directory in a string |
|
2 Copyright (C) 1990 Free Software Foundation, Inc. |
|
3 |
|
4 This program is free software; you can redistribute it and/or modify |
|
5 it under the terms of the GNU General Public License as published by |
|
6 the Free Software Foundation; either version 2, or (at your option) |
|
7 any later version. |
|
8 |
|
9 This program is distributed in the hope that it will be useful, |
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 GNU General Public License for more details. |
|
13 |
|
14 You should have received a copy of the GNU General Public License |
|
15 along with this program; if not, write to the Free Software |
|
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
17 |
285
|
18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ |
|
19 |
|
20 #ifdef HAVE_CONFIG_H |
|
21 #if defined (CONFIG_BROKETS) |
|
22 /* We use <config.h> instead of "config.h" so that a compilation |
|
23 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h |
|
24 (which it would do because it found this file in $srcdir). */ |
|
25 #include <config.h> |
|
26 #else |
|
27 #include "config.h" |
|
28 #endif |
|
29 #endif |
5
|
30 |
|
31 #include <sys/types.h> |
285
|
32 |
|
33 #ifdef HAVE_UNISTD_H |
|
34 #include <unistd.h> |
|
35 #endif |
|
36 |
314
|
37 #ifdef HAVE_DIRENT_H |
5
|
38 #include <dirent.h> |
|
39 #define NLENGTH(direct) (strlen((direct)->d_name)) |
314
|
40 #else /* not HAVE_DIRENT_H */ |
285
|
41 #define dirent direct |
5
|
42 #define NLENGTH(direct) ((direct)->d_namlen) |
314
|
43 #ifdef HAVE_SYS_NDIR_H |
5
|
44 #include <sys/ndir.h> |
314
|
45 #endif /* HAVE_SYS_NDIR_H */ |
|
46 #ifdef HAVE_SYS_DIR_H |
285
|
47 #include <sys/dir.h> |
314
|
48 #endif /* HAVE_SYS_DIR_H */ |
|
49 #ifdef HAVE_NDIR_H |
5
|
50 #include <ndir.h> |
314
|
51 #endif /* HAVE_NDIR_H */ |
|
52 #endif /* HAVE_DIRENT_H */ |
5
|
53 |
314
|
54 #ifdef CLOSEDIR_VOID |
5
|
55 /* Fake a return value. */ |
|
56 #define CLOSEDIR(d) (closedir (d), 0) |
|
57 #else |
|
58 #define CLOSEDIR(d) closedir (d) |
|
59 #endif |
|
60 |
|
61 #ifdef STDC_HEADERS |
|
62 #include <stdlib.h> |
|
63 #include <string.h> |
|
64 #else |
|
65 char *malloc (); |
|
66 char *realloc (); |
|
67 #ifndef NULL |
|
68 #define NULL 0 |
|
69 #endif |
|
70 #endif |
|
71 |
|
72 char *stpcpy (); |
|
73 |
|
74 /* Return a freshly allocated string containing the filenames |
|
75 in directory DIR, separated by '\0' characters; |
|
76 the end is marked by two '\0' characters in a row. |
|
77 NAME_SIZE is the number of bytes to initially allocate |
|
78 for the string; it will be enlarged as needed. |
|
79 Return NULL if DIR cannot be opened or if out of memory. */ |
|
80 |
|
81 char * |
|
82 savedir (dir, name_size) |
|
83 char *dir; |
|
84 unsigned name_size; |
|
85 { |
|
86 DIR *dirp; |
285
|
87 struct dirent *dp; |
5
|
88 char *name_space; |
|
89 char *namep; |
|
90 |
|
91 dirp = opendir (dir); |
|
92 if (dirp == NULL) |
|
93 return NULL; |
|
94 |
|
95 name_space = (char *) malloc (name_size); |
|
96 if (name_space == NULL) |
|
97 { |
|
98 closedir (dirp); |
|
99 return NULL; |
|
100 } |
|
101 namep = name_space; |
|
102 |
|
103 while ((dp = readdir (dirp)) != NULL) |
|
104 { |
|
105 /* Skip "." and ".." (some NFS filesystems' directories lack them). */ |
|
106 if (dp->d_name[0] != '.' |
|
107 || (dp->d_name[1] != '\0' |
|
108 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) |
|
109 { |
|
110 unsigned size_needed = (namep - name_space) + NLENGTH (dp) + 2; |
|
111 |
|
112 if (size_needed > name_size) |
|
113 { |
|
114 char *new_name_space; |
|
115 |
|
116 while (size_needed > name_size) |
|
117 name_size += 1024; |
|
118 |
|
119 new_name_space = realloc (name_space, name_size); |
|
120 if (new_name_space == NULL) |
|
121 { |
|
122 closedir (dirp); |
|
123 return NULL; |
|
124 } |
|
125 namep += new_name_space - name_space; |
|
126 name_space = new_name_space; |
|
127 } |
|
128 namep = stpcpy (namep, dp->d_name) + 1; |
|
129 } |
|
130 } |
|
131 *namep = '\0'; |
|
132 if (CLOSEDIR (dirp)) |
|
133 { |
|
134 free (name_space); |
|
135 return NULL; |
|
136 } |
|
137 return name_space; |
|
138 } |