Skip to content

Latest commit

 

History

History
376 lines (297 loc) · 11.2 KB

dir.c

File metadata and controls

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