Annotation of embedaddon/php/ext/zip/php_zip.c, revision 1.1.1.5
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.5 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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: +----------------------------------------------------------------------+
17: */
18:
1.1.1.5 ! misho 19: /* $Id: abc21c7f1559e732dba6db94c69ecf638ae5fa3f $ */
1.1 misho 20:
21: #ifdef HAVE_CONFIG_H
22: #include "config.h"
23: #endif
24:
25: #include "php.h"
26: #include "php_ini.h"
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"
1.1.1.3 misho 31: #include "ext/standard/php_filestat.h"
1.1 misho 32: #include "php_zip.h"
33: #include "lib/zip.h"
34: #include "lib/zipint.h"
35:
36: /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
37: static PHP_NAMED_FUNCTION(zif_zip_open);
38: static PHP_NAMED_FUNCTION(zif_zip_read);
39: static PHP_NAMED_FUNCTION(zif_zip_close);
40: static PHP_NAMED_FUNCTION(zif_zip_entry_read);
41: static PHP_NAMED_FUNCTION(zif_zip_entry_filesize);
42: static PHP_NAMED_FUNCTION(zif_zip_entry_name);
43: static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize);
44: static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod);
45: static PHP_NAMED_FUNCTION(zif_zip_entry_open);
46: static PHP_NAMED_FUNCTION(zif_zip_entry_close);
47:
48: #ifdef HAVE_GLOB
49: #ifndef PHP_WIN32
50: #include <glob.h>
51: #else
52: #include "win32/glob.h"
53: #endif
54: #endif
55:
56: /* {{{ Resource le */
57: static int le_zip_dir;
58: #define le_zip_dir_name "Zip Directory"
59: static int le_zip_entry;
60: #define le_zip_entry_name "Zip Entry"
61: /* }}} */
62:
63: /* {{{ PHP_ZIP_STAT_INDEX(za, index, flags, sb) */
64: #define PHP_ZIP_STAT_INDEX(za, index, flags, sb) \
65: if (zip_stat_index(za, index, flags, &sb) != 0) { \
66: RETURN_FALSE; \
67: }
68: /* }}} */
69:
70: /* {{{ PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) */
71: #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \
72: if (path_len < 1) { \
73: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name"); \
74: RETURN_FALSE; \
75: } \
76: if (zip_stat(za, path, flags, &sb) != 0) { \
77: RETURN_FALSE; \
78: }
79: /* }}} */
80:
81: /* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */
82: #define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \
83: if (comment_len == 0) { \
84: /* Passing NULL remove the existing comment */ \
85: if (zip_set_file_comment(intern, index, NULL, 0) < 0) { \
86: RETURN_FALSE; \
87: } \
88: } else if (zip_set_file_comment(intern, index, comment, comment_len) < 0) { \
89: RETURN_FALSE; \
90: } \
91: RETURN_TRUE;
92: /* }}} */
93:
94: #if (PHP_MAJOR_VERSION < 6)
95: # define add_ascii_assoc_string add_assoc_string
96: # define add_ascii_assoc_long add_assoc_long
97: #endif
98:
99: /* Flatten a path by making a relative path (to .)*/
100: static char * php_zip_make_relative_path(char *path, int path_len) /* {{{ */
101: {
102: char *path_begin = path;
103: size_t i;
104:
105: if (path_len < 1 || path == NULL) {
106: return NULL;
107: }
108:
1.1.1.5 ! misho 109: if (IS_SLASH(path[0])) {
! 110: return path + 1;
! 111: }
! 112:
1.1 misho 113: i = path_len;
114:
115: while (1) {
116: while (i > 0 && !IS_SLASH(path[i])) {
117: i--;
118: }
119:
120: if (!i) {
121: return path;
122: }
123:
124: if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) {
125: /* i is the position of . or :, add 1 for / */
126: path_begin = path + i + 1;
127: break;
128: }
129: i--;
130: }
131:
132: return path_begin;
133: }
134: /* }}} */
135:
136: #ifdef PHP_ZIP_USE_OO
137: /* {{{ php_zip_extract_file */
138: static int php_zip_extract_file(struct zip * za, char *dest, char *file, int file_len TSRMLS_DC)
139: {
140: php_stream_statbuf ssb;
141: struct zip_file *zf;
142: struct zip_stat sb;
143: char b[8192];
144: int n, len, ret;
145: php_stream *stream;
146: char *fullpath;
147: char *file_dirname_fullpath;
148: char file_dirname[MAXPATHLEN];
149: size_t dir_len;
150: char *file_basename;
151: size_t file_basename_len;
152: int is_dir_only = 0;
153: char *path_cleaned;
154: size_t path_cleaned_len;
155: cwd_state new_state;
156:
157: new_state.cwd = (char*)malloc(1);
158: new_state.cwd[0] = '\0';
159: new_state.cwd_length = 0;
160:
161: /* Clean/normlize the path and then transform any path (absolute or relative)
162: to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
163: */
1.1.1.2 misho 164: virtual_file_ex(&new_state, file, NULL, CWD_EXPAND TSRMLS_CC);
1.1 misho 165: path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
166: if(!path_cleaned) {
167: return 0;
168: }
169: path_cleaned_len = strlen(path_cleaned);
170:
171: if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) {
172: return 0;
173: }
174:
175: /* it is a directory only, see #40228 */
176: if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) {
177: len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file);
178: is_dir_only = 1;
179: } else {
180: memcpy(file_dirname, path_cleaned, path_cleaned_len);
181: dir_len = php_dirname(file_dirname, path_cleaned_len);
182:
183: if (dir_len <= 0 || (dir_len == 1 && file_dirname[0] == '.')) {
184: len = spprintf(&file_dirname_fullpath, 0, "%s", dest);
185: } else {
186: len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname);
187: }
188:
189: php_basename(path_cleaned, path_cleaned_len, NULL, 0, &file_basename, (size_t *)&file_basename_len TSRMLS_CC);
190:
191: if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
192: efree(file_dirname_fullpath);
193: efree(file_basename);
194: free(new_state.cwd);
195: return 0;
196: }
197: }
198:
199: /* let see if the path already exists */
200: if (php_stream_stat_path_ex(file_dirname_fullpath, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
201:
202: #if defined(PHP_WIN32) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1)
203: char *e;
204: e = file_dirname_fullpath;
205: while (*e) {
206: if (*e == '/') {
207: *e = DEFAULT_SLASH;
208: }
209: e++;
210: }
211: #endif
212:
213: ret = php_stream_mkdir(file_dirname_fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL);
214: if (!ret) {
215: efree(file_dirname_fullpath);
216: if (!is_dir_only) {
217: efree(file_basename);
218: free(new_state.cwd);
219: }
220: return 0;
221: }
222: }
223:
224: /* it is a standalone directory, job done */
225: if (is_dir_only) {
226: efree(file_dirname_fullpath);
227: free(new_state.cwd);
228: return 1;
229: }
230:
231: len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, file_basename);
232: if (!len) {
233: efree(file_dirname_fullpath);
234: efree(file_basename);
235: free(new_state.cwd);
236: return 0;
237: } else if (len > MAXPATHLEN) {
238: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
239: efree(file_dirname_fullpath);
240: efree(file_basename);
241: free(new_state.cwd);
242: return 0;
243: }
244:
245: /* check again the full path, not sure if it
246: * is required, does a file can have a different
247: * safemode status as its parent folder?
248: */
249: if (ZIP_OPENBASEDIR_CHECKPATH(fullpath)) {
250: efree(fullpath);
251: efree(file_dirname_fullpath);
252: efree(file_basename);
253: free(new_state.cwd);
254: return 0;
255: }
256:
257: #if PHP_API_VERSION < 20100412
258: stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
259: #else
260: stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL);
261: #endif
262:
263: if (stream == NULL) {
264: n = -1;
265: goto done;
266: }
267:
268: zf = zip_fopen(za, file, 0);
269: if (zf == NULL) {
270: n = -1;
271: php_stream_close(stream);
272: goto done;
273: }
274:
275: n = 0;
276:
277: while ((n=zip_fread(zf, b, sizeof(b))) > 0) {
278: php_stream_write(stream, b, n);
279: }
280:
281: php_stream_close(stream);
282: n = zip_fclose(zf);
283:
284: done:
285: efree(fullpath);
286: efree(file_basename);
287: efree(file_dirname_fullpath);
288: free(new_state.cwd);
289:
290: if (n<0) {
291: return 0;
292: } else {
293: return 1;
294: }
295: }
296: /* }}} */
297:
298: static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
299: char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */
300: {
301: struct zip_source *zs;
302: int cur_idx;
303: char resolved_path[MAXPATHLEN];
1.1.1.3 misho 304: zval exists_flag;
1.1 misho 305:
306:
307: if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
308: return -1;
309: }
310:
311: if (!expand_filepath(filename, resolved_path TSRMLS_CC)) {
312: return -1;
313: }
314:
1.1.1.3 misho 315: php_stat(resolved_path, strlen(resolved_path), FS_EXISTS, &exists_flag TSRMLS_CC);
316: if (!Z_BVAL(exists_flag)) {
317: return -1;
318: }
319:
1.1 misho 320: zs = zip_source_file(za, resolved_path, offset_start, offset_len);
321: if (!zs) {
322: return -1;
323: }
324:
325: cur_idx = zip_name_locate(za, (const char *)entry_name, 0);
326: /* TODO: fix _zip_replace */
327: if (cur_idx<0) {
328: /* reset the error */
329: if (za->error.str) {
330: _zip_error_fini(&za->error);
331: }
332: _zip_error_init(&za->error);
333: } else {
334: if (zip_delete(za, cur_idx) == -1) {
335: zip_source_free(zs);
336: return -1;
337: }
338: }
339:
340: if (zip_add(za, entry_name, zs) == -1) {
341: return -1;
342: } else {
343: return 1;
344: }
345: }
346: /* }}} */
347:
348: static int php_zip_parse_options(zval *options, long *remove_all_path,
349: char **remove_path, int *remove_path_len, char **add_path, int *add_path_len TSRMLS_DC) /* {{{ */
350: {
351: zval **option;
352: if (zend_hash_find(HASH_OF(options), "remove_all_path", sizeof("remove_all_path"), (void **)&option) == SUCCESS) {
353: long opt;
354: if (Z_TYPE_PP(option) != IS_LONG) {
355: zval tmp = **option;
356: zval_copy_ctor(&tmp);
357: convert_to_long(&tmp);
358: opt = Z_LVAL(tmp);
359: } else {
360: opt = Z_LVAL_PP(option);
361: }
362: *remove_all_path = opt;
363: }
364:
365: /* If I add more options, it would make sense to create a nice static struct and loop over it. */
366: if (zend_hash_find(HASH_OF(options), "remove_path", sizeof("remove_path"), (void **)&option) == SUCCESS) {
367: if (Z_TYPE_PP(option) != IS_STRING) {
368: php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path option expected to be a string");
369: return -1;
370: }
371:
372: if (Z_STRLEN_PP(option) < 1) {
373: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string given as remove_path option");
374: return -1;
375: }
376:
377: if (Z_STRLEN_PP(option) >= MAXPATHLEN) {
378: php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path string is too long (max: %i, %i given)",
379: MAXPATHLEN - 1, Z_STRLEN_PP(option));
380: return -1;
381: }
382: *remove_path_len = Z_STRLEN_PP(option);
383: *remove_path = Z_STRVAL_PP(option);
384: }
385:
386: if (zend_hash_find(HASH_OF(options), "add_path", sizeof("add_path"), (void **)&option) == SUCCESS) {
387: if (Z_TYPE_PP(option) != IS_STRING) {
388: php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path option expected to be a string");
389: return -1;
390: }
391:
392: if (Z_STRLEN_PP(option) < 1) {
393: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string given as the add_path option");
394: return -1;
395: }
396:
397: if (Z_STRLEN_PP(option) >= MAXPATHLEN) {
398: php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
399: MAXPATHLEN - 1, Z_STRLEN_PP(option));
400: return -1;
401: }
402: *add_path_len = Z_STRLEN_PP(option);
403: *add_path = Z_STRVAL_PP(option);
404: }
405: return 1;
406: }
407: /* }}} */
408:
409: /* {{{ REGISTER_ZIP_CLASS_CONST_LONG */
410: #define REGISTER_ZIP_CLASS_CONST_LONG(const_name, value) \
411: zend_declare_class_constant_long(zip_class_entry, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
412: /* }}} */
413:
414: /* {{{ ZIP_FROM_OBJECT */
415: #define ZIP_FROM_OBJECT(intern, object) \
416: { \
417: ze_zip_object *obj = (ze_zip_object*) zend_object_store_get_object(object TSRMLS_CC); \
418: intern = obj->za; \
419: if (!intern) { \
420: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized Zip object"); \
421: RETURN_FALSE; \
422: } \
423: }
424: /* }}} */
425:
426: /* {{{ RETURN_SB(sb) */
427: #define RETURN_SB(sb) \
428: { \
429: array_init(return_value); \
430: add_ascii_assoc_string(return_value, "name", (char *)(sb)->name, 1); \
431: add_ascii_assoc_long(return_value, "index", (long) (sb)->index); \
432: add_ascii_assoc_long(return_value, "crc", (long) (sb)->crc); \
433: add_ascii_assoc_long(return_value, "size", (long) (sb)->size); \
434: add_ascii_assoc_long(return_value, "mtime", (long) (sb)->mtime); \
435: add_ascii_assoc_long(return_value, "comp_size", (long) (sb)->comp_size); \
436: add_ascii_assoc_long(return_value, "comp_method", (long) (sb)->comp_method); \
437: }
438: /* }}} */
439:
440: static int php_zip_status(struct zip *za TSRMLS_DC) /* {{{ */
441: {
442: int zep, syp;
443:
444: zip_error_get(za, &zep, &syp);
445: return zep;
446: }
447: /* }}} */
448:
449: static int php_zip_status_sys(struct zip *za TSRMLS_DC) /* {{{ */
450: {
451: int zep, syp;
452:
453: zip_error_get(za, &zep, &syp);
454: return syp;
455: }
456: /* }}} */
457:
458: static int php_zip_get_num_files(struct zip *za TSRMLS_DC) /* {{{ */
459: {
460: return zip_get_num_files(za);
461: }
462: /* }}} */
463:
464: static char * php_zipobj_get_filename(ze_zip_object *obj TSRMLS_DC) /* {{{ */
465: {
466:
467: if (!obj) {
468: return NULL;
469: }
470:
471: if (obj->filename) {
472: return obj->filename;
473: }
474: return NULL;
475: }
476: /* }}} */
477:
478: static char * php_zipobj_get_zip_comment(struct zip *za, int *len TSRMLS_DC) /* {{{ */
479: {
480: if (za) {
481: return (char *)zip_get_archive_comment(za, len, 0);
482: }
483: return NULL;
484: }
485: /* }}} */
486:
487: #ifdef HAVE_GLOB /* {{{ */
488: #ifndef GLOB_ONLYDIR
489: #define GLOB_ONLYDIR (1<<30)
490: #define GLOB_EMULATE_ONLYDIR
491: #define GLOB_FLAGMASK (~GLOB_ONLYDIR)
492: #else
493: #define GLOB_FLAGMASK (~0)
494: #endif
495: #ifndef GLOB_BRACE
496: # define GLOB_BRACE 0
497: #endif
498: #ifndef GLOB_MARK
499: # define GLOB_MARK 0
500: #endif
501: #ifndef GLOB_NOSORT
502: # define GLOB_NOSORT 0
503: #endif
504: #ifndef GLOB_NOCHECK
505: # define GLOB_NOCHECK 0
506: #endif
507: #ifndef GLOB_NOESCAPE
508: # define GLOB_NOESCAPE 0
509: #endif
510: #ifndef GLOB_ERR
511: # define GLOB_ERR 0
512: #endif
513:
514: /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
515: #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
516:
517: #endif /* }}} */
518:
519: int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value TSRMLS_DC) /* {{{ */
520: {
521: #ifdef HAVE_GLOB
522: char cwd[MAXPATHLEN];
523: int cwd_skip = 0;
524: #ifdef ZTS
525: char work_pattern[MAXPATHLEN];
526: char *result;
527: #endif
528: glob_t globbuf;
529: int n;
530: int ret;
531:
532: if (pattern_len >= MAXPATHLEN) {
533: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
534: return -1;
535: }
536:
537: if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
538: php_error_docref(NULL TSRMLS_CC, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
539: return -1;
540: }
541:
542: #ifdef ZTS
543: if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
544: result = VCWD_GETCWD(cwd, MAXPATHLEN);
545: if (!result) {
546: cwd[0] = '\0';
547: }
548: #ifdef PHP_WIN32
549: if (IS_SLASH(*pattern)) {
550: cwd[2] = '\0';
551: }
552: #endif
553: cwd_skip = strlen(cwd)+1;
554:
555: snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
556: pattern = work_pattern;
557: }
558: #endif
559:
560: globbuf.gl_offs = 0;
561: if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
562: #ifdef GLOB_NOMATCH
563: if (GLOB_NOMATCH == ret) {
564: /* Some glob implementation simply return no data if no matches
565: were found, others return the GLOB_NOMATCH error code.
566: We don't want to treat GLOB_NOMATCH as an error condition
567: so that PHP glob() behaves the same on both types of
568: implementations and so that 'foreach (glob() as ...'
569: can be used for simple glob() calls without further error
570: checking.
571: */
572: array_init(return_value);
573: return 0;
574: }
575: #endif
576: return 0;
577: }
578:
579: /* now catch the FreeBSD style of "no matches" */
580: if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
581: array_init(return_value);
582: return 0;
583: }
584:
585: /* we assume that any glob pattern will match files from one directory only
586: so checking the dirname of the first match should be sufficient */
587: strncpy(cwd, globbuf.gl_pathv[0], MAXPATHLEN);
588: if (ZIP_OPENBASEDIR_CHECKPATH(cwd)) {
589: return -1;
590: }
591:
592: array_init(return_value);
593: for (n = 0; n < globbuf.gl_pathc; n++) {
594: /* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
595: * all directories will be filtered. GNU libc documentation states the
596: * following:
597: * If the information about the type of the file is easily available
598: * non-directories will be rejected but no extra work will be done to
599: * determine the information for each file. I.e., the caller must still be
600: * able to filter directories out.
601: */
602: if (flags & GLOB_ONLYDIR) {
603: struct stat s;
604:
605: if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
606: continue;
607: }
608:
609: if (S_IFDIR != (s.st_mode & S_IFMT)) {
610: continue;
611: }
612: }
613: add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip, 1);
614: }
615:
616: globfree(&globbuf);
617: return globbuf.gl_pathc;
618: #else
619: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Glob support is not available");
620: return 0;
621: #endif /* HAVE_GLOB */
622: }
623: /* }}} */
624:
625: int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *return_value TSRMLS_DC) /* {{{ */
626: {
627: #ifdef ZTS
628: char cwd[MAXPATHLEN];
629: int cwd_skip = 0;
630: char work_path[MAXPATHLEN];
631: char *result;
632: #endif
633: int files_cnt;
634: char **namelist;
635:
636: #ifdef ZTS
637: if (!IS_ABSOLUTE_PATH(path, path_len)) {
638: result = VCWD_GETCWD(cwd, MAXPATHLEN);
639: if (!result) {
640: cwd[0] = '\0';
641: }
642: #ifdef PHP_WIN32
643: if (IS_SLASH(*path)) {
644: cwd[2] = '\0';
645: }
646: #endif
647: cwd_skip = strlen(cwd)+1;
648:
649: snprintf(work_path, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, path);
650: path = work_path;
651: }
652: #endif
653:
654: if (ZIP_OPENBASEDIR_CHECKPATH(path)) {
655: return -1;
656: }
657:
658: files_cnt = php_stream_scandir(path, &namelist, NULL, (void *) php_stream_dirent_alphasort);
659:
660: if (files_cnt > 0) {
661: pcre *re = NULL;
662: pcre_extra *pcre_extra = NULL;
663: int preg_options = 0, i;
664:
665: re = pcre_get_compiled_regex(regexp, &pcre_extra, &preg_options TSRMLS_CC);
666: if (!re) {
667: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid expression");
668: return -1;
669: }
670:
671: array_init(return_value);
672:
673: /* only the files, directories are ignored */
674: for (i = 0; i < files_cnt; i++) {
675: struct stat s;
676: char fullpath[MAXPATHLEN];
677: int ovector[3];
678: int matches;
679: int namelist_len = strlen(namelist[i]);
680:
681:
682: if ((namelist_len == 1 && namelist[i][0] == '.') ||
683: (namelist_len == 2 && namelist[i][0] == '.' && namelist[i][1] == '.')) {
684: efree(namelist[i]);
685: continue;
686: }
687:
688: if ((path_len + namelist_len + 1) >= MAXPATHLEN) {
689: php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
690: MAXPATHLEN - 1, (path_len + namelist_len + 1));
691: efree(namelist[i]);
692: break;
693: }
694:
695: snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, namelist[i]);
696:
697: if (0 != VCWD_STAT(fullpath, &s)) {
698: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot read <%s>", fullpath);
699: efree(namelist[i]);
700: continue;
701: }
702:
703: if (S_IFDIR == (s.st_mode & S_IFMT)) {
704: efree(namelist[i]);
705: continue;
706: }
707:
708: matches = pcre_exec(re, NULL, namelist[i], strlen(namelist[i]), 0, 0, ovector, 3);
709: /* 0 means that the vector is too small to hold all the captured substring offsets */
710: if (matches < 0) {
711: efree(namelist[i]);
712: continue;
713: }
714:
715: add_next_index_string(return_value, fullpath, 1);
716: efree(namelist[i]);
717: }
718: efree(namelist);
719: }
720: return files_cnt;
721: }
722: /* }}} */
723:
724: #endif
725:
726: /* {{{ arginfo */
727: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1)
728: ZEND_ARG_INFO(0, filename)
729: ZEND_END_ARG_INFO()
730:
731: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_close, 0, 0, 1)
732: ZEND_ARG_INFO(0, zip)
733: ZEND_END_ARG_INFO()
734:
735: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_read, 0, 0, 1)
736: ZEND_ARG_INFO(0, zip)
737: ZEND_END_ARG_INFO()
738:
739: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_open, 0, 0, 2)
740: ZEND_ARG_INFO(0, zip_dp)
741: ZEND_ARG_INFO(0, zip_entry)
742: ZEND_ARG_INFO(0, mode)
743: ZEND_END_ARG_INFO()
744:
745: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_close, 0, 0, 1)
746: ZEND_ARG_INFO(0, zip_ent)
747: ZEND_END_ARG_INFO()
748:
749: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_read, 0, 0, 1)
750: ZEND_ARG_INFO(0, zip_entry)
751: ZEND_ARG_INFO(0, len)
752: ZEND_END_ARG_INFO()
753:
754: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_name, 0, 0, 1)
755: ZEND_ARG_INFO(0, zip_entry)
756: ZEND_END_ARG_INFO()
757:
758: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressedsize, 0, 0, 1)
759: ZEND_ARG_INFO(0, zip_entry)
760: ZEND_END_ARG_INFO()
761:
762: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_filesize, 0, 0, 1)
763: ZEND_ARG_INFO(0, zip_entry)
764: ZEND_END_ARG_INFO()
765:
766: ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressionmethod, 0, 0, 1)
767: ZEND_ARG_INFO(0, zip_entry)
768: ZEND_END_ARG_INFO()
769: /* }}} */
770:
771: /* {{{ zend_function_entry */
772: static const zend_function_entry zip_functions[] = {
773: ZEND_RAW_FENTRY("zip_open", zif_zip_open, arginfo_zip_open, 0)
774: ZEND_RAW_FENTRY("zip_close", zif_zip_close, arginfo_zip_close, 0)
775: ZEND_RAW_FENTRY("zip_read", zif_zip_read, arginfo_zip_read, 0)
776: PHP_FE(zip_entry_open, arginfo_zip_entry_open)
777: PHP_FE(zip_entry_close, arginfo_zip_entry_close)
778: PHP_FE(zip_entry_read, arginfo_zip_entry_read)
779: PHP_FE(zip_entry_filesize, arginfo_zip_entry_filesize)
780: PHP_FE(zip_entry_name, arginfo_zip_entry_name)
781: PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize)
782: PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod)
783: PHP_FE_END
784: };
785: /* }}} */
786:
787: /* {{{ ZE2 OO definitions */
788: #ifdef PHP_ZIP_USE_OO
789: static zend_class_entry *zip_class_entry;
790: static zend_object_handlers zip_object_handlers;
791:
792: static HashTable zip_prop_handlers;
793:
794: typedef int (*zip_read_int_t)(struct zip *za TSRMLS_DC);
795: typedef char *(*zip_read_const_char_t)(struct zip *za, int *len TSRMLS_DC);
796: typedef char *(*zip_read_const_char_from_ze_t)(ze_zip_object *obj TSRMLS_DC);
797:
798: typedef struct _zip_prop_handler {
799: zip_read_int_t read_int_func;
800: zip_read_const_char_t read_const_char_func;
801: zip_read_const_char_from_ze_t read_const_char_from_obj_func;
802:
803: int type;
804: } zip_prop_handler;
805: #endif
806: /* }}} */
807:
808: #ifdef PHP_ZIP_USE_OO
809: 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) /* {{{ */
810: {
811: zip_prop_handler hnd;
812:
813: hnd.read_const_char_func = read_char_func;
814: hnd.read_int_func = read_int_func;
815: hnd.read_const_char_from_obj_func = read_char_from_obj_func;
816: hnd.type = rettype;
817: zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(zip_prop_handler), NULL);
818: }
819: /* }}} */
820:
821: static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zval **retval, int newzval TSRMLS_DC) /* {{{ */
822: {
823: const char *retchar = NULL;
824: int retint = 0;
825: int len = 0;
826:
827: if (obj && obj->za != NULL) {
828: if (hnd->read_const_char_func) {
829: retchar = hnd->read_const_char_func(obj->za, &len TSRMLS_CC);
830: } else {
831: if (hnd->read_int_func) {
832: retint = hnd->read_int_func(obj->za TSRMLS_CC);
833: if (retint == -1) {
834: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal zip error returned");
835: return FAILURE;
836: }
837: } else {
838: if (hnd->read_const_char_from_obj_func) {
839: retchar = hnd->read_const_char_from_obj_func(obj TSRMLS_CC);
840: len = strlen(retchar);
841: }
842: }
843: }
844: }
845:
846: if (newzval) {
847: ALLOC_ZVAL(*retval);
848: }
849:
850: switch (hnd->type) {
851: case IS_STRING:
852: if (retchar) {
853: ZVAL_STRINGL(*retval, (char *) retchar, len, 1);
854: } else {
855: ZVAL_EMPTY_STRING(*retval);
856: }
857: break;
858: case IS_BOOL:
859: ZVAL_BOOL(*retval, (long)retint);
860: break;
861: case IS_LONG:
862: ZVAL_LONG(*retval, (long)retint);
863: break;
864: default:
865: ZVAL_NULL(*retval);
866: }
867:
868: return SUCCESS;
869: }
870: /* }}} */
871:
1.1.1.2 misho 872: static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
1.1 misho 873: {
874: ze_zip_object *obj;
875: zval tmp_member;
876: zval **retval = NULL;
877:
878: zip_prop_handler *hnd;
879: zend_object_handlers *std_hnd;
880: int ret;
881:
882: if (member->type != IS_STRING) {
883: tmp_member = *member;
884: zval_copy_ctor(&tmp_member);
885: convert_to_string(&tmp_member);
886: member = &tmp_member;
1.1.1.2 misho 887: key = NULL;
1.1 misho 888: }
889:
890: ret = FAILURE;
891: obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
892:
893: if (obj->prop_handler != NULL) {
1.1.1.2 misho 894: if (key) {
895: ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
896: } else {
897: ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
898: }
1.1 misho 899: }
900:
901:
902: if (ret == FAILURE) {
903: std_hnd = zend_get_std_object_handlers();
1.1.1.2 misho 904: retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
1.1 misho 905: }
906:
907: if (member == &tmp_member) {
908: zval_dtor(member);
909: }
910: return retval;
911: }
912: /* }}} */
913:
1.1.1.2 misho 914: static zval* php_zip_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
1.1 misho 915: {
916: ze_zip_object *obj;
917: zval tmp_member;
918: zval *retval;
919: zip_prop_handler *hnd;
920: zend_object_handlers *std_hnd;
921: int ret;
922:
923: if (member->type != IS_STRING) {
924: tmp_member = *member;
925: zval_copy_ctor(&tmp_member);
926: convert_to_string(&tmp_member);
927: member = &tmp_member;
1.1.1.2 misho 928: key = NULL;
1.1 misho 929: }
930:
931: ret = FAILURE;
932: obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
933:
934: if (obj->prop_handler != NULL) {
1.1.1.2 misho 935: if (key) {
936: ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
937: } else {
938: ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
939: }
1.1 misho 940: }
941:
942: if (ret == SUCCESS) {
943: ret = php_zip_property_reader(obj, hnd, &retval, 1 TSRMLS_CC);
944: if (ret == SUCCESS) {
945: /* ensure we're creating a temporary variable */
946: Z_SET_REFCOUNT_P(retval, 0);
947: } else {
948: retval = EG(uninitialized_zval_ptr);
949: }
950: } else {
951: std_hnd = zend_get_std_object_handlers();
1.1.1.2 misho 952: retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
1.1 misho 953: }
954:
955: if (member == &tmp_member) {
956: zval_dtor(member);
957: }
958: return retval;
959: }
960: /* }}} */
961:
1.1.1.2 misho 962: static int php_zip_has_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
1.1 misho 963: {
964: ze_zip_object *obj;
965: zval tmp_member;
966: zip_prop_handler *hnd;
967: zend_object_handlers *std_hnd;
968: int ret, retval = 0;
969:
970: if (member->type != IS_STRING) {
971: tmp_member = *member;
972: zval_copy_ctor(&tmp_member);
973: convert_to_string(&tmp_member);
974: member = &tmp_member;
1.1.1.2 misho 975: key = NULL;
1.1 misho 976: }
977:
978: ret = FAILURE;
979: obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
980:
981: if (obj->prop_handler != NULL) {
1.1.1.2 misho 982: if (key) {
983: ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
984: } else {
985: ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
986: }
1.1 misho 987: }
988:
989: if (ret == SUCCESS) {
990: zval *tmp;
991: ALLOC_INIT_ZVAL(tmp);
992:
993: if (type == 2) {
994: retval = 1;
995: } else if (php_zip_property_reader(obj, hnd, &tmp, 0 TSRMLS_CC) == SUCCESS) {
996: Z_SET_REFCOUNT_P(tmp, 1);
997: Z_UNSET_ISREF_P(tmp);
998: if (type == 1) {
999: retval = zend_is_true(tmp);
1000: } else if (type == 0) {
1001: retval = (Z_TYPE_P(tmp) != IS_NULL);
1002: }
1003: }
1004:
1005: zval_ptr_dtor(&tmp);
1006: } else {
1007: std_hnd = zend_get_std_object_handlers();
1.1.1.2 misho 1008: retval = std_hnd->has_property(object, member, type, key TSRMLS_CC);
1.1 misho 1009: }
1010:
1011: if (member == &tmp_member) {
1012: zval_dtor(member);
1013: }
1014: return retval;
1015: }
1016: /* }}} */
1017:
1018: static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */
1019: {
1020: ze_zip_object *obj;
1021: zip_prop_handler *hnd;
1022: HashTable *props;
1023: zval *val;
1024: int ret;
1025: char *key;
1026: uint key_len;
1027: HashPosition pos;
1028: ulong num_key;
1029:
1030: obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
1.1.1.2 misho 1031: props = zend_std_get_properties(object TSRMLS_CC);
1.1 misho 1032:
1033: if (obj->prop_handler == NULL) {
1034: return NULL;
1035: }
1036: zend_hash_internal_pointer_reset_ex(obj->prop_handler, &pos);
1037:
1038: while (zend_hash_get_current_data_ex(obj->prop_handler, (void**)&hnd, &pos) == SUCCESS) {
1039: zend_hash_get_current_key_ex(obj->prop_handler, &key, &key_len, &num_key, 0, &pos);
1040: MAKE_STD_ZVAL(val);
1041: ret = php_zip_property_reader(obj, hnd, &val, 0 TSRMLS_CC);
1042: if (ret != SUCCESS) {
1043: val = EG(uninitialized_zval_ptr);
1044: }
1045: zend_hash_update(props, key, key_len, (void *)&val, sizeof(zval *), NULL);
1046: zend_hash_move_forward_ex(obj->prop_handler, &pos);
1047: }
1.1.1.2 misho 1048: return props;
1.1 misho 1049: }
1050: /* }}} */
1051:
1052: static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */
1053: {
1054: ze_zip_object * intern = (ze_zip_object *) object;
1055: int i;
1056:
1057: if (!intern) {
1058: return;
1059: }
1060: if (intern->za) {
1061: if (zip_close(intern->za) != 0) {
1062: _zip_free(intern->za);
1063: }
1064: intern->za = NULL;
1065: }
1066:
1067: if (intern->buffers_cnt>0) {
1068: for (i=0; i<intern->buffers_cnt; i++) {
1069: efree(intern->buffers[i]);
1070: }
1071: efree(intern->buffers);
1072: }
1073:
1074: intern->za = NULL;
1075:
1076: #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)
1077: zend_object_std_dtor(&intern->zo TSRMLS_CC);
1078: #else
1079: if (intern->zo.guards) {
1080: zend_hash_destroy(intern->zo.guards);
1081: FREE_HASHTABLE(intern->zo.guards);
1082: }
1083:
1084: if (intern->zo.properties) {
1085: zend_hash_destroy(intern->zo.properties);
1086: FREE_HASHTABLE(intern->zo.properties);
1087: }
1088: #endif
1089:
1090: if (intern->filename) {
1091: efree(intern->filename);
1092: }
1093: efree(intern);
1094: }
1095: /* }}} */
1096:
1097: static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
1098: {
1099: ze_zip_object *intern;
1100: zend_object_value retval;
1101:
1102: intern = emalloc(sizeof(ze_zip_object));
1103: memset(&intern->zo, 0, sizeof(zend_object));
1104:
1105: intern->za = NULL;
1106: intern->buffers = NULL;
1107: intern->filename = NULL;
1108: intern->buffers_cnt = 0;
1109: intern->prop_handler = &zip_prop_handlers;
1110:
1111: #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2))
1112: zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
1113: #else
1114: ALLOC_HASHTABLE(intern->zo.properties);
1115: zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
1116: intern->zo.ce = class_type;
1117: #endif
1118:
1.1.1.2 misho 1119: object_properties_init(&intern->zo, class_type);
1.1 misho 1120:
1121: retval.handle = zend_objects_store_put(intern,
1122: NULL,
1123: (zend_objects_free_object_storage_t) php_zip_object_free_storage,
1124: NULL TSRMLS_CC);
1125:
1126: retval.handlers = (zend_object_handlers *) & zip_object_handlers;
1127:
1128: return retval;
1129: }
1130: /* }}} */
1131: #endif
1132:
1133: /* {{{ Resource dtors */
1134:
1135: /* {{{ php_zip_free_dir */
1136: static void php_zip_free_dir(zend_rsrc_list_entry *rsrc TSRMLS_DC)
1137: {
1138: zip_rsrc * zip_int = (zip_rsrc *) rsrc->ptr;
1139:
1140: if (zip_int) {
1141: if (zip_int->za) {
1142: if (zip_close(zip_int->za) != 0) {
1143: _zip_free(zip_int->za);
1144: }
1145: zip_int->za = NULL;
1146: }
1147:
1148: efree(rsrc->ptr);
1149:
1150: rsrc->ptr = NULL;
1151: }
1152: }
1153: /* }}} */
1154:
1155: /* {{{ php_zip_free_entry */
1156: static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC)
1157: {
1158: zip_read_rsrc *zr_rsrc = (zip_read_rsrc *) rsrc->ptr;
1159:
1160: if (zr_rsrc) {
1161: if (zr_rsrc->zf) {
1.1.1.3 misho 1162: if (zr_rsrc->zf->za) {
1163: zip_fclose(zr_rsrc->zf);
1164: } else {
1165: if (zr_rsrc->zf->src)
1166: zip_source_free(zr_rsrc->zf->src);
1167: free(zr_rsrc->zf);
1168: }
1.1 misho 1169: zr_rsrc->zf = NULL;
1170: }
1171: efree(zr_rsrc);
1172: rsrc->ptr = NULL;
1173: }
1174: }
1175: /* }}} */
1176:
1177: /* }}}*/
1178:
1179: /* reset macro */
1180:
1181: /* {{{ function prototypes */
1182: static PHP_MINIT_FUNCTION(zip);
1183: static PHP_MSHUTDOWN_FUNCTION(zip);
1184: static PHP_MINFO_FUNCTION(zip);
1185: /* }}} */
1186:
1187: /* {{{ zip_module_entry
1188: */
1189: zend_module_entry zip_module_entry = {
1190: STANDARD_MODULE_HEADER,
1191: "zip",
1192: zip_functions,
1193: PHP_MINIT(zip),
1194: PHP_MSHUTDOWN(zip),
1195: NULL,
1196: NULL,
1197: PHP_MINFO(zip),
1198: PHP_ZIP_VERSION_STRING,
1199: STANDARD_MODULE_PROPERTIES
1200: };
1201: /* }}} */
1202:
1203: #ifdef COMPILE_DL_ZIP
1204: ZEND_GET_MODULE(zip)
1205: #endif
1206: /* set macro */
1207:
1208: /* {{{ proto resource zip_open(string filename)
1209: Create new zip using source uri for output */
1210: static PHP_NAMED_FUNCTION(zif_zip_open)
1211: {
1212: char *filename;
1213: int filename_len;
1214: char resolved_path[MAXPATHLEN + 1];
1215: zip_rsrc *rsrc_int;
1216: int err = 0;
1217:
1.1.1.2 misho 1218: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
1.1 misho 1219: return;
1220: }
1221:
1222: if (filename_len == 0) {
1223: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
1224: RETURN_FALSE;
1225: }
1226:
1227: if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
1228: RETURN_FALSE;
1229: }
1230:
1231: if(!expand_filepath(filename, resolved_path TSRMLS_CC)) {
1232: RETURN_FALSE;
1233: }
1234:
1235: rsrc_int = (zip_rsrc *)emalloc(sizeof(zip_rsrc));
1236:
1237: rsrc_int->za = zip_open(resolved_path, 0, &err);
1238: if (rsrc_int->za == NULL) {
1239: efree(rsrc_int);
1240: RETURN_LONG((long)err);
1241: }
1242:
1243: rsrc_int->index_current = 0;
1244: rsrc_int->num_files = zip_get_num_files(rsrc_int->za);
1245:
1246: ZEND_REGISTER_RESOURCE(return_value, rsrc_int, le_zip_dir);
1247: }
1248: /* }}} */
1249:
1250: /* {{{ proto void zip_close(resource zip)
1251: Close a Zip archive */
1252: static PHP_NAMED_FUNCTION(zif_zip_close)
1253: {
1254: zval * zip;
1255: zip_rsrc *z_rsrc = NULL;
1256:
1257: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip) == FAILURE) {
1258: return;
1259: }
1260: ZEND_FETCH_RESOURCE(z_rsrc, zip_rsrc *, &zip, -1, le_zip_dir_name, le_zip_dir);
1261:
1262: /* really close the zip will break BC :-D */
1263: zend_list_delete(Z_LVAL_P(zip));
1264: }
1265: /* }}} */
1266:
1267: /* {{{ proto resource zip_read(resource zip)
1268: Returns the next file in the archive */
1269: static PHP_NAMED_FUNCTION(zif_zip_read)
1270: {
1271: zval *zip_dp;
1272: zip_read_rsrc *zr_rsrc;
1273: int ret;
1274: zip_rsrc *rsrc_int;
1275:
1276: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip_dp) == FAILURE) {
1277: return;
1278: }
1279: ZEND_FETCH_RESOURCE(rsrc_int, zip_rsrc *, &zip_dp, -1, le_zip_dir_name, le_zip_dir);
1280:
1281: if (rsrc_int && rsrc_int->za) {
1282: if (rsrc_int->index_current >= rsrc_int->num_files) {
1283: RETURN_FALSE;
1284: }
1285:
1286: zr_rsrc = emalloc(sizeof(zip_read_rsrc));
1287:
1288: ret = zip_stat_index(rsrc_int->za, rsrc_int->index_current, 0, &zr_rsrc->sb);
1289:
1290: if (ret != 0) {
1291: efree(zr_rsrc);
1292: RETURN_FALSE;
1293: }
1294:
1295: zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0);
1296: if (zr_rsrc->zf) {
1297: rsrc_int->index_current++;
1298: ZEND_REGISTER_RESOURCE(return_value, zr_rsrc, le_zip_entry);
1299: } else {
1300: efree(zr_rsrc);
1301: RETURN_FALSE;
1302: }
1303:
1304: } else {
1305: RETURN_FALSE;
1306: }
1307: }
1308: /* }}} */
1309:
1310: /* {{{ proto bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
1311: Open a Zip File, pointed by the resource entry */
1312: /* Dummy function to follow the old API */
1313: static PHP_NAMED_FUNCTION(zif_zip_entry_open)
1314: {
1315: zval * zip;
1316: zval * zip_entry;
1317: char *mode = NULL;
1318: int mode_len = 0;
1319: zip_read_rsrc * zr_rsrc;
1320: zip_rsrc *z_rsrc;
1321:
1322: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|s", &zip, &zip_entry, &mode, &mode_len) == FAILURE) {
1323: return;
1324: }
1325:
1326: ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
1327: ZEND_FETCH_RESOURCE(z_rsrc, zip_rsrc *, &zip, -1, le_zip_dir_name, le_zip_dir);
1328:
1329: if (zr_rsrc->zf != NULL) {
1330: RETURN_TRUE;
1331: } else {
1332: RETURN_FALSE;
1333: }
1334: }
1335: /* }}} */
1336:
1.1.1.3 misho 1337: /* {{{ proto bool zip_entry_close(resource zip_ent)
1.1 misho 1338: Close a zip entry */
1339: static PHP_NAMED_FUNCTION(zif_zip_entry_close)
1340: {
1341: zval * zip_entry;
1342: zip_read_rsrc * zr_rsrc;
1343:
1344: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip_entry) == FAILURE) {
1345: return;
1346: }
1347:
1348: ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
1.1.1.3 misho 1349:
1350: RETURN_BOOL(SUCCESS == zend_list_delete(Z_LVAL_P(zip_entry)));
1.1 misho 1351: }
1352: /* }}} */
1353:
1354: /* {{{ proto mixed zip_entry_read(resource zip_entry [, int len])
1355: Read from an open directory entry */
1356: static PHP_NAMED_FUNCTION(zif_zip_entry_read)
1357: {
1358: zval * zip_entry;
1359: long len = 0;
1360: zip_read_rsrc * zr_rsrc;
1361: char *buffer;
1362: int n = 0;
1363:
1364: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zip_entry, &len) == FAILURE) {
1365: return;
1366: }
1367:
1368: ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
1369:
1370: if (len <= 0) {
1371: len = 1024;
1372: }
1373:
1374: if (zr_rsrc->zf) {
1375: buffer = safe_emalloc(len, 1, 1);
1376: n = zip_fread(zr_rsrc->zf, buffer, len);
1377: if (n > 0) {
1378: buffer[n] = 0;
1379: RETURN_STRINGL(buffer, n, 0);
1380: } else {
1381: efree(buffer);
1382: RETURN_EMPTY_STRING()
1383: }
1384: } else {
1385: RETURN_FALSE;
1386: }
1387: }
1388: /* }}} */
1389:
1390: static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ */
1391: {
1392: zval * zip_entry;
1393: zip_read_rsrc * zr_rsrc;
1394:
1395: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zip_entry) == FAILURE) {
1396: return;
1397: }
1398:
1399: ZEND_FETCH_RESOURCE(zr_rsrc, zip_read_rsrc *, &zip_entry, -1, le_zip_entry_name, le_zip_entry);
1400:
1401: if (!zr_rsrc->zf) {
1402: RETURN_FALSE;
1403: }
1404:
1405: switch (opt) {
1406: case 0:
1407: RETURN_STRING((char *)zr_rsrc->sb.name, 1);
1408: break;
1409: case 1:
1410: RETURN_LONG((long) (zr_rsrc->sb.comp_size));
1411: break;
1412: case 2:
1413: RETURN_LONG((long) (zr_rsrc->sb.size));
1414: break;
1415: case 3:
1416: switch (zr_rsrc->sb.comp_method) {
1417: case 0:
1418: RETURN_STRING("stored", 1);
1419: break;
1420: case 1:
1421: RETURN_STRING("shrunk", 1);
1422: break;
1423: case 2:
1424: case 3:
1425: case 4:
1426: case 5:
1427: RETURN_STRING("reduced", 1);
1428: break;
1429: case 6:
1430: RETURN_STRING("imploded", 1);
1431: break;
1432: case 7:
1433: RETURN_STRING("tokenized", 1);
1434: break;
1435: case 8:
1436: RETURN_STRING("deflated", 1);
1437: break;
1438: case 9:
1439: RETURN_STRING("deflatedX", 1);
1440: break;
1441: case 10:
1442: RETURN_STRING("implodedX", 1);
1443: break;
1444: default:
1445: RETURN_FALSE;
1446: }
1447: RETURN_LONG((long) (zr_rsrc->sb.comp_method));
1448: break;
1449: }
1450:
1451: }
1452: /* }}} */
1453:
1454: /* {{{ proto string zip_entry_name(resource zip_entry)
1455: Return the name given a ZZip entry */
1456: static PHP_NAMED_FUNCTION(zif_zip_entry_name)
1457: {
1458: php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1459: }
1460: /* }}} */
1461:
1462: /* {{{ proto int zip_entry_compressedsize(resource zip_entry)
1463: Return the compressed size of a ZZip entry */
1464: static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize)
1465: {
1466: php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1467: }
1468: /* }}} */
1469:
1470: /* {{{ proto int zip_entry_filesize(resource zip_entry)
1471: Return the actual filesize of a ZZip entry */
1472: static PHP_NAMED_FUNCTION(zif_zip_entry_filesize)
1473: {
1474: php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
1475: }
1476: /* }}} */
1477:
1478: /* {{{ proto string zip_entry_compressionmethod(resource zip_entry)
1479: Return a string containing the compression method used on a particular entry */
1480: static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod)
1481: {
1482: php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3);
1483: }
1484: /* }}} */
1485:
1486: #ifdef PHP_ZIP_USE_OO
1487: /* {{{ proto mixed ZipArchive::open(string source [, int flags])
1488: Create new zip using source uri for output, return TRUE on success or the error code */
1489: static ZIPARCHIVE_METHOD(open)
1490: {
1491: struct zip *intern;
1492: char *filename;
1493: int filename_len;
1494: int err = 0;
1495: long flags = 0;
1496: char resolved_path[MAXPATHLEN];
1497:
1498: zval *this = getThis();
1499: ze_zip_object *ze_obj = NULL;
1500:
1.1.1.2 misho 1501: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &flags) == FAILURE) {
1.1 misho 1502: return;
1503: }
1504:
1505: if (this) {
1506: /* We do not use ZIP_FROM_OBJECT, zip init function here */
1507: ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
1508: }
1509:
1510: if (filename_len == 0) {
1511: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
1512: RETURN_FALSE;
1513: }
1514:
1515: if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
1516: RETURN_FALSE;
1517: }
1518:
1519: if (!expand_filepath(filename, resolved_path TSRMLS_CC)) {
1520: RETURN_FALSE;
1521: }
1522:
1523: if (ze_obj->za) {
1524: /* we already have an opened zip, free it */
1525: if (zip_close(ze_obj->za) != 0) {
1526: _zip_free(ze_obj->za);
1527: }
1528: ze_obj->za = NULL;
1529: }
1530: if (ze_obj->filename) {
1531: efree(ze_obj->filename);
1532: ze_obj->filename = NULL;
1533: }
1534:
1535: intern = zip_open(resolved_path, flags, &err);
1536: if (!intern || err) {
1537: RETURN_LONG((long)err);
1538: }
1539: ze_obj->filename = estrdup(resolved_path);
1.1.1.5 ! misho 1540: ze_obj->filename_len = strlen(resolved_path);
1.1 misho 1541: ze_obj->za = intern;
1542: RETURN_TRUE;
1543: }
1544: /* }}} */
1545:
1546: /* {{{ proto bool ZipArchive::close()
1547: close the zip archive */
1548: static ZIPARCHIVE_METHOD(close)
1549: {
1550: struct zip *intern;
1551: zval *this = getThis();
1552: ze_zip_object *ze_obj;
1553:
1554: if (!this) {
1555: RETURN_FALSE;
1556: }
1557:
1558: ZIP_FROM_OBJECT(intern, this);
1559:
1560: ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
1561:
1562: if (zip_close(intern)) {
1563: RETURN_FALSE;
1564: }
1565:
1566: efree(ze_obj->filename);
1567: ze_obj->filename = NULL;
1568: ze_obj->filename_len = 0;
1569: ze_obj->za = NULL;
1570:
1571: RETURN_TRUE;
1572: }
1573: /* }}} */
1574:
1575: /* {{{ proto string ZipArchive::getStatusString()
1576: * Returns the status error message, system and/or zip messages */
1577: static ZIPARCHIVE_METHOD(getStatusString)
1578: {
1579: struct zip *intern;
1580: zval *this = getThis();
1581: int zep, syp, len;
1582: char error_string[128];
1583:
1584: if (!this) {
1585: RETURN_FALSE;
1586: }
1587:
1588: ZIP_FROM_OBJECT(intern, this);
1589:
1590: zip_error_get(intern, &zep, &syp);
1591:
1592: len = zip_error_to_str(error_string, 128, zep, syp);
1593: RETVAL_STRINGL(error_string, len, 1);
1594: }
1595: /* }}} */
1596:
1597: /* {{{ proto bool ZipArchive::createEmptyDir(string dirname)
1598: Returns the index of the entry named filename in the archive */
1599: static ZIPARCHIVE_METHOD(addEmptyDir)
1600: {
1601: struct zip *intern;
1602: zval *this = getThis();
1603: char *dirname;
1604: int dirname_len;
1605: int idx;
1606: struct zip_stat sb;
1607: char *s;
1608:
1609: if (!this) {
1610: RETURN_FALSE;
1611: }
1612:
1613: ZIP_FROM_OBJECT(intern, this);
1614:
1615: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
1616: &dirname, &dirname_len) == FAILURE) {
1617: return;
1618: }
1619:
1620: if (dirname_len<1) {
1621: RETURN_FALSE;
1622: }
1623:
1624: if (dirname[dirname_len-1] != '/') {
1625: s=(char *)emalloc(dirname_len+2);
1626: strcpy(s, dirname);
1627: s[dirname_len] = '/';
1628: s[dirname_len+1] = '\0';
1629: } else {
1630: s = dirname;
1631: }
1632:
1633: idx = zip_stat(intern, s, 0, &sb);
1634: if (idx >= 0) {
1635: RETVAL_FALSE;
1636: } else {
1637: if (zip_add_dir(intern, (const char *)s) == -1) {
1638: RETVAL_FALSE;
1639: }
1640: RETVAL_TRUE;
1641: }
1642:
1643: if (s != dirname) {
1644: efree(s);
1645: }
1646: }
1647: /* }}} */
1648:
1649: static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
1650: {
1651: struct zip *intern;
1652: zval *this = getThis();
1653: char *pattern;
1654: char *path = NULL;
1655: char *remove_path = NULL;
1656: char *add_path = NULL;
1.1.1.4 misho 1657: int pattern_len, add_path_len = 0, remove_path_len = 0, path_len = 0;
1.1 misho 1658: long remove_all_path = 0;
1659: long flags = 0;
1660: zval *options = NULL;
1661: int found;
1662:
1663: if (!this) {
1664: RETURN_FALSE;
1665: }
1666:
1667: ZIP_FROM_OBJECT(intern, this);
1668: /* 1 == glob, 2==pcre */
1669: if (type == 1) {
1.1.1.2 misho 1670: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la",
1.1 misho 1671: &pattern, &pattern_len, &flags, &options) == FAILURE) {
1672: return;
1673: }
1674: } else {
1.1.1.2 misho 1675: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa",
1.1 misho 1676: &pattern, &pattern_len, &path, &path_len, &options) == FAILURE) {
1677: return;
1678: }
1679: }
1680:
1681: if (pattern_len == 0) {
1682: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as pattern");
1683: RETURN_FALSE;
1684: }
1685: if (options && (php_zip_parse_options(options, &remove_all_path, &remove_path, &remove_path_len,
1686: &add_path, &add_path_len TSRMLS_CC) < 0)) {
1687: RETURN_FALSE;
1688: }
1689:
1690: if (remove_path && remove_path_len > 1 && (remove_path[strlen(remove_path) - 1] == '/' ||
1691: remove_path[strlen(remove_path) - 1] == '\\')) {
1692: remove_path[strlen(remove_path) - 1] = '\0';
1693: }
1694:
1695: if (type == 1) {
1696: found = php_zip_glob(pattern, pattern_len, flags, return_value TSRMLS_CC);
1697: } else {
1698: found = php_zip_pcre(pattern, pattern_len, path, path_len, return_value TSRMLS_CC);
1699: }
1700:
1701: if (found > 0) {
1702: int i;
1703: zval **zval_file = NULL;
1704:
1705: for (i = 0; i < found; i++) {
1706: char *file, *file_stripped, *entry_name;
1707: size_t entry_name_len, file_stripped_len;
1708: char entry_name_buf[MAXPATHLEN];
1709: char *basename = NULL;
1710:
1711: if (zend_hash_index_find(Z_ARRVAL_P(return_value), i, (void **) &zval_file) == SUCCESS) {
1712: file = Z_STRVAL_PP(zval_file);
1713: if (remove_all_path) {
1714: php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0,
1715: &basename, (size_t *)&file_stripped_len TSRMLS_CC);
1716: file_stripped = basename;
1717: } else if (remove_path && strstr(Z_STRVAL_PP(zval_file), remove_path) != NULL) {
1718: file_stripped = Z_STRVAL_PP(zval_file) + remove_path_len + 1;
1719: file_stripped_len = Z_STRLEN_PP(zval_file) - remove_path_len - 1;
1720: } else {
1721: file_stripped = Z_STRVAL_PP(zval_file);
1722: file_stripped_len = Z_STRLEN_PP(zval_file);
1723: }
1724:
1725: if (add_path) {
1726: if ((add_path_len + file_stripped_len) > MAXPATHLEN) {
1727: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Entry name too long (max: %d, %ld given)",
1728: MAXPATHLEN - 1, (add_path_len + file_stripped_len));
1729: zval_dtor(return_value);
1730: RETURN_FALSE;
1731: }
1732:
1733: snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped);
1734: entry_name = entry_name_buf;
1735: entry_name_len = strlen(entry_name);
1736: } else {
1737: entry_name = Z_STRVAL_PP(zval_file);
1738: entry_name_len = Z_STRLEN_PP(zval_file);
1739: }
1740: if (basename) {
1741: efree(basename);
1742: basename = NULL;
1743: }
1744: if (php_zip_add_file(intern, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file),
1745: entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) {
1746: zval_dtor(return_value);
1747: RETURN_FALSE;
1748: }
1749: }
1750: }
1751: }
1752: }
1753: /* }}} */
1754:
1755: /* {{{ proto bool ZipArchive::addGlob(string pattern[,int flags [, array options]])
1756: Add files matching the glob pattern. See php's glob for the pattern syntax. */
1757: static ZIPARCHIVE_METHOD(addGlob)
1758: {
1759: php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1760: }
1761: /* }}} */
1762:
1763: /* {{{ proto bool ZipArchive::addPattern(string pattern[, string path [, array options]])
1764: Add files matching the pcre pattern. See php's pcre for the pattern syntax. */
1765: static ZIPARCHIVE_METHOD(addPattern)
1766: {
1767: php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
1768: }
1769: /* }}} */
1770:
1771: /* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
1772: Add a file in a Zip archive using its path and the name to use. */
1773: static ZIPARCHIVE_METHOD(addFile)
1774: {
1775: struct zip *intern;
1776: zval *this = getThis();
1777: char *filename;
1778: int filename_len;
1779: char *entry_name = NULL;
1780: int entry_name_len = 0;
1781: long offset_start = 0, offset_len = 0;
1782:
1783: if (!this) {
1784: RETURN_FALSE;
1785: }
1786:
1787: ZIP_FROM_OBJECT(intern, this);
1788:
1.1.1.2 misho 1789: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sll",
1.1 misho 1790: &filename, &filename_len, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
1791: return;
1792: }
1793:
1794: if (filename_len == 0) {
1795: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as filename");
1796: RETURN_FALSE;
1797: }
1798:
1799: if (entry_name_len == 0) {
1800: entry_name = filename;
1801: entry_name_len = filename_len;
1802: }
1803:
1804: if (php_zip_add_file(intern, filename, filename_len,
1805: entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) {
1806: RETURN_FALSE;
1807: } else {
1808: RETURN_TRUE;
1809: }
1810: }
1811: /* }}} */
1812:
1813: /* {{{ proto bool ZipArchive::addFromString(string name, string content)
1814: Add a file using content and the entry name */
1815: static ZIPARCHIVE_METHOD(addFromString)
1816: {
1817: struct zip *intern;
1818: zval *this = getThis();
1819: char *buffer, *name;
1820: int buffer_len, name_len;
1821: ze_zip_object *ze_obj;
1822: struct zip_source *zs;
1823: int pos = 0;
1824: int cur_idx;
1825:
1826: if (!this) {
1827: RETURN_FALSE;
1828: }
1829:
1830: ZIP_FROM_OBJECT(intern, this);
1831:
1832: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
1833: &name, &name_len, &buffer, &buffer_len) == FAILURE) {
1834: return;
1835: }
1836:
1837: ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
1838: if (ze_obj->buffers_cnt) {
1839: ze_obj->buffers = (char **)erealloc(ze_obj->buffers, sizeof(char *) * (ze_obj->buffers_cnt+1));
1840: pos = ze_obj->buffers_cnt++;
1841: } else {
1842: ze_obj->buffers = (char **)emalloc(sizeof(char *));
1843: ze_obj->buffers_cnt++;
1844: pos = 0;
1845: }
1846: ze_obj->buffers[pos] = (char *)emalloc(buffer_len + 1);
1847: memcpy(ze_obj->buffers[pos], buffer, buffer_len + 1);
1848:
1849: zs = zip_source_buffer(intern, ze_obj->buffers[pos], buffer_len, 0);
1850:
1851: if (zs == NULL) {
1852: RETURN_FALSE;
1853: }
1854:
1855: cur_idx = zip_name_locate(intern, (const char *)name, 0);
1856: /* TODO: fix _zip_replace */
1857: if (cur_idx >= 0) {
1858: if (zip_delete(intern, cur_idx) == -1) {
1.1.1.5 ! misho 1859: goto fail;
1.1 misho 1860: }
1861: }
1862:
1.1.1.5 ! misho 1863: if (zip_add(intern, name, zs) != -1) {
1.1 misho 1864: RETURN_TRUE;
1865: }
1.1.1.5 ! misho 1866: fail:
! 1867: zip_source_free(zs);
! 1868: RETURN_FALSE;
1.1 misho 1869: }
1870: /* }}} */
1871:
1872: /* {{{ proto array ZipArchive::statName(string filename[, int flags])
1873: Returns the information about a the zip entry filename */
1874: static ZIPARCHIVE_METHOD(statName)
1875: {
1876: struct zip *intern;
1877: zval *this = getThis();
1878: char *name;
1879: int name_len;
1880: long flags = 0;
1881: struct zip_stat sb;
1882:
1883: if (!this) {
1884: RETURN_FALSE;
1885: }
1886:
1887: ZIP_FROM_OBJECT(intern, this);
1888:
1.1.1.2 misho 1889: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
1.1 misho 1890: &name, &name_len, &flags) == FAILURE) {
1891: return;
1892: }
1893:
1894: PHP_ZIP_STAT_PATH(intern, name, name_len, flags, sb);
1895:
1896: RETURN_SB(&sb);
1897: }
1898: /* }}} */
1899:
1900: /* {{{ proto resource ZipArchive::statIndex(int index[, int flags])
1901: Returns the zip entry informations using its index */
1902: static ZIPARCHIVE_METHOD(statIndex)
1903: {
1904: struct zip *intern;
1905: zval *this = getThis();
1906: long index, flags = 0;
1907:
1908: struct zip_stat sb;
1909:
1910: if (!this) {
1911: RETURN_FALSE;
1912: }
1913:
1914: ZIP_FROM_OBJECT(intern, this);
1915:
1916: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
1917: &index, &flags) == FAILURE) {
1918: return;
1919: }
1920:
1921: if (zip_stat_index(intern, index, flags, &sb) != 0) {
1922: RETURN_FALSE;
1923: }
1924: RETURN_SB(&sb);
1925: }
1926: /* }}} */
1927:
1928: /* {{{ proto int ZipArchive::locateName(string filename[, int flags])
1929: Returns the index of the entry named filename in the archive */
1930: static ZIPARCHIVE_METHOD(locateName)
1931: {
1932: struct zip *intern;
1933: zval *this = getThis();
1934: char *name;
1935: int name_len;
1936: long flags = 0;
1937: long idx = -1;
1938:
1939: if (!this) {
1940: RETURN_FALSE;
1941: }
1942:
1943: ZIP_FROM_OBJECT(intern, this);
1944:
1.1.1.2 misho 1945: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
1.1 misho 1946: &name, &name_len, &flags) == FAILURE) {
1947: return;
1948: }
1949: if (name_len<1) {
1950: RETURN_FALSE;
1951: }
1952:
1953: idx = (long)zip_name_locate(intern, (const char *)name, flags);
1954:
1955: if (idx >= 0) {
1956: RETURN_LONG(idx);
1957: } else {
1958: RETURN_FALSE;
1959: }
1960: }
1961: /* }}} */
1962:
1963: /* {{{ proto string ZipArchive::getNameIndex(int index [, int flags])
1964: Returns the name of the file at position index */
1965: static ZIPARCHIVE_METHOD(getNameIndex)
1966: {
1967: struct zip *intern;
1968: zval *this = getThis();
1969: const char *name;
1970: long flags = 0, index = 0;
1971:
1972: if (!this) {
1973: RETURN_FALSE;
1974: }
1975:
1976: ZIP_FROM_OBJECT(intern, this);
1977:
1978: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
1979: &index, &flags) == FAILURE) {
1980: return;
1981: }
1982:
1983: name = zip_get_name(intern, (int) index, flags);
1984:
1985: if (name) {
1986: RETVAL_STRING((char *)name, 1);
1987: } else {
1988: RETURN_FALSE;
1989: }
1990: }
1991: /* }}} */
1992:
1993: /* {{{ proto bool ZipArchive::setArchiveComment(string comment)
1994: Set or remove (NULL/'') the comment of the archive */
1995: static ZIPARCHIVE_METHOD(setArchiveComment)
1996: {
1997: struct zip *intern;
1998: zval *this = getThis();
1999: int comment_len;
2000: char * comment;
2001:
2002: if (!this) {
2003: RETURN_FALSE;
2004: }
2005:
2006: ZIP_FROM_OBJECT(intern, this);
2007:
2008: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &comment, &comment_len) == FAILURE) {
2009: return;
2010: }
2011: if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) {
2012: RETURN_FALSE;
2013: } else {
2014: RETURN_TRUE;
2015: }
2016: }
2017: /* }}} */
2018:
2019: /* {{{ proto string ZipArchive::getArchiveComment([int flags])
2020: Returns the comment of an entry using its index */
2021: static ZIPARCHIVE_METHOD(getArchiveComment)
2022: {
2023: struct zip *intern;
2024: zval *this = getThis();
2025: long flags = 0;
2026: const char * comment;
2027: int comment_len = 0;
2028:
2029: if (!this) {
2030: RETURN_FALSE;
2031: }
2032:
2033: ZIP_FROM_OBJECT(intern, this);
2034:
2035: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) {
2036: return;
2037: }
2038:
2039: comment = zip_get_archive_comment(intern, &comment_len, (int)flags);
2040: if(comment==NULL) {
2041: RETURN_FALSE;
2042: }
2043: RETURN_STRINGL((char *)comment, (long)comment_len, 1);
2044: }
2045: /* }}} */
2046:
2047: /* {{{ proto bool ZipArchive::setCommentName(string name, string comment)
2048: Set or remove (NULL/'') the comment of an entry using its Name */
2049: static ZIPARCHIVE_METHOD(setCommentName)
2050: {
2051: struct zip *intern;
2052: zval *this = getThis();
2053: int comment_len, name_len;
2054: char * comment, *name;
2055: int idx;
2056:
2057: if (!this) {
2058: RETURN_FALSE;
2059: }
2060:
2061: ZIP_FROM_OBJECT(intern, this);
2062:
2063: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
2064: &name, &name_len, &comment, &comment_len) == FAILURE) {
2065: return;
2066: }
2067:
2068: if (name_len < 1) {
2069: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name");
2070: }
2071:
2072: idx = zip_name_locate(intern, name, 0);
2073: if (idx < 0) {
2074: RETURN_FALSE;
2075: }
2076: PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len);
2077: }
2078: /* }}} */
2079:
2080: /* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment)
2081: Set or remove (NULL/'') the comment of an entry using its index */
2082: static ZIPARCHIVE_METHOD(setCommentIndex)
2083: {
2084: struct zip *intern;
2085: zval *this = getThis();
2086: long index;
2087: int comment_len;
2088: char * comment;
2089: struct zip_stat sb;
2090:
2091: if (!this) {
2092: RETURN_FALSE;
2093: }
2094:
2095: ZIP_FROM_OBJECT(intern, this);
2096:
2097: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls",
2098: &index, &comment, &comment_len) == FAILURE) {
2099: return;
2100: }
2101:
2102: PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2103: PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len);
2104: }
2105: /* }}} */
2106:
2107: /* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
2108: Returns the comment of an entry using its name */
2109: static ZIPARCHIVE_METHOD(getCommentName)
2110: {
2111: struct zip *intern;
2112: zval *this = getThis();
2113: int name_len, idx;
2114: long flags = 0;
2115: int comment_len = 0;
2116: const char * comment;
2117: char *name;
2118:
2119: if (!this) {
2120: RETURN_FALSE;
2121: }
2122:
2123: ZIP_FROM_OBJECT(intern, this);
2124:
2125: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
2126: &name, &name_len, &flags) == FAILURE) {
2127: return;
2128: }
2129: if (name_len < 1) {
2130: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name");
2131: RETURN_FALSE;
2132: }
2133:
2134: idx = zip_name_locate(intern, name, 0);
2135: if (idx < 0) {
2136: RETURN_FALSE;
2137: }
2138:
2139: comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags);
2140: RETURN_STRINGL((char *)comment, (long)comment_len, 1);
2141: }
2142: /* }}} */
2143:
2144: /* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags])
2145: Returns the comment of an entry using its index */
2146: static ZIPARCHIVE_METHOD(getCommentIndex)
2147: {
2148: struct zip *intern;
2149: zval *this = getThis();
2150: long index, flags = 0;
2151: const char * comment;
2152: int comment_len = 0;
2153: struct zip_stat sb;
2154:
2155: if (!this) {
2156: RETURN_FALSE;
2157: }
2158:
2159: ZIP_FROM_OBJECT(intern, this);
2160:
2161: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
2162: &index, &flags) == FAILURE) {
2163: return;
2164: }
2165:
2166: PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2167: comment = zip_get_file_comment(intern, index, &comment_len, (int)flags);
2168: RETURN_STRINGL((char *)comment, (long)comment_len, 1);
2169: }
2170: /* }}} */
2171:
2172: /* {{{ proto bool ZipArchive::deleteIndex(int index)
2173: Delete a file using its index */
2174: static ZIPARCHIVE_METHOD(deleteIndex)
2175: {
2176: struct zip *intern;
2177: zval *this = getThis();
2178: long index;
2179:
2180: if (!this) {
2181: RETURN_FALSE;
2182: }
2183:
2184: ZIP_FROM_OBJECT(intern, this);
2185:
2186: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
2187: return;
2188: }
2189:
2190: if (index < 0) {
2191: RETURN_FALSE;
2192: }
2193:
2194: if (zip_delete(intern, index) < 0) {
2195: RETURN_FALSE;
2196: }
2197:
2198: RETURN_TRUE;
2199: }
2200: /* }}} */
2201:
2202: /* {{{ proto bool ZipArchive::deleteName(string name)
2203: Delete a file using its index */
2204: static ZIPARCHIVE_METHOD(deleteName)
2205: {
2206: struct zip *intern;
2207: zval *this = getThis();
2208: int name_len;
2209: char *name;
2210: struct zip_stat sb;
2211:
2212: if (!this) {
2213: RETURN_FALSE;
2214: }
2215:
2216: ZIP_FROM_OBJECT(intern, this);
2217:
2218: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
2219: return;
2220: }
2221: if (name_len < 1) {
2222: RETURN_FALSE;
2223: }
2224:
2225: PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
2226: if (zip_delete(intern, sb.index)) {
2227: RETURN_FALSE;
2228: }
2229: RETURN_TRUE;
2230: }
2231: /* }}} */
2232:
2233: /* {{{ proto bool ZipArchive::renameIndex(int index, string new_name)
2234: Rename an entry selected by its index to new_name */
2235: static ZIPARCHIVE_METHOD(renameIndex)
2236: {
2237: struct zip *intern;
2238: zval *this = getThis();
2239:
2240: char *new_name;
2241: int new_name_len;
2242: long index;
2243:
2244: if (!this) {
2245: RETURN_FALSE;
2246: }
2247:
2248: ZIP_FROM_OBJECT(intern, this);
2249:
2250: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &index, &new_name, &new_name_len) == FAILURE) {
2251: return;
2252: }
2253:
2254: if (index < 0) {
2255: RETURN_FALSE;
2256: }
2257:
2258: if (new_name_len < 1) {
2259: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as new entry name");
2260: RETURN_FALSE;
2261: }
2262: if (zip_rename(intern, index, (const char *)new_name) != 0) {
2263: RETURN_FALSE;
2264: }
2265: RETURN_TRUE;
2266: }
2267: /* }}} */
2268:
2269: /* {{{ proto bool ZipArchive::renameName(string name, string new_name)
2270: Rename an entry selected by its name to new_name */
2271: static ZIPARCHIVE_METHOD(renameName)
2272: {
2273: struct zip *intern;
2274: zval *this = getThis();
2275: struct zip_stat sb;
2276: char *name, *new_name;
2277: int name_len, new_name_len;
2278:
2279: if (!this) {
2280: RETURN_FALSE;
2281: }
2282:
2283: ZIP_FROM_OBJECT(intern, this);
2284:
2285: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) {
2286: return;
2287: }
2288:
2289: if (new_name_len < 1) {
2290: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as new entry name");
2291: RETURN_FALSE;
2292: }
2293:
2294: PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
2295:
2296: if (zip_rename(intern, sb.index, (const char *)new_name)) {
2297: RETURN_FALSE;
2298: }
2299: RETURN_TRUE;
2300: }
2301: /* }}} */
2302:
2303: /* {{{ proto bool ZipArchive::unchangeIndex(int index)
2304: Changes to the file at position index are reverted */
2305: static ZIPARCHIVE_METHOD(unchangeIndex)
2306: {
2307: struct zip *intern;
2308: zval *this = getThis();
2309: long index;
2310:
2311: if (!this) {
2312: RETURN_FALSE;
2313: }
2314:
2315: ZIP_FROM_OBJECT(intern, this);
2316:
2317: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
2318: return;
2319: }
2320:
2321: if (index < 0) {
2322: RETURN_FALSE;
2323: }
2324:
2325: if (zip_unchange(intern, index) != 0) {
2326: RETURN_FALSE;
2327: } else {
2328: RETURN_TRUE;
2329: }
2330: }
2331: /* }}} */
2332:
2333: /* {{{ proto bool ZipArchive::unchangeName(string name)
2334: Changes to the file named 'name' are reverted */
2335: static ZIPARCHIVE_METHOD(unchangeName)
2336: {
2337: struct zip *intern;
2338: zval *this = getThis();
2339: struct zip_stat sb;
2340: char *name;
2341: int name_len;
2342:
2343: if (!this) {
2344: RETURN_FALSE;
2345: }
2346:
2347: ZIP_FROM_OBJECT(intern, this);
2348:
2349: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
2350: return;
2351: }
2352:
2353: if (name_len < 1) {
2354: RETURN_FALSE;
2355: }
2356:
2357: PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
2358:
2359: if (zip_unchange(intern, sb.index) != 0) {
2360: RETURN_FALSE;
2361: } else {
2362: RETURN_TRUE;
2363: }
2364: }
2365: /* }}} */
2366:
2367: /* {{{ proto bool ZipArchive::unchangeAll()
2368: All changes to files and global information in archive are reverted */
2369: static ZIPARCHIVE_METHOD(unchangeAll)
2370: {
2371: struct zip *intern;
2372: zval *this = getThis();
2373:
2374: if (!this) {
2375: RETURN_FALSE;
2376: }
2377:
2378: ZIP_FROM_OBJECT(intern, this);
2379:
2380: if (zip_unchange_all(intern) != 0) {
2381: RETURN_FALSE;
2382: } else {
2383: RETURN_TRUE;
2384: }
2385: }
2386: /* }}} */
2387:
2388: /* {{{ proto bool ZipArchive::unchangeArchive()
2389: Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */
2390: static ZIPARCHIVE_METHOD(unchangeArchive)
2391: {
2392: struct zip *intern;
2393: zval *this = getThis();
2394:
2395: if (!this) {
2396: RETURN_FALSE;
2397: }
2398:
2399: ZIP_FROM_OBJECT(intern, this);
2400:
2401: if (zip_unchange_archive(intern) != 0) {
2402: RETURN_FALSE;
2403: } else {
2404: RETURN_TRUE;
2405: }
2406: }
2407: /* }}} */
2408:
2409: /* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files])
2410: Extract one or more file from a zip archive */
2411: /* TODO:
2412: * - allow index or array of indeces
2413: * - replace path
2414: * - patterns
2415: */
2416: static ZIPARCHIVE_METHOD(extractTo)
2417: {
2418: struct zip *intern;
2419:
2420: zval *this = getThis();
2421: zval *zval_files = NULL;
2422: zval **zval_file = NULL;
2423: php_stream_statbuf ssb;
2424: char *pathto;
2425: int pathto_len;
2426: int ret, i;
2427:
2428: int nelems;
2429:
2430: if (!this) {
2431: RETURN_FALSE;
2432: }
2433:
2434: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &pathto, &pathto_len, &zval_files) == FAILURE) {
2435: return;
2436: }
2437:
2438: if (pathto_len < 1) {
2439: RETURN_FALSE;
2440: }
2441:
2442: if (php_stream_stat_path_ex(pathto, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
1.1.1.2 misho 2443: ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL);
2444: if (!ret) {
2445: RETURN_FALSE;
2446: }
1.1 misho 2447: }
2448:
2449: ZIP_FROM_OBJECT(intern, this);
2450: if (zval_files && (Z_TYPE_P(zval_files) != IS_NULL)) {
2451: switch (Z_TYPE_P(zval_files)) {
2452: case IS_STRING:
2453: if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files) TSRMLS_CC)) {
2454: RETURN_FALSE;
2455: }
2456: break;
2457: case IS_ARRAY:
2458: nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files));
2459: if (nelems == 0 ) {
2460: RETURN_FALSE;
2461: }
2462: for (i = 0; i < nelems; i++) {
2463: if (zend_hash_index_find(Z_ARRVAL_P(zval_files), i, (void **) &zval_file) == SUCCESS) {
2464: switch (Z_TYPE_PP(zval_file)) {
2465: case IS_LONG:
2466: break;
2467: case IS_STRING:
2468: if (!php_zip_extract_file(intern, pathto, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file) TSRMLS_CC)) {
2469: RETURN_FALSE;
2470: }
2471: break;
2472: }
2473: }
2474: }
2475: break;
2476: case IS_LONG:
2477: default:
2478: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument, expect string or array of strings");
2479: break;
2480: }
2481: } else {
1.1.1.2 misho 2482: /* Extract all files */
2483: int filecount = zip_get_num_files(intern);
1.1 misho 2484:
1.1.1.2 misho 2485: if (filecount == -1) {
2486: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal archive");
2487: RETURN_FALSE;
2488: }
1.1 misho 2489:
1.1.1.2 misho 2490: for (i = 0; i < filecount; i++) {
2491: char *file = (char*)zip_get_name(intern, i, ZIP_FL_UNCHANGED);
2492: if (!php_zip_extract_file(intern, pathto, file, strlen(file) TSRMLS_CC)) {
2493: RETURN_FALSE;
2494: }
1.1 misho 2495: }
1.1.1.2 misho 2496: }
1.1 misho 2497: RETURN_TRUE;
2498: }
2499: /* }}} */
2500:
2501: static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
2502: {
2503: struct zip *intern;
2504: zval *this = getThis();
2505:
2506: struct zip_stat sb;
2507: struct zip_file *zf;
2508:
2509: char *filename;
2510: int filename_len;
2511: long index = -1;
2512: long flags = 0;
2513: long len = 0;
2514:
2515: char *buffer;
2516: int n = 0;
2517:
2518: if (!this) {
2519: RETURN_FALSE;
2520: }
2521:
2522: ZIP_FROM_OBJECT(intern, this);
2523:
2524: if (type == 1) {
1.1.1.2 misho 2525: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
1.1 misho 2526: return;
2527: }
2528: PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb);
2529: } else {
2530: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &index, &len, &flags) == FAILURE) {
2531: return;
2532: }
2533: PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2534: }
2535:
2536: if (sb.size < 1) {
2537: RETURN_EMPTY_STRING();
2538: }
2539:
2540: if (len < 1) {
2541: len = sb.size;
2542: }
2543: if (index >= 0) {
2544: zf = zip_fopen_index(intern, index, flags);
2545: } else {
2546: zf = zip_fopen(intern, filename, flags);
2547: }
2548:
2549: if (zf == NULL) {
2550: RETURN_FALSE;
2551: }
2552:
2553: buffer = safe_emalloc(len, 1, 2);
2554: n = zip_fread(zf, buffer, len);
2555: if (n < 1) {
2556: efree(buffer);
2557: RETURN_EMPTY_STRING();
2558: }
2559:
2560: zip_fclose(zf);
2561: buffer[n] = 0;
2562: RETURN_STRINGL(buffer, n, 0);
2563: }
2564: /* }}} */
2565:
2566: /* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]])
2567: get the contents of an entry using its name */
2568: static ZIPARCHIVE_METHOD(getFromName)
2569: {
2570: php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2571: }
2572: /* }}} */
2573:
2574: /* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]])
2575: get the contents of an entry using its index */
2576: static ZIPARCHIVE_METHOD(getFromIndex)
2577: {
2578: php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2579: }
2580: /* }}} */
2581:
2582: /* {{{ proto resource ZipArchive::getStream(string entryname)
2583: get a stream for an entry using its name */
2584: static ZIPARCHIVE_METHOD(getStream)
2585: {
2586: struct zip *intern;
2587: zval *this = getThis();
2588: struct zip_stat sb;
2589: char *filename;
2590: int filename_len;
2591: char *mode = "rb";
2592: php_stream *stream;
2593: ze_zip_object *obj;
2594:
2595: if (!this) {
2596: RETURN_FALSE;
2597: }
2598:
2599: ZIP_FROM_OBJECT(intern, this);
2600:
1.1.1.2 misho 2601: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
1.1 misho 2602: return;
2603: }
2604:
2605: if (zip_stat(intern, filename, 0, &sb) != 0) {
2606: RETURN_FALSE;
2607: }
2608:
2609: obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
2610:
2611: stream = php_stream_zip_open(obj->filename, filename, mode STREAMS_CC TSRMLS_CC);
2612: if (stream) {
2613: php_stream_to_zval(stream, return_value);
2614: }
2615: }
2616: /* }}} */
2617:
2618: /* {{{ arginfo */
2619: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
2620: ZEND_ARG_INFO(0, filename)
2621: ZEND_ARG_INFO(0, flags)
2622: ZEND_END_ARG_INFO()
2623:
2624: ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
2625: ZEND_END_ARG_INFO()
2626:
2627: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addemptydir, 0, 0, 1)
2628: ZEND_ARG_INFO(0, dirname)
2629: ZEND_END_ARG_INFO()
2630:
2631: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addglob, 0, 0, 1)
2632: ZEND_ARG_INFO(0, pattern)
2633: ZEND_ARG_INFO(0, flags)
2634: ZEND_ARG_INFO(0, options)
2635: ZEND_END_ARG_INFO()
2636:
2637: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addpattern, 0, 0, 1)
2638: ZEND_ARG_INFO(0, pattern)
2639: ZEND_ARG_INFO(0, path)
2640: ZEND_ARG_INFO(0, options)
2641: ZEND_END_ARG_INFO()
2642:
2643: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfile, 0, 0, 1)
2644: ZEND_ARG_INFO(0, filepath)
2645: ZEND_ARG_INFO(0, entryname)
2646: ZEND_ARG_INFO(0, start)
2647: ZEND_ARG_INFO(0, length)
2648: ZEND_END_ARG_INFO()
2649:
2650: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfromstring, 0, 0, 2)
2651: ZEND_ARG_INFO(0, name)
2652: ZEND_ARG_INFO(0, content)
2653: ZEND_END_ARG_INFO()
2654:
2655: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statname, 0, 0, 1)
2656: ZEND_ARG_INFO(0, filename)
2657: ZEND_ARG_INFO(0, flags)
2658: ZEND_END_ARG_INFO()
2659:
2660: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statindex, 0, 0, 1)
2661: ZEND_ARG_INFO(0, index)
2662: ZEND_ARG_INFO(0, flags)
2663: ZEND_END_ARG_INFO()
2664:
2665: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setarchivecomment, 0, 0, 1)
2666: ZEND_ARG_INFO(0, comment)
2667: ZEND_END_ARG_INFO()
2668:
2669: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentindex, 0, 0, 2)
2670: ZEND_ARG_INFO(0, index)
2671: ZEND_ARG_INFO(0, comment)
2672: ZEND_END_ARG_INFO()
2673:
2674: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentname, 0, 0, 1)
2675: ZEND_ARG_INFO(0, name)
2676: ZEND_ARG_INFO(0, flags)
2677: ZEND_END_ARG_INFO()
2678:
2679: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentindex, 0, 0, 1)
2680: ZEND_ARG_INFO(0, index)
2681: ZEND_ARG_INFO(0, flags)
2682: ZEND_END_ARG_INFO()
2683:
2684: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renameindex, 0, 0, 2)
2685: ZEND_ARG_INFO(0, index)
2686: ZEND_ARG_INFO(0, new_name)
2687: ZEND_END_ARG_INFO()
2688:
2689: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renamename, 0, 0, 2)
2690: ZEND_ARG_INFO(0, name)
2691: ZEND_ARG_INFO(0, new_name)
2692: ZEND_END_ARG_INFO()
2693:
2694: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangeindex, 0, 0, 1)
2695: ZEND_ARG_INFO(0, index)
2696: ZEND_END_ARG_INFO()
2697:
2698: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangename, 0, 0, 1)
2699: ZEND_ARG_INFO(0, name)
2700: ZEND_END_ARG_INFO()
2701:
2702: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_extractto, 0, 0, 1)
2703: ZEND_ARG_INFO(0, pathto)
2704: ZEND_ARG_INFO(0, files)
2705: ZEND_END_ARG_INFO()
2706:
2707: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromname, 0, 0, 1)
2708: ZEND_ARG_INFO(0, entryname)
2709: ZEND_ARG_INFO(0, len)
2710: ZEND_ARG_INFO(0, flags)
2711: ZEND_END_ARG_INFO()
2712:
2713: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromindex, 0, 0, 1)
2714: ZEND_ARG_INFO(0, index)
2715: ZEND_ARG_INFO(0, len)
2716: ZEND_ARG_INFO(0, flags)
2717: ZEND_END_ARG_INFO()
2718:
2719: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getarchivecomment, 0, 0, 0)
2720: ZEND_ARG_INFO(0, flags)
2721: ZEND_END_ARG_INFO()
2722:
2723: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentname, 0, 0, 2)
2724: ZEND_ARG_INFO(0, name)
2725: ZEND_ARG_INFO(0, comment)
2726: ZEND_END_ARG_INFO()
2727:
2728: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getstream, 0, 0, 1)
2729: ZEND_ARG_INFO(0, entryname)
2730: ZEND_END_ARG_INFO()
2731: /* }}} */
2732:
2733: /* {{{ ze_zip_object_class_functions */
2734: static const zend_function_entry zip_class_functions[] = {
2735: ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
2736: ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2737: ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2738: ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
2739: ZIPARCHIVE_ME(addFromString, arginfo_ziparchive_addfromstring, ZEND_ACC_PUBLIC)
2740: ZIPARCHIVE_ME(addFile, arginfo_ziparchive_addfile, ZEND_ACC_PUBLIC)
2741: ZIPARCHIVE_ME(addGlob, arginfo_ziparchive_addglob, ZEND_ACC_PUBLIC)
2742: ZIPARCHIVE_ME(addPattern, arginfo_ziparchive_addpattern, ZEND_ACC_PUBLIC)
2743: ZIPARCHIVE_ME(renameIndex, arginfo_ziparchive_renameindex, ZEND_ACC_PUBLIC)
2744: ZIPARCHIVE_ME(renameName, arginfo_ziparchive_renamename, ZEND_ACC_PUBLIC)
2745: ZIPARCHIVE_ME(setArchiveComment, arginfo_ziparchive_setarchivecomment, ZEND_ACC_PUBLIC)
2746: ZIPARCHIVE_ME(getArchiveComment, arginfo_ziparchive_getarchivecomment, ZEND_ACC_PUBLIC)
2747: ZIPARCHIVE_ME(setCommentIndex, arginfo_ziparchive_setcommentindex, ZEND_ACC_PUBLIC)
2748: ZIPARCHIVE_ME(setCommentName, arginfo_ziparchive_setcommentname, ZEND_ACC_PUBLIC)
2749: ZIPARCHIVE_ME(getCommentIndex, arginfo_ziparchive_getcommentindex, ZEND_ACC_PUBLIC)
2750: ZIPARCHIVE_ME(getCommentName, arginfo_ziparchive_getcommentname, ZEND_ACC_PUBLIC)
2751: ZIPARCHIVE_ME(deleteIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
2752: ZIPARCHIVE_ME(deleteName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
2753: ZIPARCHIVE_ME(statName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
2754: ZIPARCHIVE_ME(statIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
2755: ZIPARCHIVE_ME(locateName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
2756: ZIPARCHIVE_ME(getNameIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
2757: ZIPARCHIVE_ME(unchangeArchive, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2758: ZIPARCHIVE_ME(unchangeAll, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2759: ZIPARCHIVE_ME(unchangeIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
2760: ZIPARCHIVE_ME(unchangeName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
2761: ZIPARCHIVE_ME(extractTo, arginfo_ziparchive_extractto, ZEND_ACC_PUBLIC)
2762: ZIPARCHIVE_ME(getFromName, arginfo_ziparchive_getfromname, ZEND_ACC_PUBLIC)
2763: ZIPARCHIVE_ME(getFromIndex, arginfo_ziparchive_getfromindex, ZEND_ACC_PUBLIC)
2764: ZIPARCHIVE_ME(getStream, arginfo_ziparchive_getstream, ZEND_ACC_PUBLIC)
2765: {NULL, NULL, NULL}
2766: };
2767: /* }}} */
2768: #endif
2769:
2770: /* {{{ PHP_MINIT_FUNCTION */
2771: static PHP_MINIT_FUNCTION(zip)
2772: {
2773: #ifdef PHP_ZIP_USE_OO
2774: zend_class_entry ce;
2775:
2776: memcpy(&zip_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2777: zip_object_handlers.clone_obj = NULL;
2778: zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
2779:
2780: zip_object_handlers.get_properties = php_zip_get_properties;
2781: zip_object_handlers.read_property = php_zip_read_property;
2782: zip_object_handlers.has_property = php_zip_has_property;
2783:
2784: INIT_CLASS_ENTRY(ce, "ZipArchive", zip_class_functions);
2785: ce.create_object = php_zip_object_new;
2786: zip_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
2787:
2788: zend_hash_init(&zip_prop_handlers, 0, NULL, NULL, 1);
2789: php_zip_register_prop_handler(&zip_prop_handlers, "status", php_zip_status, NULL, NULL, IS_LONG TSRMLS_CC);
2790: php_zip_register_prop_handler(&zip_prop_handlers, "statusSys", php_zip_status_sys, NULL, NULL, IS_LONG TSRMLS_CC);
2791: php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, NULL, IS_LONG TSRMLS_CC);
2792: php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING TSRMLS_CC);
2793: php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING TSRMLS_CC);
2794:
2795: REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE);
2796: REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL);
2797: REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS);
2798: REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE);
2799:
2800: REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE);
2801: REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
2802: REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
2803: REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
2804: REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
2805: REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
2806: REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK);
2807: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_1", ZIP_CM_REDUCE_1);
2808: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_2", ZIP_CM_REDUCE_2);
2809: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_3", ZIP_CM_REDUCE_3);
2810: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_4", ZIP_CM_REDUCE_4);
2811: REGISTER_ZIP_CLASS_CONST_LONG("CM_IMPLODE", ZIP_CM_IMPLODE);
2812: REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE", ZIP_CM_DEFLATE);
2813: REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE64", ZIP_CM_DEFLATE64);
2814: REGISTER_ZIP_CLASS_CONST_LONG("CM_PKWARE_IMPLODE", ZIP_CM_PKWARE_IMPLODE);
2815: REGISTER_ZIP_CLASS_CONST_LONG("CM_BZIP2", ZIP_CM_BZIP2);
2816: REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA);
2817: REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE);
2818: REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77);
2819: REGISTER_ZIP_CLASS_CONST_LONG("CM_WAVPACK", ZIP_CM_WAVPACK);
2820: REGISTER_ZIP_CLASS_CONST_LONG("CM_PPMD", ZIP_CM_PPMD);
2821:
2822: /* Error code */
2823: REGISTER_ZIP_CLASS_CONST_LONG("ER_OK", ZIP_ER_OK); /* N No error */
2824: REGISTER_ZIP_CLASS_CONST_LONG("ER_MULTIDISK", ZIP_ER_MULTIDISK); /* N Multi-disk zip archives not supported */
2825: REGISTER_ZIP_CLASS_CONST_LONG("ER_RENAME", ZIP_ER_RENAME); /* S Renaming temporary file failed */
2826: REGISTER_ZIP_CLASS_CONST_LONG("ER_CLOSE", ZIP_ER_CLOSE); /* S Closing zip archive failed */
2827: REGISTER_ZIP_CLASS_CONST_LONG("ER_SEEK", ZIP_ER_SEEK); /* S Seek error */
2828: REGISTER_ZIP_CLASS_CONST_LONG("ER_READ", ZIP_ER_READ); /* S Read error */
2829: REGISTER_ZIP_CLASS_CONST_LONG("ER_WRITE", ZIP_ER_WRITE); /* S Write error */
2830: REGISTER_ZIP_CLASS_CONST_LONG("ER_CRC", ZIP_ER_CRC); /* N CRC error */
2831: REGISTER_ZIP_CLASS_CONST_LONG("ER_ZIPCLOSED", ZIP_ER_ZIPCLOSED); /* N Containing zip archive was closed */
2832: REGISTER_ZIP_CLASS_CONST_LONG("ER_NOENT", ZIP_ER_NOENT); /* N No such file */
2833: REGISTER_ZIP_CLASS_CONST_LONG("ER_EXISTS", ZIP_ER_EXISTS); /* N File already exists */
2834: REGISTER_ZIP_CLASS_CONST_LONG("ER_OPEN", ZIP_ER_OPEN); /* S Can't open file */
2835: REGISTER_ZIP_CLASS_CONST_LONG("ER_TMPOPEN", ZIP_ER_TMPOPEN); /* S Failure to create temporary file */
2836: REGISTER_ZIP_CLASS_CONST_LONG("ER_ZLIB", ZIP_ER_ZLIB); /* Z Zlib error */
2837: REGISTER_ZIP_CLASS_CONST_LONG("ER_MEMORY", ZIP_ER_MEMORY); /* N Malloc failure */
2838: REGISTER_ZIP_CLASS_CONST_LONG("ER_CHANGED", ZIP_ER_CHANGED); /* N Entry has been changed */
2839: REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPNOTSUPP", ZIP_ER_COMPNOTSUPP);/* N Compression method not supported */
2840: REGISTER_ZIP_CLASS_CONST_LONG("ER_EOF", ZIP_ER_EOF); /* N Premature EOF */
2841: REGISTER_ZIP_CLASS_CONST_LONG("ER_INVAL", ZIP_ER_INVAL); /* N Invalid argument */
2842: REGISTER_ZIP_CLASS_CONST_LONG("ER_NOZIP", ZIP_ER_NOZIP); /* N Not a zip archive */
2843: REGISTER_ZIP_CLASS_CONST_LONG("ER_INTERNAL", ZIP_ER_INTERNAL); /* N Internal error */
2844: REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS", ZIP_ER_INCONS); /* N Zip archive inconsistent */
2845: REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE", ZIP_ER_REMOVE); /* S Can't remove file */
2846: REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED", ZIP_ER_DELETED); /* N Entry has been deleted */
2847:
2848: php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper TSRMLS_CC);
2849: #endif
2850:
2851: le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number);
2852: le_zip_entry = zend_register_list_destructors_ex(php_zip_free_entry, NULL, le_zip_entry_name, module_number);
2853:
2854: return SUCCESS;
2855: }
2856: /* }}} */
2857:
2858: /* {{{ PHP_MSHUTDOWN_FUNCTION
2859: */
2860: static PHP_MSHUTDOWN_FUNCTION(zip)
2861: {
2862: #ifdef PHP_ZIP_USE_OO
2863: zend_hash_destroy(&zip_prop_handlers);
2864: php_unregister_url_stream_wrapper("zip" TSRMLS_CC);
2865: #endif
2866: return SUCCESS;
2867: }
2868: /* }}} */
2869:
2870: /* {{{ PHP_MINFO_FUNCTION
2871: */
2872: static PHP_MINFO_FUNCTION(zip)
2873: {
2874: php_info_print_table_start();
2875:
2876: php_info_print_table_row(2, "Zip", "enabled");
1.1.1.5 ! misho 2877: php_info_print_table_row(2, "Extension Version","$Id: abc21c7f1559e732dba6db94c69ecf638ae5fa3f $");
1.1 misho 2878: php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING);
1.1.1.3 misho 2879: php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
1.1 misho 2880:
2881: php_info_print_table_end();
2882: }
2883: /* }}} */
2884:
2885: /*
2886: * Local variables:
2887: * tab-width: 4
2888: * c-basic-offset: 4
2889: * End:
2890: * vim600: noet sw=4 ts=4 fdm=marker
2891: * vim<600: noet sw=4 ts=4
2892: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>