diff --git a/libclamav/unzip.c b/libclamav/unzip.c deleted file mode 100644 index 0ee892f27..000000000 --- a/libclamav/unzip.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright (C) 2003 - 2005 Tomasz Kojm - * (C) 2006 Sensory Networks, Inc. - * - * The code of this module was based on zziplib 0.12.83: - * (c) 1999 - 2002 Guido Draheim , published under - * the Lesser GNU General Public License - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#if HAVE_CONFIG_H -#include "clamav-config.h" -#endif - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#include "clamav.h" -#include "others.h" -#include "unzip.h" - -#define EC32(x) le32_to_host(x) /* Convert little endian to host */ -#define EC16(x) le16_to_host(x) - -#define __sizeof(X) ((ssize_t)(sizeof(X))) - -#define ZIPBUFSIZ 1024 -#define ZIP32K 32768 - -inline static void __fixup_rootseek(off_t offset_of_trailer, struct zip_disk_trailer *trailer) -{ - if((off_t) EC32(trailer->z_rootseek) > - offset_of_trailer - (off_t) EC32(trailer->z_rootsize) && - offset_of_trailer > (off_t) EC32(trailer->z_rootsize)) - trailer->z_rootseek = (uint32_t) (offset_of_trailer - EC32(trailer->z_rootsize)); -} - -static int __zip_find_disk_trailer(int fd, off_t filesize, struct zip_disk_trailer *trailer, off_t *start) -{ - char *buf, *end, *tail; - off_t offset = 0, bufsize; - struct zip_root_dirent dirent; - uint32_t u_rootseek, shift = 0; - int i; - - - if(!trailer) { - cli_errmsg("Unzip: __zip_find_disk_trailer: trailer == NULL\n"); - return CL_ENULLARG; - } - - if(filesize < __sizeof(struct zip_disk_trailer)) { - cli_errmsg("Unzip: __zip_find_disk_trailer: File too short\n"); - return CL_EFORMAT; - } - - if(!(buf = cli_malloc(ZIPBUFSIZ))) - return CL_EMEM; - - offset = filesize; - while(1) { - - if(offset <= 0) { - cli_dbgmsg("Unzip: __zip_find_disk_trailer: Central directory not found\n"); - free(buf); - return CL_EFORMAT; - } - - if(offset >= ZIPBUFSIZ) { - if(offset == filesize) - offset -= ZIPBUFSIZ; - else - offset -= ZIPBUFSIZ - sizeof(struct zip_disk_trailer); - - bufsize = ZIPBUFSIZ; - } else { - if(filesize < ZIPBUFSIZ) - bufsize = offset; - else - bufsize = ZIPBUFSIZ; - - offset = 0; - } - - if(lseek(fd, offset, SEEK_SET) < 0) { - cli_errmsg("Unzip: __zip_find_disk_trailer: Can't lseek descriptor %d\n", fd); - free(buf); - return CL_EIO; - } - - if(cli_readn(fd, buf, (size_t) bufsize) < (ssize_t) bufsize) { - cli_errmsg("Unzip: __zip_find_disk_trailer: Can't read %u bytes\n", (unsigned int) bufsize); - free(buf); - return CL_EIO; - } - - end = buf + bufsize; - for(tail = end - 1; tail >= buf; tail--) { - if((*tail == 'P') && (end - tail >= __sizeof(struct zip_disk_trailer) - 2) && cli_readint32(tail) == ZIP_DISK_TRAILER_MAGIC) { - if(end - tail >= __sizeof(struct zip_disk_trailer)) { - memcpy(trailer, tail, sizeof(struct zip_disk_trailer)); - } else { - memcpy(trailer, tail, sizeof(struct zip_disk_trailer) - 2); - trailer->z_comment = 0; - } - __fixup_rootseek(offset + tail - buf, trailer); - - u_rootseek = EC32(trailer->z_rootseek); - if(u_rootseek > (uint32_t) filesize) { - cli_dbgmsg("Unzip: __zip_find_disk_trailer: u_rootseek > filesize, continue search\n"); - continue; - } - - for(i = 0; i < 2; i++) { - if(u_rootseek + shift + sizeof(dirent) < (uint32_t) filesize) { - if(lseek(fd, u_rootseek + shift, SEEK_SET) < 0) { - cli_errmsg("Unzip: __zip_find_disk_trailer: Can't lseek descriptor %d\n", fd); - free(buf); - return CL_EIO; - } - - if(cli_readn(fd, &dirent, sizeof(dirent)) < __sizeof(dirent)) { - cli_errmsg("Unzip: __zip_find_disk_trailer: Can't read %u bytes\n", (unsigned int) bufsize); - free(buf); - return CL_EIO; - } - - if(EC32(dirent.z_magic) == ZIP_ROOT_DIRENT_MAGIC) { - cli_dbgmsg("Unzip: __zip_find_disk_trailer: found file header at %u, shift %u\n", u_rootseek + shift, shift); - free(buf); - *start = shift; - return CL_SUCCESS; - } - - shift = *start; - } - } - } - } - } - - /* this should never be reached */ - free(buf); - return CL_EFORMAT; -} - -static int __zip_parse_root_directory(int fd, struct zip_disk_trailer *trailer, zip_dir_hdr **hdr_return, off_t start) -{ - struct zip_root_dirent dirent, *d; - zip_dir_hdr *hdr, *hdr0, *prev_hdr; - uint16_t *p_reclen = NULL, entries; - uint32_t offset; - struct stat sb; - uint16_t u_entries = EC16(trailer->z_entries); - uint32_t u_rootsize = EC32(trailer->z_rootsize); - uint32_t u_rootseek = EC32(trailer->z_rootseek) + start; - uint16_t u_extras, u_comment, u_namlen, u_flags; - unsigned int bfcnt; - char *pt; - - - if(fstat(fd, &sb) == -1) { - cli_errmsg("Unzip: __zip_parse_root_directory: Can't fstat file descriptor %d\n", fd); - return CL_EIO; - } - - if(!u_entries) { - cli_errmsg("Unzip: __zip_parse_root_directory: File contains no entries\n"); - return CL_EFORMAT; - } - - if(u_rootsize > (uint32_t) sb.st_size) { - cli_errmsg("Unzip: __zip_parse_root_directory: Incorrect root size\n"); - return CL_EFORMAT; - } - - hdr0 = (zip_dir_hdr*) cli_malloc(u_rootsize); - if (!hdr0) - return CL_EMEM; - - hdr = hdr0; - - for(entries = u_entries, offset = 0; entries > 0; entries--) { - - if(lseek(fd, u_rootseek + offset, SEEK_SET) < 0) { - free(hdr0); - cli_errmsg("Unzip: __zip_parse_root_directory: Can't lseek descriptor %d\n", fd); - return CL_EIO; - } - - if(cli_readn(fd, &dirent, sizeof(dirent)) < __sizeof(dirent)) { - if(entries != u_entries) { - entries = 0; - break; - } else { - free(hdr0); - cli_dbgmsg("Unzip: __zip_parse_root_directory: Can't read %d bytes\n", sizeof(dirent)); - return CL_EIO; - } - } - d = &dirent; - - if(offset + sizeof(struct zip_root_dirent) > u_rootsize) { - cli_dbgmsg("Unzip: __zip_parse_root_directory: Entry %d outside of root directory\n", entries); - break; - } - - u_extras = EC16(d->z_extras); - u_comment = EC16(d->z_comment); - - u_namlen = EC16(d->z_namlen); - if(u_namlen > 1024) { - cli_dbgmsg("Unzip: __zip_parse_root_directory: Entry %d name too long\n", entries); - break; - } - - u_flags = EC16(d->z_flags); - - hdr->d_crc32 = EC32(d->z_crc32); - hdr->d_csize = EC32(d->z_csize); - hdr->d_usize = EC32(d->z_usize); - hdr->d_off = EC32(d->z_off) + start; - - hdr->d_compr = EC16(d->z_compr); - - bfcnt = 0; - if(!hdr->d_compr && hdr->d_csize != hdr->d_usize) { - cli_warnmsg("Unzip: __zip_parse_root_directory: File claims to be stored but csize != usize\n"); - cli_dbgmsg("Unzip: __zip_parse_root_directory: Also checking for method 'deflated'\n"); - hdr->d_bf[bfcnt] = ZIP_METHOD_DEFLATED; - bfcnt++; - } else if(hdr->d_compr && hdr->d_csize == hdr->d_usize) { - cli_dbgmsg("Unzip: __zip_parse_root_directory: File claims to be deflated but csize == usize\n"); - cli_dbgmsg("Unzip: __zip_parse_root_directory: Also checking for method 'stored'\n"); - hdr->d_bf[bfcnt] = ZIP_METHOD_STORED; - bfcnt++; - } - hdr->d_bf[bfcnt] = -1; - - hdr->d_flags = u_flags; - - if(offset + sizeof(struct zip_root_dirent) + u_namlen > u_rootsize) { - cli_dbgmsg("Unzip: __zip_parse_root_directory: Name of entry %d outside of root directory\n", entries); - break; - } - - if(cli_readn(fd, hdr->d_name, u_namlen) != u_namlen) { - cli_dbgmsg("Unzip: __zip_parse_root_directory: Can't read name of entry %d\n", entries); - break; - } - - hdr->d_name[u_namlen] = '\0'; - hdr->d_namlen = u_namlen; - - offset += sizeof(struct zip_root_dirent) + u_namlen + u_extras + u_comment; - - if(offset > u_rootsize) { - cli_dbgmsg("Unzip: __zip_parse_root_directory: End of entry %d outside of root directory\n", entries); - break; - } - - pt = (char *) hdr + sizeof(zip_dir_hdr) + u_namlen + 1; - pt += ((long) pt) & 1; - pt += ((long) pt) & 2; - hdr->d_reclen = (uint16_t) (pt - (char *) hdr); - p_reclen = &hdr->d_reclen; - - prev_hdr = hdr; - hdr = (zip_dir_hdr *) ((char *) hdr + hdr->d_reclen); - } - - if(p_reclen) { - *p_reclen = 0; - if(hdr_return) - *hdr_return = hdr0; - } else { - free(hdr0); - } - - return entries ? CL_EFORMAT : CL_SUCCESS; -} - -int zip_dir_close(zip_dir *dir) -{ - if(dir->hdr0) - free(dir->hdr0); - - if(dir->cache.fp) - free(dir->cache.fp); - - if(dir->cache.buf32k) - free(dir->cache.buf32k); - - free(dir); - return CL_SUCCESS; -} - -static int __zip_dir_parse(zip_dir *dir, off_t start) -{ - int ret; - struct zip_disk_trailer trailer; - struct stat sb; - - - if(fstat(dir->fd, &sb) == -1) { - cli_errmsg("Unzip: __zip_dir_parse: Can't fstat file descriptor %d\n", dir->fd); - return CL_EIO; - } - - if((ret = __zip_find_disk_trailer(dir->fd, sb.st_size, &trailer, &start))) - return ret; - - if((ret = __zip_parse_root_directory(dir->fd, &trailer, &dir->hdr0, start))) - return ret; - - return CL_SUCCESS; -} - -zip_dir *zip_dir_open(int fd, off_t start, int *errcode_p) -{ - int ret; - zip_dir * dir; - - - dir = (zip_dir *) cli_calloc(1, sizeof(zip_dir)); - if(!dir) { - if(errcode_p) - *errcode_p = CL_EMEM; - return NULL; - } - - if(start) { - if(lseek(fd, start, SEEK_SET) == -1) { - cli_errmsg("Unzip: zip_dir_open: Can't lseek descriptor %d\n", fd); - if(errcode_p) - *errcode_p = CL_EIO; - return NULL; - } - } - - dir->fd = fd; - - if((ret = __zip_dir_parse(dir, start))) { - zip_dir_close(dir); - if(errcode_p) - *errcode_p = CL_EMEM; - return NULL; - } - - dir->hdr = dir->hdr0; - - if(errcode_p) - *errcode_p = CL_SUCCESS; - - return dir; -} - -int zip_dir_read(zip_dir *dir, zip_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; - d->d_flags = dir->hdr->d_flags; - d->d_off = dir->hdr->d_off; - d->d_crc32 = dir->hdr->d_crc32; - - if(!dir->hdr->d_reclen) - dir->hdr = NULL; - else - dir->hdr = (zip_dir_hdr *) ((char *) dir->hdr + dir->hdr->d_reclen); - - return 1; -} - -int zip_file_close(zip_file *fp) -{ - zip_dir *dir; - - - if(!fp) { - cli_errmsg("Unzip: zip_file_close: fp == NULL\n"); - return CL_ENULLARG; - } - - inflateEnd(&fp->d_stream); - - dir = fp->dir; - if(fp->buf32k) { - if(!dir->cache.buf32k) - dir->cache.buf32k = fp->buf32k; - else - free(fp->buf32k); - } - - memset(fp, 0, sizeof(zip_file)); - - if(!dir->cache.fp) - dir->cache.fp = fp; - else - free(fp); - - return CL_SUCCESS; -} - -static int __zip_inflate_init(zip_file *fp, zip_dir_hdr *hdr) -{ - int ret; - fp->method = hdr->d_compr; - fp->restlen = hdr->d_usize; - - - if(fp->method) { - memset(&fp->d_stream, 0, sizeof(fp->d_stream)); - - ret = inflateInit2(&fp->d_stream, -MAX_WBITS); - - if(ret != Z_OK) { - cli_errmsg("Unzip: __zip_inflate_init: inflateInit2 failed\n"); - return CL_EZIP; - } - - fp->crestlen = hdr->d_csize; - } - - return CL_SUCCESS; -} - -zip_file *zip_file_open(zip_dir *dir, const char *name, int d_off) -{ - int ret; - zip_file *fp = NULL; - zip_dir_hdr *hdr = dir->hdr0; - const char *hdr_name; - ssize_t dataoff; - struct zip_file_header *hp; - - - if(!dir || dir->fd < 0) { - cli_errmsg("Unzip: zip_file_open: dir == NULL || dir->fd <= 0\n"); - return NULL; - } - - if(!hdr) { - cli_errmsg("Unzip: zip_file_open: hdr == NULL\n"); - dir->errcode = CL_ENULLARG; - return NULL; - } - - while(1) { - hdr_name = hdr->d_name; - - if(!strcmp(hdr_name, name) && (d_off == -1 || (uint32_t) d_off == hdr->d_off)) { - switch (hdr->d_compr) { - case ZIP_METHOD_STORED: - case ZIP_METHOD_DEFLATED: - case ZIP_METHOD_DEFLATED64: - break; - - case ZIP_METHOD_SHRUNK: - case ZIP_METHOD_REDUCEDx1: - case ZIP_METHOD_REDUCEDx2: - case ZIP_METHOD_REDUCEDx3: - case ZIP_METHOD_REDUCEDx4: - case ZIP_METHOD_IMPLODED: - case ZIP_METHOD_TOKENIZED: - case ZIP_METHOD_IMPLODED_DCL: - case ZIP_METHOD_BZIP2: - case ZIP_METHOD_AES: - cli_dbgmsg("Unzip: zip_file_open: Not supported compression method (%d)\n", hdr->d_compr); - dir->errcode = CL_ESUPPORT; - return NULL; - - default: - cli_errmsg("Unzip: zip_file_read: Unknown compression method (%d)\n", hdr->d_compr); - dir->errcode = CL_EFORMAT; - return NULL; - } - - if(dir->cache.fp) { - fp = dir->cache.fp; - dir->cache.fp = NULL; - } else { - fp = (zip_file *) cli_calloc(1, sizeof(zip_file)); - if(!fp) { - dir->errcode = CL_EMEM; - return NULL; - } - } - - fp->dir = dir; - - if(dir->cache.buf32k) { - fp->buf32k = dir->cache.buf32k; - dir->cache.buf32k = NULL; - } else { - fp->buf32k = (char *) cli_malloc(ZIP32K); - if(!fp->buf32k) { - dir->errcode = CL_EMEM; - zip_file_close(fp); - return NULL; - } - } - - if(lseek(dir->fd, hdr->d_off, SEEK_SET) < 0) { - cli_errmsg("Unzip: zip_file_open: Can't lseek descriptor %d\n", dir->fd); - dir->errcode = CL_EIO; - zip_file_close(fp); - return NULL; - } - - hp = (void *) fp->buf32k; - dataoff = cli_readn(dir->fd, (void *) hp, sizeof(struct zip_file_header)); - - if(dataoff < __sizeof(struct zip_file_header)) { - cli_errmsg("Unzip: zip_file_open: Can't read zip header (only read %d bytes)\n", dataoff); - dir->errcode = CL_EIO; - zip_file_close(fp); - return NULL; - } - - dataoff = EC16(hp->z_namlen) + EC16(hp->z_extras); - - if(lseek(dir->fd, dataoff, SEEK_CUR) < 0) { - cli_errmsg("Unzip: zip_file_open: Can't lseek descriptor %d\n", dir->fd); - dir->errcode = CL_EIO; - zip_file_close(fp); - return NULL; - } - - fp->usize = hdr->d_usize; - fp->csize = hdr->d_csize; - - fp->bf = hdr->d_bf; - - ret = __zip_inflate_init(fp, hdr); - - if(ret) { - dir->errcode = CL_EIO; - zip_file_close(fp); - return NULL; - } - - return fp; - - } else { - if(!hdr->d_reclen) - break; - - hdr = (zip_dir_hdr *) ((char *) hdr + hdr->d_reclen); - } - } - - dir->errcode = CL_EOPEN; - if(fp) - zip_file_close(fp); - return NULL; -} - -ssize_t zip_file_read(zip_file *fp, char *buf, size_t len) -{ - zip_dir *dir; - size_t l; - ssize_t bread; - - - if(!fp || !fp->dir) { - cli_errmsg("Unzip: zip_file_read: fp == NULL || fp->dir == NULL\n"); - return -1; - } - - dir = fp->dir; - l = fp->restlen > len ? len : fp->restlen; - if(!fp->restlen) - return 0; - - switch(fp->method) { - - case ZIP_METHOD_STORED: - bread = cli_readn(dir->fd, buf, l); - if(bread > 0) { - fp->restlen -= bread; - } else if(bread < 0) { - cli_errmsg("Unzip: zip_file_read: Can't read %d bytes\n", l); - dir->errcode = CL_EIO; - } - return bread; - - case ZIP_METHOD_DEFLATED: - case ZIP_METHOD_DEFLATED64: - fp->d_stream.avail_out = l; - fp->d_stream.next_out = (unsigned char *) buf; - do { - int ret; - size_t startlen; - - if(fp->crestlen > 0 && fp->d_stream.avail_in == 0) { - size_t cl = (fp->crestlen < ZIP32K ? fp->crestlen : ZIP32K); - ssize_t i = cli_readn(dir->fd, fp->buf32k, cl); - if(i <= 0) { - dir->errcode = CL_EIO; - cli_errmsg("Unzip: zip_file_read: Can't read %d bytes (read %d)\n", cl, i); - return -1; - } - fp->crestlen -= i; - fp->d_stream.avail_in = i; - fp->d_stream.next_in = (unsigned char *) fp->buf32k; - } - - startlen = fp->d_stream.total_out; - ret = inflate(&fp->d_stream, Z_NO_FLUSH); - - if(ret == Z_STREAM_END) { - fp->restlen = 0; - } else { - if(ret == Z_OK) { - fp->restlen -= (fp->d_stream.total_out - startlen); - } else { - if(fp->method == ZIP_METHOD_DEFLATED64) { - cli_dbgmsg("Unzip: zip_file_read: Not supported compression method (%u)\n", fp->method); - dir->errcode = CL_ESUPPORT; - } else { - dir->errcode = CL_EZIP; - } - return -1; - } - } - } while(fp->restlen && fp->d_stream.avail_out); - - return l - fp->d_stream.avail_out; - - default: - /* this should not be reached because of the previous check in - * zip_file_open - */ - cli_errmsg("Unzip: zip_file_read: Unknown compression method (%d)\n", fp->method); - dir->errcode = CL_EZIP; - return -1; - } -} diff --git a/libclamav/unzip.h b/libclamav/unzip.h deleted file mode 100644 index 728569c19..000000000 --- a/libclamav/unzip.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2003 - 2006 Tomasz Kojm - * (C) 2006 Sensory Networks, Inc. - * - * The code of this module was based on zziplib 0.12.83: - * (c) 1999 - 2002 Guido Draheim , published under - * the Lesser GNU General Public License - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#ifndef __UNZIP_H -#define __UNZIP_H - -#if HAVE_CONFIG_H -#include "clamav-config.h" -#endif - -#include -#include -#include - -#include "cltypes.h" - -#ifndef HAVE_ATTRIB_PACKED -#define __attribute__(x) -#endif - -#ifdef HAVE_PRAGMA_PACK -#pragma pack(1) -#endif - -#ifdef HAVE_PRAGMA_PACK_HPPA -#pragma pack 1 -#endif - -/******** Zip format structures *********/ - -/* Local file header */ -struct zip_file_header -{ -# define ZIP_FILE_HEADER_MAGIC 0x04034b50 - uint32_t z_magic; /* local file header signature */ - uint16_t z_version; /* version needed to extract */ - uint16_t z_flags; /* general purpose bit flag */ - uint16_t z_compr; /* compression method */ - uint16_t z_modtime; /* last mod file time */ - uint16_t z_moddate; /* last mod file date */ - uint32_t z_crc32; /* crc-32 */ - uint32_t z_csize; /* compressed size */ - uint32_t z_usize; /* uncompressed size */ - uint16_t z_namlen; /* file name length */ - uint16_t z_extras; /* extra field length */ - - /* followed by filename (of variable size) */ - /* followed by extra field (of variable size) */ -} __attribute__((packed)); - -/* Data descriptor (only if bit 3 of z_flags is set) */ -struct zip_file_trailer -{ -# define ZIP_FILE_TRAILER_MAGIC 0x08074B50 - uint32_t z_magic; /* data descriptor signature (0x08074b50) */ - uint32_t z_crc32; /* crc-32 */ - uint32_t z_csize; /* compressed size */ - uint32_t z_usize; /* uncompressed size */ -} __attribute__((packed)); - -/* Central file header */ -struct zip_root_dirent -{ -# define ZIP_ROOT_DIRENT_MAGIC 0x02014b50 - uint32_t z_magic; /* central file header signature */ - uint16_t z_version1; /* version made by */ - uint16_t z_version2; /* version needed to extract */ - uint16_t z_flags; /* general purpose bit flag */ - uint16_t z_compr; /* compression method */ - uint16_t z_modtime; /* last mod file time */ - uint16_t z_moddate; /* last mod file date */ - uint32_t z_crc32; /* crc-32 */ - uint32_t z_csize; /* compressed size */ - uint32_t z_usize; /* uncompressed size */ - uint16_t z_namlen; /* file name length */ - uint16_t z_extras; /* extra field length */ - uint16_t z_comment; /* file comment length */ - uint16_t z_diskstart; /* disk number start */ - uint16_t z_filetype; /* internal file attributes */ - uint32_t z_filemode; /* extrnal file attributes */ - uint32_t z_off; /* relative offset of local header */ - - /* followed by filename (of variable size) */ - /* followed by extra field (of variable size) */ - /* followed by file comment (of variable size) */ -} __attribute__((packed)); - -/* End of central directory record */ -struct zip_disk_trailer -{ -# define ZIP_DISK_TRAILER_MAGIC 0x06054b50 - uint32_t z_magic; /* end of central dir signature */ - uint16_t z_disk; /* number of this disk */ - uint16_t z_finaldisk; /* number of the disk with the start - * of the central dir - */ - uint16_t z_entries; /* total number of entries in the - * central dir on this disk - */ - uint16_t z_finalentries; /* total number of entries in the - * central dir - */ - uint32_t z_rootsize; /* size of the central directory */ - uint32_t z_rootseek; /* offset of start of central directory - * with respect to the starting disk - * number - */ - uint16_t z_comment; /* zipfile comment length */ - - /* followed by zipfile comment (of variable size) */ -} __attribute__((packed)); - -#define ZIP_METHOD_STORED 0 -#define ZIP_METHOD_SHRUNK 1 -#define ZIP_METHOD_REDUCEDx1 2 -#define ZIP_METHOD_REDUCEDx2 3 -#define ZIP_METHOD_REDUCEDx3 4 -#define ZIP_METHOD_REDUCEDx4 5 -#define ZIP_METHOD_IMPLODED 6 -#define ZIP_METHOD_TOKENIZED 7 -#define ZIP_METHOD_DEFLATED 8 -#define ZIP_METHOD_DEFLATED64 9 -#define ZIP_METHOD_IMPLODED_DCL 10 -#define ZIP_METHOD_BZIP2 12 -#define ZIP_METHOD_AES 99 - - -/******** Internal structures *********/ - -struct __zip_file -{ - struct __zip_dir *dir; - uint16_t method; - int16_t *bf; - size_t restlen; - size_t crestlen; - size_t usize; - size_t csize; - char *buf32k; - z_stream d_stream; -}; - -struct __zip_dir_hdr -{ - uint32_t d_usize; /* uncompressed size */ - uint32_t d_csize; /* compressed size */ - uint32_t d_crc32; /* crc-32 */ - uint32_t d_off; /* offset of file in zipfile */ - uint16_t d_reclen; /* next dir_hdr structure offset */ - uint16_t d_namlen; /* explicit namelen of d_name */ - uint16_t d_compr; /* compression type */ - int16_t d_bf[2]; /* compression type/brute force */ - uint16_t d_flags; /* general purpose flags */ - char d_name[1]; /* actual name of the entry */ -}; - -struct __zip_dirent -{ - uint16_t d_compr; /* compression method */ - uint32_t d_csize; /* compressed size */ - uint32_t st_size; /* file size / decompressed size */ - uint16_t d_flags; /* general purpose flags */ - char *d_name; /* file name / strdupped name */ - uint32_t d_crc32; /* crc-32 */ - uint32_t d_off; /* the offset in the file */ -}; - -struct __zip_dir -{ - int fd; - int errcode; - struct { - struct __zip_file *fp; - char *buf32k; - } cache; - struct __zip_dir_hdr *hdr0; - struct __zip_dir_hdr *hdr; - struct __zip_dirent dirent; -}; - -/* typedefs */ -typedef struct __zip_dir zip_dir; -typedef struct __zip_dir_hdr zip_dir_hdr; -typedef struct __zip_file zip_file; -typedef struct __zip_dirent zip_dirent; - -zip_dir *zip_dir_open(int fd, off_t start, int *errcode_p); -int zip_dir_read(zip_dir *dir, zip_dirent *d); -zip_file *zip_file_open(zip_dir *dir, const char *name, int d_off); -ssize_t zip_file_read(zip_file *fp, char *buf, size_t len); -int zip_file_close(zip_file *fp); -int zip_dir_close(zip_dir *dir); - -#ifdef HAVE_PRAGMA_PACK -#pragma pack() -#endif - -#ifdef HAVE_PRAGMA_PACK_HPPA -#pragma pack -#endif - -#endif /* __UNZIP_H */