Skip to content

Latest commit

 

History

History
378 lines (299 loc) · 11.2 KB

dir.c

File metadata and controls

378 lines (299 loc) · 11.2 KB
 
Jul 7, 2001
Jul 7, 2001
1
2
3
4
5
6
7
8
/*
* Standard directory I/O support routines for PhysicsFS.
*
* Please see the file LICENSE in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
May 10, 2002
May 10, 2002
9
10
11
12
#if HAVE_CONFIG_H
# include <config.h>
#endif
Jul 7, 2001
Jul 7, 2001
13
14
#include <stdio.h>
#include <stdlib.h>
Jul 8, 2001
Jul 8, 2001
15
16
17
#include <string.h>
#include <errno.h>
#include <fcntl.h>
Jul 8, 2001
Jul 8, 2001
18
#include "physfs.h"
Jul 7, 2001
Jul 7, 2001
19
20
21
22
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
Mar 24, 2002
Mar 24, 2002
23
24
25
26
static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
Aug 21, 2002
Aug 21, 2002
27
28
29
30
static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
Sep 2, 2001
Sep 2, 2001
31
static int DIR_eof(FileHandle *handle);
Mar 24, 2002
Mar 24, 2002
32
33
34
static PHYSFS_sint64 DIR_tell(FileHandle *handle);
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset);
static PHYSFS_sint64 DIR_fileLength(FileHandle *handle);
Sep 2, 2001
Sep 2, 2001
35
36
37
38
39
40
41
static int DIR_fileClose(FileHandle *handle);
static int DIR_isArchive(const char *filename, int forWriting);
static DirHandle *DIR_openArchive(const char *name, int forWriting);
static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
const char *dname,
int omitSymLinks);
static int DIR_exists(DirHandle *h, const char *name);
Aug 21, 2002
Aug 21, 2002
42
43
44
45
static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists);
static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists);
static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist);
static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *f, int *e);
Sep 2, 2001
Sep 2, 2001
46
47
48
49
50
51
52
static FileHandle *DIR_openWrite(DirHandle *h, const char *filename);
static FileHandle *DIR_openAppend(DirHandle *h, const char *filename);
static int DIR_remove(DirHandle *h, const char *name);
static int DIR_mkdir(DirHandle *h, const char *name);
static void DIR_dirClose(DirHandle *h);
Jul 26, 2002
Jul 26, 2002
53
54
55
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
{
"",
Jul 28, 2002
Jul 28, 2002
56
DIR_ARCHIVE_DESCRIPTION,
Jul 26, 2002
Jul 26, 2002
57
58
59
60
61
"Ryan C. Gordon <icculus@clutteredmind.org>",
"http://icculus.org/physfs/",
};
Sep 2, 2001
Sep 2, 2001
62
63
static const FileFunctions __PHYSFS_FileFunctions_DIR =
{
Jun 29, 2002
Jun 29, 2002
64
DIR_read, /* read() method */
Aug 21, 2002
Aug 21, 2002
65
DIR_dummyWrite, /* write() method */
Jun 29, 2002
Jun 29, 2002
66
67
68
DIR_eof, /* eof() method */
DIR_tell, /* tell() method */
DIR_seek, /* seek() method */
Sep 2, 2001
Sep 2, 2001
69
DIR_fileLength, /* fileLength() method */
Jun 29, 2002
Jun 29, 2002
70
DIR_fileClose /* fileClose() method */
Sep 2, 2001
Sep 2, 2001
71
72
73
74
75
};
static const FileFunctions __PHYSFS_FileFunctions_DIRW =
{
Aug 21, 2002
Aug 21, 2002
76
DIR_dummyRead, /* read() method */
Sep 2, 2001
Sep 2, 2001
77
78
79
80
81
82
83
84
85
86
87
DIR_write, /* write() method */
DIR_eof, /* eof() method */
DIR_tell, /* tell() method */
DIR_seek, /* seek() method */
DIR_fileLength, /* fileLength() method */
DIR_fileClose /* fileClose() method */
};
const DirFunctions __PHYSFS_DirFunctions_DIR =
{
Jul 26, 2002
Jul 26, 2002
88
&__PHYSFS_ArchiveInfo_DIR,
Sep 2, 2001
Sep 2, 2001
89
90
91
92
93
94
DIR_isArchive, /* isArchive() method */
DIR_openArchive, /* openArchive() method */
DIR_enumerateFiles, /* enumerateFiles() method */
DIR_exists, /* exists() method */
DIR_isDirectory, /* isDirectory() method */
DIR_isSymLink, /* isSymLink() method */
May 25, 2002
May 25, 2002
95
DIR_getLastModTime, /* getLastModTime() method */
Sep 2, 2001
Sep 2, 2001
96
97
98
99
100
101
102
103
104
DIR_openRead, /* openRead() method */
DIR_openWrite, /* openWrite() method */
DIR_openAppend, /* openAppend() method */
DIR_remove, /* remove() method */
DIR_mkdir, /* mkdir() method */
DIR_dirClose /* dirClose() method */
};
Mar 24, 2002
Mar 24, 2002
105
106
static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
Jul 8, 2001
Jul 8, 2001
107
{
Mar 25, 2002
Mar 25, 2002
108
109
110
PHYSFS_sint64 retval;
retval = __PHYSFS_platformRead(handle->opaque, buffer, objSize, objCount);
return(retval);
Jul 8, 2001
Jul 8, 2001
111
112
113
} /* DIR_read */
Mar 24, 2002
Mar 24, 2002
114
115
static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
Jul 8, 2001
Jul 8, 2001
116
{
Mar 25, 2002
Mar 25, 2002
117
118
119
PHYSFS_sint64 retval;
retval = __PHYSFS_platformWrite(handle->opaque, buffer, objSize, objCount);
return(retval);
Jul 8, 2001
Jul 8, 2001
120
121
122
} /* DIR_write */
Aug 21, 2002
Aug 21, 2002
123
124
125
126
127
128
129
130
131
132
133
134
135
136
static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* DIR_dummyRead */
static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* DIR_dummyWrite */
Jul 8, 2001
Jul 8, 2001
137
138
static int DIR_eof(FileHandle *handle)
{
Mar 25, 2002
Mar 25, 2002
139
return(__PHYSFS_platformEOF(handle->opaque));
Jul 8, 2001
Jul 8, 2001
140
141
142
} /* DIR_eof */
Mar 24, 2002
Mar 24, 2002
143
static PHYSFS_sint64 DIR_tell(FileHandle *handle)
Jul 8, 2001
Jul 8, 2001
144
{
Mar 25, 2002
Mar 25, 2002
145
return(__PHYSFS_platformTell(handle->opaque));
Jul 8, 2001
Jul 8, 2001
146
147
148
} /* DIR_tell */
Mar 24, 2002
Mar 24, 2002
149
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset)
Jul 8, 2001
Jul 8, 2001
150
{
Mar 25, 2002
Mar 25, 2002
151
return(__PHYSFS_platformSeek(handle->opaque, offset));
Jul 8, 2001
Jul 8, 2001
152
153
154
} /* DIR_seek */
Mar 24, 2002
Mar 24, 2002
155
static PHYSFS_sint64 DIR_fileLength(FileHandle *handle)
Jul 9, 2001
Jul 9, 2001
156
{
Mar 25, 2002
Mar 25, 2002
157
return(__PHYSFS_platformFileLength(handle->opaque));
Jul 9, 2001
Jul 9, 2001
158
159
160
} /* DIR_fileLength */
Jul 8, 2001
Jul 8, 2001
161
162
163
static int DIR_fileClose(FileHandle *handle)
{
/*
Mar 25, 2002
Mar 25, 2002
164
* we manually flush the buffer, since that's the place a close will
Jul 8, 2001
Jul 8, 2001
165
* most likely fail, but that will leave the file handle in an undefined
Mar 25, 2002
Mar 25, 2002
166
* state if it fails. Flush failures we can recover from.
Jul 8, 2001
Jul 8, 2001
167
*/
Mar 25, 2002
Mar 25, 2002
168
169
BAIL_IF_MACRO(!__PHYSFS_platformFlush(handle->opaque), NULL, 0);
BAIL_IF_MACRO(!__PHYSFS_platformClose(handle->opaque), NULL, 0);
Jul 8, 2001
Jul 8, 2001
170
171
172
173
174
175
176
177
178
179
180
181
182
183
free(handle);
return(1);
} /* DIR_fileClose */
static int DIR_isArchive(const char *filename, int forWriting)
{
/* directories ARE archives in this driver... */
return(__PHYSFS_platformIsDirectory(filename));
} /* DIR_isArchive */
static DirHandle *DIR_openArchive(const char *name, int forWriting)
{
Jul 8, 2001
Jul 8, 2001
184
const char *dirsep = PHYSFS_getDirSeparator();
Jul 8, 2001
Jul 8, 2001
185
DirHandle *retval = NULL;
Sep 2, 2001
Sep 2, 2001
186
187
size_t namelen = strlen(name);
size_t seplen = strlen(dirsep);
Jul 8, 2001
Jul 8, 2001
188
Jul 8, 2001
Jul 8, 2001
189
190
BAIL_IF_MACRO(!DIR_isArchive(name, forWriting),
ERR_UNSUPPORTED_ARCHIVE, NULL);
Jul 8, 2001
Jul 8, 2001
191
Oct 9, 2001
Oct 9, 2001
192
retval = (DirHandle *) malloc(sizeof (DirHandle));
Jul 8, 2001
Jul 8, 2001
193
194
195
196
197
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
retval->opaque = malloc(namelen + seplen + 1);
if (retval->opaque == NULL)
{
free(retval);
Oct 9, 2001
Oct 9, 2001
198
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
Jul 8, 2001
Jul 8, 2001
199
200
201
202
203
204
205
} /* if */
/* make sure there's a dir separator at the end of the string */
strcpy((char *) (retval->opaque), name);
if (strcmp((name + namelen) - seplen, dirsep) != 0)
strcat((char *) (retval->opaque), dirsep);
Oct 9, 2001
Oct 9, 2001
206
207
retval->funcs = &__PHYSFS_DirFunctions_DIR;
Jul 8, 2001
Jul 8, 2001
208
209
210
211
return(retval);
} /* DIR_openArchive */
Jul 16, 2001
Jul 16, 2001
212
213
214
static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
const char *dname,
int omitSymLinks)
Jul 8, 2001
Jul 8, 2001
215
216
217
218
219
{
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque),dname,NULL);
LinkedStringList *retval;
BAIL_IF_MACRO(d == NULL, NULL, NULL);
Jul 16, 2001
Jul 16, 2001
220
retval = __PHYSFS_platformEnumerateFiles(d, omitSymLinks);
Jul 8, 2001
Jul 8, 2001
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
free(d);
return(retval);
} /* DIR_enumerateFiles */
static int DIR_exists(DirHandle *h, const char *name)
{
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
int retval;
BAIL_IF_MACRO(f == NULL, NULL, 0);
retval = __PHYSFS_platformExists(f);
free(f);
return(retval);
} /* DIR_exists */
Aug 21, 2002
Aug 21, 2002
238
static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists)
Jul 8, 2001
Jul 8, 2001
239
240
{
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
Aug 21, 2002
Aug 21, 2002
241
int retval = 0;
Jul 8, 2001
Jul 8, 2001
242
243
BAIL_IF_MACRO(d == NULL, NULL, 0);
Aug 21, 2002
Aug 21, 2002
244
245
246
*fileExists = __PHYSFS_platformExists(d);
if (*fileExists)
retval = __PHYSFS_platformIsDirectory(d);
Jul 8, 2001
Jul 8, 2001
247
248
249
250
251
free(d);
return(retval);
} /* DIR_isDirectory */
Aug 21, 2002
Aug 21, 2002
252
static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists)
Jul 8, 2001
Jul 8, 2001
253
254
{
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
Aug 21, 2002
Aug 21, 2002
255
int retval = 0;
Jul 8, 2001
Jul 8, 2001
256
May 21, 2002
May 21, 2002
257
BAIL_IF_MACRO(f == NULL, NULL, 0);
Aug 21, 2002
Aug 21, 2002
258
259
260
*fileExists = __PHYSFS_platformExists(f);
if (*fileExists)
retval = __PHYSFS_platformIsSymLink(f);
Jul 8, 2001
Jul 8, 2001
261
262
263
264
265
free(f);
return(retval);
} /* DIR_isSymLink */
Aug 21, 2002
Aug 21, 2002
266
267
268
static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h,
const char *name,
int *fileExists)
May 25, 2002
May 25, 2002
269
270
{
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
Aug 21, 2002
Aug 21, 2002
271
PHYSFS_sint64 retval = -1;
May 25, 2002
May 25, 2002
272
273
BAIL_IF_MACRO(d == NULL, NULL, 0);
Aug 21, 2002
Aug 21, 2002
274
275
276
*fileExists = __PHYSFS_platformExists(d);
if (*fileExists)
retval = __PHYSFS_platformGetLastModTime(d);
May 25, 2002
May 25, 2002
277
278
279
280
281
free(d);
return(retval);
} /* DIR_getLastModTime */
Mar 25, 2002
Mar 25, 2002
282
283
static FileHandle *doOpen(DirHandle *h, const char *name,
void *(*openFunc)(const char *filename),
Aug 21, 2002
Aug 21, 2002
284
int *fileExists, const FileFunctions *fileFuncs)
Jul 8, 2001
Jul 8, 2001
285
286
{
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
Mar 25, 2002
Mar 25, 2002
287
void *rc;
Jul 8, 2001
Jul 8, 2001
288
289
290
291
FileHandle *retval;
BAIL_IF_MACRO(f == NULL, NULL, NULL);
Aug 21, 2002
Aug 21, 2002
292
293
294
295
296
297
298
299
300
301
if (fileExists != NULL)
{
*fileExists = __PHYSFS_platformExists(f);
if (!(*fileExists))
{
free(f);
return(NULL);
} /* if */
} /* if */
Jul 8, 2001
Jul 8, 2001
302
303
304
305
retval = (FileHandle *) malloc(sizeof (FileHandle));
if (!retval)
{
free(f);
Mar 25, 2002
Mar 25, 2002
306
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
Jul 8, 2001
Jul 8, 2001
307
308
} /* if */
Mar 25, 2002
Mar 25, 2002
309
rc = openFunc(f);
Jul 8, 2001
Jul 8, 2001
310
311
312
313
314
free(f);
if (!rc)
{
free(retval);
Mar 25, 2002
Mar 25, 2002
315
return(NULL);
Jul 8, 2001
Jul 8, 2001
316
317
318
319
} /* if */
retval->opaque = (void *) rc;
retval->dirHandle = h;
Mar 25, 2002
Mar 25, 2002
320
321
retval->funcs = fileFuncs;
Jul 8, 2001
Jul 8, 2001
322
323
324
325
return(retval);
} /* doOpen */
Aug 21, 2002
Aug 21, 2002
326
static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist)
Jul 8, 2001
Jul 8, 2001
327
{
Aug 21, 2002
Aug 21, 2002
328
return(doOpen(h, fnm, __PHYSFS_platformOpenRead, exist,
Mar 25, 2002
Mar 25, 2002
329
&__PHYSFS_FileFunctions_DIR));
Jul 8, 2001
Jul 8, 2001
330
331
332
333
334
} /* DIR_openRead */
static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
{
Aug 21, 2002
Aug 21, 2002
335
return(doOpen(h, filename, __PHYSFS_platformOpenWrite, NULL,
Mar 25, 2002
Mar 25, 2002
336
&__PHYSFS_FileFunctions_DIRW));
Jul 8, 2001
Jul 8, 2001
337
338
339
340
341
} /* DIR_openWrite */
static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
{
Aug 21, 2002
Aug 21, 2002
342
return(doOpen(h, filename, __PHYSFS_platformOpenAppend, NULL,
Mar 25, 2002
Mar 25, 2002
343
&__PHYSFS_FileFunctions_DIRW));
Jul 8, 2001
Jul 8, 2001
344
345
346
347
348
349
350
351
352
} /* DIR_openAppend */
static int DIR_remove(DirHandle *h, const char *name)
{
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
int retval;
BAIL_IF_MACRO(f == NULL, NULL, 0);
Mar 25, 2002
Mar 25, 2002
353
retval = __PHYSFS_platformDelete(f);
Jul 8, 2001
Jul 8, 2001
354
355
356
357
358
359
360
361
362
363
364
free(f);
return(retval);
} /* DIR_remove */
static int DIR_mkdir(DirHandle *h, const char *name)
{
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
int retval;
BAIL_IF_MACRO(f == NULL, NULL, 0);
Aug 23, 2001
Aug 23, 2001
365
retval = __PHYSFS_platformMkDir(f);
Jul 8, 2001
Jul 8, 2001
366
367
368
369
370
371
372
373
374
375
376
free(f);
return(retval);
} /* DIR_mkdir */
static void DIR_dirClose(DirHandle *h)
{
free(h->opaque);
free(h);
} /* DIR_dirClose */
Jul 7, 2001
Jul 7, 2001
377
/* end of dir.c ... */