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 #include <config.h> |
|
22 #endif |
5
|
23 |
|
24 #include <sys/types.h> |
285
|
25 |
|
26 #ifdef HAVE_UNISTD_H |
|
27 #include <unistd.h> |
|
28 #endif |
|
29 |
329
|
30 #if HAVE_DIRENT_H |
|
31 # include <dirent.h> |
|
32 # define NAMLEN(dirent) strlen((dirent)->d_name) |
|
33 #else |
|
34 # define dirent direct |
|
35 # define NAMLEN(dirent) (dirent)->d_namlen |
|
36 # if HAVE_SYS_NDIR_H |
|
37 # include <sys/ndir.h> |
|
38 # endif |
|
39 # if HAVE_SYS_DIR_H |
|
40 # include <sys/dir.h> |
|
41 # endif |
|
42 # if HAVE_NDIR_H |
|
43 # include <ndir.h> |
|
44 # endif |
|
45 #endif |
5
|
46 |
314
|
47 #ifdef CLOSEDIR_VOID |
5
|
48 /* Fake a return value. */ |
|
49 #define CLOSEDIR(d) (closedir (d), 0) |
|
50 #else |
|
51 #define CLOSEDIR(d) closedir (d) |
|
52 #endif |
|
53 |
|
54 #ifdef STDC_HEADERS |
|
55 #include <stdlib.h> |
|
56 #include <string.h> |
|
57 #else |
|
58 char *malloc (); |
|
59 char *realloc (); |
|
60 #ifndef NULL |
|
61 #define NULL 0 |
|
62 #endif |
|
63 #endif |
|
64 |
|
65 char *stpcpy (); |
|
66 |
|
67 /* Return a freshly allocated string containing the filenames |
|
68 in directory DIR, separated by '\0' characters; |
|
69 the end is marked by two '\0' characters in a row. |
|
70 NAME_SIZE is the number of bytes to initially allocate |
|
71 for the string; it will be enlarged as needed. |
|
72 Return NULL if DIR cannot be opened or if out of memory. */ |
|
73 |
|
74 char * |
|
75 savedir (dir, name_size) |
|
76 char *dir; |
|
77 unsigned name_size; |
|
78 { |
|
79 DIR *dirp; |
285
|
80 struct dirent *dp; |
5
|
81 char *name_space; |
|
82 char *namep; |
|
83 |
|
84 dirp = opendir (dir); |
|
85 if (dirp == NULL) |
|
86 return NULL; |
|
87 |
|
88 name_space = (char *) malloc (name_size); |
|
89 if (name_space == NULL) |
|
90 { |
|
91 closedir (dirp); |
|
92 return NULL; |
|
93 } |
|
94 namep = name_space; |
|
95 |
|
96 while ((dp = readdir (dirp)) != NULL) |
|
97 { |
|
98 /* Skip "." and ".." (some NFS filesystems' directories lack them). */ |
|
99 if (dp->d_name[0] != '.' |
|
100 || (dp->d_name[1] != '\0' |
|
101 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) |
|
102 { |
329
|
103 unsigned size_needed = (namep - name_space) + NAMLEN (dp) + 2; |
5
|
104 |
|
105 if (size_needed > name_size) |
|
106 { |
|
107 char *new_name_space; |
|
108 |
|
109 while (size_needed > name_size) |
|
110 name_size += 1024; |
|
111 |
|
112 new_name_space = realloc (name_space, name_size); |
|
113 if (new_name_space == NULL) |
|
114 { |
|
115 closedir (dirp); |
|
116 return NULL; |
|
117 } |
|
118 namep += new_name_space - name_space; |
|
119 name_space = new_name_space; |
|
120 } |
|
121 namep = stpcpy (namep, dp->d_name) + 1; |
|
122 } |
|
123 } |
|
124 *namep = '\0'; |
|
125 if (CLOSEDIR (dirp)) |
|
126 { |
|
127 free (name_space); |
|
128 return NULL; |
|
129 } |
|
130 return name_space; |
|
131 } |