1 /* $Id$
2 * Provides compiler-independent functions to read directory contents
3 *
4 * Copyright (C) 1998-1999
5 *
6 * Matthias Tichy
7 *
8 * Fido: 2:2433/1245 2:2433/1247 2:2432/605.14
9 * Internet: mtt@tichy.de
10 *
11 * Grimmestr. 12 Buchholzer Weg 4
12 * 33098 Paderborn 40472 Duesseldorf
13 * Germany Germany
14 *
15 * Latest version may be foind on http://husky.sourceforge.net
16 *
17 *
18 * HUSKYLIB: common defines, types and functions for HUSKY
19 *
20 * This is part of The HUSKY Fidonet Software project:
21 * see http://husky.sourceforge.net for details
22 *
23 *
24 * HUSKYLIB is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU Lesser General Public
26 * License as published by the Free Software Foundation; either
27 * version 2 of the License, or (at your option) any later version.
28 *
29 * HUSKYLIB is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32 * General Public License for more details.
33 *
34 * You should have received a copy of the GNU Lesser General Public
35 * License along with this library; see file COPYING. If not, write to the
36 * Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 * See also http://www.gnu.org, license may be found here.
39 */
40
41 /* standard headers */
42 #include <stdlib.h>
43 #include <string.h>
44 #include <errno.h>
45
46
47 /* huskylib: compiler.h */
48 #include <compiler.h>
49
50
51 /* compiler-dependent headers */
52 #ifdef HAS_IO_H
53 #include <io.h>
54 #endif
55
56 #ifdef HAS_DIR_H
57 #include <dir.h>
58 #endif
59
60 #ifdef HAS_DIRENT_H
61 #include <dirent.h>
62 #endif
63
64 #ifdef HAS_DIRECT_H
65 #include <direct.h>
66 #endif
67
68
69 /* huskylib headers */
70 #define DLLEXPORT
71 #include <huskyext.h>
72
73 /* huskylib headers */
74 #include <dirlayer.h>
75 #include <memory.h>
76 #include <strext.h>
77 #ifndef HAS_DIRENT_H
78 #include <ffind.h>
79 #endif
80 #include <fexist.h>
81
82 /*** Implementation *******************************************************/
83
84 #ifdef HAS_DIRENT_H
85 /* use compiler or system library: opendir/readdir/closedir */
86
husky_opendir(const char * mask)87 husky_DIR* husky_opendir(const char* mask)
88 { husky_DIR dir;
89
90 if(!mask) return NULL;
91 memset(&dir,0,sizeof(dir));
92
93 strncpy( dir.d_mask, mask, sizeof(dir.d_mask)-3 ); /* preserve two chars for "\\*"
94 d_mask filled by zero in previous source line */
95 #if 0
96 {
97 char *ch, *ch2;
98 ch = strrchr(d_mask,'/');
99 ch2 = strrchr(d_mask,'\\');
100 ch = max(ch,ch2);
101 if (ch && ch[1]=='\0') strcat(dir->d_mask,"*");
102 else strcat(dir->d_mask,"\\*");
103 }
104 #endif
105 dir.internal_DIR = opendir(mask);
106 if(!dir.internal_DIR) return NULL;
107
108 return memdup(&dir,sizeof(dir));
109 }
110
husky_readdir(husky_DIR * dir)111 char* husky_readdir(husky_DIR* dir)
112 { struct dirent *de;
113 if(!dir || !dir->internal_DIR) return 0;
114
115 do{
116 de = readdir(dir->internal_DIR);
117 if(!de || !de->d_name) return NULL;
118 }while( strcmp(de->d_name,".")==0 || strcmp(de->d_name,"..")==0 );
119 strnzcpy(dir->d_name, de->d_name, sizeof(dir->d_name));
120 dir->d_attr = 0; /* Use stat() for this! */
121 dir->d_size = -1;
122
123 return dir->d_name;
124 }
125
husky_closedir(husky_DIR * dir)126 int husky_closedir(husky_DIR* dir)
127 { int rc;
128
129 if(!dir || !dir->internal_DIR) return 0;
130
131 rc = closedir(dir->internal_DIR);
132 if(!rc){
133 free(dir);
134 }
135
136 return rc;
137 }
138
husky_rewinddir(husky_DIR * dir)139 void husky_rewinddir(husky_DIR* dir)
140 {
141 if(!dir || !dir->internal_DIR) return;
142
143 rewinddir(dir->internal_DIR);
144 dir->d_name[0] = '\0';
145 }
146
147 #else /* Use ffind.c */
148
husky_opendir(const char * mask)149 husky_DIR* husky_opendir(const char* mask)
150 { husky_DIR dir;
151
152 if(!mask) return NULL;
153
154 if(!direxist(mask)){
155 errno = ENOENT;
156 return NULL;
157 }
158 memset(&dir,0,sizeof(dir));
159
160 strncpy( dir.d_mask, mask, sizeof(dir.d_mask)-3 ); /* preserve two chars for "\\*"
161 d_mask filled by zero in previous source line */
162 {
163 char *ch, *ch2;
164 ch = strrchr(dir.d_mask,'/');
165 ch2 = strrchr(dir.d_mask,'\\');
166 ch = max(ch,ch2);
167 if (ch && ch[1]=='\0') strcat(dir.d_mask,"*");
168 else strcat(dir.d_mask,"\\*");
169 }
170 dir.d_first++;
171 return memdup(&dir,sizeof(dir));
172 }
173
174 /* Note: FFindInfo/FFindNext skips "." and ".." entries */
husky_readdir(husky_DIR * dir)175 char* husky_readdir(husky_DIR* dir)
176 {
177 if(!dir) return 0;
178
179 dir->d_name[0] = '\0';
180 dir->d_attr = 0;
181 dir->d_size = 0;
182
183 if(dir->d_first){
184 dir->ff = FFindInfo(dir->d_mask);
185 if((dir->ff)==NULL) return NULL;
186 dir->d_first=0;
187 }else{
188 if(FFindNext(dir->ff)) return NULL;
189 }
190
191 strnzcpy(dir->d_name, dir->ff->ff_name, sizeof(dir->d_name));
192 dir->d_attr = dir->ff->ff_attrib;
193 dir->d_size = dir->ff->ff_fsize;
194
195 return dir->d_name;
196 }
197
198
husky_closedir(husky_DIR * dir)199 int husky_closedir(husky_DIR* dir)
200 {
201 if(!dir) return -1;
202
203 FFindClose(dir->ff);
204 free(dir);
205
206 return 0;
207 }
208
209
husky_rewinddir(husky_DIR * dir)210 void husky_rewinddir(husky_DIR* dir)
211 {
212 if(!dir) return;
213
214 if(dir->ff) FFindClose(dir->ff);
215 dir->ff = NULL;
216 dir->d_first = 1;
217 dir->d_name[0] = '\0';
218 dir->d_attr = 0;
219 dir->d_size = 0;
220 }
221
222 #endif
223
224 #ifdef TEST
225
main(int argc,char ** argv)226 int main(int argc, char **argv){
227 husky_DIR *dd;
228 char *name=".";
229
230 if(argc>1) name = argv[1];
231
232 dd=husky_opendir(name);
233 while( (name=husky_readdir(dd)) )
234 printf("%s\n",name);
235
236 husky_closedir(dd);
237 return 0;
238 }
239 #endif
240