zip.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * ZIP support routines for PhysicsFS.
  3. *
  4. * Please see the file LICENSE 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 <unistd.h>
  12. #include "physfs.h"
  13. #include "unzip.h"
  14. #define __PHYSICSFS_INTERNAL__
  15. #include "physfs_internal.h"
  16. #if (!defined PHYSFS_SUPPORTS_ZIP)
  17. #error PHYSFS_SUPPORTS_ZIP must be defined.
  18. #endif
  19. typedef struct
  20. {
  21. unzFile handle;
  22. uLong totalEntries;
  23. } ZIPinfo;
  24. typedef struct
  25. {
  26. } ZIPfileinfo;
  27. extern const DirFunctions __PHYSFS_DirFunctions_ZIP;
  28. static const FileFunctions __PHYSFS_FileFunctions_ZIP;
  29. static int ZIP_read(FileHandle *handle, void *buffer,
  30. unsigned int objSize, unsigned int objCount)
  31. {
  32. } /* ZIP_read */
  33. static int ZIP_eof(FileHandle *handle)
  34. {
  35. } /* ZIP_eof */
  36. static int ZIP_tell(FileHandle *handle)
  37. {
  38. } /* ZIP_tell */
  39. static int ZIP_seek(FileHandle *handle, int offset)
  40. {
  41. } /* ZIP_seek */
  42. static int ZIP_fileLength(FileHandle *handle)
  43. {
  44. } /* ZIP_fileLength */
  45. static int ZIP_fileClose(FileHandle *handle)
  46. {
  47. } /* ZIP_fileClose */
  48. static int ZIP_isArchive(const char *filename, int forWriting)
  49. {
  50. int retval = 0;
  51. unzFile unz = unzOpen(name);
  52. unz_global_info global;
  53. if (unz != NULL)
  54. {
  55. if (unzGetGlobalInfo(unz, &global) == UNZ_OK)
  56. retval = 1;
  57. unzClose(unz);
  58. } /* if */
  59. return(retval);
  60. } /* ZIP_isArchive */
  61. static DirHandle *ZIP_openArchive(const char *name, int forWriting)
  62. {
  63. unzFile unz = NULL;
  64. DirHandle *retval = NULL;
  65. unz_global_info global;
  66. BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
  67. errno = 0;
  68. BAIL_IF_MACRO(access(name, R_OK) != 0, strerror(errno), NULL);
  69. retval = malloc(sizeof (DirHandle));
  70. BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
  71. unz = unzOpen(name);
  72. if ((unz == NULL) || (unzGetGlobalInfo(unz, &global) != UNZ_OK))
  73. {
  74. if (unz)
  75. unzClose(unz);
  76. free(retval);
  77. BAIL_IF_MACRO(1, ERR_UNSUPPORTED_ARCHIVE, NULL);
  78. } /* if */
  79. retval->opaque = malloc(sizeof (ZIPinfo));
  80. if (retval->opaque == NULL)
  81. {
  82. free(retval);
  83. unzClose(unz);
  84. BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
  85. } /* if */
  86. ((ZIPinfo *) (retval->opaque))->handle = unz;
  87. ((ZIPinfo *) (retval->opaque))->totalEntries = global.number_entry;
  88. return(retval);
  89. } /* ZIP_openArchive */
  90. static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname)
  91. {
  92. ZIPinfo *zi = (ZIPinfo *) (h->opaque);
  93. unzFile fh = zi->handle;
  94. int i;
  95. LinkedStringList *retval = NULL;
  96. LinkedStringList *l = NULL;
  97. LinkedStringList *prev = NULL;
  98. char buffer[256];
  99. char *d;
  100. /* jump to first file entry... */
  101. BAIL_IF_MACRO(unzGoToFirstFile(fh) != UNZ_OK, ERR_IO_ERROR, NULL);
  102. i = strlen(dirname);
  103. d = malloc(i + 1);
  104. strcpy(d, dirname);
  105. if ((i > 0) && (d[i - 1] == '/')) /* no trailing slash. */
  106. d[i - 1] = '\0';
  107. for (i = 0; i < zi->totalEntries; i++)
  108. {
  109. char *ptr;
  110. unzGetCurrentFileInfo(fh, NULL, buf, sizeof (buf), NULL, 0, NULL, 0);
  111. ptr = strrchr(p, '/'); /* !!! check this! */
  112. if (ptr == NULL)
  113. {
  114. if (*d != '\0')
  115. continue; /* not for this dir; skip it. */
  116. ptr = buf;
  117. else
  118. {
  119. *ptr = '\0';
  120. ptr++;
  121. if (strcmp(buf, d) != 0)
  122. continue; /* not for this dir; skip it. */
  123. } /* else */
  124. l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
  125. if (l != NULL)
  126. break;
  127. l->str = (char *) malloc(strlen(ptr) + 1);
  128. if (l->str == NULL)
  129. {
  130. free(l);
  131. break;
  132. } /* if */
  133. if (retval == NULL)
  134. retval = l;
  135. else
  136. prev->next = l;
  137. prev = l;
  138. l->next = NULL;
  139. } /* for */
  140. free(d);
  141. return(retval);
  142. } /* ZIP_enumerateFiles */
  143. static int ZIP_exists(DirHandle *h, const char *name)
  144. {
  145. } /* ZIP_exists */
  146. static int ZIP_isDirectory(DirHandle *h, const char *name)
  147. {
  148. } /* ZIP_isDirectory */
  149. static int ZIP_isSymLink(DirHandle *h, const char *name)
  150. {
  151. } /* ZIP_isSymLink */
  152. static FileHandle *ZIP_openRead(DirHandle *h, const char *filename)
  153. {
  154. } /* ZIP_openRead */
  155. static void ZIP_dirClose(DirHandle *h)
  156. {
  157. } /* ZIP_dirClose */
  158. static const FileFunctions __PHYSFS_FileFunctions_ZIP =
  159. {
  160. ZIP_read, /* read() method */
  161. NULL, /* write() method */
  162. ZIP_eof, /* eof() method */
  163. ZIP_tell, /* tell() method */
  164. ZIP_seek, /* seek() method */
  165. ZIP_fileLength, /* fileLength() method */
  166. ZIP_fileClose /* fileClose() method */
  167. };
  168. const DirFunctions __PHYSFS_DirFunctions_ZIP =
  169. {
  170. ZIP_isArchive, /* isArchive() method */
  171. ZIP_openArchive, /* openArchive() method */
  172. ZIP_enumerateFiles, /* enumerateFiles() method */
  173. ZIP_exists, /* exists() method */
  174. ZIP_isDirectory, /* isDirectory() method */
  175. ZIP_isSymLink, /* isSymLink() method */
  176. ZIP_openRead, /* openRead() method */
  177. NULL, /* openWrite() method */
  178. NULL, /* openAppend() method */
  179. NULL, /* remove() method */
  180. NULL, /* mkdir() method */
  181. ZIP_dirClose /* dirClose() method */
  182. };
  183. const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
  184. {
  185. "ZIP",
  186. "PkZip/WinZip/Info-Zip compatible",
  187. "Ryan C. Gordon (icculus@linuxgames.com)",
  188. "http://www.icculus.org/~icculus/",
  189. };
  190. /* end of zip.c ... */