]> granicus.if.org Git - php/commitdiff
add zip-based phar support. not quite working is webPhar(), not sure why yet
authorGreg Beaver <cellog@php.net>
Mon, 31 Dec 2007 22:42:40 +0000 (22:42 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 31 Dec 2007 22:42:40 +0000 (22:42 +0000)
61 files changed:
ext/phar/config.m4
ext/phar/config.w32
ext/phar/lib/mkstemp.c [new file with mode: 0644]
ext/phar/lib/unistd.h [new file with mode: 0644]
ext/phar/lib/zip.h [new file with mode: 0644]
ext/phar/lib/zip_add.c [new file with mode: 0644]
ext/phar/lib/zip_add_dir.c [new file with mode: 0644]
ext/phar/lib/zip_close.c [new file with mode: 0644]
ext/phar/lib/zip_delete.c [new file with mode: 0644]
ext/phar/lib/zip_dirent.c [new file with mode: 0644]
ext/phar/lib/zip_entry_free.c [new file with mode: 0644]
ext/phar/lib/zip_entry_new.c [new file with mode: 0644]
ext/phar/lib/zip_err_str.c [new file with mode: 0644]
ext/phar/lib/zip_error.c [new file with mode: 0644]
ext/phar/lib/zip_error_clear.c [new file with mode: 0644]
ext/phar/lib/zip_error_get.c [new file with mode: 0644]
ext/phar/lib/zip_error_get_sys_type.c [new file with mode: 0644]
ext/phar/lib/zip_error_strerror.c [new file with mode: 0644]
ext/phar/lib/zip_error_to_str.c [new file with mode: 0644]
ext/phar/lib/zip_fclose.c [new file with mode: 0644]
ext/phar/lib/zip_file_error_clear.c [new file with mode: 0644]
ext/phar/lib/zip_file_error_get.c [new file with mode: 0644]
ext/phar/lib/zip_file_get_offset.c [new file with mode: 0644]
ext/phar/lib/zip_file_strerror.c [new file with mode: 0644]
ext/phar/lib/zip_fopen.c [new file with mode: 0644]
ext/phar/lib/zip_fopen_index.c [new file with mode: 0644]
ext/phar/lib/zip_fread.c [new file with mode: 0644]
ext/phar/lib/zip_free.c [new file with mode: 0644]
ext/phar/lib/zip_get_archive_comment.c [new file with mode: 0644]
ext/phar/lib/zip_get_file_comment.c [new file with mode: 0644]
ext/phar/lib/zip_get_name.c [new file with mode: 0644]
ext/phar/lib/zip_get_num_files.c [new file with mode: 0644]
ext/phar/lib/zip_memdup.c [new file with mode: 0644]
ext/phar/lib/zip_name_locate.c [new file with mode: 0644]
ext/phar/lib/zip_new.c [new file with mode: 0644]
ext/phar/lib/zip_open.c [new file with mode: 0644]
ext/phar/lib/zip_rename.c [new file with mode: 0644]
ext/phar/lib/zip_replace.c [new file with mode: 0644]
ext/phar/lib/zip_set_archive_comment.c [new file with mode: 0644]
ext/phar/lib/zip_set_file_comment.c [new file with mode: 0644]
ext/phar/lib/zip_set_name.c [new file with mode: 0644]
ext/phar/lib/zip_source_buffer.c [new file with mode: 0644]
ext/phar/lib/zip_source_file.c [new file with mode: 0644]
ext/phar/lib/zip_source_filep.c [new file with mode: 0644]
ext/phar/lib/zip_source_free.c [new file with mode: 0644]
ext/phar/lib/zip_source_function.c [new file with mode: 0644]
ext/phar/lib/zip_source_zip.c [new file with mode: 0644]
ext/phar/lib/zip_stat.c [new file with mode: 0644]
ext/phar/lib/zip_stat_index.c [new file with mode: 0644]
ext/phar/lib/zip_stat_init.c [new file with mode: 0644]
ext/phar/lib/zip_strerror.c [new file with mode: 0644]
ext/phar/lib/zip_unchange.c [new file with mode: 0644]
ext/phar/lib/zip_unchange_all.c [new file with mode: 0644]
ext/phar/lib/zip_unchange_archive.c [new file with mode: 0644]
ext/phar/lib/zip_unchange_data.c [new file with mode: 0644]
ext/phar/lib/zip_win32.h [new file with mode: 0644]
ext/phar/lib/zipint.h [new file with mode: 0644]
ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/tests/001.phpt

index 5597388efb331f9c52db775320b9fec373b42d51..5de8145b071b0cc396636cc8b60157776f752f5a 100644 (file)
@@ -2,10 +2,39 @@ dnl $Id$
 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)
