summaryrefslogtreecommitdiff
path: root/ext/zip
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/zip
downloadphp2-c4dd7a1a684490673e25aaf4fabec5df138854c4.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/zip')
-rw-r--r--ext/zip/CREDITS2
-rw-r--r--ext/zip/TODO4
-rw-r--r--ext/zip/config.m4108
-rw-r--r--ext/zip/config.w3244
-rw-r--r--ext/zip/examples/comment.php6
-rw-r--r--ext/zip/examples/create.php23
-rw-r--r--ext/zip/examples/dir.php21
-rw-r--r--ext/zip/examples/extract.php28
-rw-r--r--ext/zip/examples/extractAll.php24
-rw-r--r--ext/zip/examples/fopen.php35
-rw-r--r--ext/zip/examples/get_set_comments.php38
-rw-r--r--ext/zip/examples/im.php11
-rw-r--r--ext/zip/examples/odt.php20
-rw-r--r--ext/zip/examples/oldapi.php17
-rw-r--r--ext/zip/examples/test.odtbin0 -> 6162 bytes
-rw-r--r--ext/zip/examples/test.zipbin0 -> 553 bytes
-rw-r--r--ext/zip/examples/test1.zipbin0 -> 681 bytes
-rw-r--r--ext/zip/examples/test_im.zipbin0 -> 1086 bytes
-rw-r--r--ext/zip/examples/test_with_comment.zipbin0 -> 560 bytes
-rw-r--r--ext/zip/examples/too.php2
-rw-r--r--ext/zip/lib/zip.h276
-rw-r--r--ext/zip/lib/zip_add.c56
-rw-r--r--ext/zip/lib/zip_add_dir.c88
-rw-r--r--ext/zip/lib/zip_close.c646
-rw-r--r--ext/zip/lib/zip_delete.c63
-rw-r--r--ext/zip/lib/zip_dirent.c614
-rw-r--r--ext/zip/lib/zip_entry_free.c55
-rw-r--r--ext/zip/lib/zip_entry_new.c81
-rw-r--r--ext/zip/lib/zip_err_str.c76
-rw-r--r--ext/zip/lib/zip_error.c112
-rw-r--r--ext/zip/lib/zip_error_clear.c44
-rw-r--r--ext/zip/lib/zip_error_get.c44
-rw-r--r--ext/zip/lib/zip_error_get_sys_type.c47
-rw-r--r--ext/zip/lib/zip_error_strerror.c90
-rw-r--r--ext/zip/lib/zip_error_to_str.c70
-rw-r--r--ext/zip/lib/zip_fclose.c64
-rw-r--r--ext/zip/lib/zip_fdopen.c62
-rw-r--r--ext/zip/lib/zip_file_error_clear.c44
-rw-r--r--ext/zip/lib/zip_file_error_get.c44
-rw-r--r--ext/zip/lib/zip_file_get_offset.c74
-rw-r--r--ext/zip/lib/zip_file_strerror.c44
-rw-r--r--ext/zip/lib/zip_filerange_crc.c71
-rw-r--r--ext/zip/lib/zip_fopen.c49
-rw-r--r--ext/zip/lib/zip_fopen_encrypted.c50
-rw-r--r--ext/zip/lib/zip_fopen_index.c48
-rw-r--r--ext/zip/lib/zip_fopen_index_encrypted.c191
-rw-r--r--ext/zip/lib/zip_fread.c65
-rw-r--r--ext/zip/lib/zip_free.c83
-rw-r--r--ext/zip/lib/zip_get_archive_comment.c60
-rw-r--r--ext/zip/lib/zip_get_archive_flag.c48
-rw-r--r--ext/zip/lib/zip_get_compression_implementation.c46
-rw-r--r--ext/zip/lib/zip_get_encryption_implementation.c46
-rw-r--r--ext/zip/lib/zip_get_file_comment.c58
-rw-r--r--ext/zip/lib/zip_get_file_extra.c58
-rw-r--r--ext/zip/lib/zip_get_name.c72
-rw-r--r--ext/zip/lib/zip_get_num_entries.c52
-rw-r--r--ext/zip/lib/zip_get_num_files.c47
-rw-r--r--ext/zip/lib/zip_memdup.c55
-rw-r--r--ext/zip/lib/zip_name_locate.c97
-rw-r--r--ext/zip/lib/zip_new.c71
-rw-r--r--ext/zip/lib/zip_open.c608
-rw-r--r--ext/zip/lib/zip_rename.c70
-rw-r--r--ext/zip/lib/zip_replace.c85
-rw-r--r--ext/zip/lib/zip_set_archive_comment.c70
-rw-r--r--ext/zip/lib/zip_set_archive_flag.c69
-rw-r--r--ext/zip/lib/zip_set_default_password.c62
-rw-r--r--ext/zip/lib/zip_set_file_comment.c72
-rw-r--r--ext/zip/lib/zip_set_file_extra.c72
-rw-r--r--ext/zip/lib/zip_set_name.c75
-rw-r--r--ext/zip/lib/zip_source_buffer.c163
-rw-r--r--ext/zip/lib/zip_source_close.c54
-rw-r--r--ext/zip/lib/zip_source_crc.c159
-rw-r--r--ext/zip/lib/zip_source_deflate.c394
-rw-r--r--ext/zip/lib/zip_source_error.c87
-rw-r--r--ext/zip/lib/zip_source_file.c56
-rw-r--r--ext/zip/lib/zip_source_filep.c247
-rw-r--r--ext/zip/lib/zip_source_free.c59
-rw-r--r--ext/zip/lib/zip_source_function.c78
-rw-r--r--ext/zip/lib/zip_source_layered.c59
-rw-r--r--ext/zip/lib/zip_source_open.c76
-rw-r--r--ext/zip/lib/zip_source_pkware.c241
-rw-r--r--ext/zip/lib/zip_source_pop.c63
-rw-r--r--ext/zip/lib/zip_source_read.c64
-rw-r--r--ext/zip/lib/zip_source_stat.c72
-rw-r--r--ext/zip/lib/zip_source_zip.c190
-rw-r--r--ext/zip/lib/zip_stat.c49
-rw-r--r--ext/zip/lib/zip_stat_index.c94
-rw-r--r--ext/zip/lib/zip_stat_init.c52
-rw-r--r--ext/zip/lib/zip_strerror.c43
-rw-r--r--ext/zip/lib/zip_unchange.c85
-rw-r--r--ext/zip/lib/zip_unchange_all.c54
-rw-r--r--ext/zip/lib/zip_unchange_archive.c52
-rw-r--r--ext/zip/lib/zip_unchange_data.c52
-rw-r--r--ext/zip/lib/zip_win32.h31
-rw-r--r--ext/zip/lib/zipconf.h51
-rw-r--r--ext/zip/lib/zipint.h344
-rw-r--r--ext/zip/php_zip.c2884
-rw-r--r--ext/zip/php_zip.h99
-rw-r--r--ext/zip/tests/001.phpt12
-rw-r--r--ext/zip/tests/binarynull.zipbin0 -> 656 bytes
-rw-r--r--ext/zip/tests/bug11216.phpt28
-rw-r--r--ext/zip/tests/bug14962.phpt34
-rw-r--r--ext/zip/tests/bug38943.phpt50
-rw-r--r--ext/zip/tests/bug38944.phpt40
-rw-r--r--ext/zip/tests/bug40228.phpt23
-rw-r--r--ext/zip/tests/bug40228.zipbin0 -> 274 bytes
-rw-r--r--ext/zip/tests/bug47667.phpt41
-rw-r--r--ext/zip/tests/bug49072.phpt24
-rw-r--r--ext/zip/tests/bug49072.zipbin0 -> 162657 bytes
-rw-r--r--ext/zip/tests/bug51353.phpt54
-rw-r--r--ext/zip/tests/bug53579.phpt44
-rw-r--r--ext/zip/tests/bug53603.phpt35
-rw-r--r--ext/zip/tests/bug53854.phpt44
-rw-r--r--ext/zip/tests/bug53885.phpt24
-rw-r--r--ext/zip/tests/bug7214.phpt23
-rw-r--r--ext/zip/tests/bug7658.odtbin0 -> 8873 bytes
-rw-r--r--ext/zip/tests/bug7658.phpt55
-rw-r--r--ext/zip/tests/bug7658.xml2
-rw-r--r--ext/zip/tests/bug8009.phpt27
-rw-r--r--ext/zip/tests/bug8009.zipbin0 -> 112 bytes
-rw-r--r--ext/zip/tests/bug8700.phpt30
-rw-r--r--ext/zip/tests/oo_addemptydir.phpt36
-rw-r--r--ext/zip/tests/oo_addfile.phpt37
-rw-r--r--ext/zip/tests/oo_close.phpt25
-rw-r--r--ext/zip/tests/oo_delete.phpt81
-rw-r--r--ext/zip/tests/oo_ext_zip.phpt27
-rw-r--r--ext/zip/tests/oo_extract.phpt95
-rw-r--r--ext/zip/tests/oo_getcomment.phpt36
-rw-r--r--ext/zip/tests/oo_getnameindex.phpt47
-rw-r--r--ext/zip/tests/oo_getstatusstring.phpt28
-rw-r--r--ext/zip/tests/oo_namelocate.phpt46
-rw-r--r--ext/zip/tests/oo_open.phpt46
-rw-r--r--ext/zip/tests/oo_properties.phpt60
-rw-r--r--ext/zip/tests/oo_rename.phpt58
-rw-r--r--ext/zip/tests/oo_setcomment.phpt71
-rw-r--r--ext/zip/tests/oo_stream.phpt50
-rw-r--r--ext/zip/tests/pecl12414.phpt38
-rw-r--r--ext/zip/tests/pecl12414.zipbin0 -> 17271 bytes
-rw-r--r--ext/zip/tests/stream_meta_data.phpt74
-rw-r--r--ext/zip/tests/test.zipbin0 -> 526 bytes
-rw-r--r--ext/zip/tests/test_procedural.zipbin0 -> 541 bytes
-rw-r--r--ext/zip/tests/test_with_comment.zipbin0 -> 571 bytes
-rw-r--r--ext/zip/tests/utils.inc24
-rw-r--r--ext/zip/tests/zip_close.phpt17
-rw-r--r--ext/zip/tests/zip_entry_compressedsize.phpt23
-rw-r--r--ext/zip/tests/zip_entry_compressionmethod.phpt24
-rw-r--r--ext/zip/tests/zip_entry_filesize.phpt23
-rw-r--r--ext/zip/tests/zip_entry_name.phpt23
-rw-r--r--ext/zip/tests/zip_entry_open.phpt18
-rw-r--r--ext/zip/tests/zip_entry_read.phpt19
-rw-r--r--ext/zip/tests/zip_open.phpt16
-rw-r--r--ext/zip/tests/zip_open_error.phpt28
-rw-r--r--ext/zip/tests/zip_read.phpt21
-rw-r--r--ext/zip/zip_stream.c338
154 files changed, 13498 insertions, 0 deletions
diff --git a/ext/zip/CREDITS b/ext/zip/CREDITS
new file mode 100644
index 0000000..6c7e42d
--- /dev/null
+++ b/ext/zip/CREDITS
@@ -0,0 +1,2 @@
+Zip
+Pierre-Alain Joye
diff --git a/ext/zip/TODO b/ext/zip/TODO
new file mode 100644
index 0000000..c1baba9
--- /dev/null
+++ b/ext/zip/TODO
@@ -0,0 +1,4 @@
+- add pattern support to extract or add files
+- stream to add or modify entries
+- crypt support for zip (read and write)
+- Iterators
diff --git a/ext/zip/config.m4 b/ext/zip/config.m4
new file mode 100644
index 0000000..85f9119
--- /dev/null
+++ b/ext/zip/config.m4
@@ -0,0 +1,108 @@
+dnl
+dnl $Id$
+dnl
+
+PHP_ARG_ENABLE(zip, for zip archive read/writesupport,
+[ --enable-zip Include Zip read/write support])
+
+if test -z "$PHP_ZLIB_DIR"; then
+ PHP_ARG_WITH(zlib-dir, for the location of libz,
+ [ --with-zlib-dir[=DIR] ZIP: Set the path to libz install prefix], no, no)
+fi
+
+PHP_ARG_WITH(pcre-dir, pcre install prefix,
+[ --with-pcre-dir ZIP: pcre install prefix], no, no)
+
+if test "$PHP_ZIP" != "no"; then
+
+ if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then
+ if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then
+ PHP_ZLIB_DIR="$PHP_ZLIB_DIR"
+ PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include/zlib"
+ elif test -f "$PHP_ZLIB_DIR/include/zlib.h"; then
+ PHP_ZLIB_DIR="$PHP_ZLIB_DIR"
+ PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include"
+ else
+ AC_MSG_ERROR([Can not find zlib headers under "$PHP_ZLIB_DIR"])
+ fi
+ else
+ for i in /usr/local /usr; do
+ if test -f "$i/include/zlib/zlib.h"; then
+ PHP_ZLIB_DIR="$i"
+ PHP_ZLIB_INCDIR="$i/include/zlib"
+ elif test -f "$i/include/zlib.h"; then
+ PHP_ZLIB_DIR="$i"
+ PHP_ZLIB_INCDIR="$i/include"
+ fi
+ done
+ fi
+
+ dnl # zlib
+ AC_MSG_CHECKING([for the location of zlib])
+ if test "$PHP_ZLIB_DIR" = "no"; then
+ AC_MSG_ERROR([zip support requires ZLIB. Use --with-zlib-dir=<DIR> to specify prefix where ZLIB include and library are located])
+ else
+ AC_MSG_RESULT([$PHP_ZLIB_DIR])
+ PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR/$PHP_LIBDIR, ZIP_SHARED_LIBADD)
+ PHP_ADD_INCLUDE($PHP_ZLIB_INCDIR)
+ fi
+
+ dnl This is PECL build, check if bundled PCRE library is used
+ old_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS=$INCLUDES
+ AC_EGREP_CPP(yes,[
+#include <main/php_config.h>
+#if defined(HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
+yes
+#endif
+ ],[
+ PHP_PCRE_REGEX=yes
+ ],[
+ AC_EGREP_CPP(yes,[
+#include <main/php_config.h>
+#if defined(HAVE_PCRE) && !defined(COMPILE_DL_PCRE)
+yes
+#endif
+ ],[
+ PHP_PCRE_REGEX=pecl
+ ],[
+ PHP_PCRE_REGEX=no
+ ])
+ ])
+ CPPFLAGS=$old_CPPFLAGS
+
+ PHP_ZIP_SOURCES="$PHP_ZIP_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_filerange_crc.c lib/zip_file_strerror.c lib/zip_get_num_files.c \
+ lib/zip_get_archive_flag.c lib/zip_set_archive_flag.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_get_archive_comment.c lib/zip_get_file_comment.c \
+ lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.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 \
+ lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \
+ lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \
+ lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \
+ lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \
+ lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \
+ lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \
+ lib/zip_source_read.c lib/zip_source_stat.c"
+
+ AC_DEFINE(HAVE_ZIP,1,[ ])
+ PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared)
+ PHP_ADD_BUILD_DIR($ext_builddir/lib, 1)
+ PHP_SUBST(ZIP_SHARED_LIBADD)
+
+ dnl so we always include the known-good working hack.
+ PHP_ADD_MAKEFILE_FRAGMENT
+fi
diff --git a/ext/zip/config.w32 b/ext/zip/config.w32
new file mode 100644
index 0000000..fa0a518
--- /dev/null
+++ b/ext/zip/config.w32
@@ -0,0 +1,44 @@
+// $Id$
+// vim:ft=javascript
+
+ARG_ENABLE("zip", "ZIP support", "yes");
+
+if (PHP_ZIP != "no") {
+ if (CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS_ZIP", "..\\zlib;" + PHP_ZIP) &&
+ (((PHP_ZLIB=="no") && (CHECK_LIB("zlib_a.lib", "zip", PHP_ZIP) || CHECK_LIB("zlib.lib", "zip", PHP_ZIP))) ||
+ (PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "zip", PHP_ZIP)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED)))
+ ) {
+ EXTENSION('zip', 'php_zip.c zip_stream.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_filerange_crc.c zip_file_strerror.c zip_get_num_files.c \
+ zip_get_archive_flag.c zip_set_archive_flag.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 \
+ zip_fdopen.c zip_fopen_encrypted.c zip_fopen_index_encrypted.c \
+ zip_get_compression_implementation.c zip_get_encryption_implementation.c \
+ zip_get_file_extra.c zip_get_num_entries.c zip_set_default_password.c \
+ zip_set_file_extra.c zip_source_close.c zip_source_crc.c \
+ zip_source_deflate.c zip_source_error.c zip_source_layered.c \
+ zip_source_open.c zip_source_pkware.c zip_source_pop.c \
+ zip_source_read.c zip_source_stat.c", "zip");
+
+ AC_DEFINE('HAVE_ZIP', 1);
+ } else {
+ WARNING("zip not enabled; libraries and headers not found");
+ }
+}
+
diff --git a/ext/zip/examples/comment.php b/ext/zip/examples/comment.php
new file mode 100644
index 0000000..90b37d3
--- /dev/null
+++ b/ext/zip/examples/comment.php
@@ -0,0 +1,6 @@
+<?php
+$z = new ZipArchive;
+$z->open('test_with_comment.zip');
+// Add "Foo Comment" as comment for the foo entry
+$z->setCommentName('foo', 'Too Comment ' . time());
+$z->close();
diff --git a/ext/zip/examples/create.php b/ext/zip/examples/create.php
new file mode 100644
index 0000000..a41c8e6
--- /dev/null
+++ b/ext/zip/examples/create.php
@@ -0,0 +1,23 @@
+<?php
+error_reporting(E_ALL);
+if (!extension_loaded('zip')) {
+ dl('zip.so');
+}
+$thisdir = dirname(__FILE__);
+unlink("./test112.zip");
+$zip = new ZipArchive();
+$filename = "./test112.zip";
+
+if (!$zip->open($filename, ZIPARCHIVE::CREATE)) {
+ exit("cannot open <$filename>\n");
+} else {
+ echo "file <$filename> OK\n";
+}
+
+$zip->addFromString("testfilephp.txt" . time(), "#1 This is a test string added as testfilephp.txt.\n");
+$zip->addFromString("testfilephp2.txt" . time(), "#2 This is a test string added as testfilephp2.txt.\n");
+$zip->addFile($thisdir . "/too.php","/testfromfile.php");
+echo "numfiles: " . $zip->numFiles . "\n";
+echo "status:" . $zip->status . "\n";
+$zip->close();
+unset($zip);
diff --git a/ext/zip/examples/dir.php b/ext/zip/examples/dir.php
new file mode 100644
index 0000000..c362a72
--- /dev/null
+++ b/ext/zip/examples/dir.php
@@ -0,0 +1,21 @@
+<?php
+if (!extension_loaded('zip')) {
+ dl('zip.so');
+}
+
+$za = new ZipArchive();
+
+$za->open('test_with_comment.zip');
+print_r($za);
+var_dump($za);
+echo "numFiles: " . $za->numFiles . "\n";
+echo "status: " . $za->status . "\n";
+echo "statusSys: " . $za->statusSys . "\n";
+echo "filename: " . $za->filename . "\n";
+echo "comment: " . $za->comment . "\n";
+
+for ($i=0; $i<$za->numFiles;$i++) {
+ echo "index: $i\n";
+ print_r($za->statIndex($i));
+}
+echo "numFile:" . $za->numFiles . "\n";
diff --git a/ext/zip/examples/extract.php b/ext/zip/examples/extract.php
new file mode 100644
index 0000000..5276b0d
--- /dev/null
+++ b/ext/zip/examples/extract.php
@@ -0,0 +1,28 @@
+<?php
+if (!extension_loaded('zip')) {
+ dl('zip.so');
+}
+
+$zip = new ZipArchive();
+
+echo $zip->filename . "\n";
+$zip->open("test.zip");
+/*
+$zip->addFile("./modules/");
+$zip->addFile("./testempty");
+*/
+echo $zip->status . "\n";
+echo $zip->statusSys . "\n";
+
+echo $zip->numFiles . "\n";
+echo $zip->filename . "\n";
+var_dump($zip);
+$files = array('test', 'testdir/test2');
+if (!$zip->extractTo("./testext/path/to", $files)) {
+ echo "error!\n";
+ echo $zip->status . "\n";
+ echo $zip->statusSys . "\n";
+
+}
+
+$zip->close();
diff --git a/ext/zip/examples/extractAll.php b/ext/zip/examples/extractAll.php
new file mode 100644
index 0000000..d318a45
--- /dev/null
+++ b/ext/zip/examples/extractAll.php
@@ -0,0 +1,24 @@
+<?php
+$zip = new ZipArchive();
+
+echo $zip->filename . "\n";
+$zip->open("test.zip");
+/*
+$zip->addFile("./modules/");
+$zip->addFile("./testempty");
+*/
+echo $zip->status . "\n";
+echo $zip->statusSys . "\n";
+
+echo $zip->numFiles . "\n";
+echo $zip->filename . "\n";
+var_dump($zip);
+$files = array('test', 'testdir/test2');
+if (!$zip->extractTo("./testext/path/to")) {
+ echo "error!\n";
+ echo $zip->status . "\n";
+ echo $zip->statusSys . "\n";
+
+}
+
+$zip->close();
diff --git a/ext/zip/examples/fopen.php b/ext/zip/examples/fopen.php
new file mode 100644
index 0000000..32357f3
--- /dev/null
+++ b/ext/zip/examples/fopen.php
@@ -0,0 +1,35 @@
+<?php
+if (!extension_loaded('zip')) {
+ dl('zip.so');
+}
+
+
+$fp = fopen('zip://' . dirname(__FILE__) . '/test.zip#test', 'r');
+if (!$fp) {
+ exit("cannot open\n");
+}
+while (!feof($fp)) {
+ $contents .= fread($fp, 2);
+ echo "$contents\n";
+}
+
+fclose($fp);
+echo "done.\n";
+
+
+$content = '';
+$z = new ZipArchive();
+$z->open(dirname(__FILE__) . '/test.zip');
+$fp = $z->getStream('test');
+
+var_dump($fp);
+if(!$fp) exit("\n");
+while (!feof($fp)) {
+ $contents .= fread($fp, 2);
+}
+
+fclose($fp);
+file_put_contents('t',$contents);
+echo "done.\n";
+
+
diff --git a/ext/zip/examples/get_set_comments.php b/ext/zip/examples/get_set_comments.php
new file mode 100644
index 0000000..5bd302e
--- /dev/null
+++ b/ext/zip/examples/get_set_comments.php
@@ -0,0 +1,38 @@
+<?php
+error_reporting(E_ALL|E_STRICT);
+
+copy('test_with_comment.zip', 't.zip');
+$z = new ZipArchive;
+$z->open('t.zip');
+
+print_r($z);
+
+for ($i=0; $i<$z->numFiles; $i++) {
+ echo "index: $i\n";
+ print_r($z->getCommentIndex($i));
+ echo "\n\n";
+}
+echo "foobar/ " . $z->getCommentName('foobar/') . "\n";
+
+echo "Archive comment: " . $z->getArchiveComment() . "\n";
+
+
+$z->setCommentIndex(1, 'new comment idx 1');
+$z->setCommentName('foobar/', 'new comment foobar/');
+
+$z->setArchiveComment( 'new archive comment');
+
+for ($i=0; $i<$z->numFiles; $i++) {
+ echo "index: $i\n";
+ print_r($z->getCommentIndex($i));
+ echo "\n\n";
+}
+
+echo $z->getCommentName('foobar/') . "\n";
+
+// Get the original comment
+echo $z->getCommentName('foobar/', ZIPARCHIVE::FL_UNCHANGED) . "\n";
+
+echo "Archive comment: " . $z->getArchiveComment() . "\n";
+echo "Archive comment (original): " . $z->getArchiveComment(ZIPARCHIVE::FL_UNCHANGED) . "\n";
+
diff --git a/ext/zip/examples/im.php b/ext/zip/examples/im.php
new file mode 100644
index 0000000..3721434
--- /dev/null
+++ b/ext/zip/examples/im.php
@@ -0,0 +1,11 @@
+<?php
+/* $Id$ */
+$im = imagecreatefromgif('zip://' . dirname(__FILE__) . '/test_im.zip#pear_item.gif');
+imagepng($im, 'a.png');
+
+$z = new ZipArchive();
+$z->open(dirname(__FILE__) . '/test_im.zip');
+$im_string = $z->getFromName("pear_item.gif");
+$im = imagecreatefromstring($im_string);
+imagepng($im, 'b.png');
+
diff --git a/ext/zip/examples/odt.php b/ext/zip/examples/odt.php
new file mode 100644
index 0000000..c829f12
--- /dev/null
+++ b/ext/zip/examples/odt.php
@@ -0,0 +1,20 @@
+<?php
+/* $Id$ */
+$reader = new XMLReader();
+
+$reader->open('zip://' . dirname(__FILE__) . '/test.odt#meta.xml');
+$odt_meta = array();
+while ($reader->read()) {
+ if ($reader->nodeType == XMLREADER::ELEMENT) {
+ $elm = $reader->name;
+ } else {
+ if ($reader->nodeType == XMLREADER::END_ELEMENT && $reader->name == 'office:meta') {
+ break;
+ }
+ if (!trim($reader->value)) {
+ continue;
+ }
+ $odt_meta[$elm] = $reader->value;
+ }
+}
+print_r($odt_meta);
diff --git a/ext/zip/examples/oldapi.php b/ext/zip/examples/oldapi.php
new file mode 100644
index 0000000..2f17f43
--- /dev/null
+++ b/ext/zip/examples/oldapi.php
@@ -0,0 +1,17 @@
+<?php
+
+$zip = zip_open('examples/test1.zip');
+var_dump($zip);
+
+if ($zip) {
+ $i = 0;
+ while ($zip_entry = zip_read($zip)) {
+ var_dump($zip_entry);
+ $txt = zip_entry_read($zip_entry, 10);
+ echo $i . ": " . $txt . "size: " . zip_entry_filesize($zip_entry) .
+ "comp_method: " . zip_entry_compressionmethod($zip_entry) .
+ "\n";
+ $i++;
+ }
+ var_dump($zip_entry);
+}
diff --git a/ext/zip/examples/test.odt b/ext/zip/examples/test.odt
new file mode 100644
index 0000000..6a816ad
--- /dev/null
+++ b/ext/zip/examples/test.odt
Binary files differ
diff --git a/ext/zip/examples/test.zip b/ext/zip/examples/test.zip
new file mode 100644
index 0000000..a6a2e62
--- /dev/null
+++ b/ext/zip/examples/test.zip
Binary files differ
diff --git a/ext/zip/examples/test1.zip b/ext/zip/examples/test1.zip
new file mode 100644
index 0000000..a4deb13
--- /dev/null
+++ b/ext/zip/examples/test1.zip
Binary files differ
diff --git a/ext/zip/examples/test_im.zip b/ext/zip/examples/test_im.zip
new file mode 100644
index 0000000..6385ee9
--- /dev/null
+++ b/ext/zip/examples/test_im.zip
Binary files differ
diff --git a/ext/zip/examples/test_with_comment.zip b/ext/zip/examples/test_with_comment.zip
new file mode 100644
index 0000000..cc65375
--- /dev/null
+++ b/ext/zip/examples/test_with_comment.zip
Binary files differ
diff --git a/ext/zip/examples/too.php b/ext/zip/examples/too.php
new file mode 100644
index 0000000..6d21008
--- /dev/null
+++ b/ext/zip/examples/too.php
@@ -0,0 +1,2 @@
+<?php
+echo "too";
diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h
new file mode 100644
index 0000000..f11c9ab
--- /dev/null
+++ b/ext/zip/lib/zip.h
@@ -0,0 +1,276 @@
+#ifndef _HAD_ZIP_H
+#define _HAD_ZIP_H
+
+/*
+ zip.h -- exported declarations.
+ Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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.h"
+
+#ifdef PHP_WIN32
+# include "zip_win32.h"
+# ifdef PHP_ZIP_EXPORTS
+# define ZIP_EXTERN(rt) __declspec(dllexport)rt _stdcall
+# else
+# define ZIP_EXTERN(rt) rt
+# endif
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define ZIP_EXTERN(rt) __attribute__ ((visibility("default"))) rt
+#else
+# define ZIP_EXTERN(rt) rt
+#endif
+
+BEGIN_EXTERN_C()
+
+#include "zipconf.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <time.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 */
+#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */
+#define ZIP_FL_ENCRYPTED 32 /* read encrypted data
+ (implies ZIP_FL_COMPRESSED) */
+
+/* archive global flags flags */
+
+#define ZIP_AFL_TORRENT 1 /* torrent zipped */
+#define ZIP_AFL_RDONLY 2 /* read only -- cannot be cleared */
+
+
+/* flags for compression and encryption sources */
+
+#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */
+
+
+/* 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 */
+#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
+#define ZIP_ER_RDONLY 25 /* N Read-only archive */
+#define ZIP_ER_NOPASSWD 26 /* N No password provided */
+#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */
+
+/* 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 */
+/* 13 - Reserved by PKWARE */
+#define ZIP_CM_LZMA 14 /* LZMA (EFS) */
+/* 15-17 - Reserved by PKWARE */
+#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
+#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
+#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
+#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */
+
+/* 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 */
+
+
+
+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 */
+};
+
+#define ZIP_SOURCE_ERR_LOWER -2
+
+#define ZIP_STAT_NAME 0x0001
+#define ZIP_STAT_INDEX 0x0002
+#define ZIP_STAT_SIZE 0x0004
+#define ZIP_STAT_COMP_SIZE 0x0008
+#define ZIP_STAT_MTIME 0x0010
+#define ZIP_STAT_CRC 0x0020
+#define ZIP_STAT_COMP_METHOD 0x0040
+#define ZIP_STAT_ENCRYPTION_METHOD 0x0080
+#define ZIP_STAT_FLAGS 0x0100
+
+struct zip_stat {
+ zip_uint64_t valid; /* which fields have valid values */
+ const char *name; /* name of the file */
+ zip_uint64_t index; /* index within archive */
+ zip_uint64_t size; /* size of file (uncompressed) */
+ zip_uint64_t comp_size; /* size of file (compressed) */
+ time_t mtime; /* modification time */
+ zip_uint32_t crc; /* crc of file data */
+ zip_uint16_t comp_method; /* compression method used */
+ zip_uint16_t encryption_method; /* encryption method used */
+ zip_uint32_t flags; /* reserved for future use */
+};
+
+struct zip;
+struct zip_file;
+struct zip_source;
+
+typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t,
+ enum zip_source_cmd);
+
+
+
+ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *);
+ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *);
+ZIP_EXTERN(int) zip_close(struct zip *);
+ZIP_EXTERN(int) zip_delete(struct zip *, zip_uint64_t);
+ZIP_EXTERN(void) zip_error_clear(struct zip *);
+ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *);
+ZIP_EXTERN(int) zip_error_get_sys_type(int);
+ZIP_EXTERN(int) zip_error_to_str(char *, zip_uint64_t, int, int);
+ZIP_EXTERN(int) zip_fclose(struct zip_file *);
+ZIP_EXTERN(struct zip *)zip_fdopen(int, int, int *);
+ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *);
+ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *);
+ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *);
+ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int);
+ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *,
+ int, const char *);
+ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, zip_uint64_t, int);
+ZIP_EXTERN(struct zip_file *)zip_fopen_index_encrypted(struct zip *,
+ zip_uint64_t, int,
+ const char *);
+ZIP_EXTERN(zip_int64_t) zip_fread(struct zip_file *, void *, zip_uint64_t);
+ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int);
+ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int);
+ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t,
+ int *, int);
+ZIP_EXTERN(const char *)zip_get_file_extra(struct zip *, zip_uint64_t,
+ int *, int);
+ZIP_EXTERN(const char *)zip_get_name(struct zip *, zip_uint64_t, int);
+ZIP_EXTERN(zip_uint64_t) zip_get_num_entries(struct zip *, int);
+ZIP_EXTERN(int) zip_get_num_files(struct zip *); /* deprecated, use zip_get_num_entries instead */
+ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int);
+ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *);
+ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *);
+ZIP_EXTERN(int) zip_replace(struct zip *, zip_uint64_t, struct zip_source *);
+ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int);
+ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int);
+ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *);
+ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t,
+ const char *, int);
+ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t,
+ const char *, int);
+ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *,
+ zip_uint64_t, int);
+ZIP_EXTERN(struct) zip_source *zip_source_file(struct zip *, const char *,
+ zip_uint64_t, zip_int64_t);
+ZIP_EXTERN(struct) zip_source *zip_source_filep(struct zip *, FILE *,
+ zip_uint64_t, zip_int64_t);
+ZIP_EXTERN(void) zip_source_free(struct zip_source *);
+ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *,
+ zip_source_callback, void *);
+ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *,
+ zip_uint64_t, int,
+ zip_uint64_t, zip_int64_t);
+ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *);
+ZIP_EXTERN(int) zip_stat_index(struct zip *, zip_uint64_t, int,
+ struct zip_stat *);
+ZIP_EXTERN(void) zip_stat_init(struct zip_stat *);
+ZIP_EXTERN(const char *)zip_strerror(struct zip *);
+ZIP_EXTERN(int) zip_unchange(struct zip *, zip_uint64_t);
+ZIP_EXTERN(int) zip_unchange_all(struct zip *);
+ZIP_EXTERN(int) zip_unchange_archive(struct zip *);
+
+END_EXTERN_C();
+#endif /* _HAD_ZIP_H */
diff --git a/ext/zip/lib/zip_add.c b/ext/zip/lib/zip_add.c
new file mode 100644
index 0000000..6067abb
--- /dev/null
+++ b/ext/zip/lib/zip_add.c
@@ -0,0 +1,56 @@
+/*
+ zip_add.c -- add file via callback function
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+/*
+ NOTE: Return type is signed so we can return -1 on error.
+ The index can not be larger than ZIP_INT64_MAX since the size
+ of the central directory cannot be larger than
+ ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
+*/
+
+ZIP_EXTERN(zip_int64_t)
+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, ZIP_UINT64_MAX, name, source);
+}
diff --git a/ext/zip/lib/zip_add_dir.c b/ext/zip/lib/zip_add_dir.c
new file mode 100644
index 0000000..0a9d7f4
--- /dev/null
+++ b/ext/zip/lib/zip_add_dir.c
@@ -0,0 +1,88 @@
+/*
+ zip_add_dir.c -- add directory
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
+
+ZIP_EXTERN(zip_int64_t)
+zip_add_dir(struct zip *za, const char *name)
+{
+ int len;
+ zip_int64_t ret;
+ char *s;
+ struct zip_source *source;
+
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ 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/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c
new file mode 100644
index 0000000..362f92d
--- /dev/null
+++ b/ext/zip/lib/zip_close.c
@@ -0,0 +1,646 @@
+/*
+ zip_close.c -- close zip archive and update changes
+ Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef PHP_WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+static int add_data(struct zip *, struct zip_source *, struct zip_dirent *,
+ FILE *);
+static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
+static int copy_source(struct zip *, struct zip_source *, FILE *);
+static int write_cdir(struct zip *, struct zip_cdir *, FILE *);
+static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
+static char *_zip_create_temp_output(struct zip *, FILE **);
+static int _zip_torrentzip_cmp(const void *, const void *);
+
+
+
+struct filelist {
+ int idx;
+ const char *name;
+};
+
+
+
+ZIP_EXTERN(int)
+zip_close(struct zip *za)
+{
+ int survivors;
+ int i, j, error;
+ char *temp;
+ FILE *out;
+#ifndef PHP_WIN32
+ mode_t mask;
+#endif
+ struct zip_cdir *cd;
+ struct zip_dirent de;
+ struct filelist *filelist;
+ int reopen_on_error;
+ int new_torrentzip;
+
+ reopen_on_error = 0;
+
+ if (za == NULL)
+ return -1;
+
+ if (!_zip_changed(za, &survivors)) {
+ _zip_free(za);
+ return 0;
+ }
+
+ /* don't create zip files with no entries */
+ if (survivors == 0) {
+ if (za->zn && za->zp) {
+ if (remove(za->zn) != 0) {
+ _zip_error_set(&za->error, ZIP_ER_REMOVE, errno);
+ return -1;
+ }
+ }
+ _zip_free(za);
+ return 0;
+ }
+
+ if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors))
+ == NULL)
+ return -1;
+
+ if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) {
+ free(filelist);
+ return -1;
+ }
+
+ for (i=0; i<survivors; i++)
+ _zip_dirent_init(&cd->entry[i]);
+
+ /* archive comment is special for torrentzip */
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) {
+ cd->comment = _zip_memdup(TORRENT_SIG "XXXXXXXX",
+ TORRENT_SIG_LEN + TORRENT_CRC_LEN,
+ &za->error);
+ if (cd->comment == NULL) {
+ _zip_cdir_free(cd);
+ free(filelist);
+ return -1;
+ }
+ cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN;
+ }
+ else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) {
+ if (_zip_cdir_set_comment(cd, za) == -1) {
+ _zip_cdir_free(cd);
+ free(filelist);
+ return -1;
+ }
+ }
+
+ if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
+ _zip_cdir_free(cd);
+ free(filelist);
+ return -1;
+ }
+
+
+ /* create list of files with index into original archive */
+ for (i=j=0; i<za->nentry; i++) {
+ if (za->entry[i].state == ZIP_ST_DELETED)
+ continue;
+
+ filelist[j].idx = i;
+ filelist[j].name = zip_get_name(za, i, 0);
+ j++;
+ }
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
+ qsort(filelist, survivors, sizeof(filelist[0]),
+ _zip_torrentzip_cmp);
+
+ new_torrentzip = (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 1
+ && zip_get_archive_flag(za, ZIP_AFL_TORRENT,
+ ZIP_FL_UNCHANGED) == 0);
+ error = 0;
+ for (j=0; j<survivors; j++) {
+ i = filelist[j].idx;
+
+ /* create new local directory entry */
+ if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) {
+ _zip_dirent_init(&de);
+
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
+ _zip_dirent_torrent_normalize(&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_ADDED) {
+ de.filename = strdup("-");
+ de.filename_len = 1;
+ cd->entry[j].filename = "-";
+ cd->entry[j].filename_len = 1;
+ }
+ else {
+ 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 {
+ /* copy existing directory entries */
+ if (fseeko(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, NULL, 1,
+ &za->error) != 0) {
+ error = 1;
+ break;
+ }
+ memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
+ if (de.bitflags & ZIP_GPBF_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;
+ de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
+ cd->entry[j].bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
+ }
+ }
+
+ 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_extra_len != -1) {
+ free(de.extrafield);
+ if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) {
+ error = 1;
+ break;
+ }
+ memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len);
+ de.extrafield_len = za->entry[i].ch_extra_len;
+ /* as the rest of cd entries, its malloc/free is done by za */
+ /* TODO unsure if this should also be set in the CD --
+ * not done for now
+ cd->entry[j].extrafield = za->entry[i].ch_extra;
+ cd->entry[j].extrafield_len = za->entry[i].ch_extra_len;
+ */
+ }
+
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0
+ && 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 = ftello(out);
+
+ if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) {
+ struct zip_source *zs;
+
+ zs = NULL;
+ if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
+ if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1))
+ == NULL) {
+ error = 1;
+ break;
+ }
+ }
+
+ if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) {
+ error = 1;
+ if (zs)
+ zip_source_free(zs);
+ break;
+ }
+ if (zs)
+ zip_source_free(zs);
+
+ 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, cd->entry[j].comp_size, out,
+ &za->error) < 0) {
+ error = 1;
+ break;
+ }
+ }
+
+ _zip_dirent_finalize(&de);
+ }
+
+ free(filelist);
+
+ if (!error) {
+ if (write_cdir(za, cd, out) < 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;
+ reopen_on_error = 1;
+ }
+ if (_zip_rename(temp, za->zn) != 0) {
+ _zip_error_set(&za->error, ZIP_ER_RENAME, errno);
+ remove(temp);
+ free(temp);
+ if (reopen_on_error) {
+ /* ignore errors, since we're already in an error case */
+ za->zp = fopen(za->zn, "rb");
+ }
+ return -1;
+ }
+#ifndef PHP_WIN32
+ mask = umask(0);
+ umask(mask);
+ chmod(za->zn, 0666&~mask);
+#endif
+
+ _zip_free(za);
+ free(temp);
+
+ return 0;
+}
+
+
+
+static int
+add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
+ FILE *ft)
+{
+ off_t offstart, offdata, offend;
+ struct zip_stat st;
+ struct zip_source *s2;
+ zip_compression_implementation comp_impl;
+ int ret;
+
+ if (zip_source_stat(src, &st) < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ return -1;
+ }
+
+ offstart = ftello(ft);
+
+ if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
+ return -1;
+
+ if ((s2=zip_source_crc(za, src, 0)) == NULL) {
+ zip_source_pop(s2);
+ return -1;
+ }
+
+ /* XXX: deflate 0-byte files for torrentzip? */
+ if (((st.valid & ZIP_STAT_COMP_METHOD) == 0
+ || st.comp_method == ZIP_CM_STORE)
+ && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
+ comp_impl = NULL;
+ if ((comp_impl=zip_get_compression_implementation(ZIP_CM_DEFLATE))
+ == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+ zip_source_pop(s2);
+ return -1;
+ }
+ if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE))
+ == NULL) {
+ /* XXX: set error? */
+ zip_source_pop(s2);
+ return -1;
+ }
+ }
+ else
+ s2 = src;
+
+ offdata = ftello(ft);
+
+ ret = copy_source(za, s2, ft);
+
+ if (zip_source_stat(s2, &st) < 0)
+ ret = -1;
+
+ while (s2 != src) {
+ if ((s2=zip_source_pop(s2)) == NULL) {
+ /* XXX: set erorr */
+ ret = -1;
+ break;
+ }
+ }
+
+ if (ret < 0)
+ return -1;
+
+ offend = ftello(ft);
+
+ if (fseeko(ft, offstart, SEEK_SET) < 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ de->last_mod = st.mtime;
+ de->comp_method = st.comp_method;
+ de->crc = st.crc;
+ de->uncomp_size = st.size;
+ de->comp_size = offend - offdata;
+
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
+ _zip_dirent_torrent_normalize(de);
+
+ if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
+ return -1;
+
+ if (fseeko(ft, offend, SEEK_SET) < 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+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;
+}
+
+
+
+static int
+copy_source(struct zip *za, struct zip_source *src, FILE *ft)
+{
+ char buf[BUFSIZE];
+ zip_int64_t n;
+ int ret;
+
+ if (zip_source_open(src) < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ return -1;
+ }
+
+ ret = 0;
+ while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
+ if (fwrite(buf, 1, n, ft) != (size_t)n) {
+ _zip_error_set(&za->error, ZIP_ER_WRITE, errno);
+ ret = -1;
+ break;
+ }
+ }
+
+ if (n < 0) {
+ if (ret == 0)
+ _zip_error_set_from_source(&za->error, src);
+ ret = -1;
+ }
+
+ zip_source_close(src);
+
+ return ret;
+}
+
+
+
+static int
+write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
+{
+ off_t offset;
+ uLong crc;
+ char buf[TORRENT_CRC_LEN+1];
+
+ if (_zip_cdir_write(cd, out, &za->error) < 0)
+ return -1;
+
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0)
+ return 0;
+
+
+ /* fix up torrentzip comment */
+
+ offset = ftello(out);
+
+ if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0)
+ return -1;
+
+ snprintf(buf, sizeof(buf), "%08lX", (long)crc);
+
+ if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) {
+ _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ if (fwrite(buf, TORRENT_CRC_LEN, 1, out) != 1) {
+ _zip_error_set(&za->error, ZIP_ER_WRITE, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+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;
+}
+
+
+
+int
+_zip_changed(struct zip *za, int *survivorsp)
+{
+ int changed, i, survivors;
+
+ changed = survivors = 0;
+
+ if (za->ch_comment_len != -1
+ || za->ch_flags != za->flags)
+ changed = 1;
+
+ for (i=0; i<za->nentry; i++) {
+ if ((za->entry[i].state != ZIP_ST_UNCHANGED)
+ || (za->entry[i].ch_extra_len != -1)
+ || (za->entry[i].ch_comment_len != -1))
+ changed = 1;
+ if (za->entry[i].state != ZIP_ST_DELETED)
+ survivors++;
+ }
+
+ if (survivorsp)
+ *survivorsp = survivors;
+
+ return changed;
+}
+
+
+
+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
+ /*
+ According to Pierre Joye, Windows in some environments per
+ default creates text files, so force binary mode.
+ */
+ _setmode(_fileno(tfp), _O_BINARY );
+#endif
+
+ *outp = tfp;
+ return temp;
+}
+
+
+
+static int
+_zip_torrentzip_cmp(const void *a, const void *b)
+{
+ return strcasecmp(((const struct filelist *)a)->name,
+ ((const struct filelist *)b)->name);
+}
diff --git a/ext/zip/lib/zip_delete.c b/ext/zip/lib/zip_delete.c
new file mode 100644
index 0000000..131d444
--- /dev/null
+++ b/ext/zip/lib/zip_delete.c
@@ -0,0 +1,63 @@
+/*
+ zip_delete.c -- delete file from zip archive
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_delete(struct zip *za, zip_uint64_t idx)
+{
+ if (idx >= za->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 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;
+}
+
+
diff --git a/ext/zip/lib/zip_dirent.c b/ext/zip/lib/zip_dirent.c
new file mode 100644
index 0000000..b5b9d27
--- /dev/null
+++ b/ext/zip/lib/zip_dirent.c
@@ -0,0 +1,614 @@
+/*
+ zip_dirent.c -- read directory entry (local or central), clean dirent
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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>
+#include <sys/types.h>
+#include <sys/stat.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_write2(unsigned short, FILE *);
+static void _zip_write4(unsigned int, FILE *);
+
+
+
+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);
+}
+
+
+
+int
+_zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error)
+{
+ struct zip_dirent *entry;
+
+ if (nentry < cd->nentry) {
+ _zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+
+ if ((entry=((struct zip_dirent *)
+ realloc(cd->entry, sizeof(*(cd->entry))*nentry))) == NULL) {
+ _zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ cd->nentry = nentry;
+ cd->entry = entry;
+
+ return 0;
+}
+
+
+
+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;
+}
+
+
+
+int
+_zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error)
+{
+ int i;
+
+ cd->offset = ftello(fp);
+
+ for (i=0; i<cd->nentry; i++) {
+ if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0)
+ return -1;
+ }
+
+ cd->size = ftello(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;
+}
+
+
+
+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;
+}
+
+
+
+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;
+}
+
+
+
+/* _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; otherwise data is read from fp as needed.
+
+ if leftp is non-NULL, no more bytes than specified by it are used,
+ and *leftp is reduced by the number of bytes used.
+
+ If local != 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.
+
+ XXX: leftp and file position undefined on error.
+*/
+
+int
+_zip_dirent_read(struct zip_dirent *zde, FILE *fp,
+ unsigned char **bufp, zip_uint32_t *leftp, int local,
+ struct zip_error *error)
+{
+ unsigned char buf[CDENTRYSIZE];
+ unsigned char *cur;
+ unsigned short dostime, dosdate;
+ zip_uint32_t size;
+
+ if (local)
+ size = LENTRYSIZE;
+ else
+ size = CDENTRYSIZE;
+
+ if (leftp && (*leftp < size)) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+
+ if (bufp) {
+ /* use data from buffer */
+ cur = *bufp;
+ }
+ else {
+ /* read entry from disk */
+ if ((fread(buf, 1, size, fp)<size)) {
+ _zip_error_set(error, ZIP_ER_READ, errno);
+ return -1;
+ }
+ cur = buf;
+ }
+
+ if (memcmp(cur, (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+ cur += 4;
+
+
+ /* convert buffercontents to zip_dirent */
+
+ if (!local)
+ 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 (local) {
+ 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;
+
+ size += zde->filename_len+zde->extrafield_len+zde->comment_len;
+
+ if (leftp && (*leftp < size)) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+
+ if (bufp) {
+ 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;
+ if (leftp)
+ *leftp -= size;
+
+ return 0;
+}
+
+
+
+/* _zip_dirent_torrent_normalize(de);
+ Set values suitable for torrentzip.
+*/
+
+void
+_zip_dirent_torrent_normalize(struct zip_dirent *de)
+{
+ static struct tm torrenttime;
+ static time_t last_mod = 0;
+
+ if (last_mod == 0) {
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+ time_t now;
+ struct tm *l;
+#endif
+
+ torrenttime.tm_sec = 0;
+ torrenttime.tm_min = 32;
+ torrenttime.tm_hour = 23;
+ torrenttime.tm_mday = 24;
+ torrenttime.tm_mon = 11;
+ torrenttime.tm_year = 96;
+ torrenttime.tm_wday = 0;
+ torrenttime.tm_yday = 0;
+ torrenttime.tm_isdst = 0;
+
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+ time(&now);
+ l = localtime(&now);
+ torrenttime.tm_gmtoff = l->tm_gmtoff;
+ torrenttime.tm_zone = l->tm_zone;
+#endif
+
+ last_mod = mktime(&torrenttime);
+ }
+
+ de->version_madeby = 0;
+ de->version_needed = 20; /* 2.0 */
+ de->bitflags = 2; /* maximum compression */
+ de->comp_method = ZIP_CM_DEFLATE;
+ de->last_mod = last_mod;
+
+ de->disk_number = 0;
+ de->int_attrib = 0;
+ de->ext_attrib = 0;
+ de->offset = 0;
+
+ free(de->extrafield);
+ de->extrafield = NULL;
+ de->extrafield_len = 0;
+ free(de->comment);
+ de->comment = NULL;
+ de->comment_len = 0;
+}
+
+
+
+/* _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;
+}
+
+
+
+static time_t
+_zip_d2u_time(int dtime, int ddate)
+{
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(tm));
+
+ /* let mktime decide if DST is in effect */
+ tm.tm_isdst = -1;
+
+ 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);
+}
+
+
+
+unsigned short
+_zip_read2(unsigned char **a)
+{
+ unsigned short ret;
+
+ ret = (*a)[0]+((*a)[1]<<8);
+ *a += 2;
+
+ return ret;
+}
+
+
+
+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;
+}
+
+
+
+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;
+}
+
+
+
+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;
+}
+
+
+
+static void
+_zip_write2(unsigned short i, FILE *fp)
+{
+ putc(i&0xff, fp);
+ putc((i>>8)&0xff, fp);
+
+ return;
+}
+
+
+
+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;
+}
+
+
+
+void
+_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate)
+{
+ struct tm *tm;
+
+ tm = localtime(&time);
+ *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/zip/lib/zip_entry_free.c b/ext/zip/lib/zip_entry_free.c
new file mode 100644
index 0000000..e8a7770
--- /dev/null
+++ b/ext/zip/lib/zip_entry_free.c
@@ -0,0 +1,55 @@
+/*
+ zip_entry_free.c -- free struct zip_entry
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+void
+_zip_entry_free(struct zip_entry *ze)
+{
+ free(ze->ch_filename);
+ ze->ch_filename = NULL;
+ free(ze->ch_extra);
+ ze->ch_extra = NULL;
+ ze->ch_extra_len = -1;
+ free(ze->ch_comment);
+ ze->ch_comment = NULL;
+ ze->ch_comment_len = -1;
+
+ _zip_unchange_data(ze);
+}
diff --git a/ext/zip/lib/zip_entry_new.c b/ext/zip/lib/zip_entry_new.c
new file mode 100644
index 0000000..ad5d599
--- /dev/null
+++ b/ext/zip/lib/zip_entry_new.c
@@ -0,0 +1,81 @@
+/*
+ zip_entry_new.c -- create and init struct zip_entry
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+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) {
+ return NULL;
+ }
+ }
+ else {
+ if (za->nentry+1 >= za->nentry_alloc) {
+ struct zip_entry *rentries;
+ za->nentry_alloc += 16;
+ rentries = (struct zip_entry *)realloc(za->entry,
+ sizeof(struct zip_entry)
+ * za->nentry_alloc);
+ if (!rentries) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+ za->entry = rentries;
+ }
+ ze = za->entry+za->nentry;
+ }
+
+ ze->state = ZIP_ST_UNCHANGED;
+
+ ze->ch_filename = NULL;
+ ze->ch_extra = NULL;
+ ze->ch_extra_len = -1;
+ ze->ch_comment = NULL;
+ ze->ch_comment_len = -1;
+ ze->source = NULL;
+
+ if (za)
+ za->nentry++;
+
+ return ze;
+}
diff --git a/ext/zip/lib/zip_err_str.c b/ext/zip/lib/zip_err_str.c
new file mode 100644
index 0000000..8fb6003
--- /dev/null
+++ b/ext/zip/lib/zip_err_str.c
@@ -0,0 +1,76 @@
+/*
+ This file was generated automatically by ./make_zip_err_str.sh
+ from ./zip.h; make changes there.
+ */
+
+#include "zipint.h"
+
+
+
+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",
+ "Encryption method not supported",
+ "Read-only archive",
+ "No password provided",
+ "Wrong password provided",
+};
+
+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,
+ N,
+ N,
+ N,
+ N,
+};
diff --git a/ext/zip/lib/zip_error.c b/ext/zip/lib/zip_error.c
new file mode 100644
index 0000000..b8d907a
--- /dev/null
+++ b/ext/zip/lib/zip_error.c
@@ -0,0 +1,112 @@
+/*
+ zip_error.c -- struct zip_error helper functions
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+void
+_zip_error_clear(struct zip_error *err)
+{
+ err->zip_err = ZIP_ER_OK;
+ err->sys_err = 0;
+}
+
+
+
+void
+_zip_error_copy(struct zip_error *dst, struct zip_error *src)
+{
+ dst->zip_err = src->zip_err;
+ dst->sys_err = src->sys_err;
+}
+
+
+
+void
+_zip_error_fini(struct zip_error *err)
+{
+ free(err->str);
+ err->str = NULL;
+}
+
+
+
+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;
+ }
+}
+
+
+
+void
+_zip_error_init(struct zip_error *err)
+{
+ err->zip_err = ZIP_ER_OK;
+ err->sys_err = 0;
+ err->str = NULL;
+}
+
+
+
+void
+_zip_error_set(struct zip_error *err, int ze, int se)
+{
+ if (err) {
+ err->zip_err = ze;
+ err->sys_err = se;
+ }
+}
+
+
+
+void
+_zip_error_set_from_source(struct zip_error *err, struct zip_source *src)
+{
+ int ze, se;
+
+ zip_source_error(src, &ze, &se);
+ _zip_error_set(err, ze, se);
+}
diff --git a/ext/zip/lib/zip_error_clear.c b/ext/zip/lib/zip_error_clear.c
new file mode 100644
index 0000000..34e7dea
--- /dev/null
+++ b/ext/zip/lib/zip_error_clear.c
@@ -0,0 +1,44 @@
+/*
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_error_clear(struct zip *za)
+{
+ _zip_error_clear(&za->error);
+}
diff --git a/ext/zip/lib/zip_error_get.c b/ext/zip/lib/zip_error_get.c
new file mode 100644
index 0000000..c15705e
--- /dev/null
+++ b/ext/zip/lib/zip_error_get.c
@@ -0,0 +1,44 @@
+/*
+ zip_error_get.c -- get 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_error_get(struct zip *za, int *zep, int *sep)
+{
+ _zip_error_get(&za->error, zep, sep);
+}
diff --git a/ext/zip/lib/zip_error_get_sys_type.c b/ext/zip/lib/zip_error_get_sys_type.c
new file mode 100644
index 0000000..47aa93e
--- /dev/null
+++ b/ext/zip/lib/zip_error_get_sys_type.c
@@ -0,0 +1,47 @@
+/*
+ zip_error_get_sys_type.c -- return type of system error code
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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/zip/lib/zip_error_strerror.c b/ext/zip/lib/zip_error_strerror.c
new file mode 100644
index 0000000..3d0951c
--- /dev/null
+++ b/ext/zip/lib/zip_error_strerror.c
@@ -0,0 +1,90 @@
+/*
+ zip_error_sterror.c -- get string representation of struct 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 <libzip@nih.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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+
+
+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) {
+ sprintf(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 {
+ if ((s=(char *)malloc(strlen(ss)
+ + (zs ? strlen(zs)+2 : 0) + 1)) == NULL)
+ return _zip_err_str[ZIP_ER_MEMORY];
+
+ sprintf(s, "%s%s%s",
+ (zs ? zs : ""),
+ (zs ? ": " : ""),
+ ss);
+ err->str = s;
+
+ return s;
+ }
+}
diff --git a/ext/zip/lib/zip_error_to_str.c b/ext/zip/lib/zip_error_to_str.c
new file mode 100644
index 0000000..bafe743
--- /dev/null
+++ b/ext/zip/lib/zip_error_to_str.c
@@ -0,0 +1,70 @@
+/*
+ zip_error_to_str.c -- get string representation of zip error code
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_error_to_str(char *buf, zip_uint64_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/zip/lib/zip_fclose.c b/ext/zip/lib/zip_fclose.c
new file mode 100644
index 0000000..eb55ddb
--- /dev/null
+++ b/ext/zip/lib/zip_fclose.c
@@ -0,0 +1,64 @@
+/*
+ zip_fclose.c -- close file in 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_fclose(struct zip_file *zf)
+{
+ int i, ret;
+
+ if (zf->src)
+ zip_source_free(zf->src);
+
+ 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;
+
+ free(zf);
+ return ret;
+}
diff --git a/ext/zip/lib/zip_fdopen.c b/ext/zip/lib/zip_fdopen.c
new file mode 100644
index 0000000..df70f27
--- /dev/null
+++ b/ext/zip/lib/zip_fdopen.c
@@ -0,0 +1,62 @@
+/*
+ zip_fdopen.c -- open read-only archive from file descriptor
+ Copyright (C) 2009-2010 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(struct zip *)
+zip_fdopen(int fd_orig, int flags, int *zep)
+{
+ int fd;
+ FILE *fp;
+
+ /* We dup() here to avoid messing with the passed in fd.
+ We could not restore it to the original state in case of error. */
+
+ if ((fd=dup(fd_orig)) < 0) {
+ *zep = ZIP_ER_OPEN;
+ return NULL;
+ }
+
+ if ((fp=fdopen(fd, "rb")) == NULL) {
+ close(fd);
+ *zep = ZIP_ER_OPEN;
+ return NULL;
+ }
+
+ close(fd_orig);
+ return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep);
+}
diff --git a/ext/zip/lib/zip_file_error_clear.c b/ext/zip/lib/zip_file_error_clear.c
new file mode 100644
index 0000000..6c9c2a0
--- /dev/null
+++ b/ext/zip/lib/zip_file_error_clear.c
@@ -0,0 +1,44 @@
+/*
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_file_error_clear(struct zip_file *zf)
+{
+ _zip_error_clear(&zf->error);
+}
diff --git a/ext/zip/lib/zip_file_error_get.c b/ext/zip/lib/zip_file_error_get.c
new file mode 100644
index 0000000..a53fa7e
--- /dev/null
+++ b/ext/zip/lib/zip_file_error_get.c
@@ -0,0 +1,44 @@
+/*
+ zip_file_error_get.c -- get 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_file_error_get(struct zip_file *zf, int *zep, int *sep)
+{
+ _zip_error_get(&zf->error, zep, sep);
+}
diff --git a/ext/zip/lib/zip_file_get_offset.c b/ext/zip/lib/zip_file_get_offset.c
new file mode 100644
index 0000000..b96fd5e
--- /dev/null
+++ b/ext/zip/lib/zip_file_get_offset.c
@@ -0,0 +1,74 @@
+/*
+ zip_file_get_offset.c -- get offset of file data in 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 <libzip@nih.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>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "zipint.h"
+
+
+
+/* _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 (fseeko(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, NULL, 1, &za->error) != 0)
+ return 0;
+
+ offset += LENTRYSIZE + de.filename_len + de.extrafield_len;
+
+ _zip_dirent_finalize(&de);
+
+ return offset;
+}
diff --git a/ext/zip/lib/zip_file_strerror.c b/ext/zip/lib/zip_file_strerror.c
new file mode 100644
index 0000000..c2864f2
--- /dev/null
+++ b/ext/zip/lib/zip_file_strerror.c
@@ -0,0 +1,44 @@
+/*
+ zip_file_sterror.c -- get string representation of 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(const char *)
+zip_file_strerror(struct zip_file *zf)
+{
+ return _zip_error_strerror(&zf->error);
+}
diff --git a/ext/zip/lib/zip_filerange_crc.c b/ext/zip/lib/zip_filerange_crc.c
new file mode 100644
index 0000000..4d1ad56
--- /dev/null
+++ b/ext/zip/lib/zip_filerange_crc.c
@@ -0,0 +1,71 @@
+/*
+ zip_filerange_crc.c -- compute CRC32 for a range of a file
+ Copyright (C) 2008 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <errno.h>
+
+#include "zipint.h"
+
+
+
+
+int
+_zip_filerange_crc(FILE *fp, off_t start, off_t len, uLong *crcp,
+ struct zip_error *errp)
+{
+ Bytef buf[BUFSIZE];
+ size_t n;
+
+ *crcp = crc32(0L, Z_NULL, 0);
+
+ if (fseeko(fp, start, SEEK_SET) != 0) {
+ _zip_error_set(errp, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ while (len > 0) {
+ n = len > BUFSIZE ? BUFSIZE : len;
+ if ((n=fread(buf, 1, n, fp)) <= 0) {
+ _zip_error_set(errp, ZIP_ER_READ, errno);
+ return -1;
+ }
+
+ *crcp = crc32(*crcp, buf, n);
+
+ len-= n;
+ }
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_fopen.c b/ext/zip/lib/zip_fopen.c
new file mode 100644
index 0000000..f62adbb
--- /dev/null
+++ b/ext/zip/lib/zip_fopen.c
@@ -0,0 +1,49 @@
+/*
+ zip_fopen.c -- open file in zip archive for reading
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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_encrypted(za, idx, flags, za->default_password);
+}
diff --git a/ext/zip/lib/zip_fopen_encrypted.c b/ext/zip/lib/zip_fopen_encrypted.c
new file mode 100644
index 0000000..8aba062
--- /dev/null
+++ b/ext/zip/lib/zip_fopen_encrypted.c
@@ -0,0 +1,50 @@
+/*
+ zip_fopen_encrypted.c -- open file for reading with password
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(struct zip_file *)
+zip_fopen_encrypted(struct zip *za, const char *fname, int flags,
+ const char *password)
+{
+ int idx;
+
+ if ((idx=zip_name_locate(za, fname, flags)) < 0)
+ return NULL;
+
+ return zip_fopen_index_encrypted(za, idx, flags, password);
+}
diff --git a/ext/zip/lib/zip_fopen_index.c b/ext/zip/lib/zip_fopen_index.c
new file mode 100644
index 0000000..b60fd33
--- /dev/null
+++ b/ext/zip/lib/zip_fopen_index.c
@@ -0,0 +1,48 @@
+/*
+ zip_fopen_index.c -- open file in zip archive for reading by index
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN(struct zip_file *)
+zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags)
+{
+ return zip_fopen_index_encrypted(za, fileno, flags, za->default_password);
+}
diff --git a/ext/zip/lib/zip_fopen_index_encrypted.c b/ext/zip/lib/zip_fopen_index_encrypted.c
new file mode 100644
index 0000000..988a78f
--- /dev/null
+++ b/ext/zip/lib/zip_fopen_index_encrypted.c
@@ -0,0 +1,191 @@
+/*
+ zip_fopen_index_encrypted.c -- open file for reading by index w/ password
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "zipint.h"
+
+static struct zip_file *_zip_file_new(struct zip *za);
+
+
+
+ZIP_EXTERN(struct zip_file *)
+zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags,
+ const char *password)
+{
+ struct zip_file *zf;
+ zip_compression_implementation comp_impl;
+ zip_encryption_implementation enc_impl;
+ struct zip_source *src, *s2;
+ zip_uint64_t start;
+ struct zip_stat st;
+
+ if (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;
+ }
+
+ if (flags & ZIP_FL_ENCRYPTED)
+ flags |= ZIP_FL_COMPRESSED;
+
+ zip_stat_index(za, fileno, flags, &st);
+
+ enc_impl = NULL;
+ if ((flags & ZIP_FL_ENCRYPTED) == 0) {
+ if (st.encryption_method != ZIP_EM_NONE) {
+ if (password == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
+ return NULL;
+ }
+ if ((enc_impl=zip_get_encryption_implementation(
+ st.encryption_method)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+ return NULL;
+ }
+ }
+ }
+
+ comp_impl = NULL;
+ if ((flags & ZIP_FL_COMPRESSED) == 0) {
+ if (st.comp_method != ZIP_CM_STORE) {
+ if ((comp_impl=zip_get_compression_implementation(
+ st.comp_method)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+ return NULL;
+ }
+ }
+ }
+
+ if ((start=_zip_file_get_offset(za, fileno)) == 0)
+ return NULL;
+
+ if (st.comp_size == 0) {
+ if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL)
+ return NULL;
+ }
+ else {
+ if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size,
+ 0, &st)) == NULL)
+ return NULL;
+ if (enc_impl) {
+ if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0,
+ password)) == NULL) {
+ zip_source_free(src);
+ /* XXX: set error (how?) */
+ return NULL;
+ }
+ src = s2;
+ }
+ if (comp_impl) {
+ if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method,
+ 0)) == NULL) {
+ zip_source_free(src);
+ /* XXX: set error (how?) */
+ return NULL;
+ }
+ src = s2;
+ }
+ if ((flags & ZIP_FL_COMPRESSED) == 0
+ || st.comp_method == ZIP_CM_STORE ) {
+ if ((s2=zip_source_crc(za, src, 1)) == NULL) {
+ zip_source_free(src);
+ /* XXX: set error (how?) */
+ return NULL;
+ }
+ src = s2;
+ }
+ }
+
+ if (zip_source_open(src) < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ zip_source_free(src);
+ return NULL;
+ }
+
+ zf = _zip_file_new(za);
+
+ zf->src = src;
+
+ return zf;
+}
+
+
+
+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->eof = 0;
+ zf->src = NULL;
+
+ return zf;
+}
diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c
new file mode 100644
index 0000000..a6c0851
--- /dev/null
+++ b/ext/zip/lib/zip_fread.c
@@ -0,0 +1,65 @@
+/*
+ zip_fread.c -- read from file
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(zip_int64_t)
+zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread)
+{
+ zip_int64_t n;
+
+ if (!zf)
+ return -1;
+
+ if (zf->error.zip_err != 0)
+ return -1;
+
+ if (toread > ZIP_INT64_MAX) {
+ _zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((zf->eof) || (toread == 0))
+ return 0;
+
+ if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
+ _zip_error_set_from_source(&zf->error, zf->src);
+ return -1;
+ }
+
+ return n;
+}
diff --git a/ext/zip/lib/zip_free.c b/ext/zip/lib/zip_free.c
new file mode 100644
index 0000000..9932c14
--- /dev/null
+++ b/ext/zip/lib/zip_free.c
@@ -0,0 +1,83 @@
+/*
+ zip_free.c -- free struct zip
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+/* _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);
+
+ free(za->default_password);
+ _zip_cdir_free(za->cdir);
+ free(za->ch_comment);
+
+ 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/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c
new file mode 100644
index 0000000..fe97e6e
--- /dev/null
+++ b/ext/zip/lib/zip_get_archive_comment.c
@@ -0,0 +1,60 @@
+/*
+ zip_get_archive_comment.c -- get archive comment
+ Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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;
+ }
+ else {
+ if (lenp != NULL)
+ *lenp = -1;
+ return NULL;
+ }
+ }
+
+ if (lenp != NULL)
+ *lenp = za->ch_comment_len;
+ return za->ch_comment;
+}
diff --git a/ext/zip/lib/zip_get_archive_flag.c b/ext/zip/lib/zip_get_archive_flag.c
new file mode 100644
index 0000000..2d46aa3
--- /dev/null
+++ b/ext/zip/lib/zip_get_archive_flag.c
@@ -0,0 +1,48 @@
+/*
+ zip_get_archive_flag.c -- get archive global flag
+ Copyright (C) 2008 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_get_archive_flag(struct zip *za, int flag, int flags)
+{
+ int fl;
+
+ fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags;
+
+ return (fl & flag) ? 1 : 0;
+}
diff --git a/ext/zip/lib/zip_get_compression_implementation.c b/ext/zip/lib/zip_get_compression_implementation.c
new file mode 100644
index 0000000..197cd49
--- /dev/null
+++ b/ext/zip/lib/zip_get_compression_implementation.c
@@ -0,0 +1,46 @@
+/*
+ zip_get_compression_implementation.c -- get compression implementation
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(zip_compression_implementation)
+zip_get_compression_implementation(zip_uint16_t cm)
+{
+ if (cm == ZIP_CM_DEFLATE)
+ return zip_source_deflate;
+ return NULL;
+}
diff --git a/ext/zip/lib/zip_get_encryption_implementation.c b/ext/zip/lib/zip_get_encryption_implementation.c
new file mode 100644
index 0000000..783d538
--- /dev/null
+++ b/ext/zip/lib/zip_get_encryption_implementation.c
@@ -0,0 +1,46 @@
+/*
+ zip_get_encryption_implementation.c -- get encryption implementation
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(zip_encryption_implementation)
+zip_get_encryption_implementation(zip_uint16_t em)
+{
+ if (em == ZIP_EM_TRAD_PKWARE)
+ return zip_source_pkware;
+ return NULL;
+}
diff --git a/ext/zip/lib/zip_get_file_comment.c b/ext/zip/lib/zip_get_file_comment.c
new file mode 100644
index 0000000..43c1520
--- /dev/null
+++ b/ext/zip/lib/zip_get_file_comment.c
@@ -0,0 +1,58 @@
+/*
+ zip_get_file_comment.c -- get file comment
+ Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(const char *)
+zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
+{
+ if (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/zip/lib/zip_get_file_extra.c b/ext/zip/lib/zip_get_file_extra.c
new file mode 100644
index 0000000..a27edd8
--- /dev/null
+++ b/ext/zip/lib/zip_get_file_extra.c
@@ -0,0 +1,58 @@
+/*
+ zip_get_file_extra.c -- get file extra field
+ Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(const char *)
+zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
+{
+ if (idx >= za->nentry) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED)
+ || (za->entry[idx].ch_extra_len == -1)) {
+ if (lenp != NULL)
+ *lenp = za->cdir->entry[idx].extrafield_len;
+ return za->cdir->entry[idx].extrafield;
+ }
+
+ if (lenp != NULL)
+ *lenp = za->entry[idx].ch_extra_len;
+ return za->entry[idx].ch_extra;
+}
diff --git a/ext/zip/lib/zip_get_name.c b/ext/zip/lib/zip_get_name.c
new file mode 100644
index 0000000..945e24e
--- /dev/null
+++ b/ext/zip/lib/zip_get_name.c
@@ -0,0 +1,72 @@
+/*
+ zip_get_name.c -- get filename for a file in zip 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(const char *)
+zip_get_name(struct zip *za, zip_uint64_t idx, int flags)
+{
+ return _zip_get_name(za, idx, flags, &za->error);
+}
+
+
+
+const char *
+_zip_get_name(struct zip *za, zip_uint64_t idx, int flags,
+ struct zip_error *error)
+{
+ if (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/zip/lib/zip_get_num_entries.c b/ext/zip/lib/zip_get_num_entries.c
new file mode 100644
index 0000000..dd392e9
--- /dev/null
+++ b/ext/zip/lib/zip_get_num_entries.c
@@ -0,0 +1,52 @@
+/*
+ zip_get_num_entries.c -- get number of entries in archive
+ Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(zip_uint64_t)
+zip_get_num_entries(struct zip *za, int flags)
+{
+ if (za == NULL)
+ return -1;
+
+ if (flags & ZIP_FL_UNCHANGED) {
+ if (za->cdir == NULL)
+ return 0;
+ return za->cdir->nentry;
+ }
+ return za->nentry;
+}
diff --git a/ext/zip/lib/zip_get_num_files.c b/ext/zip/lib/zip_get_num_files.c
new file mode 100644
index 0000000..a442f29
--- /dev/null
+++ b/ext/zip/lib/zip_get_num_files.c
@@ -0,0 +1,47 @@
+/*
+ zip_get_num_files.c -- get number of files in 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_get_num_files(struct zip *za)
+{
+ if (za == NULL)
+ return -1;
+
+ return za->nentry;
+}
diff --git a/ext/zip/lib/zip_memdup.c b/ext/zip/lib/zip_memdup.c
new file mode 100644
index 0000000..641125e
--- /dev/null
+++ b/ext/zip/lib/zip_memdup.c
@@ -0,0 +1,55 @@
+/*
+ zip_memdup.c -- internal zip function, "strdup" with len
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+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/zip/lib/zip_name_locate.c b/ext/zip/lib/zip_name_locate.c
new file mode 100644
index 0000000..8cdd2c4
--- /dev/null
+++ b/ext/zip/lib/zip_name_locate.c
@@ -0,0 +1,97 @@
+/*
+ zip_name_locate.c -- get index by name
+ Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <string.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_name_locate(struct zip *za, const char *fname, int flags)
+{
+ return _zip_name_locate(za, fname, flags, &za->error);
+}
+
+
+
+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 (za == NULL)
+ return -1;
+
+ if (fname == NULL) {
+ _zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED) && za->cdir == NULL) {
+ _zip_error_set(error, ZIP_ER_NOENT, 0);
+ return -1;
+ }
+
+ cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : 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;
+ }
+
+/* Look for an entry should not raise an error */
+/* _zip_error_set(error, ZIP_ER_NOENT, 0);*/
+ return -1;
+}
diff --git a/ext/zip/lib/zip_new.c b/ext/zip/lib/zip_new.c
new file mode 100644
index 0000000..7ce1237
--- /dev/null
+++ b/ext/zip/lib/zip_new.c
@@ -0,0 +1,71 @@
+/*
+ zip_new.c -- create and init struct zip
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+/* _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;
+ za->flags = za->ch_flags = 0;
+ za->default_password = NULL;
+
+ return za;
+}
diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c
new file mode 100644
index 0000000..2f56881
--- /dev/null
+++ b/ext/zip/lib/zip_open.c
@@ -0,0 +1,608 @@
+/*
+ zip_open.c -- open zip archive by name
+ Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+static void set_error(int *, struct zip_error *, int);
+static struct zip *_zip_allocate_new(const char *, int *);
+static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *);
+static void _zip_check_torrentzip(struct zip *);
+static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t);
+static int _zip_file_exists(const char *, int, int *);
+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 *, off_t, unsigned char *, unsigned char *,
+ int, int, struct zip_error *);
+
+
+
+ZIP_EXTERN(struct zip *)
+zip_open(const char *fn, int flags, int *zep)
+{
+ FILE *fp;
+
+ if (flags & ZIP_OVERWRITE) {
+ return _zip_allocate_new(fn, zep);
+ }
+
+ switch (_zip_file_exists(fn, flags, zep)) {
+ case -1:
+ if (!(flags & ZIP_OVERWRITE)) {
+ return NULL;
+ }
+ case 0:
+ return _zip_allocate_new(fn, zep);
+ default:
+ break;
+ }
+
+ if ((fp=fopen(fn, "rb")) == NULL) {
+ set_error(zep, NULL, ZIP_ER_OPEN);
+ return NULL;
+ }
+
+ return _zip_open(fn, fp, flags, 0, zep);
+}
+
+
+
+struct zip *
+_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
+{
+ struct zip *za;
+ struct zip_cdir *cdir;
+ int i;
+ off_t len;
+
+ if (fseeko(fp, 0, SEEK_END) < 0) {
+ *zep = ZIP_ER_SEEK;
+ return NULL;
+ }
+ len = ftello(fp);
+
+ /* treat empty files as empty archives */
+ if (len == 0) {
+ if ((za=_zip_allocate_new(fn, zep)) == NULL)
+ fclose(fp);
+ else
+ za->zp = fp;
+ return za;
+ }
+
+ cdir = _zip_find_central_dir(fp, flags, zep, len);
+ if (cdir == NULL) {
+ fclose(fp);
+ return NULL;
+ }
+
+ if ((za=_zip_allocate_new(fn, zep)) == NULL) {
+ _zip_cdir_free(cdir);
+ fclose(fp);
+ return NULL;
+ }
+
+ za->cdir = cdir;
+ za->zp = fp;
+
+ 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);
+
+ _zip_check_torrentzip(za);
+ za->ch_flags = za->flags;
+
+ return za;
+}
+
+
+
+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;
+}
+
+
+
+/* _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, off_t buf_offset, 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;
+ zip_uint32_t left;
+
+ 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 (((zip_uint64_t)cd->offset)+cd->size > buf_offset + (eocd-buf)) {
+ /* cdir spans past EOCD record */
+ _zip_error_set(error, ZIP_ER_INCONS, 0);
+ cd->nentry = 0;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+
+ if ((comlen < cd->comment_len) || (cd->nentry != i)) {
+ _zip_error_set(error, ZIP_ER_NOZIP, 0);
+ cd->nentry = 0;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) {
+ _zip_error_set(error, ZIP_ER_INCONS, 0);
+ cd->nentry = 0;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+
+ if (cd->comment_len) {
+ if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN,
+ cd->comment_len, error))
+ == NULL) {
+ cd->nentry = 0;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ }
+
+ if (cd->offset >= buf_offset) {
+ /* if buffer already read in, use it */
+ cdp = buf + (cd->offset - buf_offset);
+ bufp = &cdp;
+ }
+ else {
+ /* go to start of cdir and read it entry by entry */
+ bufp = NULL;
+ clearerr(fp);
+ fseeko(fp, cd->offset, SEEK_SET);
+ /* possible consistency check: cd->offset =
+ len-(cd->size+cd->comment_len+EOCDLEN) ? */
+ if (ferror(fp) || ((unsigned long)ftello(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);
+ cd->nentry = 0;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ }
+
+ left = cd->size;
+ i=0;
+ while (i<cd->nentry && left > 0) {
+ if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) {
+ cd->nentry = i;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ i++;
+
+ if (i == cd->nentry && left > 0) {
+ /* Infozip extension for more than 64k entries:
+ nentries wraps around, size indicates correct EOCD */
+ if (_zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error) < 0) {
+ cd->nentry = i;
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ }
+ }
+
+ cd->nentry = i;
+
+ return cd;
+}
+
+
+
+/* _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 (fseeko(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, NULL, 1, error) == -1)
+ return -1;
+
+ if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) {
+ _zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_dirent_finalize(&temp);
+ return -1;
+ }
+ _zip_dirent_finalize(&temp);
+ }
+
+ return max - min;
+}
+
+
+
+/* _zip_check_torrentzip:
+ check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */
+
+static void
+_zip_check_torrentzip(struct zip *za)
+{
+ uLong crc_got, crc_should;
+ char buf[8+1];
+ char *end;
+
+ if (za->zp == NULL || za->cdir == NULL)
+ return;
+
+ if (za->cdir->comment_len != TORRENT_SIG_LEN+8
+ || strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0)
+ return;
+
+ memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8);
+ buf[8] = '\0';
+ errno = 0;
+ crc_should = strtoul(buf, &end, 16);
+ if ((crc_should == UINT_MAX && errno != 0) || (end && *end))
+ return;
+
+ if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size,
+ &crc_got, NULL) < 0)
+ return;
+
+ if (crc_got == crc_should)
+ za->flags |= ZIP_AFL_TORRENT;
+}
+
+
+
+
+/* _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->filename_len != h2->filename_len)
+ || !h1->filename || !h2->filename
+ || strcmp(h1->filename, h2->filename))
+ return -1;
+
+ /* check that CRC and sizes are zero if data descriptor is used */
+ if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p
+ && (h1->crc != 0
+ || h1->comp_size != 0
+ || h1->uncomp_size != 0))
+ return -1;
+ if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p
+ && (h2->crc != 0
+ || h2->comp_size != 0
+ || h2->uncomp_size != 0))
+ return -1;
+
+ /* check that CRC and sizes are equal if no data descriptor is used */
+ if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0)
+ && ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) {
+ if ((h1->crc != h2->crc)
+ || (h1->comp_size != h2->comp_size)
+ || (h1->uncomp_size != h2->uncomp_size))
+ 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;
+}
+
+
+
+static struct zip *
+_zip_allocate_new(const char *fn, int *zep)
+{
+ struct zip *za;
+ struct zip_error error;
+
+ if ((za=_zip_new(&error)) == NULL) {
+ set_error(zep, &error, 0);
+ return NULL;
+ }
+
+ if (fn == NULL)
+ za->zn = NULL;
+ else {
+ za->zn = strdup(fn);
+ if (!za->zn) {
+ _zip_free(za);
+ set_error(zep, NULL, ZIP_ER_MEMORY);
+ return NULL;
+ }
+ }
+ return za;
+}
+
+
+
+static int
+_zip_file_exists(const char *fn, int flags, int *zep)
+{
+ struct stat st;
+
+ if (fn == NULL) {
+ set_error(zep, NULL, ZIP_ER_INVAL);
+ return -1;
+ }
+
+ if (stat(fn, &st) != 0) {
+ if (flags & ZIP_CREATE || flags & ZIP_OVERWRITE)
+ return 0;
+ else {
+ set_error(zep, NULL, ZIP_ER_OPEN);
+ return -1;
+ }
+ }
+ else if ((flags & ZIP_EXCL)) {
+ set_error(zep, NULL, ZIP_ER_EXISTS);
+ return -1;
+ }
+ /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL,
+ just like open() */
+
+ return 1;
+}
+
+
+
+static struct zip_cdir *
+_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
+{
+ struct zip_cdir *cdir, *cdirnew;
+ unsigned char *buf, *match;
+ off_t buf_offset;
+ int a, best, buflen, i;
+ struct zip_error zerr;
+
+ i = fseeko(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);
+ return NULL;
+ }
+ buf_offset = ftello(fp);
+
+ /* 64k is too much for stack */
+ if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) {
+ set_error(zep, NULL, ZIP_ER_MEMORY);
+ return NULL;
+ }
+
+ clearerr(fp);
+ buflen = fread(buf, 1, CDBUFSIZE, fp);
+
+ if (ferror(fp)) {
+ set_error(zep, NULL, ZIP_ER_READ);
+ free(buf);
+ return NULL;
+ }
+
+ best = -1;
+ cdir = NULL;
+ match = buf;
+ _zip_error_set(&zerr, ZIP_ER_NOZIP, 0);
+
+ 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_offset, buf, match-1, buflen, flags,
+ &zerr)) == NULL)
+ continue;
+
+ if (cdir) {
+ if (best <= 0)
+ best = _zip_checkcons(fp, cdir, &zerr);
+ a = _zip_checkcons(fp, cdirnew, &zerr);
+ 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, &zerr);
+ else
+ best = 0;
+ }
+ cdirnew = NULL;
+ }
+
+ free(buf);
+
+ if (best < 0) {
+ set_error(zep, &zerr, 0);
+ _zip_cdir_free(cdir);
+ return NULL;
+ }
+
+ return cdir;
+}
+
+
+
+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/zip/lib/zip_rename.c b/ext/zip/lib/zip_rename.c
new file mode 100644
index 0000000..6b5a035
--- /dev/null
+++ b/ext/zip/lib/zip_rename.c
@@ -0,0 +1,70 @@
+/*
+ zip_rename.c -- rename file in zip archive
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <string.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_rename(struct zip *za, zip_uint64_t idx, const char *name)
+{
+ const char *old_name;
+ int old_is_dir, new_is_dir;
+
+ if (idx >= za->nentry || name[0] == '\0') {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if ((old_name=zip_get_name(za, idx, 0)) == NULL)
+ return -1;
+
+ new_is_dir = (name[strlen(name)-1] == '/');
+ old_is_dir = (old_name[strlen(old_name)-1] == '/');
+
+ if (new_is_dir != old_is_dir) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ return _zip_set_name(za, idx, name);
+}
diff --git a/ext/zip/lib/zip_replace.c b/ext/zip/lib/zip_replace.c
new file mode 100644
index 0000000..6dc3dd5
--- /dev/null
+++ b/ext/zip/lib/zip_replace.c
@@ -0,0 +1,85 @@
+/*
+ zip_replace.c -- replace file via callback function
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source)
+{
+ if (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;
+}
+
+
+
+
+/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
+
+zip_int64_t
+_zip_replace(struct zip *za, zip_uint64_t idx, const char *name,
+ struct zip_source *source)
+{
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (idx == ZIP_UINT64_MAX) {
+ 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/zip/lib/zip_set_archive_comment.c b/ext/zip/lib/zip_set_archive_comment.c
new file mode 100644
index 0000000..3cd069c
--- /dev/null
+++ b/ext/zip/lib/zip_set_archive_comment.c
@@ -0,0 +1,70 @@
+/*
+ zip_set_archive_comment.c -- set archive comment
+ Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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 (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (len > 0) {
+ if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
+ return -1;
+ }
+ else
+ tmpcom = NULL;
+
+ free(za->ch_comment);
+ za->ch_comment = tmpcom;
+ za->ch_comment_len = len;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_set_archive_flag.c b/ext/zip/lib/zip_set_archive_flag.c
new file mode 100644
index 0000000..07bcfbe
--- /dev/null
+++ b/ext/zip/lib/zip_set_archive_flag.c
@@ -0,0 +1,69 @@
+/*
+ zip_get_archive_flag.c -- set archive global flag
+ Copyright (C) 2008-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_set_archive_flag(struct zip *za, int flag, int value)
+{
+ unsigned int new_flags;
+
+ if (value)
+ new_flags = za->ch_flags | flag;
+ else
+ new_flags = za->ch_flags & ~flag;
+
+ if (new_flags == za->ch_flags)
+ return 0;
+
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if ((flag & ZIP_AFL_RDONLY) && value
+ && (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
+ if (_zip_changed(za, NULL)) {
+ _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+ return -1;
+ }
+ }
+
+ za->ch_flags = new_flags;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_set_default_password.c b/ext/zip/lib/zip_set_default_password.c
new file mode 100644
index 0000000..c274d11
--- /dev/null
+++ b/ext/zip/lib/zip_set_default_password.c
@@ -0,0 +1,62 @@
+/*
+ zip_set_default_password.c -- set default password for decryption
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_set_default_password(struct zip *za, const char *passwd)
+{
+ if (za == NULL)
+ return -1;
+
+ if (za->default_password)
+ free(za->default_password);
+
+ if (passwd) {
+ if ((za->default_password=strdup(passwd)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ }
+ else
+ za->default_password = NULL;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_set_file_comment.c b/ext/zip/lib/zip_set_file_comment.c
new file mode 100644
index 0000000..5e63dc2
--- /dev/null
+++ b/ext/zip/lib/zip_set_file_comment.c
@@ -0,0 +1,72 @@
+/*
+ zip_set_file_comment.c -- set comment for file in archive
+ Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_set_file_comment(struct zip *za, zip_uint64_t idx,
+ const char *comment, int len)
+{
+ char *tmpcom;
+
+ if (idx >= za->nentry
+ || len < 0 || len > MAXCOMLEN
+ || (len > 0 && comment == NULL)) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 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/zip/lib/zip_set_file_extra.c b/ext/zip/lib/zip_set_file_extra.c
new file mode 100644
index 0000000..db829e2
--- /dev/null
+++ b/ext/zip/lib/zip_set_file_extra.c
@@ -0,0 +1,72 @@
+/*
+ zip_set_file_extra.c -- set extra field for file in archive
+ Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_set_file_extra(struct zip *za, zip_uint64_t idx,
+ const char *extra, int len)
+{
+ char *tmpext;
+
+ if (idx >= za->nentry
+ || len < 0 || len > MAXEXTLEN
+ || (len > 0 && extra == NULL)) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (len > 0) {
+ if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL)
+ return -1;
+ }
+ else
+ tmpext = NULL;
+
+ free(za->entry[idx].ch_extra);
+ za->entry[idx].ch_extra = tmpext;
+ za->entry[idx].ch_extra_len = len;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_set_name.c b/ext/zip/lib/zip_set_name.c
new file mode 100644
index 0000000..2a90601
--- /dev/null
+++ b/ext/zip/lib/zip_set_name.c
@@ -0,0 +1,75 @@
+/*
+ zip_set_name.c -- rename helper function
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+int
+_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name)
+{
+ char *s;
+ zip_int64_t i;
+
+ if (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/zip/lib/zip_source_buffer.c b/ext/zip/lib/zip_source_buffer.c
new file mode 100644
index 0000000..8c9154c
--- /dev/null
+++ b/ext/zip/lib/zip_source_buffer.c
@@ -0,0 +1,163 @@
+/*
+ zip_source_buffer.c -- create zip data source from buffer
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+struct read_data {
+ const char *buf, *data, *end;
+ time_t mtime;
+ int freep;
+};
+
+static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd);
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep)
+{
+ struct read_data *f;
+ struct zip_source *zs;
+
+ if (za == NULL)
+ return NULL;
+
+ if (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 zip_int64_t
+read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
+{
+ struct read_data *z;
+ char *buf;
+ zip_uint64_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:
+ /* XXX: return error if (len > ZIP_INT64_MAX) */
+
+ n = z->end - z->buf;
+ if (n > len)
+ n = len;
+
+ 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;
+ st->comp_size = st->size;
+ st->comp_method = ZIP_CM_STORE;
+ st->encryption_method = ZIP_EM_NONE;
+ st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE
+ |ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
+
+ 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/zip/lib/zip_source_close.c b/ext/zip/lib/zip_source_close.c
new file mode 100644
index 0000000..a3bf7e5
--- /dev/null
+++ b/ext/zip/lib/zip_source_close.c
@@ -0,0 +1,54 @@
+/*
+ zip_source_close.c -- close zip_source (stop reading)
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_source_close(struct zip_source *src)
+{
+ if (!src->is_open)
+ return;
+
+ if (src->src == NULL)
+ (void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+ else {
+ (void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+ zip_source_close(src->src);
+ }
+
+ src->is_open = 0;
+}
diff --git a/ext/zip/lib/zip_source_crc.c b/ext/zip/lib/zip_source_crc.c
new file mode 100644
index 0000000..7fd78f5
--- /dev/null
+++ b/ext/zip/lib/zip_source_crc.c
@@ -0,0 +1,159 @@
+/*
+ zip_source_crc.c -- pass-through source that calculates CRC32 and size
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+struct crc {
+ int eof;
+ int validate;
+ int e[2];
+ zip_uint64_t size;
+ zip_uint32_t crc;
+};
+
+static zip_int64_t crc_read(struct zip_source *, void *, void *
+ , zip_uint64_t, enum zip_source_cmd);
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_crc(struct zip *za, struct zip_source *src, int validate)
+{
+ struct crc *ctx;
+
+ if (src == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ ctx->validate = validate;
+
+ return zip_source_layered(za, src, crc_read, ctx);
+}
+
+
+
+static zip_int64_t
+crc_read(struct zip_source *src, void *_ctx, void *data,
+ zip_uint64_t len, enum zip_source_cmd cmd)
+{
+ struct crc *ctx;
+ zip_int64_t n;
+
+ ctx = (struct crc *)_ctx;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ ctx->eof = 0;
+ ctx->crc = crc32(0, NULL, 0);
+ ctx->size = 0;
+
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ if (ctx->eof || len == 0)
+ return 0;
+
+ if ((n=zip_source_read(src, data, len)) < 0)
+ return ZIP_SOURCE_ERR_LOWER;
+
+ if (n == 0) {
+ ctx->eof = 1;
+ if (ctx->validate) {
+ struct zip_stat st;
+
+ if (zip_source_stat(src, &st) < 0)
+ return ZIP_SOURCE_ERR_LOWER;
+
+ if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
+ ctx->e[0] = ZIP_ER_CRC;
+ ctx->e[1] = 0;
+
+ return -1;
+ }
+ if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
+ ctx->e[0] = ZIP_ER_INCONS;
+ ctx->e[1] = 0;
+
+ return -1;
+ }
+ }
+ }
+ else {
+ ctx->size += n;
+ ctx->crc = crc32(ctx->crc, data, n);
+ }
+ return n;
+
+ case ZIP_SOURCE_CLOSE:
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ struct zip_stat *st;
+
+ st = (struct zip_stat *)data;
+
+ if (ctx->eof) {
+ /* XXX: Set comp_size, comp_method, encryption_method?
+ After all, this only works for uncompressed data. */
+ st->size = ctx->size;
+ st->crc = ctx->crc;
+ st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC;
+ }
+ }
+ return 0;
+
+ case ZIP_SOURCE_ERROR:
+ memcpy(data, ctx->e, sizeof(ctx->e));
+ return 0;
+
+ case ZIP_SOURCE_FREE:
+ free(ctx);
+ return 0;
+
+ default:
+ return -1;
+ }
+
+}
diff --git a/ext/zip/lib/zip_source_deflate.c b/ext/zip/lib/zip_source_deflate.c
new file mode 100644
index 0000000..5d9c5e6
--- /dev/null
+++ b/ext/zip/lib/zip_source_deflate.c
@@ -0,0 +1,394 @@
+/*
+ zip_source_deflate.c -- deflate (de)compressoin routines
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+struct deflate {
+ int e[2];
+
+ int eof;
+ int mem_level;
+ zip_uint64_t size;
+ char buffer[BUFSIZE];
+ z_stream zstr;
+};
+
+static zip_int64_t compress_read(struct zip_source *, struct deflate *,
+ void *, zip_uint64_t);
+static zip_int64_t decompress_read(struct zip_source *, struct deflate *,
+ void *, zip_uint64_t);
+static zip_int64_t deflate_compress(struct zip_source *, void *, void *,
+ zip_uint64_t, enum zip_source_cmd);
+static zip_int64_t deflate_decompress(struct zip_source *, void *, void *,
+ zip_uint64_t, enum zip_source_cmd);
+static void deflate_free(struct deflate *);
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_deflate(struct zip *za, struct zip_source *src,
+ zip_uint16_t cm, int flags)
+{
+ struct deflate *ctx;
+ struct zip_source *s2;
+
+ if (src == NULL || cm != ZIP_CM_DEFLATE) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ ctx->e[0] = ctx->e[1] = 0;
+ ctx->eof = 0;
+ if (flags & ZIP_CODEC_ENCODE) {
+ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
+ ctx->mem_level = TORRENT_MEM_LEVEL;
+ else
+ ctx->mem_level = MAX_MEM_LEVEL;
+ }
+
+ if ((s2=zip_source_layered(za, src,
+ ((flags & ZIP_CODEC_ENCODE)
+ ? deflate_compress : deflate_decompress),
+ ctx)) == NULL) {
+ deflate_free(ctx);
+ return NULL;
+ }
+
+ return s2;
+}
+
+
+
+static zip_int64_t
+compress_read(struct zip_source *src, struct deflate *ctx,
+ void *data, zip_uint64_t len)
+{
+ int end, ret;
+ zip_int64_t n;
+
+ if (ctx->e[0] != 0)
+ return -1;
+
+ if (len == 0)
+ return 0;
+
+ ctx->zstr.next_out = (Bytef *)data;
+ ctx->zstr.avail_out = len;
+
+ end = 0;
+ while (!end) {
+ ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
+
+ switch (ret) {
+ case Z_OK:
+ case Z_STREAM_END:
+ /* all ok */
+
+ if (ctx->zstr.avail_out == 0
+ || (ctx->eof && ctx->zstr.avail_in == 0))
+ end = 1;
+ break;
+
+ case Z_BUF_ERROR:
+ if (ctx->zstr.avail_in == 0) {
+ if (ctx->eof) {
+ end = 1;
+ break;
+ }
+
+ if ((n=zip_source_read(src, ctx->buffer,
+ sizeof(ctx->buffer))) < 0) {
+ zip_source_error(src, ctx->e, ctx->e+1);
+ end = 1;
+ break;
+ }
+ else if (n == 0) {
+ ctx->eof = 1;
+ ctx->size = ctx->zstr.total_in;
+ /* XXX: check against stat of src? */
+ }
+ else {
+ ctx->zstr.next_in = (Bytef *)ctx->buffer;
+ ctx->zstr.avail_in = n;
+ }
+ continue;
+ }
+ /* fallthrough */
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_STREAM_ERROR:
+ case Z_MEM_ERROR:
+ ctx->e[0] = ZIP_ER_ZLIB;
+ ctx->e[1] = ret;
+
+ end = 1;
+ break;
+ }
+ }
+
+ if (ctx->zstr.avail_out < len)
+ return len - ctx->zstr.avail_out;
+
+ return (ctx->e[0] == 0) ? 0 : -1;
+}
+
+
+
+static zip_int64_t
+decompress_read(struct zip_source *src, struct deflate *ctx,
+ void *data, zip_uint64_t len)
+{
+ int end, ret;
+ zip_int64_t n;
+
+ if (ctx->e[0] != 0)
+ return -1;
+
+ if (len == 0)
+ return 0;
+
+ ctx->zstr.next_out = (Bytef *)data;
+ ctx->zstr.avail_out = len;
+
+ end = 0;
+ while (!end && ctx->zstr.avail_out) {
+ ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
+
+ switch (ret) {
+ case Z_OK:
+ break;
+
+ case Z_STREAM_END:
+ ctx->eof = 1;
+ end = 1;
+ break;
+
+ case Z_BUF_ERROR:
+ if (ctx->zstr.avail_in == 0) {
+ if (ctx->eof) {
+ end = 1;
+ break;
+ }
+
+ if ((n=zip_source_read(src, ctx->buffer,
+ sizeof(ctx->buffer))) < 0) {
+ zip_source_error(src, ctx->e, ctx->e+1);
+ end = 1;
+ break;
+ }
+ else if (n == 0)
+ ctx->eof = 1;
+ else {
+ ctx->zstr.next_in = (Bytef *)ctx->buffer;
+ ctx->zstr.avail_in = n;
+ }
+ continue;
+ }
+ /* fallthrough */
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_STREAM_ERROR:
+ case Z_MEM_ERROR:
+ ctx->e[0] = ZIP_ER_ZLIB;
+ ctx->e[1] = ret;
+ end = 1;
+ break;
+ }
+ }
+
+ if (ctx->zstr.avail_out < len)
+ return len - ctx->zstr.avail_out;
+
+ return (ctx->e[0] == 0) ? 0 : -1;
+}
+
+
+
+static zip_int64_t
+deflate_compress(struct zip_source *src, void *ud, void *data,
+ zip_uint64_t len, enum zip_source_cmd cmd)
+{
+ struct deflate *ctx;
+ int ret;
+
+ ctx = (struct deflate *)ud;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ ctx->zstr.zalloc = Z_NULL;
+ ctx->zstr.zfree = Z_NULL;
+ ctx->zstr.opaque = NULL;
+ ctx->zstr.avail_in = 0;
+ ctx->zstr.next_in = NULL;
+ ctx->zstr.avail_out = 0;
+ ctx->zstr.next_out = NULL;
+
+ /* negative value to tell zlib not to write a header */
+ if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED,
+ -MAX_WBITS, ctx->mem_level,
+ Z_DEFAULT_STRATEGY)) != Z_OK) {
+ ctx->e[0] = ZIP_ER_ZLIB;
+ ctx->e[1] = ret;
+ return -1;
+ }
+
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ return compress_read(src, ctx, data, len);
+
+ case ZIP_SOURCE_CLOSE:
+ deflateEnd(&ctx->zstr);
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ struct zip_stat *st;
+
+ st = (struct zip_stat *)data;
+
+ st->comp_method = ZIP_CM_DEFLATE;
+ st->valid |= ZIP_STAT_COMP_METHOD;
+ if (ctx->eof) {
+ st->comp_size = ctx->size;
+ st->valid |= ZIP_STAT_COMP_SIZE;
+ }
+ else
+ st->valid &= ~ZIP_STAT_COMP_SIZE;
+ }
+ return 0;
+
+ case ZIP_SOURCE_ERROR:
+ memcpy(data, ctx->e, sizeof(int)*2);
+ return sizeof(int)*2;
+
+ case ZIP_SOURCE_FREE:
+ deflate_free(ctx);
+ return 0;
+
+ default:
+ ctx->e[0] = ZIP_ER_INVAL;
+ ctx->e[1] = 0;
+ return -1;
+ }
+}
+
+
+
+static zip_int64_t
+deflate_decompress(struct zip_source *src, void *ud, void *data,
+ zip_uint64_t len, enum zip_source_cmd cmd)
+{
+ struct deflate *ctx;
+ zip_int64_t n;
+ int ret;
+
+ ctx = (struct deflate *)ud;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0)
+ return ZIP_SOURCE_ERR_LOWER;
+
+ ctx->zstr.zalloc = Z_NULL;
+ ctx->zstr.zfree = Z_NULL;
+ ctx->zstr.opaque = NULL;
+ ctx->zstr.next_in = (Bytef *)ctx->buffer;
+ ctx->zstr.avail_in = n;
+
+ /* negative value to tell zlib that there is no header */
+ if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
+ ctx->e[0] = ZIP_ER_ZLIB;
+ ctx->e[1] = ret;
+
+ return -1;
+ }
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ return decompress_read(src, ctx, data, len);
+
+ case ZIP_SOURCE_CLOSE:
+ inflateEnd(&ctx->zstr);
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ struct zip_stat *st;
+
+ st = (struct zip_stat *)data;
+
+ st->comp_method = ZIP_CM_STORE;
+ if (st->comp_size > 0 && st->size > 0)
+ st->comp_size = st->size;
+ }
+ return 0;
+
+ case ZIP_SOURCE_ERROR:
+ if (len < sizeof(int)*2)
+ return -1;
+
+ memcpy(data, ctx->e, sizeof(int)*2);
+ return sizeof(int)*2;
+
+ case ZIP_SOURCE_FREE:
+ /* XXX: inflateEnd if close was not called */
+ free(ctx);
+ return 0;
+
+ default:
+ ctx->e[0] = ZIP_ER_INVAL;
+ ctx->e[1] = 0;
+ return -1;
+ }
+
+}
+
+
+
+static void
+deflate_free(struct deflate *ctx)
+{
+ /* XXX: deflateEnd if close was not called */
+ free(ctx);
+}
diff --git a/ext/zip/lib/zip_source_error.c b/ext/zip/lib/zip_source_error.c
new file mode 100644
index 0000000..ffb4652
--- /dev/null
+++ b/ext/zip/lib/zip_source_error.c
@@ -0,0 +1,87 @@
+/*
+ zip_source_error.c -- get last error from zip_source
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_source_error(struct zip_source *src, int *ze, int *se)
+{
+ int e[2];
+
+ if (src->src == NULL) {
+ }
+ else {
+ switch (src->error_source) {
+ case ZIP_LES_NONE:
+ if (src->src == NULL) {
+ if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
+ e[0] = ZIP_ER_INTERNAL;
+ e[1] = 0;
+ }
+ }
+ else
+ e[0] = e[1] = 0;
+ break;
+
+ case ZIP_LES_INVAL:
+ e[0] = ZIP_ER_INVAL;
+ e[1] = 0;
+ break;
+
+ case ZIP_LES_LOWER:
+ zip_source_error(src->src, ze, se);
+ return;
+
+ case ZIP_LES_UPPER:
+ if (src->cb.l(src->src, src->ud, e, sizeof(e),
+ ZIP_SOURCE_ERROR) < 0) {
+ e[0] = ZIP_ER_INTERNAL;
+ e[1] = 0;
+ }
+ break;
+
+ default:
+ e[0] = ZIP_ER_INTERNAL;
+ e[1] = 0;
+ }
+ }
+
+ if (ze)
+ *ze = e[0];
+ if (se)
+ *se = e[1];
+}
diff --git a/ext/zip/lib/zip_source_file.c b/ext/zip/lib/zip_source_file.c
new file mode 100644
index 0000000..681cc2f
--- /dev/null
+++ b/ext/zip/lib/zip_source_file.c
@@ -0,0 +1,56 @@
+/*
+ zip_source_file.c -- create data source from file
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <errno.h>
+#include <stdio.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_file(struct zip *za, const char *fname, zip_uint64_t start,
+ zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ if (fname == NULL || len < -1) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_file_or_p(za, fname, NULL, start, len, 1, NULL);
+}
diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c
new file mode 100644
index 0000000..4d896a4
--- /dev/null
+++ b/ext/zip/lib/zip_source_filep.c
@@ -0,0 +1,247 @@
+/*
+ zip_source_filep.c -- create data source from FILE *
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct read_file {
+ char *fname; /* name of file to copy from */
+ FILE *f; /* file to copy from */
+ int closep; /* close f */
+ struct zip_stat st; /* stat information passed in */
+
+ zip_uint64_t off; /* start offset of */
+ zip_int64_t len; /* length of data to copy */
+ zip_int64_t remain; /* bytes remaining to be copied */
+ int e[2]; /* error codes */
+};
+
+static zip_int64_t read_file(void *state, void *data, zip_uint64_t len,
+ enum zip_source_cmd cmd);
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start,
+ zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ if (file == NULL || start < 0 || len < -1) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_file_or_p(za, NULL, file, start, len, 1, NULL);
+}
+
+
+
+struct zip_source *
+_zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
+ zip_uint64_t start, zip_int64_t len, int closep,
+ const struct zip_stat *st)
+{
+ struct read_file *f;
+ struct zip_source *zs;
+
+ if (file == NULL && fname == NULL) {
+ _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->fname = NULL;
+ if (fname) {
+ if ((f->fname=strdup(fname)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ free(f);
+ return NULL;
+ }
+ }
+ f->f = file;
+ f->off = start;
+ f->len = (len ? len : -1);
+ f->closep = f->fname ? 1 : closep;
+ if (st)
+ memcpy(&f->st, st, sizeof(f->st));
+ else
+ zip_stat_init(&f->st);
+
+ if ((zs=zip_source_function(za, read_file, f)) == NULL) {
+ free(f);
+ return NULL;
+ }
+
+ return zs;
+}
+
+
+
+static zip_int64_t
+read_file(void *state, void *data, zip_uint64_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 (z->fname) {
+ if ((z->f=fopen(z->fname, "rb")) == NULL) {
+ z->e[0] = ZIP_ER_OPEN;
+ z->e[1] = errno;
+ return -1;
+ }
+ }
+
+ if (z->closep) {
+ if (fseeko(z->f, (off_t)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:
+ /* XXX: return INVAL if len > size_t max */
+ if (z->remain != -1)
+ n = len > z->remain ? z->remain : len;
+ else
+ n = len;
+
+ if (!z->closep) {
+ /* we might share this file with others, so let's be safe */
+ if (fseeko(z->f, (off_t)(z->off + z->len-z->remain),
+ SEEK_SET) < 0) {
+ z->e[0] = ZIP_ER_SEEK;
+ z->e[1] = errno;
+ return -1;
+ }
+ }
+
+ 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:
+ if (z->fname) {
+ fclose(z->f);
+ z->f = NULL;
+ }
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ if (len < sizeof(z->st))
+ return -1;
+
+ if (z->st.valid != 0)
+ memcpy(data, &z->st, sizeof(z->st));
+ else {
+ struct zip_stat *st;
+ struct stat fst;
+ int err;
+
+ if (z->f)
+ err = fstat(fileno(z->f), &fst);
+ else
+ err = stat(z->fname, &fst);
+
+ if (err != 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;
+ st->valid |= ZIP_STAT_MTIME;
+ if (z->len != -1) {
+ st->size = z->len;
+ st->valid |= ZIP_STAT_SIZE;
+ }
+ else if ((fst.st_mode&S_IFMT) == S_IFREG) {
+ st->size = fst.st_size;
+ st->valid |= ZIP_STAT_SIZE;
+ }
+ }
+ return sizeof(z->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:
+ free(z->fname);
+ if (z->closep && z->f)
+ fclose(z->f);
+ free(z);
+ return 0;
+
+ default:
+ ;
+ }
+
+ return -1;
+}
diff --git a/ext/zip/lib/zip_source_free.c b/ext/zip/lib/zip_source_free.c
new file mode 100644
index 0000000..f71c71e
--- /dev/null
+++ b/ext/zip/lib/zip_source_free.c
@@ -0,0 +1,59 @@
+/*
+ zip_source_free.c -- free zip data source
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_source_free(struct zip_source *src)
+{
+ if (src == NULL)
+ return;
+
+ if (src->is_open)
+ zip_source_close(src);
+
+ if (src->src == NULL)
+ (void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_FREE);
+ else {
+ (void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
+ zip_source_free(src->src);
+ }
+
+ free(src);
+}
diff --git a/ext/zip/lib/zip_source_function.c b/ext/zip/lib/zip_source_function.c
new file mode 100644
index 0000000..984b107
--- /dev/null
+++ b/ext/zip/lib/zip_source_function.c
@@ -0,0 +1,78 @@
+/*
+ zip_source_function.c -- create zip data source from callback function
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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=_zip_source_new(za)) == NULL)
+ return NULL;
+
+ zs->cb.f = zcb;
+ zs->ud = ud;
+
+ return zs;
+}
+
+
+
+struct zip_source *
+_zip_source_new(struct zip *za)
+{
+ struct zip_source *src;
+
+ if ((src=(struct zip_source *)malloc(sizeof(*src))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ src->src = NULL;
+ src->cb.f = NULL;
+ src->ud = NULL;
+ src->error_source = ZIP_LES_NONE;
+ src->is_open = 0;
+
+ return src;
+}
diff --git a/ext/zip/lib/zip_source_layered.c b/ext/zip/lib/zip_source_layered.c
new file mode 100644
index 0000000..86ed420
--- /dev/null
+++ b/ext/zip/lib/zip_source_layered.c
@@ -0,0 +1,59 @@
+/*
+ zip_source_layered.c -- create layered source
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_layered(struct zip *za, struct zip_source *src,
+ zip_source_layered_callback cb, void *ud)
+{
+ struct zip_source *zs;
+
+ if (za == NULL)
+ return NULL;
+
+ if ((zs=_zip_source_new(za)) == NULL)
+ return NULL;
+
+ zs->src = src;
+ zs->cb.l = cb;
+ zs->ud = ud;
+
+ return zs;
+}
diff --git a/ext/zip/lib/zip_source_open.c b/ext/zip/lib/zip_source_open.c
new file mode 100644
index 0000000..2c768f7
--- /dev/null
+++ b/ext/zip/lib/zip_source_open.c
@@ -0,0 +1,76 @@
+/*
+ zip_source_open.c -- open zip_source (prepare for reading)
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_source_open(struct zip_source *src)
+{
+ zip_int64_t ret;
+
+ if (src->is_open) {
+ src->error_source = ZIP_LES_INVAL;
+ return -1;
+ }
+
+ if (src->src == NULL) {
+ if (src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_OPEN) < 0)
+ return -1;
+ }
+ else {
+ if (zip_source_open(src->src) < 0) {
+ src->error_source = ZIP_LES_LOWER;
+ return -1;
+ }
+
+ ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN);
+
+ if (ret < 0) {
+ (void)zip_source_close(src->src);
+
+ if (ret == ZIP_SOURCE_ERR_LOWER)
+ src->error_source = ZIP_LES_LOWER;
+ else
+ src->error_source = ZIP_LES_UPPER;
+ return -1;
+ }
+ }
+
+ src->is_open = 1;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_source_pkware.c b/ext/zip/lib/zip_source_pkware.c
new file mode 100644
index 0000000..83b5cc5
--- /dev/null
+++ b/ext/zip/lib/zip_source_pkware.c
@@ -0,0 +1,241 @@
+/*
+ zip_source_pkware.c -- Traditional PKWARE de/encryption routines
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+struct trad_pkware {
+ int e[2];
+
+ zip_uint32_t key[3];
+};
+
+#define HEADERLEN 12
+#define KEY0 305419896
+#define KEY1 591751049
+#define KEY2 878082192
+
+static const uLongf *crc = NULL;
+
+#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+
+
+static void decrypt(struct trad_pkware *, zip_uint8_t *,
+ const zip_uint8_t *, zip_uint64_t, int);
+static int decrypt_header(struct zip_source *, struct trad_pkware *);
+static zip_int64_t pkware_decrypt(struct zip_source *, void *, void *,
+ zip_uint64_t, enum zip_source_cmd);
+static void pkware_free(struct trad_pkware *);
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_pkware(struct zip *za, struct zip_source *src,
+ zip_uint16_t em, int flags, const char *password)
+{
+ struct trad_pkware *ctx;
+ struct zip_source *s2;
+
+ if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
+ _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ if (flags & ZIP_CODEC_ENCODE) {
+ _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+ return NULL;
+ }
+
+ if (crc == NULL)
+ crc = get_crc_table();
+
+ if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ ctx->e[0] = ctx->e[1] = 0;
+
+ ctx->key[0] = KEY0;
+ ctx->key[1] = KEY1;
+ ctx->key[2] = KEY2;
+ decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
+
+ if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
+ pkware_free(ctx);
+ return NULL;
+ }
+
+ return s2;
+}
+
+
+
+static void
+decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
+ zip_uint64_t len, int update_only)
+{
+ zip_uint16_t tmp;
+ zip_uint64_t i;
+ Bytef b;
+
+ for (i=0; i<len; i++) {
+ b = in[i];
+
+ if (!update_only) {
+ /* decrypt next byte */
+ tmp = ctx->key[2] | 2;
+ tmp = (tmp * (tmp ^ 1)) >> 8;
+ b ^= tmp;
+ }
+
+ /* store cleartext */
+ if (out)
+ out[i] = b;
+
+ /* update keys */
+ ctx->key[0] = CRC32(ctx->key[0], b);
+ ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
+ b = ctx->key[1] >> 24;
+ ctx->key[2] = CRC32(ctx->key[2], b);
+ }
+}
+
+
+
+static int
+decrypt_header(struct zip_source *src, struct trad_pkware *ctx)
+{
+ zip_uint8_t header[HEADERLEN];
+ struct zip_stat st;
+ zip_int64_t n;
+ unsigned short dostime, dosdate;
+
+ if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
+ zip_source_error(src, ctx->e, ctx->e+1);
+ return -1;
+ }
+
+ if (n != HEADERLEN) {
+ ctx->e[0] = ZIP_ER_EOF;
+ ctx->e[1] = 0;
+ return -1;
+ }
+
+ decrypt(ctx, header, header, HEADERLEN, 0);
+
+ if (zip_source_stat(src, &st) < 0) {
+ /* stat failed, skip password validation */
+ return 0;
+ }
+
+ _zip_u2d_time(st.mtime, &dostime, &dosdate);
+
+ if (header[HEADERLEN-1] != st.crc>>24
+ && header[HEADERLEN-1] != dostime>>8) {
+ ctx->e[0] = ZIP_ER_WRONGPASSWD;
+ ctx->e[1] = 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+static zip_int64_t
+pkware_decrypt(struct zip_source *src, void *ud, void *data,
+ zip_uint64_t len, enum zip_source_cmd cmd)
+{
+ struct trad_pkware *ctx;
+ zip_int64_t n;
+
+ ctx = (struct trad_pkware *)ud;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ if (decrypt_header(src, ctx) < 0)
+ return -1;
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ if ((n=zip_source_read(src, data, len)) < 0)
+ return ZIP_SOURCE_ERR_LOWER;
+
+ decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
+ 0);
+ return n;
+
+ case ZIP_SOURCE_CLOSE:
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ struct zip_stat *st;
+
+ st = (struct zip_stat *)data;
+
+ st->encryption_method = ZIP_EM_NONE;
+ st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
+ /* XXX: deduce HEADERLEN from size for uncompressed */
+ if (st->valid & ZIP_STAT_COMP_SIZE)
+ st->comp_size -= HEADERLEN;
+ }
+ return 0;
+
+ case ZIP_SOURCE_ERROR:
+ memcpy(data, ctx->e, sizeof(int)*2);
+ return sizeof(int)*2;
+
+ case ZIP_SOURCE_FREE:
+ pkware_free(ctx);
+ return 0;
+
+ default:
+ ctx->e[0] = ZIP_ER_INVAL;
+ ctx->e[1] = 0;
+ return -1;
+ }
+}
+
+
+
+static void
+pkware_free(struct trad_pkware *ctx)
+{
+ free(ctx);
+}
diff --git a/ext/zip/lib/zip_source_pop.c b/ext/zip/lib/zip_source_pop.c
new file mode 100644
index 0000000..4060938
--- /dev/null
+++ b/ext/zip/lib/zip_source_pop.c
@@ -0,0 +1,63 @@
+/*
+ zip_source_pop.c -- pop top layer from zip data source
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_pop(struct zip_source *src)
+{
+ struct zip_source *lower;
+
+ if (src == NULL)
+ return NULL;
+
+ lower = src->src;
+
+ if (lower == NULL)
+ zip_source_free(src);
+ else {
+ if (src->is_open)
+ (void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+ (void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
+
+ free(src);
+ }
+
+ return lower;
+}
diff --git a/ext/zip/lib/zip_source_read.c b/ext/zip/lib/zip_source_read.c
new file mode 100644
index 0000000..7246f9c
--- /dev/null
+++ b/ext/zip/lib/zip_source_read.c
@@ -0,0 +1,64 @@
+/*
+ zip_source_read.c -- read data from zip_source
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(zip_int64_t)
+zip_source_read(struct zip_source *src, void *data, zip_uint64_t len)
+{
+ zip_int64_t ret;
+
+ if (!src->is_open || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) {
+ src->error_source = ZIP_LES_INVAL;
+ return -1;
+ }
+
+ if (src->src == NULL)
+ return src->cb.f(src->ud, data, len, ZIP_SOURCE_READ);
+
+ ret = src->cb.l(src->src, src->ud, data, len, ZIP_SOURCE_READ);
+
+ if (ret < 0) {
+ if (ret == ZIP_SOURCE_ERR_LOWER)
+ src->error_source = ZIP_LES_LOWER;
+ else
+ src->error_source = ZIP_LES_UPPER;
+ return -1;
+ }
+
+ return ret;
+}
diff --git a/ext/zip/lib/zip_source_stat.c b/ext/zip/lib/zip_source_stat.c
new file mode 100644
index 0000000..662779e
--- /dev/null
+++ b/ext/zip/lib/zip_source_stat.c
@@ -0,0 +1,72 @@
+/*
+ zip_source_stat.c -- get meta information from zip_source
+ Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_source_stat(struct zip_source *src, struct zip_stat *st)
+{
+ zip_int64_t ret;
+
+ if (st == NULL) {
+ src->error_source = ZIP_LES_INVAL;
+ return -1;
+ }
+
+ if (src->src == NULL) {
+ if (src->cb.f(src->ud, st, sizeof(*st), ZIP_SOURCE_STAT) < 0)
+ return -1;
+ return 0;
+ }
+
+ if (zip_source_stat(src->src, st) < 0) {
+ src->error_source = ZIP_LES_LOWER;
+ return -1;
+ }
+
+ ret = src->cb.l(src->src, src->ud, st, sizeof(*st), ZIP_SOURCE_STAT);
+
+ if (ret < 0) {
+ if (ret == ZIP_SOURCE_ERR_LOWER)
+ src->error_source = ZIP_LES_LOWER;
+ else
+ src->error_source = ZIP_LES_UPPER;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_source_zip.c b/ext/zip/lib/zip_source_zip.c
new file mode 100644
index 0000000..228803c
--- /dev/null
+++ b/ext/zip/lib/zip_source_zip.c
@@ -0,0 +1,190 @@
+/*
+ zip_source_zip.c -- create data source from zip file
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+struct read_zip {
+ struct zip_file *zf;
+ struct zip_stat st;
+ zip_uint64_t off;
+ zip_int64_t len;
+};
+
+static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len,
+ enum zip_source_cmd cmd);
+
+
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx,
+ int flags, zip_uint64_t start, zip_int64_t len)
+{
+ struct zip_error error;
+ struct zip_source *zs;
+ struct read_zip *p;
+
+ /* XXX: ZIP_FL_RECOMPRESS */
+
+ if (za == NULL)
+ return NULL;
+
+ if (srcza == NULL || 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_RECOMPRESS) == 0)
+ 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;
+}
+
+
+
+static zip_int64_t
+read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
+{
+ struct read_zip *z;
+ char b[8192], *buf;
+ int i;
+ zip_uint64_t 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/zip/lib/zip_stat.c b/ext/zip/lib/zip_stat.c
new file mode 100644
index 0000000..c8a25e1
--- /dev/null
+++ b/ext/zip/lib/zip_stat.c
@@ -0,0 +1,49 @@
+/*
+ zip_stat.c -- get information about file by name
+ 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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/zip/lib/zip_stat_index.c b/ext/zip/lib/zip_stat_index.c
new file mode 100644
index 0000000..8faa8cc
--- /dev/null
+++ b/ext/zip/lib/zip_stat_index.c
@@ -0,0 +1,94 @@
+/*
+ zip_stat_index.c -- get information about file by index
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_stat_index(struct zip *za, zip_uint64_t index, int flags,
+ struct zip_stat *st)
+{
+ const char *name;
+
+ if (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 (zip_source_stat(za->entry[index].source, st) < 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;
+ }
+
+ zip_stat_init(st);
+
+ 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->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
+ |ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
+ }
+
+ st->index = index;
+ st->name = name;
+ st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_stat_init.c b/ext/zip/lib/zip_stat_init.c
new file mode 100644
index 0000000..74e1ffd
--- /dev/null
+++ b/ext/zip/lib/zip_stat_init.c
@@ -0,0 +1,52 @@
+/*
+ zip_stat_init.c -- initialize struct zip_stat.
+ Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(void)
+zip_stat_init(struct zip_stat *st)
+{
+ st->valid = 0;
+ st->name = NULL;
+ st->index = ZIP_UINT64_MAX;
+ st->crc = 0;
+ st->mtime = (time_t)-1;
+ st->size = 0;
+ st->comp_size = 0;
+ st->comp_method = ZIP_CM_STORE;
+ st->encryption_method = ZIP_EM_NONE;
+}
diff --git a/ext/zip/lib/zip_strerror.c b/ext/zip/lib/zip_strerror.c
new file mode 100644
index 0000000..ad23baf
--- /dev/null
+++ b/ext/zip/lib/zip_strerror.c
@@ -0,0 +1,43 @@
+/*
+ zip_sterror.c -- get string representation of 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 <libzip@nih.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 "zipint.h"
+
+
+ZIP_EXTERN(const char *)
+zip_strerror(struct zip *za)
+{
+ return _zip_error_strerror(&za->error);
+}
diff --git a/ext/zip/lib/zip_unchange.c b/ext/zip/lib/zip_unchange.c
new file mode 100644
index 0000000..550e8b9
--- /dev/null
+++ b/ext/zip/lib/zip_unchange.c
@@ -0,0 +1,85 @@
+/*
+ zip_unchange.c -- undo changes to file in 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_unchange(struct zip *za, zip_uint64_t idx)
+{
+ return _zip_unchange(za, idx, 0);
+}
+
+
+
+int
+_zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates)
+{
+ int i;
+
+ if (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_extra);
+ za->entry[idx].ch_extra = NULL;
+ za->entry[idx].ch_extra_len = -1;
+ 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/zip/lib/zip_unchange_all.c b/ext/zip/lib/zip_unchange_all.c
new file mode 100644
index 0000000..01282f8
--- /dev/null
+++ b/ext/zip/lib/zip_unchange_all.c
@@ -0,0 +1,54 @@
+/*
+ zip_unchange.c -- undo changes to all files in 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 <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(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/zip/lib/zip_unchange_archive.c b/ext/zip/lib/zip_unchange_archive.c
new file mode 100644
index 0000000..ca2b678
--- /dev/null
+++ b/ext/zip/lib/zip_unchange_archive.c
@@ -0,0 +1,52 @@
+/*
+ zip_unchange_archive.c -- undo global changes to ZIP archive
+ Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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 "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_unchange_archive(struct zip *za)
+{
+ free(za->ch_comment);
+ za->ch_comment = NULL;
+ za->ch_comment_len = -1;
+
+ za->ch_flags = za->flags;
+
+ return 0;
+}
diff --git a/ext/zip/lib/zip_unchange_data.c b/ext/zip/lib/zip_unchange_data.c
new file mode 100644
index 0000000..7dd93b7
--- /dev/null
+++ b/ext/zip/lib/zip_unchange_data.c
@@ -0,0 +1,52 @@
+/*
+ $NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz 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 <libzip@nih.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 "zipint.h"
+
+void
+_zip_unchange_data(struct zip_entry *ze)
+{
+ if (ze->source) {
+ zip_source_free(ze->source);
+ ze->source = NULL;
+ }
+
+ ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED;
+}
+
diff --git a/ext/zip/lib/zip_win32.h b/ext/zip/lib/zip_win32.h
new file mode 100644
index 0000000..ff28d28
--- /dev/null
+++ b/ext/zip/lib/zip_win32.h
@@ -0,0 +1,31 @@
+#define _POSIX_
+#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
+#include <string.h>
+#include <zconf.h>
+
+#ifndef strcasecmp
+# define strcmpi _strcmpi
+#endif
+
+#ifndef ssize_t
+# define ssize_t SSIZE_T
+#endif
+
+#ifndef mode_t
+# define mode_t int
+#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
+*/
diff --git a/ext/zip/lib/zipconf.h b/ext/zip/lib/zipconf.h
new file mode 100644
index 0000000..2b4340c
--- /dev/null
+++ b/ext/zip/lib/zipconf.h
@@ -0,0 +1,51 @@
+#ifndef _HAD_ZIPCONF_H
+#define _HAD_ZIPCONF_H
+
+/*
+ zipconf.h -- platform specific include file
+
+ This file was generated automatically by ./make_zipconf.sh
+ based on ../config.h.
+ */
+
+#define LIBZIP_VERSION "0.10.1"
+#define LIBZIP_VERSION_MAJOR 0
+#define LIBZIP_VERSION_MINOR 10
+#define LIBZIP_VERSION_MICRO 0
+
+#ifdef PHP_WIN32
+#include <win32/php_stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+typedef int8_t zip_int8_t;
+#define ZIP_INT8_MIN INT8_MIN
+#define ZIP_INT8_MAX INT8_MAX
+
+typedef uint8_t zip_uint8_t;
+#define ZIP_UINT8_MAX UINT8_MAX
+
+typedef int16_t zip_int16_t;
+#define ZIP_INT16_MIN INT16_MIN
+#define ZIP_INT16_MAX INT16_MAX
+
+typedef uint16_t zip_uint16_t;
+#define ZIP_UINT16_MAX UINT16_MAX
+
+typedef int32_t zip_int32_t;
+#define ZIP_INT32_MIN INT32_MIN
+#define ZIP_INT32_MAX INT32_MAX
+
+typedef uint32_t zip_uint32_t;
+#define ZIP_UINT32_MAX UINT32_MAX
+
+typedef int64_t zip_int64_t;
+#define ZIP_INT64_MIN INT64_MIN
+#define ZIP_INT64_MAX INT64_MAX
+
+typedef uint64_t zip_uint64_t;
+#define ZIP_UINT64_MAX UINT64_MAX
+
+
+#endif /* zipconf.h */
diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h
new file mode 100644
index 0000000..ea21ddd
--- /dev/null
+++ b/ext/zip/lib/zipint.h
@@ -0,0 +1,344 @@
+#ifndef _HAD_ZIPINT_H
+#define _HAD_ZIPINT_H
+
+/*
+ zipint.h -- internal declarations.
+ Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <libzip@nih.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
+
+#ifndef HAVE_FTELLO
+#define ftello(s) ((long)ftell((s)))
+#endif
+
+#ifndef PHP_WIN32
+#ifndef HAVE_MKSTEMP
+int _zip_mkstemp(char *);
+#define mkstemp _zip_mkstemp
+#endif
+#endif
+
+#ifdef PHP_WIN32
+#include <windows.h>
+#include <wchar.h>
+#define _zip_rename(s, t) \
+ (!MoveFileExA((s), (t), \
+ MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
+
+/* for dup(), close(), etc. */
+#include <io.h>
+
+#if !defined(HAVE_OPEN)
+#if defined(HAVE__OPEN)
+#define open(a, b, c) _open((a), (b))
+#endif
+#endif
+
+#else
+#define _zip_rename rename
+#endif
+
+#ifndef strcasecmp
+# define strcmpi strcasecmp
+#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 TORRENT_SIG "TORRENTZIPPED-"
+#define TORRENT_SIG_LEN 14
+#define TORRENT_CRC_LEN 8
+#define TORRENT_MEM_LEVEL 8
+#define CDENTRYSIZE 46u
+#define LENTRYSIZE 30
+#undef MAXCOMLEN /* defined as 19 on BSD for max command name */
+#define MAXCOMLEN 65536
+#define MAXEXTLEN 65536
+#define EOCDLEN 22
+#define CDBUFSIZE (MAXCOMLEN+EOCDLEN)
+#define BUFSIZE 8192
+
+
+
+/* This section contains API that won't materialize like this. It's
+ placed in the internal section, pending cleanup. */
+
+typedef struct zip_source *(*zip_compression_implementation)(struct zip *,
+ struct zip_source *,
+ zip_uint16_t, int);
+typedef struct zip_source *(*zip_encryption_implementation)(struct zip *,
+ struct zip_source *,
+ zip_uint16_t, int,
+ const char *);
+
+ZIP_EXTERN(zip_compression_implementation) zip_get_compression_implementation(
+ zip_uint16_t);
+ZIP_EXTERN(zip_encryption_implementation) zip_get_encryption_implementation(
+ zip_uint16_t);
+
+
+
+
+/* This section contains API that is of limited use until support for
+ user-supplied compression/encryption implementation is finished.
+ Thus we will keep it private for now. */
+
+typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *,
+ void *, zip_uint64_t,
+ enum zip_source_cmd);
+
+ZIP_EXTERN(void) zip_source_close(struct zip_source *);
+ZIP_EXTERN(struct zip_source *)zip_source_crc(struct zip *, struct zip_source *,
+ int);
+ZIP_EXTERN(struct zip_source *)zip_source_deflate(struct zip *,
+ struct zip_source *,
+ zip_uint16_t, int);
+ZIP_EXTERN(void) zip_source_error(struct zip_source *, int *, int *);
+ZIP_EXTERN(struct zip_source *)zip_source_layered(struct zip *,
+ struct zip_source *,
+ zip_source_layered_callback,
+ void *);
+ZIP_EXTERN(int) zip_source_open(struct zip_source *);
+ZIP_EXTERN(struct zip_source *)zip_source_pkware(struct zip *,
+ struct zip_source *,
+ zip_uint16_t, int,
+ const char *);
+ZIP_EXTERN(zip_int64_t) zip_source_read(struct zip_source *, void *,
+ zip_uint64_t);
+ZIP_EXTERN(int) zip_source_stat(struct zip_source *, struct zip_stat *);
+
+
+/* This function will probably remain private. It is not needed to
+ implement compression/encryption routines. (We should probably
+ rename it to _zip_source_pop.) */
+
+ZIP_EXTERN(struct zip_source *)zip_source_pop(struct zip_source *);
+
+
+
+/* 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 };
+
+/* error source for layered sources */
+
+enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
+
+/* directory entry: general purpose bit flags */
+
+#define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */
+#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */
+#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */
+
+/* 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 */
+
+ unsigned int flags; /* archive global flags */
+ unsigned int ch_flags; /* changed archive global flags */
+
+ char *default_password; /* password used when no other supplied */
+
+ 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 */
+ zip_uint64_t nentry; /* number of entries */
+ zip_uint64_t 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 eof;
+ struct zip_source *src; /* data source */
+};
+
+/* 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 */
+};
+
+
+
+struct zip_source {
+ struct zip_source *src;
+ union {
+ zip_source_callback f;
+ zip_source_layered_callback l;
+ } cb;
+ void *ud;
+ enum zip_les error_source;
+ int is_open;
+};
+
+/* entry in zip archive directory */
+
+struct zip_entry {
+ enum zip_state state;
+ struct zip_source *source;
+ char *ch_filename;
+ char *ch_extra;
+ int ch_extra_len;
+ char *ch_comment;
+ int ch_comment_len;
+};
+
+
+
+extern const char * const _zip_err_str[];
+extern const int _zip_nerr_str;
+extern const int _zip_err_type[];
+
+
+
+#define ZIP_ENTRY_DATA_CHANGED(x) \
+ ((x)->state == ZIP_ST_REPLACED \
+ || (x)->state == ZIP_ST_ADDED)
+
+#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
+
+
+
+int _zip_cdir_compute_crc(struct zip *, uLong *);
+void _zip_cdir_free(struct zip_cdir *);
+int _zip_cdir_grow(struct zip_cdir *, int, struct zip_error *);
+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 **,
+ zip_uint32_t *, int, struct zip_error *);
+void _zip_dirent_torrent_normalize(struct zip_dirent *);
+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);
+void _zip_error_set_from_source(struct zip_error *, struct zip_source *);
+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);
+
+int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *);
+
+struct zip *_zip_open(const char *, FILE *, int, int, int *);
+
+struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *,
+ zip_uint64_t, zip_int64_t, int,
+ const struct zip_stat *);
+struct zip_source *_zip_source_new(struct zip *);
+
+int _zip_changed(struct zip *, int *);
+void _zip_free(struct zip *);
+const char *_zip_get_name(struct zip *, zip_uint64_t, 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 **);
+zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *,
+ struct zip_source *);
+int _zip_set_name(struct zip *, zip_uint64_t, const char *);
+void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
+int _zip_unchange(struct zip *, zip_uint64_t, int);
+void _zip_unchange_data(struct zip_entry *);
+
+#endif /* zipint.h */
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
new file mode 100644
index 0000000..5683b32
--- /dev/null
+++ b/ext/zip/php_zip.c
@@ -0,0 +1,2884 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Piere-Alain Joye <pierre@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id: 727cc853ca1ae15d995c3520c5719784ddc1e292 $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "ext/standard/file.h"
+#include "ext/standard/php_string.h"
+#include "ext/pcre/php_pcre.h"
+#include "php_zip.h"
+#include "lib/zip.h"
+#include "lib/zipint.h"
+
+/* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
+static PHP_NAMED_FUNCTION(zif_zip_open);
+static PHP_NAMED_FUNCTION(zif_zip_read);
+static PHP_NAMED_FUNCTION(zif_zip_close);
+static PHP_NAMED_FUNCTION(zif_zip_entry_read);
+static PHP_NAMED_FUNCTION(zif_zip_entry_filesize);
+static PHP_NAMED_FUNCTION(zif_zip_entry_name);
+static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize);
+static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod);
+static PHP_NAMED_FUNCTION(zif_zip_entry_open);
+static PHP_NAMED_FUNCTION(zif_zip_entry_close);
+
+#ifdef HAVE_GLOB
+#ifndef PHP_WIN32
+#include <glob.h>
+#else
+#include "win32/glob.h"
+#endif
+#endif
+
+/* {{{ Resource le */
+static int le_zip_dir;
+#define le_zip_dir_name "Zip Directory"
+static int le_zip_entry;
+#define le_zip_entry_name "Zip Entry"
+/* }}} */
+
+/* {{{ PHP_ZIP_STAT_INDEX(za, index, flags, sb) */
+#define PHP_ZIP_STAT_INDEX(za, index, flags, sb) \
+ if (zip_stat_index(za, index, flags, &sb) != 0) { \
+ RETURN_FALSE; \
+ }
+/* }}} */
+
+/* {{{ PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) */
+#define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \
+ if (path_len < 1) { \
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name"); \
+ RETURN_FALSE; \
+ } \
+ if (zip_stat(za, path, flags, &sb) != 0) { \
+ RETURN_FALSE; \
+ }
+/* }}} */
+
+/* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */
+#define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \
+ if (comment_len == 0) { \
+ /* Passing NULL remove the existing comment */ \
+ if (zip_set_file_comment(intern, index, NULL, 0) < 0) { \
+ RETURN_FALSE; \
+ } \
+ } else if (zip_set_file_comment(intern, index, comment, comment_len) < 0) { \
+ RETURN_FALSE; \
+ } \
+ RETURN_TRUE;
+/* }}} */
+
+#if (PHP_MAJOR_VERSION < 6)
+# define add_ascii_assoc_string add_assoc_string
+# define add_ascii_assoc_long add_assoc_long
+#endif
+
+/* Flatten a path by making a relative path (to .)*/
+static char * php_zip_make_relative_path(char *path, int path_len) /* {{{ */
+{
+ char *path_begin = path;
+ size_t i;
+
+ if (IS_SLASH(path[0])) {
+ return path + 1;
+ }
+
+ if (path_len < 1 || path == NULL) {
+ return NULL;
+ }
+
+ i = path_len;
+
+ while (1) {
+ while (i > 0 && !IS_SLASH(path[i])) {
+ i--;
+ }
+
+ if (!i) {
+ return path;
+ }
+
+ if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) {
+ /* i is the position of . or :, add 1 for / */
+ path_begin = path + i + 1;
+ break;
+ }
+ i--;
+ }
+
+ return path_begin;
+}
+/* }}} */
+
+#ifdef PHP_ZIP_USE_OO
+/* {{{ php_zip_extract_file */
+static int php_zip_extract_file(struct zip * za, char *dest, char *file, int file_len TSRMLS_DC)
+{
+ php_stream_statbuf ssb;
+ struct zip_file *zf;
+ struct zip_stat sb;
+ char b[8192];
+ int n, len, ret;
+ php_stream *stream;
+ char *fullpath;
+ char *file_dirname_fullpath;
+ char file_dirname[MAXPATHLEN];
+ size_t dir_len;
+ char *file_basename;
+ size_t file_basename_len;
+ int is_dir_only = 0;
+ char *path_cleaned;
+ size_t path_cleaned_len;
+ cwd_state new_state;
+
+ new_state.cwd = (char*)malloc(1);
+ new_state.cwd[0] = '\0';
+ new_state.cwd_length = 0;
+
+ /* Clean/normlize the path and then transform any path (absolute or relative)
+ to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
+ */
+ virtual_file_ex(&new_state, file, NULL, CWD_EXPAND TSRMLS_CC);
+ path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
+ if(!path_cleaned) {
+ return 0;
+ }
+ path_cleaned_len = strlen(path_cleaned);
+
+ if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) {
+ return 0;
+ }
+
+ /* it is a directory only, see #40228 */
+ if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) {
+ len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file);
+ is_dir_only = 1;
+ } else {
+ memcpy(file_dirname, path_cleaned, path_cleaned_len);
+ dir_len = php_dirname(file_dirname, path_cleaned_len);
+
+ if (dir_len <= 0 || (dir_len == 1 && file_dirname[0] == '.')) {
+ len = spprintf(&file_dirname_fullpath, 0, "%s", dest);
+ } else {
+ len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname);
+ }
+
+ php_basename(path_cleaned, path_cleaned_len, NULL, 0, &file_basename, (size_t *)&file_basename_len TSRMLS_CC);
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
+ efree(file_dirname_fullpath);
+ efree(file_basename);
+ free(new_state.cwd);
+ return 0;
+ }
+ }
+
+ /* let see if the path already exists */
+ if (php_stream_stat_path_ex(file_dirname_fullpath, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
+
+#if defined(PHP_WIN32) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1)
+ char *e;
+ e = file_dirname_fullpath;
+ while (*e) {
+ if (*e == '/') {
+ *e = DEFAULT_SLASH;
+ }
+ e++;
+ }
+#endif
+
+ ret = php_stream_mkdir(file_dirname_fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL);
+ if (!ret) {
+ efree(file_dirname_fullpath);
+ if (!is_dir_only) {
+ efree(file_basename);
+ free(new_state.cwd);
+ }
+ return 0;
+ }
+ }
+
+ /* it is a standalone directory, job done */
+ if (is_dir_only) {
+ efree(file_dirname_fullpath);
+ free(new_state.cwd);
+ return 1;
+ }
+
+ len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, file_basename);
+ if (!len) {
+ efree(file_dirname_fullpath);
+ efree(file_basename);
+ free(new_state.cwd);
+ return 0;
+ } else if (len > MAXPATHLEN) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
+ efree(file_dirname_fullpath);
+ efree(file_basename);
+ free(new_state.cwd);
+ return 0;
+ }
+
+ /* check again the full path, not sure if it
+ * is required, does a file can have a different
+ * safemode status as its parent folder?
+ */
+ if (ZIP_OPENBASEDIR_CHECKPATH(fullpath)) {
+ efree(fullpath);
+ efree(file_dirname_fullpath);
+ efree(file_basename);
+ free(new_state.cwd);
+ return 0;
+ }
+
+#if PHP_API_VERSION < 20100412
+ stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
+#else
+ stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL);
+#endif
+
+ if (stream == NULL) {
+ n = -1;
+ goto done;
+ }
+
+ zf = zip_fopen(za, file, 0);
+ if (zf == NULL) {
+ n = -1;
+ php_stream_close(stream);
+ goto done;
+ }
+
+ n = 0;
+
+ while ((n=zip_fread(zf, b, sizeof(b))) > 0) {
+ php_stream_write(stream, b, n);
+ }
+
+ php_stream_close(stream);
+ n = zip_fclose(zf);
+
+done:
+ efree(fullpath);
+ efree(file_basename);
+ efree(file_dirname_fullpath);
+ free(new_state.cwd);
+
+ if (n<0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+/* }}} */
+
+static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
+ char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */
+{
+ struct zip_source *zs;
+ int cur_idx;
+ char resolved_path[MAXPATHLEN];
+
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
+ return -1;
+ }
+
+ if (!expand_filepath(filename, resolved_path TSRMLS_CC)) {
+ return -1;
+ }
+
+ zs = zip_source_file(za, resolved_path, offset_start, offset_len);
+ if (!zs) {
+ return -1;
+ }
+
+ cur_idx = zip_name_locate(za, (const char *)entry_name, 0);
+ /* TODO: fix _zip_replace */
+ if (cur_idx<0) {
+ /* reset the error */
+ if (za->error.str) {
+ _zip_error_fini(&za->error);
+ }
+ _zip_error_init(&za->error);
+ } else {
+ if (zip_delete(za, cur_idx) == -1) {
+ zip_source_free(zs);
+ return -1;
+ }
+ }
+
+ if (zip_add(za, entry_name, zs) == -1) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+/* }}} */
+
+static int php_zip_parse_options(zval *options, long *remove_all_path,
+ char **remove_path, int *remove_path_len, char **add_path, int *add_path_len TSRMLS_DC) /* {{{ */
+{
+ zval **option;
+ if (zend_hash_find(HASH_OF(options), "remove_all_path", sizeof("remove_all_path"), (void **)&option) == SUCCESS) {
+ long opt;
+ if (Z_TYPE_PP(option) != IS_LONG) {
+ zval tmp = **option;
+ zval_copy_ctor(&tmp);
+ convert_to_long(&tmp);
+ opt = Z_LVAL(tmp);
+ } else {
+ opt = Z_LVAL_PP(option);
+ }
+ *remove_all_path = opt;
+ }
+
+ /* If I add more options, it would make sense to create a nice static struct and loop over it. */
+ if (zend_hash_find(HASH_OF(options), "remove_path", sizeof("remove_path"), (void **)&option) == SUCCESS) {
+ if (Z_TYPE_PP(option) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path option expected to be a string");
+ return -1;
+ }
+
+ if (Z_STRLEN_PP(option) < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string given as remove_path option");
+ return -1;
+ }
+
+ if (Z_STRLEN_PP(option) >= MAXPATHLEN) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path string is too long (max: %i, %i given)",
+ MAXPATHLEN - 1, Z_STRLEN_PP(option));
+ return -1;
+ }
+ *remove_path_len = Z_STRLEN_PP(option);
+ *remove_path = Z_STRVAL_PP(option);
+ }
+
+ if (zend_hash_find(HASH_OF(options), "add_path", sizeof("add_path"), (void **)&option) == SUCCESS) {
+ if (Z_TYPE_PP(option) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path option expected to be a string");
+ return -1;
+ }
+
+ if (Z_STRLEN_PP(option) < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string given as the add_path option");
+ return -1;
+ }
+
+ if (Z_STRLEN_PP(option) >= MAXPATHLEN) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
+ MAXPATHLEN - 1, Z_STRLEN_PP(option));
+ return -1;
+ }
+ *add_path_len = Z_STRLEN_PP(option);
+ *add_path = Z_STRVAL_PP(option);
+ }
+ return 1;
+}
+/* }}} */
+
+/* {{{ REGISTER_ZIP_CLASS_CONST_LONG */
+#define REGISTER_ZIP_CLASS_CONST_LONG(const_name, value) \
+ zend_declare_class_constant_long(zip_class_entry, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
+/* }}} */
+
+/* {{{ ZIP_FROM_OBJECT */
+#define ZIP_FROM_OBJECT(intern, object) \
+ { \
+ ze_zip_object *obj = (ze_zip_object*) zend_object_store_get_object(object TSRMLS_CC); \
+ intern = obj->za; \
+ if (!intern) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized Zip object"); \
+ RETURN_FALSE; \
+ } \
+ }
+/* }}} */
+
+/* {{{ RETURN_SB(sb) */
+#define RETURN_SB(sb) \
+ { \
+ array_init(return_value); \
+ add_ascii_assoc_string(return_value, "name", (char *)(sb)->name, 1); \
+ add_ascii_assoc_long(return_value, "index", (long) (sb)->index); \
+ add_ascii_assoc_long(return_value, "crc", (long) (sb)->crc); \
+ add_ascii_assoc_long(return_value, "size", (long) (sb)->size); \
+ add_ascii_assoc_long(return_value, "mtime", (long) (sb)->mtime); \
+ add_ascii_assoc_long(return_value, "comp_size", (long) (sb)->comp_size); \
+ add_ascii_assoc_long(return_value, "comp_method", (long) (sb)->comp_method); \
+ }
+/* }}} */
+
+static int php_zip_status(struct zip *za TSRMLS_DC) /* {{{ */
+{
+ int zep, syp;
+
+ zip_error_get(za, &zep, &syp);
+ return zep;
+}
+/* }}} */
+
+static int php_zip_status_sys(struct zip *za TSRMLS_DC) /* {{{ */
+{
+ int zep, syp;
+
+ zip_error_get(za, &zep, &syp);
+ return syp;
+}
+/* }}} */
+
+static int php_zip_get_num_files(struct zip *za TSRMLS_DC) /* {{{ */
+{
+ return zip_get_num_files(za);
+}
+/* }}} */
+
+static char * php_zipobj_get_filename(ze_zip_object *obj TSRMLS_DC) /* {{{ */
+{
+
+ if (!obj) {
+ return NULL;
+ }
+
+ if (obj->filename) {
+ return obj->filename;
+ }
+ return NULL;
+}
+/* }}} */
+
+static char * php_zipobj_get_zip_comment(struct zip *za, int *len TSRMLS_DC) /* {{{ */
+{
+ if (za) {
+ return (char *)zip_get_archive_comment(za, len, 0);
+ }
+ return NULL;
+}
+/* }}} */
+
+#ifdef HAVE_GLOB /* {{{ */
+#ifndef GLOB_ONLYDIR
+#define GLOB_ONLYDIR (1<<30)
+#define GLOB_EMULATE_ONLYDIR
+#define GLOB_FLAGMASK (~GLOB_ONLYDIR)
+#else
+#define GLOB_FLAGMASK (~0)
+#endif
+#ifndef GLOB_BRACE
+# define GLOB_BRACE 0
+#endif
+#ifndef GLOB_MARK
+# define GLOB_MARK 0
+#endif
+#ifndef GLOB_NOSORT
+# define GLOB_NOSORT 0
+#endif
+#ifndef GLOB_NOCHECK
+# define GLOB_NOCHECK 0
+#endif
+#ifndef GLOB_NOESCAPE
+# define GLOB_NOESCAPE 0
+#endif
+#ifndef GLOB_ERR
+# define GLOB_ERR 0
+#endif
+
+/* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
+#define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
+
+#endif /* }}} */
+
+int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value TSRMLS_DC) /* {{{ */
+{
+#ifdef HAVE_GLOB
+ char cwd[MAXPATHLEN];
+ int cwd_skip = 0;
+#ifdef ZTS
+ char work_pattern[MAXPATHLEN];
+ char *result;
+#endif
+ glob_t globbuf;
+ int n;
+ int ret;
+
+ if (pattern_len >= MAXPATHLEN) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
+ return -1;
+ }
+
+ if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
+ return -1;
+ }
+
+#ifdef ZTS
+ if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
+ result = VCWD_GETCWD(cwd, MAXPATHLEN);
+ if (!result) {
+ cwd[0] = '\0';
+ }
+#ifdef PHP_WIN32
+ if (IS_SLASH(*pattern)) {
+ cwd[2] = '\0';
+ }
+#endif
+ cwd_skip = strlen(cwd)+1;
+
+ snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
+ pattern = work_pattern;
+ }
+#endif
+
+ globbuf.gl_offs = 0;
+ if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
+#ifdef GLOB_NOMATCH
+ if (GLOB_NOMATCH == ret) {
+ /* Some glob implementation simply return no data if no matches
+ were found, others return the GLOB_NOMATCH error code.
+ We don't want to treat GLOB_NOMATCH as an error condition
+ so that PHP glob() behaves the same on both types of
+ implementations and so that 'foreach (glob() as ...'
+ can be used for simple glob() calls without further error
+ checking.
+ */
+ array_init(return_value);
+ return 0;
+ }
+#endif
+ return 0;
+ }
+
+ /* now catch the FreeBSD style of "no matches" */
+ if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
+ array_init(return_value);
+ return 0;
+ }
+
+ /* we assume that any glob pattern will match files from one directory only
+ so checking the dirname of the first match should be sufficient */
+ strncpy(cwd, globbuf.gl_pathv[0], MAXPATHLEN);
+ if (ZIP_OPENBASEDIR_CHECKPATH(cwd)) {
+ return -1;
+ }
+
+ array_init(return_value);
+ for (n = 0; n < globbuf.gl_pathc; n++) {
+ /* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
+ * all directories will be filtered. GNU libc documentation states the
+ * following:
+ * If the information about the type of the file is easily available
+ * non-directories will be rejected but no extra work will be done to
+ * determine the information for each file. I.e., the caller must still be
+ * able to filter directories out.
+ */
+ if (flags & GLOB_ONLYDIR) {
+ struct stat s;
+
+ if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
+ continue;
+ }
+
+ if (S_IFDIR != (s.st_mode & S_IFMT)) {
+ continue;
+ }
+ }
+ add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip, 1);
+ }
+
+ globfree(&globbuf);
+ return globbuf.gl_pathc;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Glob support is not available");
+ return 0;
+#endif /* HAVE_GLOB */
+}
+/* }}} */
+
+int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *return_value TSRMLS_DC) /* {{{ */
+{
+#ifdef ZTS
+ char cwd[MAXPATHLEN];
+ int cwd_skip = 0;
+ char work_path[MAXPATHLEN];
+ char *result;
+#endif
+ int files_cnt;
+ char **namelist;
+
+#ifdef ZTS
+ if (!IS_ABSOLUTE_PATH(path, path_len)) {
+ result = VCWD_GETCWD(cwd, MAXPATHLEN);
+ if (!result) {
+ cwd[0] = '\0';
+ }
+#ifdef PHP_WIN32
+ if (IS_SLASH(*path)) {
+ cwd[2] = '\0';
+ }
+#endif
+ cwd_skip = strlen(cwd)+1;
+
+ snprintf(work_path, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, path);
+ path = work_path;
+ }
+#endif
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(path)) {
+ return -1;
+ }
+
+ files_cnt = php_stream_scandir(path, &namelist, NULL, (void *) php_stream_dirent_alphasort);
+
+ if (files_cnt > 0) {
+ pcre *re = NULL;
+ pcre_extra *pcre_extra = NULL;
+ int preg_options = 0, i;
+
+ re = pcre_get_compiled_regex(regexp, &pcre_extra, &preg_options TSRMLS_CC);
+ if (!re) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid expression");
+ return -1;
+ }
+
+ array_init(return_value);
+
+ /* only the files, directories are ignored */
+ for (i = 0; i < files_cnt; i++) {
+ struct stat s;
+ char fullpath[MAXPATHLEN];
+ int ovector[3];
+ int matches;
+ int namelist_len = strlen(namelist[i]);
+
+
+ if ((namelist_len == 1 && namelist[i][0] == '.') ||
+ (namelist_len == 2 && namelist[i][0] == '.' && namelist[i][1] == '.')) {
+ efree(namelist[i]);
+ continue;
+ }
+
+ if ((path_len + namelist_len + 1) >= MAXPATHLEN) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
+ MAXPATHLEN - 1, (path_len + namelist_len + 1));
+ efree(namelist[i]);
+ break;
+ }
+
+ snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, namelist[i]);
+
+ if (0 != VCWD_STAT(fullpath, &s)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot read <%s>", fullpath);
+ efree(namelist[i]);
+ continue;
+ }
+
+ if (S_IFDIR == (s.st_mode & S_IFMT)) {
+ efree(namelist[i]);
+ continue;
+ }
+
+ matches = pcre_exec(re, NULL, namelist[i], strlen(namelist[i]), 0, 0, ovector, 3);
+ /* 0 means that the vector is too small to hold all the captured substring offsets */
+ if (matches < 0) {
+ efree(namelist[i]);
+ continue;
+ }
+
+ add_next_index_string(return_value, fullpath, 1);
+ efree(namelist[i]);
+ }
+ efree(namelist);
+ }
+ return files_cnt;
+}
+/* }}} */
+
+#endif
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_close, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_read, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_open, 0, 0, 2)
+ ZEND_ARG_INFO(0, zip_dp)
+ ZEND_ARG_INFO(0, zip_entry)
+ ZEND_ARG_INFO(0, mode)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_close, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip_ent)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_read, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip_entry)
+ ZEND_ARG_INFO(0, len)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_name, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip_entry)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressedsize, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip_entry)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_filesize, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip_entry)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressionmethod, 0, 0, 1)
+ ZEND_ARG_INFO(0, zip_entry)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ zend_function_entry */
+static const zend_function_entry zip_functions[] = {
+ ZEND_RAW_FENTRY("zip_open", zif_zip_open, arginfo_zip_open, 0)
+ ZEND_RAW_FENTRY("zip_close", zif_zip_close, arginfo_zip_close, 0)
+ ZEND_RAW_FENTRY("zip_read", zif_zip_read, arginfo_zip_read, 0)
+ PHP_FE(zip_entry_open, arginfo_zip_entry_open)
+ PHP_FE(zip_entry_close, arginfo_zip_entry_close)
+ PHP_FE(zip_entry_read, arginfo_zip_entry_read)
+ PHP_FE(zip_entry_filesize, arginfo_zip_entry_filesize)
+ PHP_FE(zip_entry_name, arginfo_zip_entry_name)
+ PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize)
+ PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ ZE2 OO definitions */
+#ifdef PHP_ZIP_USE_OO
+static zend_class_entry *zip_class_entry;
+static zend_object_handlers zip_object_handlers;
+
+static HashTable zip_prop_handlers;
+
+typedef int (*zip_read_int_t)(struct zip *za TSRMLS_DC);
+typedef char *(*zip_read_const_char_t)(struct zip *za, int *len TSRMLS_DC);
+typedef char *(*zip_read_const_char_from_ze_t)(ze_zip_object *obj TSRMLS_DC);
+
+typedef struct _zip_prop_handler {
+ zip_read_int_t read_int_func;
+ zip_read_const_char_t read_const_char_func;
+ zip_read_const_char_from_ze_t read_const_char_from_obj_func;
+
+ int type;
+} zip_prop_handler;
+#endif
+/* }}} */
+
+#ifdef PHP_ZIP_USE_OO
+static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, zip_read_int_t read_int_func, zip_read_const_char_t read_char_func, zip_read_const_char_from_ze_t read_char_from_obj_func, int rettype TSRMLS_DC) /* {{{ */
+{
+ zip_prop_handler hnd;
+
+ hnd.read_const_char_func = read_char_func;
+ hnd.read_int_func = read_int_func;
+ hnd.read_const_char_from_obj_func = read_char_from_obj_func;
+ hnd.type = rettype;
+ zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(zip_prop_handler), NULL);
+}
+/* }}} */
+
+static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zval **retval, int newzval TSRMLS_DC) /* {{{ */
+{
+ const char *retchar = NULL;
+ int retint = 0;
+ int len = 0;
+
+ if (obj && obj->za != NULL) {
+ if (hnd->read_const_char_func) {
+ retchar = hnd->read_const_char_func(obj->za, &len TSRMLS_CC);
+ } else {
+ if (hnd->read_int_func) {
+ retint = hnd->read_int_func(obj->za TSRMLS_CC);
+ if (retint == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal zip error returned");
+ return FAILURE;
+ }
+ } else {
+ if (hnd->read_const_char_from_obj_func) {
+ retchar = hnd->read_const_char_from_obj_func(obj TSRMLS_CC);
+ len = strlen(retchar);
+ }
+ }
+ }
+ }
+
+ if (newzval) {
+ ALLOC_ZVAL(*retval);
+ }
+
+ switch (hnd->type) {
+ case IS_STRING:
+ if (retchar) {
+ ZVAL_STRINGL(*retval, (char *) retchar, len, 1);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+ break;
+ case IS_BOOL:
+ ZVAL_BOOL(*retval, (long)retint);
+ break;
+ case IS_LONG:
+ ZVAL_LONG(*retval, (long)retint);
+ break;
+ default:
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+{
+ ze_zip_object *obj;
+ zval tmp_member;
+ zval **retval = NULL;
+
+ zip_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ key = NULL;
+ }
+
+ ret = FAILURE;
+ obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ if (key) {
+ ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
+ } else {
+ ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ }
+
+
+ if (ret == FAILURE) {
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+ return retval;
+}
+/* }}} */
+
+static zval* php_zip_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
+{
+ ze_zip_object *obj;
+ zval tmp_member;
+ zval *retval;
+ zip_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ key = NULL;
+ }
+
+ ret = FAILURE;
+ obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ if (key) {
+ ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
+ } else {
+ ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ }
+
+ if (ret == SUCCESS) {
+ ret = php_zip_property_reader(obj, hnd, &retval, 1 TSRMLS_CC);
+ if (ret == SUCCESS) {
+ /* ensure we're creating a temporary variable */
+ Z_SET_REFCOUNT_P(retval, 0);
+ } else {
+ retval = EG(uninitialized_zval_ptr);
+ }
+ } else {
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+ return retval;
+}
+/* }}} */
+
+static int php_zip_has_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
+{
+ ze_zip_object *obj;
+ zval tmp_member;
+ zip_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret, retval = 0;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ key = NULL;
+ }
+
+ ret = FAILURE;
+ obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ if (key) {
+ ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
+ } else {
+ ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ }
+
+ if (ret == SUCCESS) {
+ zval *tmp;
+ ALLOC_INIT_ZVAL(tmp);
+
+ if (type == 2) {
+ retval = 1;
+ } else if (php_zip_property_reader(obj, hnd, &tmp, 0 TSRMLS_CC) == SUCCESS) {
+ Z_SET_REFCOUNT_P(tmp, 1);
+ Z_UNSET_ISREF_P(tmp);
+ if (type == 1) {
+ retval = zend_is_true(tmp);
+ } else if (type == 0) {
+ retval = (Z_TYPE_P(tmp) != IS_NULL);
+ }
+ }
+
+ zval_ptr_dtor(&tmp);
+ } else {
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->has_property(object, member, type, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+ return retval;
+}
+/* }}} */
+
+static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */
+{
+ ze_zip_object *obj;
+ zip_prop_handler *hnd;
+ HashTable *props;
+ zval *val;
+ int ret;
+ char *key;
+ uint key_len;
+ HashPosition pos;
+ ulong num_key;
+
+ obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
+ props = zend_std_get_properties(object TSRMLS_CC);
+
+ if (obj->prop_handler == NULL) {
+ return NULL;
+ }
+ zend_hash_internal_pointer_reset_ex(obj->prop_handler, &pos);
+
+ while (zend_hash_get_current_data_ex(obj->prop_handler, (void**)&hnd, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(obj->prop_handler, &key, &key_len, &num_key, 0, &pos);
+ MAKE_STD_ZVAL(val);
+ ret = php_zip_property_reader(obj, hnd, &val, 0 TSRMLS_CC);
+ if (ret != SUCCESS) {
+ val = EG(uninitialized_zval_ptr);
+ }
+ zend_hash_update(props, key, key_len, (void *)&val, sizeof(zval *), NULL);
+ zend_hash_move_forward_ex(obj->prop_handler, &pos);
+ }
+ return props;
+}
+/* }}} */
+
+static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+{
+ ze_zip_object * intern = (ze_zip_object *) object;
+ int i;
+
+ if (!intern) {
+ return;
+ }
+ if (intern->za) {
+ if (zip_close(intern->za) != 0) {
+ _zip_free(intern->za);
+ }
+ intern->za = NULL;
+ }
+
+ if (intern->buffers_cnt>0) {
+ for (i=0; i<intern->buffers_cnt; i++) {
+ efree(intern->buffers[i]);
+ }
+ efree(intern->buffers);
+ }
+
+ intern->za = NULL;
+
+#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
+ zend_object_std_dtor(&intern->zo TSRMLS_CC);
+#else
+ if (intern->zo.guards) {
+ zend_hash_destroy(intern->zo.guards);
+ FREE_HASHTABLE(intern->zo.guards);
+ }
+
+ if (intern->zo.properties) {
+ zend_hash_destroy(intern->zo.properties);
+ FREE_HASHTABLE(intern->zo.properties);
+ }
+#endif
+
+ if (intern->filename) {
+ efree(intern->filename);
+ }
+ efree(intern);
+}
+/* }}} */
+
+static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+{
+ ze_zip_object *intern;
+ zend_object_value retval;
+
+ intern = emalloc(sizeof(ze_zip_object));
+ memset(&intern->zo, 0, sizeof(zend_object));
+
+ intern->za = NULL;
+ intern->buffers = NULL;
+ intern->filename = NULL;
+ intern->buffers_cnt = 0;
+ intern->prop_handler = &zip_prop_handlers;
+
+#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2))
+ zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
+#else
+ ALLOC_HASHTABLE(intern->zo.properties);
+ zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+ intern->zo.ce = class_type;
+#endif
+
+ object_properties_init(&intern->zo, class_type);
+
+ retval.handle = zend_objects_store_put(intern,
+ NULL,
+ (zend_objects_free_object_storage_t) php_zip_object_free_storage,
+ NULL TSRMLS_CC);
+
+ retval.handlers = (zend_object_handlers *) & zip_object_handlers;
+
+ return retval;
+}
+/* }}} */
+#endif
+
+/* {{{ Resource dtors */
+
+/* {{{ php_zip_free_dir */
+static void php_zip_free_dir(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ zip_rsrc * zip_int = (zip_rsrc *) rsrc->ptr;
+
+ if (zip_int) {
+ if (zip_int->za) {
+ if (zip_close(zip_int->za) != 0) {
+ _zip_free(zip_int->za);
+ }
+ zip_int->za = NULL;
+ }
+
+ efree(rsrc->ptr);
+
+ rsrc->ptr = NULL;
+ }
+}
+/* }}} */
+
+/* {{{ php_zip_free_entry */
+static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ zip_read_rsrc *zr_rsrc = (zip_read_rsrc *) rsrc->ptr;
+
+ if (zr_rsrc) {
+ if (zr_rsrc->zf) {
+ if (zr_rsrc->zf->za) {
+ zip_fclose(zr_rsrc->zf);
+ } else {
+ if (zr_rsrc->zf->src)
+ zip_source_free(zr_rsrc->zf->src);
+ free(zr_rsrc->zf);
+ }
+ zr_rsrc->zf = NULL;
+ }
+ efree(zr_rsrc);
+ rsrc->ptr = NULL;
+ }
+}
+/* }}} */
+
+/* }}}*/
+
+/* reset macro */
+
+/* {{{ function prototypes */
+static PHP_MINIT_FUNCTION(zip);
+static PHP_MSHUTDOWN_FUNCTION(zip);
+static PHP_MINFO_FUNCTION(zip);
+/* }}} */
+
+/* {{{ zip_module_entry
+ */
+zend_module_entry zip_module_entry = {
+ STANDARD_MODULE_HEADER,
+ "zip",
+ zip_functions,
+ PHP_MINIT(zip),
+ PHP_MSHUTDOWN(zip),
+ NULL,
+ NULL,
+ PHP_MINFO(zip),
+ PHP_ZIP_VERSION_STRING,
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_ZIP
+ZEND_GET_MODULE(zip)
+#endif
+/* set macro */
+
+/* {{{ proto resource zip_open(string filename)
+Create new zip using source uri for output */
+static PHP_NAMED_FUNCTION(zif_zip_open)
+{
+ char *filename;
+ int filename_len;
+ char resolved_path[MAXPATHLEN + 1];
+ zip_rsrc *rsrc_int;
+ int err = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
+ return;
+ }
+
+ if (filename_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
+ RETURN_FALSE;
+ }
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
+ RETURN_FALSE;
+ }
+
+ if(!expand_filepath(filename, resolved_path TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ rsrc_int = (zip_rsrc *)emalloc(sizeof(zip_rsrc));
+
+ rsrc_int->za = zip_open(resolved_path, 0, &err);
+ if (rsrc_int->za == NULL) {
+ efree(rsrc_int);
+ RETURN_LONG((long)err);
+ }
+
+ rsrc_int->index_current = 0;
+ rsrc_int->num_files = zip_get_num_files(rsrc_int->za);
+
+ ZEND_REGISTER_RESOURCE(return_value, rsrc_int, le_zip_dir);
+}
+/* }}} */
+
+/* {{{ proto void zip_close(resource zip)
+ Close a Zip archive */
+static PHP_NAMED_FUNCTION(zif_zip_close)
+{
+ zval * zip;
+ zip_rsrc *z_rsrc = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip) == FAILURE) {
+ return;
+ }
+ ZEND_FETCH_RESOURCE(z_rsrc, zip_rsrc *, &zip, -1, le_zip_dir_name, le_zip_dir);
+
+ /* really close the zip will break BC :-D */
+ zend_list_delete(Z_LVAL_P(zip));
+}
+/* }}} */
+
+/* {{{ proto resource zip_read(resource zip)
+ Returns the next file in the archive */
+static PHP_NAMED_FUNCTION(zif_zip_read)
+{
+ zval *zip_dp;
+ zip_read_rsrc *zr_rsrc;
+ int ret;
+ zip_rsrc *rsrc_int;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip_dp) == FAILURE) {
+ return;
+ }
+ ZEND_FETCH_RESOURCE(rsrc_int, zip_rsrc *, &zip_dp, -1, le_zip_dir_name, le_zip_dir);
+
+ if (rsrc_int && rsrc_int->za) {
+ if (rsrc_int->index_current >= rsrc_int->num_files) {
+ RETURN_FALSE;
+ }
+
+ zr_rsrc = emalloc(sizeof(zip_read_rsrc));
+
+ ret = zip_stat_index(rsrc_int->za, rsrc_int->index_current, 0, &zr_rsrc->sb);
+
+ if (ret != 0) {
+ efree(zr_rsrc);
+ RETURN_FALSE;
+ }
+
+ zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0);
+ if (zr_rsrc->zf) {
+ rsrc_int->index_current++;
+ ZEND_REGISTER_RESOURCE(return_value, zr_rsrc, le_zip_entry);
+ } else {
+ efree(zr_rsrc);
+ RETURN_FALSE;
+ }
+
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
+ Open a Zip File, pointed by the resource entry */
+/* Dummy function to follow the old API */
+static PHP_NAMED_FUNCTION(zif_zip_entry_open)
+{
+ zval * zip;
+ zval * zip_entry;
+ char *mode = NULL;
+ int mode_len = 0;
+ zip_read_rsrc * zr_rsrc;
+ zip_rsrc *z_rsrc;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|s", &zip, &zip_entry, &mode, &mode_len) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
+ ZEND_FETCH_RESOURCE(z_rsrc, zip_rsrc *, &zip, -1, le_zip_dir_name, le_zip_dir);
+
+ if (zr_rsrc->zf != NULL) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool zip_entry_close(resource zip_ent)
+ Close a zip entry */
+static PHP_NAMED_FUNCTION(zif_zip_entry_close)
+{
+ zval * zip_entry;
+ zip_read_rsrc * zr_rsrc;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip_entry) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
+
+ RETURN_BOOL(SUCCESS == zend_list_delete(Z_LVAL_P(zip_entry)));
+}
+/* }}} */
+
+/* {{{ proto mixed zip_entry_read(resource zip_entry [, int len])
+ Read from an open directory entry */
+static PHP_NAMED_FUNCTION(zif_zip_entry_read)
+{
+ zval * zip_entry;
+ long len = 0;
+ zip_read_rsrc * zr_rsrc;
+ char *buffer;
+ int n = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zip_entry, &len) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
+
+ if (len <= 0) {
+ len = 1024;
+ }
+
+ if (zr_rsrc->zf) {
+ buffer = safe_emalloc(len, 1, 1);
+ n = zip_fread(zr_rsrc->zf, buffer, len);
+ if (n > 0) {
+ buffer[n] = 0;
+ RETURN_STRINGL(buffer, n, 0);
+ } else {
+ efree(buffer);
+ RETURN_EMPTY_STRING()
+ }
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ */
+{
+ zval * zip_entry;
+ zip_read_rsrc * zr_rsrc;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip_entry) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
+
+ if (!zr_rsrc->zf) {
+ RETURN_FALSE;
+ }
+
+ switch (opt) {
+ case 0:
+ RETURN_STRING((char *)zr_rsrc->sb.name, 1);
+ break;
+ case 1:
+ RETURN_LONG((long) (zr_rsrc->sb.comp_size));
+ break;
+ case 2:
+ RETURN_LONG((long) (zr_rsrc->sb.size));
+ break;
+ case 3:
+ switch (zr_rsrc->sb.comp_method) {
+ case 0:
+ RETURN_STRING("stored", 1);
+ break;
+ case 1:
+ RETURN_STRING("shrunk", 1);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ RETURN_STRING("reduced", 1);
+ break;
+ case 6:
+ RETURN_STRING("imploded", 1);
+ break;
+ case 7:
+ RETURN_STRING("tokenized", 1);
+ break;
+ case 8:
+ RETURN_STRING("deflated", 1);
+ break;
+ case 9:
+ RETURN_STRING("deflatedX", 1);
+ break;
+ case 10:
+ RETURN_STRING("implodedX", 1);
+ break;
+ default:
+ RETURN_FALSE;
+ }
+ RETURN_LONG((long) (zr_rsrc->sb.comp_method));
+ break;
+ }
+
+}
+/* }}} */
+
+/* {{{ proto string zip_entry_name(resource zip_entry)
+ Return the name given a ZZip entry */
+static PHP_NAMED_FUNCTION(zif_zip_entry_name)
+{
+ php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto int zip_entry_compressedsize(resource zip_entry)
+ Return the compressed size of a ZZip entry */
+static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize)
+{
+ php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto int zip_entry_filesize(resource zip_entry)
+ Return the actual filesize of a ZZip entry */
+static PHP_NAMED_FUNCTION(zif_zip_entry_filesize)
+{
+ php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
+}
+/* }}} */
+
+/* {{{ proto string zip_entry_compressionmethod(resource zip_entry)
+ Return a string containing the compression method used on a particular entry */
+static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod)
+{
+ php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3);
+}
+/* }}} */
+
+#ifdef PHP_ZIP_USE_OO
+/* {{{ proto mixed ZipArchive::open(string source [, int flags])
+Create new zip using source uri for output, return TRUE on success or the error code */
+static ZIPARCHIVE_METHOD(open)
+{
+ struct zip *intern;
+ char *filename;
+ int filename_len;
+ int err = 0;
+ long flags = 0;
+ char resolved_path[MAXPATHLEN];
+
+ zval *this = getThis();
+ ze_zip_object *ze_obj = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &flags) == FAILURE) {
+ return;
+ }
+
+ if (this) {
+ /* We do not use ZIP_FROM_OBJECT, zip init function here */
+ ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
+ }
+
+ if (filename_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
+ RETURN_FALSE;
+ }
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
+ RETURN_FALSE;
+ }
+
+ if (!expand_filepath(filename, resolved_path TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ if (ze_obj->za) {
+ /* we already have an opened zip, free it */
+ if (zip_close(ze_obj->za) != 0) {
+ _zip_free(ze_obj->za);
+ }
+ ze_obj->za = NULL;
+ }
+ if (ze_obj->filename) {
+ efree(ze_obj->filename);
+ ze_obj->filename = NULL;
+ }
+
+ intern = zip_open(resolved_path, flags, &err);
+ if (!intern || err) {
+ RETURN_LONG((long)err);
+ }
+ ze_obj->filename = estrdup(resolved_path);
+ ze_obj->filename_len = filename_len;
+ ze_obj->za = intern;
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::close()
+close the zip archive */
+static ZIPARCHIVE_METHOD(close)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ ze_zip_object *ze_obj;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
+
+ if (zip_close(intern)) {
+ RETURN_FALSE;
+ }
+
+ efree(ze_obj->filename);
+ ze_obj->filename = NULL;
+ ze_obj->filename_len = 0;
+ ze_obj->za = NULL;
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getStatusString()
+ * Returns the status error message, system and/or zip messages */
+static ZIPARCHIVE_METHOD(getStatusString)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ int zep, syp, len;
+ char error_string[128];
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ zip_error_get(intern, &zep, &syp);
+
+ len = zip_error_to_str(error_string, 128, zep, syp);
+ RETVAL_STRINGL(error_string, len, 1);
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::createEmptyDir(string dirname)
+Returns the index of the entry named filename in the archive */
+static ZIPARCHIVE_METHOD(addEmptyDir)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *dirname;
+ int dirname_len;
+ int idx;
+ struct zip_stat sb;
+ char *s;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &dirname, &dirname_len) == FAILURE) {
+ return;
+ }
+
+ if (dirname_len<1) {
+ RETURN_FALSE;
+ }
+
+ if (dirname[dirname_len-1] != '/') {
+ s=(char *)emalloc(dirname_len+2);
+ strcpy(s, dirname);
+ s[dirname_len] = '/';
+ s[dirname_len+1] = '\0';
+ } else {
+ s = dirname;
+ }
+
+ idx = zip_stat(intern, s, 0, &sb);
+ if (idx >= 0) {
+ RETVAL_FALSE;
+ } else {
+ if (zip_add_dir(intern, (const char *)s) == -1) {
+ RETVAL_FALSE;
+ }
+ RETVAL_TRUE;
+ }
+
+ if (s != dirname) {
+ efree(s);
+ }
+}
+/* }}} */
+
+static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *pattern;
+ char *path = NULL;
+ char *remove_path = NULL;
+ char *add_path = NULL;
+ int pattern_len, add_path_len, remove_path_len, path_len = 0;
+ long remove_all_path = 0;
+ long flags = 0;
+ zval *options = NULL;
+ int found;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+ /* 1 == glob, 2==pcre */
+ if (type == 1) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la",
+ &pattern, &pattern_len, &flags, &options) == FAILURE) {
+ return;
+ }
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa",
+ &pattern, &pattern_len, &path, &path_len, &options) == FAILURE) {
+ return;
+ }
+ }
+
+ if (pattern_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as pattern");
+ RETURN_FALSE;
+ }
+ if (options && (php_zip_parse_options(options, &remove_all_path, &remove_path, &remove_path_len,
+ &add_path, &add_path_len TSRMLS_CC) < 0)) {
+ RETURN_FALSE;
+ }
+
+ if (remove_path && remove_path_len > 1 && (remove_path[strlen(remove_path) - 1] == '/' ||
+ remove_path[strlen(remove_path) - 1] == '\\')) {
+ remove_path[strlen(remove_path) - 1] = '\0';
+ }
+
+ if (type == 1) {
+ found = php_zip_glob(pattern, pattern_len, flags, return_value TSRMLS_CC);
+ } else {
+ found = php_zip_pcre(pattern, pattern_len, path, path_len, return_value TSRMLS_CC);
+ }
+
+ if (found > 0) {
+ int i;
+ zval **zval_file = NULL;
+
+ for (i = 0; i < found; i++) {
+ char *file, *file_stripped, *entry_name;
+ size_t entry_name_len, file_stripped_len;
+ char entry_name_buf[MAXPATHLEN];
+ char *basename = NULL;
+
+ if (zend_hash_index_find(Z_ARRVAL_P(return_value), i, (void **) &zval_file) == SUCCESS) {
+ file = Z_STRVAL_PP(zval_file);
+ if (remove_all_path) {
+ php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0,
+ &basename, (size_t *)&file_stripped_len TSRMLS_CC);
+ file_stripped = basename;
+ } else if (remove_path && strstr(Z_STRVAL_PP(zval_file), remove_path) != NULL) {
+ file_stripped = Z_STRVAL_PP(zval_file) + remove_path_len + 1;
+ file_stripped_len = Z_STRLEN_PP(zval_file) - remove_path_len - 1;
+ } else {
+ file_stripped = Z_STRVAL_PP(zval_file);
+ file_stripped_len = Z_STRLEN_PP(zval_file);
+ }
+
+ if (add_path) {
+ if ((add_path_len + file_stripped_len) > MAXPATHLEN) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Entry name too long (max: %d, %ld given)",
+ MAXPATHLEN - 1, (add_path_len + file_stripped_len));
+ zval_dtor(return_value);
+ RETURN_FALSE;
+ }
+
+ snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped);
+ entry_name = entry_name_buf;
+ entry_name_len = strlen(entry_name);
+ } else {
+ entry_name = Z_STRVAL_PP(zval_file);
+ entry_name_len = Z_STRLEN_PP(zval_file);
+ }
+ if (basename) {
+ efree(basename);
+ basename = NULL;
+ }
+ if (php_zip_add_file(intern, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file),
+ entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) {
+ zval_dtor(return_value);
+ RETURN_FALSE;
+ }
+ }
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::addGlob(string pattern[,int flags [, array options]])
+Add files matching the glob pattern. See php's glob for the pattern syntax. */
+static ZIPARCHIVE_METHOD(addGlob)
+{
+ php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::addPattern(string pattern[, string path [, array options]])
+Add files matching the pcre pattern. See php's pcre for the pattern syntax. */
+static ZIPARCHIVE_METHOD(addPattern)
+{
+ php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
+Add a file in a Zip archive using its path and the name to use. */
+static ZIPARCHIVE_METHOD(addFile)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *filename;
+ int filename_len;
+ char *entry_name = NULL;
+ int entry_name_len = 0;
+ long offset_start = 0, offset_len = 0;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sll",
+ &filename, &filename_len, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
+ return;
+ }
+
+ if (filename_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as filename");
+ RETURN_FALSE;
+ }
+
+ if (entry_name_len == 0) {
+ entry_name = filename;
+ entry_name_len = filename_len;
+ }
+
+ if (php_zip_add_file(intern, filename, filename_len,
+ entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::addFromString(string name, string content)
+Add a file using content and the entry name */
+static ZIPARCHIVE_METHOD(addFromString)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *buffer, *name;
+ int buffer_len, name_len;
+ ze_zip_object *ze_obj;
+ struct zip_source *zs;
+ int pos = 0;
+ int cur_idx;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
+ &name, &name_len, &buffer, &buffer_len) == FAILURE) {
+ return;
+ }
+
+ ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
+ if (ze_obj->buffers_cnt) {
+ ze_obj->buffers = (char **)erealloc(ze_obj->buffers, sizeof(char *) * (ze_obj->buffers_cnt+1));
+ pos = ze_obj->buffers_cnt++;
+ } else {
+ ze_obj->buffers = (char **)emalloc(sizeof(char *));
+ ze_obj->buffers_cnt++;
+ pos = 0;
+ }
+ ze_obj->buffers[pos] = (char *)emalloc(buffer_len + 1);
+ memcpy(ze_obj->buffers[pos], buffer, buffer_len + 1);
+
+ zs = zip_source_buffer(intern, ze_obj->buffers[pos], buffer_len, 0);
+
+ if (zs == NULL) {
+ RETURN_FALSE;
+ }
+
+ cur_idx = zip_name_locate(intern, (const char *)name, 0);
+ /* TODO: fix _zip_replace */
+ if (cur_idx >= 0) {
+ if (zip_delete(intern, cur_idx) == -1) {
+ RETURN_FALSE;
+ }
+ }
+
+ if (zip_add(intern, name, zs) == -1) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto array ZipArchive::statName(string filename[, int flags])
+Returns the information about a the zip entry filename */
+static ZIPARCHIVE_METHOD(statName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *name;
+ int name_len;
+ long flags = 0;
+ struct zip_stat sb;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
+ &name, &name_len, &flags) == FAILURE) {
+ return;
+ }
+
+ PHP_ZIP_STAT_PATH(intern, name, name_len, flags, sb);
+
+ RETURN_SB(&sb);
+}
+/* }}} */
+
+/* {{{ proto resource ZipArchive::statIndex(int index[, int flags])
+Returns the zip entry informations using its index */
+static ZIPARCHIVE_METHOD(statIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ long index, flags = 0;
+
+ struct zip_stat sb;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
+ &index, &flags) == FAILURE) {
+ return;
+ }
+
+ if (zip_stat_index(intern, index, flags, &sb) != 0) {
+ RETURN_FALSE;
+ }
+ RETURN_SB(&sb);
+}
+/* }}} */
+
+/* {{{ proto int ZipArchive::locateName(string filename[, int flags])
+Returns the index of the entry named filename in the archive */
+static ZIPARCHIVE_METHOD(locateName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ char *name;
+ int name_len;
+ long flags = 0;
+ long idx = -1;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
+ &name, &name_len, &flags) == FAILURE) {
+ return;
+ }
+ if (name_len<1) {
+ RETURN_FALSE;
+ }
+
+ idx = (long)zip_name_locate(intern, (const char *)name, flags);
+
+ if (idx >= 0) {
+ RETURN_LONG(idx);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getNameIndex(int index [, int flags])
+Returns the name of the file at position index */
+static ZIPARCHIVE_METHOD(getNameIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ const char *name;
+ long flags = 0, index = 0;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
+ &index, &flags) == FAILURE) {
+ return;
+ }
+
+ name = zip_get_name(intern, (int) index, flags);
+
+ if (name) {
+ RETVAL_STRING((char *)name, 1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::setArchiveComment(string comment)
+Set or remove (NULL/'') the comment of the archive */
+static ZIPARCHIVE_METHOD(setArchiveComment)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ int comment_len;
+ char * comment;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &comment, &comment_len) == FAILURE) {
+ return;
+ }
+ if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getArchiveComment([int flags])
+Returns the comment of an entry using its index */
+static ZIPARCHIVE_METHOD(getArchiveComment)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ long flags = 0;
+ const char * comment;
+ int comment_len = 0;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) {
+ return;
+ }
+
+ comment = zip_get_archive_comment(intern, &comment_len, (int)flags);
+ if(comment==NULL) {
+ RETURN_FALSE;
+ }
+ RETURN_STRINGL((char *)comment, (long)comment_len, 1);
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::setCommentName(string name, string comment)
+Set or remove (NULL/'') the comment of an entry using its Name */
+static ZIPARCHIVE_METHOD(setCommentName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ int comment_len, name_len;
+ char * comment, *name;
+ int idx;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
+ &name, &name_len, &comment, &comment_len) == FAILURE) {
+ return;
+ }
+
+ if (name_len < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name");
+ }
+
+ idx = zip_name_locate(intern, name, 0);
+ if (idx < 0) {
+ RETURN_FALSE;
+ }
+ PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len);
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment)
+Set or remove (NULL/'') the comment of an entry using its index */
+static ZIPARCHIVE_METHOD(setCommentIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ long index;
+ int comment_len;
+ char * comment;
+ struct zip_stat sb;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls",
+ &index, &comment, &comment_len) == FAILURE) {
+ return;
+ }
+
+ PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
+ PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len);
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
+Returns the comment of an entry using its name */
+static ZIPARCHIVE_METHOD(getCommentName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ int name_len, idx;
+ long flags = 0;
+ int comment_len = 0;
+ const char * comment;
+ char *name;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
+ &name, &name_len, &flags) == FAILURE) {
+ return;
+ }
+ if (name_len < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name");
+ RETURN_FALSE;
+ }
+
+ idx = zip_name_locate(intern, name, 0);
+ if (idx < 0) {
+ RETURN_FALSE;
+ }
+
+ comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags);
+ RETURN_STRINGL((char *)comment, (long)comment_len, 1);
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags])
+Returns the comment of an entry using its index */
+static ZIPARCHIVE_METHOD(getCommentIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ long index, flags = 0;
+ const char * comment;
+ int comment_len = 0;
+ struct zip_stat sb;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
+ &index, &flags) == FAILURE) {
+ return;
+ }
+
+ PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
+ comment = zip_get_file_comment(intern, index, &comment_len, (int)flags);
+ RETURN_STRINGL((char *)comment, (long)comment_len, 1);
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::deleteIndex(int index)
+Delete a file using its index */
+static ZIPARCHIVE_METHOD(deleteIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ long index;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
+ return;
+ }
+
+ if (index < 0) {
+ RETURN_FALSE;
+ }
+
+ if (zip_delete(intern, index) < 0) {
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::deleteName(string name)
+Delete a file using its index */
+static ZIPARCHIVE_METHOD(deleteName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ int name_len;
+ char *name;
+ struct zip_stat sb;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+ if (name_len < 1) {
+ RETURN_FALSE;
+ }
+
+ PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
+ if (zip_delete(intern, sb.index)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::renameIndex(int index, string new_name)
+Rename an entry selected by its index to new_name */
+static ZIPARCHIVE_METHOD(renameIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+
+ char *new_name;
+ int new_name_len;
+ long index;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &index, &new_name, &new_name_len) == FAILURE) {
+ return;
+ }
+
+ if (index < 0) {
+ RETURN_FALSE;
+ }
+
+ if (new_name_len < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as new entry name");
+ RETURN_FALSE;
+ }
+ if (zip_rename(intern, index, (const char *)new_name) != 0) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::renameName(string name, string new_name)
+Rename an entry selected by its name to new_name */
+static ZIPARCHIVE_METHOD(renameName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ struct zip_stat sb;
+ char *name, *new_name;
+ int name_len, new_name_len;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) {
+ return;
+ }
+
+ if (new_name_len < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as new entry name");
+ RETURN_FALSE;
+ }
+
+ PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
+
+ if (zip_rename(intern, sb.index, (const char *)new_name)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::unchangeIndex(int index)
+Changes to the file at position index are reverted */
+static ZIPARCHIVE_METHOD(unchangeIndex)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ long index;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
+ return;
+ }
+
+ if (index < 0) {
+ RETURN_FALSE;
+ }
+
+ if (zip_unchange(intern, index) != 0) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::unchangeName(string name)
+Changes to the file named 'name' are reverted */
+static ZIPARCHIVE_METHOD(unchangeName)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ struct zip_stat sb;
+ char *name;
+ int name_len;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ if (name_len < 1) {
+ RETURN_FALSE;
+ }
+
+ PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
+
+ if (zip_unchange(intern, sb.index) != 0) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::unchangeAll()
+All changes to files and global information in archive are reverted */
+static ZIPARCHIVE_METHOD(unchangeAll)
+{
+ struct zip *intern;
+ zval *this = getThis();
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zip_unchange_all(intern) != 0) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::unchangeArchive()
+Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */
+static ZIPARCHIVE_METHOD(unchangeArchive)
+{
+ struct zip *intern;
+ zval *this = getThis();
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zip_unchange_archive(intern) != 0) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files])
+Extract one or more file from a zip archive */
+/* TODO:
+ * - allow index or array of indeces
+ * - replace path
+ * - patterns
+ */
+static ZIPARCHIVE_METHOD(extractTo)
+{
+ struct zip *intern;
+
+ zval *this = getThis();
+ zval *zval_files = NULL;
+ zval **zval_file = NULL;
+ php_stream_statbuf ssb;
+ char *pathto;
+ int pathto_len;
+ int ret, i;
+
+ int nelems;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &pathto, &pathto_len, &zval_files) == FAILURE) {
+ return;
+ }
+
+ if (pathto_len < 1) {
+ RETURN_FALSE;
+ }
+
+ if (php_stream_stat_path_ex(pathto, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
+ ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL);
+ if (!ret) {
+ RETURN_FALSE;
+ }
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+ if (zval_files && (Z_TYPE_P(zval_files) != IS_NULL)) {
+ switch (Z_TYPE_P(zval_files)) {
+ case IS_STRING:
+ if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files) TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ break;
+ case IS_ARRAY:
+ nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files));
+ if (nelems == 0 ) {
+ RETURN_FALSE;
+ }
+ for (i = 0; i < nelems; i++) {
+ if (zend_hash_index_find(Z_ARRVAL_P(zval_files), i, (void **) &zval_file) == SUCCESS) {
+ switch (Z_TYPE_PP(zval_file)) {
+ case IS_LONG:
+ break;
+ case IS_STRING:
+ if (!php_zip_extract_file(intern, pathto, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file) TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case IS_LONG:
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument, expect string or array of strings");
+ break;
+ }
+ } else {
+ /* Extract all files */
+ int filecount = zip_get_num_files(intern);
+
+ if (filecount == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal archive");
+ RETURN_FALSE;
+ }
+
+ for (i = 0; i < filecount; i++) {
+ char *file = (char*)zip_get_name(intern, i, ZIP_FL_UNCHANGED);
+ if (!php_zip_extract_file(intern, pathto, file, strlen(file) TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ }
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ struct zip *intern;
+ zval *this = getThis();
+
+ struct zip_stat sb;
+ struct zip_file *zf;
+
+ char *filename;
+ int filename_len;
+ long index = -1;
+ long flags = 0;
+ long len = 0;
+
+ char *buffer;
+ int n = 0;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (type == 1) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
+ return;
+ }
+ PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb);
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &index, &len, &flags) == FAILURE) {
+ return;
+ }
+ PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
+ }
+
+ if (sb.size < 1) {
+ RETURN_EMPTY_STRING();
+ }
+
+ if (len < 1) {
+ len = sb.size;
+ }
+ if (index >= 0) {
+ zf = zip_fopen_index(intern, index, flags);
+ } else {
+ zf = zip_fopen(intern, filename, flags);
+ }
+
+ if (zf == NULL) {
+ RETURN_FALSE;
+ }
+
+ buffer = safe_emalloc(len, 1, 2);
+ n = zip_fread(zf, buffer, len);
+ if (n < 1) {
+ efree(buffer);
+ RETURN_EMPTY_STRING();
+ }
+
+ zip_fclose(zf);
+ buffer[n] = 0;
+ RETURN_STRINGL(buffer, n, 0);
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]])
+get the contents of an entry using its name */
+static ZIPARCHIVE_METHOD(getFromName)
+{
+ php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]])
+get the contents of an entry using its index */
+static ZIPARCHIVE_METHOD(getFromIndex)
+{
+ php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto resource ZipArchive::getStream(string entryname)
+get a stream for an entry using its name */
+static ZIPARCHIVE_METHOD(getStream)
+{
+ struct zip *intern;
+ zval *this = getThis();
+ struct zip_stat sb;
+ char *filename;
+ int filename_len;
+ char *mode = "rb";
+ php_stream *stream;
+ ze_zip_object *obj;
+
+ if (!this) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, this);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
+ return;
+ }
+
+ if (zip_stat(intern, filename, 0, &sb) != 0) {
+ RETURN_FALSE;
+ }
+
+ obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
+
+ stream = php_stream_zip_open(obj->filename, filename, mode STREAMS_CC TSRMLS_CC);
+ if (stream) {
+ php_stream_to_zval(stream, return_value);
+ }
+}
+/* }}} */
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addemptydir, 0, 0, 1)
+ ZEND_ARG_INFO(0, dirname)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addglob, 0, 0, 1)
+ ZEND_ARG_INFO(0, pattern)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addpattern, 0, 0, 1)
+ ZEND_ARG_INFO(0, pattern)
+ ZEND_ARG_INFO(0, path)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfile, 0, 0, 1)
+ ZEND_ARG_INFO(0, filepath)
+ ZEND_ARG_INFO(0, entryname)
+ ZEND_ARG_INFO(0, start)
+ ZEND_ARG_INFO(0, length)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfromstring, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, content)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statname, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statindex, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setarchivecomment, 0, 0, 1)
+ ZEND_ARG_INFO(0, comment)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentindex, 0, 0, 2)
+ ZEND_ARG_INFO(0, index)
+ ZEND_ARG_INFO(0, comment)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentname, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentindex, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renameindex, 0, 0, 2)
+ ZEND_ARG_INFO(0, index)
+ ZEND_ARG_INFO(0, new_name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renamename, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, new_name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangeindex, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangename, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_extractto, 0, 0, 1)
+ ZEND_ARG_INFO(0, pathto)
+ ZEND_ARG_INFO(0, files)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromname, 0, 0, 1)
+ ZEND_ARG_INFO(0, entryname)
+ ZEND_ARG_INFO(0, len)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromindex, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ ZEND_ARG_INFO(0, len)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getarchivecomment, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentname, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, comment)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getstream, 0, 0, 1)
+ ZEND_ARG_INFO(0, entryname)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ ze_zip_object_class_functions */
+static const zend_function_entry zip_class_functions[] = {
+ ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(addFromString, arginfo_ziparchive_addfromstring, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(addFile, arginfo_ziparchive_addfile, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(addGlob, arginfo_ziparchive_addglob, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(addPattern, arginfo_ziparchive_addpattern, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(renameIndex, arginfo_ziparchive_renameindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(renameName, arginfo_ziparchive_renamename, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(setArchiveComment, arginfo_ziparchive_setarchivecomment, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getArchiveComment, arginfo_ziparchive_getarchivecomment, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(setCommentIndex, arginfo_ziparchive_setcommentindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(setCommentName, arginfo_ziparchive_setcommentname, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getCommentIndex, arginfo_ziparchive_getcommentindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getCommentName, arginfo_ziparchive_getcommentname, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(deleteIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(deleteName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(statName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(statIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(locateName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getNameIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(unchangeArchive, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(unchangeAll, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(unchangeIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(unchangeName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(extractTo, arginfo_ziparchive_extractto, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getFromName, arginfo_ziparchive_getfromname, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getFromIndex, arginfo_ziparchive_getfromindex, ZEND_ACC_PUBLIC)
+ ZIPARCHIVE_ME(getStream, arginfo_ziparchive_getstream, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+#endif
+
+/* {{{ PHP_MINIT_FUNCTION */
+static PHP_MINIT_FUNCTION(zip)
+{
+#ifdef PHP_ZIP_USE_OO
+ zend_class_entry ce;
+
+ memcpy(&zip_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zip_object_handlers.clone_obj = NULL;
+ zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
+
+ zip_object_handlers.get_properties = php_zip_get_properties;
+ zip_object_handlers.read_property = php_zip_read_property;
+ zip_object_handlers.has_property = php_zip_has_property;
+
+ INIT_CLASS_ENTRY(ce, "ZipArchive", zip_class_functions);
+ ce.create_object = php_zip_object_new;
+ zip_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+
+ zend_hash_init(&zip_prop_handlers, 0, NULL, NULL, 1);
+ php_zip_register_prop_handler(&zip_prop_handlers, "status", php_zip_status, NULL, NULL, IS_LONG TSRMLS_CC);
+ php_zip_register_prop_handler(&zip_prop_handlers, "statusSys", php_zip_status_sys, NULL, NULL, IS_LONG TSRMLS_CC);
+ php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, NULL, IS_LONG TSRMLS_CC);
+ php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING TSRMLS_CC);
+ php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING TSRMLS_CC);
+
+ REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE);
+ REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL);
+ REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS);
+ REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE);
+
+ REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE);
+ REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
+ REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
+ REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_1", ZIP_CM_REDUCE_1);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_2", ZIP_CM_REDUCE_2);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_3", ZIP_CM_REDUCE_3);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_4", ZIP_CM_REDUCE_4);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_IMPLODE", ZIP_CM_IMPLODE);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE", ZIP_CM_DEFLATE);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE64", ZIP_CM_DEFLATE64);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_PKWARE_IMPLODE", ZIP_CM_PKWARE_IMPLODE);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_BZIP2", ZIP_CM_BZIP2);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_WAVPACK", ZIP_CM_WAVPACK);
+ REGISTER_ZIP_CLASS_CONST_LONG("CM_PPMD", ZIP_CM_PPMD);
+
+ /* Error code */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_OK", ZIP_ER_OK); /* N No error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_MULTIDISK", ZIP_ER_MULTIDISK); /* N Multi-disk zip archives not supported */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_RENAME", ZIP_ER_RENAME); /* S Renaming temporary file failed */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_CLOSE", ZIP_ER_CLOSE); /* S Closing zip archive failed */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_SEEK", ZIP_ER_SEEK); /* S Seek error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_READ", ZIP_ER_READ); /* S Read error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_WRITE", ZIP_ER_WRITE); /* S Write error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_CRC", ZIP_ER_CRC); /* N CRC error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_ZIPCLOSED", ZIP_ER_ZIPCLOSED); /* N Containing zip archive was closed */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_NOENT", ZIP_ER_NOENT); /* N No such file */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_EXISTS", ZIP_ER_EXISTS); /* N File already exists */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_OPEN", ZIP_ER_OPEN); /* S Can't open file */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_TMPOPEN", ZIP_ER_TMPOPEN); /* S Failure to create temporary file */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_ZLIB", ZIP_ER_ZLIB); /* Z Zlib error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_MEMORY", ZIP_ER_MEMORY); /* N Malloc failure */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_CHANGED", ZIP_ER_CHANGED); /* N Entry has been changed */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPNOTSUPP", ZIP_ER_COMPNOTSUPP);/* N Compression method not supported */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_EOF", ZIP_ER_EOF); /* N Premature EOF */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_INVAL", ZIP_ER_INVAL); /* N Invalid argument */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_NOZIP", ZIP_ER_NOZIP); /* N Not a zip archive */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_INTERNAL", ZIP_ER_INTERNAL); /* N Internal error */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS", ZIP_ER_INCONS); /* N Zip archive inconsistent */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE", ZIP_ER_REMOVE); /* S Can't remove file */
+ REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED", ZIP_ER_DELETED); /* N Entry has been deleted */
+
+ php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper TSRMLS_CC);
+#endif
+
+ le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number);
+ le_zip_entry = zend_register_list_destructors_ex(php_zip_free_entry, NULL, le_zip_entry_name, module_number);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+static PHP_MSHUTDOWN_FUNCTION(zip)
+{
+#ifdef PHP_ZIP_USE_OO
+ zend_hash_destroy(&zip_prop_handlers);
+ php_unregister_url_stream_wrapper("zip" TSRMLS_CC);
+#endif
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+static PHP_MINFO_FUNCTION(zip)
+{
+ php_info_print_table_start();
+
+ php_info_print_table_row(2, "Zip", "enabled");
+ php_info_print_table_row(2, "Extension Version","$Id: 727cc853ca1ae15d995c3520c5719784ddc1e292 $");
+ php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING);
+ php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
+
+ php_info_print_table_end();
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h
new file mode 100644
index 0000000..7dd9ff0
--- /dev/null
+++ b/ext/zip/php_zip.h
@@ -0,0 +1,99 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Pierre-Alain Joye <pajoye@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_ZIP_H
+#define PHP_ZIP_H
+
+extern zend_module_entry zip_module_entry;
+#define phpext_zip_ptr &zip_module_entry
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#include "lib/zip.h"
+
+#define PHP_ZIP_VERSION_STRING "1.11.0"
+
+#if ((PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION >= 6)
+# define PHP_ZIP_USE_OO 1
+#endif
+
+#ifndef Z_SET_REFCOUNT_P
+# if PHP_MAJOR_VERSION < 6 && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3)
+# define Z_SET_REFCOUNT_P(pz, rc) pz->refcount = rc
+# define Z_UNSET_ISREF_P(pz) pz->is_ref = 0
+# endif
+#endif
+
+/* {{{ ZIP_OPENBASEDIR_CHECKPATH(filename) */
+#if PHP_API_VERSION < 20100412
+# define ZIP_OPENBASEDIR_CHECKPATH(filename) \
+ (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)
+#else
+#define ZIP_OPENBASEDIR_CHECKPATH(filename) \
+ php_check_open_basedir(filename TSRMLS_CC)
+#endif
+/* }}} */
+
+typedef struct _ze_zip_rsrc {
+ struct zip *za;
+ int index_current;
+ int num_files;
+} zip_rsrc;
+
+typedef zip_rsrc * zip_rsrc_ptr;
+
+typedef struct _ze_zip_read_rsrc {
+ struct zip_file *zf;
+ struct zip_stat sb;
+} zip_read_rsrc;
+
+#ifdef PHP_ZIP_USE_OO
+#define ZIPARCHIVE_ME(name, arg_info, flags) ZEND_FENTRY(name, c_ziparchive_ ##name, arg_info, flags)
+#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_##name)
+
+/* Extends zend object */
+typedef struct _ze_zip_object {
+ zend_object zo;
+ struct zip *za;
+ int buffers_cnt;
+ char **buffers;
+ HashTable *prop_handler;
+ char *filename;
+ int filename_len;
+} ze_zip_object;
+
+php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
+php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_DC TSRMLS_DC);
+
+extern php_stream_wrapper php_stream_zip_wrapper;
+#endif
+
+#endif /* PHP_ZIP_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/zip/tests/001.phpt b/ext/zip/tests/001.phpt
new file mode 100644
index 0000000..37dccc0
--- /dev/null
+++ b/ext/zip/tests/001.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Check for zip presence
+--SKIPIF--
+<?php if (!extension_loaded("zip")) print "skip"; ?>
+--POST--
+--GET--
+--FILE--
+<?php
+echo "zip extension is available";
+?>
+--EXPECT--
+zip extension is available
diff --git a/ext/zip/tests/binarynull.zip b/ext/zip/tests/binarynull.zip
new file mode 100644
index 0000000..9da004e
--- /dev/null
+++ b/ext/zip/tests/binarynull.zip
Binary files differ
diff --git a/ext/zip/tests/bug11216.phpt b/ext/zip/tests/bug11216.phpt
new file mode 100644
index 0000000..7601e6a
--- /dev/null
+++ b/ext/zip/tests/bug11216.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #11216 (::addEmptyDir() crashes when the directory already exists)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+ ?>
+--FILE--
+<?php
+$archive = new ZipArchive();
+$archive->open('__test.zip', ZIPARCHIVE::CREATE);
+var_dump($archive->addEmptyDir('test'));
+print_r($archive);
+var_dump($archive->addEmptyDir('test'));
+$archive->close();
+unlink('__test.zip');
+?>
+--EXPECTF--
+bool(true)
+ZipArchive Object
+(
+ [status] => 0
+ [statusSys] => 0
+ [numFiles] => 1
+ [filename] => %s
+ [comment] =>
+)
+bool(false)
diff --git a/ext/zip/tests/bug14962.phpt b/ext/zip/tests/bug14962.phpt
new file mode 100644
index 0000000..0006fd4
--- /dev/null
+++ b/ext/zip/tests/bug14962.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #14962 (::extractTo second argument is not really optional)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dir = dirname(__FILE__);
+$file = '__tmp14962.txt';
+$fullpath = $dir . '/' . $file;
+$za = new ZipArchive;
+$za->open($dir . '/__14962.zip', ZIPARCHIVE::CREATE);
+$za->addFromString($file, '1234');
+$za->close();
+
+if (!is_file($dir . "/__14962.zip")) {
+ die('failed to create the archive');
+}
+$za = new ZipArchive;
+$za->open($dir . '/__14962.zip');
+$za->extractTo($dir, NULL);
+$za->close();
+
+if (is_file($fullpath)) {
+ unlink($fullpath);
+ echo "Ok";
+}
+unlink($dir . '/' . '__14962.zip');
+?>
+--EXPECT--
+Ok
diff --git a/ext/zip/tests/bug38943.phpt b/ext/zip/tests/bug38943.phpt
new file mode 100644
index 0000000..c5e2284
--- /dev/null
+++ b/ext/zip/tests/bug38943.phpt
@@ -0,0 +1,50 @@
+--TEST--
+#38943, properties in extended class cannot be set (5.3+)
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+class myZip extends ZipArchive {
+ private $test = 0;
+ public $testp = 1;
+ private $testarray = array();
+
+ public function __construct() {
+ $this->testarray[] = 1;
+ var_dump($this->testarray);
+ }
+}
+
+$z = new myZip;
+$z->testp = "foobar";
+var_dump($z);
+
+?>
+--EXPECTF--
+array(1) {
+ [0]=>
+ int(1)
+}
+object(myZip)#1 (%d) {
+ ["test":"myZip":private]=>
+ int(0)
+ ["testp"]=>
+ string(6) "foobar"
+ ["testarray":"myZip":private]=>
+ array(1) {
+ [0]=>
+ int(1)
+ }
+ ["status"]=>
+ int(0)
+ ["statusSys"]=>
+ int(0)
+ ["numFiles"]=>
+ int(0)
+ ["filename"]=>
+ string(0) ""
+ ["comment"]=>
+ string(0) ""
+}
diff --git a/ext/zip/tests/bug38944.phpt b/ext/zip/tests/bug38944.phpt
new file mode 100644
index 0000000..7cff60c
--- /dev/null
+++ b/ext/zip/tests/bug38944.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #38944 (newly created ZipArchive segfaults when accessing comment property)
+--SKIPIF--
+<?php if (!extension_loaded("zip")) print "skip"; ?>
+--FILE--
+<?php
+
+$arc_name = dirname(__FILE__)."/bug38944.zip";
+$foo = new ZipArchive;
+$foo->open($arc_name, ZIPARCHIVE::CREATE);;
+
+var_dump($foo->status);
+var_dump($foo->statusSys);
+var_dump($foo->numFiles);
+var_dump($foo->filename);
+var_dump($foo->comment);
+
+var_dump($foo);
+
+echo "Done\n";
+?>
+--EXPECTF--
+int(0)
+int(0)
+int(0)
+string(%d) "%s"
+string(0) ""
+object(ZipArchive)#%d (5) {
+ ["status"]=>
+ int(0)
+ ["statusSys"]=>
+ int(0)
+ ["numFiles"]=>
+ int(0)
+ ["filename"]=>
+ string(%d) "%s"
+ ["comment"]=>
+ string(0) ""
+}
+Done
diff --git a/ext/zip/tests/bug40228.phpt b/ext/zip/tests/bug40228.phpt
new file mode 100644
index 0000000..fec2963
--- /dev/null
+++ b/ext/zip/tests/bug40228.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #40228 (extractTo does not create recursive empty path)
+--SKIPIF--
+<?php if (!extension_loaded("zip")) print "skip"; ?>
+--FILE--
+<?php
+$dest = dirname(__FILE__);
+$arc_name = $dest . "/bug40228.zip";
+$zip = new ZipArchive;
+$zip->open($arc_name, ZIPARCHIVE::CREATE);;
+$zip->extractTo($dest);
+if (is_dir($dest . '/test/empty')) {
+ echo "Ok\n";
+ rmdir($dest . '/test/empty');
+ rmdir($dest . '/test');
+} else {
+ echo "Failed.\n";
+}
+echo "Done\n";
+?>
+--EXPECT--
+Ok
+Done
diff --git a/ext/zip/tests/bug40228.zip b/ext/zip/tests/bug40228.zip
new file mode 100644
index 0000000..bbcd951
--- /dev/null
+++ b/ext/zip/tests/bug40228.zip
Binary files differ
diff --git a/ext/zip/tests/bug47667.phpt b/ext/zip/tests/bug47667.phpt
new file mode 100644
index 0000000..9c17de6
--- /dev/null
+++ b/ext/zip/tests/bug47667.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #47667 (ZipArchive::OVERWRITE seems to have no effect)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$thisdir = dirname(__FILE__);
+$filename = $thisdir . "/bug47667.zip";
+
+$zip = new ZipArchive();
+if ($zip->open($filename, ZipArchive::CREATE) !== true) {
+ exit("Unable to open the zip file");
+} else {
+ $zip->addFromString('foo.txt', 'foo bar foobar');
+ $zip->close();
+}
+
+for ($i = 0; $i < 10; $i++) {
+ $zip = new ZipArchive();
+ if ($zip->open($filename, ZipArchive::OVERWRITE) !== true) {
+ exit("Unable to open the zip file");
+ }
+ $zip->addFromString("foo_{$i}.txt", 'foo bar foobar');
+ $zip->close();
+}
+
+$zip = new ZipArchive();
+if ($zip->open($filename, ZipArchive::CREATE) !== true) {
+ exit("Unable to open the zip file");
+}
+
+echo "files: " , $zip->numFiles;
+$zip->close();
+
+unlink($filename);
+
+--EXPECT--
+files: 1
diff --git a/ext/zip/tests/bug49072.phpt b/ext/zip/tests/bug49072.phpt
new file mode 100644
index 0000000..04bd06e
--- /dev/null
+++ b/ext/zip/tests/bug49072.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #49072 (feof never returns true for damaged file in zip)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$f = dirname(__FILE__) . '/bug49072.zip';
+$o = new ZipArchive();
+if (! $o->open($f, ZipArchive::CHECKCONS)) {
+ exit ('error can\'t open');
+}
+$r = $o->getStream('file1'); // this file has a wrong crc
+if (!$r)die('failed to open a stream for file1');
+$s = '';
+while (! feof($r)) {
+ $s .= fread($r,1024);
+}
+?>
+--EXPECTF--
+
+Warning: fread(): Zip stream error: CRC error in %s on line %d
diff --git a/ext/zip/tests/bug49072.zip b/ext/zip/tests/bug49072.zip
new file mode 100644
index 0000000..16bbcd0
--- /dev/null
+++ b/ext/zip/tests/bug49072.zip
Binary files differ
diff --git a/ext/zip/tests/bug51353.phpt b/ext/zip/tests/bug51353.phpt
new file mode 100644
index 0000000..560945f
--- /dev/null
+++ b/ext/zip/tests/bug51353.phpt
@@ -0,0 +1,54 @@
+--TEST--
+Bug #51353 ZIP64 problem, archive with 100000 items
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+die('skip the test might get very long, activate it manually');
+--FILE--
+<?php
+/* This test might get very long depending on the mashine it's running on. Therefore
+adding an explicit skip, remove it to run this test. */
+set_time_limit(0);
+
+$base_path = dirname(__FILE__);
+
+/* Either we ship a file with 100000 entries which would be >12M big,
+ or create it dynamically. */
+$zip = new ZipArchive;
+$r = $zip->open("$base_path/51353.zip", ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
+if ($r) {
+ for ($i = 0; $i < 100000; $i++) {
+ $zip->addFromString("$i.txt", '1');
+ }
+ $zip->close();
+} else {
+ die("failed");
+}
+
+$zip = new ZipArchive;
+$r = $zip->open("$base_path/51353.zip");
+if ($r) {
+ $zip->extractTo("$base_path/51353_unpack");
+ $zip->close();
+
+ $a = glob("$base_path/51353_unpack/*.txt");
+ echo count($a) . "\n";
+} else {
+ die("failed");
+}
+
+echo "OK";
+--CLEAN--
+<?php
+$base_path = dirname(__FILE__);
+
+unlink("$base_path/51353.zip");
+
+$a = glob("$base_path/51353_unpack/*.txt");
+foreach($a as $f) {
+ unlink($f);
+}
+rmdir("$base_path/51353_unpack");
+--EXPECT--
+100000
+OK
diff --git a/ext/zip/tests/bug53579.phpt b/ext/zip/tests/bug53579.phpt
new file mode 100644
index 0000000..1d53330
--- /dev/null
+++ b/ext/zip/tests/bug53579.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #53579 (stream_get_contents() segfaults on ziparchive streams)
+--SKIPIF--
+<?php
+/* $Id: oo_stream.phpt 260091 2008-05-21 09:27:41Z pajoye $ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . 'test_with_comment.zip';
+include $dirname . 'utils.inc';
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+$fp = $zip->getStream('foo');
+
+var_dump($fp);
+if(!$fp) exit("\n");
+$contents = stream_get_contents($fp);
+
+fclose($fp);
+$zip->close();
+var_dump($contents);
+
+
+$fp = fopen('zip://' . dirname(__FILE__) . '/test_with_comment.zip#foo', 'rb');
+if (!$fp) {
+ exit("cannot open\n");
+}
+$contents = stream_get_contents($fp);
+var_dump($contents);
+fclose($fp);
+
+?>
+--EXPECTF--
+resource(%d) of type (stream)
+string(5) "foo
+
+"
+string(5) "foo
+
+"
diff --git a/ext/zip/tests/bug53603.phpt b/ext/zip/tests/bug53603.phpt
new file mode 100644
index 0000000..f8ff1b4
--- /dev/null
+++ b/ext/zip/tests/bug53603.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #53603 (ZipArchive should quiet stat errors)
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+class TestStream {
+ function url_stat($path, $flags) {
+ if (!($flags & STREAM_URL_STAT_QUIET))
+ trigger_error("not quiet");
+ return array();
+ }
+}
+
+stream_wrapper_register("teststream", "TestStream");
+
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . 'test_with_comment.zip';
+$zip = new ZipArchive;
+if ($zip->open($file) !== TRUE) {
+ echo "open failed.\n";
+ exit('failed');
+}
+
+$a = $zip->extractTo('teststream://test');
+var_dump($a);
+
+--EXPECTF--
+
+Warning: ZipArchive::extractTo(teststream://test/foo): failed to open stream: "TestStream::stream_open" call failed in %s on line %d
+bool(false)
+
diff --git a/ext/zip/tests/bug53854.phpt b/ext/zip/tests/bug53854.phpt
new file mode 100644
index 0000000..cd8ae7e
--- /dev/null
+++ b/ext/zip/tests/bug53854.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #53854 (Missing constants for compression type)
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+var_dump(ZipArchive::CM_DEFAULT);
+var_dump(ZipArchive::CM_STORE);
+var_dump(ZipArchive::CM_SHRINK);
+var_dump(ZipArchive::CM_REDUCE_1);
+var_dump(ZipArchive::CM_REDUCE_2);
+var_dump(ZipArchive::CM_REDUCE_3);
+var_dump(ZipArchive::CM_REDUCE_4);
+var_dump(ZipArchive::CM_IMPLODE);
+var_dump(ZipArchive::CM_DEFLATE);
+var_dump(ZipArchive::CM_DEFLATE64);
+var_dump(ZipArchive::CM_PKWARE_IMPLODE);
+var_dump(ZipArchive::CM_BZIP2);
+var_dump(ZipArchive::CM_LZMA);
+var_dump(ZipArchive::CM_TERSE);
+var_dump(ZipArchive::CM_LZ77);
+var_dump(ZipArchive::CM_WAVPACK);
+var_dump(ZipArchive::CM_PPMD);
+--EXPECT--
+int(-1)
+int(0)
+int(1)
+int(2)
+int(3)
+int(4)
+int(5)
+int(6)
+int(8)
+int(9)
+int(10)
+int(12)
+int(14)
+int(18)
+int(19)
+int(97)
+int(98)
diff --git a/ext/zip/tests/bug53885.phpt b/ext/zip/tests/bug53885.phpt
new file mode 100644
index 0000000..1b3fcb9
--- /dev/null
+++ b/ext/zip/tests/bug53885.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #53885 (ZipArchive segfault with FL_UNCHANGED on empty archive)
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$fname = dirname(__FILE__)."/test53885.zip";
+if(file_exists($fname)) unlink($fname);
+touch($fname);
+$nx=new ZipArchive();
+$nx->open($fname);
+$nx->locateName("a",ZIPARCHIVE::FL_UNCHANGED);
+$nx->statName("a",ZIPARCHIVE::FL_UNCHANGED);
+?>
+==DONE==
+--CLEAN--
+<?php
+$fname = dirname(__FILE__)."/test53885.zip";
+unlink($fname);
+?>
+--EXPECTF--
+==DONE==
diff --git a/ext/zip/tests/bug7214.phpt b/ext/zip/tests/bug7214.phpt
new file mode 100644
index 0000000..f791b79
--- /dev/null
+++ b/ext/zip/tests/bug7214.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #7214 (zip_entry_read() binary safe)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+ ?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/binarynull.zip");
+if (!is_resource($zip)) die("Failure");
+$entries = 0;
+$entry = zip_read($zip);
+$contents = zip_entry_read($entry, zip_entry_filesize($entry));
+if (strlen($contents) == zip_entry_filesize($entry)) {
+ echo "Ok";
+} else {
+ echo "failed";
+}
+
+?>
+--EXPECT--
+Ok
diff --git a/ext/zip/tests/bug7658.odt b/ext/zip/tests/bug7658.odt
new file mode 100644
index 0000000..527e09f
--- /dev/null
+++ b/ext/zip/tests/bug7658.odt
Binary files differ
diff --git a/ext/zip/tests/bug7658.phpt b/ext/zip/tests/bug7658.phpt
new file mode 100644
index 0000000..56fd00f
--- /dev/null
+++ b/ext/zip/tests/bug7658.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Bug #7658 (modify archive with general bit flag 3 set)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$expect = array(
+ "mimetype",
+ "Configurations2/statusbar/",
+ "Configurations2/accelerator/current.xml",
+ "Configurations2/floater/",
+ "Configurations2/popupmenu/",
+ "Configurations2/progressbar/",
+ "Configurations2/menubar/",
+ "Configurations2/toolbar/",
+ "Configurations2/images/Bitmaps/",
+ "content.xml",
+ "styles.xml",
+ "meta.xml",
+ "Thumbnails/thumbnail.png",
+ "settings.xml",
+ "META-INF/manifest.xml",
+);
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_bug7658.odt';
+$zip = new ZipArchive();
+copy($dirname . 'bug7658.odt', $file);
+if(!$zip->open($file)) {
+ echo 'failed';
+}
+
+
+$zip->deleteName('content.xml');
+$zip->addFile($dirname . "bug7658.xml","content.xml");
+$zip->close();
+echo "\n";
+$zip->open($file);
+
+for($i=0; $i < $zip->numFiles; $i++) {
+ $sb = $zip->statIndex($i);
+ $found[] = $sb['name'];
+}
+$ar = array_diff($found, $expect);
+
+var_dump($ar);
+unset($zip);
+unlink($file);
+?>
+--EXPECTF--
+array(0) {
+}
diff --git a/ext/zip/tests/bug7658.xml b/ext/zip/tests/bug7658.xml
new file mode 100644
index 0000000..98076f1
--- /dev/null
+++ b/ext/zip/tests/bug7658.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"><office:scripts/><office:font-face-decls><style:font-face style:name="Tahoma1" svg:font-family="Tahoma"/><style:font-face style:name="Arial Unicode MS" svg:font-family="&apos;Arial Unicode MS&apos;" style:font-pitch="variable"/><style:font-face style:name="Estrangelo Edessa" svg:font-family="&apos;Estrangelo Edessa&apos;" style:font-pitch="variable"/><style:font-face style:name="MS Mincho" svg:font-family="&apos;MS Mincho&apos;" style:font-pitch="variable"/><style:font-face style:name="Miriam CLM" svg:font-family="&apos;Miriam CLM&apos;" style:font-pitch="variable"/><style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-pitch="variable"/><style:font-face style:name="Times New Roman" svg:font-family="&apos;Times New Roman&apos;" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles><style:style style:name="Tabella1" style:family="table"><style:table-properties style:width="6.6924in" table:align="margins"/></style:style><style:style style:name="Tabella1.A" style:family="table-column"><style:table-column-properties style:column-width="4.8556in" style:rel-column-width="47546*"/></style:style><style:style style:name="Tabella1.B" style:family="table-column"><style:table-column-properties style:column-width="1.8368in" style:rel-column-width="17989*"/></style:style><style:style style:name="Tabella1.A1" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.0007in solid #000000" fo:border-right="none" fo:border-top="0.0007in solid #000000" fo:border-bottom="0.0007in solid #000000"/></style:style><style:style style:name="Tabella1.B1" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border="0.0007in solid #000000"/></style:style><style:style style:name="Tabella1.A2" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.0007in solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.0007in solid #000000"/></style:style><style:style style:name="Tabella1.B2" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.0007in solid #000000" fo:border-right="0.0007in solid #000000" fo:border-top="none" fo:border-bottom="0.0007in solid #000000"/></style:style><style:style style:name="Tabella2" style:family="table"><style:table-properties style:width="6.6924in" table:align="margins"/></style:style><style:style style:name="Tabella2.A" style:family="table-column"><style:table-column-properties style:column-width="2.584in" style:rel-column-width="25303*"/></style:style><style:style style:name="Tabella2.C" style:family="table-column"><style:table-column-properties style:column-width="1.5243in" style:rel-column-width="14929*"/></style:style><style:style style:name="Tabella2.A1" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.0007in solid #000000" fo:border-right="none" fo:border-top="0.0007in solid #000000" fo:border-bottom="0.0007in solid #000000"/></style:style><style:style style:name="Tabella2.C1" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border="0.0007in solid #000000"/></style:style><style:style style:name="Tabella2.A2" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.0007in solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.0007in solid #000000"/></style:style><style:style style:name="Tabella2.C2" style:family="table-cell"><style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.0007in solid #000000" fo:border-right="0.0007in solid #000000" fo:border-top="none" fo:border-bottom="0.0007in solid #000000"/></style:style><style:style style:name="P1" style:family="paragraph" style:parent-style-name="Table_20_Heading"><style:text-properties style:font-name="Estrangelo Edessa" fo:font-style="italic" fo:font-weight="bold" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-style-complex="italic" style:font-weight-complex="bold"/></style:style><style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table_20_Heading"><style:paragraph-properties fo:padding="0.0193in" fo:border="0.0008in solid #000000" style:shadow="none"/><style:text-properties style:font-name="Estrangelo Edessa" fo:font-style="italic" fo:font-weight="bold" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-style-complex="italic" style:font-weight-complex="bold"/></style:style><style:style style:name="P3" style:family="paragraph" style:parent-style-name="Table_20_Contents"><style:text-properties fo:color="#ff0000" style:font-name="Miriam CLM" fo:font-style="italic" fo:font-weight="bold" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-style-complex="italic" style:font-weight-complex="bold"/></style:style></office:automatic-styles><office:body><office:text><office:forms form:automatic-focus="false" form:apply-design-mode="false"/><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls><text:p text:style-name="Standard"/><text:p text:style-name="Standard"/><text:p text:style-name="Standard">Other text Silvio Berlusconi, le ricordo che ha in prestito i seguenti libri</text:p><text:p text:style-name="Standard"/><table:table table:name="Tabella1" table:style-name="Tabella1"><table:table-column table:style-name="Tabella1.A"/><table:table-column table:style-name="Tabella1.B"/><table:table-header-rows><table:table-row><table:table-cell table:style-name="Tabella1.A1" office:value-type="string"><text:p text:style-name="P1">Titolo</text:p></table:table-cell><table:table-cell table:style-name="Tabella1.B1" office:value-type="string"><text:p text:style-name="P1">Inventario</text:p></table:table-cell></table:table-row></table:table-header-rows><table:table-row><table:table-cell table:style-name="Tabella1.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">Codice Da Vinci</text:p></table:table-cell><table:table-cell table:style-name="Tabella1.B2" office:value-type="string"><text:p text:style-name="Table_20_Contents">112345678</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella1.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">Lo Zen e il tiro con l&apos;arco</text:p></table:table-cell><table:table-cell table:style-name="Tabella1.B2" office:value-type="string"><text:p text:style-name="Table_20_Contents">1020304</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella1.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">Lo Zen e l&apos;arte della manutenzione della motocicletta</text:p></table:table-cell><table:table-cell table:style-name="Tabella1.B2" office:value-type="string"><text:p text:style-name="Table_20_Contents">1020305</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella1.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">101 Storie Zen</text:p></table:table-cell><table:table-cell table:style-name="Tabella1.B2" office:value-type="string"><text:p text:style-name="Table_20_Contents">1020306</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella1.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">Antani di Blinda come fosse di Cappotto</text:p></table:table-cell><table:table-cell table:style-name="Tabella1.B2" office:value-type="string"><text:p text:style-name="Table_20_Contents">4112345</text:p></table:table-cell></table:table-row></table:table><text:p text:style-name="Standard"/><text:p text:style-name="Standard">peraltro, sottolineiamo la perentorietà della restituzione anche dei vieppiù interessanti testi:</text:p><text:p text:style-name="Standard"/><table:table table:name="Tabella2" table:style-name="Tabella2"><table:table-column table:style-name="Tabella2.A" table:number-columns-repeated="2"/><table:table-column table:style-name="Tabella2.C"/><table:table-header-rows><table:table-row><table:table-cell table:style-name="Tabella2.A1" office:value-type="string"><text:p text:style-name="P2">Titolo</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.A1" office:value-type="string"><text:p text:style-name="P2">Autore</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.C1" office:value-type="string"><text:p text:style-name="P2">Inventario</text:p></table:table-cell></table:table-row></table:table-header-rows><table:table-row><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">Angeli e Demoni</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="P3">Dan Brown</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.C2" office:value-type="string"><text:p text:style-name="Table_20_Contents">12131415</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">La versione di Barney</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="P3">Mordecai Richler</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.C2" office:value-type="string"><text:p text:style-name="Table_20_Contents">2010322</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">Manuale PHP</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="P3">Varii</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.C2" office:value-type="string"><text:p text:style-name="Table_20_Contents">32413543</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">La prematurata supercazzola negli anni a venire</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="P3">Ugo Tognazzi</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.C2" office:value-type="string"><text:p text:style-name="Table_20_Contents">31213243</text:p></table:table-cell></table:table-row><table:table-row><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="Table_20_Contents">La sbiriguda in vicesindaco</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.A2" office:value-type="string"><text:p text:style-name="P3">Ugo Tognazzi</text:p></table:table-cell><table:table-cell table:style-name="Tabella2.C2" office:value-type="string"><text:p text:style-name="Table_20_Contents">1324354654</text:p></table:table-cell></table:table-row></table:table><text:p text:style-name="Standard"/><text:p text:style-name="Standard"/><text:p text:style-name="Standard">Gentili saluti, la sua biblioteca</text:p></office:text></office:body></office:document-content>
diff --git a/ext/zip/tests/bug8009.phpt b/ext/zip/tests/bug8009.phpt
new file mode 100644
index 0000000..5dd363d
--- /dev/null
+++ b/ext/zip/tests/bug8009.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #8009 (cannot add again same entry to an archive)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$thisdir = dirname(__FILE__);
+$src = $thisdir . "/bug8009.zip";
+$filename = $thisdir . "/tmp8009.zip";
+copy($src, $filename);
+
+$zip = new ZipArchive();
+
+if (!$zip->open($filename)) {
+ exit("cannot open $filename\n");
+}
+$zip->addFromString("2.txt", "=)");
+$zip->close();
+unlink($filename);
+echo "status: " . $zip->status . "\n";
+echo "\n";
+
+--EXPECT--
+status: 0
diff --git a/ext/zip/tests/bug8009.zip b/ext/zip/tests/bug8009.zip
new file mode 100644
index 0000000..45bedcb
--- /dev/null
+++ b/ext/zip/tests/bug8009.zip
Binary files differ
diff --git a/ext/zip/tests/bug8700.phpt b/ext/zip/tests/bug8700.phpt
new file mode 100644
index 0000000..c394cf0
--- /dev/null
+++ b/ext/zip/tests/bug8700.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #8700 (getFromIndex(0) fails)
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$thisdir = dirname(__FILE__);
+$filename = $thisdir . "/bug8009.zip";
+
+$zip = new ZipArchive();
+
+if ($zip->open($filename) === FALSE) {
+ exit("cannot open $filename\n");
+}
+$contents_from_idx = $zip->getFromIndex(0);
+$contents_from_name = $zip->getFromName('1.txt');
+if ($contents_from_idx != $contents_from_name) {
+ echo "failed:";
+ var_dump($content_from_idx, $content_from_name);
+}
+
+$zip->close();
+echo "status: " . $zip->status . "\n";
+echo "\n";
+
+--EXPECT--
+status: 0
diff --git a/ext/zip/tests/oo_addemptydir.phpt b/ext/zip/tests/oo_addemptydir.phpt
new file mode 100644
index 0000000..cb57b5b
--- /dev/null
+++ b/ext/zip/tests/oo_addemptydir.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ziparchive::addEmptyDir
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_oo_addfile.zip';
+
+copy($dirname . 'test.zip', $file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+
+$zip->addEmptyDir('emptydir');
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+ dump_entries_name($zip);
+ $zip->close();
+} else {
+ echo "failed\n";
+}
+@unlink($file);
+?>
+--EXPECTF--
+0 bar
+1 foobar/
+2 foobar/baz
+3 entry1.txt
+4 emptydir/
diff --git a/ext/zip/tests/oo_addfile.phpt b/ext/zip/tests/oo_addfile.phpt
new file mode 100644
index 0000000..ab79780
--- /dev/null
+++ b/ext/zip/tests/oo_addfile.phpt
@@ -0,0 +1,37 @@
+--TEST--
+ziparchive::addFile() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_oo_addfile.zip';
+
+copy($dirname . 'test.zip', $file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+if (!$zip->addFile($dirname . 'utils.inc', 'test.php')) {
+ echo "failed\n";
+}
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+ dump_entries_name($zip);
+ $zip->close();
+} else {
+ echo "failed\n";
+}
+@unlink($file);
+?>
+--EXPECTF--
+0 bar
+1 foobar/
+2 foobar/baz
+3 entry1.txt
+4 test.php
diff --git a/ext/zip/tests/oo_close.phpt b/ext/zip/tests/oo_close.phpt
new file mode 100644
index 0000000..ea67dcd
--- /dev/null
+++ b/ext/zip/tests/oo_close.phpt
@@ -0,0 +1,25 @@
+--TEST--
+zip::close() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dirname = dirname(__FILE__) . '/';
+$zip = new ZipArchive;
+if (!$zip->open($dirname . 'test.zip')) {
+ exit('failed');
+}
+
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+ $zip->close();
+ echo "ok\n";
+} else {
+ echo "failed\n";
+}
+?>
+--EXPECTF--
+ok
diff --git a/ext/zip/tests/oo_delete.phpt b/ext/zip/tests/oo_delete.phpt
new file mode 100644
index 0000000..9eac821
--- /dev/null
+++ b/ext/zip/tests/oo_delete.phpt
@@ -0,0 +1,81 @@
+--TEST--
+Delete entries
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . '__tmp_oo_delete.zip';
+if (file_exists($file)) {
+ unlink($file);
+}
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
+ exit('failed');
+}
+$zip->addFromString('entry1.txt', 'entry #1');
+$zip->addFromString('entry2.txt', 'entry #2');
+$zip->addFromString('dir/entry2.txt', 'entry #2');
+
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+ $zip->close();
+ echo "ok\n";
+} else {
+ var_dump($zip);
+ echo "failed\n";
+}
+
+if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
+ exit('failed');
+}
+
+if ($zip->deleteIndex(0)) {
+ echo "ok\n";
+}
+
+if ($zip->deleteName('entry2.txt')) {
+ echo "ok\n";
+} else {
+ echo "failed 3\n";
+}
+
+if ($zip->deleteName('dir/entry2.txt')) {
+ echo "ok\n";
+} else {
+ echo "failed 3\n";
+}
+
+if (!$zip->deleteIndex(123)) {
+ echo "ok\n";
+} else {
+ print_r($zip);
+ echo "failed\n";
+}
+
+
+$sb = $zip->statIndex(0);
+var_dump($sb);
+$sb = $zip->statIndex(1);
+var_dump($sb);
+$sb = $zip->statIndex(2);
+var_dump($sb);
+$zip->close();
+unset($zip);
+
+if (file_exists($file)) {
+ unlink($file);
+}
+?>
+--EXPECTF--
+ok
+ok
+ok
+ok
+ok
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/zip/tests/oo_ext_zip.phpt b/ext/zip/tests/oo_ext_zip.phpt
new file mode 100644
index 0000000..739a671
--- /dev/null
+++ b/ext/zip/tests/oo_ext_zip.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Extending Zip class and array property
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+class myZip extends ZipArchive {
+ private $test = 0;
+ public $testp = 1;
+ private $testarray = array();
+
+ public function __construct() {
+ $this->testarray[] = 1;
+ var_dump($this->testarray);
+ }
+}
+
+$z = new myZip;
+?>
+--EXPECTF--
+array(1) {
+ [0]=>
+ int(1)
+}
diff --git a/ext/zip/tests/oo_extract.phpt b/ext/zip/tests/oo_extract.phpt
new file mode 100644
index 0000000..7ca39ee
--- /dev/null
+++ b/ext/zip/tests/oo_extract.phpt
@@ -0,0 +1,95 @@
+--TEST--
+extractTo
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . 'test_with_comment.zip';
+include $dirname . 'utils.inc';
+$zip = new ZipArchive;
+if ($zip->open($file) !== TRUE) {
+ echo "open failed.\n";
+ exit('failed');
+}
+
+$zip->extractTo($dirname . '__oo_extract_tmp');
+if (!is_dir($dirname . '__oo_extract_tmp')) {
+ echo "failed. mkdir\n";
+}
+
+if (!is_dir($dirname .'__oo_extract_tmp/foobar')) {
+ echo "failed. mkdir foobar\n";
+}
+
+if (!file_exists($dirname . '__oo_extract_tmp/foobar/baz')) {
+ echo "failed. extract foobar/baz\n";
+} else {
+ echo file_get_contents($dirname . '__oo_extract_tmp/foobar/baz') . "\n";
+}
+
+if (!file_exists($dirname . '__oo_extract_tmp/bar')) {
+ echo "failed. bar file\n";
+} else {
+ echo file_get_contents($dirname . '__oo_extract_tmp/bar') . "\n";
+}
+
+if (!file_exists($dirname . '__oo_extract_tmp/foo')) {
+ echo "failed. foo file\n";
+} else {
+ echo file_get_contents($dirname . '__oo_extract_tmp/foo') . "\n";
+}
+
+
+/* extract one file */
+$zip->extractTo($dirname . '__oo_extract_tmp', 'bar');
+if (!file_exists($dirname . '__oo_extract_tmp/bar')) {
+ echo "failed. extract bar file\n";
+} else {
+ echo file_get_contents($dirname . '__oo_extract_tmp/bar') . "\n";
+}
+
+/* extract two files */
+$zip->extractTo($dirname . '__oo_extract_tmp', array('bar','foo'));
+if (!file_exists($dirname . '__oo_extract_tmp/bar')) {
+ echo "failed. extract bar file\n";
+} else {
+ echo file_get_contents($dirname . '__oo_extract_tmp/bar') . "\n";
+}
+if (!file_exists($dirname . '__oo_extract_tmp/foo')) {
+ echo "failed. extract foo file\n";
+} else {
+ echo file_get_contents($dirname . '__oo_extract_tmp/foo') . "\n";
+}
+
+rmdir_rf($dirname . '__oo_extract_tmp');
+?>
+--EXPECTF--
+blabla laber rababer sülz
+
+bar
+
+foo
+
+
+bar
+
+bar
+
+foo
+--UEXPECTF--
+blabla laber rababer sülz
+
+bar
+
+foo
+
+
+bar
+
+bar
+
+foo
diff --git a/ext/zip/tests/oo_getcomment.phpt b/ext/zip/tests/oo_getcomment.phpt
new file mode 100644
index 0000000..d05385c
--- /dev/null
+++ b/ext/zip/tests/oo_getcomment.phpt
@@ -0,0 +1,36 @@
+--TEST--
+getComment
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . 'test_with_comment.zip';
+include $dirname . 'utils.inc';
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+echo $zip->getArchiveComment() . "\n";
+
+$idx = $zip->locateName('foo');
+echo $zip->getCommentName('foo') . "\n";
+echo $zip->getCommentIndex($idx);
+
+echo $zip->getCommentName('') . "\n";
+echo $zip->getCommentName() . "\n";
+
+$zip->close();
+
+?>
+--EXPECTF--
+Zip archive comment
+foo comment
+foo comment
+Notice: ZipArchive::getCommentName(): Empty string as entry name in %s on line %d
+
+
+Warning: ZipArchive::getCommentName() expects at least 1 parameter, 0 given in %s on line %d
diff --git a/ext/zip/tests/oo_getnameindex.phpt b/ext/zip/tests/oo_getnameindex.phpt
new file mode 100644
index 0000000..cd4c9db
--- /dev/null
+++ b/ext/zip/tests/oo_getnameindex.phpt
@@ -0,0 +1,47 @@
+--TEST--
+getNameIndex
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_oo_rename.zip';
+
+@unlink($file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
+ exit('failed');
+}
+
+$zip->addFromString('entry1.txt', 'entry #1');
+$zip->addFromString('entry2.txt', 'entry #2');
+$zip->addFromString('dir/entry2d.txt', 'entry #2');
+
+if (!$zip->status == ZIPARCHIVE::ER_OK) {
+ echo "failed to write zip\n";
+}
+$zip->close();
+
+if (!$zip->open($file)) {
+ exit('failed');
+}
+
+
+var_dump($zip->getNameIndex(0));
+var_dump($zip->getNameIndex(1));
+var_dump($zip->getNameIndex(2));
+var_dump($zip->getNameIndex(3));
+
+$zip->close();
+
+?>
+--EXPECTF--
+string(10) "entry1.txt"
+string(10) "entry2.txt"
+string(15) "dir/entry2d.txt"
+bool(false)
diff --git a/ext/zip/tests/oo_getstatusstring.phpt b/ext/zip/tests/oo_getstatusstring.phpt
new file mode 100644
index 0000000..efd19e3
--- /dev/null
+++ b/ext/zip/tests/oo_getstatusstring.phpt
@@ -0,0 +1,28 @@
+--TEST--
+This test will test getStatusString method in ZipArchive
+--CREDITS--
+Ole-Petter Wikene <olepw@redpill-linpro.com>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php if (!extension_loaded("zip")) { echo "skip extension not available"; } ?>
+--FILE--
+<?php
+
+$dirname = dirname(__FILE__) . '/';
+$arch = new ZipArchive;
+$arch->open($dirname.'foo.zip',ZIPARCHIVE::CREATE);
+var_dump($arch->getStatusString());
+//delete an index that does not exist - trigger error
+$arch->deleteIndex(2);
+var_dump($arch->getStatusString());
+$arch->close();
+
+?>
+--CLEAN--
+<?php
+unlink($dirname.'foo.zip');
+?>
+--EXPECT--
+string(8) "No error"
+string(16) "Invalid argument"
+
diff --git a/ext/zip/tests/oo_namelocate.phpt b/ext/zip/tests/oo_namelocate.phpt
new file mode 100644
index 0000000..bbe7ec5
--- /dev/null
+++ b/ext/zip/tests/oo_namelocate.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Locate entries by name
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_oo_rename.zip';
+
+@unlink($file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
+ exit('failed');
+}
+
+$zip->addFromString('entry1.txt', 'entry #1');
+$zip->addFromString('entry2.txt', 'entry #2');
+$zip->addFromString('dir/entry2d.txt', 'entry #2');
+
+if (!$zip->status == ZIPARCHIVE::ER_OK) {
+ echo "failed to write zip\n";
+}
+$zip->close();
+
+if (!$zip->open($file)) {
+ exit('failed');
+}
+
+
+var_dump($zip->locateName('entry1.txt'));
+var_dump($zip->locateName('eNtry2.txt'));
+var_dump($zip->locateName('eNtry2.txt', ZIPARCHIVE::FL_NOCASE));
+var_dump($zip->locateName('enTRy2d.txt', ZIPARCHIVE::FL_NOCASE|ZIPARCHIVE::FL_NODIR));
+$zip->close();
+
+?>
+--EXPECTF--
+int(0)
+bool(false)
+int(1)
+int(2)
diff --git a/ext/zip/tests/oo_open.phpt b/ext/zip/tests/oo_open.phpt
new file mode 100644
index 0000000..0760db3
--- /dev/null
+++ b/ext/zip/tests/oo_open.phpt
@@ -0,0 +1,46 @@
+--TEST--
+zip::open() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dirname = dirname(__FILE__) . '/';
+$zip = new ZipArchive;
+$r = $zip->open($dirname . 'nofile');
+if ($r !== TRUE) {
+ echo "ER_OPEN: ok\n";
+} else {
+ echo "ER_OPEN: FAILED\n";
+}
+
+$r = $zip->open($dirname . 'nofile', ZIPARCHIVE::CREATE);
+if (!$r) {
+ echo "create: failed\n";
+} else {
+ echo "create: ok\n";
+}
+@unlink($dirname . 'nofile');
+
+$zip = new ZipArchive;
+$zip->open('');
+
+if (!$zip->open($dirname . 'test.zip')) {
+ exit("failed 1\n");
+}
+
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+ echo "OK\n";
+} else {
+ echo "failed\n";
+}
+?>
+--EXPECTF--
+ER_OPEN: ok
+create: ok
+
+Warning: ZipArchive::open(): Empty string as source in %s on line %d
+OK
diff --git a/ext/zip/tests/oo_properties.phpt b/ext/zip/tests/oo_properties.phpt
new file mode 100644
index 0000000..886317b
--- /dev/null
+++ b/ext/zip/tests/oo_properties.phpt
@@ -0,0 +1,60 @@
+--TEST--
+ziparchive::properties isset()/empty() checks
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . '__property_test.zip';
+
+copy($dirname . 'test_with_comment.zip', $file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+
+printf("zip->status (%d):\n\tempty(): %d\n\tisset(): %d\n", $zip->status, empty($zip->status), isset($zip->status));
+printf("zip->numFiles (%d):\n\tempty(): %d\n\tisset(): %d\n", $zip->numFiles, empty($zip->numFiles), isset($zip->numFiles));
+printf("zip->bogus (%d):\n\tempty(): %d\n\tisset(): %d\n", $zip->bogus, empty($zip->bogus), isset($zip->bogus));
+
+
+$zip->addEmptyDir('emptydir');
+
+printf("zip->status (%d):\n\tempty(): %d\n\tisset(): %d\n", $zip->status, empty($zip->status), isset($zip->status));
+printf("zip->numFiles (%d):\n\tempty(): %d\n\tisset(): %d\n", $zip->numFiles, empty($zip->numFiles), isset($zip->numFiles));
+printf("zip->filename (%d):\n\tempty(): %d\n\tisset(): %d\n", strlen($zip->filename), empty($zip->filename), isset($zip->filename));
+printf("zip->comment (%d):\n\tempty(): %d\n\tisset(): %d\n", strlen($zip->comment), empty($zip->comment), isset($zip->comment));
+
+unset($zip); //close the file before unlinking
+@unlink($file);
+?>
+--EXPECTF--
+zip->status (0):
+ empty(): 1
+ isset(): 1
+zip->numFiles (4):
+ empty(): 0
+ isset(): 1
+
+Notice: Undefined property: ZipArchive::$bogus in %s on line %d
+zip->bogus (0):
+ empty(): 1
+ isset(): 0
+zip->status (0):
+ empty(): 1
+ isset(): 1
+zip->numFiles (5):
+ empty(): 0
+ isset(): 1
+zip->filename (%d):
+ empty(): 0
+ isset(): 1
+zip->comment (19):
+ empty(): 0
+ isset(): 1
+
diff --git a/ext/zip/tests/oo_rename.phpt b/ext/zip/tests/oo_rename.phpt
new file mode 100644
index 0000000..98489ae
--- /dev/null
+++ b/ext/zip/tests/oo_rename.phpt
@@ -0,0 +1,58 @@
+--TEST--
+Rename entries
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_oo_rename.zip';
+
+@unlink($file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
+ exit('failed');
+}
+
+$zip->addFromString('entry1.txt', 'entry #1');
+$zip->addFromString('entry2.txt', 'entry #2');
+$zip->addFromString('dir/entry2.txt', 'entry #2');
+
+if (!$zip->status == ZIPARCHIVE::ER_OK) {
+ var_dump($zip);
+ echo "failed\n";
+}
+
+$zip->close();
+
+if (!$zip->open($file)) {
+ exit('failed');
+}
+
+dump_entries_name($zip);
+echo "\n";
+
+if (!$zip->renameIndex(0, 'ren_entry1.txt')) {
+ echo "failed index 0\n";
+}
+
+if (!$zip->renameName('dir/entry2.txt', 'dir3/ren_entry2.txt')) {
+ echo "failed name dir/entry2.txt\n";
+}
+dump_entries_name($zip);
+$zip->close();
+
+@unlink($file);
+?>
+--EXPECTF--
+0 entry1.txt
+1 entry2.txt
+2 dir/entry2.txt
+
+0 ren_entry1.txt
+1 entry2.txt
+2 dir3/ren_entry2.txt
diff --git a/ext/zip/tests/oo_setcomment.phpt b/ext/zip/tests/oo_setcomment.phpt
new file mode 100644
index 0000000..89d6e8e
--- /dev/null
+++ b/ext/zip/tests/oo_setcomment.phpt
@@ -0,0 +1,71 @@
+--TEST--
+setComment
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . '__tmp_oo_set_comment.zip';
+
+@unlink($file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZIPARCHIVE::CREATE)) {
+ exit('failed');
+}
+
+$zip->addFromString('entry1.txt', 'entry #1');
+$zip->addFromString('entry2.txt', 'entry #2');
+$zip->addFromString('dir/entry2d.txt', 'entry #2');
+$zip->addFromString('entry4.txt', 'entry #1');
+$zip->addFromString('entry5.txt', 'entry #2');
+
+
+var_dump($zip->setCommentName('entry1.txt', 'entry1.txt'));
+var_dump($zip->setCommentName('entry2.txt', 'entry2.txt'));
+var_dump($zip->setCommentName('dir/entry2d.txt', 'dir/entry2d.txt'));
+var_dump($zip->setArchiveComment('archive'));
+
+var_dump($zip->setCommentIndex(3, 'entry4.txt'));
+var_dump($zip->setCommentIndex(4, 'entry5.txt'));
+var_dump($zip->setArchiveComment('archive'));
+
+if (!$zip->status == ZIPARCHIVE::ER_OK) {
+ echo "failed to write zip\n";
+}
+$zip->close();
+
+if (!$zip->open($file)) {
+ @unlink($file);
+ exit('failed');
+}
+
+var_dump($zip->getCommentIndex(0));
+var_dump($zip->getCommentIndex(1));
+var_dump($zip->getCommentIndex(2));
+var_dump($zip->getCommentIndex(3));
+var_dump($zip->getCommentIndex(4));
+var_dump($zip->getArchiveComment());
+
+$zip->close();
+@unlink($file);
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+string(10) "entry1.txt"
+string(10) "entry2.txt"
+string(15) "dir/entry2d.txt"
+string(10) "entry4.txt"
+string(10) "entry5.txt"
+string(7) "archive"
diff --git a/ext/zip/tests/oo_stream.phpt b/ext/zip/tests/oo_stream.phpt
new file mode 100644
index 0000000..126e78f
--- /dev/null
+++ b/ext/zip/tests/oo_stream.phpt
@@ -0,0 +1,50 @@
+--TEST--
+getStream
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . 'test_with_comment.zip';
+include $dirname . 'utils.inc';
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+$fp = $zip->getStream('foo');
+
+var_dump($fp);
+if(!$fp) exit("\n");
+$contents = '';
+while (!feof($fp)) {
+ $contents .= fread($fp, 255);
+}
+
+fclose($fp);
+$zip->close();
+var_dump($contents);
+
+
+$fp = fopen('zip://' . dirname(__FILE__) . '/test_with_comment.zip#foo', 'rb');
+if (!$fp) {
+ exit("cannot open\n");
+}
+$contents = '';
+while (!feof($fp)) {
+ $contents .= fread($fp, 2);
+}
+var_dump($contents);
+fclose($fp);
+
+?>
+--EXPECTF--
+resource(%d) of type (stream)
+string(5) "foo
+
+"
+string(5) "foo
+
+"
diff --git a/ext/zip/tests/pecl12414.phpt b/ext/zip/tests/pecl12414.phpt
new file mode 100644
index 0000000..6154638
--- /dev/null
+++ b/ext/zip/tests/pecl12414.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Bug #12414 ( extracting files from damaged archives)
+--SKIPIF--
+<?php
+/*$ */
+if(!extension_loaded('zip')) die('skip');
+ ?>
+--FILE--
+<?php
+$filename = 'MYLOGOV2.GFX';
+$zipname = dirname(__FILE__) . "/pecl12414.zip";
+$za = new ZipArchive();
+$res =$za->open($zipname);
+if ($res === TRUE) {
+ $finfo=$za->statName($filename);
+ $file_size=$finfo['size'];
+
+ if($file_size>0) {
+ $contents=$za->getFromName($filename);
+
+ echo "ZIP contents size: " . strlen($contents) . "\n";
+ if(strlen($contents)!=$file_size) {
+ echo "zip_readfile recorded data does not match unpacked size: " . $zipname . " : " . $filename;
+ }
+ } else {
+ $contents=false;
+ echo "zip_readfile could not open stream from zero length file " . $zipname . " : " .$filename;
+ }
+
+ $za->close();
+} else {
+ echo "zip_readfile could not read from " . $zipname . " : " . $filename;
+}
+
+?>
+--DONE--
+--EXPECTF--
+zip_readfile could not read from %specl12414.zip : MYLOGOV2.GFX
diff --git a/ext/zip/tests/pecl12414.zip b/ext/zip/tests/pecl12414.zip
new file mode 100644
index 0000000..6cbc60f
--- /dev/null
+++ b/ext/zip/tests/pecl12414.zip
Binary files differ
diff --git a/ext/zip/tests/stream_meta_data.phpt b/ext/zip/tests/stream_meta_data.phpt
new file mode 100644
index 0000000..bd08098
--- /dev/null
+++ b/ext/zip/tests/stream_meta_data.phpt
@@ -0,0 +1,74 @@
+--TEST--
+stream_get_meta_data() on zip stream
+--SKIPIF--
+<?php
+/* $Id: oo_stream.phpt 260091 2008-05-21 09:27:41Z pajoye $ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$dirname = dirname(__FILE__) . '/';
+$file = $dirname . 'test_with_comment.zip';
+include $dirname . 'utils.inc';
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+ exit('failed');
+}
+$fp = $zip->getStream('foo');
+
+if(!$fp) exit("\n");
+
+var_dump(stream_get_meta_data($fp));
+
+fclose($fp);
+$zip->close();
+
+
+$fp = fopen('zip://' . dirname(__FILE__) . '/test_with_comment.zip#foo', 'rb');
+if (!$fp) {
+ exit("cannot open\n");
+}
+
+var_dump(stream_get_meta_data($fp));
+fclose($fp);
+
+?>
+--EXPECTF--
+array(8) {
+ ["stream_type"]=>
+ string(3) "zip"
+ ["mode"]=>
+ string(2) "rb"
+ ["unread_bytes"]=>
+ int(0)
+ ["seekable"]=>
+ bool(false)
+ ["uri"]=>
+ string(3) "foo"
+ ["timed_out"]=>
+ bool(false)
+ ["blocked"]=>
+ bool(true)
+ ["eof"]=>
+ bool(false)
+}
+array(9) {
+ ["wrapper_type"]=>
+ string(11) "zip wrapper"
+ ["stream_type"]=>
+ string(3) "zip"
+ ["mode"]=>
+ string(2) "rb"
+ ["unread_bytes"]=>
+ int(0)
+ ["seekable"]=>
+ bool(false)
+ ["uri"]=>
+ string(%d) "zip://%stest_with_comment.zip#foo"
+ ["timed_out"]=>
+ bool(false)
+ ["blocked"]=>
+ bool(true)
+ ["eof"]=>
+ bool(false)
+}
diff --git a/ext/zip/tests/test.zip b/ext/zip/tests/test.zip
new file mode 100644
index 0000000..35bd5ee
--- /dev/null
+++ b/ext/zip/tests/test.zip
Binary files differ
diff --git a/ext/zip/tests/test_procedural.zip b/ext/zip/tests/test_procedural.zip
new file mode 100644
index 0000000..6b98694
--- /dev/null
+++ b/ext/zip/tests/test_procedural.zip
Binary files differ
diff --git a/ext/zip/tests/test_with_comment.zip b/ext/zip/tests/test_with_comment.zip
new file mode 100644
index 0000000..d68f761
--- /dev/null
+++ b/ext/zip/tests/test_with_comment.zip
Binary files differ
diff --git a/ext/zip/tests/utils.inc b/ext/zip/tests/utils.inc
new file mode 100644
index 0000000..02e37f6
--- /dev/null
+++ b/ext/zip/tests/utils.inc
@@ -0,0 +1,24 @@
+<?php
+/* $Id$ */
+function dump_entries_name($z) {
+ for($i=0; $i<$z->numFiles; $i++) {
+ $sb = $z->statIndex($i);
+ echo $i . ' ' . $sb['name'] . "\n";
+ }
+}
+/* recursively remove a directoryy */
+function rmdir_rf($dir) {
+ if ($handle = opendir($dir)) {
+ while (false !== ($item = readdir($handle))) {
+ if ($item != "." && $item != "..") {
+ if (is_dir($dir . '/' . $item)) {
+ rmdir_rf($dir . '/' . $item);
+ } else {
+ unlink($dir . '/' . $item);
+ }
+ }
+ }
+ closedir($handle);
+ rmdir($dir);
+ }
+}
diff --git a/ext/zip/tests/zip_close.phpt b/ext/zip/tests/zip_close.phpt
new file mode 100644
index 0000000..7f9d09a
--- /dev/null
+++ b/ext/zip/tests/zip_close.phpt
@@ -0,0 +1,17 @@
+--TEST--
+zip_close() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+if (!is_resource($zip)) die("Failure");
+zip_close($zip);
+echo "OK";
+
+?>
+--EXPECT--
+OK
diff --git a/ext/zip/tests/zip_entry_compressedsize.phpt b/ext/zip/tests/zip_entry_compressedsize.phpt
new file mode 100644
index 0000000..fefa6e5
--- /dev/null
+++ b/ext/zip/tests/zip_entry_compressedsize.phpt
@@ -0,0 +1,23 @@
+--TEST--
+zip_entry_compressedsize() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+if (!is_resource($zip)) die("Failure");
+$entries = 0;
+while ($entry = zip_read($zip)) {
+ echo zip_entry_compressedsize($entry)."\n";
+}
+zip_close($zip);
+
+?>
+--EXPECT--
+5
+4
+0
+24
diff --git a/ext/zip/tests/zip_entry_compressionmethod.phpt b/ext/zip/tests/zip_entry_compressionmethod.phpt
new file mode 100644
index 0000000..cabdbb7
--- /dev/null
+++ b/ext/zip/tests/zip_entry_compressionmethod.phpt
@@ -0,0 +1,24 @@
+--TEST--
+zip_entry_compressionmethod() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+if (!is_resource($zip)) die("Failure");
+$entries = 0;
+while ($entry = zip_read($zip)) {
+ echo zip_entry_compressionmethod($entry)."\n";
+}
+zip_close($zip);
+
+?>
+--EXPECT--
+stored
+stored
+stored
+deflated
+
diff --git a/ext/zip/tests/zip_entry_filesize.phpt b/ext/zip/tests/zip_entry_filesize.phpt
new file mode 100644
index 0000000..b8d8820
--- /dev/null
+++ b/ext/zip/tests/zip_entry_filesize.phpt
@@ -0,0 +1,23 @@
+--TEST--
+zip_entry_filesize() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+if (!is_resource($zip)) die("Failure");
+$entries = 0;
+while ($entry = zip_read($zip)) {
+ echo zip_entry_filesize($entry)."\n";
+}
+zip_close($zip);
+
+?>
+--EXPECT--
+5
+4
+0
+27
diff --git a/ext/zip/tests/zip_entry_name.phpt b/ext/zip/tests/zip_entry_name.phpt
new file mode 100644
index 0000000..1916e25
--- /dev/null
+++ b/ext/zip/tests/zip_entry_name.phpt
@@ -0,0 +1,23 @@
+--TEST--
+zip_entry_name() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+if (!is_resource($zip)) die("Failure");
+$entries = 0;
+while ($entry = zip_read($zip)) {
+ echo zip_entry_name($entry)."\n";
+}
+zip_close($zip);
+
+?>
+--EXPECT--
+foo
+bar
+foobar/
+foobar/baz
diff --git a/ext/zip/tests/zip_entry_open.phpt b/ext/zip/tests/zip_entry_open.phpt
new file mode 100644
index 0000000..c32fe57
--- /dev/null
+++ b/ext/zip/tests/zip_entry_open.phpt
@@ -0,0 +1,18 @@
+--TEST--
+zip_entry_open() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+$entry = zip_read($zip);
+echo zip_entry_open($zip, $entry, "r") ? "OK" : "Failure";
+zip_entry_close($entry);
+zip_close($zip);
+
+?>
+--EXPECT--
+OK
diff --git a/ext/zip/tests/zip_entry_read.phpt b/ext/zip/tests/zip_entry_read.phpt
new file mode 100644
index 0000000..d876f03
--- /dev/null
+++ b/ext/zip/tests/zip_entry_read.phpt
@@ -0,0 +1,19 @@
+--TEST--
+zip_entry_read() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+$entry = zip_read($zip);
+if (!zip_entry_open($zip, $entry, "r")) die("Failure");
+echo zip_entry_read($entry);
+zip_entry_close($entry);
+zip_close($zip);
+
+?>
+--EXPECT--
+foo
diff --git a/ext/zip/tests/zip_open.phpt b/ext/zip/tests/zip_open.phpt
new file mode 100644
index 0000000..91474bc
--- /dev/null
+++ b/ext/zip/tests/zip_open.phpt
@@ -0,0 +1,16 @@
+--TEST--
+zip_open() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+
+echo is_resource($zip) ? "OK" : "Failure";
+
+?>
+--EXPECT--
+OK
diff --git a/ext/zip/tests/zip_open_error.phpt b/ext/zip/tests/zip_open_error.phpt
new file mode 100644
index 0000000..eaa1d97
--- /dev/null
+++ b/ext/zip/tests/zip_open_error.phpt
@@ -0,0 +1,28 @@
+--TEST--
+zip_open() error conditions
+--CREDITS--
+Birgitte Kvarme <bitta@redpill-linpro.com>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+echo "Test case 1:";
+$zip = zip_open("");
+
+echo "Test case 2:";
+$zip = zip_open("i_dont_care_about_this_parameter", "this_is_one_to_many");
+
+echo "Test case 3:\n";
+$zip = zip_open("/non_exisitng_directory/test_procedural.zip");
+echo is_resource($zip) ? "OK" : "Failure";
+?>
+--EXPECTF--
+Test case 1:
+Warning: zip_open(): Empty string as source in %s on line %d
+Test case 2:
+Warning: zip_open() expects exactly 1 parameter, 2 given in %s on line %d
+Test case 3:
+Failure
diff --git a/ext/zip/tests/zip_read.phpt b/ext/zip/tests/zip_read.phpt
new file mode 100644
index 0000000..5cadb2d
--- /dev/null
+++ b/ext/zip/tests/zip_read.phpt
@@ -0,0 +1,21 @@
+--TEST--
+zip_read() function
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
+if (!is_resource($zip)) die("Failure");
+$entries = 0;
+while ($entry = zip_read($zip)) {
+ $entries++;
+}
+zip_close($zip);
+echo "$entries entries";
+
+?>
+--EXPECT--
+4 entries
diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c
new file mode 100644
index 0000000..400edd6
--- /dev/null
+++ b/ext/zip/zip_stream.c
@@ -0,0 +1,338 @@
+/* $Id$ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "php.h"
+#if HAVE_ZIP
+#ifdef ZEND_ENGINE_2
+
+#include "lib/zip.h"
+
+#include "php_streams.h"
+#include "ext/standard/file.h"
+#include "ext/standard/php_string.h"
+#include "fopen_wrappers.h"
+#include "php_zip.h"
+
+#include "ext/standard/url.h"
+
+struct php_zip_stream_data_t {
+ struct zip *za;
+ struct zip_file *zf;
+ size_t cursor;
+ php_stream *stream;
+};
+
+#define STREAM_DATA_FROM_STREAM() \
+ struct php_zip_stream_data_t *self = (struct php_zip_stream_data_t *) stream->abstract;
+
+
+/* {{{ php_zip_ops_read */
+static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
+{
+ ssize_t n = 0;
+ STREAM_DATA_FROM_STREAM();
+
+ if (self->za && self->zf) {
+ n = zip_fread(self->zf, buf, count);
+ if (n < 0) {
+ int ze, se;
+ zip_file_error_get(self->zf, &ze, &se);
+ stream->eof = 1;
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zip stream error: %s", zip_file_strerror(self->zf));
+ return 0;
+ }
+ /* cast count to signed value to avoid possibly negative n
+ * being cast to unsigned value */
+ if (n == 0 || n < (ssize_t)count) {
+ stream->eof = 1;
+ } else {
+ self->cursor += n;
+ }
+ }
+ return (n < 1 ? 0 : (size_t)n);
+}
+/* }}} */
+
+/* {{{ php_zip_ops_write */
+static size_t php_zip_ops_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
+{
+ if (!stream) {
+ return 0;
+ }
+
+ return count;
+}
+/* }}} */
+
+/* {{{ php_zip_ops_close */
+static int php_zip_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
+{
+ STREAM_DATA_FROM_STREAM();
+ if (close_handle) {
+ if (self->zf) {
+ zip_fclose(self->zf);
+ self->zf = NULL;
+ }
+
+ if (self->za) {
+ zip_close(self->za);
+ self->za = NULL;
+ }
+ }
+ efree(self);
+ stream->abstract = NULL;
+ return EOF;
+}
+/* }}} */
+
+/* {{{ php_zip_ops_flush */
+static int php_zip_ops_flush(php_stream *stream TSRMLS_DC)
+{
+ if (!stream) {
+ return 0;
+ }
+
+ return 0;
+}
+/* }}} */
+
+static int php_zip_ops_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) /* {{{ */
+{
+ struct zip_stat sb;
+ const char *path = stream->orig_path;
+ int path_len = strlen(stream->orig_path);
+ char *file_basename;
+ size_t file_basename_len;
+ char file_dirname[MAXPATHLEN];
+ struct zip *za;
+ char *fragment;
+ int fragment_len;
+ int err;
+
+ fragment = strchr(path, '#');
+ if (!fragment) {
+ return -1;
+ }
+
+
+ if (strncasecmp("zip://", path, 6) == 0) {
+ path += 6;
+ }
+
+ fragment_len = strlen(fragment);
+
+ if (fragment_len < 1) {
+ return -1;
+ }
+ path_len = strlen(path);
+ if (path_len >= MAXPATHLEN) {
+ return -1;
+ }
+
+ memcpy(file_dirname, path, path_len - fragment_len);
+ file_dirname[path_len - fragment_len] = '\0';
+
+ php_basename((char *)path, path_len - fragment_len, NULL, 0, &file_basename, &file_basename_len TSRMLS_CC);
+ fragment++;
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) {
+ efree(file_basename);
+ return -1;
+ }
+
+ za = zip_open(file_dirname, ZIP_CREATE, &err);
+ if (za) {
+ memset(ssb, 0, sizeof(php_stream_statbuf));
+ if (zip_stat(za, fragment, ZIP_FL_NOCASE, &sb) != 0) {
+ efree(file_basename);
+ return -1;
+ }
+ zip_close(za);
+
+ if (path[path_len-1] != '/') {
+ ssb->sb.st_size = sb.size;
+ ssb->sb.st_mode |= S_IFREG; /* regular file */
+ } else {
+ ssb->sb.st_size = 0;
+ ssb->sb.st_mode |= S_IFDIR; /* regular directory */
+ }
+
+ ssb->sb.st_mtime = sb.mtime;
+ ssb->sb.st_atime = sb.mtime;
+ ssb->sb.st_ctime = sb.mtime;
+ ssb->sb.st_nlink = 1;
+ ssb->sb.st_rdev = -1;
+#ifndef PHP_WIN32
+ ssb->sb.st_blksize = -1;
+ ssb->sb.st_blocks = -1;
+#endif
+ ssb->sb.st_ino = -1;
+ }
+ efree(file_basename);
+ return 0;
+}
+/* }}} */
+
+php_stream_ops php_stream_zipio_ops = {
+ php_zip_ops_write, php_zip_ops_read,
+ php_zip_ops_close, php_zip_ops_flush,
+ "zip",
+ NULL, /* seek */
+ NULL, /* cast */
+ php_zip_ops_stat, /* stat */
+ NULL /* set_option */
+};
+
+/* {{{ php_stream_zip_open */
+php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_DC TSRMLS_DC)
+{
+ struct zip_file *zf = NULL;
+ int err = 0;
+
+ php_stream *stream = NULL;
+ struct php_zip_stream_data_t *self;
+ struct zip *stream_za;
+
+ if (strncmp(mode,"r", strlen("r")) != 0) {
+ return NULL;
+ }
+
+ if (filename) {
+ if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
+ return NULL;
+ }
+
+ /* duplicate to make the stream za independent (esp. for MSHUTDOWN) */
+ stream_za = zip_open(filename, ZIP_CREATE, &err);
+ if (!stream_za) {
+ return NULL;
+ }
+
+ zf = zip_fopen(stream_za, path, 0);
+ if (zf) {
+ self = emalloc(sizeof(*self));
+
+ self->za = stream_za;
+ self->zf = zf;
+ self->stream = NULL;
+ self->cursor = 0;
+ stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode);
+ stream->orig_path = estrdup(path);
+ } else {
+ zip_close(stream_za);
+ }
+ }
+
+ if (!stream) {
+ return NULL;
+ } else {
+ return stream;
+ }
+
+}
+/* }}} */
+
+/* {{{ php_stream_zip_opener */
+php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper,
+ char *path,
+ char *mode,
+ int options,
+ char **opened_path,
+ php_stream_context *context STREAMS_DC TSRMLS_DC)
+{
+ int path_len;
+
+ char *file_basename;
+ size_t file_basename_len;
+ char file_dirname[MAXPATHLEN];
+
+ struct zip *za;
+ struct zip_file *zf = NULL;
+ char *fragment;
+ int fragment_len;
+ int err;
+
+ php_stream *stream = NULL;
+ struct php_zip_stream_data_t *self;
+
+ fragment = strchr(path, '#');
+ if (!fragment) {
+ return NULL;
+ }
+
+ if (strncasecmp("zip://", path, 6) == 0) {
+ path += 6;
+ }
+
+ fragment_len = strlen(fragment);
+
+ if (fragment_len < 1) {
+ return NULL;
+ }
+ path_len = strlen(path);
+ if (path_len >= MAXPATHLEN || mode[0] != 'r') {
+ return NULL;
+ }
+
+ memcpy(file_dirname, path, path_len - fragment_len);
+ file_dirname[path_len - fragment_len] = '\0';
+
+ php_basename(path, path_len - fragment_len, NULL, 0, &file_basename, &file_basename_len TSRMLS_CC);
+ fragment++;
+
+ if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) {
+ efree(file_basename);
+ return NULL;
+ }
+
+ za = zip_open(file_dirname, ZIP_CREATE, &err);
+ if (za) {
+ zf = zip_fopen(za, fragment, 0);
+ if (zf) {
+ self = emalloc(sizeof(*self));
+
+ self->za = za;
+ self->zf = zf;
+ self->stream = NULL;
+ self->cursor = 0;
+ stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode);
+
+ if (opened_path) {
+ *opened_path = estrdup(path);
+ }
+ } else {
+ zip_close(za);
+ }
+ }
+
+ efree(file_basename);
+
+ if (!stream) {
+ return NULL;
+ } else {
+ return stream;
+ }
+}
+/* }}} */
+
+static php_stream_wrapper_ops zip_stream_wops = {
+ php_stream_zip_opener,
+ NULL, /* close */
+ NULL, /* fstat */
+ NULL, /* stat */
+ NULL, /* opendir */
+ "zip wrapper",
+ NULL, /* unlink */
+ NULL, /* rename */
+ NULL, /* mkdir */
+ NULL /* rmdir */
+};
+
+php_stream_wrapper php_stream_zip_wrapper = {
+ &zip_stream_wops,
+ NULL,
+ 0 /* is_url */
+};
+#endif /* ZEND_ENGINE_2 */
+#endif /* HAVE_ZIP */