summaryrefslogtreecommitdiff
path: root/Build/source/libs/zziplib/zziplib-0.13.62/zzip/zip.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/zziplib/zziplib-0.13.62/zzip/zip.c')
-rw-r--r--Build/source/libs/zziplib/zziplib-0.13.62/zzip/zip.c870
1 files changed, 0 insertions, 870 deletions
diff --git a/Build/source/libs/zziplib/zziplib-0.13.62/zzip/zip.c b/Build/source/libs/zziplib/zziplib-0.13.62/zzip/zip.c
deleted file mode 100644
index a4b06b47189..00000000000
--- a/Build/source/libs/zziplib/zziplib-0.13.62/zzip/zip.c
+++ /dev/null
@@ -1,870 +0,0 @@
-
-/*
- * Author:
- * Guido Draheim <guidod@gmx.de>
- * Tomi Ollila <too@iki.fi>
- *
- * Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
- * All rights reserved,
- * use under the restrictions of the
- * Lesser GNU General Public License
- * or alternatively the restrictions
- * of the Mozilla Public License 1.1
- */
-
-#include <zzip/lib.h> /* archive handling */
-#include <zzip/file.h>
-#include <zzip/format.h>
-#include <zzip/fetch.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#ifdef ZZIP_HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#include <zzip/__mmap.h>
-#include <zzip/__debug.h>
-
-#define __sizeof(X) ((zzip_ssize_t)(sizeof(X)))
-
-#ifndef ZZIP_EASY
-/* per default, we use a little hack to correct bad z_rootseek parts */
-#define ZZIP_CORRECT_ROOTSEEK 1
-#endif
-
-#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ >= 4)
-# ifdef DEBUG
-# warning suppress a warning where the compiler should have optimized instead.
-# endif
-#define _255 254
-#else
-#define _255 255
-#endif
-
-#define ZZIP_DISK64_TRAILER 1
-
-#ifdef ZZIP_DISK64_TRAILER
-struct _disk_trailer
-{
- void *zz_tail;
- void *zz_for_correct_rootseek; // ZZIP_CORRECT_ROOTSEEK
- zzip_off64_t zz_entries;
- zzip_off64_t zz_finalentries;
- zzip_off64_t zz_rootseek;
- zzip_off64_t zz_rootsize;
-};
-#define _disk_trailer_entries(__p) ((__p)->zz_entries)
-#define _disk_trailer_localentries(__p) ((__p)->zz_entries)
-#define _disk_trailer_finalentries(__p) ((__p)->zz_entries)
-#define _disk_trailer_rootseek(__p) ((__p)->zz_rootseek)
-#define _disk_trailer_rootsize(__p) ((__p)->zz_rootsize)
-#define _disk_trailer_set_rootseek(__p,__v) ((__p)->rootseek = (__v))
-
-#else
-#define _disk_trailer zzip_disk_trailer
-#define _disk_trailer_entries zzip_disk_trailer_entries
-#define _disk_trailer_localentries zzip_disk_trailer_localentries
-#define _disk_trailer_finalentries zzip_disk_trailer_finalentries
-#define _disk_trailer_rootseek zzip_disk_trailer_rootseek
-#define _disk_trailer_rootsize zzip_disk_trailer_rootsize
-#define _disk_trailer_set_rootseek zzip_disk_trailer_set_rootseek
-#define __zzip_fetch_disk_trailer __zzip_find_disk_trailer
-#endif
-
-/* --------------------------- internals -------------------------------- */
-
-/* internal functions of zziplib, avoid at all cost, changes w/o warning.
- * we do export them for debugging purpose and special external tools
- * which know what they do and which can adapt from version to version
- */
-
-int __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
- struct _disk_trailer *_zzip_restrict trailer,
- zzip_plugin_io_t io);
-int __zzip_parse_root_directory(int fd,
- struct _disk_trailer *trailer,
- struct zzip_dir_hdr **hdr_return,
- zzip_plugin_io_t io);
-
-_zzip_inline static char *__zzip_aligned4(char *p);
-
-/* ------------------------ harden routines ------------------------------ */
-
-#ifdef ZZIP_HARDEN
-
-/*
- * check for inconsistent values in trailer and prefer lower seek value
- * - we fix values assuming the root directory was written at the end
- * and it is just before the zip trailer. Therefore, ...
- */
-_zzip_inline static void
-__fixup_rootseek(zzip_off_t offset_of_trailer, struct _disk_trailer *trailer)
-{
- if (_disk_trailer_rootseek(trailer) >
- offset_of_trailer - _disk_trailer_rootsize(trailer) &&
- offset_of_trailer > _disk_trailer_rootsize(trailer))
- {
- register zzip_off_t offset;
- offset = offset_of_trailer - _disk_trailer_rootsize(trailer);
- _disk_trailer_set_rootseek(trailer, offset);
- HINT2("new rootseek=%li", (long) _disk_trailer_rootseek(trailer));
- }
-}
-
-#define __correct_rootseek(A,B,C)
-
-#elif defined ZZIP_CORRECT_ROOTSEEK
-
-/* store the seekvalue of the trailer into the "z_magic" field and with
- * a 64bit off_t we overwrite z_disk/z_finaldisk as well. If you change
- * anything in zziplib or dump the trailer structure then watch out that
- * these are still unused, so that this code may still (ab)use those. */
-#define __fixup_rootseek(_offset_of_trailer, _trailer) \
- *(zzip_off_t*)_trailer = _offset_of_trailer;
-#define __correct_rootseek( _u_rootseek, _u_rootsize, _trailer) \
- if (_u_rootseek > *(zzip_off_t*)_trailer - _u_rootsize) \
- _u_rootseek = *(zzip_off_t*)_trailer - _u_rootsize;
-#else
-#define __fixup_rootseek(A,B)
-#define __correct_rootseek(A,B,C)
-#endif
-
-
-#ifdef DEBUG
-_zzip_inline static void
-__debug_dir_hdr(struct zzip_dir_hdr *hdr)
-{
- if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_disk_entry))
- { WARN1("internal sizeof-mismatch may break wreakage"); }
- /* the internal directory structure is never bigger than the
- * external zip central directory space had been beforehand
- * (as long as the following assertion holds...)
- */
-
- if (((zzip_off_t) hdr) & 3)
- {
- NOTE1("this machine's malloc(3) returns sth. not u32-aligned");
- }
- /* we assume that if this machine's malloc has returned a non-aligned
- * memory block, then it is actually safe to access misaligned data, and
- * since it does only affect the first hdr it should not even bring about
- * too much of that cpu's speed penalty
- */
-}
-#else
-#define __debug_dir_hdr(X)
-#endif
-
-/* -------------------------- low-level interface -------------------------- */
-
-#if defined BUFSIZ
-#if BUFSIZ == 1024 || BUFSIZ == 512 || BUFSIZ == 256
-#define ZZIP_BUFSIZ BUFSIZ
-#endif
-#endif
-
-#ifndef ZZIP_BUFSIZ
-#define ZZIP_BUFSIZ 512
-
-/* #define ZZIP_BUFSIZ 64 / * for testing */
-#endif
-
-/**
- * This function is used by => zzip_file_open. It tries to find
- * the zip's central directory info that is usually a few
- * bytes off the end of the file.
- */
-int
-__zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
- struct _disk_trailer *_zzip_restrict trailer,
- zzip_plugin_io_t io)
-{
-#ifdef DEBUG
-#define return(val) { e=val; HINT2("%s", zzip_strerror(e)); goto cleanup; }
-#else
-#define return(val) { e=val; goto cleanup; }
-#endif
- register int e;
-
-#ifndef _LOWSTK
- auto char buffer[2 * ZZIP_BUFSIZ];
- char *buf = buffer;
-#else
- char *buf = malloc(2 * ZZIP_BUFSIZ);
-#endif
- zzip_off_t offset = 0;
- zzip_ssize_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */
- char *fd_map = 0;
-
- if (! trailer)
- { return(EINVAL); }
-
- if (filesize < __sizeof(struct zzip_disk_trailer))
- { return(ZZIP_DIR_TOO_SHORT); }
-
- if (! buf)
- { return(ZZIP_OUTOFMEM); }
-
- offset = filesize; /* a.k.a. old offset */
- while (1) /* outer loop */
- {
- register unsigned char *mapped;
-
- if (offset <= 0)
- { return(ZZIP_DIR_EDH_MISSING); }
-
- /* trailer cannot be farther away than 64K from fileend */
- if (filesize - offset > 64 * 1024)
- { return(ZZIP_DIR_EDH_MISSING); }
-
- /* the new offset shall overlap with the area after the old offset! */
- if (USE_MMAP && io->fd.sys)
- {
- zzip_off_t mapoff = offset;
- {
- zzip_ssize_t pagesize = _zzip_getpagesize(io->fd.sys);
- if (pagesize < ZZIP_BUFSIZ)
- goto non_mmap; /* an error? */
- if (mapoff == filesize && filesize > pagesize)
- mapoff -= pagesize;
- if (mapoff < pagesize)
- {
- maplen = (zzip_ssize_t) mapoff + pagesize;
- mapoff = 0;
- } else
- {
- mapoff -= pagesize;
- maplen = 2 * pagesize;
- if ((zzip_ssize_t) mapoff & (pagesize - 1))
- { /*only 1. run */
- pagesize -= (zzip_ssize_t) mapoff & (pagesize - 1);
- mapoff += pagesize;
- maplen -= pagesize;
- }
- }
- if (mapoff + maplen > filesize)
- maplen = filesize - mapoff;
- }
-
- fd_map = _zzip_mmap(io->fd.sys, fd, mapoff, (zzip_size_t) maplen);
- if (fd_map == MAP_FAILED)
- goto non_mmap;
- mapped = (unsigned char *) fd_map;
- offset = mapoff; /* success */
- HINT3("mapped *%p len=%li", fd_map, (long) maplen);
- } else
- {
- non_mmap:
- fd_map = 0; /* have no mmap */
- {
- zzip_off_t pagesize = ZZIP_BUFSIZ;
- if (offset == filesize && filesize > pagesize)
- offset -= pagesize;
- if (offset < pagesize)
- {
- maplen = (zzip_ssize_t) offset + pagesize;
- offset = 0;
- } else
- {
- offset -= pagesize;
- maplen = 2 * pagesize;
- if ((zzip_ssize_t) offset & (pagesize - 1))
- { /*on 1st run */
- pagesize -= (zzip_ssize_t) offset & (pagesize - 1);
- offset += pagesize;
- maplen -= pagesize;
- }
- }
- if (offset + maplen > filesize)
- maplen = filesize - offset;
- }
-
- if (io->fd.seeks(fd, offset, SEEK_SET) < 0)
- { return(ZZIP_DIR_SEEK); }
- if (io->fd.read(fd, buf, (zzip_size_t) maplen) < maplen)
- { return(ZZIP_DIR_READ); }
- mapped = (unsigned char *) buf; /* success */
- HINT5("offs=$%lx len=%li filesize=%li pagesize=%i",
- (long) offset, (long) maplen, (long) filesize, ZZIP_BUFSIZ);
- }
-
- { /* now, check for the trailer-magic, hopefully near the end of file */
- register unsigned char *end = mapped + maplen;
- register unsigned char *tail;
- for (tail = end - 1; (tail >= mapped); tail--)
- {
- if ((*tail == 'P') && /* quick pre-check for trailer magic */
- end - tail >= __sizeof(struct zzip_disk_trailer) - 2 &&
- zzip_disk_trailer_check_magic(tail))
- {
-# ifndef ZZIP_DISK64_TRAILER
- /* if the file-comment is not present, it happens
- that the z_comment field often isn't either */
- if (end - tail >= __sizeof(*trailer))
- {
- memcpy(trailer, tail, sizeof(*trailer));
- } else
- {
- memcpy(trailer, tail, sizeof(*trailer) - 2);
- trailer->z_comment[0] = 0;
- trailer->z_comment[1] = 0;
- }
-# else
- struct zzip_disk_trailer *orig =
- (struct zzip_disk_trailer *) tail;
- trailer->zz_tail = tail;
- trailer->zz_entries = zzip_disk_trailer_localentries(orig);
- trailer->zz_finalentries =
- zzip_disk_trailer_finalentries(orig);
- trailer->zz_rootseek = zzip_disk_trailer_rootseek(orig);
- trailer->zz_rootsize = zzip_disk_trailer_rootsize(orig);
-# endif
-
- __fixup_rootseek(offset + tail - mapped, trailer);
- { return(0); }
- } else if ((*tail == 'P') &&
- end - tail >=
- __sizeof(struct zzip_disk64_trailer) - 2
- && zzip_disk64_trailer_check_magic(tail))
- {
-# ifndef ZZIP_DISK64_TRAILER
- return (ZZIP_DIR_LARGEFILE);
-# else
- struct zzip_disk64_trailer *orig =
- (struct zzip_disk64_trailer *) tail;
- trailer->zz_tail = tail;
- trailer->zz_entries =
- zzip_disk64_trailer_localentries(orig);
- trailer->zz_finalentries =
- zzip_disk64_trailer_finalentries(orig);
- trailer->zz_rootseek = zzip_disk64_trailer_rootseek(orig);
- trailer->zz_rootsize = zzip_disk64_trailer_rootsize(orig);
- { return(0); }
-# endif
- }
- }
- }
-
- if (USE_MMAP && fd_map)
- {
- HINT3("unmap *%p len=%li", fd_map, (long) maplen);
- _zzip_munmap(io->fd.sys, fd_map, (zzip_size_t) maplen);
- fd_map = 0;
- }
- } /*outer loop */
-
- cleanup:
- if (USE_MMAP && fd_map)
- {
- HINT3("unmap *%p len=%li", fd_map, (long) maplen);
- _zzip_munmap(io->fd.sys, fd_map, (zzip_size_t) maplen);
- }
-# ifdef _LOWSTK
- free(buf);
-# endif
-# undef return
- return e;
-}
-
-/*
- * making pointer alignments to values that can be handled as structures
- * is tricky. We assume here that an align(4) is sufficient even for
- * 64 bit machines. Note that binary operations are not usually allowed
- * to pointer types but we can cast the value to a suitably sized integer.
- */
-_zzip_inline static char *
-__zzip_aligned4(char *p)
-{
-#define aligned4 __zzip_aligned4
-#ifdef _WIN64
- p += ((__int64) p) & 1;
- p += ((__int64) p) & 2;
-#else
- p += ((long) p) & 1;
- p += ((long) p) & 2;
-#endif
- return p;
-}
-
-/**
- * This function is used by => zzip_file_open, it is usually called after
- * => __zzip_find_disk_trailer. It will parse the zip's central directory
- * information and create a zziplib private directory table in
- * memory.
- */
-int
-__zzip_parse_root_directory(int fd,
- struct _disk_trailer *trailer,
- struct zzip_dir_hdr **hdr_return,
- zzip_plugin_io_t io)
-{
- auto struct zzip_disk_entry dirent;
- struct zzip_dir_hdr *hdr;
- struct zzip_dir_hdr *hdr0;
- uint16_t *p_reclen = 0;
- zzip_off64_t entries;
- zzip_off64_t zz_offset; /* offset from start of root directory */
- char *fd_map = 0;
- zzip_off64_t zz_fd_gap = 0;
- zzip_off64_t zz_entries = _disk_trailer_localentries(trailer);
- zzip_off64_t zz_rootsize = _disk_trailer_rootsize(trailer);
- zzip_off64_t zz_rootseek = _disk_trailer_rootseek(trailer);
- __correct_rootseek(zz_rootseek, zz_rootsize, trailer);
-
- hdr0 = (struct zzip_dir_hdr *) malloc(zz_rootsize);
- if (! hdr0)
- return ZZIP_DIRSIZE;
- hdr = hdr0;
- __debug_dir_hdr(hdr);
-
- if (USE_MMAP && io->fd.sys)
- {
- zz_fd_gap = zz_rootseek & (_zzip_getpagesize(io->fd.sys) - 1);
- HINT4(" fd_gap=%ld, mapseek=0x%lx, maplen=%ld", (long) (zz_fd_gap),
- (long) (zz_rootseek - zz_fd_gap),
- (long) (zz_rootsize + zz_fd_gap));
- fd_map =
- _zzip_mmap(io->fd.sys, fd, zz_rootseek - zz_fd_gap,
- zz_rootsize + zz_fd_gap);
- /* if mmap failed we will fallback to seek/read mode */
- if (fd_map == MAP_FAILED)
- {
- NOTE2("map failed: %s", strerror(errno));
- fd_map = 0;
- } else
- {
- HINT3("mapped *%p len=%li", fd_map,
- (long) (zz_rootsize + zz_fd_gap));
- }
- }
-
- for (entries=0, zz_offset=0; ; entries++)
- {
- register struct zzip_disk_entry *d;
- uint16_t u_extras, u_comment, u_namlen;
-
-# ifndef ZZIP_ALLOW_MODULO_ENTRIES
- if (entries >= zz_entries) {
- if (zz_offset + 256 < zz_rootsize) {
- FAIL4("%li's entry is long before the end of directory - enable modulo_entries? (O:%li R:%li)",
- (long) entries, (long) (zz_offset), (long) zz_rootsize);
- }
- break;
- }
-# endif
-
- if (fd_map)
- { d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
- else
- {
- if (io->fd.seeks(fd, zz_rootseek + zz_offset, SEEK_SET) < 0)
- return ZZIP_DIR_SEEK;
- if (io->fd.read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent))
- return ZZIP_DIR_READ;
- d = &dirent;
- }
-
- if ((zzip_off64_t) (zz_offset + sizeof(*d)) > zz_rootsize ||
- (zzip_off64_t) (zz_offset + sizeof(*d)) < 0)
- {
- FAIL4("%li's entry stretches beyond root directory (O:%li R:%li)",
- (long) entries, (long) (zz_offset), (long) zz_rootsize);
- break;
- }
-
- if (! zzip_disk_entry_check_magic(d)) {
-# ifndef ZZIP_ALLOW_MODULO_ENTRIES
- FAIL4("%li's entry has no disk_entry magic indicator (O:%li R:%li)",
- (long) entries, (long) (zz_offset), (long) zz_rootsize);
-# endif
- break;
- }
-
-# if 0 && defined DEBUG
- zzip_debug_xbuf((unsigned char *) d, sizeof(*d) + 8);
-# endif
-
- u_extras = zzip_disk_entry_get_extras(d);
- u_comment = zzip_disk_entry_get_comment(d);
- u_namlen = zzip_disk_entry_get_namlen(d);
- HINT5("offset=0x%lx, size %ld, dirent *%p, hdr %p\n",
- (long) (zz_offset + zz_rootseek), (long) zz_rootsize, d, hdr);
-
- /* writes over the read buffer, Since the structure where data is
- copied is smaller than the data in buffer this can be done.
- It is important that the order of setting the fields is considered
- when filling the structure, so that some data is not trashed in
- first structure read.
- at the end the whole copied list of structures is copied into
- newly allocated buffer */
- hdr->d_crc32 = zzip_disk_entry_get_crc32(d);
- hdr->d_csize = zzip_disk_entry_get_csize(d);
- hdr->d_usize = zzip_disk_entry_get_usize(d);
- hdr->d_off = zzip_disk_entry_get_offset(d);
- hdr->d_compr = zzip_disk_entry_get_compr(d);
- if (hdr->d_compr > _255)
- hdr->d_compr = 255;
-
- if ((zzip_off64_t) (zz_offset + sizeof(*d) + u_namlen) > zz_rootsize ||
- (zzip_off64_t) (zz_offset + sizeof(*d) + u_namlen) < 0)
- {
- FAIL4("%li's name stretches beyond root directory (O:%li N:%li)",
- (long) entries, (long) (zz_offset), (long) (u_namlen));
- break;
- }
-
- if (fd_map)
- { memcpy(hdr->d_name, fd_map+zz_fd_gap + zz_offset+sizeof(*d), u_namlen); }
- else
- { io->fd.read(fd, hdr->d_name, u_namlen); }
- hdr->d_name[u_namlen] = '\0';
- hdr->d_namlen = u_namlen;
-
- /* update offset by the total length of this entry -> next entry */
- zz_offset += sizeof(*d) + u_namlen + u_extras + u_comment;
-
- if (zz_offset > zz_rootsize)
- {
- FAIL3("%li's entry stretches beyond root directory (O:%li)",
- (long) entries, (long) (zz_offset));
- entries ++;
- break;
- }
-
- HINT5("file %ld { compr=%d crc32=$%x offset=%d",
- (long) entries, hdr->d_compr, hdr->d_crc32, hdr->d_off);
- HINT5("csize=%d usize=%d namlen=%d extras=%d",
- hdr->d_csize, hdr->d_usize, u_namlen, u_extras);
- HINT5("comment=%d name='%s' %s <sizeof %d> } ",
- u_comment, hdr->d_name, "", (int) sizeof(*d));
-
- p_reclen = &hdr->d_reclen;
-
- {
- register char *p = (char *) hdr;
- register char *q = aligned4(p + sizeof(*hdr) + u_namlen + 1);
- *p_reclen = (uint16_t) (q - p);
- hdr = (struct zzip_dir_hdr *) q;
- }
- } /*for */
-
- if (USE_MMAP && fd_map)
- {
- HINT3("unmap *%p len=%li", fd_map, (long) (zz_rootsize + zz_fd_gap));
- _zzip_munmap(io->fd.sys, fd_map, zz_rootsize + zz_fd_gap);
- }
-
- if (p_reclen)
- {
- *p_reclen = 0; /* mark end of list */
-
- if (hdr_return)
- *hdr_return = hdr0;
- } /* else zero (sane) entries */
-# ifndef ZZIP_ALLOW_MODULO_ENTRIES
- return (entries != zz_entries ? ZZIP_CORRUPTED : 0);
-# else
- return ((entries & (unsigned)0xFFFF) != zz_entries ? ZZIP_CORRUPTED : 0);
-# endif
-}
-
-/* ------------------------- high-level interface ------------------------- */
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-static zzip_strings_t *
-zzip_get_default_ext(void)
-{
- static zzip_strings_t ext[] = {
- /* *INDENT-OFF* */
- ".zip", ".ZIP", /* common extension */
-# ifdef ZZIP_USE_ZIPLIKES
- ".pk3", ".PK3", /* ID Software's Quake3 zipfiles */
- ".jar", ".JAR", /* Java zipfiles */
-# endif
- /* *INDENT-ON* */
- 0
- };
-
- return ext;
-}
-
-/**
- * allocate a new ZZIP_DIR handle and do basic
- * initializations before usage by => zzip_dir_fdopen
- * => zzip_dir_open => zzip_file_open or through
- * => zzip_open
- * (ext==null flags uses { ".zip" , ".ZIP" } )
- * (io ==null flags use of posix io defaults)
- */
-ZZIP_DIR *
-zzip_dir_alloc_ext_io(zzip_strings_t * ext, const zzip_plugin_io_t io)
-{
- ZZIP_DIR *dir;
- if ((dir = (ZZIP_DIR *) calloc(1, sizeof(*dir))) == NULL)
- return 0;
-
- /* dir->fileext is currently unused - so what, still initialize it */
- dir->fileext = ext ? ext : zzip_get_default_ext();
- dir->io = io ? io : zzip_get_default_io();
- return dir;
-}
-
-/** => zzip_dir_alloc_ext_io
- * this function is obsolete - it was generally used for implementation
- * and exported to let other code build on it. It is now advised to
- * use => zzip_dir_alloc_ext_io now on explicitly, just set that second
- * argument to zero to achieve the same functionality as the old style.
- */
-ZZIP_DIR *
-zzip_dir_alloc(zzip_strings_t * fileext)
-{
- return zzip_dir_alloc_ext_io(fileext, 0);
-}
-
-/**
- * will free the zzip_dir handle unless there are still
- * zzip_files attached (that may use its cache buffer).
- * This is the inverse of => zzip_dir_alloc , and both
- * are helper functions used implicitly in other zzipcalls
- * e.g. => zzip_dir_close = zzip_close
- *
- * returns zero on sucess
- * returns the refcount when files are attached.
- */
-int
-zzip_dir_free(ZZIP_DIR * dir)
-{
- if (dir->refcount)
- return (dir->refcount); /* still open files attached */
-
- if (dir->fd >= 0)
- dir->io->fd.close(dir->fd);
- if (dir->hdr0)
- free(dir->hdr0);
- if (dir->cache.fp)
- free(dir->cache.fp);
- if (dir->cache.buf32k)
- free(dir->cache.buf32k);
- if (dir->realname)
- free(dir->realname);
- free(dir);
- return 0;
-}
-
-/** => zzip_dir_free
- * It will also => free(2) the => ZZIP_DIR-handle given.
- * the counterpart for => zzip_dir_open
- * see also => zzip_dir_free
- */
-int
-zzip_dir_close(ZZIP_DIR * dir)
-{
- dir->refcount &= ~0x10000000; /* explicit dir close */
- return zzip_dir_free(dir);
-}
-
-/**
- * used by the => zzip_dir_open and zzip_opendir(2) call. Opens the
- * zip-archive as specified with the fd which points to an
- * already openend file. This function then search and parse
- * the zip's central directory.
- *
- * NOTE: refcount is zero, so an _open/_close pair will also delete
- * this _dirhandle
- */
-ZZIP_DIR *
-zzip_dir_fdopen(int fd, zzip_error_t * errcode_p)
-{
- return zzip_dir_fdopen_ext_io(fd, errcode_p, 0, 0);
-}
-
-static zzip_error_t __zzip_dir_parse(ZZIP_DIR * dir); /* forward */
-
-/** => zzip_dir_fdopen
- * this function uses explicit ext and io instead of the internal
- * defaults, setting these to zero is equivalent to => zzip_dir_fdopen
- */
-ZZIP_DIR *
-zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errcode_p,
- zzip_strings_t * ext, const zzip_plugin_io_t io)
-{
- zzip_error_t rv;
- ZZIP_DIR *dir;
-
- if ((dir = zzip_dir_alloc_ext_io(ext, io)) == NULL)
- { rv = ZZIP_OUTOFMEM; goto error; }
-
- dir->fd = fd;
- if ((rv = __zzip_dir_parse(dir)))
- goto error;
-
- dir->hdr = dir->hdr0;
- dir->refcount |= 0x10000000;
-
- if (errcode_p)
- *errcode_p = rv;
- return dir;
- error:
- if (dir)
- zzip_dir_free(dir);
- if (errcode_p)
- *errcode_p = rv;
- return NULL;
-}
-
-static zzip_error_t
-__zzip_dir_parse(ZZIP_DIR * dir)
-{
- zzip_error_t rv;
- zzip_off_t filesize;
- struct _disk_trailer trailer;
- /* if (! dir || dir->fd < 0)
- * { rv = EINVAL; goto error; }
- */
-
- HINT2("------------------ fd=%i", (int) dir->fd);
- if ((filesize = dir->io->fd.filesize(dir->fd)) < 0)
- { rv = ZZIP_DIR_STAT; goto error; }
-
- HINT2("------------------ filesize=%ld", (long) filesize);
- if ((rv = __zzip_fetch_disk_trailer(dir->fd, filesize, &trailer,
- dir->io)) != 0)
- { goto error; }
-
- HINT5("directory = { entries= %ld/%ld, size= %ld, seek= %ld } ",
- (long) _disk_trailer_localentries(&trailer),
- (long) _disk_trailer_finalentries(&trailer),
- (long) _disk_trailer_rootsize(&trailer),
- (long) _disk_trailer_rootseek(&trailer));
-
- if ((rv = __zzip_parse_root_directory(dir->fd, &trailer, &dir->hdr0,
- dir->io)) != 0)
- { goto error; }
- error:
- return rv;
-}
-
-/**
- * This function will attach any of the .zip extensions then
- * trying to open it the with => open(2). This is a helper
- * function for => zzip_dir_open, => zzip_opendir and => zzip_open.
- *
- * This function returns a new system file handle or -1 on error.
- * On error this function leaves the errno(3) of the underlying
- * open(2) call on the last file.
- */
-int
-__zzip_try_open(zzip_char_t * filename, int filemode,
- zzip_strings_t * ext, zzip_plugin_io_t io)
-{
- auto char file[PATH_MAX];
- int fd;
- zzip_size_t len = strlen(filename);
-
- if (len + 4 >= PATH_MAX)
- { errno = ENAMETOOLONG; return -1; }
- memcpy(file, filename, len + 1);
-
- if (! io)
- io = zzip_get_default_io();
- if (! ext)
- ext = zzip_get_default_ext();
-
- for (; *ext; ++ext)
- {
- strcpy(file + len, *ext);
- fd = (io->fd.open)(file, filemode);
- if (fd != -1)
- return fd;
- }
- return -1;
-}
-
-/**
- * Opens the zip-archive (if available).
- * the two ext_io arguments will default to use posix io and
- * a set of default fileext that can atleast add .zip ext itself.
- */
-ZZIP_DIR *
-zzip_dir_open(zzip_char_t * filename, zzip_error_t * e)
-{
- return zzip_dir_open_ext_io(filename, e, 0, 0);
-}
-
-/** => zzip_dir_open
- * this function uses explicit ext and io instead of the internal
- * defaults. Setting these to zero is equivalent to => zzip_dir_open
- * Note that the referenced ext_io plugin handlers structure must be
- * static as it is not copied to the returned ZZIP_DIR structure.
- */
-ZZIP_DIR *
-zzip_dir_open_ext_io(zzip_char_t * filename, zzip_error_t * e,
- zzip_strings_t * ext, zzip_plugin_io_t io)
-{
- int fd;
-
- if (! io)
- io = zzip_get_default_io();
- if (! ext)
- ext = zzip_get_default_ext();
-
- fd = (io->fd.open)(filename, O_RDONLY | O_BINARY);
- if (fd != -1)
- {
- return zzip_dir_fdopen_ext_io(fd, e, ext, io);
- } else
- {
- fd = __zzip_try_open(filename, O_RDONLY | O_BINARY, ext, io);
- if (fd != -1)
- {
- return zzip_dir_fdopen_ext_io(fd, e, ext, io);
- } else
- {
- if (e)
- { *e = ZZIP_DIR_OPEN; }
- return 0;
- }
- }
-}
-
-/** => zzip_dir_open
- * fills the dirent-argument with the values and
- * increments the read-pointer of the dir-argument.
- *
- * returns 0 if there no entry (anymore).
- */
-int
-zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * d)
-{
- if (! dir || ! dir->hdr || ! d)
- return 0;
-
- d->d_compr = dir->hdr->d_compr;
- d->d_csize = dir->hdr->d_csize;
- d->st_size = dir->hdr->d_usize;
- d->d_name = dir->hdr->d_name;
-
- if (! dir->hdr->d_reclen)
- {
- dir->hdr = 0;
- } else
- {
- dir->hdr = (struct zzip_dir_hdr *)
- ((char *) dir->hdr + dir->hdr->d_reclen);
- }
-
- return 1;
-}
-
-/*
- * Local variables:
- * c-file-style: "stroustrup"
- * End:
- */