index 8046b06d01182a2409539e565c94092cbff502e1..edf067a21beb1a13254e61c366a658212df91515 100644 (file)
@@ -5,6 +5,24 @@ ARG_ENABLE("phar", "enable phar support", "no");
 
 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);
diff --git a/ext/phar/lib/mkstemp.c b/ext/phar/lib/mkstemp.c
new file mode 100644 (file)
index 0000000..3ac587e
--- /dev/null
@@ -0,0 +1,136 @@
+/* $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*/
+}
diff --git a/ext/phar/lib/unistd.h b/ext/phar/lib/unistd.h
new file mode 100644 (file)
index 0000000..2ef435c
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
diff --git a/ext/phar/lib/zip.h b/ext/phar/lib/zip.h
new file mode 100644 (file)
index 0000000..de115d3
--- /dev/null
@@ -0,0 +1,210 @@
+#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 */
diff --git a/ext/phar/lib/zip_add.c b/ext/phar/lib/zip_add.c
new file mode 100644 (file)
index 0000000..535d6e4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_add_dir.c b/ext/phar/lib/zip_add_dir.c
new file mode 100644 (file)
index 0000000..957aaf1
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_close.c b/ext/phar/lib/zip_close.c
new file mode 100644 (file)
index 0000000..e701321
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_delete.c b/ext/phar/lib/zip_delete.c
new file mode 100644 (file)
index 0000000..7244e61
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+  $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
diff --git a/ext/phar/lib/zip_dirent.c b/ext/phar/lib/zip_dirent.c
new file mode 100644 (file)
index 0000000..8423ad5
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_entry_free.c b/ext/phar/lib/zip_entry_free.c
new file mode 100644 (file)
index 0000000..48443ce
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_entry_new.c b/ext/phar/lib/zip_entry_new.c
new file mode 100644 (file)
index 0000000..390b72a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_err_str.c b/ext/phar/lib/zip_err_str.c
new file mode 100644 (file)
index 0000000..c74538d
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+   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,
+};
diff --git a/ext/phar/lib/zip_error.c b/ext/phar/lib/zip_error.c
new file mode 100644 (file)
index 0000000..aec1638
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+  $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;
+    }
+}
diff --git a/ext/phar/lib/zip_error_clear.c b/ext/phar/lib/zip_error_clear.c
new file mode 100644 (file)
index 0000000..e3c81eb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_error_get.c b/ext/phar/lib/zip_error_get.c
new file mode 100644 (file)
index 0000000..712575a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_error_get_sys_type.c b/ext/phar/lib/zip_error_get_sys_type.c
new file mode 100644 (file)
index 0000000..613ec94
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+  $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];
+}
diff --git a/ext/phar/lib/zip_error_strerror.c b/ext/phar/lib/zip_error_strerror.c
new file mode 100644 (file)
index 0000000..e6eee08
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+  $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;
+    }
+}
diff --git a/ext/phar/lib/zip_error_to_str.c b/ext/phar/lib/zip_error_to_str.c
new file mode 100644 (file)
index 0000000..e566192
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+  $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 : ""));
+}
diff --git a/ext/phar/lib/zip_fclose.c b/ext/phar/lib/zip_fclose.c
new file mode 100644 (file)
index 0000000..c0105a9
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_file_error_clear.c b/ext/phar/lib/zip_file_error_clear.c
new file mode 100644 (file)
index 0000000..86ed68f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_file_error_get.c b/ext/phar/lib/zip_file_error_get.c
new file mode 100644 (file)
index 0000000..2ab3a73
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_file_get_offset.c b/ext/phar/lib/zip_file_get_offset.c
new file mode 100644 (file)
index 0000000..8bcc649
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_file_strerror.c b/ext/phar/lib/zip_file_strerror.c
new file mode 100644 (file)
index 0000000..aaff189
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_fopen.c b/ext/phar/lib/zip_fopen.c
new file mode 100644 (file)
index 0000000..850a8d8
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_fopen_index.c b/ext/phar/lib/zip_fopen_index.c
new file mode 100644 (file)
index 0000000..5da9230
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_fread.c b/ext/phar/lib/zip_fread.c
new file mode 100644 (file)
index 0000000..aeb64c9
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+  $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;
+       }
+    }
+}
diff --git a/ext/phar/lib/zip_free.c b/ext/phar/lib/zip_free.c
new file mode 100644 (file)
index 0000000..c78697d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_get_archive_comment.c b/ext/phar/lib/zip_get_archive_comment.c
new file mode 100644 (file)
index 0000000..7844c5e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_get_file_comment.c b/ext/phar/lib/zip_get_file_comment.c
new file mode 100644 (file)
index 0000000..79a5c23
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_get_name.c b/ext/phar/lib/zip_get_name.c
new file mode 100644 (file)
index 0000000..c45dd03
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_get_num_files.c b/ext/phar/lib/zip_get_num_files.c
new file mode 100644 (file)
index 0000000..0cc81ed
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_memdup.c b/ext/phar/lib/zip_memdup.c
new file mode 100644 (file)
index 0000000..c4ecf4a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_name_locate.c b/ext/phar/lib/zip_name_locate.c
new file mode 100644 (file)
index 0000000..a2fce2d
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_new.c b/ext/phar/lib/zip_new.c
new file mode 100644 (file)
index 0000000..660183a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_open.c b/ext/phar/lib/zip_open.c
new file mode 100644 (file)
index 0000000..60526e8
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_rename.c b/ext/phar/lib/zip_rename.c
new file mode 100644 (file)
index 0000000..f352918
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_replace.c b/ext/phar/lib/zip_replace.c
new file mode 100644 (file)
index 0000000..ae78e62
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_set_archive_comment.c b/ext/phar/lib/zip_set_archive_comment.c
new file mode 100644 (file)
index 0000000..b0929e5
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_set_file_comment.c b/ext/phar/lib/zip_set_file_comment.c
new file mode 100644 (file)
index 0000000..cbf71db
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_set_name.c b/ext/phar/lib/zip_set_name.c
new file mode 100644 (file)
index 0000000..46dca56
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_source_buffer.c b/ext/phar/lib/zip_source_buffer.c
new file mode 100644 (file)
index 0000000..a01f18d
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_source_file.c b/ext/phar/lib/zip_source_file.c
new file mode 100644 (file)
index 0000000..d635da3
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_source_filep.c b/ext/phar/lib/zip_source_filep.c
new file mode 100644 (file)
index 0000000..efc7026
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_source_free.c b/ext/phar/lib/zip_source_free.c
new file mode 100644 (file)
index 0000000..33e36ea
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_source_function.c b/ext/phar/lib/zip_source_function.c
new file mode 100644 (file)
index 0000000..4f01a43
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_source_zip.c b/ext/phar/lib/zip_source_zip.c
new file mode 100644 (file)
index 0000000..a31fd27
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_stat.c b/ext/phar/lib/zip_stat.c
new file mode 100644 (file)
index 0000000..bea153d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_stat_index.c b/ext/phar/lib/zip_stat_index.c
new file mode 100644 (file)
index 0000000..bab79a7
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_stat_init.c b/ext/phar/lib/zip_stat_init.c
new file mode 100644 (file)
index 0000000..7ab0f4d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_strerror.c b/ext/phar/lib/zip_strerror.c
new file mode 100644 (file)
index 0000000..83e2985
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+  $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);
+}
diff --git a/ext/phar/lib/zip_unchange.c b/ext/phar/lib/zip_unchange.c
new file mode 100644 (file)
index 0000000..34e7f2d
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_unchange_all.c b/ext/phar/lib/zip_unchange_all.c
new file mode 100644 (file)
index 0000000..f1e27da
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_unchange_archive.c b/ext/phar/lib/zip_unchange_archive.c
new file mode 100644 (file)
index 0000000..7418aaf
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+  $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;
+}
diff --git a/ext/phar/lib/zip_unchange_data.c b/ext/phar/lib/zip_unchange_data.c
new file mode 100644 (file)
index 0000000..2526769
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+  $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;
+}
+
diff --git a/ext/phar/lib/zip_win32.h b/ext/phar/lib/zip_win32.h
new file mode 100644 (file)
index 0000000..a33347b
--- /dev/null
@@ -0,0 +1,29 @@
+
+#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
diff --git a/ext/phar/lib/zipint.h b/ext/phar/lib/zipint.h
new file mode 100644 (file)
index 0000000..ebf2743
--- /dev/null
@@ -0,0 +1,226 @@
+#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 */
index 18c1be04f94d3784da5d9b2d6052d718ea9d5cc1..43e66b54c6f1506256f06659f0a9071e9988c9d4 100644 (file)
 
 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) /* {{{ */
