--- a/archivers/zip.c Sun Jul 15 09:28:37 2001 +0000
+++ b/archivers/zip.c Sun Jul 15 09:29:30 2001 +0000
@@ -8,7 +8,11 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include "physfs.h"
+#include "unzip.h"
+
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
@@ -17,6 +21,18 @@
#error PHYSFS_SUPPORTS_ZIP must be defined.
#endif
+
+typedef struct
+{
+ unzFile handle;
+ uLong totalEntries;
+} ZIPinfo;
+
+typedef struct
+{
+} ZIPfileinfo;
+
+
extern const DirFunctions __PHYSFS_DirFunctions_ZIP;
static const FileFunctions __PHYSFS_FileFunctions_ZIP;
@@ -54,16 +70,119 @@
static int ZIP_isArchive(const char *filename, int forWriting)
{
+ int retval = 0;
+ unzFile unz = unzOpen(name);
+ unz_global_info global;
+
+ if (unz != NULL)
+ {
+ if (unzGetGlobalInfo(unz, &global) == UNZ_OK)
+ retval = 1;
+ unzClose(unz);
+ } /* if */
+
+ return(retval);
} /* ZIP_isArchive */
static DirHandle *ZIP_openArchive(const char *name, int forWriting)
{
+ unzFile unz = NULL;
+ DirHandle *retval = NULL;
+ unz_global_info global;
+
+ BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
+
+ errno = 0;
+ BAIL_IF_MACRO(access(name, R_OK) != 0, strerror(errno), NULL);
+
+ retval = malloc(sizeof (DirHandle));
+ BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
+
+ unz = unzOpen(name);
+ if ((unz == NULL) || (unzGetGlobalInfo(unz, &global) != UNZ_OK))
+ {
+ if (unz)
+ unzClose(unz);
+ free(retval);
+ BAIL_IF_MACRO(1, ERR_UNSUPPORTED_ARCHIVE, NULL);
+ } /* if */
+
+ retval->opaque = malloc(sizeof (ZIPinfo));
+ if (retval->opaque == NULL)
+ {
+ free(retval);
+ unzClose(unz);
+ BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ ((ZIPinfo *) (retval->opaque))->handle = unz;
+ ((ZIPinfo *) (retval->opaque))->totalEntries = global.number_entry;
+
+ return(retval);
} /* ZIP_openArchive */
static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname)
{
+ ZIPinfo *zi = (ZIPinfo *) (h->opaque);
+ unzFile fh = zi->handle;
+ int i;
+ LinkedStringList *retval = NULL;
+ LinkedStringList *l = NULL;
+ LinkedStringList *prev = NULL;
+ char buffer[256];
+ char *d;
+
+ /* jump to first file entry... */
+ BAIL_IF_MACRO(unzGoToFirstFile(fh) != UNZ_OK, ERR_IO_ERROR, NULL);
+
+ i = strlen(dirname);
+ d = malloc(i + 1);
+ strcpy(d, dirname);
+ if ((i > 0) && (d[i - 1] == '/')) /* no trailing slash. */
+ d[i - 1] = '\0';
+
+ for (i = 0; i < zi->totalEntries; i++)
+ {
+ char *ptr;
+ unzGetCurrentFileInfo(fh, NULL, buf, sizeof (buf), NULL, 0, NULL, 0);
+ ptr = strrchr(p, '/'); /* !!! check this! */
+ if (ptr == NULL)
+ {
+ if (*d != '\0')
+ continue; /* not for this dir; skip it. */
+ ptr = buf;
+ else
+ {
+ *ptr = '\0';
+ ptr++;
+ if (strcmp(buf, d) != 0)
+ continue; /* not for this dir; skip it. */
+ } /* else */
+
+ l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
+ if (l != NULL)
+ break;
+
+ l->str = (char *) malloc(strlen(ptr) + 1);
+ if (l->str == NULL)
+ {
+ free(l);
+ break;
+ } /* if */
+
+ if (retval == NULL)
+ retval = l;
+ else
+ prev->next = l;
+
+ prev = l;
+ l->next = NULL;
+ } /* for */
+
+ free(d);
+ return(retval);
} /* ZIP_enumerateFiles */