Annotation of embedaddon/php/ext/phar/phar_object.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   +----------------------------------------------------------------------+
        !             3:   | phar php single-file executable PHP extension                        |
        !             4:   +----------------------------------------------------------------------+
        !             5:   | Copyright (c) 2005-2012 The PHP Group                                |
        !             6:   +----------------------------------------------------------------------+
        !             7:   | This source file is subject to version 3.01 of the PHP license,      |
        !             8:   | that is bundled with this package in the file LICENSE, and is        |
        !             9:   | available through the world-wide-web at the following url:           |
        !            10:   | http://www.php.net/license/3_01.txt.                                 |
        !            11:   | If you did not receive a copy of the PHP license and are unable to   |
        !            12:   | obtain it through the world-wide-web, please send a note to          |
        !            13:   | license@php.net so we can mail you a copy immediately.               |
        !            14:   +----------------------------------------------------------------------+
        !            15:   | Authors: Gregory Beaver <cellog@php.net>                             |
        !            16:   |          Marcus Boerger <helly@php.net>                              |
        !            17:   +----------------------------------------------------------------------+
        !            18: */
        !            19: 
        !            20: /* $Id: phar_object.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: #include "phar_internal.h"
        !            23: #include "func_interceptors.h"
        !            24: 
        !            25: static zend_class_entry *phar_ce_archive;
        !            26: static zend_class_entry *phar_ce_data;
        !            27: static zend_class_entry *phar_ce_PharException;
        !            28: 
        !            29: #if HAVE_SPL
        !            30: static zend_class_entry *phar_ce_entry;
        !            31: #endif
        !            32: 
        !            33: #if PHP_MAJOR_VERSION > 5 || ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3))
        !            34: # define PHAR_ARG_INFO
        !            35: #else
        !            36: # define PHAR_ARG_INFO static
        !            37: #endif
        !            38: 
        !            39: static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_DC) /* {{{ */
        !            40: {
        !            41:        char *ext;
        !            42:        phar_mime_type *mime;
        !            43:        ext = strrchr(file, '.');
        !            44:        if (!ext) {
        !            45:                *mime_type = "text/plain";
        !            46:                /* no file extension = assume text/plain */
        !            47:                return PHAR_MIME_OTHER;
        !            48:        }
        !            49:        ++ext;
        !            50:        if (SUCCESS != zend_hash_find(mimes, ext, strlen(ext), (void **) &mime)) {
        !            51:                *mime_type = "application/octet-stream";
        !            52:                return PHAR_MIME_OTHER;
        !            53:        }
        !            54:        *mime_type = mime->mime;
        !            55:        return mime->type;
        !            56: }
        !            57: /* }}} */
        !            58: 
        !            59: static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char *basename, int request_uri_len TSRMLS_DC) /* {{{ */
        !            60: {
        !            61: #if PHP_MAJOR_VERSION >= 6
        !            62:        int is_unicode = 0;
        !            63: #endif
        !            64:        HashTable *_SERVER;
        !            65:        zval **stuff;
        !            66:        char *path_info;
        !            67:        int basename_len = strlen(basename);
        !            68:        int code;
        !            69:        zval *temp;
        !            70: 
        !            71:        /* "tweak" $_SERVER variables requested in earlier call to Phar::mungServer() */
        !            72:        if (!PG(http_globals)[TRACK_VARS_SERVER]) {
        !            73:                return;
        !            74:        }
        !            75: 
        !            76:        _SERVER = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]);
        !            77: 
        !            78:        /* PATH_INFO and PATH_TRANSLATED should always be munged */
        !            79: #if PHP_MAJOR_VERSION >= 6
        !            80:        if (phar_find_key(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff TSRMLS_CC)) {
        !            81:                if (Z_TYPE_PP(stuff) == IS_UNICODE) {
        !            82:                        is_unicode = 1;
        !            83:                        zval_unicode_to_string(*stuff TSRMLS_CC);
        !            84:                } else {
        !            85:                        is_unicode = 0;
        !            86:                }
        !            87: #else
        !            88:        if (SUCCESS == zend_hash_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff)) {
        !            89: #endif
        !            90: 
        !            91:                path_info = Z_STRVAL_PP(stuff);
        !            92:                code = Z_STRLEN_PP(stuff);
        !            93: 
        !            94:                if (Z_STRLEN_PP(stuff) > entry_len && !memcmp(Z_STRVAL_PP(stuff), entry, entry_len)) {
        !            95:                        ZVAL_STRINGL(*stuff, Z_STRVAL_PP(stuff) + entry_len, request_uri_len, 1);
        !            96: 
        !            97:                        MAKE_STD_ZVAL(temp);
        !            98:                        ZVAL_STRINGL(temp, path_info, code, 0);
        !            99: #if PHP_MAJOR_VERSION >= 6
        !           100:                        if (is_unicode) {
        !           101:                                zval_string_to_unicode(*stuff TSRMLS_CC);
        !           102:                        }
        !           103: #endif
        !           104:                        zend_hash_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO"), &temp, sizeof(zval **), NULL);
        !           105:                }
        !           106:        }
        !           107: 
        !           108: #if PHP_MAJOR_VERSION >= 6
        !           109:        if (phar_find_key(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff TSRMLS_CC)) {
        !           110:                if (Z_TYPE_PP(stuff) == IS_UNICODE) {
        !           111:                        is_unicode = 1;
        !           112:                        zval_unicode_to_string(*stuff TSRMLS_CC);
        !           113:                } else {
        !           114:                        is_unicode = 0;
        !           115:                }
        !           116: #else
        !           117:        if (SUCCESS == zend_hash_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff)) {
        !           118: #endif
        !           119: 
        !           120:                path_info = Z_STRVAL_PP(stuff);
        !           121:                code = Z_STRLEN_PP(stuff);
        !           122:                Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 4096, "phar://%s%s", fname, entry);
        !           123: 
        !           124:                MAKE_STD_ZVAL(temp);
        !           125:                ZVAL_STRINGL(temp, path_info, code, 0);
        !           126: #if PHP_MAJOR_VERSION >= 6
        !           127:                if (is_unicode) {
        !           128:                        zval_string_to_unicode(*stuff TSRMLS_CC);
        !           129:                }
        !           130: #endif
        !           131:                zend_hash_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED"), (void *) &temp, sizeof(zval **), NULL);
        !           132:        }
        !           133: 
        !           134:        if (!PHAR_GLOBALS->phar_SERVER_mung_list) {
        !           135:                return;
        !           136:        }
        !           137: 
        !           138:        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_REQUEST_URI) {
        !           139: #if PHP_MAJOR_VERSION >= 6
        !           140:                if (phar_find_key(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff TSRMLS_CC)) {
        !           141:                if (Z_TYPE_PP(stuff) == IS_UNICODE) {
        !           142:                        is_unicode = 1;
        !           143:                        zval_unicode_to_string(*stuff TSRMLS_CC);
        !           144:                } else {
        !           145:                        is_unicode = 0;
        !           146:                }
        !           147: #else
        !           148:                if (SUCCESS == zend_hash_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff)) {
        !           149: #endif
        !           150: 
        !           151:                        path_info = Z_STRVAL_PP(stuff);
        !           152:                        code = Z_STRLEN_PP(stuff);
        !           153: 
        !           154:                        if (Z_STRLEN_PP(stuff) > basename_len && !memcmp(Z_STRVAL_PP(stuff), basename, basename_len)) {
        !           155:                                ZVAL_STRINGL(*stuff, Z_STRVAL_PP(stuff) + basename_len, Z_STRLEN_PP(stuff) - basename_len, 1);
        !           156: 
        !           157:                                MAKE_STD_ZVAL(temp);
        !           158:                                ZVAL_STRINGL(temp, path_info, code, 0);
        !           159: #if PHP_MAJOR_VERSION >= 6
        !           160:                                if (is_unicode) {
        !           161:                                        zval_string_to_unicode(*stuff TSRMLS_CC);
        !           162:                                }
        !           163: #endif
        !           164:                                zend_hash_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI"), (void *) &temp, sizeof(zval **), NULL);
        !           165:                        }
        !           166:                }
        !           167:        }
        !           168: 
        !           169:        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_PHP_SELF) {
        !           170: #if PHP_MAJOR_VERSION >= 6
        !           171:                if (phar_find_key(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff TSRMLS_CC)) {
        !           172:                if (Z_TYPE_PP(stuff) == IS_UNICODE) {
        !           173:                        is_unicode = 1;
        !           174:                        zval_unicode_to_string(*stuff TSRMLS_CC);
        !           175:                } else {
        !           176:                        is_unicode = 0;
        !           177:                }
        !           178: #else
        !           179:                if (SUCCESS == zend_hash_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff)) {
        !           180: #endif
        !           181: 
        !           182:                        path_info = Z_STRVAL_PP(stuff);
        !           183:                        code = Z_STRLEN_PP(stuff);
        !           184: 
        !           185:                        if (Z_STRLEN_PP(stuff) > basename_len && !memcmp(Z_STRVAL_PP(stuff), basename, basename_len)) {
        !           186:                                ZVAL_STRINGL(*stuff, Z_STRVAL_PP(stuff) + basename_len, Z_STRLEN_PP(stuff) - basename_len, 1);
        !           187: 
        !           188:                                MAKE_STD_ZVAL(temp);
        !           189:                                ZVAL_STRINGL(temp, path_info, code, 0);
        !           190: #if PHP_MAJOR_VERSION >= 6
        !           191:                                if (is_unicode) {
        !           192:                                        zval_string_to_unicode(*stuff TSRMLS_CC);
        !           193:                                }
        !           194: #endif
        !           195:                                zend_hash_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF"), (void *) &temp, sizeof(zval **), NULL);
        !           196:                        }
        !           197:                }
        !           198:        }
        !           199: 
        !           200:        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_NAME) {
        !           201: #if PHP_MAJOR_VERSION >= 6
        !           202:                if (phar_find_key(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff TSRMLS_CC)) {
        !           203:                if (Z_TYPE_PP(stuff) == IS_UNICODE) {
        !           204:                        is_unicode = 1;
        !           205:                        zval_unicode_to_string(*stuff TSRMLS_CC);
        !           206:                } else {
        !           207:                        is_unicode = 0;
        !           208:                }
        !           209: #else
        !           210:                if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff)) {
        !           211: #endif
        !           212: 
        !           213:                        path_info = Z_STRVAL_PP(stuff);
        !           214:                        code = Z_STRLEN_PP(stuff);
        !           215:                        ZVAL_STRINGL(*stuff, entry, entry_len, 1);
        !           216: 
        !           217:                        MAKE_STD_ZVAL(temp);
        !           218:                        ZVAL_STRINGL(temp, path_info, code, 0);
        !           219: #if PHP_MAJOR_VERSION >= 6
        !           220:                        if (is_unicode) {
        !           221:                                zval_string_to_unicode(*stuff TSRMLS_CC);
        !           222:                        }
        !           223: #endif
        !           224:                        zend_hash_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME"), (void *) &temp, sizeof(zval **), NULL);
        !           225:                }
        !           226:        }
        !           227: 
        !           228:        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_FILENAME) {
        !           229: #if PHP_MAJOR_VERSION >= 6
        !           230:                if (phar_find_key(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff TSRMLS_CC)) {
        !           231:                if (Z_TYPE_PP(stuff) == IS_UNICODE) {
        !           232:                        is_unicode = 1;
        !           233:                        zval_unicode_to_string(*stuff TSRMLS_CC);
        !           234:                } else {
        !           235:                        is_unicode = 0;
        !           236:                }
        !           237: #else
        !           238:                if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff)) {
        !           239: #endif
        !           240: 
        !           241:                        path_info = Z_STRVAL_PP(stuff);
        !           242:                        code = Z_STRLEN_PP(stuff);
        !           243:                        Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 4096, "phar://%s%s", fname, entry);
        !           244: 
        !           245:                        MAKE_STD_ZVAL(temp);
        !           246:                        ZVAL_STRINGL(temp, path_info, code, 0);
        !           247: #if PHP_MAJOR_VERSION >= 6
        !           248:                        if (is_unicode) {
        !           249:                                zval_string_to_unicode(*stuff TSRMLS_CC);
        !           250:                        }
        !           251: #endif
        !           252:                        zend_hash_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME"), (void *) &temp, sizeof(zval **), NULL);
        !           253:                }
        !           254:        }
        !           255: }
        !           256: /* }}} */
        !           257: 
        !           258: static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, int entry_len, char *arch, char *basename, char *ru, int ru_len TSRMLS_DC) /* {{{ */
        !           259: {
        !           260:        char *name = NULL, buf[8192], *cwd;
        !           261:        zend_syntax_highlighter_ini syntax_highlighter_ini;
        !           262:        sapi_header_line ctr = {0};
        !           263:        size_t got;
        !           264:        int dummy = 1, name_len;
        !           265:        zend_file_handle file_handle;
        !           266:        zend_op_array *new_op_array;
        !           267:        zval *result = NULL;
        !           268:        php_stream *fp;
        !           269:        off_t position;
        !           270: 
        !           271:        switch (code) {
        !           272:                case PHAR_MIME_PHPS:
        !           273:                        efree(basename);
        !           274:                        /* highlight source */
        !           275:                        if (entry[0] == '/') {
        !           276:                                name_len = spprintf(&name, 4096, "phar://%s%s", arch, entry);
        !           277:                        } else {
        !           278:                                name_len = spprintf(&name, 4096, "phar://%s/%s", arch, entry);
        !           279:                        }
        !           280:                        php_get_highlight_struct(&syntax_highlighter_ini);
        !           281: 
        !           282:                        highlight_file(name, &syntax_highlighter_ini TSRMLS_CC);
        !           283: 
        !           284:                        efree(name);
        !           285: #ifdef PHP_WIN32
        !           286:                        efree(arch);
        !           287: #endif
        !           288:                        zend_bailout();
        !           289:                case PHAR_MIME_OTHER:
        !           290:                        /* send headers, output file contents */
        !           291:                        efree(basename);
        !           292:                        ctr.line_len = spprintf(&(ctr.line), 0, "Content-type: %s", mime_type);
        !           293:                        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        !           294:                        efree(ctr.line);
        !           295:                        ctr.line_len = spprintf(&(ctr.line), 0, "Content-length: %u", info->uncompressed_filesize);
        !           296:                        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        !           297:                        efree(ctr.line);
        !           298: 
        !           299:                        if (FAILURE == sapi_send_headers(TSRMLS_C)) {
        !           300:                                zend_bailout();
        !           301:                        }
        !           302: 
        !           303:                        /* prepare to output  */
        !           304:                        fp = phar_get_efp(info, 1 TSRMLS_CC);
        !           305: 
        !           306:                        if (!fp) {
        !           307:                                char *error;
        !           308:                                if (!phar_open_jit(phar, info, &error TSRMLS_CC)) {
        !           309:                                        if (error) {
        !           310:                                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !           311:                                                efree(error);
        !           312:                                        }
        !           313:                                        return -1;
        !           314:                                }
        !           315:                                fp = phar_get_efp(info, 1 TSRMLS_CC);
        !           316:                        }
        !           317:                        position = 0;
        !           318:                        phar_seek_efp(info, 0, SEEK_SET, 0, 1 TSRMLS_CC);
        !           319: 
        !           320:                        do {
        !           321:                                got = php_stream_read(fp, buf, MIN(8192, info->uncompressed_filesize - position));
        !           322:                                if (got > 0) {
        !           323:                                        PHPWRITE(buf, got);
        !           324:                                        position += got;
        !           325:                                        if (position == (off_t) info->uncompressed_filesize) {
        !           326:                                                break;
        !           327:                                        }
        !           328:                                }
        !           329:                        } while (1);
        !           330: 
        !           331:                        zend_bailout();
        !           332:                case PHAR_MIME_PHP:
        !           333:                        if (basename) {
        !           334:                                phar_mung_server_vars(arch, entry, entry_len, basename, ru_len TSRMLS_CC);
        !           335:                                efree(basename);
        !           336:                        }
        !           337: 
        !           338:                        if (entry[0] == '/') {
        !           339:                                name_len = spprintf(&name, 4096, "phar://%s%s", arch, entry);
        !           340:                        } else {
        !           341:                                name_len = spprintf(&name, 4096, "phar://%s/%s", arch, entry);
        !           342:                        }
        !           343: 
        !           344:                        file_handle.type = ZEND_HANDLE_FILENAME;
        !           345:                        file_handle.handle.fd = 0;
        !           346:                        file_handle.filename = name;
        !           347:                        file_handle.opened_path = NULL;
        !           348:                        file_handle.free_filename = 0;
        !           349: 
        !           350:                        PHAR_G(cwd) = NULL;
        !           351:                        PHAR_G(cwd_len) = 0;
        !           352: 
        !           353:                        if (zend_hash_add(&EG(included_files), name, name_len+1, (void *)&dummy, sizeof(int), NULL) == SUCCESS) {
        !           354:                                if ((cwd = zend_memrchr(entry, '/', entry_len))) {
        !           355:                                        PHAR_G(cwd_init) = 1;
        !           356:                                        if (entry == cwd) {
        !           357:                                                /* root directory */
        !           358:                                                PHAR_G(cwd_len) = 0;
        !           359:                                                PHAR_G(cwd) = NULL;
        !           360:                                        } else if (entry[0] == '/') {
        !           361:                                                PHAR_G(cwd_len) = cwd - (entry + 1);
        !           362:                                                PHAR_G(cwd) = estrndup(entry + 1, PHAR_G(cwd_len));
        !           363:                                        } else {
        !           364:                                                PHAR_G(cwd_len) = cwd - entry;
        !           365:                                                PHAR_G(cwd) = estrndup(entry, PHAR_G(cwd_len));
        !           366:                                        }
        !           367:                                }
        !           368: 
        !           369:                                new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
        !           370: 
        !           371:                                if (!new_op_array) {
        !           372:                                        zend_hash_del(&EG(included_files), name, name_len+1);
        !           373:                                }
        !           374: 
        !           375:                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
        !           376: 
        !           377:                        } else {
        !           378:                                efree(name);
        !           379:                                new_op_array = NULL;
        !           380:                        }
        !           381: #ifdef PHP_WIN32
        !           382:                        efree(arch);
        !           383: #endif
        !           384:                        if (new_op_array) {
        !           385:                                EG(return_value_ptr_ptr) = &result;
        !           386:                                EG(active_op_array) = new_op_array;
        !           387: 
        !           388:                                zend_try {
        !           389:                                        zend_execute(new_op_array TSRMLS_CC);
        !           390:                                        if (PHAR_G(cwd)) {
        !           391:                                                efree(PHAR_G(cwd));
        !           392:                                                PHAR_G(cwd) = NULL;
        !           393:                                                PHAR_G(cwd_len) = 0;
        !           394:                                        }
        !           395: 
        !           396:                                        PHAR_G(cwd_init) = 0;
        !           397:                                        efree(name);
        !           398:                                        destroy_op_array(new_op_array TSRMLS_CC);
        !           399:                                        efree(new_op_array);
        !           400: 
        !           401: 
        !           402:                                        if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
        !           403:                                                zval_ptr_dtor(EG(return_value_ptr_ptr));
        !           404:                                        }
        !           405:                                } zend_catch {
        !           406:                                        if (PHAR_G(cwd)) {
        !           407:                                                efree(PHAR_G(cwd));
        !           408:                                                PHAR_G(cwd) = NULL;
        !           409:                                                PHAR_G(cwd_len) = 0;
        !           410:                                        }
        !           411: 
        !           412:                                        PHAR_G(cwd_init) = 0;
        !           413:                                        efree(name);
        !           414:                                } zend_end_try();
        !           415: 
        !           416:                                zend_bailout();
        !           417:                        }
        !           418: 
        !           419:                        return PHAR_MIME_PHP;
        !           420:        }
        !           421:        return -1;
        !           422: }
        !           423: /* }}} */
        !           424: 
        !           425: static void phar_do_403(char *entry, int entry_len TSRMLS_DC) /* {{{ */
        !           426: {
        !           427:        sapi_header_line ctr = {0};
        !           428: 
        !           429:        ctr.response_code = 403;
        !           430:        ctr.line_len = sizeof("HTTP/1.0 403 Access Denied");
        !           431:        ctr.line = "HTTP/1.0 403 Access Denied";
        !           432:        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        !           433:        sapi_send_headers(TSRMLS_C);
        !           434:        PHPWRITE("<html>\n <head>\n  <title>Access Denied</title>\n </head>\n <body>\n  <h1>403 - File ", sizeof("<html>\n <head>\n  <title>Access Denied</title>\n </head>\n <body>\n  <h1>403 - File ") - 1);
        !           435:        PHPWRITE(entry, entry_len);
        !           436:        PHPWRITE(" Access Denied</h1>\n </body>\n</html>", sizeof(" Access Denied</h1>\n </body>\n</html>") - 1);
        !           437: }
        !           438: /* }}} */
        !           439: 
        !           440: static void phar_do_404(phar_archive_data *phar, char *fname, int fname_len, char *f404, int f404_len, char *entry, int entry_len TSRMLS_DC) /* {{{ */
        !           441: {
        !           442:        sapi_header_line ctr = {0};
        !           443:        phar_entry_info *info;
        !           444: 
        !           445:        if (phar && f404_len) {
        !           446:                info = phar_get_entry_info(phar, f404, f404_len, NULL, 1 TSRMLS_CC);
        !           447: 
        !           448:                if (info) {
        !           449:                        phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, f404, f404_len, fname, NULL, NULL, 0 TSRMLS_CC);
        !           450:                        return;
        !           451:                }
        !           452:        }
        !           453: 
        !           454:        ctr.response_code = 404;
        !           455:        ctr.line_len = sizeof("HTTP/1.0 404 Not Found")+1;
        !           456:        ctr.line = "HTTP/1.0 404 Not Found";
        !           457:        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        !           458:        sapi_send_headers(TSRMLS_C);
        !           459:        PHPWRITE("<html>\n <head>\n  <title>File Not Found</title>\n </head>\n <body>\n  <h1>404 - File ", sizeof("<html>\n <head>\n  <title>File Not Found</title>\n </head>\n <body>\n  <h1>404 - File ") - 1);
        !           460:        PHPWRITE(entry, entry_len);
        !           461:        PHPWRITE(" Not Found</h1>\n </body>\n</html>",  sizeof(" Not Found</h1>\n </body>\n</html>") - 1);
        !           462: }
        !           463: /* }}} */
        !           464: 
        !           465: /* post-process REQUEST_URI and retrieve the actual request URI.  This is for
        !           466:    cases like http://localhost/blah.phar/path/to/file.php/extra/stuff
        !           467:    which calls "blah.phar" file "path/to/file.php" with PATH_INFO "/extra/stuff" */
        !           468: static void phar_postprocess_ru_web(char *fname, int fname_len, char **entry, int *entry_len, char **ru, int *ru_len TSRMLS_DC) /* {{{ */
        !           469: {
        !           470:        char *e = *entry + 1, *u = NULL, *u1 = NULL, *saveu = NULL;
        !           471:        int e_len = *entry_len - 1, u_len = 0;
        !           472:        phar_archive_data **pphar = NULL;
        !           473: 
        !           474:        /* we already know we can retrieve the phar if we reach here */
        !           475:        zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **) &pphar);
        !           476: 
        !           477:        if (!pphar && PHAR_G(manifest_cached)) {
        !           478:                zend_hash_find(&cached_phars, fname, fname_len, (void **) &pphar);
        !           479:        }
        !           480: 
        !           481:        do {
        !           482:                if (zend_hash_exists(&((*pphar)->manifest), e, e_len)) {
        !           483:                        if (u) {
        !           484:                                u[0] = '/';
        !           485:                                *ru = estrndup(u, u_len+1);
        !           486:                                ++u_len;
        !           487:                                u[0] = '\0';
        !           488:                        } else {
        !           489:                                *ru = NULL;
        !           490:                        }
        !           491:                        *ru_len = u_len;
        !           492:                        *entry_len = e_len + 1;
        !           493:                        return;
        !           494:                }
        !           495: 
        !           496:                if (u) {
        !           497:                        u1 = strrchr(e, '/');
        !           498:                        u[0] = '/';
        !           499:                        saveu = u;
        !           500:                        e_len += u_len + 1;
        !           501:                        u = u1;
        !           502:                        if (!u) {
        !           503:                                return;
        !           504:                        }
        !           505:                } else {
        !           506:                        u = strrchr(e, '/');
        !           507:                        if (!u) {
        !           508:                                if (saveu) {
        !           509:                                        saveu[0] = '/';
        !           510:                                }
        !           511:                                return;
        !           512:                        }
        !           513:                }
        !           514: 
        !           515:                u[0] = '\0';
        !           516:                u_len = strlen(u + 1);
        !           517:                e_len -= u_len + 1;
        !           518: 
        !           519:                if (e_len < 0) {
        !           520:                        if (saveu) {
        !           521:                                saveu[0] = '/';
        !           522:                        }
        !           523:                        return;
        !           524:                }
        !           525:        } while (1);
        !           526: }
        !           527: /* }}} */
        !           528: 
        !           529: /* {{{ proto void Phar::running([bool retphar = true])
        !           530:  * return the name of the currently running phar archive.  If the optional parameter
        !           531:  * is set to true, return the phar:// URL to the currently running phar
        !           532:  */
        !           533: PHP_METHOD(Phar, running)
        !           534: {
        !           535:        char *fname, *arch, *entry;
        !           536:        int fname_len, arch_len, entry_len;
        !           537:        zend_bool retphar = 1;
        !           538: 
        !           539:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &retphar) == FAILURE) {
        !           540:                return;
        !           541:        }
        !           542: 
        !           543:        fname = zend_get_executed_filename(TSRMLS_C);
        !           544:        fname_len = strlen(fname);
        !           545: 
        !           546:        if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
        !           547:                efree(entry);
        !           548:                if (retphar) {
        !           549:                        RETVAL_STRINGL(fname, arch_len + 7, 1);
        !           550:                        efree(arch);
        !           551:                        return;
        !           552:                } else {
        !           553:                        RETURN_STRINGL(arch, arch_len, 0);
        !           554:                }
        !           555:        }
        !           556: 
        !           557:        RETURN_STRINGL("", 0, 1);
        !           558: }
        !           559: /* }}} */
        !           560: 
        !           561: /* {{{ proto void Phar::mount(string pharpath, string externalfile)
        !           562:  * mount an external file or path to a location within the phar.  This maps
        !           563:  * an external file or directory to a location within the phar archive, allowing
        !           564:  * reference to an external location as if it were within the phar archive.  This
        !           565:  * is useful for writable temp files like databases
        !           566:  */
        !           567: PHP_METHOD(Phar, mount)
        !           568: {
        !           569:        char *fname, *arch = NULL, *entry = NULL, *path, *actual;
        !           570:        int fname_len, arch_len, entry_len, path_len, actual_len;
        !           571:        phar_archive_data **pphar;
        !           572: 
        !           573:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &actual, &actual_len) == FAILURE) {
        !           574:                return;
        !           575:        }
        !           576: 
        !           577:        fname = zend_get_executed_filename(TSRMLS_C);
        !           578:        fname_len = strlen(fname);
        !           579: 
        !           580: #ifdef PHP_WIN32
        !           581:        phar_unixify_path_separators(fname, fname_len);
        !           582: #endif
        !           583: 
        !           584:        if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
        !           585:                efree(entry);
        !           586:                entry = NULL;
        !           587: 
        !           588:                if (path_len > 7 && !memcmp(path, "phar://", 7)) {
        !           589:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Can only mount internal paths within a phar archive, use a relative path instead of \"%s\"", path);
        !           590:                        efree(arch);
        !           591:                        return;
        !           592:                }
        !           593: carry_on2:
        !           594:                if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
        !           595:                        if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, arch, arch_len, (void **)&pphar)) {
        !           596:                                if (SUCCESS == phar_copy_on_write(pphar TSRMLS_CC)) {
        !           597:                                        goto carry_on;
        !           598:                                }
        !           599:                        }
        !           600: 
        !           601:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s is not a phar archive, cannot mount", arch);
        !           602: 
        !           603:                        if (arch) {
        !           604:                                efree(arch);
        !           605:                        }
        !           606:                        return;
        !           607:                }
        !           608: carry_on:
        !           609:                if (SUCCESS != phar_mount_entry(*pphar, actual, actual_len, path, path_len TSRMLS_CC)) {
        !           610:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Mounting of %s to %s within phar %s failed", path, actual, arch);
        !           611:                        if (path && path == entry) {
        !           612:                                efree(entry);
        !           613:                        }
        !           614: 
        !           615:                        if (arch) {
        !           616:                                efree(arch);
        !           617:                        }
        !           618: 
        !           619:                        return;
        !           620:                }
        !           621: 
        !           622:                if (entry && path && path == entry) {
        !           623:                        efree(entry);
        !           624:                }
        !           625: 
        !           626:                if (arch) {
        !           627:                        efree(arch);
        !           628:                }
        !           629: 
        !           630:                return;
        !           631:        } else if (PHAR_GLOBALS->phar_fname_map.arBuckets && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) {
        !           632:                goto carry_on;
        !           633:        } else if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, fname, fname_len, (void **)&pphar)) {
        !           634:                if (SUCCESS == phar_copy_on_write(pphar TSRMLS_CC)) {
        !           635:                        goto carry_on;
        !           636:                }
        !           637: 
        !           638:                goto carry_on;
        !           639:        } else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
        !           640:                path = entry;
        !           641:                path_len = entry_len;
        !           642:                goto carry_on2;
        !           643:        }
        !           644: 
        !           645:        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Mounting of %s to %s failed", path, actual);
        !           646: }
        !           647: /* }}} */
        !           648: 
        !           649: /* {{{ proto void Phar::webPhar([string alias, [string index, [string f404, [array mimetypes, [callback rewrites]]]]])
        !           650:  * mapPhar for web-based phars. Reads the currently executed file (a phar)
        !           651:  * and registers its manifest. When executed in the CLI or CGI command-line sapi,
        !           652:  * this works exactly like mapPhar().  When executed by a web-based sapi, this
        !           653:  * reads $_SERVER['REQUEST_URI'] (the actual original value) and parses out the
        !           654:  * intended internal file.
        !           655:  */
        !           656: PHP_METHOD(Phar, webPhar)
        !           657: {
        !           658:        zval *mimeoverride = NULL, *rewrite = NULL;
        !           659:        char *alias = NULL, *error, *index_php = NULL, *f404 = NULL, *ru = NULL;
        !           660:        int alias_len = 0, ret, f404_len = 0, free_pathinfo = 0, ru_len = 0;
        !           661:        char *fname, *basename, *path_info, *mime_type = NULL, *entry, *pt;
        !           662:        int fname_len, entry_len, code, index_php_len = 0, not_cgi;
        !           663:        phar_archive_data *phar = NULL;
        !           664:        phar_entry_info *info = NULL;
        !           665: 
        !           666:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!saz", &alias, &alias_len, &index_php, &index_php_len, &f404, &f404_len, &mimeoverride, &rewrite) == FAILURE) {
        !           667:                return;
        !           668:        }
        !           669: 
        !           670:        phar_request_initialize(TSRMLS_C);
        !           671:        fname = zend_get_executed_filename(TSRMLS_C);
        !           672:        fname_len = strlen(fname);
        !           673: 
        !           674:        if (phar_open_executed_filename(alias, alias_len, &error TSRMLS_CC) != SUCCESS) {
        !           675:                if (error) {
        !           676:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !           677:                        efree(error);
        !           678:                }
        !           679:                return;
        !           680:        }
        !           681: 
        !           682:        /* retrieve requested file within phar */
        !           683:        if (!(SG(request_info).request_method && SG(request_info).request_uri && (!strcmp(SG(request_info).request_method, "GET") || !strcmp(SG(request_info).request_method, "POST")))) {
        !           684:                return;
        !           685:        }
        !           686: 
        !           687: #ifdef PHP_WIN32
        !           688:        fname = estrndup(fname, fname_len);
        !           689:        phar_unixify_path_separators(fname, fname_len);
        !           690: #endif
        !           691:        basename = zend_memrchr(fname, '/', fname_len);
        !           692: 
        !           693:        if (!basename) {
        !           694:                basename = fname;
        !           695:        } else {
        !           696:                ++basename;
        !           697:        }
        !           698: 
        !           699:        if ((strlen(sapi_module.name) == sizeof("cgi-fcgi")-1 && !strncmp(sapi_module.name, "cgi-fcgi", sizeof("cgi-fcgi")-1))
        !           700:                || (strlen(sapi_module.name) == sizeof("cgi")-1 && !strncmp(sapi_module.name, "cgi", sizeof("cgi")-1))) {
        !           701: 
        !           702:                if (PG(http_globals)[TRACK_VARS_SERVER]) {
        !           703:                        HashTable *_server = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]);
        !           704:                        zval **z_script_name, **z_path_info;
        !           705: 
        !           706:                        if (SUCCESS != zend_hash_find(_server, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void**)&z_script_name) ||
        !           707:                                IS_STRING != Z_TYPE_PP(z_script_name) ||
        !           708:                                !strstr(Z_STRVAL_PP(z_script_name), basename)) {
        !           709:                                return;
        !           710:                        }
        !           711: 
        !           712:                        if (SUCCESS == zend_hash_find(_server, "PATH_INFO", sizeof("PATH_INFO"), (void**)&z_path_info) &&
        !           713:                                IS_STRING == Z_TYPE_PP(z_path_info)) {
        !           714:                                entry_len = Z_STRLEN_PP(z_path_info);
        !           715:                                entry = estrndup(Z_STRVAL_PP(z_path_info), entry_len);
        !           716:                                path_info = emalloc(Z_STRLEN_PP(z_script_name) + entry_len + 1);
        !           717:                                memcpy(path_info, Z_STRVAL_PP(z_script_name), Z_STRLEN_PP(z_script_name));
        !           718:                                memcpy(path_info + Z_STRLEN_PP(z_script_name), entry, entry_len + 1);
        !           719:                                free_pathinfo = 1;
        !           720:                        } else {
        !           721:                                entry_len = 0;
        !           722:                                entry = estrndup("", 0);
        !           723:                                path_info = Z_STRVAL_PP(z_script_name);
        !           724:                        }
        !           725: 
        !           726:                        pt = estrndup(Z_STRVAL_PP(z_script_name), Z_STRLEN_PP(z_script_name));
        !           727: 
        !           728:                } else {
        !           729:                        char *testit;
        !           730: 
        !           731:                        testit = sapi_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1 TSRMLS_CC);
        !           732:                        if (!(pt = strstr(testit, basename))) {
        !           733:                                efree(testit);
        !           734:                                return;
        !           735:                        }
        !           736: 
        !           737:                        path_info = sapi_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC);
        !           738: 
        !           739:                        if (path_info) {
        !           740:                                entry = path_info;
        !           741:                                entry_len = strlen(entry);
        !           742:                                spprintf(&path_info, 0, "%s%s", testit, path_info);
        !           743:                                free_pathinfo = 1;
        !           744:                        } else {
        !           745:                                path_info = testit;
        !           746:                                free_pathinfo = 1;
        !           747:                                entry = estrndup("", 0);
        !           748:                                entry_len = 0;
        !           749:                        }
        !           750: 
        !           751:                        pt = estrndup(testit, (pt - testit) + (fname_len - (basename - fname)));
        !           752:                }
        !           753:                not_cgi = 0;
        !           754:        } else {
        !           755:                path_info = SG(request_info).request_uri;
        !           756: 
        !           757:                if (!(pt = strstr(path_info, basename))) {
        !           758:                        /* this can happen with rewrite rules - and we have no idea what to do then, so return */
        !           759:                        return;
        !           760:                }
        !           761: 
        !           762:                entry_len = strlen(path_info);
        !           763:                entry_len -= (pt - path_info) + (fname_len - (basename - fname));
        !           764:                entry = estrndup(pt + (fname_len - (basename - fname)), entry_len);
        !           765: 
        !           766:                pt = estrndup(path_info, (pt - path_info) + (fname_len - (basename - fname)));
        !           767:                not_cgi = 1;
        !           768:        }
        !           769: 
        !           770:        if (rewrite) {
        !           771:                zend_fcall_info fci;
        !           772:                zend_fcall_info_cache fcc;
        !           773:                zval *params, *retval_ptr, **zp[1];
        !           774: 
        !           775:                MAKE_STD_ZVAL(params);
        !           776:                ZVAL_STRINGL(params, entry, entry_len, 1);
        !           777:                zp[0] = &params;
        !           778: 
        !           779: #if PHP_VERSION_ID < 50300
        !           780:                if (FAILURE == zend_fcall_info_init(rewrite, &fci, &fcc TSRMLS_CC)) {
        !           781: #else
        !           782:                if (FAILURE == zend_fcall_info_init(rewrite, 0, &fci, &fcc, NULL, NULL TSRMLS_CC)) {
        !           783: #endif
        !           784:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar error: invalid rewrite callback");
        !           785: 
        !           786:                        if (free_pathinfo) {
        !           787:                                efree(path_info);
        !           788:                        }
        !           789: 
        !           790:                        return;
        !           791:                }
        !           792: 
        !           793:                fci.param_count = 1;
        !           794:                fci.params = zp;
        !           795: #if PHP_VERSION_ID < 50300
        !           796:                ++(params->refcount);
        !           797: #else
        !           798:                Z_ADDREF_P(params);
        !           799: #endif
        !           800:                fci.retval_ptr_ptr = &retval_ptr;
        !           801: 
        !           802:                if (FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) {
        !           803:                        if (!EG(exception)) {
        !           804:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar error: failed to call rewrite callback");
        !           805:                        }
        !           806: 
        !           807:                        if (free_pathinfo) {
        !           808:                                efree(path_info);
        !           809:                        }
        !           810: 
        !           811:                        return;
        !           812:                }
        !           813: 
        !           814:                if (!fci.retval_ptr_ptr || !retval_ptr) {
        !           815:                        if (free_pathinfo) {
        !           816:                                efree(path_info);
        !           817:                        }
        !           818:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar error: rewrite callback must return a string or false");
        !           819:                        return;
        !           820:                }
        !           821: 
        !           822:                switch (Z_TYPE_P(retval_ptr)) {
        !           823: #if PHP_VERSION_ID >= 60000
        !           824:                        case IS_UNICODE:
        !           825:                                zval_unicode_to_string(retval_ptr TSRMLS_CC);
        !           826:                                /* break intentionally omitted */
        !           827: #endif
        !           828:                        case IS_STRING:
        !           829:                                efree(entry);
        !           830: 
        !           831:                                if (fci.retval_ptr_ptr != &retval_ptr) {
        !           832:                                        entry = estrndup(Z_STRVAL_PP(fci.retval_ptr_ptr), Z_STRLEN_PP(fci.retval_ptr_ptr));
        !           833:                                        entry_len = Z_STRLEN_PP(fci.retval_ptr_ptr);
        !           834:                                } else {
        !           835:                                        entry = Z_STRVAL_P(retval_ptr);
        !           836:                                        entry_len = Z_STRLEN_P(retval_ptr);
        !           837:                                }
        !           838: 
        !           839:                                break;
        !           840:                        case IS_BOOL:
        !           841:                                phar_do_403(entry, entry_len TSRMLS_CC);
        !           842: 
        !           843:                                if (free_pathinfo) {
        !           844:                                        efree(path_info);
        !           845:                                }
        !           846: 
        !           847:                                zend_bailout();
        !           848:                                return;
        !           849:                        default:
        !           850:                                efree(retval_ptr);
        !           851: 
        !           852:                                if (free_pathinfo) {
        !           853:                                        efree(path_info);
        !           854:                                }
        !           855: 
        !           856:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar error: rewrite callback must return a string or false");
        !           857:                                return;
        !           858:                }
        !           859:        }
        !           860: 
        !           861:        if (entry_len) {
        !           862:                phar_postprocess_ru_web(fname, fname_len, &entry, &entry_len, &ru, &ru_len TSRMLS_CC);
        !           863:        }
        !           864: 
        !           865:        if (!entry_len || (entry_len == 1 && entry[0] == '/')) {
        !           866:                efree(entry);
        !           867:                /* direct request */
        !           868:                if (index_php_len) {
        !           869:                        entry = index_php;
        !           870:                        entry_len = index_php_len;
        !           871:                        if (entry[0] != '/') {
        !           872:                                spprintf(&entry, 0, "/%s", index_php);
        !           873:                                ++entry_len;
        !           874:                        }
        !           875:                } else {
        !           876:                        /* assume "index.php" is starting point */
        !           877:                        entry = estrndup("/index.php", sizeof("/index.php"));
        !           878:                        entry_len = sizeof("/index.php")-1;
        !           879:                }
        !           880: 
        !           881:                if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL TSRMLS_CC) ||
        !           882:                        (info = phar_get_entry_info(phar, entry, entry_len, NULL, 0 TSRMLS_CC)) == NULL) {
        !           883:                        phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len TSRMLS_CC);
        !           884: 
        !           885:                        if (free_pathinfo) {
        !           886:                                efree(path_info);
        !           887:                        }
        !           888: 
        !           889:                        zend_bailout();
        !           890:                } else {
        !           891:                        char *tmp = NULL, sa = '\0';
        !           892:                        sapi_header_line ctr = {0};
        !           893:                        ctr.response_code = 301;
        !           894:                        ctr.line_len = sizeof("HTTP/1.1 301 Moved Permanently")+1;
        !           895:                        ctr.line = "HTTP/1.1 301 Moved Permanently";
        !           896:                        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        !           897: 
        !           898:                        if (not_cgi) {
        !           899:                                tmp = strstr(path_info, basename) + fname_len;
        !           900:                                sa = *tmp;
        !           901:                                *tmp = '\0';
        !           902:                        }
        !           903: 
        !           904:                        ctr.response_code = 0;
        !           905: 
        !           906:                        if (path_info[strlen(path_info)-1] == '/') {
        !           907:                                ctr.line_len = spprintf(&(ctr.line), 4096, "Location: %s%s", path_info, entry + 1);
        !           908:                        } else {
        !           909:                                ctr.line_len = spprintf(&(ctr.line), 4096, "Location: %s%s", path_info, entry);
        !           910:                        }
        !           911: 
        !           912:                        if (not_cgi) {
        !           913:                                *tmp = sa;
        !           914:                        }
        !           915: 
        !           916:                        if (free_pathinfo) {
        !           917:                                efree(path_info);
        !           918:                        }
        !           919: 
        !           920:                        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        !           921:                        sapi_send_headers(TSRMLS_C);
        !           922:                        efree(ctr.line);
        !           923:                        zend_bailout();
        !           924:                }
        !           925:        }
        !           926: 
        !           927:        if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL TSRMLS_CC) ||
        !           928:                (info = phar_get_entry_info(phar, entry, entry_len, NULL, 0 TSRMLS_CC)) == NULL) {
        !           929:                phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len TSRMLS_CC);
        !           930: #ifdef PHP_WIN32
        !           931:                efree(fname);
        !           932: #endif
        !           933:                zend_bailout();
        !           934:        }
        !           935: 
        !           936:        if (mimeoverride && zend_hash_num_elements(Z_ARRVAL_P(mimeoverride))) {
        !           937:                char *ext = zend_memrchr(entry, '.', entry_len);
        !           938:                zval **val;
        !           939: 
        !           940:                if (ext) {
        !           941:                        ++ext;
        !           942: 
        !           943: #if PHP_MAJOR_VERSION >= 6
        !           944:                        if (phar_find_key(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val TSRMLS_CC)) {
        !           945: #else
        !           946:                        if (SUCCESS == zend_hash_find(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val)) {
        !           947: #endif
        !           948:                                switch (Z_TYPE_PP(val)) {
        !           949:                                        case IS_LONG:
        !           950:                                                if (Z_LVAL_PP(val) == PHAR_MIME_PHP || Z_LVAL_PP(val) == PHAR_MIME_PHPS) {
        !           951:                                                        mime_type = "";
        !           952:                                                        code = Z_LVAL_PP(val);
        !           953:                                                } else {
        !           954:                                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed");
        !           955: #ifdef PHP_WIN32
        !           956:                                                        efree(fname);
        !           957: #endif
        !           958:                                                        RETURN_FALSE;
        !           959:                                                }
        !           960:                                                break;
        !           961: #if PHP_MAJOR_VERSION >= 6
        !           962:                                        case IS_UNICODE:
        !           963:                                                zval_unicode_to_string(*(val) TSRMLS_CC);
        !           964:                                                /* break intentionally omitted */
        !           965: #endif
        !           966:                                        case IS_STRING:
        !           967:                                                mime_type = Z_STRVAL_PP(val);
        !           968:                                                code = PHAR_MIME_OTHER;
        !           969:                                                break;
        !           970:                                        default:
        !           971:                                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown mime type specifier used (not a string or int), only Phar::PHP, Phar::PHPS and a mime type string are allowed");
        !           972: #ifdef PHP_WIN32
        !           973:                                                efree(fname);
        !           974: #endif
        !           975:                                                RETURN_FALSE;
        !           976:                                }
        !           977:                        }
        !           978:                }
        !           979:        }
        !           980: 
        !           981:        if (!mime_type) {
        !           982:                code = phar_file_type(&PHAR_G(mime_types), entry, &mime_type TSRMLS_CC);
        !           983:        }
        !           984:        ret = phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len TSRMLS_CC);
        !           985: }
        !           986: /* }}} */
        !           987: 
        !           988: /* {{{ proto void Phar::mungServer(array munglist)
        !           989:  * Defines a list of up to 4 $_SERVER variables that should be modified for execution
        !           990:  * to mask the presence of the phar archive.  This should be used in conjunction with
        !           991:  * Phar::webPhar(), and has no effect otherwise
        !           992:  * SCRIPT_NAME, PHP_SELF, REQUEST_URI and SCRIPT_FILENAME
        !           993:  */
        !           994: PHP_METHOD(Phar, mungServer)
        !           995: {
        !           996:        zval *mungvalues;
        !           997: 
        !           998:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &mungvalues) == FAILURE) {
        !           999:                return;
        !          1000:        }
        !          1001: 
        !          1002:        if (!zend_hash_num_elements(Z_ARRVAL_P(mungvalues))) {
        !          1003:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "No values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME");
        !          1004:                return;
        !          1005:        }
        !          1006: 
        !          1007:        if (zend_hash_num_elements(Z_ARRVAL_P(mungvalues)) > 4) {
        !          1008:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Too many values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME");
        !          1009:                return;
        !          1010:        }
        !          1011: 
        !          1012:        phar_request_initialize(TSRMLS_C);
        !          1013: 
        !          1014:        for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(mungvalues)); SUCCESS == zend_hash_has_more_elements(Z_ARRVAL_P(mungvalues)); zend_hash_move_forward(Z_ARRVAL_P(mungvalues))) {
        !          1015:                zval **data = NULL;
        !          1016: #if PHP_MAJOR_VERSION >= 6
        !          1017:                zval *unicopy = NULL;
        !          1018: #endif
        !          1019: 
        !          1020:                if (SUCCESS != zend_hash_get_current_data(Z_ARRVAL_P(mungvalues), (void **) &data)) {
        !          1021:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "unable to retrieve array value in Phar::mungServer()");
        !          1022:                        return;
        !          1023:                }
        !          1024: 
        !          1025: #if PHP_MAJOR_VERSION >= 6
        !          1026:                if (Z_TYPE_PP(data) == IS_UNICODE) {
        !          1027:                        MAKE_STD_ZVAL(unicopy);
        !          1028:                        *unicopy = **data;
        !          1029:                        zval_copy_ctor(unicopy);
        !          1030:                        INIT_PZVAL(unicopy);
        !          1031:                        zval_unicode_to_string(unicopy TSRMLS_CC);
        !          1032:                        data = &unicopy;
        !          1033:                }
        !          1034: #endif
        !          1035: 
        !          1036:                if (Z_TYPE_PP(data) != IS_STRING) {
        !          1037:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME");
        !          1038:                        return;
        !          1039:                }
        !          1040: 
        !          1041:                if (Z_STRLEN_PP(data) == sizeof("PHP_SELF")-1 && !strncmp(Z_STRVAL_PP(data), "PHP_SELF", sizeof("PHP_SELF")-1)) {
        !          1042:                        PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_PHP_SELF;
        !          1043:                }
        !          1044: 
        !          1045:                if (Z_STRLEN_PP(data) == sizeof("REQUEST_URI")-1) {
        !          1046:                        if (!strncmp(Z_STRVAL_PP(data), "REQUEST_URI", sizeof("REQUEST_URI")-1)) {
        !          1047:                                PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_REQUEST_URI;
        !          1048:                        }
        !          1049:                        if (!strncmp(Z_STRVAL_PP(data), "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1)) {
        !          1050:                                PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_SCRIPT_NAME;
        !          1051:                        }
        !          1052:                }
        !          1053: 
        !          1054:                if (Z_STRLEN_PP(data) == sizeof("SCRIPT_FILENAME")-1 && !strncmp(Z_STRVAL_PP(data), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1)) {
        !          1055:                        PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_SCRIPT_FILENAME;
        !          1056:                }
        !          1057: #if PHP_MAJOR_VERSION >= 6
        !          1058:                if (unicopy) {
        !          1059:                        zval_ptr_dtor(&unicopy);
        !          1060:                }
        !          1061: #endif
        !          1062:        }
        !          1063: }
        !          1064: /* }}} */
        !          1065: 
        !          1066: /* {{{ proto void Phar::interceptFileFuncs()
        !          1067:  * instructs phar to intercept fopen, file_get_contents, opendir, and all of the stat-related functions
        !          1068:  * and return stat on files within the phar for relative paths
        !          1069:  *
        !          1070:  * Once called, this cannot be reversed, and continue until the end of the request.
        !          1071:  *
        !          1072:  * This allows legacy scripts to be pharred unmodified
        !          1073:  */
        !          1074: PHP_METHOD(Phar, interceptFileFuncs)
        !          1075: {
        !          1076:        if (zend_parse_parameters_none() == FAILURE) {
        !          1077:                return;
        !          1078:        }
        !          1079:        phar_intercept_functions(TSRMLS_C);
        !          1080: }
        !          1081: /* }}} */
        !          1082: 
        !          1083: /* {{{ proto array Phar::createDefaultStub([string indexfile[, string webindexfile]])
        !          1084:  * Return a stub that can be used to run a phar-based archive without the phar extension
        !          1085:  * indexfile is the CLI startup filename, which defaults to "index.php", webindexfile
        !          1086:  * is the web startup filename, and also defaults to "index.php"
        !          1087:  */
        !          1088: PHP_METHOD(Phar, createDefaultStub)
        !          1089: {
        !          1090:        char *index = NULL, *webindex = NULL, *stub, *error;
        !          1091:        int index_len = 0, webindex_len = 0;
        !          1092:        size_t stub_len;
        !          1093: 
        !          1094:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &index, &index_len, &webindex, &webindex_len) == FAILURE) {
        !          1095:                return;
        !          1096:        }
        !          1097: 
        !          1098:        stub = phar_create_default_stub(index, webindex, &stub_len, &error TSRMLS_CC);
        !          1099: 
        !          1100:        if (error) {
        !          1101:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          1102:                efree(error);
        !          1103:                return;
        !          1104:        }
        !          1105:        RETURN_STRINGL(stub, stub_len, 0);
        !          1106: }
        !          1107: /* }}} */
        !          1108: 
        !          1109: /* {{{ proto mixed Phar::mapPhar([string alias, [int dataoffset]])
        !          1110:  * Reads the currently executed file (a phar) and registers its manifest */
        !          1111: PHP_METHOD(Phar, mapPhar)
        !          1112: {
        !          1113:        char *alias = NULL, *error;
        !          1114:        int alias_len = 0;
        !          1115:        long dataoffset = 0;
        !          1116: 
        !          1117:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!l", &alias, &alias_len, &dataoffset) == FAILURE) {
        !          1118:                return;
        !          1119:        }
        !          1120: 
        !          1121:        phar_request_initialize(TSRMLS_C);
        !          1122: 
        !          1123:        RETVAL_BOOL(phar_open_executed_filename(alias, alias_len, &error TSRMLS_CC) == SUCCESS);
        !          1124: 
        !          1125:        if (error) {
        !          1126:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          1127:                efree(error);
        !          1128:        }
        !          1129: } /* }}} */
        !          1130: 
        !          1131: /* {{{ proto mixed Phar::loadPhar(string filename [, string alias])
        !          1132:  * Loads any phar archive with an alias */
        !          1133: PHP_METHOD(Phar, loadPhar)
        !          1134: {
        !          1135:        char *fname, *alias = NULL, *error;
        !          1136:        int fname_len, alias_len = 0;
        !          1137: 
        !          1138:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &fname, &fname_len, &alias, &alias_len) == FAILURE) {
        !          1139:                return;
        !          1140:        }
        !          1141: 
        !          1142:        phar_request_initialize(TSRMLS_C);
        !          1143: 
        !          1144:        RETVAL_BOOL(phar_open_from_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, &error TSRMLS_CC) == SUCCESS);
        !          1145: 
        !          1146:        if (error) {
        !          1147:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          1148:                efree(error);
        !          1149:        }
        !          1150: } /* }}} */
        !          1151: 
        !          1152: /* {{{ proto string Phar::apiVersion()
        !          1153:  * Returns the api version */
        !          1154: PHP_METHOD(Phar, apiVersion)
        !          1155: {
        !          1156:        if (zend_parse_parameters_none() == FAILURE) {
        !          1157:                return;
        !          1158:        }
        !          1159:        RETURN_STRINGL(PHP_PHAR_API_VERSION, sizeof(PHP_PHAR_API_VERSION)-1, 1);
        !          1160: }
        !          1161: /* }}}*/
        !          1162: 
        !          1163: /* {{{ proto bool Phar::canCompress([int method])
        !          1164:  * Returns whether phar extension supports compression using zlib/bzip2 */
        !          1165: PHP_METHOD(Phar, canCompress)
        !          1166: {
        !          1167:        long method = 0;
        !          1168: 
        !          1169:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &method) == FAILURE) {
        !          1170:                return;
        !          1171:        }
        !          1172: 
        !          1173:        phar_request_initialize(TSRMLS_C);
        !          1174:        switch (method) {
        !          1175:        case PHAR_ENT_COMPRESSED_GZ:
        !          1176:                if (PHAR_G(has_zlib)) {
        !          1177:                        RETURN_TRUE;
        !          1178:                } else {
        !          1179:                        RETURN_FALSE;
        !          1180:                }
        !          1181:        case PHAR_ENT_COMPRESSED_BZ2:
        !          1182:                if (PHAR_G(has_bz2)) {
        !          1183:                        RETURN_TRUE;
        !          1184:                } else {
        !          1185:                        RETURN_FALSE;
        !          1186:                }
        !          1187:        default:
        !          1188:                if (PHAR_G(has_zlib) || PHAR_G(has_bz2)) {
        !          1189:                        RETURN_TRUE;
        !          1190:                } else {
        !          1191:                        RETURN_FALSE;
        !          1192:                }
        !          1193:        }
        !          1194: }
        !          1195: /* }}} */
        !          1196: 
        !          1197: /* {{{ proto bool Phar::canWrite()
        !          1198:  * Returns whether phar extension supports writing and creating phars */
        !          1199: PHP_METHOD(Phar, canWrite)
        !          1200: {
        !          1201:        if (zend_parse_parameters_none() == FAILURE) {
        !          1202:                return;
        !          1203:        }
        !          1204:        RETURN_BOOL(!PHAR_G(readonly));
        !          1205: }
        !          1206: /* }}} */
        !          1207: 
        !          1208: /* {{{ proto bool Phar::isValidPharFilename(string filename[, bool executable = true])
        !          1209:  * Returns whether the given filename is a valid phar filename */
        !          1210: PHP_METHOD(Phar, isValidPharFilename)
        !          1211: {
        !          1212:        char *fname;
        !          1213:        const char *ext_str;
        !          1214:        int fname_len, ext_len, is_executable;
        !          1215:        zend_bool executable = 1;
        !          1216: 
        !          1217:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &fname, &fname_len, &executable) == FAILURE) {
        !          1218:                return;
        !          1219:        }
        !          1220: 
        !          1221:        is_executable = executable;
        !          1222:        RETVAL_BOOL(phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, is_executable, 2, 1 TSRMLS_CC) == SUCCESS);
        !          1223: }
        !          1224: /* }}} */
        !          1225: 
        !          1226: #if HAVE_SPL
        !          1227: /**
        !          1228:  * from spl_directory
        !          1229:  */
        !          1230: static void phar_spl_foreign_dtor(spl_filesystem_object *object TSRMLS_DC) /* {{{ */
        !          1231: {
        !          1232:        phar_archive_data *phar = (phar_archive_data *) object->oth;
        !          1233: 
        !          1234:        if (!phar->is_persistent) {
        !          1235:                phar_archive_delref(phar TSRMLS_CC);
        !          1236:        }
        !          1237: 
        !          1238:        object->oth = NULL;
        !          1239: }
        !          1240: /* }}} */
        !          1241: 
        !          1242: /**
        !          1243:  * from spl_directory
        !          1244:  */
        !          1245: static void phar_spl_foreign_clone(spl_filesystem_object *src, spl_filesystem_object *dst TSRMLS_DC) /* {{{ */
        !          1246: {
        !          1247:        phar_archive_data *phar_data = (phar_archive_data *) dst->oth;
        !          1248: 
        !          1249:        if (!phar_data->is_persistent) {
        !          1250:                ++(phar_data->refcount);
        !          1251:        }
        !          1252: }
        !          1253: /* }}} */
        !          1254: 
        !          1255: static spl_other_handler phar_spl_foreign_handler = {
        !          1256:        phar_spl_foreign_dtor,
        !          1257:        phar_spl_foreign_clone
        !          1258: };
        !          1259: #endif /* HAVE_SPL */
        !          1260: 
        !          1261: /* {{{ proto void Phar::__construct(string fname [, int flags [, string alias]])
        !          1262:  * Construct a Phar archive object
        !          1263:  *
        !          1264:  * proto void PharData::__construct(string fname [[, int flags [, string alias]], int file format = Phar::TAR])
        !          1265:  * Construct a PharData archive object
        !          1266:  *
        !          1267:  * This function is used as the constructor for both the Phar and PharData
        !          1268:  * classes, hence the two prototypes above.
        !          1269:  */
        !          1270: PHP_METHOD(Phar, __construct)
        !          1271: {
        !          1272: #if !HAVE_SPL
        !          1273:        zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Cannot instantiate Phar object without SPL extension");
        !          1274: #else
        !          1275:        char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname;
        !          1276:        int fname_len, alias_len = 0, arch_len, entry_len, is_data;
        !          1277: #if PHP_VERSION_ID < 50300
        !          1278:        long flags = 0;
        !          1279: #else
        !          1280:        long flags = SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS;
        !          1281: #endif
        !          1282:        long format = 0;
        !          1283:        phar_archive_object *phar_obj;
        !          1284:        phar_archive_data   *phar_data;
        !          1285:        zval *zobj = getThis(), arg1, arg2;
        !          1286: 
        !          1287:        phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
        !          1288: 
        !          1289:        is_data = instanceof_function(Z_OBJCE_P(zobj), phar_ce_data TSRMLS_CC);
        !          1290: 
        !          1291:        if (is_data) {
        !          1292:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!l", &fname, &fname_len, &flags, &alias, &alias_len, &format) == FAILURE) {
        !          1293:                        return;
        !          1294:                }
        !          1295:        } else {
        !          1296:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) {
        !          1297:                        return;
        !          1298:                }
        !          1299:        }
        !          1300: 
        !          1301:        if (phar_obj->arc.archive) {
        !          1302:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
        !          1303:                return;
        !          1304:        }
        !          1305: 
        !          1306:        save_fname = fname;
        !          1307:        if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, !is_data, 2 TSRMLS_CC)) {
        !          1308:                /* use arch (the basename for the archive) for fname instead of fname */
        !          1309:                /* this allows support for RecursiveDirectoryIterator of subdirectories */
        !          1310: #ifdef PHP_WIN32
        !          1311:                phar_unixify_path_separators(arch, arch_len);
        !          1312: #endif
        !          1313:                fname = arch;
        !          1314:                fname_len = arch_len;
        !          1315: #ifdef PHP_WIN32
        !          1316:        } else {
        !          1317:                arch = estrndup(fname, fname_len);
        !          1318:                arch_len = fname_len;
        !          1319:                fname = arch;
        !          1320:                phar_unixify_path_separators(arch, arch_len);
        !          1321: #endif
        !          1322:        }
        !          1323: 
        !          1324:        if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, is_data, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
        !          1325: 
        !          1326:                if (fname == arch && fname != save_fname) {
        !          1327:                        efree(arch);
        !          1328:                        fname = save_fname;
        !          1329:                }
        !          1330: 
        !          1331:                if (entry) {
        !          1332:                        efree(entry);
        !          1333:                }
        !          1334: 
        !          1335:                if (error) {
        !          1336:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          1337:                                "%s", error);
        !          1338:                        efree(error);
        !          1339:                } else {
        !          1340:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          1341:                                "Phar creation or opening failed");
        !          1342:                }
        !          1343: 
        !          1344:                return;
        !          1345:        }
        !          1346: 
        !          1347:        if (is_data && phar_data->is_tar && phar_data->is_brandnew && format == PHAR_FORMAT_ZIP) {
        !          1348:                phar_data->is_zip = 1;
        !          1349:                phar_data->is_tar = 0;
        !          1350:        }
        !          1351: 
        !          1352:        if (fname == arch) {
        !          1353:                efree(arch);
        !          1354:                fname = save_fname;
        !          1355:        }
        !          1356: 
        !          1357:        if ((is_data && !phar_data->is_data) || (!is_data && phar_data->is_data)) {
        !          1358:                if (is_data) {
        !          1359:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          1360:                                "PharData class can only be used for non-executable tar and zip archives");
        !          1361:                } else {
        !          1362:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          1363:                                "Phar class can only be used for executable tar and zip archives");
        !          1364:                }
        !          1365:                efree(entry);
        !          1366:                return;
        !          1367:        }
        !          1368: 
        !          1369:        is_data = phar_data->is_data;
        !          1370: 
        !          1371:        if (!phar_data->is_persistent) {
        !          1372:                ++(phar_data->refcount);
        !          1373:        }
        !          1374: 
        !          1375:        phar_obj->arc.archive = phar_data;
        !          1376:        phar_obj->spl.oth_handler = &phar_spl_foreign_handler;
        !          1377: 
        !          1378:        if (entry) {
        !          1379:                fname_len = spprintf(&fname, 0, "phar://%s%s", phar_data->fname, entry);
        !          1380:                efree(entry);
        !          1381:        } else {
        !          1382:                fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
        !          1383:        }
        !          1384: 
        !          1385:        INIT_PZVAL(&arg1);
        !          1386:        ZVAL_STRINGL(&arg1, fname, fname_len, 0);
        !          1387:        INIT_PZVAL(&arg2);
        !          1388:        ZVAL_LONG(&arg2, flags);
        !          1389: 
        !          1390:        zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj), 
        !          1391:                &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1, &arg2);
        !          1392: 
        !          1393:        if (!phar_data->is_persistent) {
        !          1394:                phar_obj->arc.archive->is_data = is_data;
        !          1395:        } else if (!EG(exception)) {
        !          1396:                /* register this guy so we can modify if necessary */
        !          1397:                zend_hash_add(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive), (void *) &phar_obj, sizeof(phar_archive_object **), NULL);
        !          1398:        }
        !          1399: 
        !          1400:        phar_obj->spl.info_class = phar_ce_entry;
        !          1401:        efree(fname);
        !          1402: #endif /* HAVE_SPL */
        !          1403: }
        !          1404: /* }}} */
        !          1405: 
        !          1406: /* {{{ proto array Phar::getSupportedSignatures()
        !          1407:  * Return array of supported signature types
        !          1408:  */
        !          1409: PHP_METHOD(Phar, getSupportedSignatures)
        !          1410: {
        !          1411:        if (zend_parse_parameters_none() == FAILURE) {
        !          1412:                return;
        !          1413:        }
        !          1414:        
        !          1415:        array_init(return_value);
        !          1416: 
        !          1417:        add_next_index_stringl(return_value, "MD5", 3, 1);
        !          1418:        add_next_index_stringl(return_value, "SHA-1", 5, 1);
        !          1419: #ifdef PHAR_HASH_OK
        !          1420:        add_next_index_stringl(return_value, "SHA-256", 7, 1);
        !          1421:        add_next_index_stringl(return_value, "SHA-512", 7, 1);
        !          1422: #endif
        !          1423: #if PHAR_HAVE_OPENSSL
        !          1424:        add_next_index_stringl(return_value, "OpenSSL", 7, 1);
        !          1425: #else
        !          1426:        if (zend_hash_exists(&module_registry, "openssl", sizeof("openssl"))) {
        !          1427:                add_next_index_stringl(return_value, "OpenSSL", 7, 1);
        !          1428:        }
        !          1429: #endif
        !          1430: }
        !          1431: /* }}} */
        !          1432: 
        !          1433: /* {{{ proto array Phar::getSupportedCompression()
        !          1434:  * Return array of supported comparession algorithms
        !          1435:  */
        !          1436: PHP_METHOD(Phar, getSupportedCompression)
        !          1437: {
        !          1438:        if (zend_parse_parameters_none() == FAILURE) {
        !          1439:                return;
        !          1440:        }
        !          1441:        
        !          1442:        array_init(return_value);
        !          1443:        phar_request_initialize(TSRMLS_C);
        !          1444: 
        !          1445:        if (PHAR_G(has_zlib)) {
        !          1446:                add_next_index_stringl(return_value, "GZ", 2, 1);
        !          1447:        }
        !          1448: 
        !          1449:        if (PHAR_G(has_bz2)) {
        !          1450:                add_next_index_stringl(return_value, "BZIP2", 5, 1);
        !          1451:        }
        !          1452: }
        !          1453: /* }}} */
        !          1454: 
        !          1455: /* {{{ proto array Phar::unlinkArchive(string archive)
        !          1456:  * Completely remove a phar archive from memory and disk
        !          1457:  */
        !          1458: PHP_METHOD(Phar, unlinkArchive)
        !          1459: {
        !          1460:        char *fname, *error, *zname, *arch, *entry;
        !          1461:        int fname_len, zname_len, arch_len, entry_len;
        !          1462:        phar_archive_data *phar;
        !          1463: 
        !          1464:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
        !          1465:                RETURN_FALSE;
        !          1466:        }
        !          1467: 
        !          1468:        if (!fname_len) {
        !          1469:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown phar archive \"\"");
        !          1470:                return;
        !          1471:        }
        !          1472: 
        !          1473:        if (FAILURE == phar_open_from_filename(fname, fname_len, NULL, 0, REPORT_ERRORS, &phar, &error TSRMLS_CC)) {
        !          1474:                if (error) {
        !          1475:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown phar archive \"%s\": %s", fname, error);
        !          1476:                        efree(error);
        !          1477:                } else {
        !          1478:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown phar archive \"%s\"", fname);
        !          1479:                }
        !          1480:                return;
        !          1481:        }
        !          1482: 
        !          1483:        zname = zend_get_executed_filename(TSRMLS_C);
        !          1484:        zname_len = strlen(zname);
        !          1485: 
        !          1486:        if (zname_len > 7 && !memcmp(zname, "phar://", 7) && SUCCESS == phar_split_fname(zname, zname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
        !          1487:                if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) {
        !          1488:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar archive \"%s\" cannot be unlinked from within itself", fname);
        !          1489:                        efree(arch);
        !          1490:                        efree(entry);
        !          1491:                        return;
        !          1492:                }
        !          1493:                efree(arch);
        !          1494:                efree(entry);
        !          1495:        }
        !          1496: 
        !          1497:        if (phar->is_persistent) {
        !          1498:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar archive \"%s\" is in phar.cache_list, cannot unlinkArchive()", fname);
        !          1499:                return;
        !          1500:        }
        !          1501: 
        !          1502:        if (phar->refcount) {
        !          1503:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar archive \"%s\" has open file handles or objects.  fclose() all file handles, and unset() all objects prior to calling unlinkArchive()", fname);
        !          1504:                return;
        !          1505:        }
        !          1506: 
        !          1507:        fname = estrndup(phar->fname, phar->fname_len);
        !          1508: 
        !          1509:        /* invalidate phar cache */
        !          1510:        PHAR_G(last_phar) = NULL;
        !          1511:        PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
        !          1512: 
        !          1513:        phar_archive_delref(phar TSRMLS_CC);
        !          1514:        unlink(fname);
        !          1515:        efree(fname);
        !          1516:        RETURN_TRUE;
        !          1517: }
        !          1518: /* }}} */
        !          1519: 
        !          1520: #if HAVE_SPL
        !          1521: 
        !          1522: #define PHAR_ARCHIVE_OBJECT() \
        !          1523:        phar_archive_object *phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
        !          1524:        if (!phar_obj->arc.archive) { \
        !          1525:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          1526:                        "Cannot call method on an uninitialized Phar object"); \
        !          1527:                return; \
        !          1528:        }
        !          1529: 
        !          1530: /* {{{ proto void Phar::__destruct()
        !          1531:  * if persistent, remove from the cache
        !          1532:  */
        !          1533: PHP_METHOD(Phar, __destruct)
        !          1534: {
        !          1535:        phar_archive_object *phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
        !          1536: 
        !          1537:        if (phar_obj->arc.archive && phar_obj->arc.archive->is_persistent) {
        !          1538:                zend_hash_del(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive));
        !          1539:        }
        !          1540: }
        !          1541: /* }}} */
        !          1542: 
        !          1543: struct _phar_t {
        !          1544:        phar_archive_object *p;
        !          1545:        zend_class_entry *c;
        !          1546:        char *b;
        !          1547:        uint l;
        !          1548:        zval *ret;
        !          1549:        int count;
        !          1550:        php_stream *fp;
        !          1551: };
        !          1552: 
        !          1553: static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */
        !          1554: {
        !          1555:        zval **value;
        !          1556:        zend_uchar key_type;
        !          1557:        zend_bool close_fp = 1;
        !          1558:        ulong int_key;
        !          1559:        struct _phar_t *p_obj = (struct _phar_t*) puser;
        !          1560:        uint str_key_len, base_len = p_obj->l, fname_len;
        !          1561:        phar_entry_data *data;
        !          1562:        php_stream *fp;
        !          1563:        size_t contents_len;
        !          1564:        char *fname, *error = NULL, *base = p_obj->b, *opened, *save = NULL, *temp = NULL;
        !          1565:        phar_zstr key;
        !          1566:        char *str_key;
        !          1567:        zend_class_entry *ce = p_obj->c;
        !          1568:        phar_archive_object *phar_obj = p_obj->p;
        !          1569:        char *str = "[stream]";
        !          1570: 
        !          1571:        iter->funcs->get_current_data(iter, &value TSRMLS_CC);
        !          1572: 
        !          1573:        if (EG(exception)) {
        !          1574:                return ZEND_HASH_APPLY_STOP;
        !          1575:        }
        !          1576: 
        !          1577:        if (!value) {
        !          1578:                /* failure in get_current_data */
        !          1579:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned no value", ce->name);
        !          1580:                return ZEND_HASH_APPLY_STOP;
        !          1581:        }
        !          1582: 
        !          1583:        switch (Z_TYPE_PP(value)) {
        !          1584: #if PHP_VERSION_ID >= 60000
        !          1585:                case IS_UNICODE:
        !          1586:                        zval_unicode_to_string(*(value) TSRMLS_CC);
        !          1587:                        /* break intentionally omitted */
        !          1588: #endif
        !          1589:                case IS_STRING:
        !          1590:                        break;
        !          1591:                case IS_RESOURCE:
        !          1592:                        php_stream_from_zval_no_verify(fp, value);
        !          1593: 
        !          1594:                        if (!fp) {
        !          1595:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator %v returned an invalid stream handle", ce->name);
        !          1596:                                return ZEND_HASH_APPLY_STOP;
        !          1597:                        }
        !          1598: 
        !          1599:                        if (iter->funcs->get_current_key) {
        !          1600:                                key_type = iter->funcs->get_current_key(iter, &key, &str_key_len, &int_key TSRMLS_CC);
        !          1601: 
        !          1602:                                if (EG(exception)) {
        !          1603:                                        return ZEND_HASH_APPLY_STOP;
        !          1604:                                }
        !          1605: 
        !          1606:                                if (key_type == HASH_KEY_IS_LONG) {
        !          1607:                                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
        !          1608:                                        return ZEND_HASH_APPLY_STOP;
        !          1609:                                }
        !          1610: 
        !          1611:                                if (key_type > 9) { /* IS_UNICODE == 10 */
        !          1612: #if PHP_VERSION_ID < 60000
        !          1613: /* this can never happen, but fixes a compile warning */
        !          1614:                                        spprintf(&str_key, 0, "%s", key);
        !          1615: #else
        !          1616:                                        spprintf(&str_key, 0, "%v", key);
        !          1617:                                        ezfree(key);
        !          1618: #endif
        !          1619:                                } else {
        !          1620:                                        PHAR_STR(key, str_key);
        !          1621:                                }
        !          1622: 
        !          1623:                                save = str_key;
        !          1624: 
        !          1625:                                if (str_key[str_key_len - 1] == '\0') {
        !          1626:                                        str_key_len--;
        !          1627:                                }
        !          1628: 
        !          1629:                        } else {
        !          1630:                                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
        !          1631:                                return ZEND_HASH_APPLY_STOP;
        !          1632:                        }
        !          1633: 
        !          1634:                        close_fp = 0;
        !          1635:                        opened = (char *) estrndup(str, sizeof("[stream]") + 1);
        !          1636:                        goto after_open_fp;
        !          1637:                case IS_OBJECT:
        !          1638:                        if (instanceof_function(Z_OBJCE_PP(value), spl_ce_SplFileInfo TSRMLS_CC)) {
        !          1639:                                char *test = NULL;
        !          1640:                                zval dummy;
        !          1641:                                spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(*value TSRMLS_CC);
        !          1642: 
        !          1643:                                if (!base_len) {
        !          1644:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator %v returns an SplFileInfo object, so base directory must be specified", ce->name);
        !          1645:                                        return ZEND_HASH_APPLY_STOP;
        !          1646:                                }
        !          1647: 
        !          1648:                                switch (intern->type) {
        !          1649:                                        case SPL_FS_DIR:
        !          1650: #if PHP_VERSION_ID >= 60000
        !          1651:                                                test = spl_filesystem_object_get_path(intern, NULL, NULL TSRMLS_CC).s;
        !          1652: #elif PHP_VERSION_ID >= 50300
        !          1653:                                                test = spl_filesystem_object_get_path(intern, NULL TSRMLS_CC);
        !          1654: #else
        !          1655:                                                test = intern->path;
        !          1656: #endif
        !          1657:                                                fname_len = spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name);
        !          1658:                                                php_stat(fname, fname_len, FS_IS_DIR, &dummy TSRMLS_CC);
        !          1659: 
        !          1660:                                                if (Z_BVAL(dummy)) {
        !          1661:                                                        /* ignore directories */
        !          1662:                                                        efree(fname);
        !          1663:                                                        return ZEND_HASH_APPLY_KEEP;
        !          1664:                                                }
        !          1665: 
        !          1666:                                                test = expand_filepath(fname, NULL TSRMLS_CC);
        !          1667:                                                efree(fname);
        !          1668: 
        !          1669:                                                if (test) {
        !          1670:                                                        fname = test;
        !          1671:                                                        fname_len = strlen(fname);
        !          1672:                                                } else {
        !          1673:                                                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Could not resolve file path");
        !          1674:                                                        return ZEND_HASH_APPLY_STOP;
        !          1675:                                                }
        !          1676: 
        !          1677:                                                save = fname;
        !          1678:                                                goto phar_spl_fileinfo;
        !          1679:                                        case SPL_FS_INFO:
        !          1680:                                        case SPL_FS_FILE:
        !          1681: #if PHP_VERSION_ID >= 60000
        !          1682:                                                if (intern->file_name_type == IS_UNICODE) {
        !          1683:                                                        zval zv;
        !          1684: 
        !          1685:                                                        INIT_ZVAL(zv);
        !          1686:                                                        Z_UNIVAL(zv) = intern->file_name;
        !          1687:                                                        Z_UNILEN(zv) = intern->file_name_len;
        !          1688:                                                        Z_TYPE(zv) = IS_UNICODE;
        !          1689: 
        !          1690:                                                        zval_copy_ctor(&zv);
        !          1691:                                                        zval_unicode_to_string(&zv TSRMLS_CC);
        !          1692:                                                        fname = expand_filepath(Z_STRVAL(zv), NULL TSRMLS_CC);
        !          1693:                                                        ezfree(Z_UNIVAL(zv));
        !          1694:                                                } else {
        !          1695:                                                        fname = expand_filepath(intern->file_name.s, NULL TSRMLS_CC);
        !          1696:                                                }
        !          1697: #else
        !          1698:                                                fname = expand_filepath(intern->file_name, NULL TSRMLS_CC);
        !          1699: #endif
        !          1700:                                                if (!fname) {
        !          1701:                                                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Could not resolve file path");
        !          1702:                                                        return ZEND_HASH_APPLY_STOP;
        !          1703:                                                }
        !          1704: 
        !          1705:                                                fname_len = strlen(fname);
        !          1706:                                                save = fname;
        !          1707:                                                goto phar_spl_fileinfo;
        !          1708:                                }
        !          1709:                        }
        !          1710:                        /* fall-through */
        !          1711:                default:
        !          1712:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid value (must return a string)", ce->name);
        !          1713:                        return ZEND_HASH_APPLY_STOP;
        !          1714:        }
        !          1715: 
        !          1716:        fname = Z_STRVAL_PP(value);
        !          1717:        fname_len = Z_STRLEN_PP(value);
        !          1718: 
        !          1719: phar_spl_fileinfo:
        !          1720:        if (base_len) {
        !          1721:                temp = expand_filepath(base, NULL TSRMLS_CC);
        !          1722:                if (!temp) {
        !          1723:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Could not resolve file path");
        !          1724:                        if (save) {
        !          1725:                                efree(save);
        !          1726:                        }
        !          1727:                        return ZEND_HASH_APPLY_STOP;
        !          1728:                }
        !          1729:                
        !          1730:                base = temp;
        !          1731:                base_len = strlen(base);
        !          1732: 
        !          1733:                if (strstr(fname, base)) {
        !          1734:                        str_key_len = fname_len - base_len;
        !          1735: 
        !          1736:                        if (str_key_len <= 0) {
        !          1737:                                if (save) {
        !          1738:                                        efree(save);
        !          1739:                                        efree(temp);
        !          1740:                                }
        !          1741:                                return ZEND_HASH_APPLY_KEEP;
        !          1742:                        }
        !          1743: 
        !          1744:                        str_key = fname + base_len;
        !          1745: 
        !          1746:                        if (*str_key == '/' || *str_key == '\\') {
        !          1747:                                str_key++;
        !          1748:                                str_key_len--;
        !          1749:                        }
        !          1750: 
        !          1751:                } else {
        !          1752:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned a path \"%s\" that is not in the base directory \"%s\"", ce->name, fname, base);
        !          1753: 
        !          1754:                        if (save) {
        !          1755:                                efree(save);
        !          1756:                                efree(temp);
        !          1757:                        }
        !          1758: 
        !          1759:                        return ZEND_HASH_APPLY_STOP;
        !          1760:                }
        !          1761:        } else {
        !          1762:                if (iter->funcs->get_current_key) {
        !          1763:                        key_type = iter->funcs->get_current_key(iter, &key, &str_key_len, &int_key TSRMLS_CC);
        !          1764: 
        !          1765:                        if (EG(exception)) {
        !          1766:                                return ZEND_HASH_APPLY_STOP;
        !          1767:                        }
        !          1768: 
        !          1769:                        if (key_type == HASH_KEY_IS_LONG) {
        !          1770:                                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
        !          1771:                                return ZEND_HASH_APPLY_STOP;
        !          1772:                        }
        !          1773: 
        !          1774:                        if (key_type > 9) { /* IS_UNICODE == 10 */
        !          1775: #if PHP_VERSION_ID < 60000
        !          1776: /* this can never happen, but fixes a compile warning */
        !          1777:                                spprintf(&str_key, 0, "%s", key);
        !          1778: #else
        !          1779:                                spprintf(&str_key, 0, "%v", key);
        !          1780:                                ezfree(key);
        !          1781: #endif
        !          1782:                        } else {
        !          1783:                                PHAR_STR(key, str_key);
        !          1784:                        }
        !          1785: 
        !          1786:                        save = str_key;
        !          1787: 
        !          1788:                        if (str_key[str_key_len - 1] == '\0') str_key_len--;
        !          1789:                } else {
        !          1790:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
        !          1791:                        return ZEND_HASH_APPLY_STOP;
        !          1792:                }
        !          1793:        }
        !          1794: #if PHP_API_VERSION < 20100412
        !          1795:        if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
        !          1796:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned a path \"%s\" that safe mode prevents opening", ce->name, fname);
        !          1797: 
        !          1798:                if (save) {
        !          1799:                        efree(save);
        !          1800:                }
        !          1801: 
        !          1802:                if (temp) {
        !          1803:                        efree(temp);
        !          1804:                }
        !          1805: 
        !          1806:                return ZEND_HASH_APPLY_STOP;
        !          1807:        }
        !          1808: #endif
        !          1809: 
        !          1810:        if (php_check_open_basedir(fname TSRMLS_CC)) {
        !          1811:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned a path \"%s\" that open_basedir prevents opening", ce->name, fname);
        !          1812: 
        !          1813:                if (save) {
        !          1814:                        efree(save);
        !          1815:                }
        !          1816: 
        !          1817:                if (temp) {
        !          1818:                        efree(temp);
        !          1819:                }
        !          1820: 
        !          1821:                return ZEND_HASH_APPLY_STOP;
        !          1822:        }
        !          1823: 
        !          1824:        /* try to open source file, then create internal phar file and copy contents */
        !          1825:        fp = php_stream_open_wrapper(fname, "rb", STREAM_MUST_SEEK|0, &opened);
        !          1826: 
        !          1827:        if (!fp) {
        !          1828:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned a file that could not be opened \"%s\"", ce->name, fname);
        !          1829: 
        !          1830:                if (save) {
        !          1831:                        efree(save);
        !          1832:                }
        !          1833: 
        !          1834:                if (temp) {
        !          1835:                        efree(temp);
        !          1836:                }
        !          1837: 
        !          1838:                return ZEND_HASH_APPLY_STOP;
        !          1839:        }
        !          1840: after_open_fp:
        !          1841:        if (str_key_len >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) {
        !          1842:                /* silently skip any files that would be added to the magic .phar directory */
        !          1843:                if (save) {
        !          1844:                        efree(save);
        !          1845:                }
        !          1846: 
        !          1847:                if (temp) {
        !          1848:                        efree(temp);
        !          1849:                }
        !          1850: 
        !          1851:                if (opened) {
        !          1852:                        efree(opened);
        !          1853:                }
        !          1854: 
        !          1855:                if (close_fp) {
        !          1856:                        php_stream_close(fp);
        !          1857:                }
        !          1858: 
        !          1859:                return ZEND_HASH_APPLY_KEEP;
        !          1860:        }
        !          1861: 
        !          1862:        if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, str_key, str_key_len, "w+b", 0, &error, 1 TSRMLS_CC))) {
        !          1863:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s cannot be created: %s", str_key, error);
        !          1864:                efree(error);
        !          1865: 
        !          1866:                if (save) {
        !          1867:                        efree(save);
        !          1868:                }
        !          1869: 
        !          1870:                if (opened) {
        !          1871:                        efree(opened);
        !          1872:                }
        !          1873: 
        !          1874:                if (temp) {
        !          1875:                        efree(temp);
        !          1876:                }
        !          1877: 
        !          1878:                if (close_fp) {
        !          1879:                        php_stream_close(fp);
        !          1880:                }
        !          1881: 
        !          1882:                return ZEND_HASH_APPLY_STOP;
        !          1883: 
        !          1884:        } else {
        !          1885:                if (error) {
        !          1886:                        efree(error);
        !          1887:                }
        !          1888:                /* convert to PHAR_UFP */
        !          1889:                if (data->internal_file->fp_type == PHAR_MOD) {
        !          1890:                        php_stream_close(data->internal_file->fp);
        !          1891:                }
        !          1892: 
        !          1893:                data->internal_file->fp = NULL;
        !          1894:                data->internal_file->fp_type = PHAR_UFP;
        !          1895:                data->internal_file->offset_abs = data->internal_file->offset = php_stream_tell(p_obj->fp);
        !          1896:                data->fp = NULL;
        !          1897:                phar_stream_copy_to_stream(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len);
        !          1898:                data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize =
        !          1899:                        php_stream_tell(p_obj->fp) - data->internal_file->offset;
        !          1900:        }
        !          1901: 
        !          1902:        if (close_fp) {
        !          1903:                php_stream_close(fp);
        !          1904:        }
        !          1905: 
        !          1906:        add_assoc_string(p_obj->ret, str_key, opened, 0);
        !          1907: 
        !          1908:        if (save) {
        !          1909:                efree(save);
        !          1910:        }
        !          1911: 
        !          1912:        if (temp) {
        !          1913:                efree(temp);
        !          1914:        }
        !          1915: 
        !          1916:        data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
        !          1917:        phar_entry_delref(data TSRMLS_CC);
        !          1918: 
        !          1919:        return ZEND_HASH_APPLY_KEEP;
        !          1920: }
        !          1921: /* }}} */
        !          1922: 
        !          1923: /* {{{ proto array Phar::buildFromDirectory(string base_dir[, string regex])
        !          1924:  * Construct a phar archive from an existing directory, recursively.
        !          1925:  * Optional second parameter is a regular expression for filtering directory contents.
        !          1926:  * 
        !          1927:  * Return value is an array mapping phar index to actual files added.
        !          1928:  */
        !          1929: PHP_METHOD(Phar, buildFromDirectory)
        !          1930: {
        !          1931:        char *dir, *error, *regex = NULL;
        !          1932:        int dir_len, regex_len = 0;
        !          1933:        zend_bool apply_reg = 0;
        !          1934:        zval arg, arg2, *iter, *iteriter, *regexiter = NULL;
        !          1935:        struct _phar_t pass;
        !          1936: 
        !          1937:        PHAR_ARCHIVE_OBJECT();
        !          1938: 
        !          1939:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          1940:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          1941:                        "Cannot write to archive - write operations restricted by INI setting");
        !          1942:                return;
        !          1943:        }
        !          1944: 
        !          1945:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &dir, &dir_len, &regex, &regex_len) == FAILURE) {
        !          1946:                RETURN_FALSE;
        !          1947:        }
        !          1948: 
        !          1949:        MAKE_STD_ZVAL(iter);
        !          1950: 
        !          1951:        if (SUCCESS != object_init_ex(iter, spl_ce_RecursiveDirectoryIterator)) {
        !          1952:                zval_ptr_dtor(&iter);
        !          1953:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate directory iterator for %s", phar_obj->arc.archive->fname);
        !          1954:                RETURN_FALSE;
        !          1955:        }
        !          1956: 
        !          1957:        INIT_PZVAL(&arg);
        !          1958:        ZVAL_STRINGL(&arg, dir, dir_len, 0);
        !          1959:        INIT_PZVAL(&arg2);
        !          1960: #if PHP_VERSION_ID < 50300
        !          1961:        ZVAL_LONG(&arg2, 0);
        !          1962: #else
        !          1963:        ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS);
        !          1964: #endif
        !          1965: 
        !          1966:        zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator, 
        !          1967:                        &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2);
        !          1968: 
        !          1969:        if (EG(exception)) {
        !          1970:                zval_ptr_dtor(&iter);
        !          1971:                RETURN_FALSE;
        !          1972:        }
        !          1973: 
        !          1974:        MAKE_STD_ZVAL(iteriter);
        !          1975: 
        !          1976:        if (SUCCESS != object_init_ex(iteriter, spl_ce_RecursiveIteratorIterator)) {
        !          1977:                zval_ptr_dtor(&iter);
        !          1978:                zval_ptr_dtor(&iteriter);
        !          1979:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate directory iterator for %s", phar_obj->arc.archive->fname);
        !          1980:                RETURN_FALSE;
        !          1981:        }
        !          1982: 
        !          1983:        zend_call_method_with_1_params(&iteriter, spl_ce_RecursiveIteratorIterator, 
        !          1984:                        &spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, iter);
        !          1985: 
        !          1986:        if (EG(exception)) {
        !          1987:                zval_ptr_dtor(&iter);
        !          1988:                zval_ptr_dtor(&iteriter);
        !          1989:                RETURN_FALSE;
        !          1990:        }
        !          1991: 
        !          1992:        zval_ptr_dtor(&iter);
        !          1993: 
        !          1994:        if (regex_len > 0) {
        !          1995:                apply_reg = 1;
        !          1996:                MAKE_STD_ZVAL(regexiter);
        !          1997: 
        !          1998:                if (SUCCESS != object_init_ex(regexiter, spl_ce_RegexIterator)) {
        !          1999:                        zval_ptr_dtor(&iteriter);
        !          2000:                        zval_dtor(regexiter);
        !          2001:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate regex iterator for %s", phar_obj->arc.archive->fname);
        !          2002:                        RETURN_FALSE;
        !          2003:                }
        !          2004: 
        !          2005:                INIT_PZVAL(&arg2);
        !          2006:                ZVAL_STRINGL(&arg2, regex, regex_len, 0);
        !          2007: 
        !          2008:                zend_call_method_with_2_params(&regexiter, spl_ce_RegexIterator, 
        !          2009:                        &spl_ce_RegexIterator->constructor, "__construct", NULL, iteriter, &arg2);
        !          2010:        }
        !          2011: 
        !          2012:        array_init(return_value);
        !          2013: 
        !          2014:        pass.c = apply_reg ? Z_OBJCE_P(regexiter) : Z_OBJCE_P(iteriter);
        !          2015:        pass.p = phar_obj;
        !          2016:        pass.b = dir;
        !          2017:        pass.l = dir_len;
        !          2018:        pass.count = 0;
        !          2019:        pass.ret = return_value;
        !          2020:        pass.fp = php_stream_fopen_tmpfile();
        !          2021: 
        !          2022:        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          2023:                zval_ptr_dtor(&iteriter);
        !          2024:                if (apply_reg) {
        !          2025:                        zval_ptr_dtor(&regexiter);
        !          2026:                }
        !          2027:                php_stream_close(pass.fp);
        !          2028:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          2029:                return;
        !          2030:        }
        !          2031: 
        !          2032:        if (SUCCESS == spl_iterator_apply((apply_reg ? regexiter : iteriter), (spl_iterator_apply_func_t) phar_build, (void *) &pass TSRMLS_CC)) {
        !          2033:                zval_ptr_dtor(&iteriter);
        !          2034: 
        !          2035:                if (apply_reg) {
        !          2036:                        zval_ptr_dtor(&regexiter);
        !          2037:                }
        !          2038: 
        !          2039:                phar_obj->arc.archive->ufp = pass.fp;
        !          2040:                phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          2041: 
        !          2042:                if (error) {
        !          2043:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          2044:                        efree(error);
        !          2045:                }
        !          2046: 
        !          2047:        } else {
        !          2048:                zval_ptr_dtor(&iteriter);
        !          2049:                if (apply_reg) {
        !          2050:                        zval_ptr_dtor(&regexiter);
        !          2051:                }
        !          2052:                php_stream_close(pass.fp);
        !          2053:        }
        !          2054: }
        !          2055: /* }}} */
        !          2056: 
        !          2057: /* {{{ proto array Phar::buildFromIterator(Iterator iter[, string base_directory])
        !          2058:  * Construct a phar archive from an iterator.  The iterator must return a series of strings
        !          2059:  * that are full paths to files that should be added to the phar.  The iterator key should
        !          2060:  * be the path that the file will have within the phar archive.
        !          2061:  *
        !          2062:  * If base directory is specified, then the key will be ignored, and instead the portion of
        !          2063:  * the current value minus the base directory will be used
        !          2064:  *
        !          2065:  * Returned is an array mapping phar index to actual file added
        !          2066:  */
        !          2067: PHP_METHOD(Phar, buildFromIterator)
        !          2068: {
        !          2069:        zval *obj;
        !          2070:        char *error;
        !          2071:        uint base_len = 0;
        !          2072:        char *base = NULL;
        !          2073:        struct _phar_t pass;
        !          2074: 
        !          2075:        PHAR_ARCHIVE_OBJECT();
        !          2076: 
        !          2077:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          2078:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2079:                        "Cannot write out phar archive, phar is read-only");
        !          2080:                return;
        !          2081:        }
        !          2082: 
        !          2083:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|s", &obj, zend_ce_traversable, &base, &base_len) == FAILURE) {
        !          2084:                RETURN_FALSE;
        !          2085:        }
        !          2086: 
        !          2087:        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          2088:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          2089:                return;
        !          2090:        }
        !          2091: 
        !          2092:        array_init(return_value);
        !          2093: 
        !          2094:        pass.c = Z_OBJCE_P(obj);
        !          2095:        pass.p = phar_obj;
        !          2096:        pass.b = base;
        !          2097:        pass.l = base_len;
        !          2098:        pass.ret = return_value;
        !          2099:        pass.count = 0;
        !          2100:        pass.fp = php_stream_fopen_tmpfile();
        !          2101: 
        !          2102:        if (SUCCESS == spl_iterator_apply(obj, (spl_iterator_apply_func_t) phar_build, (void *) &pass TSRMLS_CC)) {
        !          2103:                phar_obj->arc.archive->ufp = pass.fp;
        !          2104:                phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          2105:                if (error) {
        !          2106:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          2107:                        efree(error);
        !          2108:                }
        !          2109:        } else {
        !          2110:                php_stream_close(pass.fp);
        !          2111:        }
        !          2112: }
        !          2113: /* }}} */
        !          2114: 
        !          2115: /* {{{ proto int Phar::count()
        !          2116:  * Returns the number of entries in the Phar archive
        !          2117:  */
        !          2118: PHP_METHOD(Phar, count)
        !          2119: {
        !          2120:        PHAR_ARCHIVE_OBJECT();
        !          2121:        
        !          2122:        if (zend_parse_parameters_none() == FAILURE) {
        !          2123:                return;
        !          2124:        }
        !          2125: 
        !          2126:        RETURN_LONG(zend_hash_num_elements(&phar_obj->arc.archive->manifest));
        !          2127: }
        !          2128: /* }}} */
        !          2129: 
        !          2130: /* {{{ proto bool Phar::isFileFormat(int format)
        !          2131:  * Returns true if the phar archive is based on the tar/zip/phar file format depending
        !          2132:  * on whether Phar::TAR, Phar::ZIP or Phar::PHAR was passed in
        !          2133:  */
        !          2134: PHP_METHOD(Phar, isFileFormat)
        !          2135: {
        !          2136:        long type;
        !          2137:        PHAR_ARCHIVE_OBJECT();
        !          2138: 
        !          2139:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type) == FAILURE) {
        !          2140:                RETURN_FALSE;
        !          2141:        }
        !          2142: 
        !          2143:        switch (type) {
        !          2144:                case PHAR_FORMAT_TAR:
        !          2145:                        RETURN_BOOL(phar_obj->arc.archive->is_tar);
        !          2146:                case PHAR_FORMAT_ZIP:
        !          2147:                        RETURN_BOOL(phar_obj->arc.archive->is_zip);
        !          2148:                case PHAR_FORMAT_PHAR:
        !          2149:                        RETURN_BOOL(!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip);
        !          2150:                default:
        !          2151:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown file format specified");
        !          2152:        }
        !          2153: }
        !          2154: /* }}} */
        !          2155: 
        !          2156: static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp TSRMLS_DC) /* {{{ */
        !          2157: {
        !          2158:        char *error;
        !          2159:        off_t offset;
        !          2160:        phar_entry_info *link;
        !          2161: 
        !          2162:        if (FAILURE == phar_open_entry_fp(entry, &error, 1 TSRMLS_CC)) {
        !          2163:                if (error) {
        !          2164:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2165:                                "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents: %s", entry->phar->fname, entry->filename, error);
        !          2166:                        efree(error);
        !          2167:                } else {
        !          2168:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2169:                                "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents", entry->phar->fname, entry->filename);
        !          2170:                }
        !          2171:                return FAILURE;
        !          2172:        }
        !          2173: 
        !          2174:        /* copy old contents in entirety */
        !          2175:        phar_seek_efp(entry, 0, SEEK_SET, 0, 1 TSRMLS_CC);
        !          2176:        offset = php_stream_tell(fp);
        !          2177:        link = phar_get_link_source(entry TSRMLS_CC);
        !          2178: 
        !          2179:        if (!link) {
        !          2180:                link = entry;
        !          2181:        }
        !          2182: 
        !          2183:        if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize, NULL)) {
        !          2184:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2185:                        "Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", entry->phar->fname, entry->filename);
        !          2186:                return FAILURE;
        !          2187:        }
        !          2188: 
        !          2189:        if (entry->fp_type == PHAR_MOD) {
        !          2190:                /* save for potential restore on error */
        !          2191:                entry->cfp = entry->fp;
        !          2192:                entry->fp = NULL;
        !          2193:        }
        !          2194: 
        !          2195:        /* set new location of file contents */
        !          2196:        entry->fp_type = PHAR_FP;
        !          2197:        entry->offset = offset;
        !          2198:        return SUCCESS;
        !          2199: }
        !          2200: /* }}} */
        !          2201: 
        !          2202: static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */
        !          2203: {
        !          2204:        char *oldname = NULL, *oldpath = NULL;
        !          2205:        char *basename = NULL, *basepath = NULL;
        !          2206:        char *newname = NULL, *newpath = NULL;
        !          2207:        zval *ret, arg1;
        !          2208:        zend_class_entry *ce;
        !          2209:        char *error;
        !          2210:        const char *pcr_error;
        !          2211:        int ext_len = ext ? strlen(ext) : 0;
        !          2212:        int oldname_len;
        !          2213:        phar_archive_data **pphar = NULL;
        !          2214:        php_stream_statbuf ssb;
        !          2215: 
        !          2216:        if (!ext) {
        !          2217:                if (phar->is_zip) {
        !          2218: 
        !          2219:                        if (phar->is_data) {
        !          2220:                                ext = "zip";
        !          2221:                        } else {
        !          2222:                                ext = "phar.zip";
        !          2223:                        }
        !          2224: 
        !          2225:                } else if (phar->is_tar) {
        !          2226: 
        !          2227:                        switch (phar->flags) {
        !          2228:                                case PHAR_FILE_COMPRESSED_GZ:
        !          2229:                                        if (phar->is_data) {
        !          2230:                                                ext = "tar.gz";
        !          2231:                                        } else {
        !          2232:                                                ext = "phar.tar.gz";
        !          2233:                                        }
        !          2234:                                        break;
        !          2235:                                case PHAR_FILE_COMPRESSED_BZ2:
        !          2236:                                        if (phar->is_data) {
        !          2237:                                                ext = "tar.bz2";
        !          2238:                                        } else {
        !          2239:                                                ext = "phar.tar.bz2";
        !          2240:                                        }
        !          2241:                                        break;
        !          2242:                                default:
        !          2243:                                        if (phar->is_data) {
        !          2244:                                                ext = "tar";
        !          2245:                                        } else {
        !          2246:                                                ext = "phar.tar";
        !          2247:                                        }
        !          2248:                        }
        !          2249:                } else {
        !          2250: 
        !          2251:                        switch (phar->flags) {
        !          2252:                                case PHAR_FILE_COMPRESSED_GZ:
        !          2253:                                        ext = "phar.gz";
        !          2254:                                        break;
        !          2255:                                case PHAR_FILE_COMPRESSED_BZ2:
        !          2256:                                        ext = "phar.bz2";
        !          2257:                                        break;
        !          2258:                                default:
        !          2259:                                        ext = "phar";
        !          2260:                        }
        !          2261:                }
        !          2262:        } else if (phar_path_check(&ext, &ext_len, &pcr_error) > pcr_is_ok) {
        !          2263: 
        !          2264:                if (phar->is_data) {
        !          2265:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "data phar converted from \"%s\" has invalid extension %s", phar->fname, ext);
        !          2266:                } else {
        !          2267:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "phar converted from \"%s\" has invalid extension %s", phar->fname, ext);
        !          2268:                }
        !          2269:                return NULL;
        !          2270:        }
        !          2271: 
        !          2272:        if (ext[0] == '.') {
        !          2273:                ++ext;
        !          2274:        }
        !          2275: 
        !          2276:        oldpath = estrndup(phar->fname, phar->fname_len);
        !          2277:        oldname = zend_memrchr(phar->fname, '/', phar->fname_len);
        !          2278:        ++oldname;
        !          2279:        oldname_len = strlen(oldname);
        !          2280: 
        !          2281:        basename = estrndup(oldname, oldname_len);
        !          2282:        spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext);
        !          2283:        efree(basename);
        !          2284: 
        !          2285:        
        !          2286: 
        !          2287:        basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len));
        !          2288:        phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
        !          2289:        phar->fname = newpath;
        !          2290:        phar->ext = newpath + phar->fname_len - strlen(ext) - 1;
        !          2291:        efree(basepath);
        !          2292:        efree(newname);
        !          2293: 
        !          2294:        if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, newpath, phar->fname_len, (void **) &pphar)) {
        !          2295:                efree(oldpath);
        !          2296:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars, new phar name is in phar.cache_list", phar->fname);
        !          2297:                return NULL;
        !          2298:        }
        !          2299: 
        !          2300:        if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void **) &pphar)) {
        !          2301:                if ((*pphar)->fname_len == phar->fname_len && !memcmp((*pphar)->fname, phar->fname, phar->fname_len)) {
        !          2302:                        if (!zend_hash_num_elements(&phar->manifest)) {
        !          2303:                                (*pphar)->is_tar = phar->is_tar;
        !          2304:                                (*pphar)->is_zip = phar->is_zip;
        !          2305:                                (*pphar)->is_data = phar->is_data;
        !          2306:                                (*pphar)->flags = phar->flags;
        !          2307:                                (*pphar)->fp = phar->fp;
        !          2308:                                phar->fp = NULL;
        !          2309:                                phar_destroy_phar_data(phar TSRMLS_CC);
        !          2310:                                phar = *pphar;
        !          2311:                                phar->refcount++;
        !          2312:                                newpath = oldpath;
        !          2313:                                goto its_ok;
        !          2314:                        }
        !          2315:                }
        !          2316: 
        !          2317:                efree(oldpath);
        !          2318:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars, a phar with that name already exists", phar->fname);
        !          2319:                return NULL;
        !          2320:        }
        !          2321: its_ok:
        !          2322:        if (SUCCESS == php_stream_stat_path(newpath, &ssb)) {
        !          2323:                efree(oldpath);
        !          2324:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "phar \"%s\" exists and must be unlinked prior to conversion", newpath);
        !          2325:                return NULL;
        !          2326:        }
        !          2327:        if (!phar->is_data) {
        !          2328:                if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &(phar->ext_len), 1, 1, 1 TSRMLS_CC)) {
        !          2329:                        efree(oldpath);
        !          2330:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "phar \"%s\" has invalid extension %s", phar->fname, ext);
        !          2331:                        return NULL;
        !          2332:                }
        !          2333: 
        !          2334:                if (phar->alias) {
        !          2335:                        if (phar->is_temporary_alias) {
        !          2336:                                phar->alias = NULL;
        !          2337:                                phar->alias_len = 0;
        !          2338:                        } else {
        !          2339:                                phar->alias = estrndup(newpath, strlen(newpath));
        !          2340:                                phar->alias_len = strlen(newpath);
        !          2341:                                phar->is_temporary_alias = 1;
        !          2342:                                zend_hash_update(&(PHAR_GLOBALS->phar_alias_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL);
        !          2343:                        }
        !          2344:                }
        !          2345: 
        !          2346:        } else {
        !          2347: 
        !          2348:                if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &(phar->ext_len), 0, 1, 1 TSRMLS_CC)) {
        !          2349:                        efree(oldpath);
        !          2350:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "data phar \"%s\" has invalid extension %s", phar->fname, ext);
        !          2351:                        return NULL;
        !          2352:                }
        !          2353: 
        !          2354:                phar->alias = NULL;
        !          2355:                phar->alias_len = 0;
        !          2356:        }
        !          2357: 
        !          2358:        if ((!pphar || phar == *pphar) && SUCCESS != zend_hash_update(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
        !          2359:                efree(oldpath);
        !          2360:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname);
        !          2361:                return NULL;
        !          2362:        }
        !          2363: 
        !          2364:        phar_flush(phar, 0, 0, 1, &error TSRMLS_CC);
        !          2365: 
        !          2366:        if (error) {
        !          2367:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s", error);
        !          2368:                efree(error);
        !          2369:                efree(oldpath);
        !          2370:                return NULL;
        !          2371:        }
        !          2372: 
        !          2373:        efree(oldpath);
        !          2374: 
        !          2375:        if (phar->is_data) {
        !          2376:                ce = phar_ce_data;
        !          2377:        } else {
        !          2378:                ce = phar_ce_archive;
        !          2379:        }
        !          2380: 
        !          2381:        MAKE_STD_ZVAL(ret);
        !          2382: 
        !          2383:        if (SUCCESS != object_init_ex(ret, ce)) {
        !          2384:                zval_dtor(ret);
        !          2385:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate phar object when converting archive \"%s\"", phar->fname);
        !          2386:                return NULL;
        !          2387:        }
        !          2388: 
        !          2389:        INIT_PZVAL(&arg1);
        !          2390:        ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len, 0);
        !          2391: 
        !          2392:        zend_call_method_with_1_params(&ret, ce, &ce->constructor, "__construct", NULL, &arg1);
        !          2393:        return ret;
        !          2394: }
        !          2395: /* }}} */
        !          2396: 
        !          2397: static zval *phar_convert_to_other(phar_archive_data *source, int convert, char *ext, php_uint32 flags TSRMLS_DC) /* {{{ */
        !          2398: {
        !          2399:        phar_archive_data *phar;
        !          2400:        phar_entry_info *entry, newentry;
        !          2401:        zval *ret;
        !          2402: 
        !          2403:        /* invalidate phar cache */
        !          2404:        PHAR_G(last_phar) = NULL;
        !          2405:        PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
        !          2406: 
        !          2407:        phar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data));
        !          2408:        /* set whole-archive compression and type from parameter */
        !          2409:        phar->flags = flags;
        !          2410:        phar->is_data = source->is_data;
        !          2411: 
        !          2412:        switch (convert) {
        !          2413:                case PHAR_FORMAT_TAR:
        !          2414:                        phar->is_tar = 1;
        !          2415:                        break;
        !          2416:                case PHAR_FORMAT_ZIP:
        !          2417:                        phar->is_zip = 1;
        !          2418:                        break;
        !          2419:                default:
        !          2420:                        phar->is_data = 0;
        !          2421:                        break;
        !          2422:        }
        !          2423: 
        !          2424:        zend_hash_init(&(phar->manifest), sizeof(phar_entry_info),
        !          2425:                zend_get_hash_value, destroy_phar_manifest_entry, 0);
        !          2426:        zend_hash_init(&phar->mounted_dirs, sizeof(char *),
        !          2427:                zend_get_hash_value, NULL, 0);
        !          2428:        zend_hash_init(&phar->virtual_dirs, sizeof(char *),
        !          2429:                zend_get_hash_value, NULL, 0);
        !          2430: 
        !          2431:        phar->fp = php_stream_fopen_tmpfile();
        !          2432:        phar->fname = source->fname;
        !          2433:        phar->fname_len = source->fname_len;
        !          2434:        phar->is_temporary_alias = source->is_temporary_alias;
        !          2435:        phar->alias = source->alias;
        !          2436: 
        !          2437:        if (source->metadata) {
        !          2438:                zval *t;
        !          2439: 
        !          2440:                t = source->metadata;
        !          2441:                ALLOC_ZVAL(phar->metadata);
        !          2442:                *phar->metadata = *t;
        !          2443:                zval_copy_ctor(phar->metadata);
        !          2444: #if PHP_VERSION_ID < 50300
        !          2445:                phar->metadata->refcount = 1;
        !          2446: #else
        !          2447:                Z_SET_REFCOUNT_P(phar->metadata, 1);
        !          2448: #endif
        !          2449: 
        !          2450:                phar->metadata_len = 0;
        !          2451:        }
        !          2452: 
        !          2453:        /* first copy each file's uncompressed contents to a temporary file and set per-file flags */
        !          2454:        for (zend_hash_internal_pointer_reset(&source->manifest); SUCCESS == zend_hash_has_more_elements(&source->manifest); zend_hash_move_forward(&source->manifest)) {
        !          2455: 
        !          2456:                if (FAILURE == zend_hash_get_current_data(&source->manifest, (void **) &entry)) {
        !          2457:                        zend_hash_destroy(&(phar->manifest));
        !          2458:                        php_stream_close(phar->fp);
        !          2459:                        efree(phar);
        !          2460:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2461:                                "Cannot convert phar archive \"%s\"", source->fname);
        !          2462:                        return NULL;
        !          2463:                }
        !          2464: 
        !          2465:                newentry = *entry;
        !          2466: 
        !          2467:                if (newentry.link) {
        !          2468:                        newentry.link = estrdup(newentry.link);
        !          2469:                        goto no_copy;
        !          2470:                }
        !          2471: 
        !          2472:                if (newentry.tmp) {
        !          2473:                        newentry.tmp = estrdup(newentry.tmp);
        !          2474:                        goto no_copy;
        !          2475:                }
        !          2476: 
        !          2477:                newentry.metadata_str.c = 0;
        !          2478: 
        !          2479:                if (FAILURE == phar_copy_file_contents(&newentry, phar->fp TSRMLS_CC)) {
        !          2480:                        zend_hash_destroy(&(phar->manifest));
        !          2481:                        php_stream_close(phar->fp);
        !          2482:                        efree(phar);
        !          2483:                        /* exception already thrown */
        !          2484:                        return NULL;
        !          2485:                }
        !          2486: no_copy:
        !          2487:                newentry.filename = estrndup(newentry.filename, newentry.filename_len);
        !          2488: 
        !          2489:                if (newentry.metadata) {
        !          2490:                        zval *t;
        !          2491: 
        !          2492:                        t = newentry.metadata;
        !          2493:                        ALLOC_ZVAL(newentry.metadata);
        !          2494:                        *newentry.metadata = *t;
        !          2495:                        zval_copy_ctor(newentry.metadata);
        !          2496: #if PHP_VERSION_ID < 50300
        !          2497:                        newentry.metadata->refcount = 1;
        !          2498: #else
        !          2499:                        Z_SET_REFCOUNT_P(newentry.metadata, 1);
        !          2500: #endif
        !          2501: 
        !          2502:                        newentry.metadata_str.c = NULL;
        !          2503:                        newentry.metadata_str.len = 0;
        !          2504:                }
        !          2505: 
        !          2506:                newentry.is_zip = phar->is_zip;
        !          2507:                newentry.is_tar = phar->is_tar;
        !          2508: 
        !          2509:                if (newentry.is_tar) {
        !          2510:                        newentry.tar_type = (entry->is_dir ? TAR_DIR : TAR_FILE);
        !          2511:                }
        !          2512: 
        !          2513:                newentry.is_modified = 1;
        !          2514:                newentry.phar = phar;
        !          2515:                newentry.old_flags = newentry.flags & ~PHAR_ENT_COMPRESSION_MASK; /* remove compression from old_flags */
        !          2516:                phar_set_inode(&newentry TSRMLS_CC);
        !          2517:                zend_hash_add(&(phar->manifest), newentry.filename, newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
        !          2518:                phar_add_virtual_dirs(phar, newentry.filename, newentry.filename_len TSRMLS_CC);
        !          2519:        }
        !          2520: 
        !          2521:        if ((ret = phar_rename_archive(phar, ext, 0 TSRMLS_CC))) {
        !          2522:                return ret;
        !          2523:        } else {
        !          2524:                zend_hash_destroy(&(phar->manifest));
        !          2525:                zend_hash_destroy(&(phar->mounted_dirs));
        !          2526:                zend_hash_destroy(&(phar->virtual_dirs));
        !          2527:                php_stream_close(phar->fp);
        !          2528:                efree(phar->fname);
        !          2529:                efree(phar);
        !          2530:                return NULL;
        !          2531:        }
        !          2532: }
        !          2533: /* }}} */
        !          2534: 
        !          2535: /* {{{ proto object Phar::convertToExecutable([int format[, int compression [, string file_ext]]])
        !          2536:  * Convert a phar.tar or phar.zip archive to the phar file format. The
        !          2537:  * optional parameter allows the user to determine the new
        !          2538:  * filename extension (default is phar).
        !          2539:  */
        !          2540: PHP_METHOD(Phar, convertToExecutable)
        !          2541: {
        !          2542:        char *ext = NULL;
        !          2543:        int is_data, ext_len = 0;
        !          2544:        php_uint32 flags;
        !          2545:        zval *ret;
        !          2546:        /* a number that is not 0, 1 or 2 (Which is also Greg's birthday, so there) */
        !          2547:        long format = 9021976, method = 9021976;
        !          2548:        PHAR_ARCHIVE_OBJECT();
        !          2549: 
        !          2550:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lls", &format, &method, &ext, &ext_len) == FAILURE) {
        !          2551:                return;
        !          2552:        }
        !          2553: 
        !          2554:        if (PHAR_G(readonly)) {
        !          2555:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2556:                        "Cannot write out executable phar archive, phar is read-only");
        !          2557:                return;
        !          2558:        }
        !          2559: 
        !          2560:        switch (format) {
        !          2561:                case 9021976:
        !          2562:                case PHAR_FORMAT_SAME: /* null is converted to 0 */
        !          2563:                        /* by default, use the existing format */
        !          2564:                        if (phar_obj->arc.archive->is_tar) {
        !          2565:                                format = PHAR_FORMAT_TAR;
        !          2566:                        } else if (phar_obj->arc.archive->is_zip) {
        !          2567:                                format = PHAR_FORMAT_ZIP;
        !          2568:                        } else {
        !          2569:                                format = PHAR_FORMAT_PHAR;
        !          2570:                        }
        !          2571:                        break;
        !          2572:                case PHAR_FORMAT_PHAR:
        !          2573:                case PHAR_FORMAT_TAR:
        !          2574:                case PHAR_FORMAT_ZIP:
        !          2575:                        break;
        !          2576:                default:
        !          2577:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2578:                                "Unknown file format specified, please pass one of Phar::PHAR, Phar::TAR or Phar::ZIP");
        !          2579:                        return;
        !          2580:        }
        !          2581: 
        !          2582:        switch (method) {
        !          2583:                case 9021976:
        !          2584:                        flags = phar_obj->arc.archive->flags & PHAR_FILE_COMPRESSION_MASK;
        !          2585:                        break;
        !          2586:                case 0:
        !          2587:                        flags = PHAR_FILE_COMPRESSED_NONE;
        !          2588:                        break;
        !          2589:                case PHAR_ENT_COMPRESSED_GZ:
        !          2590:                        if (format == PHAR_FORMAT_ZIP) {
        !          2591:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2592:                                        "Cannot compress entire archive with gzip, zip archives do not support whole-archive compression");
        !          2593:                                return;
        !          2594:                        }
        !          2595: 
        !          2596:                        if (!PHAR_G(has_zlib)) {
        !          2597:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2598:                                        "Cannot compress entire archive with gzip, enable ext/zlib in php.ini");
        !          2599:                                return;
        !          2600:                        }
        !          2601: 
        !          2602:                        flags = PHAR_FILE_COMPRESSED_GZ;
        !          2603:                        break;
        !          2604:                case PHAR_ENT_COMPRESSED_BZ2:
        !          2605:                        if (format == PHAR_FORMAT_ZIP) {
        !          2606:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2607:                                        "Cannot compress entire archive with bz2, zip archives do not support whole-archive compression");
        !          2608:                                return;
        !          2609:                        }
        !          2610: 
        !          2611:                        if (!PHAR_G(has_bz2)) {
        !          2612:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2613:                                        "Cannot compress entire archive with bz2, enable ext/bz2 in php.ini");
        !          2614:                                return;
        !          2615:                        }
        !          2616: 
        !          2617:                        flags = PHAR_FILE_COMPRESSED_BZ2;
        !          2618:                        break;
        !          2619:                default:
        !          2620:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2621:                                "Unknown compression specified, please pass one of Phar::GZ or Phar::BZ2");
        !          2622:                        return;
        !          2623:        }
        !          2624: 
        !          2625:        is_data = phar_obj->arc.archive->is_data;
        !          2626:        phar_obj->arc.archive->is_data = 0;
        !          2627:        ret = phar_convert_to_other(phar_obj->arc.archive, format, ext, flags TSRMLS_CC);
        !          2628:        phar_obj->arc.archive->is_data = is_data;
        !          2629: 
        !          2630:        if (ret) {
        !          2631:                RETURN_ZVAL(ret, 1, 1);
        !          2632:        } else {
        !          2633:                RETURN_NULL();
        !          2634:        }
        !          2635: }
        !          2636: /* }}} */
        !          2637: 
        !          2638: /* {{{ proto object Phar::convertToData([int format[, int compression [, string file_ext]]])
        !          2639:  * Convert an archive to a non-executable .tar or .zip.
        !          2640:  * The optional parameter allows the user to determine the new
        !          2641:  * filename extension (default is .zip or .tar).
        !          2642:  */
        !          2643: PHP_METHOD(Phar, convertToData)
        !          2644: {
        !          2645:        char *ext = NULL;
        !          2646:        int is_data, ext_len = 0;
        !          2647:        php_uint32 flags;
        !          2648:        zval *ret;
        !          2649:        /* a number that is not 0, 1 or 2 (Which is also Greg's birthday so there) */
        !          2650:        long format = 9021976, method = 9021976;
        !          2651:        PHAR_ARCHIVE_OBJECT();
        !          2652: 
        !          2653:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lls", &format, &method, &ext, &ext_len) == FAILURE) {
        !          2654:                return;
        !          2655:        }
        !          2656: 
        !          2657:        switch (format) {
        !          2658:                case 9021976:
        !          2659:                case PHAR_FORMAT_SAME: /* null is converted to 0 */
        !          2660:                        /* by default, use the existing format */
        !          2661:                        if (phar_obj->arc.archive->is_tar) {
        !          2662:                                format = PHAR_FORMAT_TAR;
        !          2663:                        } else if (phar_obj->arc.archive->is_zip) {
        !          2664:                                format = PHAR_FORMAT_ZIP;
        !          2665:                        } else {
        !          2666:                                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2667:                                        "Cannot write out data phar archive, use Phar::TAR or Phar::ZIP");
        !          2668:                                return;
        !          2669:                        }
        !          2670:                        break;
        !          2671:                case PHAR_FORMAT_PHAR:
        !          2672:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2673:                                "Cannot write out data phar archive, use Phar::TAR or Phar::ZIP");
        !          2674:                        return;
        !          2675:                case PHAR_FORMAT_TAR:
        !          2676:                case PHAR_FORMAT_ZIP:
        !          2677:                        break;
        !          2678:                default:
        !          2679:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2680:                                "Unknown file format specified, please pass one of Phar::TAR or Phar::ZIP");
        !          2681:                        return;
        !          2682:        }
        !          2683: 
        !          2684:        switch (method) {
        !          2685:                case 9021976:
        !          2686:                        flags = phar_obj->arc.archive->flags & PHAR_FILE_COMPRESSION_MASK;
        !          2687:                        break;
        !          2688:                case 0:
        !          2689:                        flags = PHAR_FILE_COMPRESSED_NONE;
        !          2690:                        break;
        !          2691:                case PHAR_ENT_COMPRESSED_GZ:
        !          2692:                        if (format == PHAR_FORMAT_ZIP) {
        !          2693:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2694:                                        "Cannot compress entire archive with gzip, zip archives do not support whole-archive compression");
        !          2695:                                return;
        !          2696:                        }
        !          2697: 
        !          2698:                        if (!PHAR_G(has_zlib)) {
        !          2699:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2700:                                        "Cannot compress entire archive with gzip, enable ext/zlib in php.ini");
        !          2701:                                return;
        !          2702:                        }
        !          2703: 
        !          2704:                        flags = PHAR_FILE_COMPRESSED_GZ;
        !          2705:                        break;
        !          2706:                case PHAR_ENT_COMPRESSED_BZ2:
        !          2707:                        if (format == PHAR_FORMAT_ZIP) {
        !          2708:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2709:                                        "Cannot compress entire archive with bz2, zip archives do not support whole-archive compression");
        !          2710:                                return;
        !          2711:                        }
        !          2712: 
        !          2713:                        if (!PHAR_G(has_bz2)) {
        !          2714:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2715:                                        "Cannot compress entire archive with bz2, enable ext/bz2 in php.ini");
        !          2716:                                return;
        !          2717:                        }
        !          2718: 
        !          2719:                        flags = PHAR_FILE_COMPRESSED_BZ2;
        !          2720:                        break;
        !          2721:                default:
        !          2722:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          2723:                                "Unknown compression specified, please pass one of Phar::GZ or Phar::BZ2");
        !          2724:                        return;
        !          2725:        }
        !          2726: 
        !          2727:        is_data = phar_obj->arc.archive->is_data;
        !          2728:        phar_obj->arc.archive->is_data = 1;
        !          2729:        ret = phar_convert_to_other(phar_obj->arc.archive, format, ext, flags TSRMLS_CC);
        !          2730:        phar_obj->arc.archive->is_data = is_data;
        !          2731: 
        !          2732:        if (ret) {
        !          2733:                RETURN_ZVAL(ret, 1, 1);
        !          2734:        } else {
        !          2735:                RETURN_NULL();
        !          2736:        }
        !          2737: }
        !          2738: /* }}} */
        !          2739: 
        !          2740: /* {{{ proto int|false Phar::isCompressed()
        !          2741:  * Returns Phar::GZ or PHAR::BZ2 if the entire archive is compressed
        !          2742:  * (.tar.gz/tar.bz2 and so on), or FALSE otherwise.
        !          2743:  */
        !          2744: PHP_METHOD(Phar, isCompressed)
        !          2745: {
        !          2746:        PHAR_ARCHIVE_OBJECT();
        !          2747:        
        !          2748:        if (zend_parse_parameters_none() == FAILURE) {
        !          2749:                return;
        !          2750:        }
        !          2751: 
        !          2752:        if (phar_obj->arc.archive->flags & PHAR_FILE_COMPRESSED_GZ) {
        !          2753:                RETURN_LONG(PHAR_ENT_COMPRESSED_GZ);
        !          2754:        }
        !          2755: 
        !          2756:        if (phar_obj->arc.archive->flags & PHAR_FILE_COMPRESSED_BZ2) {
        !          2757:                RETURN_LONG(PHAR_ENT_COMPRESSED_BZ2);
        !          2758:        }
        !          2759: 
        !          2760:        RETURN_FALSE;
        !          2761: }
        !          2762: /* }}} */
        !          2763: 
        !          2764: /* {{{ proto bool Phar::isWritable()
        !          2765:  * Returns true if phar.readonly=0 or phar is a PharData AND the actual file is writable.
        !          2766:  */
        !          2767: PHP_METHOD(Phar, isWritable)
        !          2768: {
        !          2769:        php_stream_statbuf ssb;
        !          2770:        PHAR_ARCHIVE_OBJECT();
        !          2771:        
        !          2772:        if (zend_parse_parameters_none() == FAILURE) {
        !          2773:                return;
        !          2774:        }
        !          2775: 
        !          2776:        if (!phar_obj->arc.archive->is_writeable) {
        !          2777:                RETURN_FALSE;
        !          2778:        }
        !          2779: 
        !          2780:        if (SUCCESS != php_stream_stat_path(phar_obj->arc.archive->fname, &ssb)) {
        !          2781:                if (phar_obj->arc.archive->is_brandnew) {
        !          2782:                        /* assume it works if the file doesn't exist yet */
        !          2783:                        RETURN_TRUE;
        !          2784:                }
        !          2785:                RETURN_FALSE;
        !          2786:        }
        !          2787: 
        !          2788:        RETURN_BOOL((ssb.sb.st_mode & (S_IWOTH | S_IWGRP | S_IWUSR)) != 0);
        !          2789: }
        !          2790: /* }}} */
        !          2791: 
        !          2792: /* {{{ proto bool Phar::delete(string entry)
        !          2793:  * Deletes a named file within the archive.
        !          2794:  */
        !          2795: PHP_METHOD(Phar, delete)
        !          2796: {
        !          2797:        char *fname;
        !          2798:        int fname_len;
        !          2799:        char *error;
        !          2800:        phar_entry_info *entry;
        !          2801:        PHAR_ARCHIVE_OBJECT();
        !          2802: 
        !          2803:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          2804:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2805:                        "Cannot write out phar archive, phar is read-only");
        !          2806:                return;
        !          2807:        }
        !          2808: 
        !          2809:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
        !          2810:                RETURN_FALSE;
        !          2811:        }
        !          2812: 
        !          2813:        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          2814:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          2815:                return;
        !          2816:        }
        !          2817:        if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
        !          2818:                if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) {
        !          2819:                        if (entry->is_deleted) {
        !          2820:                                /* entry is deleted, but has not been flushed to disk yet */
        !          2821:                                RETURN_TRUE;
        !          2822:                        } else {
        !          2823:                                entry->is_deleted = 1;
        !          2824:                                entry->is_modified = 1;
        !          2825:                                phar_obj->arc.archive->is_modified = 1;
        !          2826:                        }
        !          2827:                }
        !          2828:        } else {
        !          2829:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be deleted", fname);
        !          2830:                RETURN_FALSE;
        !          2831:        }
        !          2832: 
        !          2833:        phar_flush(phar_obj->arc.archive, NULL, 0, 0, &error TSRMLS_CC);
        !          2834:        if (error) {
        !          2835:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          2836:                efree(error);
        !          2837:        }
        !          2838: 
        !          2839:        RETURN_TRUE;
        !          2840: }
        !          2841: /* }}} */
        !          2842: 
        !          2843: /* {{{ proto int Phar::getAlias()
        !          2844:  * Returns the alias for the Phar or NULL.
        !          2845:  */
        !          2846: PHP_METHOD(Phar, getAlias)
        !          2847: {
        !          2848:        PHAR_ARCHIVE_OBJECT();
        !          2849:        
        !          2850:        if (zend_parse_parameters_none() == FAILURE) {
        !          2851:                return;
        !          2852:        }
        !          2853: 
        !          2854:        if (phar_obj->arc.archive->alias && phar_obj->arc.archive->alias != phar_obj->arc.archive->fname) {
        !          2855:                RETURN_STRINGL(phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, 1);
        !          2856:        }
        !          2857: }
        !          2858: /* }}} */
        !          2859: 
        !          2860: /* {{{ proto int Phar::getPath()
        !          2861:  * Returns the real path to the phar archive on disk
        !          2862:  */
        !          2863: PHP_METHOD(Phar, getPath)
        !          2864: {
        !          2865:        PHAR_ARCHIVE_OBJECT();
        !          2866:        
        !          2867:        if (zend_parse_parameters_none() == FAILURE) {
        !          2868:                return;
        !          2869:        }
        !          2870: 
        !          2871:        RETURN_STRINGL(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, 1);
        !          2872: }
        !          2873: /* }}} */
        !          2874: 
        !          2875: /* {{{ proto bool Phar::setAlias(string alias)
        !          2876:  * Sets the alias for a Phar archive. The default value is the full path
        !          2877:  * to the archive.
        !          2878:  */
        !          2879: PHP_METHOD(Phar, setAlias)
        !          2880: {
        !          2881:        char *alias, *error, *oldalias;
        !          2882:        phar_archive_data **fd_ptr;
        !          2883:        int alias_len, oldalias_len, old_temp, readd = 0;
        !          2884: 
        !          2885:        PHAR_ARCHIVE_OBJECT();
        !          2886: 
        !          2887:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          2888:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2889:                        "Cannot write out phar archive, phar is read-only");
        !          2890:                RETURN_FALSE;
        !          2891:        }
        !          2892: 
        !          2893:        /* invalidate phar cache */
        !          2894:        PHAR_G(last_phar) = NULL;
        !          2895:        PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
        !          2896: 
        !          2897:        if (phar_obj->arc.archive->is_data) {
        !          2898:                if (phar_obj->arc.archive->is_tar) {
        !          2899:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2900:                                "A Phar alias cannot be set in a plain tar archive");
        !          2901:                } else {
        !          2902:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2903:                                "A Phar alias cannot be set in a plain zip archive");
        !          2904:                }
        !          2905:                RETURN_FALSE;
        !          2906:        }
        !          2907: 
        !          2908:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &alias, &alias_len) == SUCCESS) {
        !          2909:                if (alias_len == phar_obj->arc.archive->alias_len && memcmp(phar_obj->arc.archive->alias, alias, alias_len) == 0) {
        !          2910:                        RETURN_TRUE;
        !          2911:                }
        !          2912:                if (alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
        !          2913:                        spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, (*fd_ptr)->fname);
        !          2914:                        if (SUCCESS == phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
        !          2915:                                efree(error);
        !          2916:                                goto valid_alias;
        !          2917:                        }
        !          2918:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          2919:                        efree(error);
        !          2920:                        RETURN_FALSE;
        !          2921:                }
        !          2922:                if (!phar_validate_alias(alias, alias_len)) {
        !          2923:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          2924:                                "Invalid alias \"%s\" specified for phar \"%s\"", alias, phar_obj->arc.archive->fname);
        !          2925:                        RETURN_FALSE;
        !          2926:                }
        !          2927: valid_alias:
        !          2928:                if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          2929:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          2930:                        return;
        !          2931:                }
        !          2932:                if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
        !          2933:                        zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
        !          2934:                        readd = 1;
        !          2935:                }
        !          2936: 
        !          2937:                oldalias = phar_obj->arc.archive->alias;
        !          2938:                oldalias_len = phar_obj->arc.archive->alias_len;
        !          2939:                old_temp = phar_obj->arc.archive->is_temporary_alias;
        !          2940: 
        !          2941:                if (alias_len) {
        !          2942:                        phar_obj->arc.archive->alias = estrndup(alias, alias_len);
        !          2943:                } else {
        !          2944:                        phar_obj->arc.archive->alias = NULL;
        !          2945:                }
        !          2946: 
        !          2947:                phar_obj->arc.archive->alias_len = alias_len;
        !          2948:                phar_obj->arc.archive->is_temporary_alias = 0;
        !          2949:                phar_flush(phar_obj->arc.archive, NULL, 0, 0, &error TSRMLS_CC);
        !          2950: 
        !          2951:                if (error) {
        !          2952:                        phar_obj->arc.archive->alias = oldalias;
        !          2953:                        phar_obj->arc.archive->alias_len = oldalias_len;
        !          2954:                        phar_obj->arc.archive->is_temporary_alias = old_temp;
        !          2955:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          2956:                        if (readd) {
        !          2957:                                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
        !          2958:                        }
        !          2959:                        efree(error);
        !          2960:                        RETURN_FALSE;
        !          2961:                }
        !          2962: 
        !          2963:                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
        !          2964: 
        !          2965:                if (oldalias) {
        !          2966:                        efree(oldalias);
        !          2967:                }
        !          2968: 
        !          2969:                RETURN_TRUE;
        !          2970:        }
        !          2971: 
        !          2972:        RETURN_FALSE;
        !          2973: }
        !          2974: /* }}} */
        !          2975: 
        !          2976: /* {{{ proto string Phar::getVersion()
        !          2977:  * Return version info of Phar archive
        !          2978:  */
        !          2979: PHP_METHOD(Phar, getVersion)
        !          2980: {
        !          2981:        PHAR_ARCHIVE_OBJECT();
        !          2982:        
        !          2983:        if (zend_parse_parameters_none() == FAILURE) {
        !          2984:                return;
        !          2985:        }
        !          2986: 
        !          2987:        RETURN_STRING(phar_obj->arc.archive->version, 1);
        !          2988: }
        !          2989: /* }}} */
        !          2990: 
        !          2991: /* {{{ proto void Phar::startBuffering()
        !          2992:  * Do not flush a writeable phar (save its contents) until explicitly requested
        !          2993:  */
        !          2994: PHP_METHOD(Phar, startBuffering)
        !          2995: {
        !          2996:        PHAR_ARCHIVE_OBJECT();
        !          2997:        
        !          2998:        if (zend_parse_parameters_none() == FAILURE) {
        !          2999:                return;
        !          3000:        }
        !          3001: 
        !          3002:        phar_obj->arc.archive->donotflush = 1;
        !          3003: }
        !          3004: /* }}} */
        !          3005: 
        !          3006: /* {{{ proto bool Phar::isBuffering()
        !          3007:  * Returns whether write operations are flushing to disk immediately.
        !          3008:  */
        !          3009: PHP_METHOD(Phar, isBuffering)
        !          3010: {
        !          3011:        PHAR_ARCHIVE_OBJECT();
        !          3012:        
        !          3013:        if (zend_parse_parameters_none() == FAILURE) {
        !          3014:                return;
        !          3015:        }
        !          3016: 
        !          3017:        RETURN_BOOL(phar_obj->arc.archive->donotflush);
        !          3018: }
        !          3019: /* }}} */
        !          3020: 
        !          3021: /* {{{ proto bool Phar::stopBuffering()
        !          3022:  * Saves the contents of a modified archive to disk.
        !          3023:  */
        !          3024: PHP_METHOD(Phar, stopBuffering)
        !          3025: {
        !          3026:        char *error;
        !          3027: 
        !          3028:        PHAR_ARCHIVE_OBJECT();
        !          3029:        
        !          3030:        if (zend_parse_parameters_none() == FAILURE) {
        !          3031:                return;
        !          3032:        }
        !          3033: 
        !          3034:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3035:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3036:                        "Cannot write out phar archive, phar is read-only");
        !          3037:                return;
        !          3038:        }
        !          3039: 
        !          3040:        phar_obj->arc.archive->donotflush = 0;
        !          3041:        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          3042: 
        !          3043:        if (error) {
        !          3044:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3045:                efree(error);
        !          3046:        }
        !          3047: }
        !          3048: /* }}} */
        !          3049: 
        !          3050: /* {{{ proto bool Phar::setStub(string|stream stub [, int len])
        !          3051:  * Change the stub in a phar, phar.tar or phar.zip archive to something other
        !          3052:  * than the default. The stub *must* end with a call to __HALT_COMPILER().
        !          3053:  */
        !          3054: PHP_METHOD(Phar, setStub)
        !          3055: {
        !          3056:        zval *zstub;
        !          3057:        char *stub, *error;
        !          3058:        int stub_len;
        !          3059:        long len = -1;
        !          3060:        php_stream *stream;
        !          3061:        PHAR_ARCHIVE_OBJECT();
        !          3062: 
        !          3063:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3064:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3065:                        "Cannot change stub, phar is read-only");
        !          3066:                return;
        !          3067:        }
        !          3068: 
        !          3069:        if (phar_obj->arc.archive->is_data) {
        !          3070:                if (phar_obj->arc.archive->is_tar) {
        !          3071:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3072:                                "A Phar stub cannot be set in a plain tar archive");
        !          3073:                } else {
        !          3074:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3075:                                "A Phar stub cannot be set in a plain zip archive");
        !          3076:                }
        !          3077:                return;
        !          3078:        }
        !          3079: 
        !          3080:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zstub, &len) == SUCCESS) {
        !          3081:                if ((php_stream_from_zval_no_verify(stream, &zstub)) != NULL) {
        !          3082:                        if (len > 0) {
        !          3083:                                len = -len;
        !          3084:                        } else {
        !          3085:                                len = -1;
        !          3086:                        }
        !          3087:                        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3088:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3089:                                return;
        !          3090:                        }
        !          3091:                        phar_flush(phar_obj->arc.archive, (char *) &zstub, len, 0, &error TSRMLS_CC);
        !          3092:                        if (error) {
        !          3093:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3094:                                efree(error);
        !          3095:                        }
        !          3096:                        RETURN_TRUE;
        !          3097:                } else {
        !          3098:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3099:                                "Cannot change stub, unable to read from input stream");
        !          3100:                }
        !          3101:        } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &stub, &stub_len) == SUCCESS) {
        !          3102:                if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3103:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3104:                        return;
        !          3105:                }
        !          3106:                phar_flush(phar_obj->arc.archive, stub, stub_len, 0, &error TSRMLS_CC);
        !          3107: 
        !          3108:                if (error) {
        !          3109:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3110:                        efree(error);
        !          3111:                }
        !          3112: 
        !          3113:                RETURN_TRUE;
        !          3114:        }
        !          3115: 
        !          3116:        RETURN_FALSE;
        !          3117: }
        !          3118: /* }}} */
        !          3119: 
        !          3120: /* {{{ proto bool Phar::setDefaultStub([string index[, string webindex]])
        !          3121:  * In a pure phar archive, sets a stub that can be used to run the archive
        !          3122:  * regardless of whether the phar extension is available. The first parameter
        !          3123:  * is the CLI startup filename, which defaults to "index.php". The second
        !          3124:  * parameter is the web startup filename and also defaults to "index.php"
        !          3125:  * (falling back to CLI behaviour).
        !          3126:  * Both parameters are optional.
        !          3127:  * In a phar.zip or phar.tar archive, the default stub is used only to
        !          3128:  * identify the archive to the extension as a Phar object. This allows the
        !          3129:  * extension to treat phar.zip and phar.tar types as honorary phars. Since
        !          3130:  * files cannot be loaded via this kind of stub, no parameters are accepted
        !          3131:  * when the Phar object is zip- or tar-based.
        !          3132:  */
        !          3133: PHP_METHOD(Phar, setDefaultStub)
        !          3134: {
        !          3135:        char *index = NULL, *webindex = NULL, *error = NULL, *stub = NULL;
        !          3136:        int index_len = 0, webindex_len = 0, created_stub = 0;
        !          3137:        size_t stub_len = 0;
        !          3138:        PHAR_ARCHIVE_OBJECT();
        !          3139: 
        !          3140:        if (phar_obj->arc.archive->is_data) {
        !          3141:                if (phar_obj->arc.archive->is_tar) {
        !          3142:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3143:                                "A Phar stub cannot be set in a plain tar archive");
        !          3144:                } else {
        !          3145:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3146:                                "A Phar stub cannot be set in a plain zip archive");
        !          3147:                }
        !          3148:                return;
        !          3149:        }
        !          3150: 
        !          3151:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s", &index, &index_len, &webindex, &webindex_len) == FAILURE) {
        !          3152:                RETURN_FALSE;
        !          3153:        }
        !          3154: 
        !          3155:        if (ZEND_NUM_ARGS() > 0 && (phar_obj->arc.archive->is_tar || phar_obj->arc.archive->is_zip)) {
        !          3156:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "method accepts no arguments for a tar- or zip-based phar stub, %d given", ZEND_NUM_ARGS());
        !          3157:                RETURN_FALSE;
        !          3158:        }
        !          3159: 
        !          3160:        if (PHAR_G(readonly)) {
        !          3161:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3162:                        "Cannot change stub: phar.readonly=1");
        !          3163:                RETURN_FALSE;
        !          3164:        }
        !          3165: 
        !          3166:        if (!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip) {
        !          3167:                stub = phar_create_default_stub(index, webindex, &stub_len, &error TSRMLS_CC);
        !          3168: 
        !          3169:                if (error) {
        !          3170:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "%s", error);
        !          3171:                        efree(error);
        !          3172:                        if (stub) {
        !          3173:                                efree(stub);
        !          3174:                        }
        !          3175:                        RETURN_FALSE;
        !          3176:                }
        !          3177: 
        !          3178:                created_stub = 1;
        !          3179:        }
        !          3180: 
        !          3181:        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3182:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3183:                return;
        !          3184:        }
        !          3185:        phar_flush(phar_obj->arc.archive, stub, stub_len, 1, &error TSRMLS_CC);
        !          3186: 
        !          3187:        if (created_stub) {
        !          3188:                efree(stub);
        !          3189:        }
        !          3190: 
        !          3191:        if (error) {
        !          3192:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3193:                efree(error);
        !          3194:                RETURN_FALSE;
        !          3195:        }
        !          3196: 
        !          3197:        RETURN_TRUE;
        !          3198: }
        !          3199: /* }}} */
        !          3200: 
        !          3201: /* {{{ proto array Phar::setSignatureAlgorithm(int sigtype[, string privatekey])
        !          3202:  * Sets the signature algorithm for a phar and applies it. The signature
        !          3203:  * algorithm must be one of Phar::MD5, Phar::SHA1, Phar::SHA256,
        !          3204:  * Phar::SHA512, or Phar::OPENSSL. Note that zip- based phar archives
        !          3205:  * cannot support signatures.
        !          3206:  */
        !          3207: PHP_METHOD(Phar, setSignatureAlgorithm)
        !          3208: {
        !          3209:        long algo;
        !          3210:        char *error, *key = NULL;
        !          3211:        int key_len = 0;
        !          3212: 
        !          3213:        PHAR_ARCHIVE_OBJECT();
        !          3214: 
        !          3215:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3216:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3217:                        "Cannot set signature algorithm, phar is read-only");
        !          3218:                return;
        !          3219:        }
        !          3220: 
        !          3221:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &algo, &key, &key_len) != SUCCESS) {
        !          3222:                return;
        !          3223:        }
        !          3224: 
        !          3225:        switch (algo) {
        !          3226:                case PHAR_SIG_SHA256:
        !          3227:                case PHAR_SIG_SHA512:
        !          3228: #ifndef PHAR_HASH_OK
        !          3229:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3230:                                "SHA-256 and SHA-512 signatures are only supported if the hash extension is enabled and built non-shared");
        !          3231:                        return;
        !          3232: #endif
        !          3233:                case PHAR_SIG_MD5:
        !          3234:                case PHAR_SIG_SHA1:
        !          3235:                case PHAR_SIG_OPENSSL:
        !          3236:                        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3237:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3238:                                return;
        !          3239:                        }
        !          3240:                        phar_obj->arc.archive->sig_flags = algo;
        !          3241:                        phar_obj->arc.archive->is_modified = 1;
        !          3242:                        PHAR_G(openssl_privatekey) = key;
        !          3243:                        PHAR_G(openssl_privatekey_len) = key_len;
        !          3244: 
        !          3245:                        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          3246:                        if (error) {
        !          3247:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3248:                                efree(error);
        !          3249:                        }
        !          3250:                        break;
        !          3251:                default:
        !          3252:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3253:                                "Unknown signature algorithm specified");
        !          3254:        }
        !          3255: }
        !          3256: /* }}} */
        !          3257: 
        !          3258: /* {{{ proto array|false Phar::getSignature()
        !          3259:  * Returns a hash signature, or FALSE if the archive is unsigned.
        !          3260:  */
        !          3261: PHP_METHOD(Phar, getSignature)
        !          3262: {
        !          3263:        PHAR_ARCHIVE_OBJECT();
        !          3264:        
        !          3265:        if (zend_parse_parameters_none() == FAILURE) {
        !          3266:                return;
        !          3267:        }
        !          3268: 
        !          3269:        if (phar_obj->arc.archive->signature) {
        !          3270:                char *unknown;
        !          3271:                int unknown_len;
        !          3272: 
        !          3273:                array_init(return_value);
        !          3274:                add_assoc_stringl(return_value, "hash", phar_obj->arc.archive->signature, phar_obj->arc.archive->sig_len, 1);
        !          3275:                switch(phar_obj->arc.archive->sig_flags) {
        !          3276:                        case PHAR_SIG_MD5:
        !          3277:                                add_assoc_stringl(return_value, "hash_type", "MD5", 3, 1);
        !          3278:                                break;
        !          3279:                        case PHAR_SIG_SHA1:
        !          3280:                                add_assoc_stringl(return_value, "hash_type", "SHA-1", 5, 1);
        !          3281:                                break;
        !          3282:                        case PHAR_SIG_SHA256:
        !          3283:                                add_assoc_stringl(return_value, "hash_type", "SHA-256", 7, 1);
        !          3284:                                break;
        !          3285:                        case PHAR_SIG_SHA512:
        !          3286:                                add_assoc_stringl(return_value, "hash_type", "SHA-512", 7, 1);
        !          3287:                                break;
        !          3288:                        case PHAR_SIG_OPENSSL:
        !          3289:                                add_assoc_stringl(return_value, "hash_type", "OpenSSL", 7, 1);
        !          3290:                                break;
        !          3291:                        default:
        !          3292:                                unknown_len = spprintf(&unknown, 0, "Unknown (%u)", phar_obj->arc.archive->sig_flags);
        !          3293:                                add_assoc_stringl(return_value, "hash_type", unknown, unknown_len, 0);
        !          3294:                                break;
        !          3295:                }
        !          3296:        } else {
        !          3297:                RETURN_FALSE;
        !          3298:        }
        !          3299: }
        !          3300: /* }}} */
        !          3301: 
        !          3302: /* {{{ proto bool Phar::getModified()
        !          3303:  * Return whether phar was modified
        !          3304:  */
        !          3305: PHP_METHOD(Phar, getModified)
        !          3306: {
        !          3307:        PHAR_ARCHIVE_OBJECT();
        !          3308:        
        !          3309:        if (zend_parse_parameters_none() == FAILURE) {
        !          3310:                return;
        !          3311:        }
        !          3312: 
        !          3313:        RETURN_BOOL(phar_obj->arc.archive->is_modified);
        !          3314: }
        !          3315: /* }}} */
        !          3316: 
        !          3317: static int phar_set_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ */
        !          3318: {
        !          3319:        phar_entry_info *entry = (phar_entry_info *)pDest;
        !          3320:        php_uint32 compress = *(php_uint32 *)argument;
        !          3321: 
        !          3322:        if (entry->is_deleted) {
        !          3323:                return ZEND_HASH_APPLY_KEEP;
        !          3324:        }
        !          3325: 
        !          3326:        entry->old_flags = entry->flags;
        !          3327:        entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
        !          3328:        entry->flags |= compress;
        !          3329:        entry->is_modified = 1;
        !          3330:        return ZEND_HASH_APPLY_KEEP;
        !          3331: }
        !          3332: /* }}} */
        !          3333: 
        !          3334: static int phar_test_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ */
        !          3335: {
        !          3336:        phar_entry_info *entry = (phar_entry_info *)pDest;
        !          3337: 
        !          3338:        if (entry->is_deleted) {
        !          3339:                return ZEND_HASH_APPLY_KEEP;
        !          3340:        }
        !          3341: 
        !          3342:        if (!PHAR_G(has_bz2)) {
        !          3343:                if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
        !          3344:                        *(int *) argument = 0;
        !          3345:                }
        !          3346:        }
        !          3347: 
        !          3348:        if (!PHAR_G(has_zlib)) {
        !          3349:                if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
        !          3350:                        *(int *) argument = 0;
        !          3351:                }
        !          3352:        }
        !          3353: 
        !          3354:        return ZEND_HASH_APPLY_KEEP;
        !          3355: }
        !          3356: /* }}} */
        !          3357: 
        !          3358: static void pharobj_set_compression(HashTable *manifest, php_uint32 compress TSRMLS_DC) /* {{{ */
        !          3359: {
        !          3360:        zend_hash_apply_with_argument(manifest, phar_set_compression, &compress TSRMLS_CC);
        !          3361: }
        !          3362: /* }}} */
        !          3363: 
        !          3364: static int pharobj_cancompress(HashTable *manifest TSRMLS_DC) /* {{{ */
        !          3365: {
        !          3366:        int test;
        !          3367: 
        !          3368:        test = 1;
        !          3369:        zend_hash_apply_with_argument(manifest, phar_test_compression, &test TSRMLS_CC);
        !          3370:        return test;
        !          3371: }
        !          3372: /* }}} */
        !          3373: 
        !          3374: /* {{{ proto object Phar::compress(int method[, string extension])
        !          3375:  * Compress a .tar, or .phar.tar with whole-file compression
        !          3376:  * The parameter can be one of Phar::GZ or Phar::BZ2 to specify
        !          3377:  * the kind of compression desired
        !          3378:  */
        !          3379: PHP_METHOD(Phar, compress)
        !          3380: {
        !          3381:        long method;
        !          3382:        char *ext = NULL;
        !          3383:        int ext_len = 0;
        !          3384:        php_uint32 flags;
        !          3385:        zval *ret;
        !          3386:        PHAR_ARCHIVE_OBJECT();
        !          3387: 
        !          3388:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &method, &ext, &ext_len) == FAILURE) {
        !          3389:                return;
        !          3390:        }
        !          3391: 
        !          3392:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3393:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3394:                        "Cannot compress phar archive, phar is read-only");
        !          3395:                return;
        !          3396:        }
        !          3397: 
        !          3398:        if (phar_obj->arc.archive->is_zip) {
        !          3399:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3400:                        "Cannot compress zip-based archives with whole-archive compression");
        !          3401:                return;
        !          3402:        }
        !          3403: 
        !          3404:        switch (method) {
        !          3405:                case 0:
        !          3406:                        flags = PHAR_FILE_COMPRESSED_NONE;
        !          3407:                        break;
        !          3408:                case PHAR_ENT_COMPRESSED_GZ:
        !          3409:                        if (!PHAR_G(has_zlib)) {
        !          3410:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3411:                                        "Cannot compress entire archive with gzip, enable ext/zlib in php.ini");
        !          3412:                                return;
        !          3413:                        }
        !          3414:                        flags = PHAR_FILE_COMPRESSED_GZ;
        !          3415:                        break;
        !          3416: 
        !          3417:                case PHAR_ENT_COMPRESSED_BZ2:
        !          3418:                        if (!PHAR_G(has_bz2)) {
        !          3419:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3420:                                        "Cannot compress entire archive with bz2, enable ext/bz2 in php.ini");
        !          3421:                                return;
        !          3422:                        }
        !          3423:                        flags = PHAR_FILE_COMPRESSED_BZ2;
        !          3424:                        break;
        !          3425:                default:
        !          3426:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3427:                                "Unknown compression specified, please pass one of Phar::GZ or Phar::BZ2");
        !          3428:                        return;
        !          3429:        }
        !          3430: 
        !          3431:        if (phar_obj->arc.archive->is_tar) {
        !          3432:                ret = phar_convert_to_other(phar_obj->arc.archive, PHAR_FORMAT_TAR, ext, flags TSRMLS_CC);
        !          3433:        } else {
        !          3434:                ret = phar_convert_to_other(phar_obj->arc.archive, PHAR_FORMAT_PHAR, ext, flags TSRMLS_CC);
        !          3435:        }
        !          3436: 
        !          3437:        if (ret) {
        !          3438:                RETURN_ZVAL(ret, 1, 1);
        !          3439:        } else {
        !          3440:                RETURN_NULL();
        !          3441:        }
        !          3442: }
        !          3443: /* }}} */
        !          3444: 
        !          3445: /* {{{ proto object Phar::decompress([string extension])
        !          3446:  * Decompress a .tar, or .phar.tar with whole-file compression
        !          3447:  */
        !          3448: PHP_METHOD(Phar, decompress)
        !          3449: {
        !          3450:        char *ext = NULL;
        !          3451:        int ext_len = 0;
        !          3452:        zval *ret;
        !          3453:        PHAR_ARCHIVE_OBJECT();
        !          3454: 
        !          3455:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
        !          3456:                return;
        !          3457:        }
        !          3458: 
        !          3459:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3460:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3461:                        "Cannot decompress phar archive, phar is read-only");
        !          3462:                return;
        !          3463:        }
        !          3464: 
        !          3465:        if (phar_obj->arc.archive->is_zip) {
        !          3466:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3467:                        "Cannot decompress zip-based archives with whole-archive compression");
        !          3468:                return;
        !          3469:        }
        !          3470: 
        !          3471:        if (phar_obj->arc.archive->is_tar) {
        !          3472:                ret = phar_convert_to_other(phar_obj->arc.archive, PHAR_FORMAT_TAR, ext, PHAR_FILE_COMPRESSED_NONE TSRMLS_CC);
        !          3473:        } else {
        !          3474:                ret = phar_convert_to_other(phar_obj->arc.archive, PHAR_FORMAT_PHAR, ext, PHAR_FILE_COMPRESSED_NONE TSRMLS_CC);
        !          3475:        }
        !          3476: 
        !          3477:        if (ret) {
        !          3478:                RETURN_ZVAL(ret, 1, 1);
        !          3479:        } else {
        !          3480:                RETURN_NULL();
        !          3481:        }
        !          3482: }
        !          3483: /* }}} */
        !          3484: 
        !          3485: /* {{{ proto object Phar::compressFiles(int method)
        !          3486:  * Compress all files within a phar or zip archive using the specified compression
        !          3487:  * The parameter can be one of Phar::GZ or Phar::BZ2 to specify
        !          3488:  * the kind of compression desired
        !          3489:  */
        !          3490: PHP_METHOD(Phar, compressFiles)
        !          3491: {
        !          3492:        char *error;
        !          3493:        php_uint32 flags;
        !          3494:        long method;
        !          3495:        PHAR_ARCHIVE_OBJECT();
        !          3496: 
        !          3497:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &method) == FAILURE) {
        !          3498:                return;
        !          3499:        }
        !          3500: 
        !          3501:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3502:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3503:                        "Phar is readonly, cannot change compression");
        !          3504:                return;
        !          3505:        }
        !          3506: 
        !          3507:        switch (method) {
        !          3508:                case PHAR_ENT_COMPRESSED_GZ:
        !          3509:                        if (!PHAR_G(has_zlib)) {
        !          3510:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3511:                                        "Cannot compress files within archive with gzip, enable ext/zlib in php.ini");
        !          3512:                                return;
        !          3513:                        }
        !          3514:                        flags = PHAR_ENT_COMPRESSED_GZ;
        !          3515:                        break;
        !          3516: 
        !          3517:                case PHAR_ENT_COMPRESSED_BZ2:
        !          3518:                        if (!PHAR_G(has_bz2)) {
        !          3519:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3520:                                        "Cannot compress files within archive with bz2, enable ext/bz2 in php.ini");
        !          3521:                                return;
        !          3522:                        }
        !          3523:                        flags = PHAR_ENT_COMPRESSED_BZ2;
        !          3524:                        break;
        !          3525:                default:
        !          3526:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3527:                                "Unknown compression specified, please pass one of Phar::GZ or Phar::BZ2");
        !          3528:                        return;
        !          3529:        }
        !          3530: 
        !          3531:        if (phar_obj->arc.archive->is_tar) {
        !          3532:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3533:                        "Cannot compress with Gzip compression, tar archives cannot compress individual files, use compress() to compress the whole archive");
        !          3534:                return;
        !          3535:        }
        !          3536: 
        !          3537:        if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
        !          3538:                if (flags == PHAR_FILE_COMPRESSED_GZ) {
        !          3539:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3540:                                "Cannot compress all files as Gzip, some are compressed as bzip2 and cannot be decompressed");
        !          3541:                } else {
        !          3542:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3543:                                "Cannot compress all files as Bzip2, some are compressed as gzip and cannot be decompressed");
        !          3544:                }
        !          3545:                return;
        !          3546:        }
        !          3547: 
        !          3548:        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3549:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3550:                return;
        !          3551:        }
        !          3552:        pharobj_set_compression(&phar_obj->arc.archive->manifest, flags TSRMLS_CC);
        !          3553:        phar_obj->arc.archive->is_modified = 1;
        !          3554:        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          3555: 
        !          3556:        if (error) {
        !          3557:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s", error);
        !          3558:                efree(error);
        !          3559:        }
        !          3560: }
        !          3561: /* }}} */
        !          3562: 
        !          3563: /* {{{ proto bool Phar::decompressFiles()
        !          3564:  * decompress every file
        !          3565:  */
        !          3566: PHP_METHOD(Phar, decompressFiles)
        !          3567: {
        !          3568:        char *error;
        !          3569:        PHAR_ARCHIVE_OBJECT();
        !          3570:        
        !          3571:        if (zend_parse_parameters_none() == FAILURE) {
        !          3572:                return;
        !          3573:        }
        !          3574: 
        !          3575:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3576:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3577:                        "Phar is readonly, cannot change compression");
        !          3578:                return;
        !          3579:        }
        !          3580: 
        !          3581:        if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
        !          3582:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          3583:                        "Cannot decompress all files, some are compressed as bzip2 or gzip and cannot be decompressed");
        !          3584:                return;
        !          3585:        }
        !          3586: 
        !          3587:        if (phar_obj->arc.archive->is_tar) {
        !          3588:                RETURN_TRUE;
        !          3589:        } else {
        !          3590:                if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3591:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3592:                        return;
        !          3593:                }
        !          3594:                pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_NONE TSRMLS_CC);
        !          3595:        }
        !          3596: 
        !          3597:        phar_obj->arc.archive->is_modified = 1;
        !          3598:        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          3599: 
        !          3600:        if (error) {
        !          3601:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s", error);
        !          3602:                efree(error);
        !          3603:        }
        !          3604: 
        !          3605:        RETURN_TRUE;
        !          3606: }
        !          3607: /* }}} */
        !          3608: 
        !          3609: /* {{{ proto bool Phar::copy(string oldfile, string newfile)
        !          3610:  * copy a file internal to the phar archive to another new file within the phar
        !          3611:  */
        !          3612: PHP_METHOD(Phar, copy)
        !          3613: {
        !          3614:        char *oldfile, *newfile, *error;
        !          3615:        const char *pcr_error;
        !          3616:        int oldfile_len, newfile_len;
        !          3617:        phar_entry_info *oldentry, newentry = {0}, *temp;
        !          3618: 
        !          3619:        PHAR_ARCHIVE_OBJECT();
        !          3620: 
        !          3621:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &oldfile, &oldfile_len, &newfile, &newfile_len) == FAILURE) {
        !          3622:                return;
        !          3623:        }
        !          3624: 
        !          3625:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3626:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3627:                        "Cannot copy \"%s\" to \"%s\", phar is read-only", oldfile, newfile);
        !          3628:                RETURN_FALSE;
        !          3629:        }
        !          3630: 
        !          3631:        if (oldfile_len >= sizeof(".phar")-1 && !memcmp(oldfile, ".phar", sizeof(".phar")-1)) {
        !          3632:                /* can't copy a meta file */
        !          3633:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3634:                        "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", oldfile, newfile, phar_obj->arc.archive->fname);
        !          3635:                RETURN_FALSE;
        !          3636:        }
        !          3637: 
        !          3638:        if (newfile_len >= sizeof(".phar")-1 && !memcmp(newfile, ".phar", sizeof(".phar")-1)) {
        !          3639:                /* can't copy a meta file */
        !          3640:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3641:                        "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", oldfile, newfile, phar_obj->arc.archive->fname);
        !          3642:                RETURN_FALSE;
        !          3643:        }
        !          3644: 
        !          3645:        if (!zend_hash_exists(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len) || SUCCESS != zend_hash_find(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len, (void**)&oldentry) || oldentry->is_deleted) {
        !          3646:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3647:                        "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", oldfile, newfile, phar_obj->arc.archive->fname);
        !          3648:                RETURN_FALSE;
        !          3649:        }
        !          3650: 
        !          3651:        if (zend_hash_exists(&phar_obj->arc.archive->manifest, newfile, (uint) newfile_len)) {
        !          3652:                if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, newfile, (uint) newfile_len, (void**)&temp) || !temp->is_deleted) {
        !          3653:                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3654:                                "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", oldfile, newfile, phar_obj->arc.archive->fname);
        !          3655:                        RETURN_FALSE;
        !          3656:                }
        !          3657:        }
        !          3658: 
        !          3659:        if (phar_path_check(&newfile, &newfile_len, &pcr_error) > pcr_is_ok) {
        !          3660:                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
        !          3661:                                "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", newfile, pcr_error, oldfile, phar_obj->arc.archive->fname);
        !          3662:                RETURN_FALSE;
        !          3663:        }
        !          3664: 
        !          3665:        if (phar_obj->arc.archive->is_persistent) {
        !          3666:                if (FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3667:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3668:                        return;
        !          3669:                }
        !          3670:                /* re-populate with copied-on-write entry */
        !          3671:                zend_hash_find(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len, (void**)&oldentry);
        !          3672:        }
        !          3673: 
        !          3674:        memcpy((void *) &newentry, oldentry, sizeof(phar_entry_info));
        !          3675: 
        !          3676:        if (newentry.metadata) {
        !          3677:                zval *t;
        !          3678: 
        !          3679:                t = newentry.metadata;
        !          3680:                ALLOC_ZVAL(newentry.metadata);
        !          3681:                *newentry.metadata = *t;
        !          3682:                zval_copy_ctor(newentry.metadata);
        !          3683: #if PHP_VERSION_ID < 50300
        !          3684:                newentry.metadata->refcount = 1;
        !          3685: #else
        !          3686:                Z_SET_REFCOUNT_P(newentry.metadata, 1);
        !          3687: #endif
        !          3688: 
        !          3689:                newentry.metadata_str.c = NULL;
        !          3690:                newentry.metadata_str.len = 0;
        !          3691:        }
        !          3692: 
        !          3693:        newentry.filename = estrndup(newfile, newfile_len);
        !          3694:        newentry.filename_len = newfile_len;
        !          3695:        newentry.fp_refcount = 0;
        !          3696: 
        !          3697:        if (oldentry->fp_type != PHAR_FP) {
        !          3698:                if (FAILURE == phar_copy_entry_fp(oldentry, &newentry, &error TSRMLS_CC)) {
        !          3699:                        efree(newentry.filename);
        !          3700:                        php_stream_close(newentry.fp);
        !          3701:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3702:                        efree(error);
        !          3703:                        return;
        !          3704:                }
        !          3705:        }
        !          3706: 
        !          3707:        zend_hash_add(&oldentry->phar->manifest, newfile, newfile_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
        !          3708:        phar_obj->arc.archive->is_modified = 1;
        !          3709:        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          3710: 
        !          3711:        if (error) {
        !          3712:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3713:                efree(error);
        !          3714:        }
        !          3715: 
        !          3716:        RETURN_TRUE;
        !          3717: }
        !          3718: /* }}} */
        !          3719: 
        !          3720: /* {{{ proto int Phar::offsetExists(string entry)
        !          3721:  * determines whether a file exists in the phar
        !          3722:  */
        !          3723: PHP_METHOD(Phar, offsetExists)
        !          3724: {
        !          3725:        char *fname;
        !          3726:        int fname_len;
        !          3727:        phar_entry_info *entry;
        !          3728: 
        !          3729:        PHAR_ARCHIVE_OBJECT();
        !          3730: 
        !          3731:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
        !          3732:                return;
        !          3733:        }
        !          3734: 
        !          3735:        if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
        !          3736:                if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) {
        !          3737:                        if (entry->is_deleted) {
        !          3738:                                /* entry is deleted, but has not been flushed to disk yet */
        !          3739:                                RETURN_FALSE;
        !          3740:                        }
        !          3741:                }
        !          3742: 
        !          3743:                if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) {
        !          3744:                        /* none of these are real files, so they don't exist */
        !          3745:                        RETURN_FALSE;
        !          3746:                }
        !          3747:                RETURN_TRUE;
        !          3748:        } else {
        !          3749:                if (zend_hash_exists(&phar_obj->arc.archive->virtual_dirs, fname, (uint) fname_len)) {
        !          3750:                        RETURN_TRUE;
        !          3751:                }
        !          3752:                RETURN_FALSE;
        !          3753:        }
        !          3754: }
        !          3755: /* }}} */
        !          3756: 
        !          3757: /* {{{ proto int Phar::offsetGet(string entry)
        !          3758:  * get a PharFileInfo object for a specific file
        !          3759:  */
        !          3760: PHP_METHOD(Phar, offsetGet)
        !          3761: {
        !          3762:        char *fname, *error;
        !          3763:        int fname_len;
        !          3764:        zval *zfname;
        !          3765:        phar_entry_info *entry;
        !          3766:        PHAR_ARCHIVE_OBJECT();
        !          3767: 
        !          3768:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
        !          3769:                return;
        !          3770:        }
        !          3771: 
        !          3772:        /* security is 0 here so that we can get a better error message than "entry doesn't exist" */
        !          3773:        if (!(entry = phar_get_entry_info_dir(phar_obj->arc.archive, fname, fname_len, 1, &error, 0 TSRMLS_CC))) {
        !          3774:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist%s%s", fname, error?", ":"", error?error:"");
        !          3775:        } else {
        !          3776:                if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
        !          3777:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", phar_obj->arc.archive->fname);
        !          3778:                        return;
        !          3779:                }
        !          3780: 
        !          3781:                if (fname_len == sizeof(".phar/alias.txt")-1 && !memcmp(fname, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
        !          3782:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", phar_obj->arc.archive->fname);
        !          3783:                        return;
        !          3784:                }
        !          3785: 
        !          3786:                if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) {
        !          3787:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot directly get any files or directories in magic \".phar\" directory", phar_obj->arc.archive->fname);
        !          3788:                        return;
        !          3789:                }
        !          3790: 
        !          3791:                if (entry->is_temp_dir) {
        !          3792:                        efree(entry->filename);
        !          3793:                        efree(entry);
        !          3794:                }
        !          3795: 
        !          3796:                fname_len = spprintf(&fname, 0, "phar://%s/%s", phar_obj->arc.archive->fname, fname);
        !          3797:                MAKE_STD_ZVAL(zfname);
        !          3798:                ZVAL_STRINGL(zfname, fname, fname_len, 0);
        !          3799:                spl_instantiate_arg_ex1(phar_obj->spl.info_class, &return_value, 0, zfname TSRMLS_CC);
        !          3800:                zval_ptr_dtor(&zfname);
        !          3801:        }
        !          3802: }
        !          3803: /* }}} */
        !          3804: 
        !          3805: /* {{{ add a file within the phar archive from a string or resource
        !          3806:  */
        !          3807: static void phar_add_file(phar_archive_data **pphar, char *filename, int filename_len, char *cont_str, int cont_len, zval *zresource TSRMLS_DC)
        !          3808: {
        !          3809:        char *error;
        !          3810:        size_t contents_len;
        !          3811:        phar_entry_data *data;
        !          3812:        php_stream *contents_file;
        !          3813: 
        !          3814:        if (filename_len >= sizeof(".phar")-1 && !memcmp(filename, ".phar", sizeof(".phar")-1)) {
        !          3815:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot create any files in magic \".phar\" directory", (*pphar)->fname);
        !          3816:                return;
        !          3817:        }
        !          3818: 
        !          3819:        if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, filename, filename_len, "w+b", 0, &error, 1 TSRMLS_CC))) {
        !          3820:                if (error) {
        !          3821:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be created: %s", filename, error);
        !          3822:                        efree(error);
        !          3823:                } else {
        !          3824:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be created", filename);
        !          3825:                }
        !          3826:                return;
        !          3827:        } else {
        !          3828:                if (error) {
        !          3829:                        efree(error);
        !          3830:                }
        !          3831: 
        !          3832:                if (!data->internal_file->is_dir) {
        !          3833:                        if (cont_str) {
        !          3834:                                contents_len = php_stream_write(data->fp, cont_str, cont_len);
        !          3835:                                if (contents_len != cont_len) {
        !          3836:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", filename);
        !          3837:                                        return;
        !          3838:                                }
        !          3839:                        } else {
        !          3840:                                if (!(php_stream_from_zval_no_verify(contents_file, &zresource))) {
        !          3841:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", filename);
        !          3842:                                        return;
        !          3843:                                }
        !          3844:                                phar_stream_copy_to_stream(contents_file, data->fp, PHP_STREAM_COPY_ALL, &contents_len);
        !          3845:                        }
        !          3846: 
        !          3847:                        data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
        !          3848:                }
        !          3849: 
        !          3850:                /* check for copy-on-write */
        !          3851:                if (pphar[0] != data->phar) {
        !          3852:                        *pphar = data->phar;
        !          3853:                }
        !          3854:                phar_entry_delref(data TSRMLS_CC);
        !          3855:                phar_flush(*pphar, 0, 0, 0, &error TSRMLS_CC);
        !          3856: 
        !          3857:                if (error) {
        !          3858:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3859:                        efree(error);
        !          3860:                }
        !          3861:        }
        !          3862: }
        !          3863: /* }}} */
        !          3864: 
        !          3865: /* {{{ create a directory within the phar archive
        !          3866:  */
        !          3867: static void phar_mkdir(phar_archive_data **pphar, char *dirname, int dirname_len TSRMLS_DC)
        !          3868: {
        !          3869:        char *error;
        !          3870:        phar_entry_data *data;
        !          3871: 
        !          3872:        if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, dirname, dirname_len, "w+b", 2, &error, 1 TSRMLS_CC))) {
        !          3873:                if (error) {
        !          3874:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Directory %s does not exist and cannot be created: %s", dirname, error);
        !          3875:                        efree(error);
        !          3876:                } else {
        !          3877:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Directory %s does not exist and cannot be created", dirname);
        !          3878:                }
        !          3879: 
        !          3880:                return;
        !          3881:        } else {
        !          3882:                if (error) {
        !          3883:                        efree(error);
        !          3884:                }
        !          3885: 
        !          3886:                /* check for copy on write */
        !          3887:                if (data->phar != *pphar) {
        !          3888:                        *pphar = data->phar;
        !          3889:                }
        !          3890:                phar_entry_delref(data TSRMLS_CC);
        !          3891:                phar_flush(*pphar, 0, 0, 0, &error TSRMLS_CC);
        !          3892: 
        !          3893:                if (error) {
        !          3894:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3895:                        efree(error);
        !          3896:                }
        !          3897:        }
        !          3898: }
        !          3899: /* }}} */
        !          3900: 
        !          3901: /* {{{ proto int Phar::offsetSet(string entry, string value)
        !          3902:  * set the contents of an internal file to those of an external file
        !          3903:  */
        !          3904: PHP_METHOD(Phar, offsetSet)
        !          3905: {
        !          3906:        char *fname, *cont_str = NULL;
        !          3907:        int fname_len, cont_len;
        !          3908:        zval *zresource;
        !          3909:        PHAR_ARCHIVE_OBJECT();
        !          3910: 
        !          3911:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3912:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by the php.ini setting phar.readonly");
        !          3913:                return;
        !          3914:        }
        !          3915: 
        !          3916:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sr", &fname, &fname_len, &zresource) == FAILURE
        !          3917:        && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &fname, &fname_len, &cont_str, &cont_len) == FAILURE) {
        !          3918:                return;
        !          3919:        }
        !          3920: 
        !          3921:        if (fname_len == sizeof(".phar/stub.php")-1 && !memcmp(fname, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
        !          3922:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", phar_obj->arc.archive->fname);
        !          3923:                return;
        !          3924:        }
        !          3925: 
        !          3926:        if (fname_len == sizeof(".phar/alias.txt")-1 && !memcmp(fname, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
        !          3927:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", phar_obj->arc.archive->fname);
        !          3928:                return;
        !          3929:        }
        !          3930: 
        !          3931:        if (fname_len >= sizeof(".phar")-1 && !memcmp(fname, ".phar", sizeof(".phar")-1)) {
        !          3932:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot set any files or directories in magic \".phar\" directory", phar_obj->arc.archive->fname);
        !          3933:                return;
        !          3934:        }
        !          3935: 
        !          3936:        phar_add_file(&(phar_obj->arc.archive), fname, fname_len, cont_str, cont_len, zresource TSRMLS_CC);
        !          3937: }
        !          3938: /* }}} */
        !          3939: 
        !          3940: /* {{{ proto int Phar::offsetUnset(string entry)
        !          3941:  * remove a file from a phar
        !          3942:  */
        !          3943: PHP_METHOD(Phar, offsetUnset)
        !          3944: {
        !          3945:        char *fname, *error;
        !          3946:        int fname_len;
        !          3947:        phar_entry_info *entry;
        !          3948:        PHAR_ARCHIVE_OBJECT();
        !          3949: 
        !          3950:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          3951:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by the php.ini setting phar.readonly");
        !          3952:                return;
        !          3953:        }
        !          3954: 
        !          3955:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
        !          3956:                return;
        !          3957:        }
        !          3958: 
        !          3959:        if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
        !          3960:                if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) {
        !          3961:                        if (entry->is_deleted) {
        !          3962:                                /* entry is deleted, but has not been flushed to disk yet */
        !          3963:                                return;
        !          3964:                        }
        !          3965: 
        !          3966:                        if (phar_obj->arc.archive->is_persistent) {
        !          3967:                                if (FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          3968:                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          3969:                                        return;
        !          3970:                                }
        !          3971:                                /* re-populate entry after copy on write */
        !          3972:                                zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void **)&entry);
        !          3973:                        }
        !          3974:                        entry->is_modified = 0;
        !          3975:                        entry->is_deleted = 1;
        !          3976:                        /* we need to "flush" the stream to save the newly deleted file on disk */
        !          3977:                        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          3978: 
        !          3979:                        if (error) {
        !          3980:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          3981:                                efree(error);
        !          3982:                        }
        !          3983: 
        !          3984:                        RETURN_TRUE;
        !          3985:                }
        !          3986:        } else {
        !          3987:                RETURN_FALSE;
        !          3988:        }
        !          3989: }
        !          3990: /* }}} */
        !          3991: 
        !          3992: /* {{{ proto string Phar::addEmptyDir(string dirname)
        !          3993:  * Adds an empty directory to the phar archive
        !          3994:  */
        !          3995: PHP_METHOD(Phar, addEmptyDir)
        !          3996: {
        !          3997:        char *dirname;
        !          3998:        int dirname_len;
        !          3999: 
        !          4000:        PHAR_ARCHIVE_OBJECT();
        !          4001: 
        !          4002:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &dirname, &dirname_len) == FAILURE) {
        !          4003:                return;
        !          4004:        }
        !          4005: 
        !          4006:        if (dirname_len >= sizeof(".phar")-1 && !memcmp(dirname, ".phar", sizeof(".phar")-1)) {
        !          4007:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot create a directory in magic \".phar\" directory");
        !          4008:                return;
        !          4009:        }
        !          4010: 
        !          4011:        phar_mkdir(&phar_obj->arc.archive, dirname, dirname_len TSRMLS_CC);
        !          4012: }
        !          4013: /* }}} */
        !          4014: 
        !          4015: /* {{{ proto string Phar::addFile(string filename[, string localname])
        !          4016:  * Adds a file to the archive using the filename, or the second parameter as the name within the archive
        !          4017:  */
        !          4018: PHP_METHOD(Phar, addFile)
        !          4019: {
        !          4020:        char *fname, *localname = NULL;
        !          4021:        int fname_len, localname_len = 0;
        !          4022:        php_stream *resource;
        !          4023:        zval *zresource;
        !          4024: 
        !          4025:        PHAR_ARCHIVE_OBJECT();
        !          4026: 
        !          4027:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &fname, &fname_len, &localname, &localname_len) == FAILURE) {
        !          4028:                return;
        !          4029:        }
        !          4030: 
        !          4031: #if PHP_API_VERSION < 20100412
        !          4032:        if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
        !          4033:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "phar error: unable to open file \"%s\" to add to phar archive, safe_mode restrictions prevent this", fname);
        !          4034:                return;
        !          4035:        }
        !          4036: #endif
        !          4037: 
        !          4038:        if (!strstr(fname, "://") && php_check_open_basedir(fname TSRMLS_CC)) {
        !          4039:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "phar error: unable to open file \"%s\" to add to phar archive, open_basedir restrictions prevent this", fname);
        !          4040:                return;
        !          4041:        }
        !          4042: 
        !          4043:        if (!(resource = php_stream_open_wrapper(fname, "rb", 0, NULL))) {
        !          4044:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "phar error: unable to open file \"%s\" to add to phar archive", fname);
        !          4045:                return;
        !          4046:        }
        !          4047: 
        !          4048:        if (localname) {
        !          4049:                fname = localname;
        !          4050:                fname_len = localname_len;
        !          4051:        }
        !          4052: 
        !          4053:        MAKE_STD_ZVAL(zresource);
        !          4054:        php_stream_to_zval(resource, zresource);
        !          4055:        phar_add_file(&(phar_obj->arc.archive), fname, fname_len, NULL, 0, zresource TSRMLS_CC);
        !          4056:        efree(zresource);
        !          4057:        php_stream_close(resource);
        !          4058: }
        !          4059: /* }}} */
        !          4060: 
        !          4061: /* {{{ proto string Phar::addFromString(string localname, string contents)
        !          4062:  * Adds a file to the archive using its contents as a string
        !          4063:  */
        !          4064: PHP_METHOD(Phar, addFromString)
        !          4065: {
        !          4066:        char *localname, *cont_str;
        !          4067:        int localname_len, cont_len;
        !          4068: 
        !          4069:        PHAR_ARCHIVE_OBJECT();
        !          4070: 
        !          4071:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &localname, &localname_len, &cont_str, &cont_len) == FAILURE) {
        !          4072:                return;
        !          4073:        }
        !          4074: 
        !          4075:        phar_add_file(&(phar_obj->arc.archive), localname, localname_len, cont_str, cont_len, NULL TSRMLS_CC);
        !          4076: }
        !          4077: /* }}} */
        !          4078: 
        !          4079: /* {{{ proto string Phar::getStub()
        !          4080:  * Returns the stub at the head of a phar archive as a string.
        !          4081:  */
        !          4082: PHP_METHOD(Phar, getStub)
        !          4083: {
        !          4084:        size_t len;
        !          4085:        char *buf;
        !          4086:        php_stream *fp;
        !          4087:        php_stream_filter *filter = NULL;
        !          4088:        phar_entry_info *stub;
        !          4089: 
        !          4090:        PHAR_ARCHIVE_OBJECT();
        !          4091:        
        !          4092:        if (zend_parse_parameters_none() == FAILURE) {
        !          4093:                return;
        !          4094:        }
        !          4095: 
        !          4096:        if (phar_obj->arc.archive->is_tar || phar_obj->arc.archive->is_zip) {
        !          4097: 
        !          4098:                if (SUCCESS == zend_hash_find(&(phar_obj->arc.archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1, (void **)&stub)) {
        !          4099:                        if (phar_obj->arc.archive->fp && !phar_obj->arc.archive->is_brandnew && !(stub->flags & PHAR_ENT_COMPRESSION_MASK)) {
        !          4100:                                fp = phar_obj->arc.archive->fp;
        !          4101:                        } else {
        !          4102:                                if (!(fp = php_stream_open_wrapper(phar_obj->arc.archive->fname, "rb", 0, NULL))) {
        !          4103:                                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "phar error: unable to open phar \"%s\"", phar_obj->arc.archive->fname);
        !          4104:                                        return;
        !          4105:                                }
        !          4106:                                if (stub->flags & PHAR_ENT_COMPRESSION_MASK) {
        !          4107:                                        char *filter_name;
        !          4108: 
        !          4109:                                        if ((filter_name = phar_decompress_filter(stub, 0)) != NULL) {
        !          4110:                                                filter = php_stream_filter_create(filter_name, NULL, php_stream_is_persistent(fp) TSRMLS_CC);
        !          4111:                                        } else {
        !          4112:                                                filter = NULL;
        !          4113:                                        }
        !          4114:                                        if (!filter) {
        !          4115:                                                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", phar_obj->arc.archive->fname, phar_decompress_filter(stub, 1));
        !          4116:                                                return;
        !          4117:                                        }
        !          4118:                                        php_stream_filter_append(&fp->readfilters, filter);
        !          4119:                                }
        !          4120:                        }
        !          4121: 
        !          4122:                        if (!fp)  {
        !          4123:                                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4124:                                        "Unable to read stub");
        !          4125:                                return;
        !          4126:                        }
        !          4127: 
        !          4128:                        php_stream_seek(fp, stub->offset_abs, SEEK_SET);
        !          4129:                        len = stub->uncompressed_filesize;
        !          4130:                        goto carry_on;
        !          4131:                } else {
        !          4132:                        RETURN_STRINGL("", 0, 1);
        !          4133:                }
        !          4134:        }
        !          4135:        len = phar_obj->arc.archive->halt_offset;
        !          4136: 
        !          4137:        if (phar_obj->arc.archive->fp && !phar_obj->arc.archive->is_brandnew) {
        !          4138:                fp = phar_obj->arc.archive->fp;
        !          4139:        } else {
        !          4140:                fp = php_stream_open_wrapper(phar_obj->arc.archive->fname, "rb", 0, NULL);
        !          4141:        }
        !          4142: 
        !          4143:        if (!fp)  {
        !          4144:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4145:                        "Unable to read stub");
        !          4146:                return;
        !          4147:        }
        !          4148: 
        !          4149:        php_stream_rewind(fp);
        !          4150: carry_on:
        !          4151:        buf = safe_emalloc(len, 1, 1);
        !          4152: 
        !          4153:        if (len != php_stream_read(fp, buf, len)) {
        !          4154:                if (fp != phar_obj->arc.archive->fp) {
        !          4155:                        php_stream_close(fp);
        !          4156:                }
        !          4157:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4158:                        "Unable to read stub");
        !          4159:                efree(buf);
        !          4160:                return;
        !          4161:        }
        !          4162: 
        !          4163:        if (filter) {
        !          4164:                php_stream_filter_flush(filter, 1);
        !          4165:                php_stream_filter_remove(filter, 1 TSRMLS_CC);
        !          4166:        }
        !          4167: 
        !          4168:        if (fp != phar_obj->arc.archive->fp) {
        !          4169:                php_stream_close(fp);
        !          4170:        }
        !          4171: 
        !          4172:        buf[len] = '\0';
        !          4173:        RETURN_STRINGL(buf, len, 0);
        !          4174: }
        !          4175: /* }}}*/
        !          4176: 
        !          4177: /* {{{ proto int Phar::hasMetaData()
        !          4178:  * Returns TRUE if the phar has global metadata, FALSE otherwise.
        !          4179:  */
        !          4180: PHP_METHOD(Phar, hasMetadata)
        !          4181: {
        !          4182:        PHAR_ARCHIVE_OBJECT();
        !          4183: 
        !          4184:        RETURN_BOOL(phar_obj->arc.archive->metadata != NULL);
        !          4185: }
        !          4186: /* }}} */
        !          4187: 
        !          4188: /* {{{ proto int Phar::getMetaData()
        !          4189:  * Returns the global metadata of the phar
        !          4190:  */
        !          4191: PHP_METHOD(Phar, getMetadata)
        !          4192: {
        !          4193:        PHAR_ARCHIVE_OBJECT();
        !          4194:        
        !          4195:        if (zend_parse_parameters_none() == FAILURE) {
        !          4196:                return;
        !          4197:        }
        !          4198: 
        !          4199:        if (phar_obj->arc.archive->metadata) {
        !          4200:                if (phar_obj->arc.archive->is_persistent) {
        !          4201:                        zval *ret;
        !          4202:                        char *buf = estrndup((char *) phar_obj->arc.archive->metadata, phar_obj->arc.archive->metadata_len);
        !          4203:                        /* assume success, we would have failed before */
        !          4204:                        phar_parse_metadata(&buf, &ret, phar_obj->arc.archive->metadata_len TSRMLS_CC);
        !          4205:                        efree(buf);
        !          4206:                        RETURN_ZVAL(ret, 0, 1);
        !          4207:                }
        !          4208:                RETURN_ZVAL(phar_obj->arc.archive->metadata, 1, 0);
        !          4209:        }
        !          4210: }
        !          4211: /* }}} */
        !          4212: 
        !          4213: /* {{{ proto int Phar::setMetaData(mixed $metadata)
        !          4214:  * Sets the global metadata of the phar
        !          4215:  */
        !          4216: PHP_METHOD(Phar, setMetadata)
        !          4217: {
        !          4218:        char *error;
        !          4219:        zval *metadata;
        !          4220: 
        !          4221:        PHAR_ARCHIVE_OBJECT();
        !          4222: 
        !          4223:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          4224:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by the php.ini setting phar.readonly");
        !          4225:                return;
        !          4226:        }
        !          4227: 
        !          4228:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &metadata) == FAILURE) {
        !          4229:                return;
        !          4230:        }
        !          4231: 
        !          4232:        if (phar_obj->arc.archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->arc.archive) TSRMLS_CC)) {
        !          4233:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
        !          4234:                return;
        !          4235:        }
        !          4236:        if (phar_obj->arc.archive->metadata) {
        !          4237:                zval_ptr_dtor(&phar_obj->arc.archive->metadata);
        !          4238:                phar_obj->arc.archive->metadata = NULL;
        !          4239:        }
        !          4240: 
        !          4241:        MAKE_STD_ZVAL(phar_obj->arc.archive->metadata);
        !          4242:        ZVAL_ZVAL(phar_obj->arc.archive->metadata, metadata, 1, 0);
        !          4243:        phar_obj->arc.archive->is_modified = 1;
        !          4244:        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          4245: 
        !          4246:        if (error) {
        !          4247:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          4248:                efree(error);
        !          4249:        }
        !          4250: }
        !          4251: /* }}} */
        !          4252: 
        !          4253: /* {{{ proto int Phar::delMetadata()
        !          4254:  * Deletes the global metadata of the phar
        !          4255:  */
        !          4256: PHP_METHOD(Phar, delMetadata)
        !          4257: {
        !          4258:        char *error;
        !          4259: 
        !          4260:        PHAR_ARCHIVE_OBJECT();
        !          4261: 
        !          4262:        if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
        !          4263:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by the php.ini setting phar.readonly");
        !          4264:                return;
        !          4265:        }
        !          4266: 
        !          4267:        if (phar_obj->arc.archive->metadata) {
        !          4268:                zval_ptr_dtor(&phar_obj->arc.archive->metadata);
        !          4269:                phar_obj->arc.archive->metadata = NULL;
        !          4270:                phar_obj->arc.archive->is_modified = 1;
        !          4271:                phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        !          4272: 
        !          4273:                if (error) {
        !          4274:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          4275:                        efree(error);
        !          4276:                        RETURN_FALSE;
        !          4277:                } else {
        !          4278:                        RETURN_TRUE;
        !          4279:                }
        !          4280: 
        !          4281:        } else {
        !          4282:                RETURN_TRUE;
        !          4283:        }
        !          4284: }
        !          4285: /* }}} */
        !          4286: #if PHP_API_VERSION < 20100412
        !          4287: #define PHAR_OPENBASEDIR_CHECKPATH(filename) \
        !          4288:        (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)
        !          4289: #else
        !          4290: #define PHAR_OPENBASEDIR_CHECKPATH(filename) \
        !          4291:        php_check_open_basedir(filename TSRMLS_CC)
        !          4292: #endif
        !          4293: 
        !          4294: static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char *dest, int dest_len, char **error TSRMLS_DC) /* {{{ */
        !          4295: {
        !          4296:        php_stream_statbuf ssb;
        !          4297:        int len;
        !          4298:        php_stream *fp;
        !          4299:        char *fullpath, *slash;
        !          4300:        mode_t mode;
        !          4301: 
        !          4302:        if (entry->is_mounted) {
        !          4303:                /* silently ignore mounted entries */
        !          4304:                return SUCCESS;
        !          4305:        }
        !          4306: 
        !          4307:        if (entry->filename_len >= sizeof(".phar")-1 && !memcmp(entry->filename, ".phar", sizeof(".phar")-1)) {
        !          4308:                return SUCCESS;
        !          4309:        }
        !          4310: 
        !          4311:        len = spprintf(&fullpath, 0, "%s/%s", dest, entry->filename);
        !          4312: 
        !          4313:        if (len >= MAXPATHLEN) {
        !          4314:                char *tmp;
        !          4315:                /* truncate for error message */
        !          4316:                fullpath[50] = '\0';
        !          4317:                if (entry->filename_len > 50) {
        !          4318:                        tmp = estrndup(entry->filename, 50);
        !          4319:                        spprintf(error, 4096, "Cannot extract \"%s...\" to \"%s...\", extracted filename is too long for filesystem", tmp, fullpath);
        !          4320:                        efree(tmp);
        !          4321:                } else {
        !          4322:                        spprintf(error, 4096, "Cannot extract \"%s\" to \"%s...\", extracted filename is too long for filesystem", entry->filename, fullpath);
        !          4323:                }
        !          4324:                efree(fullpath);
        !          4325:                return FAILURE;
        !          4326:        }
        !          4327: 
        !          4328:        if (!len) {
        !          4329:                spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename);
        !          4330:                efree(fullpath);
        !          4331:                return FAILURE;
        !          4332:        }
        !          4333: 
        !          4334:        if (PHAR_OPENBASEDIR_CHECKPATH(fullpath)) {
        !          4335:                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", openbasedir/safe mode restrictions in effect", entry->filename, fullpath);
        !          4336:                efree(fullpath);
        !          4337:                return FAILURE;
        !          4338:        }
        !          4339: 
        !          4340:        /* let see if the path already exists */
        !          4341:        if (!overwrite && SUCCESS == php_stream_stat_path(fullpath, &ssb)) {
        !          4342:                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", path already exists", entry->filename, fullpath);
        !          4343:                efree(fullpath);
        !          4344:                return FAILURE;
        !          4345:        }
        !          4346: 
        !          4347:        /* perform dirname */
        !          4348:        slash = zend_memrchr(entry->filename, '/', entry->filename_len);
        !          4349: 
        !          4350:        if (slash) {
        !          4351:                fullpath[dest_len + (slash - entry->filename) + 1] = '\0';
        !          4352:        } else {
        !          4353:                fullpath[dest_len] = '\0';
        !          4354:        }
        !          4355: 
        !          4356:        if (FAILURE == php_stream_stat_path(fullpath, &ssb)) {
        !          4357:                if (entry->is_dir) {
        !          4358:                        if (!php_stream_mkdir(fullpath, entry->flags & PHAR_ENT_PERM_MASK,  PHP_STREAM_MKDIR_RECURSIVE, NULL)) {
        !          4359:                                spprintf(error, 4096, "Cannot extract \"%s\", could not create directory \"%s\"", entry->filename, fullpath);
        !          4360:                                efree(fullpath);
        !          4361:                                return FAILURE;
        !          4362:                        }
        !          4363:                } else {
        !          4364:                        if (!php_stream_mkdir(fullpath, 0777,  PHP_STREAM_MKDIR_RECURSIVE, NULL)) {
        !          4365:                                spprintf(error, 4096, "Cannot extract \"%s\", could not create directory \"%s\"", entry->filename, fullpath);
        !          4366:                                efree(fullpath);
        !          4367:                                return FAILURE;
        !          4368:                        }
        !          4369:                }
        !          4370:        }
        !          4371: 
        !          4372:        if (slash) {
        !          4373:                fullpath[dest_len + (slash - entry->filename) + 1] = '/';
        !          4374:        } else {
        !          4375:                fullpath[dest_len] = '/';
        !          4376:        }
        !          4377: 
        !          4378:        /* it is a standalone directory, job done */
        !          4379:        if (entry->is_dir) {
        !          4380:                efree(fullpath);
        !          4381:                return SUCCESS;
        !          4382:        }
        !          4383: 
        !          4384: #if PHP_API_VERSION < 20100412
        !          4385:        fp = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
        !          4386: #else
        !          4387:        fp = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL);
        !          4388: #endif
        !          4389: 
        !          4390:        if (!fp) {
        !          4391:                spprintf(error, 4096, "Cannot extract \"%s\", could not open for writing \"%s\"", entry->filename, fullpath);
        !          4392:                efree(fullpath);
        !          4393:                return FAILURE;
        !          4394:        }
        !          4395: 
        !          4396:        if (!phar_get_efp(entry, 0 TSRMLS_CC)) {
        !          4397:                if (FAILURE == phar_open_entry_fp(entry, error, 1 TSRMLS_CC)) {
        !          4398:                        if (error) {
        !          4399:                                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer: %s", entry->filename, fullpath, *error);
        !          4400:                        } else {
        !          4401:                                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer", entry->filename, fullpath);
        !          4402:                        }
        !          4403:                        efree(fullpath);
        !          4404:                        php_stream_close(fp);
        !          4405:                        return FAILURE;
        !          4406:                }
        !          4407:        }
        !          4408: 
        !          4409:        if (FAILURE == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
        !          4410:                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to seek internal file pointer", entry->filename, fullpath);
        !          4411:                efree(fullpath);
        !          4412:                php_stream_close(fp);
        !          4413:                return FAILURE;
        !          4414:        }
        !          4415: 
        !          4416:        if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), fp, entry->uncompressed_filesize, NULL)) {
        !          4417:                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", copying contents failed", entry->filename, fullpath);
        !          4418:                efree(fullpath);
        !          4419:                php_stream_close(fp);
        !          4420:                return FAILURE;
        !          4421:        }
        !          4422: 
        !          4423:        php_stream_close(fp);
        !          4424:        mode = (mode_t) entry->flags & PHAR_ENT_PERM_MASK;
        !          4425: 
        !          4426:        if (FAILURE == VCWD_CHMOD(fullpath, mode)) {
        !          4427:                spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", setting file permissions failed", entry->filename, fullpath);
        !          4428:                efree(fullpath);
        !          4429:                return FAILURE;
        !          4430:        }
        !          4431: 
        !          4432:        efree(fullpath);
        !          4433:        return SUCCESS;
        !          4434: }
        !          4435: /* }}} */
        !          4436: 
        !          4437: /* {{{ proto bool Phar::extractTo(string pathto[[, mixed files], bool overwrite])
        !          4438:  * Extract one or more file from a phar archive, optionally overwriting existing files
        !          4439:  */
        !          4440: PHP_METHOD(Phar, extractTo)
        !          4441: {
        !          4442:        char *error = NULL;
        !          4443:        php_stream *fp;
        !          4444:        php_stream_statbuf ssb;
        !          4445:        phar_entry_info *entry;
        !          4446:        char *pathto, *filename, *actual;
        !          4447:        int pathto_len, filename_len;
        !          4448:        int ret, i;
        !          4449:        int nelems;
        !          4450:        zval *zval_files = NULL;
        !          4451:        zend_bool overwrite = 0;
        !          4452: 
        !          4453:        PHAR_ARCHIVE_OBJECT();
        !          4454: 
        !          4455:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z!b", &pathto, &pathto_len, &zval_files, &overwrite) == FAILURE) {
        !          4456:                return;
        !          4457:        }
        !          4458: 
        !          4459:        fp = php_stream_open_wrapper(phar_obj->arc.archive->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK, &actual);
        !          4460: 
        !          4461:        if (!fp) {
        !          4462:                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
        !          4463:                        "Invalid argument, %s cannot be found", phar_obj->arc.archive->fname);
        !          4464:                return;
        !          4465:        }
        !          4466: 
        !          4467:        efree(actual);
        !          4468:        php_stream_close(fp);
        !          4469: 
        !          4470:        if (pathto_len < 1) {
        !          4471:                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
        !          4472:                        "Invalid argument, extraction path must be non-zero length");
        !          4473:                return;
        !          4474:        }
        !          4475: 
        !          4476:        if (pathto_len >= MAXPATHLEN) {
        !          4477:                char *tmp = estrndup(pathto, 50);
        !          4478:                /* truncate for error message */
        !          4479:                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Cannot extract to \"%s...\", destination directory is too long for filesystem", tmp);
        !          4480:                efree(tmp);
        !          4481:                return;
        !          4482:        }
        !          4483: 
        !          4484:        if (php_stream_stat_path(pathto, &ssb) < 0) {
        !          4485:                ret = php_stream_mkdir(pathto, 0777,  PHP_STREAM_MKDIR_RECURSIVE, NULL);
        !          4486:                if (!ret) {
        !          4487:                        zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4488:                                "Unable to create path \"%s\" for extraction", pathto);
        !          4489:                        return;
        !          4490:                }
        !          4491:        } else if (!(ssb.sb.st_mode & S_IFDIR)) {
        !          4492:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4493:                        "Unable to use path \"%s\" for extraction, it is a file, must be a directory", pathto);
        !          4494:                return;
        !          4495:        }
        !          4496: 
        !          4497:        if (zval_files) {
        !          4498:                switch (Z_TYPE_P(zval_files)) {
        !          4499:                        case IS_NULL:
        !          4500:                                goto all_files;
        !          4501: #if PHP_VERSION_ID >= 60000
        !          4502:                        case IS_UNICODE:
        !          4503:                                zval_unicode_to_string(zval_files TSRMLS_CC);
        !          4504:                                /* break intentionally omitted */
        !          4505: #endif
        !          4506:                        case IS_STRING:
        !          4507:                                filename = Z_STRVAL_P(zval_files);
        !          4508:                                filename_len = Z_STRLEN_P(zval_files);
        !          4509:                                break;
        !          4510:                        case IS_ARRAY:
        !          4511:                                nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files));
        !          4512:                                if (nelems == 0 ) {
        !          4513:                                        RETURN_FALSE;
        !          4514:                                }
        !          4515:                                for (i = 0; i < nelems; i++) {
        !          4516:                                        zval **zval_file;
        !          4517:                                        if (zend_hash_index_find(Z_ARRVAL_P(zval_files), i, (void **) &zval_file) == SUCCESS) {
        !          4518:                                                switch (Z_TYPE_PP(zval_file)) {
        !          4519: #if PHP_VERSION_ID >= 60000
        !          4520:                                                        case IS_UNICODE:
        !          4521:                                                                zval_unicode_to_string(*(zval_file) TSRMLS_CC);
        !          4522:                                                                /* break intentionally omitted */
        !          4523: #endif
        !          4524:                                                        case IS_STRING:
        !          4525:                                                                break;
        !          4526:                                                        default:
        !          4527:                                                                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
        !          4528:                                                                        "Invalid argument, array of filenames to extract contains non-string value");
        !          4529:                                                                return;
        !          4530:                                                }
        !          4531:                                                if (FAILURE == zend_hash_find(&phar_obj->arc.archive->manifest, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), (void **)&entry)) {
        !          4532:                                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
        !          4533:                                                                "Phar Error: attempted to extract non-existent file \"%s\" from phar \"%s\"", Z_STRVAL_PP(zval_file), phar_obj->arc.archive->fname);
        !          4534:                                                }
        !          4535:                                                if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error TSRMLS_CC)) {
        !          4536:                                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
        !          4537:                                                                "Extraction from phar \"%s\" failed: %s", phar_obj->arc.archive->fname, error);
        !          4538:                                                        efree(error);
        !          4539:                                                        return;
        !          4540:                                                }
        !          4541:                                        }
        !          4542:                                }
        !          4543:                                RETURN_TRUE;
        !          4544:                        default:
        !          4545:                                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
        !          4546:                                        "Invalid argument, expected a filename (string) or array of filenames");
        !          4547:                                return;
        !          4548:                }
        !          4549: 
        !          4550:                if (FAILURE == zend_hash_find(&phar_obj->arc.archive->manifest, filename, filename_len, (void **)&entry)) {
        !          4551:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
        !          4552:                                "Phar Error: attempted to extract non-existent file \"%s\" from phar \"%s\"", filename, phar_obj->arc.archive->fname);
        !          4553:                        return;
        !          4554:                }
        !          4555: 
        !          4556:                if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error TSRMLS_CC)) {
        !          4557:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
        !          4558:                                "Extraction from phar \"%s\" failed: %s", phar_obj->arc.archive->fname, error);
        !          4559:                        efree(error);
        !          4560:                        return;
        !          4561:                }
        !          4562:        } else {
        !          4563:                phar_archive_data *phar;
        !          4564: all_files:
        !          4565:                phar = phar_obj->arc.archive;
        !          4566:                /* Extract all files */
        !          4567:                if (!zend_hash_num_elements(&(phar->manifest))) {
        !          4568:                        RETURN_TRUE;
        !          4569:                }
        !          4570: 
        !          4571:                for (zend_hash_internal_pointer_reset(&phar->manifest);
        !          4572:                zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
        !          4573:                zend_hash_move_forward(&phar->manifest)) {
        !          4574: 
        !          4575:                        if (zend_hash_get_current_data(&phar->manifest, (void **)&entry) == FAILURE) {
        !          4576:                                continue;
        !          4577:                        }
        !          4578: 
        !          4579:                        if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error TSRMLS_CC)) {
        !          4580:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
        !          4581:                                        "Extraction from phar \"%s\" failed: %s", phar->fname, error);
        !          4582:                                efree(error);
        !          4583:                                return;
        !          4584:                        }
        !          4585:                }
        !          4586:        }
        !          4587:        RETURN_TRUE;
        !          4588: }
        !          4589: /* }}} */
        !          4590: 
        !          4591: 
        !          4592: /* {{{ proto void PharFileInfo::__construct(string entry)
        !          4593:  * Construct a Phar entry object
        !          4594:  */
        !          4595: PHP_METHOD(PharFileInfo, __construct)
        !          4596: {
        !          4597:        char *fname, *arch, *entry, *error;
        !          4598:        int fname_len, arch_len, entry_len;
        !          4599:        phar_entry_object *entry_obj;
        !          4600:        phar_entry_info *entry_info;
        !          4601:        phar_archive_data *phar_data;
        !          4602:        zval *zobj = getThis(), arg1;
        !          4603: 
        !          4604:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) {
        !          4605:                return;
        !          4606:        }
        !          4607: 
        !          4608:        entry_obj = (phar_entry_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
        !          4609: 
        !          4610:        if (entry_obj->ent.entry) {
        !          4611:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
        !          4612:                return;
        !          4613:        }
        !          4614: 
        !          4615:        if (fname_len < 7 || memcmp(fname, "phar://", 7) || phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC) == FAILURE) {
        !          4616:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4617:                        "'%s' is not a valid phar archive URL (must have at least phar://filename.phar)", fname);
        !          4618:                return;
        !          4619:        }
        !          4620: 
        !          4621:        if (phar_open_from_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
        !          4622:                efree(arch);
        !          4623:                efree(entry);
        !          4624:                if (error) {
        !          4625:                        zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4626:                                "Cannot open phar file '%s': %s", fname, error);
        !          4627:                        efree(error);
        !          4628:                } else {
        !          4629:                        zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4630:                                "Cannot open phar file '%s'", fname);
        !          4631:                }
        !          4632:                return;
        !          4633:        }
        !          4634: 
        !          4635:        if ((entry_info = phar_get_entry_info_dir(phar_data, entry, entry_len, 1, &error, 1 TSRMLS_CC)) == NULL) {
        !          4636:                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC,
        !          4637:                        "Cannot access phar file entry '%s' in archive '%s'%s%s", entry, arch, error ? ", " : "", error ? error : "");
        !          4638:                efree(arch);
        !          4639:                efree(entry);
        !          4640:                return;
        !          4641:        }
        !          4642: 
        !          4643:        efree(arch);
        !          4644:        efree(entry);
        !          4645: 
        !          4646:        entry_obj->ent.entry = entry_info;
        !          4647: 
        !          4648:        INIT_PZVAL(&arg1);
        !          4649:        ZVAL_STRINGL(&arg1, fname, fname_len, 0);
        !          4650: 
        !          4651:        zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj), 
        !          4652:                &spl_ce_SplFileInfo->constructor, "__construct", NULL, &arg1);
        !          4653: }
        !          4654: /* }}} */
        !          4655: 
        !          4656: #define PHAR_ENTRY_OBJECT() \
        !          4657:        phar_entry_object *entry_obj = (phar_entry_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
        !          4658:        if (!entry_obj->ent.entry) { \
        !          4659:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4660:                        "Cannot call method on an uninitialized PharFileInfo object"); \
        !          4661:                return; \
        !          4662:        }
        !          4663: 
        !          4664: /* {{{ proto void PharFileInfo::__destruct()
        !          4665:  * clean up directory-based entry objects
        !          4666:  */
        !          4667: PHP_METHOD(PharFileInfo, __destruct)
        !          4668: {
        !          4669:        phar_entry_object *entry_obj = (phar_entry_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
        !          4670: 
        !          4671:        if (entry_obj->ent.entry && entry_obj->ent.entry->is_temp_dir) {
        !          4672:                if (entry_obj->ent.entry->filename) {
        !          4673:                        efree(entry_obj->ent.entry->filename);
        !          4674:                        entry_obj->ent.entry->filename = NULL;
        !          4675:                }
        !          4676: 
        !          4677:                efree(entry_obj->ent.entry);
        !          4678:                entry_obj->ent.entry = NULL;
        !          4679:        }
        !          4680: }
        !          4681: /* }}} */
        !          4682: 
        !          4683: /* {{{ proto int PharFileInfo::getCompressedSize()
        !          4684:  * Returns the compressed size
        !          4685:  */
        !          4686: PHP_METHOD(PharFileInfo, getCompressedSize)
        !          4687: {
        !          4688:        PHAR_ENTRY_OBJECT();
        !          4689:        
        !          4690:        if (zend_parse_parameters_none() == FAILURE) {
        !          4691:                return;
        !          4692:        }
        !          4693: 
        !          4694:        RETURN_LONG(entry_obj->ent.entry->compressed_filesize);
        !          4695: }
        !          4696: /* }}} */
        !          4697: 
        !          4698: /* {{{ proto bool PharFileInfo::isCompressed([int compression_type])
        !          4699:  * Returns whether the entry is compressed, and whether it is compressed with Phar::GZ or Phar::BZ2 if specified
        !          4700:  */
        !          4701: PHP_METHOD(PharFileInfo, isCompressed)
        !          4702: {
        !          4703:        /* a number that is not Phar::GZ or Phar::BZ2 */
        !          4704:        long method = 9021976;
        !          4705:        PHAR_ENTRY_OBJECT();
        !          4706: 
        !          4707:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &method) == FAILURE) {
        !          4708:                return;
        !          4709:        }
        !          4710: 
        !          4711:        switch (method) {
        !          4712:                case 9021976:
        !          4713:                        RETURN_BOOL(entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSION_MASK);
        !          4714:                case PHAR_ENT_COMPRESSED_GZ:
        !          4715:                        RETURN_BOOL(entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ);
        !          4716:                case PHAR_ENT_COMPRESSED_BZ2:
        !          4717:                        RETURN_BOOL(entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2);
        !          4718:                default:
        !          4719:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4720:                                "Unknown compression type specified"); \
        !          4721:        }
        !          4722: }
        !          4723: /* }}} */
        !          4724: 
        !          4725: /* {{{ proto int PharFileInfo::getCRC32()
        !          4726:  * Returns CRC32 code or throws an exception if not CRC checked
        !          4727:  */
        !          4728: PHP_METHOD(PharFileInfo, getCRC32)
        !          4729: {
        !          4730:        PHAR_ENTRY_OBJECT();
        !          4731:        
        !          4732:        if (zend_parse_parameters_none() == FAILURE) {
        !          4733:                return;
        !          4734:        }
        !          4735: 
        !          4736:        if (entry_obj->ent.entry->is_dir) {
        !          4737:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4738:                        "Phar entry is a directory, does not have a CRC"); \
        !          4739:                return;
        !          4740:        }
        !          4741: 
        !          4742:        if (entry_obj->ent.entry->is_crc_checked) {
        !          4743:                RETURN_LONG(entry_obj->ent.entry->crc32);
        !          4744:        } else {
        !          4745:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4746:                        "Phar entry was not CRC checked"); \
        !          4747:        }
        !          4748: }
        !          4749: /* }}} */
        !          4750: 
        !          4751: /* {{{ proto int PharFileInfo::isCRCChecked()
        !          4752:  * Returns whether file entry is CRC checked
        !          4753:  */
        !          4754: PHP_METHOD(PharFileInfo, isCRCChecked)
        !          4755: {
        !          4756:        PHAR_ENTRY_OBJECT();
        !          4757:        
        !          4758:        if (zend_parse_parameters_none() == FAILURE) {
        !          4759:                return;
        !          4760:        }
        !          4761: 
        !          4762:        RETURN_BOOL(entry_obj->ent.entry->is_crc_checked);
        !          4763: }
        !          4764: /* }}} */
        !          4765: 
        !          4766: /* {{{ proto int PharFileInfo::getPharFlags()
        !          4767:  * Returns the Phar file entry flags
        !          4768:  */
        !          4769: PHP_METHOD(PharFileInfo, getPharFlags)
        !          4770: {
        !          4771:        PHAR_ENTRY_OBJECT();
        !          4772:        
        !          4773:        if (zend_parse_parameters_none() == FAILURE) {
        !          4774:                return;
        !          4775:        }
        !          4776: 
        !          4777:        RETURN_LONG(entry_obj->ent.entry->flags & ~(PHAR_ENT_PERM_MASK|PHAR_ENT_COMPRESSION_MASK));
        !          4778: }
        !          4779: /* }}} */
        !          4780: 
        !          4781: /* {{{ proto int PharFileInfo::chmod()
        !          4782:  * set the file permissions for the Phar.  This only allows setting execution bit, read/write
        !          4783:  */
        !          4784: PHP_METHOD(PharFileInfo, chmod)
        !          4785: {
        !          4786:        char *error;
        !          4787:        long perms;
        !          4788:        PHAR_ENTRY_OBJECT();
        !          4789: 
        !          4790:        if (entry_obj->ent.entry->is_temp_dir) {
        !          4791:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4792:                        "Phar entry \"%s\" is a temporary directory (not an actual entry in the archive), cannot chmod", entry_obj->ent.entry->filename); \
        !          4793:                return;
        !          4794:        }
        !          4795: 
        !          4796:        if (PHAR_G(readonly) && !entry_obj->ent.entry->phar->is_data) {
        !          4797:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Cannot modify permissions for file \"%s\" in phar \"%s\", write operations are prohibited", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
        !          4798:                return;
        !          4799:        }
        !          4800: 
        !          4801:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &perms) == FAILURE) {
        !          4802:                return;
        !          4803:        }
        !          4804: 
        !          4805:        if (entry_obj->ent.entry->is_persistent) {
        !          4806:                phar_archive_data *phar = entry_obj->ent.entry->phar;
        !          4807: 
        !          4808:                if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) {
        !          4809:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname);
        !          4810:                        return;
        !          4811:                }
        !          4812:                /* re-populate after copy-on-write */
        !          4813:                zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
        !          4814:        }
        !          4815:        /* clear permissions */
        !          4816:        entry_obj->ent.entry->flags &= ~PHAR_ENT_PERM_MASK;
        !          4817:        perms &= 0777;
        !          4818:        entry_obj->ent.entry->flags |= perms;
        !          4819:        entry_obj->ent.entry->old_flags = entry_obj->ent.entry->flags;
        !          4820:        entry_obj->ent.entry->phar->is_modified = 1;
        !          4821:        entry_obj->ent.entry->is_modified = 1;
        !          4822: 
        !          4823:        /* hackish cache in php_stat needs to be cleared */
        !          4824:        /* if this code fails to work, check main/streams/streams.c, _php_stream_stat_path */
        !          4825:        if (BG(CurrentLStatFile)) {
        !          4826:                efree(BG(CurrentLStatFile));
        !          4827:        }
        !          4828: 
        !          4829:        if (BG(CurrentStatFile)) {
        !          4830:                efree(BG(CurrentStatFile));
        !          4831:        }
        !          4832: 
        !          4833:        BG(CurrentLStatFile) = NULL;
        !          4834:        BG(CurrentStatFile) = NULL;
        !          4835:        phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        !          4836: 
        !          4837:        if (error) {
        !          4838:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          4839:                efree(error);
        !          4840:        }
        !          4841: }
        !          4842: /* }}} */
        !          4843: 
        !          4844: /* {{{ proto int PharFileInfo::hasMetaData()
        !          4845:  * Returns the metadata of the entry
        !          4846:  */
        !          4847: PHP_METHOD(PharFileInfo, hasMetadata)
        !          4848: {
        !          4849:        PHAR_ENTRY_OBJECT();
        !          4850:        
        !          4851:        if (zend_parse_parameters_none() == FAILURE) {
        !          4852:                return;
        !          4853:        }
        !          4854: 
        !          4855:        RETURN_BOOL(entry_obj->ent.entry->metadata != NULL);
        !          4856: }
        !          4857: /* }}} */
        !          4858: 
        !          4859: /* {{{ proto int PharFileInfo::getMetaData()
        !          4860:  * Returns the metadata of the entry
        !          4861:  */
        !          4862: PHP_METHOD(PharFileInfo, getMetadata)
        !          4863: {
        !          4864:        PHAR_ENTRY_OBJECT();
        !          4865:        
        !          4866:        if (zend_parse_parameters_none() == FAILURE) {
        !          4867:                return;
        !          4868:        }
        !          4869: 
        !          4870:        if (entry_obj->ent.entry->metadata) {
        !          4871:                if (entry_obj->ent.entry->is_persistent) {
        !          4872:                        zval *ret;
        !          4873:                        char *buf = estrndup((char *) entry_obj->ent.entry->metadata, entry_obj->ent.entry->metadata_len);
        !          4874:                        /* assume success, we would have failed before */
        !          4875:                        phar_parse_metadata(&buf, &ret, entry_obj->ent.entry->metadata_len TSRMLS_CC);
        !          4876:                        efree(buf);
        !          4877:                        RETURN_ZVAL(ret, 0, 1);
        !          4878:                }
        !          4879:                RETURN_ZVAL(entry_obj->ent.entry->metadata, 1, 0);
        !          4880:        }
        !          4881: }
        !          4882: /* }}} */
        !          4883: 
        !          4884: /* {{{ proto int PharFileInfo::setMetaData(mixed $metadata)
        !          4885:  * Sets the metadata of the entry
        !          4886:  */
        !          4887: PHP_METHOD(PharFileInfo, setMetadata)
        !          4888: {
        !          4889:        char *error;
        !          4890:        zval *metadata;
        !          4891: 
        !          4892:        PHAR_ENTRY_OBJECT();
        !          4893: 
        !          4894:        if (PHAR_G(readonly) && !entry_obj->ent.entry->phar->is_data) {
        !          4895:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by the php.ini setting phar.readonly");
        !          4896:                return;
        !          4897:        }
        !          4898: 
        !          4899:        if (entry_obj->ent.entry->is_temp_dir) {
        !          4900:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4901:                        "Phar entry is a temporary directory (not an actual entry in the archive), cannot set metadata"); \
        !          4902:                return;
        !          4903:        }
        !          4904: 
        !          4905:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &metadata) == FAILURE) {
        !          4906:                return;
        !          4907:        }
        !          4908: 
        !          4909:        if (entry_obj->ent.entry->is_persistent) {
        !          4910:                phar_archive_data *phar = entry_obj->ent.entry->phar;
        !          4911: 
        !          4912:                if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) {
        !          4913:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname);
        !          4914:                        return;
        !          4915:                }
        !          4916:                /* re-populate after copy-on-write */
        !          4917:                zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
        !          4918:        }
        !          4919:        if (entry_obj->ent.entry->metadata) {
        !          4920:                zval_ptr_dtor(&entry_obj->ent.entry->metadata);
        !          4921:                entry_obj->ent.entry->metadata = NULL;
        !          4922:        }
        !          4923: 
        !          4924:        MAKE_STD_ZVAL(entry_obj->ent.entry->metadata);
        !          4925:        ZVAL_ZVAL(entry_obj->ent.entry->metadata, metadata, 1, 0);
        !          4926: 
        !          4927:        entry_obj->ent.entry->is_modified = 1;
        !          4928:        entry_obj->ent.entry->phar->is_modified = 1;
        !          4929:        phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        !          4930: 
        !          4931:        if (error) {
        !          4932:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          4933:                efree(error);
        !          4934:        }
        !          4935: }
        !          4936: /* }}} */
        !          4937: 
        !          4938: /* {{{ proto bool PharFileInfo::delMetaData()
        !          4939:  * Deletes the metadata of the entry
        !          4940:  */
        !          4941: PHP_METHOD(PharFileInfo, delMetadata)
        !          4942: {
        !          4943:        char *error;
        !          4944: 
        !          4945:        PHAR_ENTRY_OBJECT();
        !          4946:        
        !          4947:        if (zend_parse_parameters_none() == FAILURE) {
        !          4948:                return;
        !          4949:        }
        !          4950: 
        !          4951:        if (PHAR_G(readonly) && !entry_obj->ent.entry->phar->is_data) {
        !          4952:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by the php.ini setting phar.readonly");
        !          4953:                return;
        !          4954:        }
        !          4955: 
        !          4956:        if (entry_obj->ent.entry->is_temp_dir) {
        !          4957:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          4958:                        "Phar entry is a temporary directory (not an actual entry in the archive), cannot delete metadata"); \
        !          4959:                return;
        !          4960:        }
        !          4961: 
        !          4962:        if (entry_obj->ent.entry->metadata) {
        !          4963:                if (entry_obj->ent.entry->is_persistent) {
        !          4964:                        phar_archive_data *phar = entry_obj->ent.entry->phar;
        !          4965: 
        !          4966:                        if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) {
        !          4967:                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname);
        !          4968:                                return;
        !          4969:                        }
        !          4970:                        /* re-populate after copy-on-write */
        !          4971:                        zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
        !          4972:                }
        !          4973:                zval_ptr_dtor(&entry_obj->ent.entry->metadata);
        !          4974:                entry_obj->ent.entry->metadata = NULL;
        !          4975:                entry_obj->ent.entry->is_modified = 1;
        !          4976:                entry_obj->ent.entry->phar->is_modified = 1;
        !          4977: 
        !          4978:                phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        !          4979: 
        !          4980:                if (error) {
        !          4981:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          4982:                        efree(error);
        !          4983:                        RETURN_FALSE;
        !          4984:                } else {
        !          4985:                        RETURN_TRUE;
        !          4986:                }
        !          4987: 
        !          4988:        } else {
        !          4989:                RETURN_TRUE;
        !          4990:        }
        !          4991: }
        !          4992: /* }}} */
        !          4993: 
        !          4994: /* {{{ proto string PharFileInfo::getContent()
        !          4995:  * return the complete file contents of the entry (like file_get_contents)
        !          4996:  */
        !          4997: PHP_METHOD(PharFileInfo, getContent)
        !          4998: {
        !          4999:        char *error;
        !          5000:        php_stream *fp;
        !          5001:        phar_entry_info *link;
        !          5002: 
        !          5003:        PHAR_ENTRY_OBJECT();
        !          5004:        
        !          5005:        if (zend_parse_parameters_none() == FAILURE) {
        !          5006:                return;
        !          5007:        }
        !          5008: 
        !          5009:        if (entry_obj->ent.entry->is_dir) {
        !          5010:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5011:                        "Phar error: Cannot retrieve contents, \"%s\" in phar \"%s\" is a directory", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
        !          5012:                return;
        !          5013:        }
        !          5014: 
        !          5015:        link = phar_get_link_source(entry_obj->ent.entry TSRMLS_CC);
        !          5016: 
        !          5017:        if (!link) {
        !          5018:                link = entry_obj->ent.entry;
        !          5019:        }
        !          5020: 
        !          5021:        if (SUCCESS != phar_open_entry_fp(link, &error, 0 TSRMLS_CC)) {
        !          5022:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5023:                        "Phar error: Cannot retrieve contents, \"%s\" in phar \"%s\": %s", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname, error);
        !          5024:                efree(error);
        !          5025:                return;
        !          5026:        }
        !          5027: 
        !          5028:        if (!(fp = phar_get_efp(link, 0 TSRMLS_CC))) {
        !          5029:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5030:                        "Phar error: Cannot retrieve contents of \"%s\" in phar \"%s\"", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
        !          5031:                return;
        !          5032:        }
        !          5033: 
        !          5034:        phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC);
        !          5035:        Z_TYPE_P(return_value) = IS_STRING;
        !          5036: #if PHP_MAJOR_VERSION >= 6
        !          5037:        Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, (void **) &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
        !          5038: #else
        !          5039:        Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
        !          5040: #endif
        !          5041: 
        !          5042:        if (!Z_STRVAL_P(return_value)) {
        !          5043:                Z_STRVAL_P(return_value) = estrndup("", 0);
        !          5044:        }
        !          5045: }
        !          5046: /* }}} */
        !          5047: 
        !          5048: /* {{{ proto int PharFileInfo::compress(int compression_type)
        !          5049:  * Instructs the Phar class to compress the current file using zlib or bzip2 compression
        !          5050:  */
        !          5051: PHP_METHOD(PharFileInfo, compress)
        !          5052: {
        !          5053:        long method;
        !          5054:        char *error;
        !          5055:        PHAR_ENTRY_OBJECT();
        !          5056: 
        !          5057:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &method) == FAILURE) {
        !          5058:                return;
        !          5059:        }
        !          5060: 
        !          5061:        if (entry_obj->ent.entry->is_tar) {
        !          5062:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5063:                        "Cannot compress with Gzip compression, not possible with tar-based phar archives");
        !          5064:                return;
        !          5065:        }
        !          5066: 
        !          5067:        if (entry_obj->ent.entry->is_dir) {
        !          5068:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          5069:                        "Phar entry is a directory, cannot set compression"); \
        !          5070:                return;
        !          5071:        }
        !          5072: 
        !          5073:        if (PHAR_G(readonly) && !entry_obj->ent.entry->phar->is_data) {
        !          5074:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5075:                        "Phar is readonly, cannot change compression");
        !          5076:                return;
        !          5077:        }
        !          5078: 
        !          5079:        if (entry_obj->ent.entry->is_deleted) {
        !          5080:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5081:                        "Cannot compress deleted file");
        !          5082:                return;
        !          5083:        }
        !          5084: 
        !          5085:        if (entry_obj->ent.entry->is_persistent) {
        !          5086:                phar_archive_data *phar = entry_obj->ent.entry->phar;
        !          5087: 
        !          5088:                if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) {
        !          5089:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname);
        !          5090:                        return;
        !          5091:                }
        !          5092:                /* re-populate after copy-on-write */
        !          5093:                zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
        !          5094:        }
        !          5095:        switch (method) {
        !          5096:                case PHAR_ENT_COMPRESSED_GZ:
        !          5097:                        if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) {
        !          5098:                                RETURN_TRUE;
        !          5099:                        }
        !          5100: 
        !          5101:                        if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) != 0) {
        !          5102:                                if (!PHAR_G(has_bz2)) {
        !          5103:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5104:                                                "Cannot compress with gzip compression, file is already compressed with bzip2 compression and bz2 extension is not enabled, cannot decompress");
        !          5105:                                        return;
        !          5106:                                }
        !          5107: 
        !          5108:                                /* decompress this file indirectly */
        !          5109:                                if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error, 1 TSRMLS_CC)) {
        !          5110:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5111:                                                "Phar error: Cannot decompress bzip2-compressed file \"%s\" in phar \"%s\" in order to compress with gzip: %s", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname, error);
        !          5112:                                        efree(error);
        !          5113:                                        return;
        !          5114:                                }
        !          5115:                        }
        !          5116: 
        !          5117:                        if (!PHAR_G(has_zlib)) {
        !          5118:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5119:                                        "Cannot compress with gzip compression, zlib extension is not enabled");
        !          5120:                                return;
        !          5121:                        }
        !          5122: 
        !          5123:                        entry_obj->ent.entry->old_flags = entry_obj->ent.entry->flags;
        !          5124:                        entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
        !          5125:                        entry_obj->ent.entry->flags |= PHAR_ENT_COMPRESSED_GZ;
        !          5126:                        break;
        !          5127:                case PHAR_ENT_COMPRESSED_BZ2:
        !          5128:                        if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
        !          5129:                                RETURN_TRUE;
        !          5130:                        }
        !          5131: 
        !          5132:                        if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) != 0) {
        !          5133:                                if (!PHAR_G(has_zlib)) {
        !          5134:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5135:                                                "Cannot compress with bzip2 compression, file is already compressed with gzip compression and zlib extension is not enabled, cannot decompress");
        !          5136:                                        return;
        !          5137:                                }
        !          5138: 
        !          5139:                                /* decompress this file indirectly */
        !          5140:                                if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error, 1 TSRMLS_CC)) {
        !          5141:                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5142:                                                "Phar error: Cannot decompress gzip-compressed file \"%s\" in phar \"%s\" in order to compress with bzip2: %s", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname, error);
        !          5143:                                        efree(error);
        !          5144:                                        return;
        !          5145:                                }
        !          5146:                        }
        !          5147: 
        !          5148:                        if (!PHAR_G(has_bz2)) {
        !          5149:                                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5150:                                        "Cannot compress with bzip2 compression, bz2 extension is not enabled");
        !          5151:                                return;
        !          5152:                        }
        !          5153:                        entry_obj->ent.entry->old_flags = entry_obj->ent.entry->flags;
        !          5154:                        entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
        !          5155:                        entry_obj->ent.entry->flags |= PHAR_ENT_COMPRESSED_BZ2;
        !          5156:                        break;
        !          5157:                default:
        !          5158:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          5159:                                "Unknown compression type specified"); \
        !          5160:        }
        !          5161: 
        !          5162:        entry_obj->ent.entry->phar->is_modified = 1;
        !          5163:        entry_obj->ent.entry->is_modified = 1;
        !          5164:        phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        !          5165: 
        !          5166:        if (error) {
        !          5167:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          5168:                efree(error);
        !          5169:        }
        !          5170: 
        !          5171:        RETURN_TRUE;
        !          5172: }
        !          5173: /* }}} */
        !          5174: 
        !          5175: /* {{{ proto int PharFileInfo::decompress()
        !          5176:  * Instructs the Phar class to decompress the current file
        !          5177:  */
        !          5178: PHP_METHOD(PharFileInfo, decompress)
        !          5179: {
        !          5180:        char *error;
        !          5181:        PHAR_ENTRY_OBJECT();
        !          5182:        
        !          5183:        if (zend_parse_parameters_none() == FAILURE) {
        !          5184:                return;
        !          5185:        }
        !          5186: 
        !          5187:        if (entry_obj->ent.entry->is_dir) {
        !          5188:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
        !          5189:                        "Phar entry is a directory, cannot set compression"); \
        !          5190:                return;
        !          5191:        }
        !          5192: 
        !          5193:        if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSION_MASK) == 0) {
        !          5194:                RETURN_TRUE;
        !          5195:        }
        !          5196: 
        !          5197:        if (PHAR_G(readonly) && !entry_obj->ent.entry->phar->is_data) {
        !          5198:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5199:                        "Phar is readonly, cannot decompress");
        !          5200:                return;
        !          5201:        }
        !          5202: 
        !          5203:        if (entry_obj->ent.entry->is_deleted) {
        !          5204:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5205:                        "Cannot compress deleted file");
        !          5206:                return;
        !          5207:        }
        !          5208: 
        !          5209:        if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) != 0 && !PHAR_G(has_zlib)) {
        !          5210:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5211:                        "Cannot decompress Gzip-compressed file, zlib extension is not enabled");
        !          5212:                return;
        !          5213:        }
        !          5214: 
        !          5215:        if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) != 0 && !PHAR_G(has_bz2)) {
        !          5216:                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
        !          5217:                        "Cannot decompress Bzip2-compressed file, bz2 extension is not enabled");
        !          5218:                return;
        !          5219:        }
        !          5220: 
        !          5221:        if (entry_obj->ent.entry->is_persistent) {
        !          5222:                phar_archive_data *phar = entry_obj->ent.entry->phar;
        !          5223: 
        !          5224:                if (FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) {
        !          5225:                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar->fname);
        !          5226:                        return;
        !          5227:                }
        !          5228:                /* re-populate after copy-on-write */
        !          5229:                zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
        !          5230:        }
        !          5231:        if (!entry_obj->ent.entry->fp) {
        !          5232:                if (FAILURE == phar_open_archive_fp(entry_obj->ent.entry->phar TSRMLS_CC)) {
        !          5233:                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot decompress entry \"%s\", phar error: Cannot open phar archive \"%s\" for reading", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
        !          5234:                        return;
        !          5235:                }
        !          5236:                entry_obj->ent.entry->fp_type = PHAR_FP;
        !          5237:        }
        !          5238: 
        !          5239:        entry_obj->ent.entry->old_flags = entry_obj->ent.entry->flags;
        !          5240:        entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
        !          5241:        entry_obj->ent.entry->phar->is_modified = 1;
        !          5242:        entry_obj->ent.entry->is_modified = 1;
        !          5243:        phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        !          5244: 
        !          5245:        if (error) {
        !          5246:                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
        !          5247:                efree(error);
        !          5248:        }
        !          5249:        RETURN_TRUE;
        !          5250: }
        !          5251: /* }}} */
        !          5252: 
        !          5253: #endif /* HAVE_SPL */
        !          5254: 
        !          5255: /* {{{ phar methods */
        !          5256: PHAR_ARG_INFO
        !          5257: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1)
        !          5258:        ZEND_ARG_INFO(0, filename)
        !          5259:        ZEND_ARG_INFO(0, flags)
        !          5260:        ZEND_ARG_INFO(0, alias)
        !          5261:        ZEND_ARG_INFO(0, fileformat)
        !          5262: ZEND_END_ARG_INFO()
        !          5263: 
        !          5264: PHAR_ARG_INFO
        !          5265: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_createDS, 0, 0, 0)
        !          5266:        ZEND_ARG_INFO(0, index)
        !          5267:        ZEND_ARG_INFO(0, webindex)
        !          5268: ZEND_END_ARG_INFO()
        !          5269: 
        !          5270: PHAR_ARG_INFO
        !          5271: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_cancompress, 0, 0, 0)
        !          5272:        ZEND_ARG_INFO(0, method)
        !          5273: ZEND_END_ARG_INFO()
        !          5274: 
        !          5275: PHAR_ARG_INFO
        !          5276: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_isvalidpharfilename, 0, 0, 1)
        !          5277:        ZEND_ARG_INFO(0, filename)
        !          5278:        ZEND_ARG_INFO(0, executable)
        !          5279: ZEND_END_ARG_INFO()
        !          5280: 
        !          5281: PHAR_ARG_INFO
        !          5282: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_loadPhar, 0, 0, 1)
        !          5283:        ZEND_ARG_INFO(0, filename)
        !          5284:        ZEND_ARG_INFO(0, alias)
        !          5285: ZEND_END_ARG_INFO()
        !          5286: 
        !          5287: PHAR_ARG_INFO
        !          5288: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mapPhar, 0, 0, 0)
        !          5289:        ZEND_ARG_INFO(0, alias)
        !          5290:        ZEND_ARG_INFO(0, offset)
        !          5291: ZEND_END_ARG_INFO()
        !          5292: 
        !          5293: PHAR_ARG_INFO
        !          5294: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mount, 0, 0, 2)
        !          5295:        ZEND_ARG_INFO(0, inphar)
        !          5296:        ZEND_ARG_INFO(0, externalfile)
        !          5297: ZEND_END_ARG_INFO()
        !          5298: 
        !          5299: PHAR_ARG_INFO
        !          5300: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mungServer, 0, 0, 1)
        !          5301:        ZEND_ARG_INFO(0, munglist)
        !          5302: ZEND_END_ARG_INFO()
        !          5303: 
        !          5304: PHAR_ARG_INFO
        !          5305: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_webPhar, 0, 0, 0)
        !          5306:        ZEND_ARG_INFO(0, alias)
        !          5307:        ZEND_ARG_INFO(0, index)
        !          5308:        ZEND_ARG_INFO(0, f404)
        !          5309:        ZEND_ARG_INFO(0, mimetypes)
        !          5310:        ZEND_ARG_INFO(0, rewrites)
        !          5311: ZEND_END_ARG_INFO()
        !          5312: 
        !          5313: PHAR_ARG_INFO
        !          5314: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_running, 0, 0, 1)
        !          5315:        ZEND_ARG_INFO(0, retphar)
        !          5316: ZEND_END_ARG_INFO()
        !          5317: 
        !          5318: PHAR_ARG_INFO
        !          5319: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_ua, 0, 0, 1)
        !          5320:        ZEND_ARG_INFO(0, archive)
        !          5321: ZEND_END_ARG_INFO()
        !          5322: 
        !          5323: #if HAVE_SPL
        !          5324: PHAR_ARG_INFO
        !          5325: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_build, 0, 0, 1)
        !          5326:        ZEND_ARG_INFO(0, iterator)
        !          5327:        ZEND_ARG_INFO(0, base_directory)
        !          5328: ZEND_END_ARG_INFO()
        !          5329: 
        !          5330: PHAR_ARG_INFO
        !          5331: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_conv, 0, 0, 0)
        !          5332:        ZEND_ARG_INFO(0, format)
        !          5333:        ZEND_ARG_INFO(0, compression_type)
        !          5334:        ZEND_ARG_INFO(0, file_ext)
        !          5335: ZEND_END_ARG_INFO()
        !          5336: 
        !          5337: PHAR_ARG_INFO
        !          5338: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comps, 0, 0, 1)
        !          5339:        ZEND_ARG_INFO(0, compression_type)
        !          5340:        ZEND_ARG_INFO(0, file_ext)
        !          5341: ZEND_END_ARG_INFO()
        !          5342: 
        !          5343: PHAR_ARG_INFO
        !          5344: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_decomp, 0, 0, 0)
        !          5345:        ZEND_ARG_INFO(0, file_ext)
        !          5346: ZEND_END_ARG_INFO()
        !          5347: 
        !          5348: PHAR_ARG_INFO
        !          5349: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comp, 0, 0, 1)
        !          5350:        ZEND_ARG_INFO(0, compression_type)
        !          5351: ZEND_END_ARG_INFO()
        !          5352: 
        !          5353: PHAR_ARG_INFO
        !          5354: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_compo, 0, 0, 0)
        !          5355:        ZEND_ARG_INFO(0, compression_type)
        !          5356: ZEND_END_ARG_INFO()
        !          5357: 
        !          5358: PHAR_ARG_INFO
        !          5359: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_copy, 0, 0, 2)
        !          5360:        ZEND_ARG_INFO(0, newfile)
        !          5361:        ZEND_ARG_INFO(0, oldfile)
        !          5362: ZEND_END_ARG_INFO()
        !          5363: 
        !          5364: PHAR_ARG_INFO
        !          5365: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_delete, 0, 0, 1)
        !          5366:        ZEND_ARG_INFO(0, entry)
        !          5367: ZEND_END_ARG_INFO()
        !          5368: 
        !          5369: PHAR_ARG_INFO
        !          5370: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_fromdir, 0, 0, 1)
        !          5371:        ZEND_ARG_INFO(0, base_dir)
        !          5372:        ZEND_ARG_INFO(0, regex)
        !          5373: ZEND_END_ARG_INFO()
        !          5374: 
        !          5375: PHAR_ARG_INFO
        !          5376: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_offsetExists, 0, 0, 1)
        !          5377:        ZEND_ARG_INFO(0, entry)
        !          5378: ZEND_END_ARG_INFO()
        !          5379: 
        !          5380: PHAR_ARG_INFO
        !          5381: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_offsetSet, 0, 0, 2)
        !          5382:        ZEND_ARG_INFO(0, entry)
        !          5383:        ZEND_ARG_INFO(0, value)
        !          5384: ZEND_END_ARG_INFO()
        !          5385: 
        !          5386: PHAR_ARG_INFO
        !          5387: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setAlias, 0, 0, 1)
        !          5388:        ZEND_ARG_INFO(0, alias)
        !          5389: ZEND_END_ARG_INFO()
        !          5390: 
        !          5391: PHAR_ARG_INFO
        !          5392: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setMetadata, 0, 0, 1)
        !          5393:        ZEND_ARG_INFO(0, metadata)
        !          5394: ZEND_END_ARG_INFO()
        !          5395: 
        !          5396: PHAR_ARG_INFO
        !          5397: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setSigAlgo, 0, 0, 1)
        !          5398:        ZEND_ARG_INFO(0, algorithm)
        !          5399:        ZEND_ARG_INFO(0, privatekey)
        !          5400: ZEND_END_ARG_INFO()
        !          5401: 
        !          5402: PHAR_ARG_INFO
        !          5403: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setStub, 0, 0, 1)
        !          5404:        ZEND_ARG_INFO(0, newstub)
        !          5405:        ZEND_ARG_INFO(0, maxlen)
        !          5406: ZEND_END_ARG_INFO()
        !          5407: 
        !          5408: PHAR_ARG_INFO
        !          5409: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_emptydir, 0, 0, 0)
        !          5410:        ZEND_ARG_INFO(0, dirname)
        !          5411: ZEND_END_ARG_INFO()
        !          5412: 
        !          5413: PHAR_ARG_INFO
        !          5414: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_extract, 0, 0, 1)
        !          5415:        ZEND_ARG_INFO(0, pathto)
        !          5416:        ZEND_ARG_INFO(0, files)
        !          5417:        ZEND_ARG_INFO(0, overwrite)
        !          5418: ZEND_END_ARG_INFO()
        !          5419: 
        !          5420: PHAR_ARG_INFO
        !          5421: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_addfile, 0, 0, 1)
        !          5422:        ZEND_ARG_INFO(0, filename)
        !          5423:        ZEND_ARG_INFO(0, localname)
        !          5424: ZEND_END_ARG_INFO()
        !          5425: 
        !          5426: PHAR_ARG_INFO
        !          5427: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_fromstring, 0, 0, 1)
        !          5428:        ZEND_ARG_INFO(0, localname)
        !          5429:        ZEND_ARG_INFO(0, contents)
        !          5430: ZEND_END_ARG_INFO()
        !          5431: 
        !          5432: PHAR_ARG_INFO
        !          5433: ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_isff, 0, 0, 1)
        !          5434:        ZEND_ARG_INFO(0, fileformat)
        !          5435: ZEND_END_ARG_INFO()
        !          5436: 
        !          5437: PHAR_ARG_INFO
        !          5438: ZEND_BEGIN_ARG_INFO(arginfo_phar__void, 0)
        !          5439: ZEND_END_ARG_INFO()
        !          5440: 
        !          5441: 
        !          5442: #endif /* HAVE_SPL */
        !          5443: 
        !          5444: zend_function_entry php_archive_methods[] = {
        !          5445: #if !HAVE_SPL
        !          5446:        PHP_ME(Phar, __construct,           arginfo_phar___construct,  ZEND_ACC_PRIVATE)
        !          5447: #else
        !          5448:        PHP_ME(Phar, __construct,           arginfo_phar___construct,  ZEND_ACC_PUBLIC)
        !          5449:        PHP_ME(Phar, __destruct,            arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5450:        PHP_ME(Phar, addEmptyDir,           arginfo_phar_emptydir,     ZEND_ACC_PUBLIC)
        !          5451:        PHP_ME(Phar, addFile,               arginfo_phar_addfile,      ZEND_ACC_PUBLIC)
        !          5452:        PHP_ME(Phar, addFromString,         arginfo_phar_fromstring,   ZEND_ACC_PUBLIC)
        !          5453:        PHP_ME(Phar, buildFromDirectory,    arginfo_phar_fromdir,      ZEND_ACC_PUBLIC)
        !          5454:        PHP_ME(Phar, buildFromIterator,     arginfo_phar_build,        ZEND_ACC_PUBLIC)
        !          5455:        PHP_ME(Phar, compressFiles,         arginfo_phar_comp,         ZEND_ACC_PUBLIC)
        !          5456:        PHP_ME(Phar, decompressFiles,       arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5457:        PHP_ME(Phar, compress,              arginfo_phar_comps,        ZEND_ACC_PUBLIC)
        !          5458:        PHP_ME(Phar, decompress,            arginfo_phar_decomp,       ZEND_ACC_PUBLIC)
        !          5459:        PHP_ME(Phar, convertToExecutable,   arginfo_phar_conv,         ZEND_ACC_PUBLIC)
        !          5460:        PHP_ME(Phar, convertToData,         arginfo_phar_conv,         ZEND_ACC_PUBLIC)
        !          5461:        PHP_ME(Phar, copy,                  arginfo_phar_copy,         ZEND_ACC_PUBLIC)
        !          5462:        PHP_ME(Phar, count,                 arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5463:        PHP_ME(Phar, delete,                arginfo_phar_delete,       ZEND_ACC_PUBLIC)
        !          5464:        PHP_ME(Phar, delMetadata,           arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5465:        PHP_ME(Phar, extractTo,             arginfo_phar_extract,      ZEND_ACC_PUBLIC)
        !          5466:        PHP_ME(Phar, getAlias,              arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5467:        PHP_ME(Phar, getPath,               arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5468:        PHP_ME(Phar, getMetadata,           arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5469:        PHP_ME(Phar, getModified,           arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5470:        PHP_ME(Phar, getSignature,          arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5471:        PHP_ME(Phar, getStub,               arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5472:        PHP_ME(Phar, getVersion,            arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5473:        PHP_ME(Phar, hasMetadata,           arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5474:        PHP_ME(Phar, isBuffering,           arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5475:        PHP_ME(Phar, isCompressed,          arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5476:        PHP_ME(Phar, isFileFormat,          arginfo_phar_isff,         ZEND_ACC_PUBLIC)
        !          5477:        PHP_ME(Phar, isWritable,            arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5478:        PHP_ME(Phar, offsetExists,          arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
        !          5479:        PHP_ME(Phar, offsetGet,             arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
        !          5480:        PHP_ME(Phar, offsetSet,             arginfo_phar_offsetSet,    ZEND_ACC_PUBLIC)
        !          5481:        PHP_ME(Phar, offsetUnset,           arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
        !          5482:        PHP_ME(Phar, setAlias,              arginfo_phar_setAlias,     ZEND_ACC_PUBLIC)
        !          5483:        PHP_ME(Phar, setDefaultStub,        arginfo_phar_createDS,     ZEND_ACC_PUBLIC)
        !          5484:        PHP_ME(Phar, setMetadata,           arginfo_phar_setMetadata,  ZEND_ACC_PUBLIC)
        !          5485:        PHP_ME(Phar, setSignatureAlgorithm, arginfo_phar_setSigAlgo,   ZEND_ACC_PUBLIC)
        !          5486:        PHP_ME(Phar, setStub,               arginfo_phar_setStub,      ZEND_ACC_PUBLIC)
        !          5487:        PHP_ME(Phar, startBuffering,        arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5488:        PHP_ME(Phar, stopBuffering,         arginfo_phar__void,        ZEND_ACC_PUBLIC)
        !          5489: #endif
        !          5490:        /* static member functions */
        !          5491:        PHP_ME(Phar, apiVersion,            arginfo_phar__void,        ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5492:        PHP_ME(Phar, canCompress,           arginfo_phar_cancompress,  ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5493:        PHP_ME(Phar, canWrite,              arginfo_phar__void,        ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5494:        PHP_ME(Phar, createDefaultStub,     arginfo_phar_createDS,     ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5495:        PHP_ME(Phar, getSupportedCompression,arginfo_phar__void,       ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5496:        PHP_ME(Phar, getSupportedSignatures,arginfo_phar__void,        ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5497:        PHP_ME(Phar, interceptFileFuncs,    arginfo_phar__void,        ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5498:        PHP_ME(Phar, isValidPharFilename,   arginfo_phar_isvalidpharfilename, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5499:        PHP_ME(Phar, loadPhar,              arginfo_phar_loadPhar,     ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5500:        PHP_ME(Phar, mapPhar,               arginfo_phar_mapPhar,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5501:        PHP_ME(Phar, running,               arginfo_phar_running,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5502:        PHP_ME(Phar, mount,                 arginfo_phar_mount,        ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5503:        PHP_ME(Phar, mungServer,            arginfo_phar_mungServer,   ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5504:        PHP_ME(Phar, unlinkArchive,         arginfo_phar_ua,           ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5505:        PHP_ME(Phar, webPhar,               arginfo_phar_webPhar,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        !          5506:        PHP_FE_END
        !          5507: };
        !          5508: 
        !          5509: #if HAVE_SPL
        !          5510: PHAR_ARG_INFO
        !          5511: ZEND_BEGIN_ARG_INFO_EX(arginfo_entry___construct, 0, 0, 1)
        !          5512:        ZEND_ARG_INFO(0, filename)
        !          5513: ZEND_END_ARG_INFO()
        !          5514: 
        !          5515: PHAR_ARG_INFO
        !          5516: ZEND_BEGIN_ARG_INFO_EX(arginfo_entry_chmod, 0, 0, 1)
        !          5517:        ZEND_ARG_INFO(0, perms)
        !          5518: ZEND_END_ARG_INFO()
        !          5519: 
        !          5520: zend_function_entry php_entry_methods[] = {
        !          5521:        PHP_ME(PharFileInfo, __construct,        arginfo_entry___construct,  ZEND_ACC_PUBLIC)
        !          5522:        PHP_ME(PharFileInfo, __destruct,         arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5523:        PHP_ME(PharFileInfo, chmod,              arginfo_entry_chmod,        ZEND_ACC_PUBLIC)
        !          5524:        PHP_ME(PharFileInfo, compress,           arginfo_phar_comp,          ZEND_ACC_PUBLIC)
        !          5525:        PHP_ME(PharFileInfo, decompress,         arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5526:        PHP_ME(PharFileInfo, delMetadata,        arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5527:        PHP_ME(PharFileInfo, getCompressedSize,  arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5528:        PHP_ME(PharFileInfo, getCRC32,           arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5529:        PHP_ME(PharFileInfo, getContent,         arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5530:        PHP_ME(PharFileInfo, getMetadata,        arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5531:        PHP_ME(PharFileInfo, getPharFlags,       arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5532:        PHP_ME(PharFileInfo, hasMetadata,        arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5533:        PHP_ME(PharFileInfo, isCompressed,       arginfo_phar_compo,         ZEND_ACC_PUBLIC)
        !          5534:        PHP_ME(PharFileInfo, isCRCChecked,       arginfo_phar__void,         ZEND_ACC_PUBLIC)
        !          5535:        PHP_ME(PharFileInfo, setMetadata,        arginfo_phar_setMetadata,   ZEND_ACC_PUBLIC)
        !          5536:        PHP_FE_END
        !          5537: };
        !          5538: #endif /* HAVE_SPL */
        !          5539: 
        !          5540: zend_function_entry phar_exception_methods[] = {
        !          5541:        PHP_FE_END
        !          5542: };
        !          5543: /* }}} */
        !          5544: 
        !          5545: #define REGISTER_PHAR_CLASS_CONST_LONG(class_name, const_name, value) \
        !          5546:        zend_declare_class_constant_long(class_name, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
        !          5547: 
        !          5548: #if PHP_VERSION_ID < 50200
        !          5549: # define phar_exception_get_default() zend_exception_get_default()
        !          5550: #else
        !          5551: # define phar_exception_get_default() zend_exception_get_default(TSRMLS_C)
        !          5552: #endif
        !          5553: 
        !          5554: void phar_object_init(TSRMLS_D) /* {{{ */
        !          5555: {
        !          5556:        zend_class_entry ce;
        !          5557: 
        !          5558:        INIT_CLASS_ENTRY(ce, "PharException", phar_exception_methods);
        !          5559:        phar_ce_PharException = zend_register_internal_class_ex(&ce, phar_exception_get_default(), NULL  TSRMLS_CC);
        !          5560: 
        !          5561: #if HAVE_SPL
        !          5562:        INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods);
        !          5563:        phar_ce_archive = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL  TSRMLS_CC);
        !          5564: 
        !          5565:        zend_class_implements(phar_ce_archive TSRMLS_CC, 2, spl_ce_Countable, zend_ce_arrayaccess);
        !          5566: 
        !          5567:        INIT_CLASS_ENTRY(ce, "PharData", php_archive_methods);
        !          5568:        phar_ce_data = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL  TSRMLS_CC);
        !          5569: 
        !          5570:        zend_class_implements(phar_ce_data TSRMLS_CC, 2, spl_ce_Countable, zend_ce_arrayaccess);
        !          5571: 
        !          5572:        INIT_CLASS_ENTRY(ce, "PharFileInfo", php_entry_methods);
        !          5573:        phar_ce_entry = zend_register_internal_class_ex(&ce, spl_ce_SplFileInfo, NULL  TSRMLS_CC);
        !          5574: #else
        !          5575:        INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods);
        !          5576:        phar_ce_archive = zend_register_internal_class(&ce TSRMLS_CC);
        !          5577:        phar_ce_archive->ce_flags |= ZEND_ACC_FINAL_CLASS;
        !          5578: 
        !          5579:        INIT_CLASS_ENTRY(ce, "PharData", php_archive_methods);
        !          5580:        phar_ce_data = zend_register_internal_class(&ce TSRMLS_CC);
        !          5581:        phar_ce_data->ce_flags |= ZEND_ACC_FINAL_CLASS;
        !          5582: #endif
        !          5583: 
        !          5584:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "BZ2", PHAR_ENT_COMPRESSED_BZ2)
        !          5585:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "GZ", PHAR_ENT_COMPRESSED_GZ)
        !          5586:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "NONE", PHAR_ENT_COMPRESSED_NONE)
        !          5587:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHAR", PHAR_FORMAT_PHAR)
        !          5588:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "TAR", PHAR_FORMAT_TAR)
        !          5589:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "ZIP", PHAR_FORMAT_ZIP)
        !          5590:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "COMPRESSED", PHAR_ENT_COMPRESSION_MASK)
        !          5591:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHP", PHAR_MIME_PHP)
        !          5592:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHPS", PHAR_MIME_PHPS)
        !          5593:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "MD5", PHAR_SIG_MD5)
        !          5594:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "OPENSSL", PHAR_SIG_OPENSSL)
        !          5595:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA1", PHAR_SIG_SHA1)
        !          5596:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA256", PHAR_SIG_SHA256)
        !          5597:        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA512", PHAR_SIG_SHA512)
        !          5598: }
        !          5599: /* }}} */
        !          5600: 
        !          5601: /*
        !          5602:  * Local variables:
        !          5603:  * tab-width: 4
        !          5604:  * c-basic-offset: 4
        !          5605:  * End:
        !          5606:  * vim600: noet sw=4 ts=4 fdm=marker
        !          5607:  * vim<600: noet sw=4 ts=4
        !          5608:  */

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