@@ -206,7 +227,12 @@ static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
                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);
 }
 /* }}}*/
@@ -296,6 +322,12 @@ static void destroy_phar_manifest(void *pDest) /* {{{ */
                entry->metadata_str.c = 0;
        }
        efree(entry->filename);
+#if HAVE_PHAR_ZIP
+       if (entry->zip) {
+               zip_fclose(entry->zip);
+               entry->zip = 0;
+       }
+#endif
 }
 /* }}} */
 
@@ -392,13 +424,13 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
 
        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;
        }
@@ -407,6 +439,21 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
                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;
@@ -445,6 +492,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
                                /* 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;
@@ -461,11 +510,12 @@ typedef struct {
        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) {
@@ -538,13 +588,13 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char
        }
        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;
        }
@@ -552,6 +602,19 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char
                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));
@@ -560,6 +623,7 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char
        (*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) {
@@ -659,6 +723,15 @@ void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC) /* {{{ */
                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);
@@ -714,13 +787,43 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
        }
        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);
@@ -779,7 +882,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
 /**
  * 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
@@ -837,13 +940,17 @@ static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_l
  * 
  * 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);
@@ -881,6 +988,199 @@ static int phar_hex_str(const char *digest, size_t digest_len, char ** signature
        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.
  *
@@ -1217,10 +1517,10 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
        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);
@@ -1254,7 +1554,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
                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\"");
                }
@@ -1346,19 +1646,89 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
 }
 /* }}} */
 
