39 case EDQUOT: return PHYSFS_ERR_NO_SPACE; |
39 case EDQUOT: return PHYSFS_ERR_NO_SPACE; |
40 case EIO: return PHYSFS_ERR_IO; |
40 case EIO: return PHYSFS_ERR_IO; |
41 case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP; |
41 case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP; |
42 case EMLINK: return PHYSFS_ERR_NO_SPACE; |
42 case EMLINK: return PHYSFS_ERR_NO_SPACE; |
43 case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME; |
43 case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME; |
44 case ENOENT: return PHYSFS_ERR_NO_SUCH_PATH; |
44 case ENOENT: return PHYSFS_ERR_NOT_FOUND; |
45 case ENOSPC: return PHYSFS_ERR_NO_SPACE; |
45 case ENOSPC: return PHYSFS_ERR_NO_SPACE; |
46 case ENOTDIR: return PHYSFS_ERR_NO_SUCH_PATH; |
46 case ENOTDIR: return PHYSFS_ERR_NOT_FOUND; |
47 case EISDIR: return PHYSFS_ERR_NOT_A_FILE; |
47 case EISDIR: return PHYSFS_ERR_NOT_A_FILE; |
48 case EROFS: return PHYSFS_ERR_READ_ONLY; |
48 case EROFS: return PHYSFS_ERR_READ_ONLY; |
49 case ETXTBSY: return PHYSFS_ERR_BUSY; |
49 case ETXTBSY: return PHYSFS_ERR_BUSY; |
50 case EBUSY: return PHYSFS_ERR_BUSY; |
50 case EBUSY: return PHYSFS_ERR_BUSY; |
51 case ENOMEM: return PHYSFS_ERR_OUT_OF_MEMORY; |
51 case ENOMEM: return PHYSFS_ERR_OUT_OF_MEMORY; |
120 return retval; |
120 return retval; |
121 } /* __PHYSFS_platformCalcUserDir */ |
121 } /* __PHYSFS_platformCalcUserDir */ |
122 |
122 |
123 |
123 |
124 void __PHYSFS_platformEnumerateFiles(const char *dirname, |
124 void __PHYSFS_platformEnumerateFiles(const char *dirname, |
125 int omitSymLinks, |
|
126 PHYSFS_EnumFilesCallback callback, |
125 PHYSFS_EnumFilesCallback callback, |
127 const char *origdir, |
126 const char *origdir, |
128 void *callbackdata) |
127 void *callbackdata) |
129 { |
128 { |
130 DIR *dir; |
129 DIR *dir; |
131 struct dirent *ent; |
130 struct dirent *ent; |
132 int bufsize = 0; |
|
133 char *buf = NULL; |
131 char *buf = NULL; |
134 int dlen = 0; |
|
135 |
|
136 if (omitSymLinks) /* !!! FIXME: this malloc sucks. */ |
|
137 { |
|
138 dlen = strlen(dirname); |
|
139 bufsize = dlen + 256; |
|
140 buf = (char *) allocator.Malloc(bufsize); |
|
141 if (buf == NULL) |
|
142 return; |
|
143 strcpy(buf, dirname); |
|
144 if (buf[dlen - 1] != '/') |
|
145 { |
|
146 buf[dlen++] = '/'; |
|
147 buf[dlen] = '\0'; |
|
148 } /* if */ |
|
149 } /* if */ |
|
150 |
132 |
151 errno = 0; |
133 errno = 0; |
152 dir = opendir(dirname); |
134 dir = opendir(dirname); |
153 if (dir == NULL) |
135 if (dir == NULL) |
154 { |
136 { |
158 |
140 |
159 while ((ent = readdir(dir)) != NULL) |
141 while ((ent = readdir(dir)) != NULL) |
160 { |
142 { |
161 if (strcmp(ent->d_name, ".") == 0) |
143 if (strcmp(ent->d_name, ".") == 0) |
162 continue; |
144 continue; |
163 |
145 else if (strcmp(ent->d_name, "..") == 0) |
164 if (strcmp(ent->d_name, "..") == 0) |
|
165 continue; |
146 continue; |
166 |
|
167 if (omitSymLinks) |
|
168 { |
|
169 PHYSFS_Stat statbuf; |
|
170 int exists = 0; |
|
171 char *p; |
|
172 int len = strlen(ent->d_name) + dlen + 1; |
|
173 if (len > bufsize) |
|
174 { |
|
175 p = (char *) allocator.Realloc(buf, len); |
|
176 if (p == NULL) |
|
177 continue; |
|
178 buf = p; |
|
179 bufsize = len; |
|
180 } /* if */ |
|
181 |
|
182 strcpy(buf + dlen, ent->d_name); |
|
183 |
|
184 if (!__PHYSFS_platformStat(buf, &exists, &statbuf)) |
|
185 continue; |
|
186 else if (!exists) |
|
187 continue; /* probably can't happen, but just in case. */ |
|
188 else if (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK) |
|
189 continue; |
|
190 } /* if */ |
|
191 |
147 |
192 callback(callbackdata, origdir, ent->d_name); |
148 callback(callbackdata, origdir, ent->d_name); |
193 } /* while */ |
149 } /* while */ |
194 |
150 |
195 allocator.Free(buf); |
151 allocator.Free(buf); |
321 |
277 |
322 |
278 |
323 int __PHYSFS_platformFlush(void *opaque) |
279 int __PHYSFS_platformFlush(void *opaque) |
324 { |
280 { |
325 const int fd = *((int *) opaque); |
281 const int fd = *((int *) opaque); |
326 BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0); |
282 if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY) |
|
283 BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0); |
327 return 1; |
284 return 1; |
328 } /* __PHYSFS_platformFlush */ |
285 } /* __PHYSFS_platformFlush */ |
329 |
286 |
330 |
287 |
331 void __PHYSFS_platformClose(void *opaque) |
288 void __PHYSFS_platformClose(void *opaque) |
341 BAIL_IF_MACRO(remove(path) == -1, errcodeFromErrno(), 0); |
298 BAIL_IF_MACRO(remove(path) == -1, errcodeFromErrno(), 0); |
342 return 1; |
299 return 1; |
343 } /* __PHYSFS_platformDelete */ |
300 } /* __PHYSFS_platformDelete */ |
344 |
301 |
345 |
302 |
346 int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *st) |
303 int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st) |
347 { |
304 { |
348 struct stat statbuf; |
305 struct stat statbuf; |
349 |
306 |
350 if (lstat(filename, &statbuf) == -1) |
307 BAIL_IF_MACRO(lstat(filename, &statbuf) == -1, errcodeFromErrno(), 0); |
351 { |
|
352 *exists = (errno != ENOENT); |
|
353 BAIL_MACRO(errcodeFromErrno(), 0); |
|
354 } /* if */ |
|
355 |
|
356 *exists = 1; |
|
357 |
308 |
358 if (S_ISREG(statbuf.st_mode)) |
309 if (S_ISREG(statbuf.st_mode)) |
359 { |
310 { |
360 st->filetype = PHYSFS_FILETYPE_REGULAR; |
311 st->filetype = PHYSFS_FILETYPE_REGULAR; |
361 st->filesize = statbuf.st_size; |
312 st->filesize = statbuf.st_size; |
362 } /* if */ |
313 } /* if */ |
363 |
314 |
364 else if(S_ISDIR(statbuf.st_mode)) |
315 else if(S_ISDIR(statbuf.st_mode)) |
365 { |
316 { |
366 st->filetype = PHYSFS_FILETYPE_DIRECTORY; |
317 st->filetype = PHYSFS_FILETYPE_DIRECTORY; |
|
318 st->filesize = 0; |
|
319 } /* else if */ |
|
320 |
|
321 else if(S_ISLNK(statbuf.st_mode)) |
|
322 { |
|
323 st->filetype = PHYSFS_FILETYPE_SYMLINK; |
367 st->filesize = 0; |
324 st->filesize = 0; |
368 } /* else if */ |
325 } /* else if */ |
369 |
326 |
370 else |
327 else |
371 { |
328 { |