archiver_dir.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Standard directory I/O support routines for PhysicsFS.
  3. *
  4. * Please see the file LICENSE.txt in the source's root directory.
  5. *
  6. * This file written by Ryan C. Gordon.
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "physfs.h"
  12. #define __PHYSICSFS_INTERNAL__
  13. #include "physfs_internal.h"
  14. /* There's no PHYSFS_Io interface here. Use __PHYSFS_createNativeIo(). */
  15. static void *DIR_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
  16. {
  17. const char *dirsep = PHYSFS_getDirSeparator();
  18. char *retval = NULL;
  19. const size_t namelen = strlen(name);
  20. const size_t seplen = strlen(dirsep);
  21. assert(io == NULL); /* shouldn't create an Io for these. */
  22. BAIL_IF_MACRO(!__PHYSFS_platformIsDirectory(name), ERR_NOT_AN_ARCHIVE, NULL);
  23. retval = allocator.Malloc(namelen + seplen + 1);
  24. BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
  25. /* make sure there's a dir separator at the end of the string */
  26. /* !!! FIXME: is there really any place where (seplen != 1)? */
  27. strcpy(retval, name);
  28. if (strcmp((name + namelen) - seplen, dirsep) != 0)
  29. strcat(retval, dirsep);
  30. return retval;
  31. } /* DIR_openArchive */
  32. /* !!! FIXME: I would like to smallAlloc() all these conversions somehow. */
  33. static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
  34. int omitSymLinks, PHYSFS_EnumFilesCallback cb,
  35. const char *origdir, void *callbackdata)
  36. {
  37. char *d = __PHYSFS_platformCvtToDependent((char *) opaque, dname, NULL);
  38. if (d != NULL)
  39. {
  40. __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
  41. origdir, callbackdata);
  42. allocator.Free(d);
  43. } /* if */
  44. } /* DIR_enumerateFiles */
  45. static int DIR_exists(dvoid *opaque, const char *name)
  46. {
  47. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  48. int retval;
  49. BAIL_IF_MACRO(f == NULL, NULL, 0);
  50. retval = __PHYSFS_platformExists(f);
  51. allocator.Free(f);
  52. return retval;
  53. } /* DIR_exists */
  54. static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists)
  55. {
  56. char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  57. int retval = 0;
  58. BAIL_IF_MACRO(d == NULL, NULL, 0);
  59. *fileExists = __PHYSFS_platformExists(d);
  60. if (*fileExists)
  61. retval = __PHYSFS_platformIsDirectory(d);
  62. allocator.Free(d);
  63. return retval;
  64. } /* DIR_isDirectory */
  65. static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists)
  66. {
  67. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  68. int retval = 0;
  69. BAIL_IF_MACRO(f == NULL, NULL, 0);
  70. *fileExists = __PHYSFS_platformExists(f);
  71. if (*fileExists)
  72. retval = __PHYSFS_platformIsSymLink(f);
  73. allocator.Free(f);
  74. return retval;
  75. } /* DIR_isSymLink */
  76. static PHYSFS_Io *doOpen(dvoid *opaque, const char *name,
  77. const int mode, int *fileExists)
  78. {
  79. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  80. PHYSFS_Io *io = NULL;
  81. int existtmp = 0;
  82. if (fileExists == NULL)
  83. fileExists = &existtmp;
  84. *fileExists = 0;
  85. BAIL_IF_MACRO(f == NULL, NULL, NULL);
  86. io = __PHYSFS_createNativeIo(f, mode);
  87. allocator.Free(f);
  88. if (io == NULL)
  89. {
  90. *fileExists = __PHYSFS_platformExists(f);
  91. return NULL;
  92. } /* if */
  93. *fileExists = 1;
  94. return io;
  95. } /* doOpen */
  96. static PHYSFS_Io *DIR_openRead(dvoid *opaque, const char *fnm, int *exist)
  97. {
  98. return doOpen(opaque, fnm, 'r', exist);
  99. } /* DIR_openRead */
  100. static PHYSFS_Io *DIR_openWrite(dvoid *opaque, const char *filename)
  101. {
  102. return doOpen(opaque, filename, 'w', NULL);
  103. } /* DIR_openWrite */
  104. static PHYSFS_Io *DIR_openAppend(dvoid *opaque, const char *filename)
  105. {
  106. return doOpen(opaque, filename, 'a', NULL);
  107. } /* DIR_openAppend */
  108. static int DIR_remove(dvoid *opaque, const char *name)
  109. {
  110. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  111. int retval;
  112. BAIL_IF_MACRO(f == NULL, NULL, 0);
  113. retval = __PHYSFS_platformDelete(f);
  114. allocator.Free(f);
  115. return retval;
  116. } /* DIR_remove */
  117. static int DIR_mkdir(dvoid *opaque, const char *name)
  118. {
  119. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  120. int retval;
  121. BAIL_IF_MACRO(f == NULL, NULL, 0);
  122. retval = __PHYSFS_platformMkDir(f);
  123. allocator.Free(f);
  124. return retval;
  125. } /* DIR_mkdir */
  126. static void DIR_dirClose(dvoid *opaque)
  127. {
  128. allocator.Free(opaque);
  129. } /* DIR_dirClose */
  130. static int DIR_stat(dvoid *opaque, const char *name, int *exists,
  131. PHYSFS_Stat *stat)
  132. {
  133. char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  134. int retval = 0;
  135. BAIL_IF_MACRO(d == NULL, NULL, 0);
  136. retval = __PHYSFS_platformStat(d, exists, stat);
  137. allocator.Free(d);
  138. return retval;
  139. } /* DIR_stat */
  140. const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
  141. {
  142. "",
  143. DIR_ARCHIVE_DESCRIPTION,
  144. "Ryan C. Gordon <icculus@icculus.org>",
  145. "http://icculus.org/physfs/",
  146. };
  147. const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
  148. {
  149. &__PHYSFS_ArchiveInfo_DIR,
  150. DIR_openArchive, /* openArchive() method */
  151. DIR_enumerateFiles, /* enumerateFiles() method */
  152. DIR_exists, /* exists() method */
  153. DIR_isDirectory, /* isDirectory() method */
  154. DIR_isSymLink, /* isSymLink() method */
  155. DIR_openRead, /* openRead() method */
  156. DIR_openWrite, /* openWrite() method */
  157. DIR_openAppend, /* openAppend() method */
  158. DIR_remove, /* remove() method */
  159. DIR_mkdir, /* mkdir() method */
  160. DIR_dirClose, /* dirClose() method */
  161. DIR_stat /* stat() method */
  162. };
  163. /* end of dir.c ... */