Initial work on ZIPfile support. Not complete. Not very pleased with this
authorRyan C. Gordon <icculus@icculus.org>
Sun, 15 Jul 2001 09:29:30 +0000
changeset 32 09a8197fad3b
parent 31 41c23ac35615
child 33 313a6bc49a46
Initial work on ZIPfile support. Not complete. Not very pleased with this minizip library at this moment in time. --ryan.
archivers/zip.c
--- 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 */