(file) Return to dir.c CVS log (file) (dir) Up to [OMI] / omi / base

  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           }

ViewCVS 0.9.2