1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "dir.h"
26 #include "strarr.h"
27 #include "strings.h"
28 #include "paths.h"
29 #include <ctype.h>
30
31 #if defined(CONFIG_POSIX)
32 # include <sys/types.h>
33 # include <sys/stat.h>
34 # include <dirent.h>
35 # include <unistd.h>
36 #endif
37
38 #if defined(CONFIG_OS_WINDOWS)
39 # include <windows.h>
40 # include <sys/stat.h>
41 # include <io.h>
42 #endif
43 mike 1.1
44 /*
45 **==============================================================================
46 **
47 ** POSIC Implementation
48 **
49 **==============================================================================
50 */
51
52 #if defined(CONFIG_POSIX)
53
54 struct _Dir
55 {
56 DIR* dir;
57 DirEnt ent;
58 };
59
60 Dir* Dir_Open(const char* path)
61 {
62 Dir* self = (Dir*)calloc(1, sizeof(Dir));
63
64 mike 1.1 if (!self)
65 return NULL;
66
67 self->dir = opendir(path);
68 if (!self->dir)
69 {
70 free(self);
71 return NULL;
72 }
73
74 return self;
75 }
76
77 DirEnt* Dir_Read(Dir* self)
78 {
79 struct dirent* p = readdir(self->dir);
80 if (!p)
81 return NULL;
82
83 Strlcpy(self->ent.name, p->d_name, sizeof(self->ent.name));
84 self->ent.type = 0;
85 mike 1.1
86 return &self->ent;
87 }
88
89 int Dir_Close(Dir* self)
90 {
91 if (!self)
92 return -1;
93
94 if (closedir(self->dir) != 0)
95 {
96 free(self);
97 return -1;
98 }
99
100 free(self);
101 return 0;
102 }
103
104 #endif /* defined(CONFIG_POSIX) */
105
106 mike 1.1 /*
107 **==============================================================================
108 **
109 ** Windows Implementation
110 **
111 **==============================================================================
112 */
113
114 #if defined(CONFIG_OS_WINDOWS)
115
116 struct _Dir
117 {
118 intptr_t handle;
119 struct _finddata_t fileinfo;
120 DirEnt ent;
121 int firstTime;
122 };
123
124 Dir* Dir_Open(const char* path)
125 {
126 Dir* dir;
127 mike 1.1 char filespec[MAX_PATH_SIZE];
128
129 /* Allocate and zero-fill struct */
130 dir = (Dir*)calloc(1, sizeof(Dir));
131 if (!dir)
132 return NULL;
133
134 /* Build files spec */
135 {
136 if (Strlcpy(filespec, path, sizeof(filespec)) >= MAX_PATH_SIZE)
137 return NULL;
138
139 if (Strlcat(filespec, "/*", sizeof(filespec)) >= MAX_PATH_SIZE)
140 return NULL;
141 }
142
143 /* Find first file matching the file spec */
144 dir->handle = _findfirst(filespec, &dir->fileinfo);
145 if (dir->handle == -1)
146 {
147 free(dir);
148 mike 1.1 return NULL;
149 }
150
151 /* Note that readdir() has not been called yet */
152 dir->firstTime = 1;
153
154 return dir;
155 }
156
157 DirEnt* Dir_Read(Dir* dir)
158 {
159 if (!dir->firstTime)
160 {
161 if (_findnext(dir->handle, &dir->fileinfo) != 0)
162 return NULL;
163 }
164
165 Strlcpy(dir->ent.name, dir->fileinfo.name, MAX_PATH_SIZE);
166 dir->firstTime = 0;
167 return &dir->ent;
168 }
169 mike 1.1
170 int Dir_Close(Dir* dir)
171 {
172 _findclose(dir->handle);
173 free(dir);
174 return 0;
175 }
176
177 #endif /* defined(CONFIG_OS_WINDOWS) */
178
179 char** Listdir(const char* path)
180 {
181 Dir* dir;
182 char** arr;
183
184 dir = Dir_Open(path);
185 if (!dir)
186 return NULL;
187
188 arr = StrArr();
189 if (!arr)
190 mike 1.1 {
191 Dir_Close(dir);
192 return NULL;
193 }
194
195 for (;;)
196 {
197 DirEnt* ent = Dir_Read(dir);
198 if (!ent)
199 break;
200
201 if (strcmp(ent->name, ".") == 0 || strcmp(ent->name, "..") == 0)
202 continue;
203
204 StrArrCat(&arr, ent->name);
205 }
206
207 Dir_Close(dir);
208 return arr;
209 }
210
211 mike 1.1 MI_Boolean Isdir(const char* path)
212 {
213 #if defined(CONFIG_OS_WINDOWS)
214 {
215 struct _stat st;
216
217 if (_stat(path, &st) != 0)
218 return 0;
219
220 return (_S_IFDIR & st.st_mode) ? MI_TRUE : MI_FALSE;
221 }
222 #else
223 {
224 struct stat st;
225
226 if (stat(path, &st) != 0)
227 return 0;
228
229 return S_ISDIR(st.st_mode);
230 }
231 #endif
232 mike 1.1 }
233
234 int Mkdirhier(const char* path_, int mode)
235 {
236 char path[MAX_PATH_SIZE];
237 char buf[MAX_PATH_SIZE];
238 char* p;
239 char* context = NULL;
240
241 /* Make a complete copy of the path (that we can destroy) */
242 if (Strlcpy(path, path_, sizeof(path)) >= sizeof(path))
243 return -1;
244
245 buf[0] = '\0';
246
247 for (p = Strtok(path, "/", &context); p; p = Strtok(NULL, "/", &context))
248 {
249 #if defined(CONFIG_OS_WINDOWS)
250 /* Skip drive letters (on Windows) */
251 if (p == path && isalpha((unsigned char)p[0]) && p[1] == ':' && p[2] == '\0')
252 {
253 mike 1.1 Strlcat(buf, p, sizeof(buf));
254 continue;
255 }
256 #endif
257
258 /* Concatenate next component */
259 Strlcat(buf, "/", sizeof(buf));
260 Strlcat(buf, p, sizeof(buf));
261
262 /* Create directory if it does not already exist */
263 if (!Isdir(buf))
264 {
265 if (Mkdir(buf, mode) != 0)
266 return -1;
267 }
268 }
269
270 return 0;
271 }
272
273 char* TempPath(char path[MAX_PATH_SIZE], const char* file)
274 mike 1.1 {
275 if (Strlcpy(path, GetPath(ID_TMPDIR), MAX_PATH_SIZE) >= MAX_PATH_SIZE)
276 return NULL;
277
278 if (Strlcat(path, "/", MAX_PATH_SIZE) >= MAX_PATH_SIZE)
279 return NULL;
280
281 if (Strlcat(path, file, MAX_PATH_SIZE) >= MAX_PATH_SIZE)
282 return NULL;
283
284 return path;
285 }
286
287 MI_Char* ZSTempPath(MI_Char path[MAX_PATH_SIZE], const char* file)
288 {
289 if (ZStrlcpy(path, GetPath(ID_TMPDIR), MAX_PATH_SIZE) >= MAX_PATH_SIZE)
290 return NULL;
291
292 if (ZStrlcat(path, "/", MAX_PATH_SIZE) >= MAX_PATH_SIZE)
293 return NULL;
294
295 mike 1.1 if (ZStrlcat(path, file, MAX_PATH_SIZE) >= MAX_PATH_SIZE)
296 return NULL;
297
298 return path;
299 }
300
301 const char* Basename(const char* path)
302 {
303 const char* p = strrchr(path, '/');
304
305 if (p)
306 return p + 1;
307
308 return path;
309 }
|