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