Annotation of embedaddon/php/ext/zip/php_zip.c, revision 1.1.1.4
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 misho 5: | Copyright (c) 1997-2013 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.4 ! misho 19: /* $Id: d7bd5f49e62be1c7d06e510b3bf330b83fe65b28 $ */
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 (IS_SLASH(path[0])) {
106: return path + 1;
107: }
108:
109: if (path_len < 1 || path == NULL) {
110: return NULL;
111: }
112:
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);
1540: ze_obj->filename_len = filename_len;
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) {
1859: RETURN_FALSE;
1860: }
1861: }
1862:
1863: if (zip_add(intern, name, zs) == -1) {
1864: RETURN_FALSE;
1865: } else {
1866: RETURN_TRUE;
1867: }
1868: }
1869: /* }}} */
1870:
1871: /* {{{ proto array ZipArchive::statName(string filename[, int flags])
1872: Returns the information about a the zip entry filename */
1873: static ZIPARCHIVE_METHOD(statName)
1874: {
1875: struct zip *intern;
1876: zval *this = getThis();
1877: char *name;
1878: int name_len;
1879: long flags = 0;
1880: struct zip_stat sb;
1881:
1882: if (!this) {
1883: RETURN_FALSE;
1884: }
1885:
1886: ZIP_FROM_OBJECT(intern, this);
1887:
1.1.1.2 misho 1888: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
1.1 misho 1889: &name, &name_len, &flags) == FAILURE) {
1890: return;
1891: }
1892:
1893: PHP_ZIP_STAT_PATH(intern, name, name_len, flags, sb);
1894:
1895: RETURN_SB(&sb);
1896: }
1897: /* }}} */
1898:
1899: /* {{{ proto resource ZipArchive::statIndex(int index[, int flags])
1900: Returns the zip entry informations using its index */
1901: static ZIPARCHIVE_METHOD(statIndex)
1902: {
1903: struct zip *intern;
1904: zval *this = getThis();
1905: long index, flags = 0;
1906:
1907: struct zip_stat sb;
1908:
1909: if (!this) {
1910: RETURN_FALSE;
1911: }
1912:
1913: ZIP_FROM_OBJECT(intern, this);
1914:
1915: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
1916: &index, &flags) == FAILURE) {
1917: return;
1918: }
1919:
1920: if (zip_stat_index(intern, index, flags, &sb) != 0) {
1921: RETURN_FALSE;
1922: }
1923: RETURN_SB(&sb);
1924: }
1925: /* }}} */
1926:
1927: /* {{{ proto int ZipArchive::locateName(string filename[, int flags])
1928: Returns the index of the entry named filename in the archive */
1929: static ZIPARCHIVE_METHOD(locateName)
1930: {
1931: struct zip *intern;
1932: zval *this = getThis();
1933: char *name;
1934: int name_len;
1935: long flags = 0;
1936: long idx = -1;
1937:
1938: if (!this) {
1939: RETURN_FALSE;
1940: }
1941:
1942: ZIP_FROM_OBJECT(intern, this);
1943:
1.1.1.2 misho 1944: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
1.1 misho 1945: &name, &name_len, &flags) == FAILURE) {
1946: return;
1947: }
1948: if (name_len<1) {
1949: RETURN_FALSE;
1950: }
1951:
1952: idx = (long)zip_name_locate(intern, (const char *)name, flags);
1953:
1954: if (idx >= 0) {
1955: RETURN_LONG(idx);
1956: } else {
1957: RETURN_FALSE;
1958: }
1959: }
1960: /* }}} */
1961:
1962: /* {{{ proto string ZipArchive::getNameIndex(int index [, int flags])
1963: Returns the name of the file at position index */
1964: static ZIPARCHIVE_METHOD(getNameIndex)
1965: {
1966: struct zip *intern;
1967: zval *this = getThis();
1968: const char *name;
1969: long flags = 0, index = 0;
1970:
1971: if (!this) {
1972: RETURN_FALSE;
1973: }
1974:
1975: ZIP_FROM_OBJECT(intern, this);
1976:
1977: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
1978: &index, &flags) == FAILURE) {
1979: return;
1980: }
1981:
1982: name = zip_get_name(intern, (int) index, flags);
1983:
1984: if (name) {
1985: RETVAL_STRING((char *)name, 1);
1986: } else {
1987: RETURN_FALSE;
1988: }
1989: }
1990: /* }}} */
1991:
1992: /* {{{ proto bool ZipArchive::setArchiveComment(string comment)
1993: Set or remove (NULL/'') the comment of the archive */
1994: static ZIPARCHIVE_METHOD(setArchiveComment)
1995: {
1996: struct zip *intern;
1997: zval *this = getThis();
1998: int comment_len;
1999: char * comment;
2000:
2001: if (!this) {
2002: RETURN_FALSE;
2003: }
2004:
2005: ZIP_FROM_OBJECT(intern, this);
2006:
2007: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &comment, &comment_len) == FAILURE) {
2008: return;
2009: }
2010: if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) {
2011: RETURN_FALSE;
2012: } else {
2013: RETURN_TRUE;
2014: }
2015: }
2016: /* }}} */
2017:
2018: /* {{{ proto string ZipArchive::getArchiveComment([int flags])
2019: Returns the comment of an entry using its index */
2020: static ZIPARCHIVE_METHOD(getArchiveComment)
2021: {
2022: struct zip *intern;
2023: zval *this = getThis();
2024: long flags = 0;
2025: const char * comment;
2026: int comment_len = 0;
2027:
2028: if (!this) {
2029: RETURN_FALSE;
2030: }
2031:
2032: ZIP_FROM_OBJECT(intern, this);
2033:
2034: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) {
2035: return;
2036: }
2037:
2038: comment = zip_get_archive_comment(intern, &comment_len, (int)flags);
2039: if(comment==NULL) {
2040: RETURN_FALSE;
2041: }
2042: RETURN_STRINGL((char *)comment, (long)comment_len, 1);
2043: }
2044: /* }}} */
2045:
2046: /* {{{ proto bool ZipArchive::setCommentName(string name, string comment)
2047: Set or remove (NULL/'') the comment of an entry using its Name */
2048: static ZIPARCHIVE_METHOD(setCommentName)
2049: {
2050: struct zip *intern;
2051: zval *this = getThis();
2052: int comment_len, name_len;
2053: char * comment, *name;
2054: int idx;
2055:
2056: if (!this) {
2057: RETURN_FALSE;
2058: }
2059:
2060: ZIP_FROM_OBJECT(intern, this);
2061:
2062: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
2063: &name, &name_len, &comment, &comment_len) == FAILURE) {
2064: return;
2065: }
2066:
2067: if (name_len < 1) {
2068: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name");
2069: }
2070:
2071: idx = zip_name_locate(intern, name, 0);
2072: if (idx < 0) {
2073: RETURN_FALSE;
2074: }
2075: PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len);
2076: }
2077: /* }}} */
2078:
2079: /* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment)
2080: Set or remove (NULL/'') the comment of an entry using its index */
2081: static ZIPARCHIVE_METHOD(setCommentIndex)
2082: {
2083: struct zip *intern;
2084: zval *this = getThis();
2085: long index;
2086: int comment_len;
2087: char * comment;
2088: struct zip_stat sb;
2089:
2090: if (!this) {
2091: RETURN_FALSE;
2092: }
2093:
2094: ZIP_FROM_OBJECT(intern, this);
2095:
2096: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls",
2097: &index, &comment, &comment_len) == FAILURE) {
2098: return;
2099: }
2100:
2101: PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2102: PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len);
2103: }
2104: /* }}} */
2105:
2106: /* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
2107: Returns the comment of an entry using its name */
2108: static ZIPARCHIVE_METHOD(getCommentName)
2109: {
2110: struct zip *intern;
2111: zval *this = getThis();
2112: int name_len, idx;
2113: long flags = 0;
2114: int comment_len = 0;
2115: const char * comment;
2116: char *name;
2117:
2118: if (!this) {
2119: RETURN_FALSE;
2120: }
2121:
2122: ZIP_FROM_OBJECT(intern, this);
2123:
2124: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
2125: &name, &name_len, &flags) == FAILURE) {
2126: return;
2127: }
2128: if (name_len < 1) {
2129: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name");
2130: RETURN_FALSE;
2131: }
2132:
2133: idx = zip_name_locate(intern, name, 0);
2134: if (idx < 0) {
2135: RETURN_FALSE;
2136: }
2137:
2138: comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags);
2139: RETURN_STRINGL((char *)comment, (long)comment_len, 1);
2140: }
2141: /* }}} */
2142:
2143: /* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags])
2144: Returns the comment of an entry using its index */
2145: static ZIPARCHIVE_METHOD(getCommentIndex)
2146: {
2147: struct zip *intern;
2148: zval *this = getThis();
2149: long index, flags = 0;
2150: const char * comment;
2151: int comment_len = 0;
2152: struct zip_stat sb;
2153:
2154: if (!this) {
2155: RETURN_FALSE;
2156: }
2157:
2158: ZIP_FROM_OBJECT(intern, this);
2159:
2160: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
2161: &index, &flags) == FAILURE) {
2162: return;
2163: }
2164:
2165: PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2166: comment = zip_get_file_comment(intern, index, &comment_len, (int)flags);
2167: RETURN_STRINGL((char *)comment, (long)comment_len, 1);
2168: }
2169: /* }}} */
2170:
2171: /* {{{ proto bool ZipArchive::deleteIndex(int index)
2172: Delete a file using its index */
2173: static ZIPARCHIVE_METHOD(deleteIndex)
2174: {
2175: struct zip *intern;
2176: zval *this = getThis();
2177: long index;
2178:
2179: if (!this) {
2180: RETURN_FALSE;
2181: }
2182:
2183: ZIP_FROM_OBJECT(intern, this);
2184:
2185: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
2186: return;
2187: }
2188:
2189: if (index < 0) {
2190: RETURN_FALSE;
2191: }
2192:
2193: if (zip_delete(intern, index) < 0) {
2194: RETURN_FALSE;
2195: }
2196:
2197: RETURN_TRUE;
2198: }
2199: /* }}} */
2200:
2201: /* {{{ proto bool ZipArchive::deleteName(string name)
2202: Delete a file using its index */
2203: static ZIPARCHIVE_METHOD(deleteName)
2204: {
2205: struct zip *intern;
2206: zval *this = getThis();
2207: int name_len;
2208: char *name;
2209: struct zip_stat sb;
2210:
2211: if (!this) {
2212: RETURN_FALSE;
2213: }
2214:
2215: ZIP_FROM_OBJECT(intern, this);
2216:
2217: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
2218: return;
2219: }
2220: if (name_len < 1) {
2221: RETURN_FALSE;
2222: }
2223:
2224: PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
2225: if (zip_delete(intern, sb.index)) {
2226: RETURN_FALSE;
2227: }
2228: RETURN_TRUE;
2229: }
2230: /* }}} */
2231:
2232: /* {{{ proto bool ZipArchive::renameIndex(int index, string new_name)
2233: Rename an entry selected by its index to new_name */
2234: static ZIPARCHIVE_METHOD(renameIndex)
2235: {
2236: struct zip *intern;
2237: zval *this = getThis();
2238:
2239: char *new_name;
2240: int new_name_len;
2241: long index;
2242:
2243: if (!this) {
2244: RETURN_FALSE;
2245: }
2246:
2247: ZIP_FROM_OBJECT(intern, this);
2248:
2249: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &index, &new_name, &new_name_len) == FAILURE) {
2250: return;
2251: }
2252:
2253: if (index < 0) {
2254: RETURN_FALSE;
2255: }
2256:
2257: if (new_name_len < 1) {
2258: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as new entry name");
2259: RETURN_FALSE;
2260: }
2261: if (zip_rename(intern, index, (const char *)new_name) != 0) {
2262: RETURN_FALSE;
2263: }
2264: RETURN_TRUE;
2265: }
2266: /* }}} */
2267:
2268: /* {{{ proto bool ZipArchive::renameName(string name, string new_name)
2269: Rename an entry selected by its name to new_name */
2270: static ZIPARCHIVE_METHOD(renameName)
2271: {
2272: struct zip *intern;
2273: zval *this = getThis();
2274: struct zip_stat sb;
2275: char *name, *new_name;
2276: int name_len, new_name_len;
2277:
2278: if (!this) {
2279: RETURN_FALSE;
2280: }
2281:
2282: ZIP_FROM_OBJECT(intern, this);
2283:
2284: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) {
2285: return;
2286: }
2287:
2288: if (new_name_len < 1) {
2289: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as new entry name");
2290: RETURN_FALSE;
2291: }
2292:
2293: PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
2294:
2295: if (zip_rename(intern, sb.index, (const char *)new_name)) {
2296: RETURN_FALSE;
2297: }
2298: RETURN_TRUE;
2299: }
2300: /* }}} */
2301:
2302: /* {{{ proto bool ZipArchive::unchangeIndex(int index)
2303: Changes to the file at position index are reverted */
2304: static ZIPARCHIVE_METHOD(unchangeIndex)
2305: {
2306: struct zip *intern;
2307: zval *this = getThis();
2308: long index;
2309:
2310: if (!this) {
2311: RETURN_FALSE;
2312: }
2313:
2314: ZIP_FROM_OBJECT(intern, this);
2315:
2316: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
2317: return;
2318: }
2319:
2320: if (index < 0) {
2321: RETURN_FALSE;
2322: }
2323:
2324: if (zip_unchange(intern, index) != 0) {
2325: RETURN_FALSE;
2326: } else {
2327: RETURN_TRUE;
2328: }
2329: }
2330: /* }}} */
2331:
2332: /* {{{ proto bool ZipArchive::unchangeName(string name)
2333: Changes to the file named 'name' are reverted */
2334: static ZIPARCHIVE_METHOD(unchangeName)
2335: {
2336: struct zip *intern;
2337: zval *this = getThis();
2338: struct zip_stat sb;
2339: char *name;
2340: int name_len;
2341:
2342: if (!this) {
2343: RETURN_FALSE;
2344: }
2345:
2346: ZIP_FROM_OBJECT(intern, this);
2347:
2348: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
2349: return;
2350: }
2351:
2352: if (name_len < 1) {
2353: RETURN_FALSE;
2354: }
2355:
2356: PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
2357:
2358: if (zip_unchange(intern, sb.index) != 0) {
2359: RETURN_FALSE;
2360: } else {
2361: RETURN_TRUE;
2362: }
2363: }
2364: /* }}} */
2365:
2366: /* {{{ proto bool ZipArchive::unchangeAll()
2367: All changes to files and global information in archive are reverted */
2368: static ZIPARCHIVE_METHOD(unchangeAll)
2369: {
2370: struct zip *intern;
2371: zval *this = getThis();
2372:
2373: if (!this) {
2374: RETURN_FALSE;
2375: }
2376:
2377: ZIP_FROM_OBJECT(intern, this);
2378:
2379: if (zip_unchange_all(intern) != 0) {
2380: RETURN_FALSE;
2381: } else {
2382: RETURN_TRUE;
2383: }
2384: }
2385: /* }}} */
2386:
2387: /* {{{ proto bool ZipArchive::unchangeArchive()
2388: Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */
2389: static ZIPARCHIVE_METHOD(unchangeArchive)
2390: {
2391: struct zip *intern;
2392: zval *this = getThis();
2393:
2394: if (!this) {
2395: RETURN_FALSE;
2396: }
2397:
2398: ZIP_FROM_OBJECT(intern, this);
2399:
2400: if (zip_unchange_archive(intern) != 0) {
2401: RETURN_FALSE;
2402: } else {
2403: RETURN_TRUE;
2404: }
2405: }
2406: /* }}} */
2407:
2408: /* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files])
2409: Extract one or more file from a zip archive */
2410: /* TODO:
2411: * - allow index or array of indeces
2412: * - replace path
2413: * - patterns
2414: */
2415: static ZIPARCHIVE_METHOD(extractTo)
2416: {
2417: struct zip *intern;
2418:
2419: zval *this = getThis();
2420: zval *zval_files = NULL;
2421: zval **zval_file = NULL;
2422: php_stream_statbuf ssb;
2423: char *pathto;
2424: int pathto_len;
2425: int ret, i;
2426:
2427: int nelems;
2428:
2429: if (!this) {
2430: RETURN_FALSE;
2431: }
2432:
2433: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &pathto, &pathto_len, &zval_files) == FAILURE) {
2434: return;
2435: }
2436:
2437: if (pathto_len < 1) {
2438: RETURN_FALSE;
2439: }
2440:
2441: if (php_stream_stat_path_ex(pathto, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
1.1.1.2 misho 2442: ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL);
2443: if (!ret) {
2444: RETURN_FALSE;
2445: }
1.1 misho 2446: }
2447:
2448: ZIP_FROM_OBJECT(intern, this);
2449: if (zval_files && (Z_TYPE_P(zval_files) != IS_NULL)) {
2450: switch (Z_TYPE_P(zval_files)) {
2451: case IS_STRING:
2452: if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files) TSRMLS_CC)) {
2453: RETURN_FALSE;
2454: }
2455: break;
2456: case IS_ARRAY:
2457: nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files));
2458: if (nelems == 0 ) {
2459: RETURN_FALSE;
2460: }
2461: for (i = 0; i < nelems; i++) {
2462: if (zend_hash_index_find(Z_ARRVAL_P(zval_files), i, (void **) &zval_file) == SUCCESS) {
2463: switch (Z_TYPE_PP(zval_file)) {
2464: case IS_LONG:
2465: break;
2466: case IS_STRING:
2467: if (!php_zip_extract_file(intern, pathto, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file) TSRMLS_CC)) {
2468: RETURN_FALSE;
2469: }
2470: break;
2471: }
2472: }
2473: }
2474: break;
2475: case IS_LONG:
2476: default:
2477: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument, expect string or array of strings");
2478: break;
2479: }
2480: } else {
1.1.1.2 misho 2481: /* Extract all files */
2482: int filecount = zip_get_num_files(intern);
1.1 misho 2483:
1.1.1.2 misho 2484: if (filecount == -1) {
2485: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal archive");
2486: RETURN_FALSE;
2487: }
1.1 misho 2488:
1.1.1.2 misho 2489: for (i = 0; i < filecount; i++) {
2490: char *file = (char*)zip_get_name(intern, i, ZIP_FL_UNCHANGED);
2491: if (!php_zip_extract_file(intern, pathto, file, strlen(file) TSRMLS_CC)) {
2492: RETURN_FALSE;
2493: }
1.1 misho 2494: }
1.1.1.2 misho 2495: }
1.1 misho 2496: RETURN_TRUE;
2497: }
2498: /* }}} */
2499:
2500: static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
2501: {
2502: struct zip *intern;
2503: zval *this = getThis();
2504:
2505: struct zip_stat sb;
2506: struct zip_file *zf;
2507:
2508: char *filename;
2509: int filename_len;
2510: long index = -1;
2511: long flags = 0;
2512: long len = 0;
2513:
2514: char *buffer;
2515: int n = 0;
2516:
2517: if (!this) {
2518: RETURN_FALSE;
2519: }
2520:
2521: ZIP_FROM_OBJECT(intern, this);
2522:
2523: if (type == 1) {
1.1.1.2 misho 2524: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
1.1 misho 2525: return;
2526: }
2527: PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb);
2528: } else {
2529: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &index, &len, &flags) == FAILURE) {
2530: return;
2531: }
2532: PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
2533: }
2534:
2535: if (sb.size < 1) {
2536: RETURN_EMPTY_STRING();
2537: }
2538:
2539: if (len < 1) {
2540: len = sb.size;
2541: }
2542: if (index >= 0) {
2543: zf = zip_fopen_index(intern, index, flags);
2544: } else {
2545: zf = zip_fopen(intern, filename, flags);
2546: }
2547:
2548: if (zf == NULL) {
2549: RETURN_FALSE;
2550: }
2551:
2552: buffer = safe_emalloc(len, 1, 2);
2553: n = zip_fread(zf, buffer, len);
2554: if (n < 1) {
2555: efree(buffer);
2556: RETURN_EMPTY_STRING();
2557: }
2558:
2559: zip_fclose(zf);
2560: buffer[n] = 0;
2561: RETURN_STRINGL(buffer, n, 0);
2562: }
2563: /* }}} */
2564:
2565: /* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]])
2566: get the contents of an entry using its name */
2567: static ZIPARCHIVE_METHOD(getFromName)
2568: {
2569: php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2570: }
2571: /* }}} */
2572:
2573: /* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]])
2574: get the contents of an entry using its index */
2575: static ZIPARCHIVE_METHOD(getFromIndex)
2576: {
2577: php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2578: }
2579: /* }}} */
2580:
2581: /* {{{ proto resource ZipArchive::getStream(string entryname)
2582: get a stream for an entry using its name */
2583: static ZIPARCHIVE_METHOD(getStream)
2584: {
2585: struct zip *intern;
2586: zval *this = getThis();
2587: struct zip_stat sb;
2588: char *filename;
2589: int filename_len;
2590: char *mode = "rb";
2591: php_stream *stream;
2592: ze_zip_object *obj;
2593:
2594: if (!this) {
2595: RETURN_FALSE;
2596: }
2597:
2598: ZIP_FROM_OBJECT(intern, this);
2599:
1.1.1.2 misho 2600: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
1.1 misho 2601: return;
2602: }
2603:
2604: if (zip_stat(intern, filename, 0, &sb) != 0) {
2605: RETURN_FALSE;
2606: }
2607:
2608: obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
2609:
2610: stream = php_stream_zip_open(obj->filename, filename, mode STREAMS_CC TSRMLS_CC);
2611: if (stream) {
2612: php_stream_to_zval(stream, return_value);
2613: }
2614: }
2615: /* }}} */
2616:
2617: /* {{{ arginfo */
2618: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
2619: ZEND_ARG_INFO(0, filename)
2620: ZEND_ARG_INFO(0, flags)
2621: ZEND_END_ARG_INFO()
2622:
2623: ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
2624: ZEND_END_ARG_INFO()
2625:
2626: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addemptydir, 0, 0, 1)
2627: ZEND_ARG_INFO(0, dirname)
2628: ZEND_END_ARG_INFO()
2629:
2630: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addglob, 0, 0, 1)
2631: ZEND_ARG_INFO(0, pattern)
2632: ZEND_ARG_INFO(0, flags)
2633: ZEND_ARG_INFO(0, options)
2634: ZEND_END_ARG_INFO()
2635:
2636: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addpattern, 0, 0, 1)
2637: ZEND_ARG_INFO(0, pattern)
2638: ZEND_ARG_INFO(0, path)
2639: ZEND_ARG_INFO(0, options)
2640: ZEND_END_ARG_INFO()
2641:
2642: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfile, 0, 0, 1)
2643: ZEND_ARG_INFO(0, filepath)
2644: ZEND_ARG_INFO(0, entryname)
2645: ZEND_ARG_INFO(0, start)
2646: ZEND_ARG_INFO(0, length)
2647: ZEND_END_ARG_INFO()
2648:
2649: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfromstring, 0, 0, 2)
2650: ZEND_ARG_INFO(0, name)
2651: ZEND_ARG_INFO(0, content)
2652: ZEND_END_ARG_INFO()
2653:
2654: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statname, 0, 0, 1)
2655: ZEND_ARG_INFO(0, filename)
2656: ZEND_ARG_INFO(0, flags)
2657: ZEND_END_ARG_INFO()
2658:
2659: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statindex, 0, 0, 1)
2660: ZEND_ARG_INFO(0, index)
2661: ZEND_ARG_INFO(0, flags)
2662: ZEND_END_ARG_INFO()
2663:
2664: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setarchivecomment, 0, 0, 1)
2665: ZEND_ARG_INFO(0, comment)
2666: ZEND_END_ARG_INFO()
2667:
2668: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentindex, 0, 0, 2)
2669: ZEND_ARG_INFO(0, index)
2670: ZEND_ARG_INFO(0, comment)
2671: ZEND_END_ARG_INFO()
2672:
2673: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentname, 0, 0, 1)
2674: ZEND_ARG_INFO(0, name)
2675: ZEND_ARG_INFO(0, flags)
2676: ZEND_END_ARG_INFO()
2677:
2678: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentindex, 0, 0, 1)
2679: ZEND_ARG_INFO(0, index)
2680: ZEND_ARG_INFO(0, flags)
2681: ZEND_END_ARG_INFO()
2682:
2683: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renameindex, 0, 0, 2)
2684: ZEND_ARG_INFO(0, index)
2685: ZEND_ARG_INFO(0, new_name)
2686: ZEND_END_ARG_INFO()
2687:
2688: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renamename, 0, 0, 2)
2689: ZEND_ARG_INFO(0, name)
2690: ZEND_ARG_INFO(0, new_name)
2691: ZEND_END_ARG_INFO()
2692:
2693: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangeindex, 0, 0, 1)
2694: ZEND_ARG_INFO(0, index)
2695: ZEND_END_ARG_INFO()
2696:
2697: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangename, 0, 0, 1)
2698: ZEND_ARG_INFO(0, name)
2699: ZEND_END_ARG_INFO()
2700:
2701: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_extractto, 0, 0, 1)
2702: ZEND_ARG_INFO(0, pathto)
2703: ZEND_ARG_INFO(0, files)
2704: ZEND_END_ARG_INFO()
2705:
2706: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromname, 0, 0, 1)
2707: ZEND_ARG_INFO(0, entryname)
2708: ZEND_ARG_INFO(0, len)
2709: ZEND_ARG_INFO(0, flags)
2710: ZEND_END_ARG_INFO()
2711:
2712: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromindex, 0, 0, 1)
2713: ZEND_ARG_INFO(0, index)
2714: ZEND_ARG_INFO(0, len)
2715: ZEND_ARG_INFO(0, flags)
2716: ZEND_END_ARG_INFO()
2717:
2718: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getarchivecomment, 0, 0, 0)
2719: ZEND_ARG_INFO(0, flags)
2720: ZEND_END_ARG_INFO()
2721:
2722: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentname, 0, 0, 2)
2723: ZEND_ARG_INFO(0, name)
2724: ZEND_ARG_INFO(0, comment)
2725: ZEND_END_ARG_INFO()
2726:
2727: ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getstream, 0, 0, 1)
2728: ZEND_ARG_INFO(0, entryname)
2729: ZEND_END_ARG_INFO()
2730: /* }}} */
2731:
2732: /* {{{ ze_zip_object_class_functions */
2733: static const zend_function_entry zip_class_functions[] = {
2734: ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
2735: ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2736: ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2737: ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
2738: ZIPARCHIVE_ME(addFromString, arginfo_ziparchive_addfromstring, ZEND_ACC_PUBLIC)
2739: ZIPARCHIVE_ME(addFile, arginfo_ziparchive_addfile, ZEND_ACC_PUBLIC)
2740: ZIPARCHIVE_ME(addGlob, arginfo_ziparchive_addglob, ZEND_ACC_PUBLIC)
2741: ZIPARCHIVE_ME(addPattern, arginfo_ziparchive_addpattern, ZEND_ACC_PUBLIC)
2742: ZIPARCHIVE_ME(renameIndex, arginfo_ziparchive_renameindex, ZEND_ACC_PUBLIC)
2743: ZIPARCHIVE_ME(renameName, arginfo_ziparchive_renamename, ZEND_ACC_PUBLIC)
2744: ZIPARCHIVE_ME(setArchiveComment, arginfo_ziparchive_setarchivecomment, ZEND_ACC_PUBLIC)
2745: ZIPARCHIVE_ME(getArchiveComment, arginfo_ziparchive_getarchivecomment, ZEND_ACC_PUBLIC)
2746: ZIPARCHIVE_ME(setCommentIndex, arginfo_ziparchive_setcommentindex, ZEND_ACC_PUBLIC)
2747: ZIPARCHIVE_ME(setCommentName, arginfo_ziparchive_setcommentname, ZEND_ACC_PUBLIC)
2748: ZIPARCHIVE_ME(getCommentIndex, arginfo_ziparchive_getcommentindex, ZEND_ACC_PUBLIC)
2749: ZIPARCHIVE_ME(getCommentName, arginfo_ziparchive_getcommentname, ZEND_ACC_PUBLIC)
2750: ZIPARCHIVE_ME(deleteIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
2751: ZIPARCHIVE_ME(deleteName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
2752: ZIPARCHIVE_ME(statName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
2753: ZIPARCHIVE_ME(statIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
2754: ZIPARCHIVE_ME(locateName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
2755: ZIPARCHIVE_ME(getNameIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
2756: ZIPARCHIVE_ME(unchangeArchive, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2757: ZIPARCHIVE_ME(unchangeAll, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
2758: ZIPARCHIVE_ME(unchangeIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
2759: ZIPARCHIVE_ME(unchangeName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
2760: ZIPARCHIVE_ME(extractTo, arginfo_ziparchive_extractto, ZEND_ACC_PUBLIC)
2761: ZIPARCHIVE_ME(getFromName, arginfo_ziparchive_getfromname, ZEND_ACC_PUBLIC)
2762: ZIPARCHIVE_ME(getFromIndex, arginfo_ziparchive_getfromindex, ZEND_ACC_PUBLIC)
2763: ZIPARCHIVE_ME(getStream, arginfo_ziparchive_getstream, ZEND_ACC_PUBLIC)
2764: {NULL, NULL, NULL}
2765: };
2766: /* }}} */
2767: #endif
2768:
2769: /* {{{ PHP_MINIT_FUNCTION */
2770: static PHP_MINIT_FUNCTION(zip)
2771: {
2772: #ifdef PHP_ZIP_USE_OO
2773: zend_class_entry ce;
2774:
2775: memcpy(&zip_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2776: zip_object_handlers.clone_obj = NULL;
2777: zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
2778:
2779: zip_object_handlers.get_properties = php_zip_get_properties;
2780: zip_object_handlers.read_property = php_zip_read_property;
2781: zip_object_handlers.has_property = php_zip_has_property;
2782:
2783: INIT_CLASS_ENTRY(ce, "ZipArchive", zip_class_functions);
2784: ce.create_object = php_zip_object_new;
2785: zip_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
2786:
2787: zend_hash_init(&zip_prop_handlers, 0, NULL, NULL, 1);
2788: php_zip_register_prop_handler(&zip_prop_handlers, "status", php_zip_status, NULL, NULL, IS_LONG TSRMLS_CC);
2789: php_zip_register_prop_handler(&zip_prop_handlers, "statusSys", php_zip_status_sys, NULL, NULL, IS_LONG TSRMLS_CC);
2790: php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, NULL, IS_LONG TSRMLS_CC);
2791: php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING TSRMLS_CC);
2792: php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING TSRMLS_CC);
2793:
2794: REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE);
2795: REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL);
2796: REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS);
2797: REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE);
2798:
2799: REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE);
2800: REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
2801: REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
2802: REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
2803: REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
2804: REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
2805: REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK);
2806: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_1", ZIP_CM_REDUCE_1);
2807: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_2", ZIP_CM_REDUCE_2);
2808: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_3", ZIP_CM_REDUCE_3);
2809: REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_4", ZIP_CM_REDUCE_4);
2810: REGISTER_ZIP_CLASS_CONST_LONG("CM_IMPLODE", ZIP_CM_IMPLODE);
2811: REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE", ZIP_CM_DEFLATE);
2812: REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE64", ZIP_CM_DEFLATE64);
2813: REGISTER_ZIP_CLASS_CONST_LONG("CM_PKWARE_IMPLODE", ZIP_CM_PKWARE_IMPLODE);
2814: REGISTER_ZIP_CLASS_CONST_LONG("CM_BZIP2", ZIP_CM_BZIP2);
2815: REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA);
2816: REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE);
2817: REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77);
2818: REGISTER_ZIP_CLASS_CONST_LONG("CM_WAVPACK", ZIP_CM_WAVPACK);
2819: REGISTER_ZIP_CLASS_CONST_LONG("CM_PPMD", ZIP_CM_PPMD);
2820:
2821: /* Error code */
2822: REGISTER_ZIP_CLASS_CONST_LONG("ER_OK", ZIP_ER_OK); /* N No error */
2823: REGISTER_ZIP_CLASS_CONST_LONG("ER_MULTIDISK", ZIP_ER_MULTIDISK); /* N Multi-disk zip archives not supported */
2824: REGISTER_ZIP_CLASS_CONST_LONG("ER_RENAME", ZIP_ER_RENAME); /* S Renaming temporary file failed */
2825: REGISTER_ZIP_CLASS_CONST_LONG("ER_CLOSE", ZIP_ER_CLOSE); /* S Closing zip archive failed */
2826: REGISTER_ZIP_CLASS_CONST_LONG("ER_SEEK", ZIP_ER_SEEK); /* S Seek error */
2827: REGISTER_ZIP_CLASS_CONST_LONG("ER_READ", ZIP_ER_READ); /* S Read error */
2828: REGISTER_ZIP_CLASS_CONST_LONG("ER_WRITE", ZIP_ER_WRITE); /* S Write error */
2829: REGISTER_ZIP_CLASS_CONST_LONG("ER_CRC", ZIP_ER_CRC); /* N CRC error */
2830: REGISTER_ZIP_CLASS_CONST_LONG("ER_ZIPCLOSED", ZIP_ER_ZIPCLOSED); /* N Containing zip archive was closed */
2831: REGISTER_ZIP_CLASS_CONST_LONG("ER_NOENT", ZIP_ER_NOENT); /* N No such file */
2832: REGISTER_ZIP_CLASS_CONST_LONG("ER_EXISTS", ZIP_ER_EXISTS); /* N File already exists */
2833: REGISTER_ZIP_CLASS_CONST_LONG("ER_OPEN", ZIP_ER_OPEN); /* S Can't open file */
2834: REGISTER_ZIP_CLASS_CONST_LONG("ER_TMPOPEN", ZIP_ER_TMPOPEN); /* S Failure to create temporary file */
2835: REGISTER_ZIP_CLASS_CONST_LONG("ER_ZLIB", ZIP_ER_ZLIB); /* Z Zlib error */
2836: REGISTER_ZIP_CLASS_CONST_LONG("ER_MEMORY", ZIP_ER_MEMORY); /* N Malloc failure */
2837: REGISTER_ZIP_CLASS_CONST_LONG("ER_CHANGED", ZIP_ER_CHANGED); /* N Entry has been changed */
2838: REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPNOTSUPP", ZIP_ER_COMPNOTSUPP);/* N Compression method not supported */
2839: REGISTER_ZIP_CLASS_CONST_LONG("ER_EOF", ZIP_ER_EOF); /* N Premature EOF */
2840: REGISTER_ZIP_CLASS_CONST_LONG("ER_INVAL", ZIP_ER_INVAL); /* N Invalid argument */
2841: REGISTER_ZIP_CLASS_CONST_LONG("ER_NOZIP", ZIP_ER_NOZIP); /* N Not a zip archive */
2842: REGISTER_ZIP_CLASS_CONST_LONG("ER_INTERNAL", ZIP_ER_INTERNAL); /* N Internal error */
2843: REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS", ZIP_ER_INCONS); /* N Zip archive inconsistent */
2844: REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE", ZIP_ER_REMOVE); /* S Can't remove file */
2845: REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED", ZIP_ER_DELETED); /* N Entry has been deleted */
2846:
2847: php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper TSRMLS_CC);
2848: #endif
2849:
2850: le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number);
2851: le_zip_entry = zend_register_list_destructors_ex(php_zip_free_entry, NULL, le_zip_entry_name, module_number);
2852:
2853: return SUCCESS;
2854: }
2855: /* }}} */
2856:
2857: /* {{{ PHP_MSHUTDOWN_FUNCTION
2858: */
2859: static PHP_MSHUTDOWN_FUNCTION(zip)
2860: {
2861: #ifdef PHP_ZIP_USE_OO
2862: zend_hash_destroy(&zip_prop_handlers);
2863: php_unregister_url_stream_wrapper("zip" TSRMLS_CC);
2864: #endif
2865: return SUCCESS;
2866: }
2867: /* }}} */
2868:
2869: /* {{{ PHP_MINFO_FUNCTION
2870: */
2871: static PHP_MINFO_FUNCTION(zip)
2872: {
2873: php_info_print_table_start();
2874:
2875: php_info_print_table_row(2, "Zip", "enabled");
1.1.1.4 ! misho 2876: php_info_print_table_row(2, "Extension Version","$Id: d7bd5f49e62be1c7d06e510b3bf330b83fe65b28 $");
1.1 misho 2877: php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING);
1.1.1.3 misho 2878: php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
1.1 misho 2879:
2880: php_info_print_table_end();
2881: }
2882: /* }}} */
2883:
2884: /*
2885: * Local variables:
2886: * tab-width: 4
2887: * c-basic-offset: 4
2888: * End:
2889: * vim600: noet sw=4 ts=4 fdm=marker
2890: * vim<600: noet sw=4 ts=4
2891: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>