2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt. |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Piere-Alain Joye <pierre@php.net> |
16 +----------------------------------------------------------------------+
27 #include "ext/standard/info.h"
28 #include "ext/standard/file.h"
29 #include "ext/standard/php_string.h"
30 #include "ext/pcre/php_pcre.h"
33 #include "lib/zipint.h"
35 /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
36 static PHP_NAMED_FUNCTION(zif_zip_open
);
37 static PHP_NAMED_FUNCTION(zif_zip_read
);
38 static PHP_NAMED_FUNCTION(zif_zip_close
);
39 static PHP_NAMED_FUNCTION(zif_zip_entry_read
);
40 static PHP_NAMED_FUNCTION(zif_zip_entry_filesize
);
41 static PHP_NAMED_FUNCTION(zif_zip_entry_name
);
42 static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize
);
43 static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod
);
44 static PHP_NAMED_FUNCTION(zif_zip_entry_open
);
45 static PHP_NAMED_FUNCTION(zif_zip_entry_close
);
51 #include "win32/glob.h"
56 static int le_zip_dir
;
57 #define le_zip_dir_name "Zip Directory"
58 static int le_zip_entry
;
59 #define le_zip_entry_name "Zip Entry"
62 /* {{{ PHP_ZIP_STAT_INDEX(za, index, flags, sb) */
63 #define PHP_ZIP_STAT_INDEX(za, index, flags, sb) \
64 if (zip_stat_index(za, index, flags, &sb) != 0) { \
69 /* {{{ PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) */
70 #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \
72 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name"); \
75 if (zip_stat(za, path, flags, &sb) != 0) { \
80 /* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */
81 #define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \
82 if (comment_len == 0) { \
83 /* Passing NULL remove the existing comment */ \
84 if (zip_set_file_comment(intern, index, NULL, 0) < 0) { \
87 } else if (zip_set_file_comment(intern, index, comment, comment_len) < 0) { \
93 #if (PHP_MAJOR_VERSION < 6)
94 # define add_ascii_assoc_string add_assoc_string
95 # define add_ascii_assoc_long add_assoc_long
98 /* Flatten a path by making a relative path (to .)*/
99 static char * php_zip_make_relative_path(char *path
, int path_len
) /* {{{ */
101 char *path_begin
= path
;
104 if (IS_SLASH(path
[0])) {
108 if (path_len
< 1 || path
== NULL
) {
115 while (i
> 0 && !IS_SLASH(path
[i
])) {
123 if (i
>= 2 && (path
[i
-1] == '.' || path
[i
-1] == ':')) {
124 /* i is the position of . or :, add 1 for / */
125 path_begin
= path
+ i
+ 1;
135 #ifdef PHP_ZIP_USE_OO
136 /* {{{ php_zip_extract_file */
137 static int php_zip_extract_file(struct zip
* za
, char *dest
, char *file
, int file_len TSRMLS_DC
)
139 php_stream_statbuf ssb
;
146 char *file_dirname_fullpath
;
147 char file_dirname
[MAXPATHLEN
];
150 size_t file_basename_len
;
153 size_t path_cleaned_len
;
156 new_state
.cwd
= (char*)malloc(1);
157 new_state
.cwd
[0] = '\0';
158 new_state
.cwd_length
= 0;
160 /* Clean/normlize the path and then transform any path (absolute or relative)
161 to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
163 virtual_file_ex(&new_state
, file
, NULL
, CWD_EXPAND TSRMLS_CC
);
164 path_cleaned
= php_zip_make_relative_path(new_state
.cwd
, new_state
.cwd_length
);
168 path_cleaned_len
= strlen(path_cleaned
);
170 if (path_cleaned_len
>= MAXPATHLEN
|| zip_stat(za
, file
, 0, &sb
) != 0) {
174 /* it is a directory only, see #40228 */
175 if (path_cleaned_len
> 1 && IS_SLASH(path_cleaned
[path_cleaned_len
- 1])) {
176 len
= spprintf(&file_dirname_fullpath
, 0, "%s/%s", dest
, file
);
179 memcpy(file_dirname
, path_cleaned
, path_cleaned_len
);
180 dir_len
= php_dirname(file_dirname
, path_cleaned_len
);
182 if (dir_len
<= 0 || (dir_len
== 1 && file_dirname
[0] == '.')) {
183 len
= spprintf(&file_dirname_fullpath
, 0, "%s", dest
);
185 len
= spprintf(&file_dirname_fullpath
, 0, "%s/%s", dest
, file_dirname
);
188 php_basename(path_cleaned
, path_cleaned_len
, NULL
, 0, &file_basename
, (size_t *)&file_basename_len TSRMLS_CC
);
190 if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath
)) {
191 efree(file_dirname_fullpath
);
192 efree(file_basename
);
198 /* let see if the path already exists */
199 if (php_stream_stat_path_ex(file_dirname_fullpath
, PHP_STREAM_URL_STAT_QUIET
, &ssb
, NULL
) < 0) {
201 #if defined(PHP_WIN32) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1)
203 e
= file_dirname_fullpath
;
212 ret
= php_stream_mkdir(file_dirname_fullpath
, 0777, PHP_STREAM_MKDIR_RECURSIVE
|REPORT_ERRORS
, NULL
);
214 efree(file_dirname_fullpath
);
216 efree(file_basename
);
223 /* it is a standalone directory, job done */
225 efree(file_dirname_fullpath
);
230 len
= spprintf(&fullpath
, 0, "%s/%s", file_dirname_fullpath
, file_basename
);
232 efree(file_dirname_fullpath
);
233 efree(file_basename
);
236 } else if (len
> MAXPATHLEN
) {
237 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN
);
238 efree(file_dirname_fullpath
);
239 efree(file_basename
);
244 /* check again the full path, not sure if it
245 * is required, does a file can have a different
246 * safemode status as its parent folder?
248 if (ZIP_OPENBASEDIR_CHECKPATH(fullpath
)) {
250 efree(file_dirname_fullpath
);
251 efree(file_basename
);
256 #if PHP_API_VERSION < 20100412
257 stream
= php_stream_open_wrapper(fullpath
, "w+b", REPORT_ERRORS
|ENFORCE_SAFE_MODE
, NULL
);
259 stream
= php_stream_open_wrapper(fullpath
, "w+b", REPORT_ERRORS
, NULL
);
262 if (stream
== NULL
) {
267 zf
= zip_fopen(za
, file
, 0);
270 php_stream_close(stream
);
276 while ((n
=zip_fread(zf
, b
, sizeof(b
))) > 0) {
277 php_stream_write(stream
, b
, n
);
280 php_stream_close(stream
);
285 efree(file_basename
);
286 efree(file_dirname_fullpath
);
297 static int php_zip_add_file(struct zip
*za
, const char *filename
, size_t filename_len
,
298 char *entry_name
, size_t entry_name_len
, long offset_start
, long offset_len TSRMLS_DC
) /* {{{ */
300 struct zip_source
*zs
;
302 char resolved_path
[MAXPATHLEN
];
305 if (ZIP_OPENBASEDIR_CHECKPATH(filename
)) {
309 if (!expand_filepath(filename
, resolved_path TSRMLS_CC
)) {
313 zs
= zip_source_file(za
, resolved_path
, offset_start
, offset_len
);
318 cur_idx
= zip_name_locate(za
, (const char *)entry_name
, 0);
319 /* TODO: fix _zip_replace */
321 /* reset the error */
323 _zip_error_fini(&za
->error
);
325 _zip_error_init(&za
->error
);
327 if (zip_delete(za
, cur_idx
) == -1) {
333 if (zip_add(za
, entry_name
, zs
) == -1) {
341 static int php_zip_parse_options(zval
*options
, long *remove_all_path
,
342 char **remove_path
, int *remove_path_len
, char **add_path
, int *add_path_len TSRMLS_DC
) /* {{{ */
345 if (zend_hash_find(HASH_OF(options
), "remove_all_path", sizeof("remove_all_path"), (void **)&option
) == SUCCESS
) {
347 if (Z_TYPE_PP(option
) != IS_LONG
) {
349 zval_copy_ctor(&tmp
);
350 convert_to_long(&tmp
);
353 opt
= Z_LVAL_PP(option
);
355 *remove_all_path
= opt
;
358 /* If I add more options, it would make sense to create a nice static struct and loop over it. */
359 if (zend_hash_find(HASH_OF(options
), "remove_path", sizeof("remove_path"), (void **)&option
) == SUCCESS
) {
360 if (Z_TYPE_PP(option
) != IS_STRING
) {
361 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "remove_path option expected to be a string");
365 if (Z_STRLEN_PP(option
) < 1) {
366 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string given as remove_path option");
370 if (Z_STRLEN_PP(option
) >= MAXPATHLEN
) {
371 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "remove_path string is too long (max: %i, %i given)",
372 MAXPATHLEN
- 1, Z_STRLEN_PP(option
));
375 *remove_path_len
= Z_STRLEN_PP(option
);
376 *remove_path
= Z_STRVAL_PP(option
);
379 if (zend_hash_find(HASH_OF(options
), "add_path", sizeof("add_path"), (void **)&option
) == SUCCESS
) {
380 if (Z_TYPE_PP(option
) != IS_STRING
) {
381 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "add_path option expected to be a string");
385 if (Z_STRLEN_PP(option
) < 1) {
386 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string given as the add_path option");
390 if (Z_STRLEN_PP(option
) >= MAXPATHLEN
) {
391 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "add_path string too long (max: %i, %i given)",
392 MAXPATHLEN
- 1, Z_STRLEN_PP(option
));
395 *add_path_len
= Z_STRLEN_PP(option
);
396 *add_path
= Z_STRVAL_PP(option
);
402 /* {{{ REGISTER_ZIP_CLASS_CONST_LONG */
403 #define REGISTER_ZIP_CLASS_CONST_LONG(const_name, value) \
404 zend_declare_class_constant_long(zip_class_entry, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
407 /* {{{ ZIP_FROM_OBJECT */
408 #define ZIP_FROM_OBJECT(intern, object) \
410 ze_zip_object *obj = (ze_zip_object*) zend_object_store_get_object(object TSRMLS_CC); \
413 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized Zip object"); \
419 /* {{{ RETURN_SB(sb) */
420 #define RETURN_SB(sb) \
422 array_init(return_value); \
423 add_ascii_assoc_string(return_value, "name", (char *)(sb)->name, 1); \
424 add_ascii_assoc_long(return_value, "index", (long) (sb)->index); \
425 add_ascii_assoc_long(return_value, "crc", (long) (sb)->crc); \
426 add_ascii_assoc_long(return_value, "size", (long) (sb)->size); \
427 add_ascii_assoc_long(return_value, "mtime", (long) (sb)->mtime); \
428 add_ascii_assoc_long(return_value, "comp_size", (long) (sb)->comp_size); \
429 add_ascii_assoc_long(return_value, "comp_method", (long) (sb)->comp_method); \
433 static int php_zip_status(struct zip
*za TSRMLS_DC
) /* {{{ */
437 zip_error_get(za
, &zep
, &syp
);
442 static int php_zip_status_sys(struct zip
*za TSRMLS_DC
) /* {{{ */
446 zip_error_get(za
, &zep
, &syp
);
451 static int php_zip_get_num_files(struct zip
*za TSRMLS_DC
) /* {{{ */
453 return zip_get_num_files(za
);
457 static char * php_zipobj_get_filename(ze_zip_object
*obj TSRMLS_DC
) /* {{{ */
465 return obj
->filename
;
471 static char * php_zipobj_get_zip_comment(struct zip
*za
, int *len TSRMLS_DC
) /* {{{ */
474 return (char *)zip_get_archive_comment(za
, len
, 0);
480 #ifdef HAVE_GLOB /* {{{ */
482 #define GLOB_ONLYDIR (1<<30)
483 #define GLOB_EMULATE_ONLYDIR
484 #define GLOB_FLAGMASK (~GLOB_ONLYDIR)
486 #define GLOB_FLAGMASK (~0)
489 # define GLOB_BRACE 0
495 # define GLOB_NOSORT 0
498 # define GLOB_NOCHECK 0
500 #ifndef GLOB_NOESCAPE
501 # define GLOB_NOESCAPE 0
507 /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
508 #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
512 int php_zip_glob(char *pattern
, int pattern_len
, long flags
, zval
*return_value TSRMLS_DC
) /* {{{ */
515 char cwd
[MAXPATHLEN
];
518 char work_pattern
[MAXPATHLEN
];
525 if (pattern_len
>= MAXPATHLEN
) {
526 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN
);
530 if ((GLOB_AVAILABLE_FLAGS
& flags
) != flags
) {
531 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "At least one of the passed flags is invalid or not supported on this platform");
536 if (!IS_ABSOLUTE_PATH(pattern
, pattern_len
)) {
537 result
= VCWD_GETCWD(cwd
, MAXPATHLEN
);
542 if (IS_SLASH(*pattern
)) {
546 cwd_skip
= strlen(cwd
)+1;
548 snprintf(work_pattern
, MAXPATHLEN
, "%s%c%s", cwd
, DEFAULT_SLASH
, pattern
);
549 pattern
= work_pattern
;
554 if (0 != (ret
= glob(pattern
, flags
& GLOB_FLAGMASK
, NULL
, &globbuf
))) {
556 if (GLOB_NOMATCH
== ret
) {
557 /* Some glob implementation simply return no data if no matches
558 were found, others return the GLOB_NOMATCH error code.
559 We don't want to treat GLOB_NOMATCH as an error condition
560 so that PHP glob() behaves the same on both types of
561 implementations and so that 'foreach (glob() as ...'
562 can be used for simple glob() calls without further error
565 array_init(return_value
);
572 /* now catch the FreeBSD style of "no matches" */
573 if (!globbuf
.gl_pathc
|| !globbuf
.gl_pathv
) {
574 array_init(return_value
);
578 /* we assume that any glob pattern will match files from one directory only
579 so checking the dirname of the first match should be sufficient */
580 strncpy(cwd
, globbuf
.gl_pathv
[0], MAXPATHLEN
);
581 if (ZIP_OPENBASEDIR_CHECKPATH(cwd
)) {
585 array_init(return_value
);
586 for (n
= 0; n
< globbuf
.gl_pathc
; n
++) {
587 /* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
588 * all directories will be filtered. GNU libc documentation states the
590 * If the information about the type of the file is easily available
591 * non-directories will be rejected but no extra work will be done to
592 * determine the information for each file. I.e., the caller must still be
593 * able to filter directories out.
595 if (flags
& GLOB_ONLYDIR
) {
598 if (0 != VCWD_STAT(globbuf
.gl_pathv
[n
], &s
)) {
602 if (S_IFDIR
!= (s
.st_mode
& S_IFMT
)) {
606 add_next_index_string(return_value
, globbuf
.gl_pathv
[n
]+cwd_skip
, 1);
610 return globbuf
.gl_pathc
;
612 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Glob support is not available");
614 #endif /* HAVE_GLOB */
618 int php_zip_pcre(char *regexp
, int regexp_len
, char *path
, int path_len
, zval
*return_value TSRMLS_DC
) /* {{{ */
621 char cwd
[MAXPATHLEN
];
623 char work_path
[MAXPATHLEN
];
630 if (!IS_ABSOLUTE_PATH(path
, path_len
)) {
631 result
= VCWD_GETCWD(cwd
, MAXPATHLEN
);
636 if (IS_SLASH(*path
)) {
640 cwd_skip
= strlen(cwd
)+1;
642 snprintf(work_path
, MAXPATHLEN
, "%s%c%s", cwd
, DEFAULT_SLASH
, path
);
647 if (ZIP_OPENBASEDIR_CHECKPATH(path
)) {
651 files_cnt
= php_stream_scandir(path
, &namelist
, NULL
, (void *) php_stream_dirent_alphasort
);
655 pcre_extra
*pcre_extra
= NULL
;
656 int preg_options
= 0, i
;
658 re
= pcre_get_compiled_regex(regexp
, &pcre_extra
, &preg_options TSRMLS_CC
);
660 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid expression");
664 array_init(return_value
);
666 /* only the files, directories are ignored */
667 for (i
= 0; i
< files_cnt
; i
++) {
669 char fullpath
[MAXPATHLEN
];
672 int namelist_len
= strlen(namelist
[i
]);
675 if ((namelist_len
== 1 && namelist
[i
][0] == '.') ||
676 (namelist_len
== 2 && namelist
[i
][0] == '.' && namelist
[i
][1] == '.')) {
681 if ((path_len
+ namelist_len
+ 1) >= MAXPATHLEN
) {
682 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "add_path string too long (max: %i, %i given)",
683 MAXPATHLEN
- 1, (path_len
+ namelist_len
+ 1));
688 snprintf(fullpath
, MAXPATHLEN
, "%s%c%s", path
, DEFAULT_SLASH
, namelist
[i
]);
690 if (0 != VCWD_STAT(fullpath
, &s
)) {
691 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Cannot read <%s>", fullpath
);
696 if (S_IFDIR
== (s
.st_mode
& S_IFMT
)) {
701 matches
= pcre_exec(re
, NULL
, namelist
[i
], strlen(namelist
[i
]), 0, 0, ovector
, 3);
702 /* 0 means that the vector is too small to hold all the captured substring offsets */
708 add_next_index_string(return_value
, fullpath
, 1);
720 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open
, 0, 0, 1)
721 ZEND_ARG_INFO(0, filename
)
724 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_close
, 0, 0, 1)
725 ZEND_ARG_INFO(0, zip
)
728 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_read
, 0, 0, 1)
729 ZEND_ARG_INFO(0, zip
)
732 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_open
, 0, 0, 2)
733 ZEND_ARG_INFO(0, zip_dp
)
734 ZEND_ARG_INFO(0, zip_entry
)
735 ZEND_ARG_INFO(0, mode
)
738 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_close
, 0, 0, 1)
739 ZEND_ARG_INFO(0, zip_ent
)
742 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_read
, 0, 0, 1)
743 ZEND_ARG_INFO(0, zip_entry
)
744 ZEND_ARG_INFO(0, len
)
747 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_name
, 0, 0, 1)
748 ZEND_ARG_INFO(0, zip_entry
)
751 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressedsize
, 0, 0, 1)
752 ZEND_ARG_INFO(0, zip_entry
)
755 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_filesize
, 0, 0, 1)
756 ZEND_ARG_INFO(0, zip_entry
)
759 ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressionmethod
, 0, 0, 1)
760 ZEND_ARG_INFO(0, zip_entry
)
764 /* {{{ zend_function_entry */
765 static const zend_function_entry zip_functions
[] = {
766 ZEND_RAW_FENTRY("zip_open", zif_zip_open
, arginfo_zip_open
, 0)
767 ZEND_RAW_FENTRY("zip_close", zif_zip_close
, arginfo_zip_close
, 0)
768 ZEND_RAW_FENTRY("zip_read", zif_zip_read
, arginfo_zip_read
, 0)
769 PHP_FE(zip_entry_open
, arginfo_zip_entry_open
)
770 PHP_FE(zip_entry_close
, arginfo_zip_entry_close
)
771 PHP_FE(zip_entry_read
, arginfo_zip_entry_read
)
772 PHP_FE(zip_entry_filesize
, arginfo_zip_entry_filesize
)
773 PHP_FE(zip_entry_name
, arginfo_zip_entry_name
)
774 PHP_FE(zip_entry_compressedsize
, arginfo_zip_entry_compressedsize
)
775 PHP_FE(zip_entry_compressionmethod
, arginfo_zip_entry_compressionmethod
)
780 /* {{{ ZE2 OO definitions */
781 #ifdef PHP_ZIP_USE_OO
782 static zend_class_entry
*zip_class_entry
;
783 static zend_object_handlers zip_object_handlers
;
785 static HashTable zip_prop_handlers
;
787 typedef int (*zip_read_int_t
)(struct zip
*za TSRMLS_DC
);
788 typedef char *(*zip_read_const_char_t
)(struct zip
*za
, int *len TSRMLS_DC
);
789 typedef char *(*zip_read_const_char_from_ze_t
)(ze_zip_object
*obj TSRMLS_DC
);
791 typedef struct _zip_prop_handler
{
792 zip_read_int_t read_int_func
;
793 zip_read_const_char_t read_const_char_func
;
794 zip_read_const_char_from_ze_t read_const_char_from_obj_func
;
801 #ifdef PHP_ZIP_USE_OO
802 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
) /* {{{ */
804 zip_prop_handler hnd
;
806 hnd
.read_const_char_func
= read_char_func
;
807 hnd
.read_int_func
= read_int_func
;
808 hnd
.read_const_char_from_obj_func
= read_char_from_obj_func
;
810 zend_hash_add(prop_handler
, name
, strlen(name
)+1, &hnd
, sizeof(zip_prop_handler
), NULL
);
814 static int php_zip_property_reader(ze_zip_object
*obj
, zip_prop_handler
*hnd
, zval
**retval
, int newzval TSRMLS_DC
) /* {{{ */
816 const char *retchar
= NULL
;
820 if (obj
&& obj
->za
!= NULL
) {
821 if (hnd
->read_const_char_func
) {
822 retchar
= hnd
->read_const_char_func(obj
->za
, &len TSRMLS_CC
);
824 if (hnd
->read_int_func
) {
825 retint
= hnd
->read_int_func(obj
->za TSRMLS_CC
);
827 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Internal zip error returned");
831 if (hnd
->read_const_char_from_obj_func
) {
832 retchar
= hnd
->read_const_char_from_obj_func(obj TSRMLS_CC
);
833 len
= strlen(retchar
);
846 ZVAL_STRINGL(*retval
, (char *) retchar
, len
, 1);
848 ZVAL_EMPTY_STRING(*retval
);
852 ZVAL_BOOL(*retval
, (long)retint
);
855 ZVAL_LONG(*retval
, (long)retint
);
865 static zval
**php_zip_get_property_ptr_ptr(zval
*object
, zval
*member
, const zend_literal
*key TSRMLS_DC
) /* {{{ */
869 zval
**retval
= NULL
;
871 zip_prop_handler
*hnd
;
872 zend_object_handlers
*std_hnd
;
875 if (member
->type
!= IS_STRING
) {
876 tmp_member
= *member
;
877 zval_copy_ctor(&tmp_member
);
878 convert_to_string(&tmp_member
);
879 member
= &tmp_member
;
884 obj
= (ze_zip_object
*)zend_objects_get_address(object TSRMLS_CC
);
886 if (obj
->prop_handler
!= NULL
) {
888 ret
= zend_hash_quick_find(obj
->prop_handler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, key
->hash_value
, (void **) &hnd
);
890 ret
= zend_hash_find(obj
->prop_handler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void **) &hnd
);
895 if (ret
== FAILURE
) {
896 std_hnd
= zend_get_std_object_handlers();
897 retval
= std_hnd
->get_property_ptr_ptr(object
, member
, key TSRMLS_CC
);
900 if (member
== &tmp_member
) {
907 static zval
* php_zip_read_property(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
) /* {{{ */
912 zip_prop_handler
*hnd
;
913 zend_object_handlers
*std_hnd
;
916 if (member
->type
!= IS_STRING
) {
917 tmp_member
= *member
;
918 zval_copy_ctor(&tmp_member
);
919 convert_to_string(&tmp_member
);
920 member
= &tmp_member
;
925 obj
= (ze_zip_object
*)zend_objects_get_address(object TSRMLS_CC
);
927 if (obj
->prop_handler
!= NULL
) {
929 ret
= zend_hash_quick_find(obj
->prop_handler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, key
->hash_value
, (void **) &hnd
);
931 ret
= zend_hash_find(obj
->prop_handler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void **) &hnd
);
935 if (ret
== SUCCESS
) {
936 ret
= php_zip_property_reader(obj
, hnd
, &retval
, 1 TSRMLS_CC
);
937 if (ret
== SUCCESS
) {
938 /* ensure we're creating a temporary variable */
939 Z_SET_REFCOUNT_P(retval
, 0);
941 retval
= EG(uninitialized_zval_ptr
);
944 std_hnd
= zend_get_std_object_handlers();
945 retval
= std_hnd
->read_property(object
, member
, type
, key TSRMLS_CC
);
948 if (member
== &tmp_member
) {
955 static int php_zip_has_property(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
) /* {{{ */
959 zip_prop_handler
*hnd
;
960 zend_object_handlers
*std_hnd
;
963 if (member
->type
!= IS_STRING
) {
964 tmp_member
= *member
;
965 zval_copy_ctor(&tmp_member
);
966 convert_to_string(&tmp_member
);
967 member
= &tmp_member
;
972 obj
= (ze_zip_object
*)zend_objects_get_address(object TSRMLS_CC
);
974 if (obj
->prop_handler
!= NULL
) {
976 ret
= zend_hash_quick_find(obj
->prop_handler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, key
->hash_value
, (void **) &hnd
);
978 ret
= zend_hash_find(obj
->prop_handler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void **) &hnd
);
982 if (ret
== SUCCESS
) {
984 ALLOC_INIT_ZVAL(tmp
);
988 } else if (php_zip_property_reader(obj
, hnd
, &tmp
, 0 TSRMLS_CC
) == SUCCESS
) {
989 Z_SET_REFCOUNT_P(tmp
, 1);
990 Z_UNSET_ISREF_P(tmp
);
992 retval
= zend_is_true(tmp
);
993 } else if (type
== 0) {
994 retval
= (Z_TYPE_P(tmp
) != IS_NULL
);
1000 std_hnd
= zend_get_std_object_handlers();
1001 retval
= std_hnd
->has_property(object
, member
, type
, key TSRMLS_CC
);
1004 if (member
== &tmp_member
) {
1011 static HashTable
*php_zip_get_properties(zval
*object TSRMLS_DC
)/* {{{ */
1014 zip_prop_handler
*hnd
;
1023 obj
= (ze_zip_object
*)zend_objects_get_address(object TSRMLS_CC
);
1024 props
= zend_std_get_properties(object TSRMLS_CC
);
1026 if (obj
->prop_handler
== NULL
) {
1029 zend_hash_internal_pointer_reset_ex(obj
->prop_handler
, &pos
);
1031 while (zend_hash_get_current_data_ex(obj
->prop_handler
, (void**)&hnd
, &pos
) == SUCCESS
) {
1032 zend_hash_get_current_key_ex(obj
->prop_handler
, &key
, &key_len
, &num_key
, 0, &pos
);
1034 ret
= php_zip_property_reader(obj
, hnd
, &val
, 0 TSRMLS_CC
);
1035 if (ret
!= SUCCESS
) {
1036 val
= EG(uninitialized_zval_ptr
);
1038 zend_hash_update(props
, key
, key_len
, (void *)&val
, sizeof(zval
*), NULL
);
1039 zend_hash_move_forward_ex(obj
->prop_handler
, &pos
);
1045 static void php_zip_object_free_storage(void *object TSRMLS_DC
) /* {{{ */
1047 ze_zip_object
* intern
= (ze_zip_object
*) object
;
1054 if (zip_close(intern
->za
) != 0) {
1055 _zip_free(intern
->za
);
1060 if (intern
->buffers_cnt
>0) {
1061 for (i
=0; i
<intern
->buffers_cnt
; i
++) {
1062 efree(intern
->buffers
[i
]);
1064 efree(intern
->buffers
);
1069 #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)
1070 zend_object_std_dtor(&intern
->zo TSRMLS_CC
);
1072 if (intern
->zo
.guards
) {
1073 zend_hash_destroy(intern
->zo
.guards
);
1074 FREE_HASHTABLE(intern
->zo
.guards
);
1077 if (intern
->zo
.properties
) {
1078 zend_hash_destroy(intern
->zo
.properties
);
1079 FREE_HASHTABLE(intern
->zo
.properties
);
1083 if (intern
->filename
) {
1084 efree(intern
->filename
);
1090 static zend_object_value
php_zip_object_new(zend_class_entry
*class_type TSRMLS_DC
) /* {{{ */
1092 ze_zip_object
*intern
;
1093 zend_object_value retval
;
1095 intern
= emalloc(sizeof(ze_zip_object
));
1096 memset(&intern
->zo
, 0, sizeof(zend_object
));
1099 intern
->buffers
= NULL
;
1100 intern
->filename
= NULL
;
1101 intern
->buffers_cnt
= 0;
1102 intern
->prop_handler
= &zip_prop_handlers
;
1104 #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2))
1105 zend_object_std_init(&intern
->zo
, class_type TSRMLS_CC
);
1107 ALLOC_HASHTABLE(intern
->zo
.properties
);
1108 zend_hash_init(intern
->zo
.properties
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
1109 intern
->zo
.ce
= class_type
;
1112 object_properties_init(&intern
->zo
, class_type
);
1114 retval
.handle
= zend_objects_store_put(intern
,
1116 (zend_objects_free_object_storage_t
) php_zip_object_free_storage
,
1119 retval
.handlers
= (zend_object_handlers
*) & zip_object_handlers
;
1126 /* {{{ Resource dtors */
1128 /* {{{ php_zip_free_dir */
1129 static void php_zip_free_dir(zend_rsrc_list_entry
*rsrc TSRMLS_DC
)
1131 zip_rsrc
* zip_int
= (zip_rsrc
*) rsrc
->ptr
;
1135 if (zip_close(zip_int
->za
) != 0) {
1136 _zip_free(zip_int
->za
);
1148 /* {{{ php_zip_free_entry */
1149 static void php_zip_free_entry(zend_rsrc_list_entry
*rsrc TSRMLS_DC
)
1151 zip_read_rsrc
*zr_rsrc
= (zip_read_rsrc
*) rsrc
->ptr
;
1155 if (zr_rsrc
->zf
->za
) {
1156 zip_fclose(zr_rsrc
->zf
);
1158 if (zr_rsrc
->zf
->src
)
1159 zip_source_free(zr_rsrc
->zf
->src
);
1174 /* {{{ function prototypes */
1175 static PHP_MINIT_FUNCTION(zip
);
1176 static PHP_MSHUTDOWN_FUNCTION(zip
);
1177 static PHP_MINFO_FUNCTION(zip
);
1180 /* {{{ zip_module_entry
1182 zend_module_entry zip_module_entry
= {
1183 STANDARD_MODULE_HEADER
,
1191 PHP_ZIP_VERSION_STRING
,
1192 STANDARD_MODULE_PROPERTIES
1196 #ifdef COMPILE_DL_ZIP
1197 ZEND_GET_MODULE(zip
)
1201 /* {{{ proto resource zip_open(string filename)
1202 Create new zip using source uri for output */
1203 static PHP_NAMED_FUNCTION(zif_zip_open
)
1207 char resolved_path
[MAXPATHLEN
+ 1];
1211 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p", &filename
, &filename_len
) == FAILURE
) {
1215 if (filename_len
== 0) {
1216 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Empty string as source");
1220 if (ZIP_OPENBASEDIR_CHECKPATH(filename
)) {
1224 if(!expand_filepath(filename
, resolved_path TSRMLS_CC
)) {
1228 rsrc_int
= (zip_rsrc
*)emalloc(sizeof(zip_rsrc
));
1230 rsrc_int
->za
= zip_open(resolved_path
, 0, &err
);
1231 if (rsrc_int
->za
== NULL
) {
1233 RETURN_LONG((long)err
);
1236 rsrc_int
->index_current
= 0;
1237 rsrc_int
->num_files
= zip_get_num_files(rsrc_int
->za
);
1239 ZEND_REGISTER_RESOURCE(return_value
, rsrc_int
, le_zip_dir
);
1243 /* {{{ proto void zip_close(resource zip)
1244 Close a Zip archive */
1245 static PHP_NAMED_FUNCTION(zif_zip_close
)
1248 zip_rsrc
*z_rsrc
= NULL
;
1250 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &zip
) == FAILURE
) {
1253 ZEND_FETCH_RESOURCE(z_rsrc
, zip_rsrc
*, &zip
, -1, le_zip_dir_name
, le_zip_dir
);
1255 /* really close the zip will break BC :-D */
1256 zend_list_delete(Z_LVAL_P(zip
));
1260 /* {{{ proto resource zip_read(resource zip)
1261 Returns the next file in the archive */
1262 static PHP_NAMED_FUNCTION(zif_zip_read
)
1265 zip_read_rsrc
*zr_rsrc
;
1269 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &zip_dp
) == FAILURE
) {
1272 ZEND_FETCH_RESOURCE(rsrc_int
, zip_rsrc
*, &zip_dp
, -1, le_zip_dir_name
, le_zip_dir
);
1274 if (rsrc_int
&& rsrc_int
->za
) {
1275 if (rsrc_int
->index_current
>= rsrc_int
->num_files
) {
1279 zr_rsrc
= emalloc(sizeof(zip_read_rsrc
));
1281 ret
= zip_stat_index(rsrc_int
->za
, rsrc_int
->index_current
, 0, &zr_rsrc
->sb
);
1288 zr_rsrc
->zf
= zip_fopen_index(rsrc_int
->za
, rsrc_int
->index_current
, 0);
1290 rsrc_int
->index_current
++;
1291 ZEND_REGISTER_RESOURCE(return_value
, zr_rsrc
, le_zip_entry
);
1303 /* {{{ proto bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
1304 Open a Zip File, pointed by the resource entry */
1305 /* Dummy function to follow the old API */
1306 static PHP_NAMED_FUNCTION(zif_zip_entry_open
)
1312 zip_read_rsrc
* zr_rsrc
;
1315 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "rr|s", &zip
, &zip_entry
, &mode
, &mode_len
) == FAILURE
) {
1319 ZEND_FETCH_RESOURCE(zr_rsrc
, zip_read_rsrc
*, &zip_entry
, -1, le_zip_entry_name
, le_zip_entry
);
1320 ZEND_FETCH_RESOURCE(z_rsrc
, zip_rsrc
*, &zip
, -1, le_zip_dir_name
, le_zip_dir
);
1322 if (zr_rsrc
->zf
!= NULL
) {
1330 /* {{{ proto bool zip_entry_close(resource zip_ent)
1331 Close a zip entry */
1332 static PHP_NAMED_FUNCTION(zif_zip_entry_close
)
1335 zip_read_rsrc
* zr_rsrc
;
1337 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &zip_entry
) == FAILURE
) {
1341 ZEND_FETCH_RESOURCE(zr_rsrc
, zip_read_rsrc
*, &zip_entry
, -1, le_zip_entry_name
, le_zip_entry
);
1343 RETURN_BOOL(SUCCESS
== zend_list_delete(Z_LVAL_P(zip_entry
)));
1347 /* {{{ proto mixed zip_entry_read(resource zip_entry [, int len])
1348 Read from an open directory entry */
1349 static PHP_NAMED_FUNCTION(zif_zip_entry_read
)
1353 zip_read_rsrc
* zr_rsrc
;
1357 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r|l", &zip_entry
, &len
) == FAILURE
) {
1361 ZEND_FETCH_RESOURCE(zr_rsrc
, zip_read_rsrc
*, &zip_entry
, -1, le_zip_entry_name
, le_zip_entry
);
1368 buffer
= safe_emalloc(len
, 1, 1);
1369 n
= zip_fread(zr_rsrc
->zf
, buffer
, len
);
1372 RETURN_STRINGL(buffer
, n
, 0);
1375 RETURN_EMPTY_STRING()
1383 static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS
, int opt
) /* {{{ */
1386 zip_read_rsrc
* zr_rsrc
;
1388 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &zip_entry
) == FAILURE
) {
1392 ZEND_FETCH_RESOURCE(zr_rsrc
, zip_read_rsrc
*, &zip_entry
, -1, le_zip_entry_name
, le_zip_entry
);
1400 RETURN_STRING((char *)zr_rsrc
->sb
.name
, 1);
1403 RETURN_LONG((long) (zr_rsrc
->sb
.comp_size
));
1406 RETURN_LONG((long) (zr_rsrc
->sb
.size
));
1409 switch (zr_rsrc
->sb
.comp_method
) {
1411 RETURN_STRING("stored", 1);
1414 RETURN_STRING("shrunk", 1);
1420 RETURN_STRING("reduced", 1);
1423 RETURN_STRING("imploded", 1);
1426 RETURN_STRING("tokenized", 1);
1429 RETURN_STRING("deflated", 1);
1432 RETURN_STRING("deflatedX", 1);
1435 RETURN_STRING("implodedX", 1);
1440 RETURN_LONG((long) (zr_rsrc
->sb
.comp_method
));
1447 /* {{{ proto string zip_entry_name(resource zip_entry)
1448 Return the name given a ZZip entry */
1449 static PHP_NAMED_FUNCTION(zif_zip_entry_name
)
1451 php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 0);
1455 /* {{{ proto int zip_entry_compressedsize(resource zip_entry)
1456 Return the compressed size of a ZZip entry */
1457 static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize
)
1459 php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 1);
1463 /* {{{ proto int zip_entry_filesize(resource zip_entry)
1464 Return the actual filesize of a ZZip entry */
1465 static PHP_NAMED_FUNCTION(zif_zip_entry_filesize
)
1467 php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 2);
1471 /* {{{ proto string zip_entry_compressionmethod(resource zip_entry)
1472 Return a string containing the compression method used on a particular entry */
1473 static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod
)
1475 php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 3);
1479 #ifdef PHP_ZIP_USE_OO
1480 /* {{{ proto mixed ZipArchive::open(string source [, int flags])
1481 Create new zip using source uri for output, return TRUE on success or the error code */
1482 static ZIPARCHIVE_METHOD(open
)
1489 char resolved_path
[MAXPATHLEN
];
1491 zval
*this = getThis();
1492 ze_zip_object
*ze_obj
= NULL
;
1494 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|l", &filename
, &filename_len
, &flags
) == FAILURE
) {
1499 /* We do not use ZIP_FROM_OBJECT, zip init function here */
1500 ze_obj
= (ze_zip_object
*) zend_object_store_get_object(this TSRMLS_CC
);
1503 if (filename_len
== 0) {
1504 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Empty string as source");
1508 if (ZIP_OPENBASEDIR_CHECKPATH(filename
)) {
1512 if (!expand_filepath(filename
, resolved_path TSRMLS_CC
)) {
1517 /* we already have an opened zip, free it */
1518 if (zip_close(ze_obj
->za
) != 0) {
1519 _zip_free(ze_obj
->za
);
1523 if (ze_obj
->filename
) {
1524 efree(ze_obj
->filename
);
1525 ze_obj
->filename
= NULL
;
1528 intern
= zip_open(resolved_path
, flags
, &err
);
1529 if (!intern
|| err
) {
1530 RETURN_LONG((long)err
);
1532 ze_obj
->filename
= estrdup(resolved_path
);
1533 ze_obj
->filename_len
= filename_len
;
1534 ze_obj
->za
= intern
;
1539 /* {{{ proto bool ZipArchive::close()
1540 close the zip archive */
1541 static ZIPARCHIVE_METHOD(close
)
1544 zval
*this = getThis();
1545 ze_zip_object
*ze_obj
;
1551 ZIP_FROM_OBJECT(intern
, this);
1553 ze_obj
= (ze_zip_object
*) zend_object_store_get_object(this TSRMLS_CC
);
1555 if (zip_close(intern
)) {
1559 efree(ze_obj
->filename
);
1560 ze_obj
->filename
= NULL
;
1561 ze_obj
->filename_len
= 0;
1568 /* {{{ proto string ZipArchive::getStatusString()
1569 * Returns the status error message, system and/or zip messages */
1570 static ZIPARCHIVE_METHOD(getStatusString
)
1573 zval
*this = getThis();
1575 char error_string
[128];
1581 ZIP_FROM_OBJECT(intern
, this);
1583 zip_error_get(intern
, &zep
, &syp
);
1585 len
= zip_error_to_str(error_string
, 128, zep
, syp
);
1586 RETVAL_STRINGL(error_string
, len
, 1);
1590 /* {{{ proto bool ZipArchive::createEmptyDir(string dirname)
1591 Returns the index of the entry named filename in the archive */
1592 static ZIPARCHIVE_METHOD(addEmptyDir
)
1595 zval
*this = getThis();
1606 ZIP_FROM_OBJECT(intern
, this);
1608 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s",
1609 &dirname
, &dirname_len
) == FAILURE
) {
1613 if (dirname_len
<1) {
1617 if (dirname
[dirname_len
-1] != '/') {
1618 s
=(char *)emalloc(dirname_len
+2);
1620 s
[dirname_len
] = '/';
1621 s
[dirname_len
+1] = '\0';
1626 idx
= zip_stat(intern
, s
, 0, &sb
);
1630 if (zip_add_dir(intern
, (const char *)s
) == -1) {
1642 static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS
, int type
) /* {{{ */
1645 zval
*this = getThis();
1648 char *remove_path
= NULL
;
1649 char *add_path
= NULL
;
1650 int pattern_len
, add_path_len
, remove_path_len
, path_len
= 0;
1651 long remove_all_path
= 0;
1653 zval
*options
= NULL
;
1660 ZIP_FROM_OBJECT(intern
, this);
1661 /* 1 == glob, 2==pcre */
1663 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|la",
1664 &pattern
, &pattern_len
, &flags
, &options
) == FAILURE
) {
1668 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|sa",
1669 &pattern
, &pattern_len
, &path
, &path_len
, &options
) == FAILURE
) {
1674 if (pattern_len
== 0) {
1675 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string as pattern");
1678 if (options
&& (php_zip_parse_options(options
, &remove_all_path
, &remove_path
, &remove_path_len
,
1679 &add_path
, &add_path_len TSRMLS_CC
) < 0)) {
1683 if (remove_path
&& remove_path_len
> 1 && (remove_path
[strlen(remove_path
) - 1] == '/' ||
1684 remove_path
[strlen(remove_path
) - 1] == '\\')) {
1685 remove_path
[strlen(remove_path
) - 1] = '\0';
1689 found
= php_zip_glob(pattern
, pattern_len
, flags
, return_value TSRMLS_CC
);
1691 found
= php_zip_pcre(pattern
, pattern_len
, path
, path_len
, return_value TSRMLS_CC
);
1696 zval
**zval_file
= NULL
;
1698 for (i
= 0; i
< found
; i
++) {
1699 char *file
, *file_stripped
, *entry_name
;
1700 size_t entry_name_len
, file_stripped_len
;
1701 char entry_name_buf
[MAXPATHLEN
];
1702 char *basename
= NULL
;
1704 if (zend_hash_index_find(Z_ARRVAL_P(return_value
), i
, (void **) &zval_file
) == SUCCESS
) {
1705 file
= Z_STRVAL_PP(zval_file
);
1706 if (remove_all_path
) {
1707 php_basename(Z_STRVAL_PP(zval_file
), Z_STRLEN_PP(zval_file
), NULL
, 0,
1708 &basename
, (size_t *)&file_stripped_len TSRMLS_CC
);
1709 file_stripped
= basename
;
1710 } else if (remove_path
&& strstr(Z_STRVAL_PP(zval_file
), remove_path
) != NULL
) {
1711 file_stripped
= Z_STRVAL_PP(zval_file
) + remove_path_len
+ 1;
1712 file_stripped_len
= Z_STRLEN_PP(zval_file
) - remove_path_len
- 1;
1714 file_stripped
= Z_STRVAL_PP(zval_file
);
1715 file_stripped_len
= Z_STRLEN_PP(zval_file
);
1719 if ((add_path_len
+ file_stripped_len
) > MAXPATHLEN
) {
1720 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Entry name too long (max: %d, %ld given)",
1721 MAXPATHLEN
- 1, (add_path_len
+ file_stripped_len
));
1722 zval_dtor(return_value
);
1726 snprintf(entry_name_buf
, MAXPATHLEN
, "%s%s", add_path
, file_stripped
);
1727 entry_name
= entry_name_buf
;
1728 entry_name_len
= strlen(entry_name
);
1730 entry_name
= Z_STRVAL_PP(zval_file
);
1731 entry_name_len
= Z_STRLEN_PP(zval_file
);
1737 if (php_zip_add_file(intern
, Z_STRVAL_PP(zval_file
), Z_STRLEN_PP(zval_file
),
1738 entry_name
, entry_name_len
, 0, 0 TSRMLS_CC
) < 0) {
1739 zval_dtor(return_value
);
1748 /* {{{ proto bool ZipArchive::addGlob(string pattern[,int flags [, array options]])
1749 Add files matching the glob pattern. See php's glob for the pattern syntax. */
1750 static ZIPARCHIVE_METHOD(addGlob
)
1752 php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 1);
1756 /* {{{ proto bool ZipArchive::addPattern(string pattern[, string path [, array options]])
1757 Add files matching the pcre pattern. See php's pcre for the pattern syntax. */
1758 static ZIPARCHIVE_METHOD(addPattern
)
1760 php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 2);
1764 /* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
1765 Add a file in a Zip archive using its path and the name to use. */
1766 static ZIPARCHIVE_METHOD(addFile
)
1769 zval
*this = getThis();
1772 char *entry_name
= NULL
;
1773 int entry_name_len
= 0;
1774 long offset_start
= 0, offset_len
= 0;
1780 ZIP_FROM_OBJECT(intern
, this);
1782 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|sll",
1783 &filename
, &filename_len
, &entry_name
, &entry_name_len
, &offset_start
, &offset_len
) == FAILURE
) {
1787 if (filename_len
== 0) {
1788 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string as filename");
1792 if (entry_name_len
== 0) {
1793 entry_name
= filename
;
1794 entry_name_len
= filename_len
;
1797 if (php_zip_add_file(intern
, filename
, filename_len
,
1798 entry_name
, entry_name_len
, 0, 0 TSRMLS_CC
) < 0) {
1806 /* {{{ proto bool ZipArchive::addFromString(string name, string content)
1807 Add a file using content and the entry name */
1808 static ZIPARCHIVE_METHOD(addFromString
)
1811 zval
*this = getThis();
1812 char *buffer
, *name
;
1813 int buffer_len
, name_len
;
1814 ze_zip_object
*ze_obj
;
1815 struct zip_source
*zs
;
1823 ZIP_FROM_OBJECT(intern
, this);
1825 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss",
1826 &name
, &name_len
, &buffer
, &buffer_len
) == FAILURE
) {
1830 ze_obj
= (ze_zip_object
*) zend_object_store_get_object(this TSRMLS_CC
);
1831 if (ze_obj
->buffers_cnt
) {
1832 ze_obj
->buffers
= (char **)erealloc(ze_obj
->buffers
, sizeof(char *) * (ze_obj
->buffers_cnt
+1));
1833 pos
= ze_obj
->buffers_cnt
++;
1835 ze_obj
->buffers
= (char **)emalloc(sizeof(char *));
1836 ze_obj
->buffers_cnt
++;
1839 ze_obj
->buffers
[pos
] = (char *)emalloc(buffer_len
+ 1);
1840 memcpy(ze_obj
->buffers
[pos
], buffer
, buffer_len
+ 1);
1842 zs
= zip_source_buffer(intern
, ze_obj
->buffers
[pos
], buffer_len
, 0);
1848 cur_idx
= zip_name_locate(intern
, (const char *)name
, 0);
1849 /* TODO: fix _zip_replace */
1851 if (zip_delete(intern
, cur_idx
) == -1) {
1856 if (zip_add(intern
, name
, zs
) == -1) {
1864 /* {{{ proto array ZipArchive::statName(string filename[, int flags])
1865 Returns the information about a the zip entry filename */
1866 static ZIPARCHIVE_METHOD(statName
)
1869 zval
*this = getThis();
1879 ZIP_FROM_OBJECT(intern
, this);
1881 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|l",
1882 &name
, &name_len
, &flags
) == FAILURE
) {
1886 PHP_ZIP_STAT_PATH(intern
, name
, name_len
, flags
, sb
);
1892 /* {{{ proto resource ZipArchive::statIndex(int index[, int flags])
1893 Returns the zip entry informations using its index */
1894 static ZIPARCHIVE_METHOD(statIndex
)
1897 zval
*this = getThis();
1898 long index
, flags
= 0;
1906 ZIP_FROM_OBJECT(intern
, this);
1908 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l",
1909 &index
, &flags
) == FAILURE
) {
1913 if (zip_stat_index(intern
, index
, flags
, &sb
) != 0) {
1920 /* {{{ proto int ZipArchive::locateName(string filename[, int flags])
1921 Returns the index of the entry named filename in the archive */
1922 static ZIPARCHIVE_METHOD(locateName
)
1925 zval
*this = getThis();
1935 ZIP_FROM_OBJECT(intern
, this);
1937 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|l",
1938 &name
, &name_len
, &flags
) == FAILURE
) {
1945 idx
= (long)zip_name_locate(intern
, (const char *)name
, flags
);
1955 /* {{{ proto string ZipArchive::getNameIndex(int index [, int flags])
1956 Returns the name of the file at position index */
1957 static ZIPARCHIVE_METHOD(getNameIndex
)
1960 zval
*this = getThis();
1962 long flags
= 0, index
= 0;
1968 ZIP_FROM_OBJECT(intern
, this);
1970 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l",
1971 &index
, &flags
) == FAILURE
) {
1975 name
= zip_get_name(intern
, (int) index
, flags
);
1978 RETVAL_STRING((char *)name
, 1);
1985 /* {{{ proto bool ZipArchive::setArchiveComment(string comment)
1986 Set or remove (NULL/'') the comment of the archive */
1987 static ZIPARCHIVE_METHOD(setArchiveComment
)
1990 zval
*this = getThis();
1998 ZIP_FROM_OBJECT(intern
, this);
2000 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &comment
, &comment_len
) == FAILURE
) {
2003 if (zip_set_archive_comment(intern
, (const char *)comment
, (int)comment_len
)) {
2011 /* {{{ proto string ZipArchive::getArchiveComment([int flags])
2012 Returns the comment of an entry using its index */
2013 static ZIPARCHIVE_METHOD(getArchiveComment
)
2016 zval
*this = getThis();
2018 const char * comment
;
2019 int comment_len
= 0;
2025 ZIP_FROM_OBJECT(intern
, this);
2027 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &flags
) == FAILURE
) {
2031 comment
= zip_get_archive_comment(intern
, &comment_len
, (int)flags
);
2035 RETURN_STRINGL((char *)comment
, (long)comment_len
, 1);
2039 /* {{{ proto bool ZipArchive::setCommentName(string name, string comment)
2040 Set or remove (NULL/'') the comment of an entry using its Name */
2041 static ZIPARCHIVE_METHOD(setCommentName
)
2044 zval
*this = getThis();
2045 int comment_len
, name_len
;
2046 char * comment
, *name
;
2053 ZIP_FROM_OBJECT(intern
, this);
2055 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss",
2056 &name
, &name_len
, &comment
, &comment_len
) == FAILURE
) {
2061 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string as entry name");
2064 idx
= zip_name_locate(intern
, name
, 0);
2068 PHP_ZIP_SET_FILE_COMMENT(intern
, idx
, comment
, comment_len
);
2072 /* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment)
2073 Set or remove (NULL/'') the comment of an entry using its index */
2074 static ZIPARCHIVE_METHOD(setCommentIndex
)
2077 zval
*this = getThis();
2087 ZIP_FROM_OBJECT(intern
, this);
2089 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ls",
2090 &index
, &comment
, &comment_len
) == FAILURE
) {
2094 PHP_ZIP_STAT_INDEX(intern
, index
, 0, sb
);
2095 PHP_ZIP_SET_FILE_COMMENT(intern
, index
, comment
, comment_len
);
2099 /* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
2100 Returns the comment of an entry using its name */
2101 static ZIPARCHIVE_METHOD(getCommentName
)
2104 zval
*this = getThis();
2107 int comment_len
= 0;
2108 const char * comment
;
2115 ZIP_FROM_OBJECT(intern
, this);
2117 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|l",
2118 &name
, &name_len
, &flags
) == FAILURE
) {
2122 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string as entry name");
2126 idx
= zip_name_locate(intern
, name
, 0);
2131 comment
= zip_get_file_comment(intern
, idx
, &comment_len
, (int)flags
);
2132 RETURN_STRINGL((char *)comment
, (long)comment_len
, 1);
2136 /* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags])
2137 Returns the comment of an entry using its index */
2138 static ZIPARCHIVE_METHOD(getCommentIndex
)
2141 zval
*this = getThis();
2142 long index
, flags
= 0;
2143 const char * comment
;
2144 int comment_len
= 0;
2151 ZIP_FROM_OBJECT(intern
, this);
2153 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l",
2154 &index
, &flags
) == FAILURE
) {
2158 PHP_ZIP_STAT_INDEX(intern
, index
, 0, sb
);
2159 comment
= zip_get_file_comment(intern
, index
, &comment_len
, (int)flags
);
2160 RETURN_STRINGL((char *)comment
, (long)comment_len
, 1);
2164 /* {{{ proto bool ZipArchive::deleteIndex(int index)
2165 Delete a file using its index */
2166 static ZIPARCHIVE_METHOD(deleteIndex
)
2169 zval
*this = getThis();
2176 ZIP_FROM_OBJECT(intern
, this);
2178 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &index
) == FAILURE
) {
2186 if (zip_delete(intern
, index
) < 0) {
2194 /* {{{ proto bool ZipArchive::deleteName(string name)
2195 Delete a file using its index */
2196 static ZIPARCHIVE_METHOD(deleteName
)
2199 zval
*this = getThis();
2208 ZIP_FROM_OBJECT(intern
, this);
2210 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &name
, &name_len
) == FAILURE
) {
2217 PHP_ZIP_STAT_PATH(intern
, name
, name_len
, 0, sb
);
2218 if (zip_delete(intern
, sb
.index
)) {
2225 /* {{{ proto bool ZipArchive::renameIndex(int index, string new_name)
2226 Rename an entry selected by its index to new_name */
2227 static ZIPARCHIVE_METHOD(renameIndex
)
2230 zval
*this = getThis();
2240 ZIP_FROM_OBJECT(intern
, this);
2242 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ls", &index
, &new_name
, &new_name_len
) == FAILURE
) {
2250 if (new_name_len
< 1) {
2251 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string as new entry name");
2254 if (zip_rename(intern
, index
, (const char *)new_name
) != 0) {
2261 /* {{{ proto bool ZipArchive::renameName(string name, string new_name)
2262 Rename an entry selected by its name to new_name */
2263 static ZIPARCHIVE_METHOD(renameName
)
2266 zval
*this = getThis();
2268 char *name
, *new_name
;
2269 int name_len
, new_name_len
;
2275 ZIP_FROM_OBJECT(intern
, this);
2277 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &name
, &name_len
, &new_name
, &new_name_len
) == FAILURE
) {
2281 if (new_name_len
< 1) {
2282 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Empty string as new entry name");
2286 PHP_ZIP_STAT_PATH(intern
, name
, name_len
, 0, sb
);
2288 if (zip_rename(intern
, sb
.index
, (const char *)new_name
)) {
2295 /* {{{ proto bool ZipArchive::unchangeIndex(int index)
2296 Changes to the file at position index are reverted */
2297 static ZIPARCHIVE_METHOD(unchangeIndex
)
2300 zval
*this = getThis();
2307 ZIP_FROM_OBJECT(intern
, this);
2309 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &index
) == FAILURE
) {
2317 if (zip_unchange(intern
, index
) != 0) {
2325 /* {{{ proto bool ZipArchive::unchangeName(string name)
2326 Changes to the file named 'name' are reverted */
2327 static ZIPARCHIVE_METHOD(unchangeName
)
2330 zval
*this = getThis();
2339 ZIP_FROM_OBJECT(intern
, this);
2341 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &name
, &name_len
) == FAILURE
) {
2349 PHP_ZIP_STAT_PATH(intern
, name
, name_len
, 0, sb
);
2351 if (zip_unchange(intern
, sb
.index
) != 0) {
2359 /* {{{ proto bool ZipArchive::unchangeAll()
2360 All changes to files and global information in archive are reverted */
2361 static ZIPARCHIVE_METHOD(unchangeAll
)
2364 zval
*this = getThis();
2370 ZIP_FROM_OBJECT(intern
, this);
2372 if (zip_unchange_all(intern
) != 0) {
2380 /* {{{ proto bool ZipArchive::unchangeArchive()
2381 Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */
2382 static ZIPARCHIVE_METHOD(unchangeArchive
)
2385 zval
*this = getThis();
2391 ZIP_FROM_OBJECT(intern
, this);
2393 if (zip_unchange_archive(intern
) != 0) {
2401 /* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files])
2402 Extract one or more file from a zip archive */
2404 * - allow index or array of indeces
2408 static ZIPARCHIVE_METHOD(extractTo
)
2412 zval
*this = getThis();
2413 zval
*zval_files
= NULL
;
2414 zval
**zval_file
= NULL
;
2415 php_stream_statbuf ssb
;
2426 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|z", &pathto
, &pathto_len
, &zval_files
) == FAILURE
) {
2430 if (pathto_len
< 1) {
2434 if (php_stream_stat_path_ex(pathto
, PHP_STREAM_URL_STAT_QUIET
, &ssb
, NULL
) < 0) {
2435 ret
= php_stream_mkdir(pathto
, 0777, PHP_STREAM_MKDIR_RECURSIVE
, NULL
);
2441 ZIP_FROM_OBJECT(intern
, this);
2442 if (zval_files
&& (Z_TYPE_P(zval_files
) != IS_NULL
)) {
2443 switch (Z_TYPE_P(zval_files
)) {
2445 if (!php_zip_extract_file(intern
, pathto
, Z_STRVAL_P(zval_files
), Z_STRLEN_P(zval_files
) TSRMLS_CC
)) {
2450 nelems
= zend_hash_num_elements(Z_ARRVAL_P(zval_files
));
2454 for (i
= 0; i
< nelems
; i
++) {
2455 if (zend_hash_index_find(Z_ARRVAL_P(zval_files
), i
, (void **) &zval_file
) == SUCCESS
) {
2456 switch (Z_TYPE_PP(zval_file
)) {
2460 if (!php_zip_extract_file(intern
, pathto
, Z_STRVAL_PP(zval_file
), Z_STRLEN_PP(zval_file
) TSRMLS_CC
)) {
2470 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid argument, expect string or array of strings");
2474 /* Extract all files */
2475 int filecount
= zip_get_num_files(intern
);
2477 if (filecount
== -1) {
2478 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Illegal archive");
2482 for (i
= 0; i
< filecount
; i
++) {
2483 char *file
= (char*)zip_get_name(intern
, i
, ZIP_FL_UNCHANGED
);
2484 if (!php_zip_extract_file(intern
, pathto
, file
, strlen(file
) TSRMLS_CC
)) {
2493 static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS
, int type
) /* {{{ */
2496 zval
*this = getThis();
2499 struct zip_file
*zf
;
2514 ZIP_FROM_OBJECT(intern
, this);
2517 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p|ll", &filename
, &filename_len
, &len
, &flags
) == FAILURE
) {
2520 PHP_ZIP_STAT_PATH(intern
, filename
, filename_len
, flags
, sb
);
2522 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|ll", &index
, &len
, &flags
) == FAILURE
) {
2525 PHP_ZIP_STAT_INDEX(intern
, index
, 0, sb
);
2529 RETURN_EMPTY_STRING();
2536 zf
= zip_fopen_index(intern
, index
, flags
);
2538 zf
= zip_fopen(intern
, filename
, flags
);
2545 buffer
= safe_emalloc(len
, 1, 2);
2546 n
= zip_fread(zf
, buffer
, len
);
2549 RETURN_EMPTY_STRING();
2554 RETURN_STRINGL(buffer
, n
, 0);
2558 /* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]])
2559 get the contents of an entry using its name */
2560 static ZIPARCHIVE_METHOD(getFromName
)
2562 php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 1);
2566 /* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]])
2567 get the contents of an entry using its index */
2568 static ZIPARCHIVE_METHOD(getFromIndex
)
2570 php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU
, 0);
2574 /* {{{ proto resource ZipArchive::getStream(string entryname)
2575 get a stream for an entry using its name */
2576 static ZIPARCHIVE_METHOD(getStream
)
2579 zval
*this = getThis();
2591 ZIP_FROM_OBJECT(intern
, this);
2593 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "p", &filename
, &filename_len
) == FAILURE
) {
2597 if (zip_stat(intern
, filename
, 0, &sb
) != 0) {
2601 obj
= (ze_zip_object
*) zend_object_store_get_object(this TSRMLS_CC
);
2603 stream
= php_stream_zip_open(obj
->filename
, filename
, mode STREAMS_CC TSRMLS_CC
);
2605 php_stream_to_zval(stream
, return_value
);
2611 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open
, 0, 0, 1)
2612 ZEND_ARG_INFO(0, filename
)
2613 ZEND_ARG_INFO(0, flags
)
2616 ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void
, 0)
2619 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addemptydir
, 0, 0, 1)
2620 ZEND_ARG_INFO(0, dirname
)
2623 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addglob
, 0, 0, 1)
2624 ZEND_ARG_INFO(0, pattern
)
2625 ZEND_ARG_INFO(0, flags
)
2626 ZEND_ARG_INFO(0, options
)
2629 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addpattern
, 0, 0, 1)
2630 ZEND_ARG_INFO(0, pattern
)
2631 ZEND_ARG_INFO(0, path
)
2632 ZEND_ARG_INFO(0, options
)
2635 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfile
, 0, 0, 1)
2636 ZEND_ARG_INFO(0, filepath
)
2637 ZEND_ARG_INFO(0, entryname
)
2638 ZEND_ARG_INFO(0, start
)
2639 ZEND_ARG_INFO(0, length
)
2642 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfromstring
, 0, 0, 2)
2643 ZEND_ARG_INFO(0, name
)
2644 ZEND_ARG_INFO(0, content
)
2647 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statname
, 0, 0, 1)
2648 ZEND_ARG_INFO(0, filename
)
2649 ZEND_ARG_INFO(0, flags
)
2652 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statindex
, 0, 0, 1)
2653 ZEND_ARG_INFO(0, index
)
2654 ZEND_ARG_INFO(0, flags
)
2657 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setarchivecomment
, 0, 0, 1)
2658 ZEND_ARG_INFO(0, comment
)
2661 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentindex
, 0, 0, 2)
2662 ZEND_ARG_INFO(0, index
)
2663 ZEND_ARG_INFO(0, comment
)
2666 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentname
, 0, 0, 1)
2667 ZEND_ARG_INFO(0, name
)
2668 ZEND_ARG_INFO(0, flags
)
2671 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentindex
, 0, 0, 1)
2672 ZEND_ARG_INFO(0, index
)
2673 ZEND_ARG_INFO(0, flags
)
2676 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renameindex
, 0, 0, 2)
2677 ZEND_ARG_INFO(0, index
)
2678 ZEND_ARG_INFO(0, new_name
)
2681 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renamename
, 0, 0, 2)
2682 ZEND_ARG_INFO(0, name
)
2683 ZEND_ARG_INFO(0, new_name
)
2686 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangeindex
, 0, 0, 1)
2687 ZEND_ARG_INFO(0, index
)
2690 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangename
, 0, 0, 1)
2691 ZEND_ARG_INFO(0, name
)
2694 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_extractto
, 0, 0, 1)
2695 ZEND_ARG_INFO(0, pathto
)
2696 ZEND_ARG_INFO(0, files
)
2699 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromname
, 0, 0, 1)
2700 ZEND_ARG_INFO(0, entryname
)
2701 ZEND_ARG_INFO(0, len
)
2702 ZEND_ARG_INFO(0, flags
)
2705 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromindex
, 0, 0, 1)
2706 ZEND_ARG_INFO(0, index
)
2707 ZEND_ARG_INFO(0, len
)
2708 ZEND_ARG_INFO(0, flags
)
2711 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getarchivecomment
, 0, 0, 0)
2712 ZEND_ARG_INFO(0, flags
)
2715 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentname
, 0, 0, 2)
2716 ZEND_ARG_INFO(0, name
)
2717 ZEND_ARG_INFO(0, comment
)
2720 ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getstream
, 0, 0, 1)
2721 ZEND_ARG_INFO(0, entryname
)
2725 /* {{{ ze_zip_object_class_functions */
2726 static const zend_function_entry zip_class_functions
[] = {
2727 ZIPARCHIVE_ME(open
, arginfo_ziparchive_open
, ZEND_ACC_PUBLIC
)
2728 ZIPARCHIVE_ME(close
, arginfo_ziparchive__void
, ZEND_ACC_PUBLIC
)
2729 ZIPARCHIVE_ME(getStatusString
, arginfo_ziparchive__void
, ZEND_ACC_PUBLIC
)
2730 ZIPARCHIVE_ME(addEmptyDir
, arginfo_ziparchive_addemptydir
, ZEND_ACC_PUBLIC
)
2731 ZIPARCHIVE_ME(addFromString
, arginfo_ziparchive_addfromstring
, ZEND_ACC_PUBLIC
)
2732 ZIPARCHIVE_ME(addFile
, arginfo_ziparchive_addfile
, ZEND_ACC_PUBLIC
)
2733 ZIPARCHIVE_ME(addGlob
, arginfo_ziparchive_addglob
, ZEND_ACC_PUBLIC
)
2734 ZIPARCHIVE_ME(addPattern
, arginfo_ziparchive_addpattern
, ZEND_ACC_PUBLIC
)
2735 ZIPARCHIVE_ME(renameIndex
, arginfo_ziparchive_renameindex
, ZEND_ACC_PUBLIC
)
2736 ZIPARCHIVE_ME(renameName
, arginfo_ziparchive_renamename
, ZEND_ACC_PUBLIC
)
2737 ZIPARCHIVE_ME(setArchiveComment
, arginfo_ziparchive_setarchivecomment
, ZEND_ACC_PUBLIC
)
2738 ZIPARCHIVE_ME(getArchiveComment
, arginfo_ziparchive_getarchivecomment
, ZEND_ACC_PUBLIC
)
2739 ZIPARCHIVE_ME(setCommentIndex
, arginfo_ziparchive_setcommentindex
, ZEND_ACC_PUBLIC
)
2740 ZIPARCHIVE_ME(setCommentName
, arginfo_ziparchive_setcommentname
, ZEND_ACC_PUBLIC
)
2741 ZIPARCHIVE_ME(getCommentIndex
, arginfo_ziparchive_getcommentindex
, ZEND_ACC_PUBLIC
)
2742 ZIPARCHIVE_ME(getCommentName
, arginfo_ziparchive_getcommentname
, ZEND_ACC_PUBLIC
)
2743 ZIPARCHIVE_ME(deleteIndex
, arginfo_ziparchive_unchangeindex
, ZEND_ACC_PUBLIC
)
2744 ZIPARCHIVE_ME(deleteName
, arginfo_ziparchive_unchangename
, ZEND_ACC_PUBLIC
)
2745 ZIPARCHIVE_ME(statName
, arginfo_ziparchive_statname
, ZEND_ACC_PUBLIC
)
2746 ZIPARCHIVE_ME(statIndex
, arginfo_ziparchive_statindex
, ZEND_ACC_PUBLIC
)
2747 ZIPARCHIVE_ME(locateName
, arginfo_ziparchive_statname
, ZEND_ACC_PUBLIC
)
2748 ZIPARCHIVE_ME(getNameIndex
, arginfo_ziparchive_statindex
, ZEND_ACC_PUBLIC
)
2749 ZIPARCHIVE_ME(unchangeArchive
, arginfo_ziparchive__void
, ZEND_ACC_PUBLIC
)
2750 ZIPARCHIVE_ME(unchangeAll
, arginfo_ziparchive__void
, ZEND_ACC_PUBLIC
)
2751 ZIPARCHIVE_ME(unchangeIndex
, arginfo_ziparchive_unchangeindex
, ZEND_ACC_PUBLIC
)
2752 ZIPARCHIVE_ME(unchangeName
, arginfo_ziparchive_unchangename
, ZEND_ACC_PUBLIC
)
2753 ZIPARCHIVE_ME(extractTo
, arginfo_ziparchive_extractto
, ZEND_ACC_PUBLIC
)
2754 ZIPARCHIVE_ME(getFromName
, arginfo_ziparchive_getfromname
, ZEND_ACC_PUBLIC
)
2755 ZIPARCHIVE_ME(getFromIndex
, arginfo_ziparchive_getfromindex
, ZEND_ACC_PUBLIC
)
2756 ZIPARCHIVE_ME(getStream
, arginfo_ziparchive_getstream
, ZEND_ACC_PUBLIC
)
2762 /* {{{ PHP_MINIT_FUNCTION */
2763 static PHP_MINIT_FUNCTION(zip
)
2765 #ifdef PHP_ZIP_USE_OO
2766 zend_class_entry ce
;
2768 memcpy(&zip_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2769 zip_object_handlers
.clone_obj
= NULL
;
2770 zip_object_handlers
.get_property_ptr_ptr
= php_zip_get_property_ptr_ptr
;
2772 zip_object_handlers
.get_properties
= php_zip_get_properties
;
2773 zip_object_handlers
.read_property
= php_zip_read_property
;
2774 zip_object_handlers
.has_property
= php_zip_has_property
;
2776 INIT_CLASS_ENTRY(ce
, "ZipArchive", zip_class_functions
);
2777 ce
.create_object
= php_zip_object_new
;
2778 zip_class_entry
= zend_register_internal_class(&ce TSRMLS_CC
);
2780 zend_hash_init(&zip_prop_handlers
, 0, NULL
, NULL
, 1);
2781 php_zip_register_prop_handler(&zip_prop_handlers
, "status", php_zip_status
, NULL
, NULL
, IS_LONG TSRMLS_CC
);
2782 php_zip_register_prop_handler(&zip_prop_handlers
, "statusSys", php_zip_status_sys
, NULL
, NULL
, IS_LONG TSRMLS_CC
);
2783 php_zip_register_prop_handler(&zip_prop_handlers
, "numFiles", php_zip_get_num_files
, NULL
, NULL
, IS_LONG TSRMLS_CC
);
2784 php_zip_register_prop_handler(&zip_prop_handlers
, "filename", NULL
, NULL
, php_zipobj_get_filename
, IS_STRING TSRMLS_CC
);
2785 php_zip_register_prop_handler(&zip_prop_handlers
, "comment", NULL
, php_zipobj_get_zip_comment
, NULL
, IS_STRING TSRMLS_CC
);
2787 REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE
);
2788 REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL
);
2789 REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS
);
2790 REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE
);
2792 REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE
);
2793 REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR
);
2794 REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED
);
2795 REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED
);
2796 REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT
);
2797 REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE
);
2798 REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK
);
2799 REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_1", ZIP_CM_REDUCE_1
);
2800 REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_2", ZIP_CM_REDUCE_2
);
2801 REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_3", ZIP_CM_REDUCE_3
);
2802 REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_4", ZIP_CM_REDUCE_4
);
2803 REGISTER_ZIP_CLASS_CONST_LONG("CM_IMPLODE", ZIP_CM_IMPLODE
);
2804 REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE", ZIP_CM_DEFLATE
);
2805 REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE64", ZIP_CM_DEFLATE64
);
2806 REGISTER_ZIP_CLASS_CONST_LONG("CM_PKWARE_IMPLODE", ZIP_CM_PKWARE_IMPLODE
);
2807 REGISTER_ZIP_CLASS_CONST_LONG("CM_BZIP2", ZIP_CM_BZIP2
);
2808 REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA
);
2809 REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE
);
2810 REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77
);
2811 REGISTER_ZIP_CLASS_CONST_LONG("CM_WAVPACK", ZIP_CM_WAVPACK
);
2812 REGISTER_ZIP_CLASS_CONST_LONG("CM_PPMD", ZIP_CM_PPMD
);
2815 REGISTER_ZIP_CLASS_CONST_LONG("ER_OK", ZIP_ER_OK
); /* N No error */
2816 REGISTER_ZIP_CLASS_CONST_LONG("ER_MULTIDISK", ZIP_ER_MULTIDISK
); /* N Multi-disk zip archives not supported */
2817 REGISTER_ZIP_CLASS_CONST_LONG("ER_RENAME", ZIP_ER_RENAME
); /* S Renaming temporary file failed */
2818 REGISTER_ZIP_CLASS_CONST_LONG("ER_CLOSE", ZIP_ER_CLOSE
); /* S Closing zip archive failed */
2819 REGISTER_ZIP_CLASS_CONST_LONG("ER_SEEK", ZIP_ER_SEEK
); /* S Seek error */
2820 REGISTER_ZIP_CLASS_CONST_LONG("ER_READ", ZIP_ER_READ
); /* S Read error */
2821 REGISTER_ZIP_CLASS_CONST_LONG("ER_WRITE", ZIP_ER_WRITE
); /* S Write error */
2822 REGISTER_ZIP_CLASS_CONST_LONG("ER_CRC", ZIP_ER_CRC
); /* N CRC error */
2823 REGISTER_ZIP_CLASS_CONST_LONG("ER_ZIPCLOSED", ZIP_ER_ZIPCLOSED
); /* N Containing zip archive was closed */
2824 REGISTER_ZIP_CLASS_CONST_LONG("ER_NOENT", ZIP_ER_NOENT
); /* N No such file */
2825 REGISTER_ZIP_CLASS_CONST_LONG("ER_EXISTS", ZIP_ER_EXISTS
); /* N File already exists */
2826 REGISTER_ZIP_CLASS_CONST_LONG("ER_OPEN", ZIP_ER_OPEN
); /* S Can't open file */
2827 REGISTER_ZIP_CLASS_CONST_LONG("ER_TMPOPEN", ZIP_ER_TMPOPEN
); /* S Failure to create temporary file */
2828 REGISTER_ZIP_CLASS_CONST_LONG("ER_ZLIB", ZIP_ER_ZLIB
); /* Z Zlib error */
2829 REGISTER_ZIP_CLASS_CONST_LONG("ER_MEMORY", ZIP_ER_MEMORY
); /* N Malloc failure */
2830 REGISTER_ZIP_CLASS_CONST_LONG("ER_CHANGED", ZIP_ER_CHANGED
); /* N Entry has been changed */
2831 REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPNOTSUPP", ZIP_ER_COMPNOTSUPP
);/* N Compression method not supported */
2832 REGISTER_ZIP_CLASS_CONST_LONG("ER_EOF", ZIP_ER_EOF
); /* N Premature EOF */
2833 REGISTER_ZIP_CLASS_CONST_LONG("ER_INVAL", ZIP_ER_INVAL
); /* N Invalid argument */
2834 REGISTER_ZIP_CLASS_CONST_LONG("ER_NOZIP", ZIP_ER_NOZIP
); /* N Not a zip archive */
2835 REGISTER_ZIP_CLASS_CONST_LONG("ER_INTERNAL", ZIP_ER_INTERNAL
); /* N Internal error */
2836 REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS", ZIP_ER_INCONS
); /* N Zip archive inconsistent */
2837 REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE", ZIP_ER_REMOVE
); /* S Can't remove file */
2838 REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED", ZIP_ER_DELETED
); /* N Entry has been deleted */
2840 php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper TSRMLS_CC
);
2843 le_zip_dir
= zend_register_list_destructors_ex(php_zip_free_dir
, NULL
, le_zip_dir_name
, module_number
);
2844 le_zip_entry
= zend_register_list_destructors_ex(php_zip_free_entry
, NULL
, le_zip_entry_name
, module_number
);
2850 /* {{{ PHP_MSHUTDOWN_FUNCTION
2852 static PHP_MSHUTDOWN_FUNCTION(zip
)
2854 #ifdef PHP_ZIP_USE_OO
2855 zend_hash_destroy(&zip_prop_handlers
);
2856 php_unregister_url_stream_wrapper("zip" TSRMLS_CC
);
2862 /* {{{ PHP_MINFO_FUNCTION
2864 static PHP_MINFO_FUNCTION(zip
)
2866 php_info_print_table_start();
2868 php_info_print_table_row(2, "Zip", "enabled");
2869 php_info_print_table_row(2, "Extension Version","$Id$");
2870 php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING
);
2871 php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION
);
2873 php_info_print_table_end();
2882 * vim600: noet sw=4 ts=4 fdm=marker
2883 * vim<600: noet sw=4 ts=4