dnl config.m4 for extension phar
PHP_ARG_ENABLE(phar, for phar support/phar zlib support,
-[ --enable-phar Enable phar support, use --with-zlib-dir if zlib detection fails])
+[ --enable-phar Enable phar support])
+
+PHP_ARG_WITH(phar-zip, for zip-based phar support,
+[ --without-phar-zip PHAR: Disable zip-based phar archive support], no, no)
if test "$PHP_PHAR" != "no"; then
- PHP_NEW_EXTENSION(phar, phar.c phar_object.c phar_path_check.c, $ext_shared)
+ AC_MSG_CHECKING([for zip-based phar support])
+ if test "$PHP_PHAR_ZIP" != "yes"; then
+ AC_MSG_RESULT([yes])
+ PHP_PHAR_SOURCES="$PHP_PHAR_SOURCES lib/zip_add.c lib/zip_error.c lib/zip_fclose.c \
+ lib/zip_fread.c lib/zip_open.c lib/zip_source_filep.c \
+ lib/zip_strerror.c lib/zip_close.c lib/zip_error_get.c \
+ lib/zip_file_error_get.c lib/zip_free.c lib/zip_rename.c \
+ lib/zip_source_free.c lib/zip_unchange_all.c lib/zip_delete.c \
+ lib/zip_error_get_sys_type.c lib/zip_file_get_offset.c \
+ lib/zip_get_name.c lib/zip_replace.c lib/zip_source_function.c \
+ lib/zip_unchange.c lib/zip_dirent.c lib/zip_error_strerror.c \
+ lib/zip_file_strerror.c lib/zip_get_num_files.c \
+ lib/zip_set_name.c lib/zip_source_zip.c lib/zip_unchange_data.c \
+ lib/zip_entry_free.c lib/zip_error_to_str.c lib/zip_fopen.c \
+ lib/zip_name_locate.c lib/zip_source_buffer.c lib/zip_stat.c \
+ lib/zip_entry_new.c lib/zip_err_str.c lib/zip_fopen_index.c \
+ lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c lib/zip_get_archive_comment.c \
+ lib/zip_get_file_comment.c lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \
+ lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \
+ lib/zip_error_clear.c lib/zip_file_error_clear.c"
+ AC_DEFINE(HAVE_PHAR_ZIP,1,[ ])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ PHP_NEW_EXTENSION(phar, phar.c phar_object.c phar_path_check.c $PHP_PHAR_SOURCES, $ext_shared)
+ PHP_ADD_BUILD_DIR($ext_builddir/lib, 1)
+ PHP_SUBST(PHAR_SHARED_LIBADD)
PHP_ADD_EXTENSION_DEP(phar, zlib, true)
PHP_ADD_EXTENSION_DEP(phar, bz2, true)
PHP_ADD_EXTENSION_DEP(phar, spl, true)
if (PHP_PHAR != "no") {
EXTENSION("phar", "phar.c phar_object.c phar_path_check.c");
+ ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_error.c zip_fclose.c \
+ zip_fread.c zip_open.c zip_source_filep.c \
+ zip_strerror.c zip_close.c zip_error_get.c \
+ zip_file_error_get.c zip_free.c zip_rename.c \
+ zip_source_free.c zip_unchange_all.c zip_delete.c \
+ zip_error_get_sys_type.c zip_file_get_offset.c \
+ zip_get_name.c zip_replace.c zip_source_function.c \
+ zip_unchange.c zip_dirent.c zip_error_strerror.c \
+ zip_file_strerror.c zip_get_num_files.c \
+ zip_set_name.c zip_source_zip.c zip_unchange_data.c \
+ zip_entry_free.c zip_error_to_str.c zip_fopen.c \
+ zip_name_locate.c zip_source_buffer.c zip_stat.c \
+ zip_entry_new.c zip_err_str.c zip_fopen_index.c \
+ zip_new.c zip_source_file.c zip_stat_index.c \
+ zip_get_archive_comment.c zip_get_file_comment.c \
+ zip_set_archive_comment.c zip_set_file_comment.c \
+ zip_unchange_archive.c zip_memdup.c zip_stat_init.c \
+ zip_add_dir.c zip_file_error_clear.c zip_error_clear.c", "phar");
ADD_EXTENSION_DEP('phar', 'zlib', true);
ADD_EXTENSION_DEP('phar', 'bz2', true);
ADD_EXTENSION_DEP('phar', 'spl', true);
--- /dev/null
+/* $NiH: mkstemp.c,v 1.3 2006/04/23 14:51:45 wiz Exp $ */
+
+/* Adapted from NetBSB libc by Dieter Baron */
+
+/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+int
+_zip_mkstemp(char *path)
+{
+ int fd;
+ char *start, *trv;
+ struct stat sbuf;
+ pid_t pid;
+
+ /* To guarantee multiple calls generate unique names even if
+ the file is not created. 676 different possibilities with 7
+ or more X's, 26 with 6 or less. */
+ static char xtra[2] = "aa";
+ int xcnt = 0;
+
+ pid = getpid();
+
+ /* Move to end of path and count trailing X's. */
+ for (trv = path; *trv; ++trv)
+ if (*trv == 'X')
+ xcnt++;
+ else
+ xcnt = 0;
+
+ /* Use at least one from xtra. Use 2 if more than 6 X's. */
+ if (*(trv - 1) == 'X')
+ *--trv = xtra[0];
+ if (xcnt > 6 && *(trv - 1) == 'X')
+ *--trv = xtra[1];
+
+ /* Set remaining X's to pid digits with 0's to the left. */
+ while (*--trv == 'X') {
+ *trv = (pid % 10) + '0';
+ pid /= 10;
+ }
+
+ /* update xtra for next call. */
+ if (xtra[0] != 'z')
+ xtra[0]++;
+ else {
+ xtra[0] = 'a';
+ if (xtra[1] != 'z')
+ xtra[1]++;
+ else
+ xtra[1] = 'a';
+ }
+
+ /*
+ * check the target directory; if you have six X's and it
+ * doesn't exist this runs for a *very* long time.
+ */
+ for (start = trv + 1;; --trv) {
+ if (trv <= path)
+ break;
+ if (*trv == '/') {
+ *trv = '\0';
+ if (stat(path, &sbuf))
+ return (0);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return (0);
+ }
+ *trv = '/';
+ break;
+ }
+ }
+
+ for (;;) {
+ if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0)
+ return (1);
+ if (errno != EEXIST)
+ return (0);
+
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (!*trv)
+ return (0);
+ if (*trv == 'z')
+ *trv++ = 'a';
+ else {
+ if (isdigit((unsigned char)*trv))
+ *trv = 'a';
+ else
+ ++*trv;
+ break;
+ }
+ }
+ }
+ /*NOTREACHED*/
+}
--- /dev/null
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
--- /dev/null
+#ifndef _HAD_ZIP_H
+#define _HAD_ZIP_H
+
+/*
+ $NiH: zip.h,v 1.57 2006/04/24 14:04:19 dillo Exp $
+
+ zip.h -- exported declarations.
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "zip_win32.h"
+
+/* flags for zip_open */
+
+#define ZIP_CREATE 1
+#define ZIP_EXCL 2
+#define ZIP_CHECKCONS 4
+#define ZIP_OVERWRITE 8
+
+
+/* flags for zip_name_locate, zip_fopen, zip_stat, ... */
+
+#define ZIP_FL_NOCASE 1 /* ignore case on name lookup */
+#define ZIP_FL_NODIR 2 /* ignore directory component */
+#define ZIP_FL_COMPRESSED 4 /* read compressed data */
+#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */
+
+/* libzip error codes */
+
+#define ZIP_ER_OK 0 /* N No error */
+#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */
+#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */
+#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */
+#define ZIP_ER_SEEK 4 /* S Seek error */
+#define ZIP_ER_READ 5 /* S Read error */
+#define ZIP_ER_WRITE 6 /* S Write error */
+#define ZIP_ER_CRC 7 /* N CRC error */
+#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */
+#define ZIP_ER_NOENT 9 /* N No such file */
+#define ZIP_ER_EXISTS 10 /* N File already exists */
+#define ZIP_ER_OPEN 11 /* S Can't open file */
+#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */
+#define ZIP_ER_ZLIB 13 /* Z Zlib error */
+#define ZIP_ER_MEMORY 14 /* N Malloc failure */
+#define ZIP_ER_CHANGED 15 /* N Entry has been changed */
+#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */
+#define ZIP_ER_EOF 17 /* N Premature EOF */
+#define ZIP_ER_INVAL 18 /* N Invalid argument */
+#define ZIP_ER_NOZIP 19 /* N Not a zip archive */
+#define ZIP_ER_INTERNAL 20 /* N Internal error */
+#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */
+#define ZIP_ER_REMOVE 22 /* S Can't remove file */
+#define ZIP_ER_DELETED 23 /* N Entry has been deleted */
+
+
+/* type of system error value */
+
+#define ZIP_ET_NONE 0 /* sys_err unused */
+#define ZIP_ET_SYS 1 /* sys_err is errno */
+#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */
+
+/* compression methods */
+
+#define ZIP_CM_DEFAULT -1 /* better of deflate or store */
+#define ZIP_CM_STORE 0 /* stored (uncompressed) */
+#define ZIP_CM_SHRINK 1 /* shrunk */
+#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */
+#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */
+#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */
+#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */
+#define ZIP_CM_IMPLODE 6 /* imploded */
+/* 7 - Reserved for Tokenizing compression algorithm */
+#define ZIP_CM_DEFLATE 8 /* deflated */
+#define ZIP_CM_DEFLATE64 9 /* deflate64 */
+#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */
+/* 11 - Reserved by PKWARE */
+#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */
+
+/* encryption methods */
+
+#define ZIP_EM_NONE 0 /* not encrypted */
+#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */
+#if 0 /* Strong Encryption Header not parsed yet */
+#define ZIP_EM_DES 0x6601 /* strong encryption: DES */
+#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */
+#define ZIP_EM_3DES_168 0x6603
+#define ZIP_EM_3DES_112 0x6609
+#define ZIP_EM_AES_128 0x660e
+#define ZIP_EM_AES_192 0x660f
+#define ZIP_EM_AES_256 0x6610
+#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */
+#define ZIP_EM_RC4 0x6801
+#endif
+#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */
+
+\f
+
+enum zip_source_cmd {
+ ZIP_SOURCE_OPEN, /* prepare for reading */
+ ZIP_SOURCE_READ, /* read data */
+ ZIP_SOURCE_CLOSE, /* reading is done */
+ ZIP_SOURCE_STAT, /* get meta information */
+ ZIP_SOURCE_ERROR, /* get error information */
+ ZIP_SOURCE_FREE /* cleanup and free resources */
+};
+
+typedef ssize_t (*zip_source_callback)(void *state, void *data,
+ size_t len, enum zip_source_cmd cmd);
+
+struct zip_stat {
+ const char *name; /* name of the file */
+ int index; /* index within archive */
+ unsigned int crc; /* crc of file data */
+ time_t mtime; /* modification time */
+ off_t size; /* size of file (uncompressed) */
+ off_t comp_size; /* size of file (compressed) */
+ unsigned short comp_method; /* compression method used */
+ unsigned short encryption_method; /* encryption method used */
+};
+
+struct zip;
+struct zip_file;
+struct zip_source;
+
+\f
+
+int zip_add(struct zip *, const char *, struct zip_source *);
+int zip_add_dir(struct zip *, const char *);
+int zip_close(struct zip *);
+int zip_delete(struct zip *, int);
+void zip_error_clear(struct zip *);
+void zip_error_get(struct zip *, int *, int *);
+int zip_error_get_sys_type(int);
+int zip_error_to_str(char *, size_t, int, int);
+int zip_fclose(struct zip_file *);
+void zip_file_error_clear(struct zip_file *);
+void zip_file_error_get(struct zip_file *, int *, int *);
+const char *zip_file_strerror(struct zip_file *);
+struct zip_file *zip_fopen(struct zip *, const char *, int);
+struct zip_file *zip_fopen_index(struct zip *, int, int);
+ssize_t zip_fread(struct zip_file *, void *, size_t);
+const char *zip_get_archive_comment(struct zip *, int *, int);
+const char *zip_get_file_comment(struct zip *, int, int *, int);
+const char *zip_get_name(struct zip *, int, int);
+int zip_get_num_files(struct zip *);
+int zip_name_locate(struct zip *, const char *, int);
+struct zip *zip_open(const char *, int, int *);
+int zip_rename(struct zip *, int, const char *);
+int zip_replace(struct zip *, int, struct zip_source *);
+int zip_set_archive_comment(struct zip *, const char *, int);
+int zip_set_file_comment(struct zip *, int, const char *, int);
+struct zip_source *zip_source_buffer(struct zip *, const void *, off_t, int);
+struct zip_source *zip_source_file(struct zip *, const char *, off_t, off_t);
+struct zip_source *zip_source_filep(struct zip *, FILE *, off_t, off_t);
+void zip_source_free(struct zip_source *);
+struct zip_source *zip_source_function(struct zip *,
+ zip_source_callback, void *);
+struct zip_source *zip_source_zip(struct zip *, struct zip *, int, int,
+ off_t, off_t);
+int zip_stat(struct zip *, const char *, int, struct zip_stat *);
+int zip_stat_index(struct zip *, int, int, struct zip_stat *);
+void zip_stat_init(struct zip_stat *);
+const char *zip_strerror(struct zip *);
+int zip_unchange(struct zip *, int);
+int zip_unchange_all(struct zip *);
+int zip_unchange_archive(struct zip *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HAD_ZIP_H */
--- /dev/null
+/*
+ $NiH: zip_add.c,v 1.14 2004/11/18 15:04:04 wiz Exp $
+
+ zip_add.c -- add file via callback function
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_add(struct zip *za, const char *name, struct zip_source *source)
+{
+ if (name == NULL || source == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+ return _zip_replace(za, -1, name, source);
+}
--- /dev/null
+/*
+ $NiH: zip_add_dir.c,v 1.1 2006/10/03 12:23:13 dillo Exp $
+
+ zip_add_dir.c -- add directory
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_add_dir(struct zip *za, const char *name)
+{
+ int len, ret;
+ char *s;
+ struct zip_source *source;
+
+ if (name == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ s = NULL;
+ len = strlen(name);
+
+ if (name[len-1] != '/') {
+ if ((s=(char *)malloc(len+2)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ strcpy(s, name);
+ s[len] = '/';
+ s[len+1] = '\0';
+ }
+
+ if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
+ free(s);
+ return -1;
+ }
+
+ ret = _zip_replace(za, -1, s ? s : name, source);
+
+ free(s);
+ if (ret < 0)
+ zip_source_free(source);
+
+ return ret;
+}
--- /dev/null
+/*
+ $NiH: zip_close.c,v 1.60 2006/05/09 17:21:47 wiz Exp $
+
+ zip_close.c -- close zip archive and update changes
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+static int add_data(struct zip *, int, struct zip_dirent *, FILE *);
+static int add_data_comp(zip_source_callback, void *, struct zip_stat *,
+ FILE *, struct zip_error *);
+static int add_data_uncomp(zip_source_callback, void *, struct zip_stat *,
+ FILE *, struct zip_error *);
+static void ch_set_error(struct zip_error *, zip_source_callback, void *);
+static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
+static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
+static int _zip_changed(struct zip *, int *);
+static char *_zip_create_temp_output(struct zip *, FILE **);
+
+int
+zip_close(struct zip *za)
+{
+ int survivors;
+ int i, j, error;
+ char *temp;
+ FILE *out;
+ mode_t mask;
+ struct zip_cdir *cd;
+ struct zip_dirent de;
+ int rename_error = 0;
+
+ if (!_zip_changed(za, &survivors)) {
+ _zip_free(za);
+ return 0;
+ }
+
+ /* don't create zip files with no entries */
+ if (survivors == 0) {
+ if (za->zn) {
+ if (remove(za->zn) != 0) {
+ _zip_error_set(&za->error, ZIP_ER_REMOVE, errno);
+ return -1;
+ }
+ }
+ _zip_free(za);
+ return 0;
+ }
+
+ if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL)
+ return -1;
+
+ for (i=0; i<survivors; i++)
+ _zip_dirent_init(&cd->entry[i]);
+
+ if (_zip_cdir_set_comment(cd, za) == -1) {
+ _zip_cdir_free(cd);
+ return -1;
+ }
+
+ if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
+ _zip_cdir_free(cd);
+ return -1;
+ }
+
+ error = 0;
+ for (i=j=0; i<za->nentry; i++) {
+ if (za->entry[i].state == ZIP_ST_DELETED)
+ continue;
+
+ /* create new local directory entry */
+ if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
+ _zip_dirent_init(&de);
+ /* use it as central directory entry */
+ memcpy(cd->entry+j, &de, sizeof(cd->entry[j]));
+
+ /* set/update file name */
+ if (za->entry[i].ch_filename == NULL) {
+ if (za->entry[i].state == ZIP_ST_REPLACED) {
+ de.filename = strdup(za->cdir->entry[i].filename);
+ de.filename_len = strlen(de.filename);
+ cd->entry[j].filename = za->cdir->entry[i].filename;
+ cd->entry[j].filename_len = de.filename_len;
+ }
+ else {
+ de.filename = strdup("-");
+ de.filename_len = 1;
+ cd->entry[j].filename = "-";
+ cd->entry[j].filename_len = de.filename_len;
+ }
+ }
+ }
+ else {
+ /* copy existing directory entries */
+ if (fseek(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ error = 1;
+ break;
+ }
+ if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0) {
+ error = 1;
+ break;
+ }
+
+ if (de.bitflags & ZIP_GPBF_USE_DATA_DESCRIPTOR) {
+ de.crc = (za->cdir->entry+i)->crc;
+ de.comp_size = (za->cdir->entry+i)->comp_size;
+ de.uncomp_size = (za->cdir->entry+i)->uncomp_size;
+ }
+ memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
+ }
+
+ if (za->entry[i].ch_filename) {
+ free(de.filename);
+ if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) {
+ error = 1;
+ break;
+ }
+ de.filename_len = strlen(de.filename);
+ cd->entry[j].filename = za->entry[i].ch_filename;
+ cd->entry[j].filename_len = de.filename_len;
+ }
+
+ if (za->entry[i].ch_comment_len != -1) {
+ /* as the rest of cd entries, its malloc/free is done by za */
+ cd->entry[j].comment = za->entry[i].ch_comment;
+ cd->entry[j].comment_len = za->entry[i].ch_comment_len;
+ }
+
+ cd->entry[j].offset = ftell(out);
+
+ if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
+ if (add_data(za, i, &de, out) < 0) {
+ error = 1;
+ break;
+ }
+
+ cd->entry[j].last_mod = de.last_mod;
+ cd->entry[j].comp_method = de.comp_method;
+ cd->entry[j].comp_size = de.comp_size;
+ cd->entry[j].uncomp_size = de.uncomp_size;
+ cd->entry[j].crc = de.crc;
+ }
+ else {
+ if (_zip_dirent_write(&de, out, 1, &za->error) < 0) {
+ error = 1;
+ break;
+ }
+ /* we just read the local dirent, file is at correct position */
+ if (copy_data(za->zp, de.comp_size, out, &za->error) < 0) {
+ error = 1;
+ break;
+ }
+ }
+
+ j++;
+
+ _zip_dirent_finalize(&de);
+ }
+
+ if (!error) {
+ if (_zip_cdir_write(cd, out, &za->error) < 0)
+ error = 1;
+ }
+
+ /* pointers in cd entries are owned by za */
+ cd->nentry = 0;
+ _zip_cdir_free(cd);
+
+ if (error) {
+ _zip_dirent_finalize(&de);
+ fclose(out);
+ remove(temp);
+ free(temp);
+ return -1;
+ }
+
+ if (fclose(out) != 0) {
+ _zip_error_set(&za->error, ZIP_ER_CLOSE, errno);
+ remove(temp);
+ free(temp);
+ return -1;
+ }
+
+ if (za->zp) {
+ fclose(za->zp);
+ za->zp = NULL;
+ }
+
+#ifdef PHP_WIN32
+ if (!MoveFileEx(temp, za->zn, MOVEFILE_REPLACE_EXISTING)) {
+ rename_error = -1;
+ }
+#else
+ if (rename(temp, za->zn) != 0) {
+ rename_error = -1;
+ }
+#endif
+
+ if (rename_error < 0) {
+ _zip_error_set(&za->error, ZIP_ER_RENAME, errno);
+ remove(temp);
+ free(temp);
+ return -1;
+ }
+
+ mask = umask(0);
+ umask(mask);
+ chmod(za->zn, 0666&~mask);
+
+ _zip_free(za);
+ free(temp);
+ return 0;
+}
+
+\f
+
+static int
+add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft)
+{
+ off_t offstart, offend;
+ zip_source_callback cb;
+ void *ud;
+ struct zip_stat st;
+
+ cb = za->entry[idx].source->f;
+ ud = za->entry[idx].source->ud;
+
+ if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) {
+ ch_set_error(&za->error, cb, ud);
+ return -1;
+ }
+
+ if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
+ ch_set_error(&za->error, cb, ud);
+ return -1;
+ }
+
+ offstart = ftell(ft);
+
+ if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
+ return -1;
+
+ if (st.comp_method != ZIP_CM_STORE) {
+ if (add_data_comp(cb, ud, &st, ft, &za->error) < 0)
+ return -1;
+ }
+ else {
+ if (add_data_uncomp(cb, ud, &st, ft, &za->error) < 0)
+ return -1;
+ }
+
+ if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) {
+ ch_set_error(&za->error, cb, ud);
+ return -1;
+ }
+
+ offend = ftell(ft);
+
+ if (fseek(ft, offstart, SEEK_SET) < 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ de->comp_method = st.comp_method;
+ de->last_mod = st.mtime;
+ de->crc = st.crc;
+ de->uncomp_size = st.size;
+ de->comp_size = st.comp_size;
+
+ if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
+ return -1;
+
+ if (fseek(ft, offend, SEEK_SET) < 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+\f
+
+static int
+add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft,
+ struct zip_error *error)
+{
+ char buf[BUFSIZE];
+ ssize_t n;
+
+ st->comp_size = 0;
+ while ((n=cb(ud, buf, sizeof(buf), ZIP_SOURCE_READ)) > 0) {
+ if (fwrite(buf, 1, n, ft) != (size_t)n) {
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
+ return -1;
+ }
+
+ st->comp_size += n;
+ }
+ if (n < 0) {
+ ch_set_error(error, cb, ud);
+ return -1;
+ }
+
+ return 0;
+}
+
+\f
+
+static int
+add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
+ FILE *ft, struct zip_error *error)
+{
+ char b1[BUFSIZE], b2[BUFSIZE];
+ int end, flush, ret;
+ ssize_t n;
+ size_t n2;
+ z_stream zstr;
+
+ st->comp_method = ZIP_CM_DEFLATE;
+ st->comp_size = st->size = 0;
+ st->crc = crc32(0, NULL, 0);
+
+ zstr.zalloc = Z_NULL;
+ zstr.zfree = Z_NULL;
+ zstr.opaque = NULL;
+ zstr.avail_in = 0;
+ zstr.avail_out = 0;
+
+ /* -15: undocumented feature of zlib to _not_ write a zlib header */
+ deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 9,
+ Z_DEFAULT_STRATEGY);
+
+ zstr.next_out = (Bytef *)b2;
+ zstr.avail_out = sizeof(b2);
+ zstr.avail_in = 0;
+
+ flush = 0;
+ end = 0;
+ while (!end) {
+ if (zstr.avail_in == 0 && !flush) {
+ if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) {
+ ch_set_error(error, cb, ud);
+ deflateEnd(&zstr);
+ return -1;
+ }
+ if (n > 0) {
+ zstr.avail_in = n;
+ zstr.next_in = (Bytef *)b1;
+ st->size += n;
+ st->crc = crc32(st->crc, (Bytef *)b1, n);
+ }
+ else
+ flush = Z_FINISH;
+ }
+
+ ret = deflate(&zstr, flush);
+ if (ret != Z_OK && ret != Z_STREAM_END) {
+ _zip_error_set(error, ZIP_ER_ZLIB, ret);
+ return -1;
+ }
+
+ if (zstr.avail_out != sizeof(b2)) {
+ n2 = sizeof(b2) - zstr.avail_out;
+
+ if (fwrite(b2, 1, n2, ft) != n2) {
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
+ return -1;
+ }
+
+ zstr.next_out = (Bytef *)b2;
+ zstr.avail_out = sizeof(b2);
+ st->comp_size += n2;
+ }
+
+ if (ret == Z_STREAM_END) {
+ deflateEnd(&zstr);
+ end = 1;
+ }
+ }
+
+ return 0;
+}
+
+\f
+
+static void
+ch_set_error(struct zip_error *error, zip_source_callback cb, void *ud)
+{
+ int e[2];
+
+ if ((cb(ud, e, sizeof(e), ZIP_SOURCE_ERROR)) < (ssize_t)sizeof(e)) {
+ error->zip_err = ZIP_ER_INTERNAL;
+ error->sys_err = 0;
+ }
+ else {
+ error->zip_err = e[0];
+ error->sys_err = e[1];
+ }
+}
+
+\f
+
+static int
+copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
+{
+ char buf[BUFSIZE];
+ int n, nn;
+
+ if (len == 0)
+ return 0;
+
+ while (len > 0) {
+ nn = len > sizeof(buf) ? sizeof(buf) : len;
+ if ((n=fread(buf, 1, nn, fs)) < 0) {
+ _zip_error_set(error, ZIP_ER_READ, errno);
+ return -1;
+ }
+ else if (n == 0) {
+ _zip_error_set(error, ZIP_ER_EOF, 0);
+ return -1;
+ }
+
+ if (fwrite(buf, 1, n, ft) != (size_t)n) {
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
+ return -1;
+ }
+
+ len -= n;
+ }
+
+ return 0;
+}
+
+\f
+
+static int
+_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
+{
+ if (src->ch_comment_len != -1) {
+ dest->comment = _zip_memdup(src->ch_comment,
+ src->ch_comment_len, &src->error);
+ if (dest->comment == NULL)
+ return -1;
+ dest->comment_len = src->ch_comment_len;
+ } else {
+ if (src->cdir && src->cdir->comment) {
+ dest->comment = _zip_memdup(src->cdir->comment,
+ src->cdir->comment_len, &src->error);
+ if (dest->comment == NULL)
+ return -1;
+ dest->comment_len = src->cdir->comment_len;
+ }
+ }
+
+ return 0;
+}
+
+\f
+
+static int
+_zip_changed(struct zip *za, int *survivorsp)
+{
+ int changed, i, survivors;
+
+ changed = survivors = 0;
+
+ if (za->ch_comment_len != -1)
+ changed = 1;
+
+ for (i=0; i<za->nentry; i++) {
+ if ((za->entry[i].state != ZIP_ST_UNCHANGED)
+ || (za->entry[i].ch_comment_len != -1))
+ changed = 1;
+ if (za->entry[i].state != ZIP_ST_DELETED)
+ survivors++;
+ }
+
+ *survivorsp = survivors;
+
+ return changed;
+}
+
+\f
+
+static char *
+_zip_create_temp_output(struct zip *za, FILE **outp)
+{
+ char *temp;
+ int tfd;
+ FILE *tfp;
+ int len = strlen(za->zn) + 8;
+
+ if ((temp=(char *)malloc(len)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ snprintf(temp, len, "%s.XXXXXX", za->zn);
+
+ if ((tfd=mkstemp(temp)) == -1) {
+ _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
+ free(temp);
+ return NULL;
+ }
+
+ if ((tfp=fdopen(tfd, "r+b")) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
+ close(tfd);
+ remove(temp);
+ free(temp);
+ return NULL;
+ }
+#ifdef PHP_WIN32
+ _setmode(_fileno(tfp), _O_BINARY );
+#endif
+
+ *outp = tfp;
+ return temp;
+}
--- /dev/null
+/*
+ $NiH: zip_delete.c,v 1.17 2005/06/09 19:57:09 dillo Exp $
+
+ zip_delete.c -- delete file from zip archive
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_delete(struct zip *za, int idx)
+{
+ if (idx < 0 || idx >= za->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ /* allow duplicate file names, because the file will
+ * be removed directly afterwards */
+ if (_zip_unchange(za, idx, 1) != 0)
+ return -1;
+
+ za->entry[idx].state = ZIP_ST_DELETED;
+
+ return 0;
+}
+
+\f
--- /dev/null
+/*
+ $NiH: zip_dirent.c,v 1.9 2006/04/23 14:51:45 wiz Exp $
+
+ zip_dirent.c -- read directory entry (local or central), clean dirent
+ Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "main/php_reentrancy.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+static time_t _zip_d2u_time(int, int);
+static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *);
+static char *_zip_readstr(unsigned char **, int, int, struct zip_error *);
+static void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
+static void _zip_write2(unsigned short, FILE *);
+static void _zip_write4(unsigned int, FILE *);
+
+\f
+
+void
+_zip_cdir_free(struct zip_cdir *cd)
+{
+ int i;
+
+ if (!cd)
+ return;
+
+ for (i=0; i<cd->nentry; i++)
+ _zip_dirent_finalize(cd->entry+i);
+ free(cd->comment);
+ free(cd->entry);
+ free(cd);
+}
+
+\f
+
+struct zip_cdir *
+_zip_cdir_new(int nentry, struct zip_error *error)
+{
+ struct zip_cdir *cd;
+
+ if ((cd=(struct zip_cdir *)malloc(sizeof(*cd))) == NULL) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry))
+ == NULL) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(cd);
+ return NULL;
+ }
+
+ /* entries must be initialized by caller */
+
+ cd->nentry = nentry;
+ cd->size = cd->offset = 0;
+ cd->comment = NULL;
+ cd->comment_len = 0;
+
+ return cd;
+}
+
+\f
+
+int
+_zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error)
+{
+ int i;
+
+ cd->offset = ftell(fp);
+
+ for (i=0; i<cd->nentry; i++) {
+ if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0)
+ return -1;
+ }
+
+ cd->size = ftell(fp) - cd->offset;
+
+ /* clearerr(fp); */
+ fwrite(EOCD_MAGIC, 1, 4, fp);
+ _zip_write4(0, fp);
+ _zip_write2((unsigned short)cd->nentry, fp);
+ _zip_write2((unsigned short)cd->nentry, fp);
+ _zip_write4(cd->size, fp);
+ _zip_write4(cd->offset, fp);
+ _zip_write2(cd->comment_len, fp);
+ fwrite(cd->comment, 1, cd->comment_len, fp);
+
+ if (ferror(fp)) {
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+\f
+
+void
+_zip_dirent_finalize(struct zip_dirent *zde)
+{
+ free(zde->filename);
+ zde->filename = NULL;
+ free(zde->extrafield);
+ zde->extrafield = NULL;
+ free(zde->comment);
+ zde->comment = NULL;
+}
+
+\f
+
+void
+_zip_dirent_init(struct zip_dirent *de)
+{
+ de->version_madeby = 0;
+ de->version_needed = 20; /* 2.0 */
+ de->bitflags = 0;
+ de->comp_method = 0;
+ de->last_mod = 0;
+ de->crc = 0;
+ de->comp_size = 0;
+ de->uncomp_size = 0;
+ de->filename = NULL;
+ de->filename_len = 0;
+ de->extrafield = NULL;
+ de->extrafield_len = 0;
+ de->comment = NULL;
+ de->comment_len = 0;
+ de->disk_number = 0;
+ de->int_attrib = 0;
+ de->ext_attrib = 0;
+ de->offset = 0;
+}
+
+\f
+
+/* _zip_dirent_read(zde, fp, bufp, left, localp, error):
+ Fills the zip directory entry zde.
+
+ If bufp is non-NULL, data is taken from there and bufp is advanced
+ by the amount of data used; no more than left bytes are used.
+ Otherwise data is read from fp as needed.
+
+ If localp != 0, it reads a local header instead of a central
+ directory entry.
+
+ Returns 0 if successful. On error, error is filled in and -1 is
+ returned.
+*/
+
+int
+_zip_dirent_read(struct zip_dirent *zde, FILE *fp,
+ unsigned char **bufp, unsigned int left, int localp,
+ struct zip_error *error)
+{
+ unsigned char buf[CDENTRYSIZE];
+ unsigned char *cur;
+ unsigned short dostime, dosdate;
+ unsigned int size;
+
+ if (localp)
+ size = LENTRYSIZE;
+ else
+ size = CDENTRYSIZE;
+
+ if (bufp) {
+ /* use data from buffer */
+ cur = *bufp;
+ if (left < size) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+ }
+ else {
+ /* read entry from disk */
+ if ((fread(buf, 1, size, fp)<size)) {
+ _zip_error_set(error, ZIP_ER_READ, errno);
+ return -1;
+ }
+ left = size;
+ cur = buf;
+ }
+
+ if (memcmp(cur, (localp ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+ cur += 4;
+
+
+ /* convert buffercontents to zip_dirent */
+
+ if (!localp)
+ zde->version_madeby = _zip_read2(&cur);
+ else
+ zde->version_madeby = 0;
+ zde->version_needed = _zip_read2(&cur);
+ zde->bitflags = _zip_read2(&cur);
+ zde->comp_method = _zip_read2(&cur);
+
+ /* convert to time_t */
+ dostime = _zip_read2(&cur);
+ dosdate = _zip_read2(&cur);
+ zde->last_mod = _zip_d2u_time(dostime, dosdate);
+
+ zde->crc = _zip_read4(&cur);
+ zde->comp_size = _zip_read4(&cur);
+ zde->uncomp_size = _zip_read4(&cur);
+
+ zde->filename_len = _zip_read2(&cur);
+ zde->extrafield_len = _zip_read2(&cur);
+
+ if (localp) {
+ zde->comment_len = 0;
+ zde->disk_number = 0;
+ zde->int_attrib = 0;
+ zde->ext_attrib = 0;
+ zde->offset = 0;
+ } else {
+ zde->comment_len = _zip_read2(&cur);
+ zde->disk_number = _zip_read2(&cur);
+ zde->int_attrib = _zip_read2(&cur);
+ zde->ext_attrib = _zip_read4(&cur);
+ zde->offset = _zip_read4(&cur);
+ }
+
+ zde->filename = NULL;
+ zde->extrafield = NULL;
+ zde->comment = NULL;
+
+ if (bufp) {
+ if (left < CDENTRYSIZE + (zde->filename_len+zde->extrafield_len
+ +zde->comment_len)) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+
+ if (zde->filename_len) {
+ zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error);
+ if (!zde->filename)
+ return -1;
+ }
+
+ if (zde->extrafield_len) {
+ zde->extrafield = _zip_readstr(&cur, zde->extrafield_len, 0,
+ error);
+ if (!zde->extrafield)
+ return -1;
+ }
+
+ if (zde->comment_len) {
+ zde->comment = _zip_readstr(&cur, zde->comment_len, 0, error);
+ if (!zde->comment)
+ return -1;
+ }
+ }
+ else {
+ if (zde->filename_len) {
+ zde->filename = _zip_readfpstr(fp, zde->filename_len, 1, error);
+ if (!zde->filename)
+ return -1;
+ }
+
+ if (zde->extrafield_len) {
+ zde->extrafield = _zip_readfpstr(fp, zde->extrafield_len, 0,
+ error);
+ if (!zde->extrafield)
+ return -1;
+ }
+
+ if (zde->comment_len) {
+ zde->comment = _zip_readfpstr(fp, zde->comment_len, 0, error);
+ if (!zde->comment)
+ return -1;
+ }
+ }
+
+ if (bufp)
+ *bufp = cur;
+
+ return 0;
+}
+
+\f
+
+/* _zip_dirent_write(zde, fp, localp, error):
+ Writes zip directory entry zde to file fp.
+
+ If localp != 0, it writes a local header instead of a central
+ directory entry.
+
+ Returns 0 if successful. On error, error is filled in and -1 is
+ returned.
+*/
+
+int
+_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp,
+ struct zip_error *error)
+{
+ unsigned short dostime, dosdate;
+
+ fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp);
+
+ if (!localp)
+ _zip_write2(zde->version_madeby, fp);
+ _zip_write2(zde->version_needed, fp);
+ _zip_write2(zde->bitflags, fp);
+ _zip_write2(zde->comp_method, fp);
+
+ _zip_u2d_time(zde->last_mod, &dostime, &dosdate);
+ _zip_write2(dostime, fp);
+ _zip_write2(dosdate, fp);
+
+ _zip_write4(zde->crc, fp);
+ _zip_write4(zde->comp_size, fp);
+ _zip_write4(zde->uncomp_size, fp);
+
+ _zip_write2(zde->filename_len, fp);
+ _zip_write2(zde->extrafield_len, fp);
+
+ if (!localp) {
+ _zip_write2(zde->comment_len, fp);
+ _zip_write2(zde->disk_number, fp);
+ _zip_write2(zde->int_attrib, fp);
+ _zip_write4(zde->ext_attrib, fp);
+ _zip_write4(zde->offset, fp);
+ }
+
+ if (zde->filename_len)
+ fwrite(zde->filename, 1, zde->filename_len, fp);
+
+ if (zde->extrafield_len)
+ fwrite(zde->extrafield, 1, zde->extrafield_len, fp);
+
+ if (!localp) {
+ if (zde->comment_len)
+ fwrite(zde->comment, 1, zde->comment_len, fp);
+ }
+
+ if (ferror(fp)) {
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+\f
+
+static time_t
+_zip_d2u_time(int dtime, int ddate)
+{
+ struct tm *tm, tmbuf;
+ time_t now;
+
+ now = time(NULL);
+ tm = php_localtime_r(&now, &tmbuf);
+
+ tm->tm_year = ((ddate>>9)&127) + 1980 - 1900;
+ tm->tm_mon = ((ddate>>5)&15) - 1;
+ tm->tm_mday = ddate&31;
+
+ tm->tm_hour = (dtime>>11)&31;
+ tm->tm_min = (dtime>>5)&63;
+ tm->tm_sec = (dtime<<1)&62;
+
+ return mktime(tm);
+}
+
+\f
+
+unsigned short
+_zip_read2(unsigned char **a)
+{
+ unsigned short ret;
+
+ ret = (*a)[0]+((*a)[1]<<8);
+ *a += 2;
+
+ return ret;
+}
+
+\f
+
+unsigned int
+_zip_read4(unsigned char **a)
+{
+ unsigned int ret;
+
+ ret = ((((((*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
+ *a += 4;
+
+ return ret;
+}
+
+\f
+
+static char *
+_zip_readfpstr(FILE *fp, unsigned int len, int nulp, struct zip_error *error)
+{
+ char *r, *o;
+
+ r = (char *)malloc(nulp ? len+1 : len);
+ if (!r) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if (fread(r, 1, len, fp)<len) {
+ free(r);
+ _zip_error_set(error, ZIP_ER_READ, errno);
+ return NULL;
+ }
+
+ if (nulp) {
+ /* replace any in-string NUL characters with spaces */
+ r[len] = 0;
+ for (o=r; o<r+len; o++)
+ if (*o == '\0')
+ *o = ' ';
+ }
+
+ return r;
+}
+
+\f
+
+static char *
+_zip_readstr(unsigned char **buf, int len, int nulp, struct zip_error *error)
+{
+ char *r, *o;
+
+ r = (char *)malloc(nulp ? len+1 : len);
+ if (!r) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ memcpy(r, *buf, len);
+ *buf += len;
+
+ if (nulp) {
+ /* replace any in-string NUL characters with spaces */
+ r[len] = 0;
+ for (o=r; o<r+len; o++)
+ if (*o == '\0')
+ *o = ' ';
+ }
+
+ return r;
+}
+
+\f
+
+static void
+_zip_write2(unsigned short i, FILE *fp)
+{
+ putc(i&0xff, fp);
+ putc((i>>8)&0xff, fp);
+
+ return;
+}
+
+\f
+
+static void
+_zip_write4(unsigned int i, FILE *fp)
+{
+ putc(i&0xff, fp);
+ putc((i>>8)&0xff, fp);
+ putc((i>>16)&0xff, fp);
+ putc((i>>24)&0xff, fp);
+
+ return;
+}
+
+\f
+
+static void
+_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate)
+{
+ struct tm *tm, tmbuf;
+
+ tm = php_localtime_r(&time, &tmbuf);
+ *ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5)
+ + tm->tm_mday;
+ *dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5)
+ + ((tm->tm_sec)>>1);
+
+ return;
+}
--- /dev/null
+/*
+ $NiH: zip_entry_free.c,v 1.2 2006/04/09 19:05:47 wiz Exp $
+
+ zip_entry_free.c -- free struct zip_entry
+ Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+_zip_entry_free(struct zip_entry *ze)
+{
+ free(ze->ch_filename);
+ ze->ch_filename = NULL;
+ free(ze->ch_comment);
+ ze->ch_comment = NULL;
+ ze->ch_comment_len = -1;
+
+ _zip_unchange_data(ze);
+}
--- /dev/null
+/*
+ $NiH: zip_entry_new.c,v 1.2 2006/04/09 19:05:47 wiz Exp $
+
+ zip_entry_new.c -- create and init struct zip_entry
+ Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+struct zip_entry *
+_zip_entry_new(struct zip *za)
+{
+ struct zip_entry *ze;
+ if (!za) {
+ ze = (struct zip_entry *)malloc(sizeof(struct zip_entry));
+ if (!ze) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+ }
+ else {
+ if (za->nentry >= za->nentry_alloc-1) {
+ za->nentry_alloc += 16;
+ za->entry = (struct zip_entry *)realloc(za->entry,
+ sizeof(struct zip_entry)
+ * za->nentry_alloc);
+ if (!za->entry) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+ }
+ ze = za->entry+za->nentry;
+ }
+
+ ze->state = ZIP_ST_UNCHANGED;
+
+ ze->ch_filename = NULL;
+ ze->ch_comment = NULL;
+ ze->ch_comment_len = -1;
+ ze->source = NULL;
+
+ if (za)
+ za->nentry++;
+
+ return ze;
+}
--- /dev/null
+/*
+ This file was generated automatically by ./make_zip_err_str.sh
+ from ./zip.h; make changes there.
+
+ NiH: make_zip_err_str.sh,v 1.8 2004/11/17 21:55:09 wiz Exp
+ NiH: zip.h,v 1.57 2006/04/24 14:04:19 dillo Exp
+ */
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char * const _zip_err_str[] = {
+ "No error",
+ "Multi-disk zip archives not supported",
+ "Renaming temporary file failed",
+ "Closing zip archive failed",
+ "Seek error",
+ "Read error",
+ "Write error",
+ "CRC error",
+ "Containing zip archive was closed",
+ "No such file",
+ "File already exists",
+ "Can't open file",
+ "Failure to create temporary file",
+ "Zlib error",
+ "Malloc failure",
+ "Entry has been changed",
+ "Compression method not supported",
+ "Premature EOF",
+ "Invalid argument",
+ "Not a zip archive",
+ "Internal error",
+ "Zip archive inconsistent",
+ "Can't remove file",
+ "Entry has been deleted",
+};
+
+const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
+
+#define N ZIP_ET_NONE
+#define S ZIP_ET_SYS
+#define Z ZIP_ET_ZLIB
+
+const int _zip_err_type[] = {
+ N,
+ N,
+ S,
+ S,
+ S,
+ S,
+ S,
+ N,
+ N,
+ N,
+ N,
+ S,
+ S,
+ Z,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ S,
+ N,
+};
--- /dev/null
+/*
+ $NiH: zip_error.c,v 1.7 2005/06/09 19:57:09 dillo Exp $
+
+ zip_error.c -- struct zip_error helper functions
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+_zip_error_clear(struct zip_error *err)
+{
+ err->zip_err = ZIP_ER_OK;
+ err->sys_err = 0;
+}
+
+\f
+
+void
+_zip_error_copy(struct zip_error *dst, struct zip_error *src)
+{
+ dst->zip_err = src->zip_err;
+ dst->sys_err = src->sys_err;
+}
+
+\f
+
+void
+_zip_error_fini(struct zip_error *err)
+{
+ free(err->str);
+ err->str = NULL;
+}
+
+\f
+
+void
+_zip_error_get(struct zip_error *err, int *zep, int *sep)
+{
+ if (zep)
+ *zep = err->zip_err;
+ if (sep) {
+ if (zip_error_get_sys_type(err->zip_err) != ZIP_ET_NONE)
+ *sep = err->sys_err;
+ else
+ *sep = 0;
+ }
+}
+
+\f
+
+void
+_zip_error_init(struct zip_error *err)
+{
+ err->zip_err = ZIP_ER_OK;
+ err->sys_err = 0;
+ err->str = NULL;
+}
+
+\f
+
+void
+_zip_error_set(struct zip_error *err, int ze, int se)
+{
+ if (err) {
+ err->zip_err = ze;
+ err->sys_err = se;
+ }
+}
--- /dev/null
+/*
+ $NiH: zip_error_clear.c,v 1.1 2006/10/04 15:21:09 dillo Exp $
+
+ zip_error_clear.c -- clear zip error
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+zip_error_clear(struct zip *za)
+{
+ _zip_error_clear(&za->error);
+}
--- /dev/null
+/*
+ $NiH: zip_error_get.c,v 1.1 2004/11/18 15:06:20 wiz Exp $
+
+ zip_error_get.c -- get zip error
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+zip_error_get(struct zip *za, int *zep, int *sep)
+{
+ _zip_error_get(&za->error, zep, sep);
+}
--- /dev/null
+/*
+ $NiH: zip_error_get_sys_type.c,v 1.1 2004/12/22 15:49:18 wiz Exp $
+
+ zip_error_get_sys_type.c -- return type of system error code
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_error_get_sys_type(int ze)
+{
+ if (ze < 0 || ze >= _zip_nerr_str)
+ return 0;
+
+ return _zip_err_type[ze];
+}
--- /dev/null
+/*
+ $NiH: zip_error_strerror.c,v 1.4 2006/02/21 09:41:00 dillo Exp $
+
+ zip_error_sterror.c -- get string representation of struct zip_error
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char *
+_zip_error_strerror(struct zip_error *err)
+{
+ const char *zs, *ss;
+ char buf[128], *s;
+
+ _zip_error_fini(err);
+
+ if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) {
+ snprintf(buf, sizeof(buf), "Unknown error %d", err->zip_err);
+ zs = NULL;
+ ss = buf;
+ }
+ else {
+ zs = _zip_err_str[err->zip_err];
+
+ switch (_zip_err_type[err->zip_err]) {
+ case ZIP_ET_SYS:
+ ss = strerror(err->sys_err);
+ break;
+
+ case ZIP_ET_ZLIB:
+ ss = zError(err->sys_err);
+ break;
+
+ default:
+ ss = NULL;
+ }
+ }
+
+ if (ss == NULL)
+ return zs;
+ else {
+ int l = strlen(ss) + (zs ? strlen(zs)+2 : 0) + 1;
+ if ((s=(char *)malloc(l)) == NULL)
+ return _zip_err_str[ZIP_ER_MEMORY];
+
+ snprintf(s, l, "%s%s%s",
+ (zs ? zs : ""),
+ (zs ? ": " : ""),
+ ss);
+ err->str = s;
+
+ return ss;
+ }
+}
--- /dev/null
+/*
+ $NiH: zip_error_to_str.c,v 1.1 2004/11/18 15:06:20 wiz Exp $
+
+ zip_error_to_str.c -- get string representation of zip error code
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_error_to_str(char *buf, size_t len, int ze, int se)
+{
+ const char *zs, *ss;
+
+ if (ze < 0 || ze >= _zip_nerr_str)
+ return snprintf(buf, len, "Unknown error %d", ze);
+
+ zs = _zip_err_str[ze];
+
+ switch (_zip_err_type[ze]) {
+ case ZIP_ET_SYS:
+ ss = strerror(se);
+ break;
+
+ case ZIP_ET_ZLIB:
+ ss = zError(se);
+ break;
+
+ default:
+ ss = NULL;
+ }
+
+ return snprintf(buf, len, "%s%s%s",
+ zs, (ss ? ": " : ""), (ss ? ss : ""));
+}
--- /dev/null
+/*
+ $NiH: zip_fclose.c,v 1.14 2005/06/09 19:57:09 dillo Exp $
+
+ zip_fclose.c -- close file in zip archive
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_fclose(struct zip_file *zf)
+{
+ int i, ret;
+
+ if (zf->zstr)
+ inflateEnd(zf->zstr);
+ free(zf->buffer);
+ free(zf->zstr);
+
+ if (zf->za) {
+ for (i=0; i<zf->za->nfile; i++) {
+ if (zf->za->file[i] == zf) {
+ zf->za->file[i] = zf->za->file[zf->za->nfile-1];
+ zf->za->nfile--;
+ break;
+ }
+ }
+ }
+
+ ret = 0;
+ if (zf->error.zip_err)
+ ret = zf->error.zip_err;
+ else if ((zf->flags & ZIP_ZF_CRC) && (zf->flags & ZIP_ZF_EOF)) {
+ /* if EOF, compare CRC */
+ if (zf->crc_orig != zf->crc)
+ ret = ZIP_ER_CRC;
+ }
+
+ free(zf);
+ return ret;
+}
--- /dev/null
+/*
+ $NiH: zip_file_error_clear.c,v 1.4 2006/10/04 18:37:54 wiz Exp $
+
+ zip_file_error_clear.c -- clear zip file error
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+zip_file_error_clear(struct zip_file *zf)
+{
+ _zip_error_clear(&zf->error);
+}
--- /dev/null
+/*
+ $NiH: zip_file_error_get.c,v 1.1 2004/11/18 15:06:21 wiz Exp $
+
+ zip_file_error_get.c -- get zip file error
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+zip_file_error_get(struct zip_file *zf, int *zep, int *sep)
+{
+ _zip_error_get(&zf->error, zep, sep);
+}
--- /dev/null
+/*
+ $NiH: zip_file_get_offset.c,v 1.4 2006/04/23 14:51:45 wiz Exp $
+
+ zip_file_get_offset.c -- get offset of file data in archive.
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+/* _zip_file_get_offset(za, ze):
+ Returns the offset of the file data for entry ze.
+
+ On error, fills in za->error and returns 0.
+*/
+
+unsigned int
+_zip_file_get_offset(struct zip *za, int idx)
+{
+ struct zip_dirent de;
+ unsigned int offset;
+
+ offset = za->cdir->entry[idx].offset;
+
+ if (fseek(za->zp, offset, SEEK_SET) != 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return 0;
+ }
+
+ if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0)
+ return 0;
+
+ offset += LENTRYSIZE + de.filename_len + de.extrafield_len;
+
+ _zip_dirent_finalize(&de);
+
+ return offset;
+}
--- /dev/null
+/*
+ $NiH: zip_file_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $
+
+ zip_file_sterror.c -- get string representation of zip file error
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char *
+zip_file_strerror(struct zip_file *zf)
+{
+ return _zip_error_strerror(&zf->error);
+}
--- /dev/null
+/*
+ $NiH: zip_fopen.c,v 1.12 2005/06/09 19:57:09 dillo Exp $
+
+ zip_fopen.c -- open file in zip archive for reading
+ Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+struct zip_file *
+zip_fopen(struct zip *za, const char *fname, int flags)
+{
+ int idx;
+
+ if ((idx=zip_name_locate(za, fname, flags)) < 0)
+ return NULL;
+
+ return zip_fopen_index(za, idx, flags);
+}
--- /dev/null
+/*
+ $NiH: zip_fopen_index.c,v 1.24 2005/05/20 21:54:53 wiz Exp $
+
+ zip_fopen_index.c -- open file in zip archive for reading by index
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+static struct zip_file *_zip_file_new(struct zip *za);
+
+\f
+
+struct zip_file *
+zip_fopen_index(struct zip *za, int fileno, int flags)
+{
+ int len, ret;
+ int zfflags;
+ struct zip_file *zf;
+
+ if ((fileno < 0) || (fileno >= za->nentry)) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED) == 0
+ && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
+ _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+ return NULL;
+ }
+
+ if (fileno >= za->cdir->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ zfflags = 0;
+ switch (za->cdir->entry[fileno].comp_method) {
+ case ZIP_CM_STORE:
+ zfflags |= ZIP_ZF_CRC;
+ break;
+
+ case ZIP_CM_DEFLATE:
+ if ((flags & ZIP_FL_COMPRESSED) == 0)
+ zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP;
+ break;
+ default:
+ if ((flags & ZIP_FL_COMPRESSED) == 0) {
+ _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+ return NULL;
+ }
+ break;
+ }
+
+ zf = _zip_file_new(za);
+
+ zf->flags = zfflags;
+ /* zf->name = za->cdir->entry[fileno].filename; */
+ zf->method = za->cdir->entry[fileno].comp_method;
+ zf->bytes_left = za->cdir->entry[fileno].uncomp_size;
+ zf->cbytes_left = za->cdir->entry[fileno].comp_size;
+ zf->crc_orig = za->cdir->entry[fileno].crc;
+
+ if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) {
+ zip_fclose(zf);
+ return NULL;
+ }
+
+ if ((zf->flags & ZIP_ZF_DECOMP) == 0)
+ zf->bytes_left = zf->cbytes_left;
+ else {
+ if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ zip_fclose(zf);
+ return NULL;
+ }
+
+ len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
+ if (len <= 0) {
+ _zip_error_copy(&za->error, &zf->error);
+ zip_fclose(zf);
+ return NULL;
+ }
+
+ if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ zip_fclose(zf);
+ return NULL;
+ }
+ zf->zstr->zalloc = Z_NULL;
+ zf->zstr->zfree = Z_NULL;
+ zf->zstr->opaque = NULL;
+ zf->zstr->next_in = (Bytef *)zf->buffer;
+ zf->zstr->avail_in = len;
+
+ /* negative value to tell zlib that there is no header */
+ if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) {
+ _zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
+ zip_fclose(zf);
+ return NULL;
+ }
+ }
+
+ return zf;
+}
+
+\f
+
+int
+_zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf)
+{
+ int i, j;
+
+ if (zf->error.zip_err != ZIP_ER_OK)
+ return -1;
+
+ if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0)
+ return 0;
+
+ if (fseek(zf->za->zp, zf->fpos, SEEK_SET) < 0) {
+ _zip_error_set(&zf->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+ if (buflen < zf->cbytes_left)
+ i = buflen;
+ else
+ i = zf->cbytes_left;
+
+ j = fread(buf, 1, i, zf->za->zp);
+ if (j == 0) {
+ _zip_error_set(&zf->error, ZIP_ER_EOF, 0);
+ j = -1;
+ }
+ else if (j < 0)
+ _zip_error_set(&zf->error, ZIP_ER_READ, errno);
+ else {
+ zf->fpos += j;
+ zf->cbytes_left -= j;
+ }
+
+ return j;
+}
+
+\f
+
+static struct zip_file *
+_zip_file_new(struct zip *za)
+{
+ struct zip_file *zf, **file;
+ int n;
+
+ if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if (za->nfile >= za->nfile_alloc-1) {
+ n = za->nfile_alloc + 10;
+ file = (struct zip_file **)realloc(za->file,
+ n*sizeof(struct zip_file *));
+ if (file == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ free(zf);
+ return NULL;
+ }
+ za->nfile_alloc = n;
+ za->file = file;
+ }
+
+ za->file[za->nfile++] = zf;
+
+ zf->za = za;
+ _zip_error_init(&zf->error);
+ zf->flags = 0;
+ zf->crc = crc32(0L, Z_NULL, 0);
+ zf->crc_orig = 0;
+ zf->method = -1;
+ zf->bytes_left = zf->cbytes_left = 0;
+ zf->fpos = 0;
+ zf->buffer = NULL;
+ zf->zstr = NULL;
+
+ return zf;
+}
--- /dev/null
+/*
+ $NiH: zip_fread.c,v 1.21 2006/04/23 14:49:50 wiz Exp $
+
+ zip_fread.c -- read from file
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+ssize_t
+zip_fread(struct zip_file *zf, void *outbuf, size_t toread)
+{
+ int ret;
+ size_t out_before, len;
+ int i;
+
+ if (!zf)
+ return -1;
+
+ if (zf->error.zip_err != 0)
+ return -1;
+
+ if ((zf->flags & ZIP_ZF_EOF) || (toread == 0))
+ return 0;
+
+ if (zf->bytes_left == 0) {
+ zf->flags |= ZIP_ZF_EOF;
+ if (zf->flags & ZIP_ZF_CRC) {
+ if (zf->crc != zf->crc_orig) {
+ _zip_error_set(&zf->error, ZIP_ER_CRC, 0);
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ if ((zf->flags & ZIP_ZF_DECOMP) == 0) {
+ ret = _zip_file_fillbuf(outbuf, toread, zf);
+ if (ret > 0) {
+ if (zf->flags & ZIP_ZF_CRC)
+ zf->crc = crc32(zf->crc, (Bytef *)outbuf, ret);
+ zf->bytes_left -= ret;
+ }
+ return ret;
+ }
+
+ zf->zstr->next_out = (Bytef *)outbuf;
+ zf->zstr->avail_out = toread;
+ out_before = zf->zstr->total_out;
+
+ /* endless loop until something has been accomplished */
+ for (;;) {
+ ret = inflate(zf->zstr, Z_SYNC_FLUSH);
+
+ switch (ret) {
+ case Z_OK:
+ case Z_STREAM_END:
+ /* all ok */
+ /* Z_STREAM_END probably won't happen, since we didn't
+ have a header */
+ len = zf->zstr->total_out - out_before;
+ if (len >= zf->bytes_left || len >= toread) {
+ if (zf->flags & ZIP_ZF_CRC)
+ zf->crc = crc32(zf->crc, (Bytef *)outbuf, len);
+ zf->bytes_left -= len;
+ return len;
+ }
+ break;
+
+ case Z_BUF_ERROR:
+ if (zf->zstr->avail_in == 0) {
+ i = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
+ if (i == 0) {
+ _zip_error_set(&zf->error, ZIP_ER_INCONS, 0);
+ return -1;
+ }
+ else if (i < 0)
+ return -1;
+ zf->zstr->next_in = (Bytef *)zf->buffer;
+ zf->zstr->avail_in = i;
+ continue;
+ }
+ /* fallthrough */
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_STREAM_ERROR:
+ case Z_MEM_ERROR:
+ _zip_error_set(&zf->error, ZIP_ER_ZLIB, ret);
+ return -1;
+ }
+ }
+}
--- /dev/null
+/*
+ $NiH: zip_free.c,v 1.17 2005/06/09 19:57:10 dillo Exp $
+
+ zip_free.c -- free struct zip
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+/* _zip_free:
+ frees the space allocated to a zipfile struct, and closes the
+ corresponding file. */
+
+void
+_zip_free(struct zip *za)
+{
+ int i;
+
+ if (za == NULL)
+ return;
+
+ if (za->zn)
+ free(za->zn);
+
+ if (za->zp)
+ fclose(za->zp);
+
+ if (za->ch_comment)
+ free(za->ch_comment);
+
+ _zip_cdir_free(za->cdir);
+
+ if (za->entry) {
+ for (i=0; i<za->nentry; i++) {
+ _zip_entry_free(za->entry+i);
+ }
+ free(za->entry);
+ }
+
+ for (i=0; i<za->nfile; i++) {
+ if (za->file[i]->error.zip_err == ZIP_ER_OK) {
+ _zip_error_set(&za->file[i]->error, ZIP_ER_ZIPCLOSED, 0);
+ za->file[i]->za = NULL;
+ }
+ }
+
+ free(za->file);
+
+ free(za);
+
+ return;
+}
--- /dev/null
+/*
+ $NiH: zip_get_archive_comment.c,v 1.4 2006/04/23 16:11:33 wiz Exp $
+
+ zip_get_archive_comment.c -- get archive comment
+ Copyright (C) 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char *
+zip_get_archive_comment(struct zip *za, int *lenp, int flags)
+{
+ if ((flags & ZIP_FL_UNCHANGED)
+ || (za->ch_comment_len == -1)) {
+ if (za->cdir) {
+ if (lenp != NULL)
+ *lenp = za->cdir->comment_len;
+ return za->cdir->comment;
+ }
+ }
+
+ if (lenp != NULL)
+ *lenp = za->ch_comment_len;
+ return za->ch_comment;
+}
--- /dev/null
+/*
+ $NiH: zip_get_file_comment.c,v 1.2 2006/04/23 13:06:28 wiz Exp $
+
+ zip_get_file_comment.c -- get file comment
+ Copyright (C) 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char *
+zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags)
+{
+ if (idx < 0 || idx >= za->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED)
+ || (za->entry[idx].ch_comment_len == -1)) {
+ if (lenp != NULL)
+ *lenp = za->cdir->entry[idx].comment_len;
+ return za->cdir->entry[idx].comment;
+ }
+
+ if (lenp != NULL)
+ *lenp = za->entry[idx].ch_comment_len;
+ return za->entry[idx].ch_comment;
+}
--- /dev/null
+/*
+ $NiH: zip_get_name.c,v 1.13 2005/01/20 21:00:54 dillo Exp $
+
+ zip_get_name.c -- get filename for a file in zip file
+ Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char *
+zip_get_name(struct zip *za, int idx, int flags)
+{
+ return _zip_get_name(za, idx, flags, &za->error);
+}
+
+\f
+
+const char *
+_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error)
+{
+ if (idx < 0 || idx >= za->nentry) {
+ _zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED) == 0) {
+ if (za->entry[idx].state == ZIP_ST_DELETED) {
+ _zip_error_set(error, ZIP_ER_DELETED, 0);
+ return NULL;
+ }
+ if (za->entry[idx].ch_filename)
+ return za->entry[idx].ch_filename;
+ }
+
+ if (za->cdir == NULL || idx >= za->cdir->nentry) {
+ _zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return za->cdir->entry[idx].filename;
+}
--- /dev/null
+/*
+ $NiH: zip_get_num_files.c,v 1.2 2003/12/27 22:53:15 wiz Exp $
+
+ zip_get_num_files.c -- get number of files in archive
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_get_num_files(struct zip *za)
+{
+ if (za == NULL)
+ return -1;
+
+ return za->nentry;
+}
--- /dev/null
+/*
+ $NiH: zip_memdup.c,v 1.2 2006/04/24 10:34:39 dillo Exp $
+
+ zip_memdup.c -- internal zip function, "strdup" with len
+ Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void *
+_zip_memdup(const void *mem, size_t len, struct zip_error *error)
+{
+ void *ret;
+
+ ret = malloc(len);
+ if (!ret) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ memcpy(ret, mem, len);
+
+ return ret;
+}
--- /dev/null
+/*
+ $NiH: zip_name_locate.c,v 1.19 2005/06/09 19:57:10 dillo Exp $
+
+ zip_name_locate.c -- get index by name
+ Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_name_locate(struct zip *za, const char *fname, int flags)
+{
+ return _zip_name_locate(za, fname, flags, &za->error);
+}
+
+\f
+
+int
+_zip_name_locate(struct zip *za, const char *fname, int flags,
+ struct zip_error *error)
+{
+ int (*cmp)(const char *, const char *);
+ const char *fn, *p;
+ int i, n;
+
+ if (fname == NULL) {
+ _zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
+
+ n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry;
+ for (i=0; i<n; i++) {
+ if (flags & ZIP_FL_UNCHANGED)
+ fn = za->cdir->entry[i].filename;
+ else
+ fn = _zip_get_name(za, i, flags, error);
+
+ /* newly added (partially filled) entry */
+ if (fn == NULL)
+ continue;
+
+ if (flags & ZIP_FL_NODIR) {
+ p = strrchr(fn, '/');
+ if (p)
+ fn = p+1;
+ }
+
+ if (cmp(fname, fn) == 0)
+ return i;
+ }
+
+ _zip_error_set(error, ZIP_ER_NOENT, 0);
+ return -1;
+}
--- /dev/null
+/*
+ $NiH: zip_new.c,v 1.12 2006/04/23 00:40:47 wiz Exp $
+
+ zip_new.c -- create and init struct zip
+ Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+/* _zip_new:
+ creates a new zipfile struct, and sets the contents to zero; returns
+ the new struct. */
+
+struct zip *
+_zip_new(struct zip_error *error)
+{
+ struct zip *za;
+
+ za = (struct zip *)malloc(sizeof(struct zip));
+ if (!za) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ za->zn = NULL;
+ za->zp = NULL;
+ _zip_error_init(&za->error);
+ za->cdir = NULL;
+ za->ch_comment = NULL;
+ za->ch_comment_len = -1;
+ za->nentry = za->nentry_alloc = 0;
+ za->entry = NULL;
+ za->nfile = za->nfile_alloc = 0;
+ za->file = NULL;
+
+ return za;
+}
--- /dev/null
+/*
+ $NiH: zip_open.c,v 1.38 2006/05/04 00:01:26 dillo Exp $
+
+ zip_open.c -- open zip archive
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include "zip.h"
+#include "zipint.h"
+
+static void set_error(int *, struct zip_error *, int);
+static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *);
+static int _zip_headercomp(struct zip_dirent *, int,
+ struct zip_dirent *, int);
+static unsigned char *_zip_memmem(const unsigned char *, int,
+ const unsigned char *, int);
+static struct zip_cdir *_zip_readcdir(FILE *, unsigned char *, unsigned char *,
+ int, int, struct zip_error *);
+
+\f
+
+struct zip *
+zip_open(const char *fn, int flags, int *zep)
+{
+ FILE *fp;
+ unsigned char *buf, *match;
+ int a, i, buflen, best;
+ struct zip *za;
+ struct zip_cdir *cdir, *cdirnew;
+ long len;
+ struct stat st;
+ struct zip_error error, err2;
+
+ if (fn == NULL) {
+ set_error(zep, NULL, ZIP_ER_INVAL);
+ return NULL;
+ }
+
+ if (flags & ZIP_OVERWRITE || stat(fn, &st) != 0) {
+ if ((flags & ZIP_CREATE) || (flags & ZIP_OVERWRITE)) {
+ if ((za=_zip_new(&error)) == NULL) {
+ set_error(zep, &error, 0);
+ return NULL;
+ }
+
+ za->zn = strdup(fn);
+ if (!za->zn) {
+ _zip_free(za);
+ set_error(zep, NULL, ZIP_ER_MEMORY);
+ return NULL;
+ }
+ return za;
+ }
+ else {
+ set_error(zep, NULL, ZIP_ER_OPEN);
+ return NULL;
+ }
+ }
+ else if ((flags & ZIP_EXCL)) {
+ set_error(zep, NULL, ZIP_ER_EXISTS);
+ return NULL;
+ }
+
+ /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL,
+ just like open() */
+ if ((fp=fopen(fn, "rb")) == NULL) {
+ set_error(zep, NULL, ZIP_ER_OPEN);
+ return NULL;
+ }
+
+#ifdef PHP_WIN32
+ _setmode(_fileno(fp), _O_BINARY );
+#endif
+
+ clearerr(fp);
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ i = fseek(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END);
+ if (i == -1 && errno != EFBIG) {
+ /* seek before start of file on my machine */
+ set_error(zep, NULL, ZIP_ER_SEEK);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* 64k is too much for stack */
+ if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) {
+ set_error(zep, NULL, ZIP_ER_MEMORY);
+ fclose(fp);
+ return NULL;
+ }
+
+ clearerr(fp);
+ buflen = fread(buf, 1, CDBUFSIZE, fp);
+
+ if (ferror(fp)) {
+ set_error(zep, NULL, ZIP_ER_READ);
+ free(buf);
+ fclose(fp);
+ return NULL;
+ }
+
+ best = -2;
+ cdir = NULL;
+ match = buf;
+ while ((match=_zip_memmem(match, buflen-(match-buf)-18,
+ (const unsigned char *)EOCD_MAGIC, 4))!=NULL) {
+ /* found match -- check, if good */
+ /* to avoid finding the same match all over again */
+ match++;
+ if ((cdirnew=_zip_readcdir(fp, buf, match-1, buflen, flags,
+ &err2)) == NULL) {
+ if (best == -2) {
+ set_error(zep, &err2, 0);
+ best = -1;
+ }
+ continue;
+ }
+
+ if (cdir) {
+ if (best <= 0)
+ best = _zip_checkcons(fp, cdir, &err2);
+ a = _zip_checkcons(fp, cdirnew, &err2);
+ if (best < a) {
+ _zip_cdir_free(cdir);
+ cdir = cdirnew;
+ best = a;
+ }
+ else
+ _zip_cdir_free(cdirnew);
+ }
+ else {
+ cdir = cdirnew;
+ if (flags & ZIP_CHECKCONS)
+ best = _zip_checkcons(fp, cdir, &err2);
+ else
+ best = 0;
+ }
+ cdirnew = NULL;
+ }
+
+ free(buf);
+
+ if (best < 0) {
+ /* no consistent eocd found */
+ if (best == -2) {
+ /* no eocd found at all */
+ set_error(zep, NULL, ZIP_ER_NOZIP);
+ }
+ _zip_cdir_free(cdir);
+ fclose(fp);
+ return NULL;
+ }
+
+ if ((za=_zip_new(&error)) == NULL) {
+ set_error(zep, &error, 0);
+ _zip_cdir_free(cdir);
+ fclose(fp);
+ return NULL;
+ }
+
+ za->zp = fp;
+ za->cdir = cdir;
+
+ if ((za->zn=strdup(fn)) == NULL) {
+ set_error(zep, NULL, ZIP_ER_MEMORY);
+ _zip_free(za);
+ return NULL;
+ }
+
+ if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry))
+ * cdir->nentry)) == NULL) {
+ set_error(zep, NULL, ZIP_ER_MEMORY);
+ _zip_free(za);
+ return NULL;
+ }
+ for (i=0; i<cdir->nentry; i++)
+ _zip_entry_new(za);
+
+ return za;
+}
+
+\f
+
+static void
+set_error(int *zep, struct zip_error *err, int ze)
+{
+ int se;
+
+ if (err) {
+ _zip_error_get(err, &ze, &se);
+ if (zip_error_get_sys_type(ze) == ZIP_ET_SYS)
+ errno = se;
+ }
+
+ if (zep)
+ *zep = ze;
+}
+
+\f
+
+/* _zip_readcdir:
+ tries to find a valid end-of-central-directory at the beginning of
+ buf, and then the corresponding central directory entries.
+ Returns a struct zip_cdir which contains the central directory
+ entries, or NULL if unsuccessful. */
+
+static struct zip_cdir *
+_zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
+ int flags, struct zip_error *error)
+{
+ struct zip_cdir *cd;
+ unsigned char *cdp, **bufp;
+ int i, comlen, nentry;
+
+ comlen = buf + buflen - eocd - EOCDLEN;
+ if (comlen < 0) {
+ /* not enough bytes left for comment */
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return NULL;
+ }
+
+ /* check for end-of-central-dir magic */
+ if (memcmp(eocd, EOCD_MAGIC, 4) != 0) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return NULL;
+ }
+
+ if (memcmp(eocd+4, "\0\0\0\0", 4) != 0) {
+ _zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ return NULL;
+ }
+
+ cdp = eocd + 8;
+ /* number of cdir-entries on this disk */
+ i = _zip_read2(&cdp);
+ /* number of cdir-entries */
+ nentry = _zip_read2(&cdp);
+
+ if ((cd=_zip_cdir_new(nentry, error)) == NULL)
+ return NULL;
+
+ cd->size = _zip_read4(&cdp);
+ cd->offset = _zip_read4(&cdp);
+ cd->comment = NULL;
+ cd->comment_len = _zip_read2(&cdp);
+
+ if ((comlen < cd->comment_len) || (cd->nentry != i)) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ free(cd);
+ return NULL;
+ }
+ if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) {
+ _zip_error_set(error, ZIP_ER_INCONS, 0);
+ free(cd);
+ return NULL;
+ }
+
+ if (cd->comment_len)
+ if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN,
+ cd->comment_len, error))
+ == NULL) {
+ free(cd);
+ return NULL;
+ }
+
+ cdp = eocd;
+ if (cd->size < (unsigned int)(eocd-buf)) {
+ /* if buffer already read in, use it */
+ cdp = eocd - cd->size;
+ bufp = &cdp;
+ }
+ else {
+ /* go to start of cdir and read it entry by entry */
+ bufp = NULL;
+ clearerr(fp);
+ fseek(fp, -(cd->size+cd->comment_len+EOCDLEN), SEEK_END);
+ if (ferror(fp) || ((unsigned int)ftell(fp) != cd->offset)) {
+ /* seek error or offset of cdir wrong */
+ if (ferror(fp))
+ _zip_error_set(error, ZIP_ER_SEEK, errno);
+ else
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ free(cd);
+ return NULL;
+ }
+ }
+
+ for (i=0; i<cd->nentry; i++) {
+ if ((_zip_dirent_read(cd->entry+i, fp, bufp, eocd-cdp, 0,
+ error)) < 0) {
+ cd->nentry = i;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ }
+
+ return cd;
+}
+
+\f
+
+/* _zip_checkcons:
+ Checks the consistency of the central directory by comparing central
+ directory entries with local headers and checking for plausible
+ file and header offsets. Returns -1 if not plausible, else the
+ difference between the lowest and the highest fileposition reached */
+
+static int
+_zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error)
+{
+ int i;
+ unsigned int min, max, j;
+ struct zip_dirent temp;
+
+ if (cd->nentry) {
+ max = cd->entry[0].offset;
+ min = cd->entry[0].offset;
+ }
+ else
+ min = max = 0;
+
+ for (i=0; i<cd->nentry; i++) {
+ if (cd->entry[i].offset < min)
+ min = cd->entry[i].offset;
+ if (min > cd->offset) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+
+ j = cd->entry[i].offset + cd->entry[i].comp_size
+ + cd->entry[i].filename_len + LENTRYSIZE;
+ if (j > max)
+ max = j;
+ if (max > cd->offset) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+
+ if (fseek(fp, cd->entry[i].offset, SEEK_SET) != 0) {
+ _zip_error_set(error, ZIP_ER_SEEK, 0);
+ return -1;
+ }
+
+ if (_zip_dirent_read(&temp, fp, NULL, 0, 1, error) == -1)
+ return -1;
+
+ if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ _zip_dirent_finalize(&temp);
+ return -1;
+ }
+ _zip_dirent_finalize(&temp);
+ }
+
+ return max - min;
+}
+
+\f
+
+/* _zip_headercomp:
+ compares two headers h1 and h2; if they are local headers, set
+ local1p or local2p respectively to 1, else 0. Return 0 if they
+ are identical, -1 if not. */
+
+static int
+_zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2,
+ int local2p)
+{
+ if ((h1->version_needed != h2->version_needed)
+#if 0
+ /* some zip-files have different values in local
+ and global headers for the bitflags */
+ || (h1->bitflags != h2->bitflags)
+#endif
+ || (h1->comp_method != h2->comp_method)
+ || (h1->last_mod != h2->last_mod)
+ || (h1->crc != h2->crc)
+ || (h1->comp_size != h2->comp_size)
+ || (h1->uncomp_size != h2->uncomp_size)
+ || (h1->filename_len != h2->filename_len)
+ || !h1->filename || !h2->filename
+ || strcmp(h1->filename, h2->filename))
+ return -1;
+
+ if ((local1p == local2p)
+ && ((h1->extrafield_len != h2->extrafield_len)
+ || (h1->extrafield_len && h2->extrafield
+ && memcmp(h1->extrafield, h2->extrafield,
+ h1->extrafield_len))))
+ return -1;
+
+ /* if either is local, nothing more to check */
+ if (local1p || local2p)
+ return 0;
+
+ if ((h1->version_madeby != h2->version_madeby)
+ || (h1->disk_number != h2->disk_number)
+ || (h1->int_attrib != h2->int_attrib)
+ || (h1->ext_attrib != h2->ext_attrib)
+ || (h1->offset != h2->offset)
+ || (h1->comment_len != h2->comment_len)
+ || (h1->comment_len && h2->comment
+ && memcmp(h1->comment, h2->comment, h1->comment_len)))
+ return -1;
+
+ return 0;
+}
+
+\f
+
+static unsigned char *
+_zip_memmem(const unsigned char *big, int biglen, const unsigned char *little,
+ int littlelen)
+{
+ const unsigned char *p;
+
+ if ((biglen < littlelen) || (littlelen == 0))
+ return NULL;
+ p = big-1;
+ while ((p=(const unsigned char *)
+ memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1)))
+ != NULL) {
+ if (memcmp(p+1, little+1, littlelen-1)==0)
+ return (unsigned char *)p;
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ $NiH: zip_rename.c,v 1.15 2004/11/30 22:19:38 wiz Exp $
+
+ zip_rename.c -- rename file in zip archive
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_rename(struct zip *za, int idx, const char *name)
+{
+ if (idx >= za->nentry || idx < 0) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ return _zip_set_name(za, idx, name);
+}
--- /dev/null
+/*
+ $NiH: zip_replace.c,v 1.20 2006/04/09 14:52:02 wiz Exp $
+
+ zip_replace.c -- replace file via callback function
+ Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_replace(struct zip *za, int idx, struct zip_source *source)
+{
+ if (idx < 0 || idx >= za->nentry || source == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (_zip_replace(za, idx, NULL, source) == -1)
+ return -1;
+
+ return 0;
+}
+
+
+\f
+
+int
+_zip_replace(struct zip *za, int idx, const char *name,
+ struct zip_source *source)
+{
+ if (idx == -1) {
+ if (_zip_entry_new(za) == NULL)
+ return -1;
+ idx = za->nentry - 1;
+ }
+
+
+ _zip_unchange_data(za->entry+idx);
+
+ if (name && _zip_set_name(za, idx, name) != 0)
+ return -1;
+
+
+ za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry)
+ ? ZIP_ST_ADDED : ZIP_ST_REPLACED);
+ za->entry[idx].source = source;
+
+ return idx;
+}
--- /dev/null
+/*
+ $NiH: zip_set_archive_comment.c,v 1.3 2006/04/24 10:34:39 dillo Exp $
+
+ zip_set_archive_comment.c -- set archive comment
+ Copyright (C) 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_set_archive_comment(struct zip *za, const char *comment, int len)
+{
+ char *tmpcom;
+
+ if (len < 0 || len > MAXCOMLEN
+ || (len > 0 && comment == NULL)) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (len > 0) {
+ if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
+ return -1;
+ }
+ else
+ tmpcom = NULL;
+
+ if (za->ch_comment) free(za->ch_comment);
+ za->ch_comment = tmpcom;
+ za->ch_comment_len = len;
+
+ return 0;
+}
--- /dev/null
+/*
+ $NiH: zip_set_file_comment.c,v 1.4 2006/04/24 10:34:39 dillo Exp $
+
+ zip_set_file_comment.c -- set comment for file in archive
+ Copyright (C) 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_set_file_comment(struct zip *za, int idx, const char *comment, int len)
+{
+ char *tmpcom;
+
+ if (idx < 0 || idx >= za->nentry
+ || len < 0 || len > MAXCOMLEN
+ || (len > 0 && comment == NULL)) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (len > 0) {
+ if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
+ return -1;
+ }
+ else
+ tmpcom = NULL;
+
+ free(za->entry[idx].ch_comment);
+ za->entry[idx].ch_comment = tmpcom;
+ za->entry[idx].ch_comment_len = len;
+
+ return 0;
+}
--- /dev/null
+/*
+ $NiH: zip_set_name.c,v 1.16 2004/11/30 23:02:47 wiz Exp $
+
+ zip_set_name.c -- rename helper function
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+_zip_set_name(struct zip *za, int idx, const char *name)
+{
+ char *s;
+ int i;
+
+ if (idx < 0 || idx >= za->nentry || name == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) {
+ _zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ return -1;
+ }
+
+ /* no effective name change */
+ if (i == idx)
+ return 0;
+
+ if ((s=strdup(name)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ if (za->entry[idx].state == ZIP_ST_UNCHANGED)
+ za->entry[idx].state = ZIP_ST_RENAMED;
+
+ free(za->entry[idx].ch_filename);
+ za->entry[idx].ch_filename = s;
+
+ return 0;
+}
--- /dev/null
+/*
+ $NiH: zip_source_buffer.c,v 1.8 2006/04/23 14:50:49 wiz Exp $
+
+ zip_source_buffer.c -- create zip data source from buffer
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+struct read_data {
+ const char *buf, *data, *end;
+ time_t mtime;
+ int freep;
+};
+
+static ssize_t read_data(void *state, void *data, size_t len,
+ enum zip_source_cmd cmd);
+
+\f
+
+struct zip_source *
+zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
+{
+ struct read_data *f;
+ struct zip_source *zs;
+
+ if (za == NULL)
+ return NULL;
+
+ if (len < 0 || (data == NULL && len > 0)) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((f=(struct read_data *)malloc(sizeof(*f))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ f->data = (const char *)data;
+ f->end = ((const char *)data)+len;
+ f->freep = freep;
+ f->mtime = time(NULL);
+
+ if ((zs=zip_source_function(za, read_data, f)) == NULL) {
+ free(f);
+ return NULL;
+ }
+
+ return zs;
+}
+
+static ssize_t
+read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+{
+ struct read_data *z;
+ char *buf;
+ size_t n;
+
+ z = (struct read_data *)state;
+ buf = (char *)data;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ z->buf = z->data;
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ n = z->end - z->buf;
+ if (n > len)
+ n = len;
+ if (n < 0)
+ n = 0;
+
+ if (n) {
+ memcpy(buf, z->buf, n);
+ z->buf += n;
+ }
+
+ return n;
+
+ case ZIP_SOURCE_CLOSE:
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ struct zip_stat *st;
+
+ if (len < sizeof(*st))
+ return -1;
+
+ st = (struct zip_stat *)data;
+
+ zip_stat_init(st);
+ st->mtime = z->mtime;
+ st->size = z->end - z->data;
+
+ return sizeof(*st);
+ }
+
+ case ZIP_SOURCE_ERROR:
+ {
+ int *e;
+
+ if (len < sizeof(int)*2)
+ return -1;
+
+ e = (int *)data;
+ e[0] = e[1] = 0;
+ }
+ return sizeof(int)*2;
+
+ case ZIP_SOURCE_FREE:
+ if (z->freep) {
+ free((void *)z->data);
+ z->data = NULL;
+ }
+ free(z);
+ return 0;
+
+ default:
+ ;
+ }
+
+ return -1;
+}
--- /dev/null
+/*
+ $NiH: zip_source_file.c,v 1.2 2004/11/18 16:28:13 wiz Exp $
+
+ zip_source_file.c -- create data source from file
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+struct zip_source *
+zip_source_file(struct zip *za, const char *fname, off_t start, off_t len)
+{
+ struct zip_source *zs;
+ FILE *fp;
+
+ if (za == NULL)
+ return NULL;
+
+ if (fname == NULL || start < 0 || len < -1) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((fp=fopen(fname, "rb")) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_OPEN, errno);
+ return NULL;
+ }
+
+#ifdef PHP_WIN32
+ _setmode(_fileno(fp), _O_BINARY );
+#endif
+
+ if ((zs=zip_source_filep(za, fp, start, len)) == NULL) {
+ fclose(fp);
+ return NULL;
+ }
+
+ return zs;
+}
--- /dev/null
+/*
+ $NiH: zip_source_filep.c,v 1.6 2005/06/09 19:57:10 dillo Exp $
+
+ zip_source_filep.c -- create data source from FILE *
+ Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+struct read_file {
+ FILE *f; /* file to copy from */
+ off_t off; /* start offset of */
+ off_t len; /* lengt of data to copy */
+ off_t remain; /* bytes remaining to be copied */
+ int e[2]; /* error codes */
+};
+
+static ssize_t read_file(void *state, void *data, size_t len,
+ enum zip_source_cmd cmd);
+
+\f
+
+struct zip_source *
+zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
+{
+ struct read_file *f;
+ struct zip_source *zs;
+
+ if (za == NULL)
+ return NULL;
+
+ if (file == NULL || start < 0 || len < -1) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ f->f = file;
+ f->off = start;
+ f->len = (len ? len : -1);
+
+ if ((zs=zip_source_function(za, read_file, f)) == NULL) {
+ free(f);
+ return NULL;
+ }
+
+ return zs;
+}
+
+\f
+
+static ssize_t
+read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+{
+ struct read_file *z;
+ char *buf;
+ int i, n;
+
+ z = (struct read_file *)state;
+ buf = (char *)data;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ if (fseeko(z->f, z->off, SEEK_SET) < 0) {
+ z->e[0] = ZIP_ER_SEEK;
+ z->e[1] = errno;
+ return -1;
+ }
+ z->remain = z->len;
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ if (z->remain != -1)
+ n = len > z->remain ? z->remain : len;
+ else
+ n = len;
+
+ if ((i=fread(buf, 1, n, z->f)) < 0) {
+ z->e[0] = ZIP_ER_READ;
+ z->e[1] = errno;
+ return -1;
+ }
+
+ if (z->remain != -1)
+ z->remain -= i;
+
+ return i;
+
+ case ZIP_SOURCE_CLOSE:
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ struct zip_stat *st;
+ struct stat fst;
+
+ if (len < sizeof(*st))
+ return -1;
+
+ if (fstat(fileno(z->f), &fst) != 0) {
+ z->e[0] = ZIP_ER_READ; /* best match */
+ z->e[1] = errno;
+ return -1;
+ }
+
+ st = (struct zip_stat *)data;
+
+ zip_stat_init(st);
+ st->mtime = fst.st_mtime;
+ if (z->len != -1)
+ st->size = z->len;
+ else if ((fst.st_mode&S_IFMT) == S_IFREG)
+ st->size = fst.st_size;
+
+ return sizeof(*st);
+ }
+
+ case ZIP_SOURCE_ERROR:
+ if (len < sizeof(int)*2)
+ return -1;
+
+ memcpy(data, z->e, sizeof(int)*2);
+ return sizeof(int)*2;
+
+ case ZIP_SOURCE_FREE:
+ fclose(z->f);
+ free(z);
+ return 0;
+
+ default:
+ ;
+ }
+
+ return -1;
+}
--- /dev/null
+/*
+ $NiH: zip_source_free.c,v 1.2 2004/12/22 16:32:00 dillo Exp $
+
+ zip_source_free.c -- free zip data source
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+void
+zip_source_free(struct zip_source *source)
+{
+ if (source == NULL)
+ return;
+
+ (void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE);
+
+ free(source);
+}
--- /dev/null
+/*
+ $NiH: zip_source_function.c,v 1.4 2006/02/21 09:41:00 dillo Exp $
+
+ zip_source_function.c -- create zip data source from callback function
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+struct zip_source *
+zip_source_function(struct zip *za, zip_source_callback zcb, void *ud)
+{
+ struct zip_source *zs;
+
+ if (za == NULL)
+ return NULL;
+
+ if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ zs->f = zcb;
+ zs->ud = ud;
+
+ return zs;
+}
--- /dev/null
+/*
+ $NiH: zip_source_zip.c,v 1.7 2006/02/21 09:41:00 dillo Exp $
+
+ zip_source_zip.c -- create data source from zip file
+ Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zip.h"
+#include "zipint.h"
+
+struct read_zip {
+ struct zip_file *zf;
+ struct zip_stat st;
+ off_t off, len;
+};
+
+static ssize_t read_zip(void *st, void *data, size_t len,
+ enum zip_source_cmd cmd);
+
+\f
+
+struct zip_source *
+zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
+ off_t start, off_t len)
+{
+ struct zip_error error;
+ struct zip_source *zs;
+ struct read_zip *p;
+
+ if (za == NULL)
+ return NULL;
+
+ if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED) == 0
+ && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) {
+ _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+ return NULL;
+ }
+
+ if (len == 0)
+ len = -1;
+
+ if (start == 0 && len == -1)
+ flags |= ZIP_FL_COMPRESSED;
+ else
+ flags &= ~ZIP_FL_COMPRESSED;
+
+ if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ _zip_error_copy(&error, &srcza->error);
+
+ if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0
+ || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) {
+ free(p);
+ _zip_error_copy(&za->error, &srcza->error);
+ _zip_error_copy(&srcza->error, &error);
+
+ return NULL;
+ }
+ p->off = start;
+ p->len = len;
+
+ if ((flags & ZIP_FL_COMPRESSED) == 0) {
+ p->st.size = p->st.comp_size = len;
+ p->st.comp_method = ZIP_CM_STORE;
+ p->st.crc = 0;
+ }
+
+ if ((zs=zip_source_function(za, read_zip, p)) == NULL) {
+ free(p);
+ return NULL;
+ }
+
+ return zs;
+}
+
+\f
+
+static ssize_t
+read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+{
+ struct read_zip *z;
+ char b[8192], *buf;
+ int i, n;
+
+ z = (struct read_zip *)state;
+ buf = (char *)data;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ for (n=0; n<z->off; n+= i) {
+ i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n);
+ if ((i=zip_fread(z->zf, b, i)) < 0) {
+ zip_fclose(z->zf);
+ z->zf = NULL;
+ return -1;
+ }
+ }
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ if (z->len != -1)
+ n = len > z->len ? z->len : len;
+ else
+ n = len;
+
+
+ if ((i=zip_fread(z->zf, buf, n)) < 0)
+ return -1;
+
+ if (z->len != -1)
+ z->len -= i;
+
+ return i;
+
+ case ZIP_SOURCE_CLOSE:
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ if (len < sizeof(z->st))
+ return -1;
+ len = sizeof(z->st);
+
+ memcpy(data, &z->st, len);
+ return len;
+
+ case ZIP_SOURCE_ERROR:
+ {
+ int *e;
+
+ if (len < sizeof(int)*2)
+ return -1;
+
+ e = (int *)data;
+ zip_file_error_get(z->zf, e, e+1);
+ }
+ return sizeof(int)*2;
+
+ case ZIP_SOURCE_FREE:
+ zip_fclose(z->zf);
+ free(z);
+ return 0;
+
+ default:
+ ;
+ }
+
+ return -1;
+}
--- /dev/null
+/*
+ $NiH: zip_stat.c,v 1.3 2004/04/16 09:40:30 dillo Exp $
+
+ zip_stat.c -- get information about file by name
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st)
+{
+ int idx;
+
+ if ((idx=zip_name_locate(za, fname, flags)) < 0)
+ return -1;
+
+ return zip_stat_index(za, idx, flags, st);
+}
--- /dev/null
+/*
+ $NiH: zip_stat_index.c,v 1.10 2006/04/24 14:04:19 dillo Exp $
+
+ zip_stat_index.c -- get information about file by index
+ Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
+{
+ const char *name;
+
+ if (index < 0 || index >= za->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((name=zip_get_name(za, index, flags)) == NULL)
+ return -1;
+
+
+ if ((flags & ZIP_FL_UNCHANGED) == 0
+ && ZIP_ENTRY_DATA_CHANGED(za->entry+index)) {
+ if (za->entry[index].source->f(za->entry[index].source->ud,
+ st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
+ _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+ return -1;
+ }
+ }
+ else {
+ if (za->cdir == NULL || index >= za->cdir->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ st->crc = za->cdir->entry[index].crc;
+ st->size = za->cdir->entry[index].uncomp_size;
+ st->mtime = za->cdir->entry[index].last_mod;
+ st->comp_size = za->cdir->entry[index].comp_size;
+ st->comp_method = za->cdir->entry[index].comp_method;
+ if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) {
+ if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
+ /* XXX */
+ st->encryption_method = ZIP_EM_UNKNOWN;
+ }
+ else
+ st->encryption_method = ZIP_EM_TRAD_PKWARE;
+ }
+ else
+ st->encryption_method = ZIP_EM_NONE;
+ /* st->bitflags = za->cdir->entry[index].bitflags; */
+ }
+
+ st->index = index;
+ st->name = name;
+
+ return 0;
+}
--- /dev/null
+/*
+ $NiH: zip_stat_init.c,v 1.1 2006/10/31 12:03:04 dillo Exp $
+
+ zip_stat_init.c -- initialize struct zip_stat.
+ Copyright (C) 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+void
+zip_stat_init(struct zip_stat *st)
+{
+ st->name = NULL;
+ st->index = -1;
+ st->crc = 0;
+ st->mtime = (time_t)-1;
+ st->size = -1;
+ st->comp_size = -1;
+ st->comp_method = ZIP_CM_STORE;
+ st->encryption_method = ZIP_EM_NONE;
+}
--- /dev/null
+/*
+ $NiH: zip_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $
+
+ zip_sterror.c -- get string representation of zip error
+ Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+const char *
+zip_strerror(struct zip *za)
+{
+ return _zip_error_strerror(&za->error);
+}
--- /dev/null
+/*
+ $NiH: zip_unchange.c,v 1.19 2006/04/23 13:21:18 wiz Exp $
+
+ zip_unchange.c -- undo changes to file in zip archive
+ Copyright (C) 1999, 2004, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_unchange(struct zip *za, int idx)
+{
+ return _zip_unchange(za, idx, 0);
+}
+
+\f
+
+int
+_zip_unchange(struct zip *za, int idx, int allow_duplicates)
+{
+ int i;
+
+ if (idx < 0 || idx >= za->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (za->entry[idx].ch_filename) {
+ if (!allow_duplicates) {
+ i = _zip_name_locate(za,
+ _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL),
+ 0, NULL);
+ if (i != -1 && i != idx) {
+ _zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ return -1;
+ }
+ }
+
+ free(za->entry[idx].ch_filename);
+ za->entry[idx].ch_filename = NULL;
+ }
+
+ free(za->entry[idx].ch_comment);
+ za->entry[idx].ch_comment = NULL;
+ za->entry[idx].ch_comment_len = -1;
+
+ _zip_unchange_data(za->entry+idx);
+
+ return 0;
+}
--- /dev/null
+/*
+ $NiH: zip_unchange_all.c,v 1.10 2006/04/23 13:14:46 wiz Exp $
+
+ zip_unchange.c -- undo changes to all files in zip archive
+ Copyright (C) 1999, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_unchange_all(struct zip *za)
+{
+ int ret, i;
+
+ ret = 0;
+ for (i=0; i<za->nentry; i++)
+ ret |= _zip_unchange(za, i, 1);
+
+ ret |= zip_unchange_archive(za);
+
+ return ret;
+}
--- /dev/null
+/*
+ $NiH: zip_unchange_archive.c,v 1.1 2006/04/23 13:14:46 wiz Exp $
+
+ zip_unchange_archive.c -- undo global changes to ZIP archive
+ Copyright (C) 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+#include "zip.h"
+#include "zipint.h"
+
+\f
+
+int
+zip_unchange_archive(struct zip *za)
+{
+ free(za->ch_comment);
+ za->ch_comment = NULL;
+ za->ch_comment_len = -1;
+
+ return 0;
+}
--- /dev/null
+/*
+ $NiH: zip_unchange_data.c,v 1.15 2004/12/22 16:32:00 dillo Exp $
+
+ zip_unchange_data.c -- undo helper function
+ Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zipint.h"
+
+void
+_zip_unchange_data(struct zip_entry *ze)
+{
+ if (ze->source) {
+ (void)ze->source->f(ze->source->ud, NULL, 0, ZIP_SOURCE_FREE);
+ free(ze->source);
+ ze->source = NULL;
+ }
+
+ ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED;
+}
+
--- /dev/null
+
+#ifdef _MSC_VER
+
+#define _POSIX_
+#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
+
+#ifndef ssize_t
+# define ssize_t SSIZE_T
+#endif
+#ifndef mode_t
+# define mode_t int
+#endif
+#ifndef strcasecmp
+# define strcasecmp stricmp
+#endif
+#ifndef snprintf
+# define snprintf _snprintf
+#endif
+#ifndef mkstemp
+# define mkstemp(t) _creat(_mktemp(t), _S_IREAD|_S_IWRITE)
+#endif
+/*
+#ifndef fseeko
+# define fseeko fseek
+#endif
+*/
+#endif
--- /dev/null
+#ifndef _HAD_ZIPINT_H
+#define _HAD_ZIPINT_H
+
+/*
+ $NiH: zipint.h,v 1.48 2006/04/24 14:04:19 dillo Exp $
+
+ zipint.h -- internal declarations.
+ Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <nih@giga.or.at>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. The names of the authors may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <zlib.h>
+
+#include "zip.h"
+#ifndef HAVE_FSEEKO
+#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
+#endif
+
+#define CENTRAL_MAGIC "PK\1\2"
+#define LOCAL_MAGIC "PK\3\4"
+#define EOCD_MAGIC "PK\5\6"
+#define DATADES_MAGIC "PK\7\8"
+#define CDENTRYSIZE 46u
+#define LENTRYSIZE 30
+#define MAXCOMLEN 65536
+#define EOCDLEN 22
+#define CDBUFSIZE (MAXCOMLEN+EOCDLEN)
+#define BUFSIZE 8192
+
+\f
+
+/* state of change of a file in zip archive */
+
+enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED,
+ ZIP_ST_ADDED, ZIP_ST_RENAMED };
+
+/* constants for struct zip_file's member flags */
+
+#define ZIP_ZF_EOF 1 /* EOF reached */
+#define ZIP_ZF_DECOMP 2 /* decompress data */
+#define ZIP_ZF_CRC 4 /* compute and compare CRC */
+
+/* directory entry: general purpose bit flags */
+
+#define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */
+#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */
+#define ZIP_GPBF_USE_DATA_DESCRIPTOR 0x0008 /* uses crc and size from data header */
+
+/* error information */
+
+struct zip_error {
+ int zip_err; /* libzip error code (ZIP_ER_*) */
+ int sys_err; /* copy of errno (E*) or zlib error code */
+ char *str; /* string representation or NULL */
+};
+
+/* zip archive, part of API */
+
+struct zip {
+ char *zn; /* file name */
+ FILE *zp; /* file */
+ struct zip_error error; /* error information */
+
+ struct zip_cdir *cdir; /* central directory */
+ char *ch_comment; /* changed archive comment */
+ int ch_comment_len; /* length of changed zip archive
+ * comment, -1 if unchanged */
+ int nentry; /* number of entries */
+ int nentry_alloc; /* number of entries allocated */
+ struct zip_entry *entry; /* entries */
+ int nfile; /* number of opened files within archive */
+ int nfile_alloc; /* number of files allocated */
+ struct zip_file **file; /* opened files within archive */
+};
+
+/* file in zip archive, part of API */
+
+struct zip_file {
+ struct zip *za; /* zip archive containing this file */
+ struct zip_error error; /* error information */
+ int flags; /* -1: eof, >0: error */
+
+ int method; /* compression method */
+ long fpos; /* position within zip file (fread/fwrite) */
+ unsigned long bytes_left; /* number of bytes left to read */
+ unsigned long cbytes_left; /* number of bytes of compressed data left */
+
+ unsigned long crc; /* CRC so far */
+ unsigned long crc_orig; /* CRC recorded in archive */
+
+ char *buffer;
+ z_stream *zstr;
+};
+
+/* zip archive directory entry (central or local) */
+
+struct zip_dirent {
+ unsigned short version_madeby; /* (c) version of creator */
+ unsigned short version_needed; /* (cl) version needed to extract */
+ unsigned short bitflags; /* (cl) general purpose bit flag */
+ unsigned short comp_method; /* (cl) compression method used */
+ time_t last_mod; /* (cl) time of last modification */
+ unsigned int crc; /* (cl) CRC-32 of uncompressed data */
+ unsigned int comp_size; /* (cl) size of commpressed data */
+ unsigned int uncomp_size; /* (cl) size of uncommpressed data */
+ char *filename; /* (cl) file name (NUL-terminated) */
+ unsigned short filename_len; /* (cl) length of filename (w/o NUL) */
+ char *extrafield; /* (cl) extra field */
+ unsigned short extrafield_len; /* (cl) length of extra field */
+ char *comment; /* (c) file comment */
+ unsigned short comment_len; /* (c) length of file comment */
+ unsigned short disk_number; /* (c) disk number start */
+ unsigned short int_attrib; /* (c) internal file attributes */
+ unsigned int ext_attrib; /* (c) external file attributes */
+ unsigned int offset; /* (c) offset of local header */
+};
+
+/* zip archive central directory */
+
+struct zip_cdir {
+ struct zip_dirent *entry; /* directory entries */
+ int nentry; /* number of entries */
+
+ unsigned int size; /* size of central direcotry */
+ unsigned int offset; /* offset of central directory in file */
+ char *comment; /* zip archive comment */
+ unsigned short comment_len; /* length of zip archive comment */
+};
+
+\f
+
+struct zip_source {
+ zip_source_callback f;
+ void *ud;
+};
+
+/* entry in zip archive directory */
+
+struct zip_entry {
+ enum zip_state state;
+ struct zip_source *source;
+ char *ch_filename;
+ char *ch_comment;
+ int ch_comment_len;
+};
+
+\f
+
+extern const char * const _zip_err_str[];
+extern const int _zip_nerr_str;
+extern const int _zip_err_type[];
+
+\f
+
+#define ZIP_ENTRY_DATA_CHANGED(x) \
+ ((x)->state == ZIP_ST_REPLACED \
+ || (x)->state == ZIP_ST_ADDED)
+
+\f
+
+void _zip_cdir_free(struct zip_cdir *);
+struct zip_cdir *_zip_cdir_new(int, struct zip_error *);
+int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *);
+
+void _zip_dirent_finalize(struct zip_dirent *);
+void _zip_dirent_init(struct zip_dirent *);
+int _zip_dirent_read(struct zip_dirent *, FILE *,
+ unsigned char **, unsigned int, int, struct zip_error *);
+int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *);
+
+void _zip_entry_free(struct zip_entry *);
+void _zip_entry_init(struct zip *, int);
+struct zip_entry *_zip_entry_new(struct zip *);
+
+void _zip_error_clear(struct zip_error *);
+void _zip_error_copy(struct zip_error *, struct zip_error *);
+void _zip_error_fini(struct zip_error *);
+void _zip_error_get(struct zip_error *, int *, int *);
+void _zip_error_init(struct zip_error *);
+void _zip_error_set(struct zip_error *, int, int);
+const char *_zip_error_strerror(struct zip_error *);
+
+int _zip_file_fillbuf(void *, size_t, struct zip_file *);
+unsigned int _zip_file_get_offset(struct zip *, int);
+
+void _zip_free(struct zip *);
+const char *_zip_get_name(struct zip *, int, int, struct zip_error *);
+int _zip_local_header_read(struct zip *, int);
+void *_zip_memdup(const void *, size_t, struct zip_error *);
+int _zip_name_locate(struct zip *, const char *, int, struct zip_error *);
+struct zip *_zip_new(struct zip_error *);
+unsigned short _zip_read2(unsigned char **);
+unsigned int _zip_read4(unsigned char **);
+int _zip_replace(struct zip *, int, const char *, struct zip_source *);
+int _zip_set_name(struct zip *, int, const char *);
+int _zip_unchange(struct zip *, int, int);
+void _zip_unchange_data(struct zip_entry *);
+
+#endif /* zipint.h */
ZEND_DECLARE_MODULE_GLOBALS(phar)
+#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 60000)
+
+static int _php_stream_unlink(char *url, int options, php_stream_context *context TSRMLS_DC)
+{
+ php_stream_wrapper *wrapper = php_stream_locate_url_wrapper(url, NULL, options TSRMLS_CC);
+
+ if (!wrapper || !wrapper->wops) {
+ return 0;
+ }
+
+ if (!wrapper->wops->unlink) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
+ return 0;
+ }
+ return wrapper->wops->unlink(wrapper, url, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC);
+}
+
+#define php_stream_unlink(url, options, context) _php_stream_unlink((url), (options), (context) TSRMLS_CC)
+
+#endif
+
/* if the original value is 0 (disabled), then allow setting/unsetting at will
otherwise, only allow 1 (enabled), and error on disabling */
ZEND_INI_MH(phar_ini_modify_handler) /* {{{ */
php_stream_close(data->fp);
data->fp = 0;
}
-
+#if HAVE_PHAR_ZIP
+ if (data->zip) {
+ zip_close(data->zip);
+ data->zip = 0;
+ }
+#endif
efree(data);
}
/* }}}*/
entry->metadata_str.c = 0;
}
efree(entry->filename);
+#if HAVE_PHAR_ZIP
+ if (entry->zip) {
+ zip_fclose(entry->zip);
+ entry->zip = 0;
+ }
+#endif
}
/* }}} */
if (!path_len && !dir) {
if (error) {
- spprintf(error, 0, "phar error: invalid path \"%s\" must not be empty", path);
+ spprintf(error, 4096, "phar error: invalid path \"%s\" must not be empty", path);
}
return NULL;
}
if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
if (error) {
- spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
+ spprintf(error, 4096, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
}
return NULL;
}
return NULL;
}
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
+#if HAVE_PHAR_ZIP
+ if (phar->is_zip) {
+ /* construct phar_entry_info JIT */
+ if (path[path_len - 1] == '/') {
+ if (!dir) {
+ if (error) {
+ spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
+ }
+ return NULL;
+ }
+
+ entry->is_dir = 1;
+ }
+ }
+#endif
if (entry->is_deleted) {
/* entry is deleted, but has not been flushed to disk yet */
return NULL;
/* found a file in this path */
entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
entry->is_dir = 1;
+ /* this next line tells PharFileInfo->__destruct() to efree the filename */
+ entry->is_zip = 0;
entry->filename = (char *) estrndup(path, path_len + 1);
entry->filename_len = path_len;
return entry;
size_t fpos;
size_t fsize;
size_t smax;
- int mode;
+ int mode;
php_stream **owner_ptr;
} php_stream_memory_data;
#endif
+/* this is only called for non-zip-based phars */
static int phar_open_entry_file(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC) /* {{{ */
{
if (error) {
}
if (entry->is_modified && !for_write) {
if (error) {
- spprintf(error, 0, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname);
+ spprintf(error, 4096, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname);
}
return FAILURE;
}
if (entry->fp_refcount && for_write) {
if (error) {
- spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname);
+ spprintf(error, 4096, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname);
}
return FAILURE;
}
if (!for_create) {
return FAILURE;
}
+#if HAVE_PHAR_ZIP
+ if (entry->is_zip) {
+ /* for new files, start with an empty string */
+ struct zip_source *s = zip_source_buffer(entry->phar->zip, (void *)"", 0, 0);
+ if (-1 == zip_replace(entry->phar->zip, entry->index, s)) {
+ if (error) {
+ spprintf(error, 4096, "phar error: zip-based phar \"%s\" entry \"%s\" error \"%s\"", entry->phar->fname, fname, zip_strerror(phar->zip));
+ }
+ zip_error_clear(phar->zip);
+ return FAILURE;
+ }
+ }
+#endif
entry->is_deleted = 0;
}
*ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
(*ret)->phar = phar;
(*ret)->for_write = for_write;
(*ret)->internal_file = entry;
+ (*ret)->is_zip = entry->is_zip;
if (entry->fp) {
/* make a copy */
if (for_trunc) {
if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->internal_file->fp) {
php_stream_close(idata->fp);
}
+#if HAVE_PHAR_ZIP
+ if (idata->internal_file->is_zip) {
+ if (idata->internal_file->zip) {
+ zip_fclose(idata->internal_file->zip);
+ idata->internal_file->zip = 0;
+ }
+ zip_delete(phar->zip, idata->internal_file->index);
+ }
+#endif
zend_hash_del(&idata->phar->manifest, idata->internal_file->filename, idata->internal_file->filename_len);
idata->phar->refcount--;
efree(idata);
}
etemp.fp_refcount = 1;
etemp.is_modified = 1;
- etemp.filename = estrndup(path, path_len);
etemp.timestamp = time(0);
etemp.offset_within_phar = -1;
etemp.is_crc_checked = 1;
etemp.flags = PHAR_ENT_PERM_DEF_FILE;
etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
etemp.phar = phar;
+#if HAVE_PHAR_ZIP
+ if (phar->is_zip) {
+ int zindex;
+ etemp.is_zip = 1;
+ /* prevent attempts to check the CRC */
+ etemp.is_crc_checked = 1;
+ /* for new files, start with an empty string */
+ struct zip_source *s = zip_source_buffer(phar->zip, (void *)"", 0, 0);
+ if (-1 == (zindex = zip_add(phar->zip, path, s))) {
+ if (error) {
+ spprintf(error, 4096, "phar error: zip-based phar \"%s\" entry \"%s\" error \"%s\"", path, phar->fname, zip_strerror(phar->zip));
+ }
+ zip_error_clear(phar->zip);
+ return NULL;
+ }
+ etemp.index = zindex;
+ etemp.filename = (char *) zip_get_name(phar->zip, zindex, 0);
+ if (NULL == etemp.filename) {
+ if (error) {
+ spprintf(error, 4096, "phar error: zip-based phar \"%s\" entry \"%s\" error \"%s\"", path, phar->fname, zip_strerror(phar->zip));
+ }
+ zip_error_clear(phar->zip);
+ return NULL;
+ }
+ etemp.filename = estrndup(etemp.filename, strlen(etemp.filename));
+ } else {
+ etemp.filename = estrndup(path, path_len);
+ }
+#else
+ etemp.filename = estrndup(path, path_len);
+#endif
zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), NULL);
/* retrieve the phar manifest copy */
entry = phar_get_entry_info(phar, path, path_len, error TSRMLS_CC);
/**
* Open an already loaded phar
*/
-static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
{
phar_archive_data *phar;
#ifdef PHP_WIN32
*
* data is the serialized zval
*/
-static int phar_parse_metadata(php_stream *fp, char **buffer, char *endbuffer, zval **metadata TSRMLS_DC) /* {{{ */
+static int phar_parse_metadata(char **buffer, zval **metadata, int is_zip TSRMLS_DC) /* {{{ */
{
const unsigned char *p;
php_uint32 buf_len;
php_unserialize_data_t var_hash;
- PHAR_GET_32(*buffer, buf_len);
+ if (!is_zip) {
+ PHAR_GET_32(*buffer, buf_len);
+ } else {
+ buf_len = is_zip;
+ }
if (buf_len) {
ALLOC_INIT_ZVAL(*metadata);
return pos;
}
+/**
+ * Does not check for a previously opened phar in the cache.
+ *
+ * Parse a new one and add it to the cache, returning either SUCCESS or
+ * FAILURE, and setting pphar to the pointer to the manifest entry
+ *
+ * This is used by phar_open_fp to process a zip-based phar, but can be called
+ * directly.
+ */
+int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+{
+#if HAVE_PHAR_ZIP
+ struct zip *zip;
+ int ziperror, i, phar_alias_index, register_alias, metadata_len;
+ phar_entry_info entry = {0};
+ struct zip_stat zs;
+ char tmp_buf[1024], *metadata;
+
+ if (error) {
+ *error = NULL;
+ }
+
+ zip = zip_open(fname, 0, &ziperror);
+ if (!zip) {
+ if (error) {
+ /* now for the stupid hoops libzip forces... */
+ char *tmp;
+ int tmp_len;
+ tmp_len = zip_error_to_str(NULL, 0, ziperror, ziperror);
+ if (!(tmp = emalloc((tmp_len + 1) * sizeof(char)))) {
+ spprintf(error, 4096, "phar zip error: cannot open zip-based phar \"%s\"", fname);
+ } else {
+ if (!zip_error_to_str(tmp, tmp_len + 1, ziperror, ziperror)) {
+ spprintf(error, 4096, "phar zip error: cannot open zip-based phar \"%s\"", fname);
+ } else {
+ spprintf(error, 4096, "phar zip error: cannot open zip-based phar \"%s\": %s", fname, tmp);
+ efree(tmp);
+ }
+ }
+ }
+ return FAILURE;
+ }
+ phar_archive_data *mydata = NULL;
+ mydata = ecalloc(sizeof(phar_archive_data), 1);
+ mydata->fname = estrndup(fname, fname_len);
+#ifdef PHP_WIN32
+ phar_unixify_path_separators(mydata->fname, fname_len);
+#endif
+ mydata->fname_len = fname_len;
+ if (-1 != (phar_alias_index = zip_name_locate(zip, "./phar/alias.txt", 0))) {
+ struct zip_file *zf = zip_fopen_index(zip, phar_alias_index, 0);
+ int tmp_len;
+
+ tmp_len = zip_fread(zf, tmp_buf, 1024);
+ zip_fclose(zf);
+ /* if the alias is stored we enforce it (implicit overrides explicit) */
+ if (tmp_len != -1 && alias && alias_len && (alias_len != tmp_len || strncmp(alias, tmp_buf, tmp_len)))
+ {
+ if (error) {
+ spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%s\" under different alias \"%s\"", fname, tmp_buf, alias);
+ }
+ return FAILURE;
+ }
+ if (tmp_len != -1) {
+ /* use implicit alias */
+ alias = tmp_buf;
+ alias_len = tmp_len;
+ register_alias = 0;
+ }
+ } else {
+ register_alias = alias ? 1 : 0;
+ }
+ mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
+ mydata->alias_len = alias ? alias_len : fname_len;
+ mydata->is_zip = 1;
+ mydata->zip = zip;
+
+ phar_request_initialize(TSRMLS_C);
+
+ /* read in phar metadata (zip file comment) */
+ metadata = (char *) zip_get_archive_comment(zip, &metadata_len, 0);
+ if (metadata) {
+ if (phar_parse_metadata(&metadata, &mydata->metadata, metadata_len TSRMLS_CC) == FAILURE) {
+ /* if not valid serialized data, it is a regular string */
+ ALLOC_INIT_ZVAL(mydata->metadata);
+ Z_STRVAL_P(mydata->metadata) = estrndup(metadata, metadata_len);
+ Z_STRLEN_P(mydata->metadata) = metadata_len;
+ Z_TYPE_P(mydata->metadata) = IS_STRING;
+ }
+ } else {
+ mydata->metadata = NULL;
+ }
+ /* set up our manifest */
+ zend_hash_init(&mydata->manifest, sizeof(phar_entry_info),
+ zend_get_hash_value, destroy_phar_manifest, 0);
+ entry.phar = mydata;
+ entry.is_zip = 1;
+ /* prevent CRC checking */
+ entry.is_crc_checked = 1;
+ for (i = 0; i < zip_get_num_files(zip); i++) {
+ char *name;
+ name = (char *) zip_get_name(zip, i, 0);
+ if (name) {
+ /* get file stat */
+ if (-1 != zip_stat_index(zip, i, 0, &zs)) {
+ entry.compressed_filesize = zs.comp_size;
+ entry.uncompressed_filesize = zs.size;
+ entry.crc32 = zs.crc;
+ entry.timestamp = (php_uint32) zs.mtime;
+ entry.flags = 0;
+ switch (zs.comp_method) {
+ case ZIP_CM_DEFLATE :
+ /* if we have zip, we have zlib decompression */
+ entry.flags |= PHAR_ENT_COMPRESSED_GZ;
+ break;
+ case ZIP_CM_BZIP2 :
+#if !HAVE_BZ2
+ if (mydata->metadata) {
+ zval_dtor(mydata->metadata);
+ }
+ efree(mydata->fname);
+ if (mydata->alias) {
+ efree(mydata->alias);
+ }
+ zip_close(zip);
+ zend_hash_destroy(&(mydata->manifest));
+ efree(mydata);
+ if (error) {
+ spprintf(error, 0, "bz2 extension is required for Bzip2 compressed zip-based .phar file \"%s\"", fname);
+ }
+ return FAILURE;
+#else
+ if (!phar_has_bz2) {
+ if (mydata->metadata) {
+ zval_dtor(mydata->metadata);
+ }
+ efree(mydata->fname);
+ if (mydata->alias) {
+ efree(mydata->alias);
+ }
+ zip_close(zip);
+ zend_hash_destroy(&(mydata->manifest));
+ efree(mydata);
+ if (error) {
+ spprintf(error, 0, "bz2 extension is required for gz compressed zip-based .phar file \"%s\"", fname);
+ }
+ return FAILURE;
+ }
+#endif
+ entry.flags |= PHAR_ENT_COMPRESSED_BZ2;
+ break;
+ }
+ }
+ entry.index = i;
+ entry.filename_len = strlen(name);
+ entry.filename = estrndup(name, entry.filename_len);
+ /* get file metadata */
+ metadata = (char *) zip_get_file_comment(zip, i, &metadata_len, 0);
+ if (metadata) {
+ if (phar_parse_metadata(&metadata, &(entry.metadata), metadata_len TSRMLS_CC) == FAILURE) {
+ /* if not valid serialized data, it is a regular string */
+ ALLOC_INIT_ZVAL(entry.metadata);
+ Z_STRVAL_P(entry.metadata) = estrndup(metadata, metadata_len);
+ Z_STRLEN_P(entry.metadata) = metadata_len;
+ Z_TYPE_P(entry.metadata) = IS_STRING;
+ }
+ } else {
+ entry.metadata = NULL;
+ }
+ zend_hash_add(&mydata->manifest, name, strlen(name), (void *)&entry,sizeof(phar_entry_info), NULL);
+ }
+ }
+ /* ignore all errors in loading up manifest */
+ zip_error_clear(zip);
+
+ zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+ if (register_alias) {
+ mydata->is_explicit_alias = 1;
+ zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+ } else {
+ mydata->is_explicit_alias = 0;
+ }
+ if (pphar) {
+ *pphar = mydata;
+ }
+ return SUCCESS;
+#else
+ spprintf(error, 4096, "Error: Cannot open zip-based phar \"%s\"", fname);
+ return FAILURE;
+#endif
+}
+/* }}} */
+
/**
* Does not check for a previously opened phar in the cache.
*
mydata = ecalloc(sizeof(phar_archive_data), 1);
/* check whether we have meta data, zero check works regardless of byte order */
- if (phar_parse_metadata(fp, &buffer, endbuffer, &mydata->metadata TSRMLS_CC) == FAILURE) {
+ if (phar_parse_metadata(&buffer, &mydata->metadata, 0 TSRMLS_CC) == FAILURE) {
MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\"");
}
-
+
/* set up our manifest */
zend_hash_init(&mydata->manifest, sizeof(phar_entry_info),
zend_get_hash_value, destroy_phar_manifest, 0);
PHAR_GET_32(buffer, entry.compressed_filesize);
PHAR_GET_32(buffer, entry.crc32);
PHAR_GET_32(buffer, entry.flags);
- if (phar_parse_metadata(fp, &buffer, endbuffer, &entry.metadata TSRMLS_CC) == FAILURE) {
+ if (phar_parse_metadata(&buffer, &entry.metadata, 0 TSRMLS_CC) == FAILURE) {
efree(entry.filename);
MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\"");
}
}
/* }}} */
+/* forward declaration */
+static int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
+
/**
* Create or open a phar for writing
*/
-int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
{
- phar_archive_data *mydata;
- char *my_realpath;
+#if HAVE_PHAR_ZIP
+ phar_archive_data *phar;
+ int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
int register_alias;
- php_stream *fp;
- if (!pphar) {
- pphar = &mydata;
+ if (FAILURE == ret) {
+ return FAILURE;
+ }
+ if ((*pphar)->is_zip) {
+ return ret;
+ }
+
+ phar = *pphar;
+ if (phar->is_brandnew) {
+ int *errorp;
+ phar->is_zip = 1;
+ if (phar->fp) {
+ php_stream_close(phar->fp);
+ phar->fp = NULL;
+ php_stream_unlink(phar->fname, 0, NULL);
+ }
+ phar->zip = zip_open(fname, 0 | ZIP_CREATE | ZIP_EXCL, errorp);
+ if (NULL != phar->zip) {
+ return SUCCESS;
+ }
+ /* fail - free newly created manifest entry */
+ if (register_alias) {
+ zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len);
+ }
+ zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len);
+ efree(phar->fname);
+ efree(phar->alias);
+ efree(phar);
+ *pphar = NULL;
+
+ if (error) {
+ /* now for the stupid hoops libzip forces... */
+ char *tmp;
+ int tmp_len;
+ tmp_len = zip_error_to_str(NULL, 0, *errorp, *errorp);
+ if (!(tmp = emalloc((tmp_len + 1) * sizeof(char)))) {
+ spprintf(error, 4096, "phar zip error: cannot create zip-based phar \"%s\"", fname);
+ } else {
+ if (!zip_error_to_str(tmp, tmp_len + 1, *errorp, *errorp)) {
+ spprintf(error, 4096, "phar zip error: cannot create zip-based phar \"%s\"", fname);
+ } else {
+ spprintf(error, 4096, "phar zip error: cannot create zip-based phar \"%s\": %s", fname, tmp);
+ efree(tmp);
+ }
+ }
+ }
+ return FAILURE;
+ }
+
+ /* we've reached here - the phar exists and is a regular phar */
+ if (error) {
+ spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", fname);
}
+ return FAILURE;
+#else
+ if (error) {
+ spprintf(error, 4096, "phar zip error: phar \"%s\" cannot be created as zip-based phar, zip-based phars are disabled", fname);
+ }
+ return FAILURE;
+#endif /* #if HAVE_PHAR_ZIP */
+}
+
+/**
+ * Create or open a phar for writing
+ */
+int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+{
+ char *ext_str;
+ int ext_len;
+
if (error) {
*error = NULL;
}
return SUCCESS;
}
+ if (phar_detect_phar_fname_ext(fname, 1, &ext_str, &ext_len) == SUCCESS) {
+ if (ext_len >= sizeof(".phar.zip")-1 && !memcmp((void *) ext_str, (void *) ".phar.zip", sizeof(".phar.zip")-1)) {
+ /* assume zip-based phar */
+ return phar_open_or_create_zip(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
+ }
+ }
+ return phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
+}
+
+static int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+{
+ phar_archive_data *mydata;
+ char *my_realpath;
+ int register_alias;
+ php_stream *fp;
+
+ if (!pphar) {
+ pphar = &mydata;
+ }
#if PHP_MAJOR_VERSION < 6
if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
return FAILURE;
static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
{
const char token[] = "__HALT_COMPILER();";
- char *pos, buffer[1024 + sizeof(token)];
+ const char zip_magic[] = "PK\x03\x04";
+ char *pos, buffer[1024 + sizeof(token)], test = '\0';
const long readsize = sizeof(buffer) - sizeof(token);
const long tokenlen = sizeof(token) - 1;
long halt_offset;
if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) < (size_t) tokenlen) {
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
}
+ if (!test) {
+ test = '\1';
+ pos = buffer+tokenlen;
+ if (!memcmp(pos, zip_magic, 4)) {
+ php_stream_close(fp);
+ return phar_open_zipfile(fname, fname_len, alias, alias_len, pphar, error TSRMLS_CC);
+ }
+ }
if ((pos = strstr(buffer, token)) != NULL) {
halt_offset += (pos - buffer); /* no -tokenlen+tokenlen here */
return phar_open_file(fp, fname, fname_len, alias, alias_len, halt_offset, pphar, error TSRMLS_CC);
{
char end;
char *pos_p = strstr(filename, ".phar.php");
+ char *pos_zi = strstr(filename, ".phar.zip");
+ char *pos_zi2 = strstr(filename, ".phar.zip.php");
char *pos_z = strstr(filename, ".phar.gz");
char *pos_b = strstr(filename, ".phar.bz2");
} else if (pos_b) {
*ext_str = pos_b;
*ext_len = 9;
+ } else if (pos_zi2) {
+ *ext_str = pos_zi2;
+ *ext_len = 13;
+ } else if (pos_zi) {
+ *ext_str = pos_zi;
+ *ext_len = 9;
} else if ((pos_p = strstr(filename, ".phar")) != NULL) {
*ext_str = pos_p;
*ext_len = 5;
*error = NULL;
}
fname = zend_get_executed_filename(TSRMLS_C);
-
fname_len = strlen(fname);
+ if (strstr(fname, "phar://") && strstr(fname, ".phar/stub.php")) {
+ char *arch, *entry;
+ int arch_len, entry_len;
+ phar_archive_data *phar;
+
+ if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
+ efree(entry);
+ efree(arch);
+ goto regular_error;
+ }
+ if (strcmp(entry, "/.phar/stub.php")) {
+ efree(entry);
+ efree(arch);
+ goto regular_error;
+ }
+
+ /* we're running from inside a zip-based phar */
+ efree(entry);
+ entry = fname;
+ fname = arch;
+ fname_len = arch_len;
+ if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && phar->is_zip) {
+ efree(arch);
+ return SUCCESS;
+ }
+ /* restore original value for error purpose */
+ fname = entry;
+ }
+regular_error:
+
if (phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) {
return SUCCESS;
}
/**
* helper function to open an internal file's fp just-in-time
*/
-static phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp,
+phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp,
char **error, int for_write TSRMLS_DC)
{
php_uint32 offset, flags;
php_stream_filter *filter/*, *consumed */;
- char tmpbuf[8];
char *filter_name;
char *buffer;
if (error) {
*error = NULL;
}
+#if HAVE_PHAR_ZIP
+ if (entry->is_zip) {
+ char readbuf[8192];
+ int got;
+ if (entry->fp) {
+ return entry;
+ }
+ if (!entry->zip) {
+ if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
+# if HAVE_BZ2
+ char *filter_name;
+ php_stream_filter *filter;
+ php_stream *fp;
+ /* we have to decompress this by hand */
+
+ if (!phar_has_bz2) {
+ if (error) {
+ spprintf(error, 4096, "phar error, cannot decompress bzip2-compressed entry");
+ }
+ return NULL;
+ }
+
+ /* first, read into a temp stream */
+ fp = php_stream_temp_new();
+ entry->zip = zip_fopen_index(phar->zip, entry->index, ZIP_FL_COMPRESSED);
+ if (!entry->zip) {
+ if (error) {
+ spprintf(error, 4096, "phar error: %s", zip_strerror(phar->zip));
+ }
+ zip_error_clear(phar->zip);
+ return NULL;
+ }
+ do {
+ size_t check;
+ got = zip_fread(entry->zip, (void *)readbuf, 8192);
+ if (-1 == got) break;
+ check = got;
+ if (check != php_stream_write(fp, readbuf, got)) {
+ if (error) {
+ spprintf(error, 4096, "phar error: could not copy full zip file contents of entry \"%s\"", entry->filename);
+ }
+ fclose(fp);
+ entry->fp = NULL;
+ zip_fclose(entry->zip);
+ entry->zip = NULL;
+ return NULL;
+ }
+ } while (got == 8192);
+ zip_fclose(entry->zip);
+ php_stream_seek(fp, 0, SEEK_SET);
+
+ /* now use a decompression filter to inflate into our temp file */
+ if ((filter_name = phar_decompress_filter(entry, 0)) != NULL) {
+ filter = php_stream_filter_create(phar_decompress_filter(phar, 0), NULL, php_stream_is_persistent(fp) TSRMLS_CC);
+ } else {
+ filter = NULL;
+ }
+ if (!filter) {
+ spprintf(error, 0, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->phar->fname, phar_decompress_filter(entry, 1), entry->filename);
+ return NULL;
+ }
+
+ /* now we can safely use proper decompression */
+ entry->fp = php_stream_temp_new();
+ php_stream_filter_append(&entry->fp->writefilters, filter);
+ if (php_stream_copy_to_stream(fp, entry->fp, entry->compressed_filesize) != entry->compressed_filesize || php_stream_tell(entry->fp) != (off_t) entry->uncompressed_filesize) {
+ spprintf(error, 0, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ return NULL;
+ }
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(fp);
+ return entry;
+# else /* #if HAVE_BZ2 */
+ if (error) {
+ spprintf(error, 4096, "phar error, cannot decompress bzip2-compressed entry");
+ }
+ return NULL;
+# endif /* #if HAVE_BZ2 */
+ } else {
+ /* uncompressed or zlib-compressed */
+ entry->zip = zip_fopen_index(phar->zip, entry->index, 0);
+ if (!entry->zip) {
+ if (error) {
+ spprintf(error, 4096, "phar error: %s", zip_strerror(phar->zip));
+ }
+ zip_error_clear(phar->zip);
+ return NULL;
+ }
+ }
+ }
+
+ /* load contents of zip file to temp stream */
+ entry->fp = php_stream_temp_new();
+ do {
+ size_t check;
+ got = zip_fread(entry->zip, (void *)readbuf, 8192);
+ if (-1 == got) break;
+ check = got;
+ if (check != php_stream_write(entry->fp, readbuf, got)) {
+ if (error) {
+ spprintf(error, 4096, "phar error: could not copy full zip file contents of entry \"%s\"", entry->filename);
+ }
+ php_stream_close(entry->fp);
+ entry->fp = NULL;
+ zip_fclose(entry->zip);
+ entry->zip = NULL;
+ return NULL;
+ }
+ } while (got == 8192);
+ zip_fclose(entry->zip);
+ entry->zip = NULL;
+ return entry;
+ }
+#endif /* #if HAVE_PHAR_ZIP */
/* seek to start of internal file and read it */
offset = phar->internal_file_start + entry->offset_within_phar;
if (-1 == php_stream_seek(fp, offset, SEEK_SET)) {
entry->fp = phar->fp;
return entry;
}
- buffer = &tmpbuf[0];
/* bypass to temp stream */
entry->fp = php_stream_temp_new();
if (php_stream_copy_to_stream(fp, entry->fp, entry->uncompressed_filesize) != entry->uncompressed_filesize) {
fp = idata->phar->fp;
- if (!fp) {
+ if (!idata->phar->is_zip && !fp) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot open phar \"%s\"", idata->phar->fname);
phar_entry_delref(idata TSRMLS_CC);
efree(internal_file);
}
/* }}} */
+#if HAVE_PHAR_ZIP
+static ssize_t phar_zip_source(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+{
+ char *buf = (char *) data;
+ phar_entry_info *entry = (phar_entry_info *) state;
+ size_t read;
+ struct zip_stat *sb = (struct zip_stat *) data;
+ TSRMLS_FETCH();
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN :
+ php_stream_seek(entry->fp, 0, SEEK_SET);
+ return 0;
+ case ZIP_SOURCE_READ :
+ read = php_stream_read(entry->fp, buf, len);
+ if (read < 0) return 0;
+ return read;
+ case ZIP_SOURCE_STAT :
+ zip_stat_init(sb);
+ sb->mtime = time(NULL);
+ sb->size = entry->uncompressed_filesize;
+ return sizeof(struct zip_stat);
+ default:
+ return len;
+ }
+}
+
+/* reconstruct the zip index of each manifest entry */
+static int phar_zip_reconstruct_apply(void *data TSRMLS_DC) /* {{{ */
+{
+ phar_entry_info *entry = (phar_entry_info *)data;
+ if (entry->is_deleted) {
+ entry->index = -1;
+ if (entry->fp_refcount <= 0) {
+ return ZEND_HASH_APPLY_REMOVE;
+ } else {
+ /* we can't delete this in-memory until it is closed */
+ return ZEND_HASH_APPLY_KEEP;
+ }
+ }
+ entry->index = zip_name_locate(entry->phar->zip, entry->filename, 0);
+ return ZEND_HASH_APPLY_KEEP;
+}
+
+/* perform final modification of zip contents for each file in the manifest before saving */
+static int phar_zip_changed_apply(void *data TSRMLS_DC) /* {{{ */
+{
+ phar_entry_info *entry = (phar_entry_info *)data;
+
+ if (entry->is_deleted) {
+ if (entry->fp_refcount <= 0) {
+ return ZEND_HASH_APPLY_REMOVE;
+ } else {
+ /* we can't delete this in-memory until it is closed */
+ return ZEND_HASH_APPLY_KEEP;
+ }
+ }
+ if (entry->is_modified) {
+ ssize_t (*cb)(void *state, void *data, size_t len, enum zip_source_cmd cmd) = phar_zip_source;
+ if (entry->fp) {
+ struct zip_source *s = zip_source_function(entry->phar->zip, cb, entry);
+ if (-1 == zip_replace(entry->phar->zip, entry->index, s)) {
+ zip_error_clear(entry->phar->zip);
+ return ZEND_HASH_APPLY_REMOVE;
+ }
+ }
+
+ /* set file metadata */
+ if (entry->metadata) {
+ php_serialize_data_t metadata_hash;
+ if (entry->metadata_str.c) {
+ smart_str_free(&entry->metadata_str);
+ }
+ entry->metadata_str.c = 0;
+ entry->metadata_str.len = 0;
+ PHP_VAR_SERIALIZE_INIT(metadata_hash);
+ php_var_serialize(&entry->metadata_str, &entry->metadata, &metadata_hash TSRMLS_CC);
+ PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
+ if (-1 == zip_set_file_comment(entry->phar->zip, entry->index, entry->metadata_str.c, entry->metadata_str.len)) {
+ return ZEND_HASH_APPLY_STOP;
+ }
+ } else {
+ zip_set_file_comment(entry->phar->zip, entry->index, NULL, 0);
+ }
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+
+int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */
+{
+ char *pos;
+ smart_str main_metadata_str = {0};
+ int ziperrint;
+ static const char newstub[] = "<?php // zip-based phar archive stub file\n__HALT_COMPILER();";
+ php_stream *stubfile;
+ php_serialize_data_t metadata_hash;
+ int free_user_stub;
+ int phar_stub_index, phar_alias_index;
+
+ /* save modified files to the zip */
+ zend_hash_apply(&archive->manifest, phar_zip_changed_apply TSRMLS_CC);
+ if (archive->zip->error.str) {
+ if (error) {
+ spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", archive->fname, zip_strerror(archive->zip));
+ }
+ return EOF;
+ }
+
+ /* set phar metadata */
+ main_metadata_str.c = 0;
+ if (archive->metadata) {
+ PHP_VAR_SERIALIZE_INIT(metadata_hash);
+ php_var_serialize(&main_metadata_str, &archive->metadata, &metadata_hash TSRMLS_CC);
+ PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
+ zip_set_archive_comment(archive->zip, main_metadata_str.c, main_metadata_str.len);
+ smart_str_free(&main_metadata_str);
+ } else {
+ zip_set_archive_comment(archive->zip, NULL, 0);
+ }
+
+ /* set alias */
+ if (archive->is_explicit_alias) {
+ struct zip_source *source;
+ phar_alias_index = zip_name_locate(archive->zip, ".phar/alias.txt", 0);
+ if (NULL == (source = zip_source_buffer(archive->zip, archive->alias, archive->alias_len, 0)) ||
+ (-1 == phar_alias_index && -1 == zip_add(archive->zip, ".phar/alias.txt", source)) ||
+ (-1 != phar_alias_index && -1 == zip_replace(archive->zip, phar_alias_index, source))) {
+ if (error) {
+ spprintf(error, 0, "unable to set alias in new zip-based phar \"%s\": %s", archive->fname, zip_strerror(archive->zip));
+ }
+ zip_error_clear(archive->zip);
+ return EOF;
+ }
+ }
+ /* set stub */
+ phar_stub_index = zip_name_locate(archive->zip, ".phar/stub.php", 0);
+ zip_error_clear(archive->zip);
+ if (user_stub) {
+ struct zip_source *source;
+ if (len < 0) {
+ /* resource passed in */
+ if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) {
+ if (error) {
+ spprintf(error, 0, "unable to access resource to copy stub to new phar \"%s\"", archive->fname);
+ }
+ return EOF;
+ }
+ if (len == -1) {
+ len = PHP_STREAM_COPY_ALL;
+ } else {
+ len = -len;
+ }
+ user_stub = 0;
+ if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
+ if (error) {
+ spprintf(error, 0, "unable to read resource to copy stub to new phar \"%s\"", archive->fname);
+ }
+ return EOF;
+ }
+ free_user_stub = 1;
+ } else {
+ free_user_stub = 0;
+ }
+ if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL)
+ {
+ if (error) {
+ spprintf(error, 0, "illegal stub for phar \"%s\"", archive->fname);
+ }
+ if (free_user_stub) {
+ efree(user_stub);
+ }
+ return EOF;
+ }
+ len = pos - user_stub + 18;
+ if (NULL == (source = zip_source_buffer(archive->zip, user_stub, len, 0)) ||
+ (-1 == phar_stub_index && -1 == zip_add(archive->zip, ".phar/stub.php", source)) ||
+ (-1 != phar_stub_index && -1 == zip_replace(archive->zip, phar_stub_index, source))) {
+ if (error) {
+ spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\": %s", archive->fname, zip_strerror(archive->zip));
+ }
+ if (free_user_stub) {
+ efree(user_stub);
+ }
+ zip_error_clear(archive->zip);
+ return EOF;
+ }
+ if (free_user_stub) {
+ efree(user_stub);
+ }
+ } else {
+ if (archive->is_brandnew) {
+ struct zip_source *source;
+ /* this is a brand new phar, add the stub */
+ if (NULL == (source = zip_source_buffer(archive->zip, newstub, sizeof(newstub) - 1, 0)) || -1 == zip_add(archive->zip, ".phar/stub.php", source)) {
+ if (error) {
+ spprintf(error, 0, "unable to create stub in new zip-based phar \"%s\": %s", archive->fname, zip_strerror(archive->zip));
+ }
+ zip_error_clear(archive->zip);
+ return EOF;
+ }
+ }
+ }
+
+ /* save zip */
+ if (-1 == zip_close(archive->zip)) {
+ if (error) {
+ spprintf(error, 4096, "saving of zip-based phar \"%s\" failed: %s", archive->fname, zip_strerror(archive->zip));
+ }
+ return EOF;
+ }
+
+ /* re-open */
+ archive->zip = zip_open(archive->fname, 0, &ziperrint);
+ if (!archive->zip) {
+ if (error) {
+ /* now for the stupid hoops libzip forces... */
+ char *tmp;
+ int tmp_len;
+ tmp_len = zip_error_to_str(NULL, 0, ziperrint, ziperrint);
+ if (!(tmp = emalloc((tmp_len + 1) * sizeof(char)))) {
+ spprintf(error, 4096, "phar zip error: cannot re-open zip-based phar \"%s\"", archive->fname);
+ } else {
+ if (!zip_error_to_str(tmp, tmp_len + 1, ziperrint, ziperrint)) {
+ spprintf(error, 4096, "phar zip error: cannot re-open zip-based phar \"%s\"", archive->fname);
+ } else {
+ spprintf(error, 4096, "phar zip error: cannot re-open zip-based phar \"%s\": %s", archive->fname, tmp);
+ efree(tmp);
+ }
+ }
+ }
+ return EOF;
+ }
+
+ /* reconstruct manifest zip index map */
+ zend_hash_apply(&archive->manifest, phar_zip_reconstruct_apply TSRMLS_CC);
+ return EOF;
+}
+/* }}} */
+#endif /* if HAVE_PHAR_ZIP */
+
/**
* Save phar contents to disk
*
return EOF;
}
+#if HAVE_PHAR_ZIP
+ if (archive->is_zip) {
+ return phar_zip_flush(archive, user_stub, len, error TSRMLS_CC);
+ }
+#endif
if (archive->fp && !archive->is_brandnew) {
oldfile = archive->fp;
closeoldfile = 0;
}
/* }}}*/
-#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 60000)
-
-static int _php_stream_unlink(char *url, int options, php_stream_context *context TSRMLS_DC)
-{
- php_stream_wrapper *wrapper = php_stream_locate_url_wrapper(url, NULL, options TSRMLS_CC);
-
- if (!wrapper || !wrapper->wops) {
- return 0;
- }
-
- if (!wrapper->wops->unlink) {
- php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
- return 0;
- }
- return wrapper->wops->unlink(wrapper, url, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC);
-}
-
-#define php_stream_unlink(url, options, context) _php_stream_unlink((url), (options), (context) TSRMLS_CC)
-
-#endif
-
/**
* Unlink a file within a phar archive
*/
static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */
{
zend_op_array *res;
- char *s, *name = NULL;
+ char *name = NULL;
char *fname = NULL;
int fname_len, failed;
zend_op_array *(*save)(zend_file_handle *file_handle, int type TSRMLS_DC);
save = zend_compile_file; /* restore current handler or we cause trouble */
zend_compile_file = phar_orig_compile_file;
+ if (strstr(file_handle->filename, ".phar.zip") && !strstr(file_handle->filename, ":\\")) {
+ /* zip-based phar */
+ spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
+ file_handle->type = ZEND_HANDLE_FILENAME;
+ file_handle->free_filename = 1;
+ file_handle->filename = name;
+ if (file_handle->opened_path) {
+ efree(file_handle->opened_path);
+ }
+ goto skip_phar;
+ }
if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) {
char *arch, *entry;
int arch_len, entry_len;
efree(entry);
entry = file_handle->filename;
/* include within phar, if :// is not in the url, then prepend phar://<archive>/ */
- entry_len = strlen(entry);
- for (s = entry; s < (entry + entry_len - 4); s++) {
- if (*s == ':' && *(s + 1) == '/' && *(s + 2) == '/') {
- efree(arch);
- goto skip_phar;
- }
+ if (strstr(entry, "://")) {
+ efree(arch);
+ goto skip_phar;
}
+ entry_len = strlen(entry);
/* auto-convert to phar:// */
spprintf(&name, 4096, "phar://%s/%s", arch, entry);
efree(arch);
php_info_print_table_row(2, "Phar EXT version", PHAR_EXT_VERSION_STR);
php_info_print_table_row(2, "Phar API version", PHAR_API_VERSION_STR);
php_info_print_table_row(2, "CVS revision", "$Revision$");
+ php_info_print_table_row(2, "Phar-based phar archives",
+ "enabled");
+#if HAVE_PHAR_ZIP
+ php_info_print_table_row(2, "ZIP-based phar archives",
+ "enabled");
+#else
+ php_info_print_table_row(2, "ZIP-based phar archives",
+ "disabled");
+#endif
#if HAVE_ZLIB
if (phar_has_zlib) {
php_info_print_table_row(2, "gzip compression",
#ifndef PHP_WIN32
#include "TSRM/tsrm_strtok_r.h"
#endif
+#if HAVE_PHAR_ZIP
+#include "lib/zip.h"
+#include "lib/zipint.h"
+#endif
#if HAVE_SPL
#include "ext/spl/spl_array.h"
#include "ext/spl/spl_directory.h"
int is_dir:1;
phar_archive_data *phar;
smart_str metadata_str;
+ /* zip-based phar file stuff */
+ int is_zip:1;
+#if HAVE_PHAR_ZIP
+ int index;
+ struct zip_file *zip;
+#endif
} phar_entry_info;
/* information about a phar file (the archive itself) */
int is_brandnew:1;
/* defer phar creation */
int donotflush:1;
+ /* zip-based phar variables */
+ int is_zip:1;
+#if HAVE_PHAR_ZIP
+ struct zip *zip;
+#endif
};
#define PHAR_MIME_PHP '\0'
/* for copies of the phar fp, defines where 0 is */
off_t zero;
int for_write:1;
+ int is_zip:1;
phar_entry_info *internal_file;
} phar_entry_data;
int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC);
-
+phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp,
+ char **error, int for_write TSRMLS_DC);
+int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
#ifdef PHAR_MAIN
static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
/* prepare to output */
if (!phar->fp) {
- phar->internal_file->fp_refcount++;
- phar->fp = phar->phar->fp;
- phar->zero = phar->phar->internal_file_start + phar->internal_file->offset_within_phar;
- phar->internal_file->fp = phar->phar->fp;
+ char *error;
+ if (!phar_open_jit(phar->phar, phar->internal_file, phar->phar->fp, &error, 0 TSRMLS_CC)) {
+ if (error) {
+ zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
+ efree(error);
+ }
+ return -1;
+ }
+ phar->fp = phar->internal_file->fp;
}
php_stream_seek(phar->fp, phar->position + phar->zero, SEEK_SET);
do {
fname = zend_get_executed_filename(TSRMLS_C);
fname_len = strlen(fname);
+
+ if (strstr(fname, "://")) {
+ char *arch, *entry;
+ int arch_len, entry_len;
+ phar_archive_data *phar;
+
+ /* running within a zip-based phar, acquire the actual name */
+ if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
+ efree(entry);
+ efree(arch);
+ return; /* this, incidentally, should be impossible */
+ }
+
+ efree(entry);
+ entry = fname;
+ fname = arch;
+ fname_len = arch_len;
+ if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && phar->is_zip) {
+ efree(arch);
+ fname = phar->fname;
+ fname_len = phar->fname_len;
+ } else {
+ efree(arch);
+ fname = entry;
+ }
+ }
#ifdef PHP_WIN32
fname = estrndup(fname, fname_len);
phar_unixify_path_separators(fname, fname_len);
}
efree(phar_obj->arc.archive->alias);
- phar_obj->arc.archive->alias = estrndup(alias, alias_len);
+ if (alias_len) {
+ phar_obj->arc.archive->alias = estrndup(alias, alias_len);
+ } else {
+ phar_obj->arc.archive->alias = NULL;
+ }
phar_obj->arc.archive->alias_len = alias_len;
+ phar_obj->arc.archive->is_explicit_alias = 0;
phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
newentry.metadata_str.c = NULL;
newentry.metadata_str.len = 0;
}
+#if HAVE_PHAR_ZIP
+ if (oldentry->is_zip) {
+ newentry.index = -1;
+ }
+#endif
newentry.fp = fp;
newentry.filename = estrndup(newfile, newfile_len);
newentry.filename_len = newfile_len;
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
efree(error);
}
-
+
RETURN_TRUE;
}
}
entry->is_modified = 0;
entry->is_deleted = 1;
+#if HAVE_PHAR_ZIP
+ if (entry->is_zip) {
+ if (entry->zip) {
+ zip_fclose(entry->zip);
+ entry->zip = 0;
+ }
+ zip_delete(phar_obj->arc.archive->zip, entry->index);
+ }
+#endif
/* we need to "flush" the stream to save the newly deleted file on disk */
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
if (error) {
php_stream *fp;
PHAR_ARCHIVE_OBJECT();
+#if HAVE_PHAR_ZIP
+ if (phar_obj->arc.archive->is_zip) {
+ struct zip_stat zs;
+ struct zip_file *zf;
+ int index;
+
+ if (-1 == zip_stat(phar_obj->arc.archive->zip, ".phar/stub.php", 0, &zs)) {
+ zip_error_clear(phar_obj->arc.archive->zip);
+ RETURN_STRINGL("", 0, 1);
+ }
+ index = zs.index;
+ len = zs.size;
+ zf = zip_fopen_index(phar_obj->arc.archive->zip, index, 0);
+ if (!zf) {
+ zip_error_clear(phar_obj->arc.archive->zip);
+ RETURN_STRINGL("", 0, 1);
+ }
+ buf = safe_emalloc(len, 1, 1);
+ if (len != zip_fread(zf, buf, len)) {
+ zip_fclose(zf);
+ efree(buf);
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
+ "Unable to read stub");
+ return;
+ }
+ buf[len] = '\0';
+
+ RETURN_STRINGL(buf, len, 0);
+ }
+#endif
len = phar_obj->arc.archive->halt_offset;
if (phar_obj->arc.archive->fp && !phar_obj->arc.archive->is_brandnew) {
php_stream_close(fp);
}
buf[len] = '\0';
-
+
RETURN_STRINGL(buf, len, 0);
}
/* }}}*/
PHAR_ENTRY_OBJECT();
if (entry_obj->ent.entry->is_dir) {
- if (entry_obj->ent.entry->filename) {
+ if (!entry_obj->ent.entry->is_zip && entry_obj->ent.entry->filename) {
efree(entry_obj->ent.entry->filename);
entry_obj->ent.entry->filename = NULL;
}
char *error;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_zip) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+ "Cannot compress with Bzip2 compression, not possible with zip-based phar archives");
+ }
if (!phar_has_bz2) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Cannot compress with Bzip2 compression, bz2 extension is not enabled");
?>
===DONE===
--EXPECT--
-string(5) "1.2.0"
+string(5) "1.1.0"
===DONE===