Annotation of embedaddon/php/ext/zip/php_zip.c, revision 1.1.1.4

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>