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

  1 krisbash 1.1 #include "dir.h"
  2              #include <base/paths.h>
  3              #include <pal/strings.h>
  4              #include <ctype.h>
  5              
  6              #if defined(PAL_HAVE_POSIX)
  7              # include <sys/types.h>
  8              # include <sys/stat.h>
  9              # include <dirent.h>
 10              # include <unistd.h>
 11              #endif
 12              
 13              #if defined(_MSC_VER)
 14              # include <windows.h>
 15              # include <sys/stat.h>
 16              # include <io.h>
 17              #endif
 18              
 19              /*
 20              **==============================================================================
 21              **
 22 krisbash 1.1 ** Dir type (POSIX)
 23              **
 24              **==============================================================================
 25              */
 26              
 27              #if defined(PAL_HAVE_POSIX)
 28              
 29              struct _Dir
 30              {
 31                  DIR* dir;
 32                  DirEnt ent;
 33              };
 34              
 35              Dir* Dir_Open(const char* path)
 36              {
 37                  Dir* self = (Dir*)PAL_Calloc(1, sizeof(Dir));
 38              
 39                  if (!self)
 40                      return NULL;
 41              
 42                  self->dir = opendir(path);
 43 krisbash 1.1     if (!self->dir)
 44                  {
 45                      PAL_Free(self);
 46                      return NULL;
 47                  }
 48              
 49                  return self;
 50              }
 51              
 52              DirEnt* Dir_Read(Dir* self)
 53              {
 54                  struct dirent* p = readdir(self->dir);
 55                  if (!p)
 56                      return NULL;
 57              
 58                  Strlcpy(self->ent.name, p->d_name, sizeof(self->ent.name));
 59              
 60                  return &self->ent;
 61              }
 62              
 63              int Dir_Close(Dir* self)
 64 krisbash 1.1 {
 65                  if (!self)
 66                      return -1;
 67              
 68                  if (closedir(self->dir) != 0)
 69                  {
 70                      PAL_Free(self);
 71                      return -1;
 72                  }
 73              
 74                  PAL_Free(self);
 75                  return 0;
 76              }
 77              
 78              #endif /* defined(PAL_HAVE_POSIX) */
 79              
 80              /*
 81              **==============================================================================
 82              **
 83              ** Dir type (Windows)
 84              **
 85 krisbash 1.1 **==============================================================================
 86              */
 87              
 88              #if defined(_MSC_VER)
 89              
 90              struct _Dir
 91              {
 92                  intptr_t handle;
 93                  struct _finddata_t fileinfo;
 94                  DirEnt ent;
 95                  int firstTime;
 96              };
 97              
 98              Dir* Dir_Open(const char* path)
 99              {
100                  Dir* dir;
101                  char filespec[PAL_MAX_PATH_SIZE];
102                  
103                  /* Allocate and zero-fill struct */
104                  dir = (Dir*)PAL_Calloc(1, sizeof(Dir));
105                  if (!dir)
106 krisbash 1.1         return NULL;
107              
108                  /* Build files spec */
109                  {
110                      if (Strlcpy(filespec, path, sizeof(filespec)) >= PAL_MAX_PATH_SIZE)
111                          return NULL;
112              
113                      if (Strlcat(filespec, "/*", sizeof(filespec)) >= PAL_MAX_PATH_SIZE)
114                          return NULL;
115                  }
116              
117                  /* Find first file matching the file spec */
118                  dir->handle = _findfirst(filespec, &dir->fileinfo);
119                  if (dir->handle == -1)
120                  {
121                      PAL_Free(dir);
122                      return NULL;
123                  }
124              
125                  /* Note that readdir() has not been called yet */
126                  dir->firstTime = 1;
127 krisbash 1.1 
128                  return dir;
129              }
130              
131              DirEnt* Dir_Read(Dir* dir)
132              {
133                  if (!dir->firstTime)
134                  {
135                      if (_findnext(dir->handle, &dir->fileinfo) != 0)
136                          return NULL;
137                  }
138              
139                  Strlcpy(dir->ent.name, dir->fileinfo.name, PAL_MAX_PATH_SIZE);
140                  dir->firstTime = 0;
141                  return &dir->ent;
142              }
143              
144              int Dir_Close(Dir* dir)
145              {
146                  _findclose(dir->handle);
147                  PAL_Free(dir);
148 krisbash 1.1     return 0;
149              }
150              
151              #endif /* defined(_MSC_VER) */
152              
153              /*
154              **==============================================================================
155              **
156              ** Isdir()
157              **
158              **==============================================================================
159              */
160              
161              PAL_Boolean Isdir(const char* path)
162              {
163              #if defined(_MSC_VER)
164                  {
165                      struct _stat st;
166              
167                      if (_stat(path, &st) != 0)
168                          return 0;
169 krisbash 1.1 
170                      return (_S_IFDIR  & st.st_mode) ? PAL_TRUE : PAL_FALSE;
171                  }
172              #else
173                  {
174                      struct stat st;
175              
176                      if (stat(path, &st) != 0)
177                          return 0;
178              
179                      return S_ISDIR(st.st_mode);
180                  }
181              #endif
182              }
183              
184              const char* Basename(const char* path)
185              {
186                  const char* p = strrchr(path, '/');
187              
188                  if (p)
189                      return p + 1;
190 krisbash 1.1 
191                  return path;
192              }
193              
194              int Mkdirhier(const char* path_, int mode)
195              {
196                  char path[PAL_MAX_PATH_SIZE];
197                  char buf[PAL_MAX_PATH_SIZE];
198                  char* p;
199                  char* context = NULL;
200              
201                  /* Make a complete copy of the path (that we can destroy) */
202                  if (Strlcpy(path, path_, sizeof(path)) >= sizeof(path))
203                      return -1;
204              
205                  buf[0] = '\0';
206              
207                  for (p = Strtok(path, "/", &context); p; p = Strtok(NULL, "/", &context))
208                  {
209              #if defined(CONFIG_OS_WINDOWS)
210                      /* Skip drive letters (on Windows) */
211 krisbash 1.1         if (p == path && isalpha((unsigned char)p[0]) && p[1] == ':' && p[2] == '\0')
212                      {
213                          Strlcat(buf, p, sizeof(buf));
214                          continue;
215                      }
216              #endif
217              
218                      /* Concatenate next component */
219                      Strlcat(buf, "/", sizeof(buf));
220                      Strlcat(buf, p, sizeof(buf));
221              
222                      /* Create directory if it does not already exist */
223                      if (!Isdir(buf))
224                      {
225                          if (Mkdir(buf, mode) != 0)
226                              return -1;
227                      }
228                  }
229              
230                  return 0;
231              }

ViewCVS 0.9.2