zip.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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,
  91. const char *dirname,
  92. int omitSymLinks)
  93. {
  94. ZIPinfo *zi = (ZIPinfo *) (h->opaque);
  95. unzFile fh = zi->handle;
  96. int i;
  97. LinkedStringList *retval = NULL;
  98. LinkedStringList *l = NULL;
  99. LinkedStringList *prev = NULL;
  100. char buffer[256];
  101. char *d;
  102. /* jump to first file entry... */
  103. BAIL_IF_MACRO(unzGoToFirstFile(fh) != UNZ_OK, ERR_IO_ERROR, NULL);
  104. i = strlen(dirname);
  105. d = malloc(i + 1);
  106. strcpy(d, dirname);
  107. if ((i > 0) && (d[i - 1] == '/')) /* no trailing slash. */
  108. d[i - 1] = '\0';
  109. for (i = 0; i < zi->totalEntries; i++)
  110. {
  111. char *ptr;
  112. unzGetCurrentFileInfo(fh, NULL, buf, sizeof (buf), NULL, 0, NULL, 0);
  113. ptr = strrchr(p, '/'); /* !!! check this! */
  114. if (ptr == NULL)
  115. {
  116. if (*d != '\0')
  117. continue; /* not for this dir; skip it. */
  118. ptr = buf;
  119. else
  120. {
  121. *ptr = '\0';
  122. ptr++;
  123. if (strcmp(buf, d) != 0)
  124. continue; /* not for this dir; skip it. */
  125. } /* else */
  126. l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
  127. if (l == NULL)
  128. break;
  129. l->str = (char *) malloc(strlen(ptr) + 1);
  130. if (l->str == NULL)
  131. {
  132. free(l);
  133. break;
  134. } /* if */
  135. strcpy(l->str, ptr);
  136. if (retval == NULL)
  137. retval = l;
  138. else
  139. prev->next = l;
  140. prev = l;
  141. l->next = NULL;
  142. } /* for */
  143. free(d);
  144. return(retval);
  145. } /* ZIP_enumerateFiles */
  146. static int ZIP_exists(DirHandle *h, const char *name)
  147. {
  148. } /* ZIP_exists */
  149. static int ZIP_isDirectory(DirHandle *h, const char *name)
  150. {
  151. } /* ZIP_isDirectory */
  152. static int ZIP_isSymLink(DirHandle *h, const char *name)
  153. {
  154. } /* ZIP_isSymLink */
  155. static FileHandle *ZIP_openRead(DirHandle *h, const char *filename)
  156. {
  157. } /* ZIP_openRead */
  158. static void ZIP_dirClose(DirHandle *h)
  159. {
  160. } /* ZIP_dirClose */
  161. static const FileFunctions __PHYSFS_FileFunctions_ZIP =
  162. {
  163. ZIP_read, /* read() method */
  164. NULL, /* write() method */
  165. ZIP_eof, /* eof() method */
  166. ZIP_tell, /* tell() method */
  167. ZIP_seek, /* seek() method */
  168. ZIP_fileLength, /* fileLength() method */
  169. ZIP_fileClose /* fileClose() method */
  170. };
  171. const DirFunctions __PHYSFS_DirFunctions_ZIP =
  172. {
  173. ZIP_isArchive, /* isArchive() method */
  174. ZIP_openArchive, /* openArchive() method */
  175. ZIP_enumerateFiles, /* enumerateFiles() method */
  176. ZIP_exists, /* exists() method */
  177. ZIP_isDirectory, /* isDirectory() method */
  178. ZIP_isSymLink, /* isSymLink() method */
  179. ZIP_openRead, /* openRead() method */
  180. NULL, /* openWrite() method */
  181. NULL, /* openAppend() method */
  182. NULL, /* remove() method */
  183. NULL, /* mkdir() method */
  184. ZIP_dirClose /* dirClose() method */
  185. };
  186. const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
  187. {
  188. "ZIP",
  189. "PkZip/WinZip/Info-Zip compatible",
  190. "Ryan C. Gordon (icculus@linuxgames.com)",
  191. "http://www.icculus.org/~icculus/",
  192. };
  193. /* end of zip.c ... */