+/* 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;
        }
@@ -1370,6 +1740,25 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
                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;
@@ -1500,7 +1889,8 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i
 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;
@@ -1523,6 +1913,14 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias,
                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);
@@ -1540,6 +1938,8 @@ int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ex
 {
        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");
 
@@ -1555,6 +1955,12 @@ int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ex
        } 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;
@@ -1863,9 +2269,38 @@ int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC)
                *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;
        }
@@ -2009,18 +2444,133 @@ static char * phar_decompress_filter(phar_entry_info * entry, int return_unknown
 /**
  * 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)) {
@@ -2067,7 +2617,6 @@ static phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info
                        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) {
@@ -2214,7 +2763,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat
 
        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);
@@ -2490,6 +3039,247 @@ static int phar_flush_clean_deleted_apply(void *data TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
+#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
  *
@@ -2522,6 +3312,11 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
                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;
@@ -3500,27 +4295,6 @@ PHAR_ADD_ENTRY:
 }
 /* }}}*/
 
-#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
  */
@@ -3896,13 +4670,24 @@ static void php_phar_init_globals_module(zend_phar_globals *phar_globals)
 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;
@@ -3916,13 +4701,11 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
                        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);
@@ -4075,6 +4858,15 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */
        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", 
index c3b0d42776449a1d39eb243e3d5cbabf57abf593..a39d7e93d58f837fc7388fc6c26fe24d3e2fe38e 100755 (executable)
 #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"
@@ -180,6 +184,12 @@ typedef struct _phar_entry_info {
        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) */
@@ -207,6 +217,11 @@ struct _phar_archive_data {
        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'
@@ -229,6 +244,7 @@ typedef struct _phar_entry_data {
        /* 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;
 
@@ -268,7 +284,9 @@ void phar_object_init(TSRMLS_D);
 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);
index 1efa016c18f17145ab023a40e2c3ba82d8598c9c..8f5be1c79e6d07029016ae7222438ec11867cd56 100755 (executable)
@@ -135,10 +135,15 @@ static int phar_file_action(phar_entry_data *phar, char *mime_type, int code, ch
 
                        /* 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 {
@@ -273,6 +278,32 @@ PHP_METHOD(Phar, webPhar)
 
        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);
@@ -1103,8 +1134,13 @@ PHP_METHOD(Phar, setAlias)
                }
 
                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);
@@ -1541,6 +1577,11 @@ PHP_METHOD(Phar, copy)
                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;
@@ -1552,7 +1593,7 @@ PHP_METHOD(Phar, copy)
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
        }
-       
+
        RETURN_TRUE;
 }
 
@@ -1694,6 +1735,15 @@ PHP_METHOD(Phar, offsetUnset)
                        }
                        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) {
@@ -1718,6 +1768,36 @@ PHP_METHOD(Phar, getStub)
        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) {
@@ -1747,7 +1827,7 @@ PHP_METHOD(Phar, getStub)
                php_stream_close(fp);
        }
        buf[len] = '\0';
-       
+
        RETURN_STRINGL(buf, len, 0);
 }
 /* }}}*/
@@ -1913,7 +1993,7 @@ PHP_METHOD(PharFileInfo, __destruct)
        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;
                }
@@ -2198,6 +2278,10 @@ PHP_METHOD(PharFileInfo, setCompressedBZIP2)
        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");
index 26c225deb035257f19380ea9b056ba282f220946..397501e8e40b2dacc62a8dbe3e5626fae84a7850 100644 (file)
@@ -8,5 +8,5 @@ var_dump(Phar::apiVersion());
 ?>
 ===DONE===
 --EXPECT--
-string(5) "1.2.0"
+string(5) "1.1.0"
 ===DONE===