Initial work on ZIPfile support. Not complete. Not very pleased with this
minizip library at this moment in time. --ryan.
This commit is contained in:
parent
fe77666054
commit
0ddd2b1f6d
119
archivers/zip.c
119
archivers/zip.c
|
@ -8,7 +8,11 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "physfs.h"
|
#include "physfs.h"
|
||||||
|
#include "unzip.h"
|
||||||
|
|
||||||
|
|
||||||
#define __PHYSICSFS_INTERNAL__
|
#define __PHYSICSFS_INTERNAL__
|
||||||
#include "physfs_internal.h"
|
#include "physfs_internal.h"
|
||||||
|
@ -17,6 +21,18 @@
|
||||||
#error PHYSFS_SUPPORTS_ZIP must be defined.
|
#error PHYSFS_SUPPORTS_ZIP must be defined.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unzFile handle;
|
||||||
|
uLong totalEntries;
|
||||||
|
} ZIPinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
} ZIPfileinfo;
|
||||||
|
|
||||||
|
|
||||||
extern const DirFunctions __PHYSFS_DirFunctions_ZIP;
|
extern const DirFunctions __PHYSFS_DirFunctions_ZIP;
|
||||||
static const FileFunctions __PHYSFS_FileFunctions_ZIP;
|
static const FileFunctions __PHYSFS_FileFunctions_ZIP;
|
||||||
|
|
||||||
|
@ -54,16 +70,119 @@ static int ZIP_fileClose(FileHandle *handle)
|
||||||
|
|
||||||
static int ZIP_isArchive(const char *filename, int forWriting)
|
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 */
|
} /* ZIP_isArchive */
|
||||||
|
|
||||||
|
|
||||||
static DirHandle *ZIP_openArchive(const char *name, int forWriting)
|
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 */
|
} /* ZIP_openArchive */
|
||||||
|
|
||||||
|
|
||||||
static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname)
|
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 */
|
} /* ZIP_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue