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>