Annotation of embedaddon/php/ext/fileinfo/fileinfo.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:   | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       6:   +----------------------------------------------------------------------+
                      7:   | This source file is subject to version 3.0 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_0.txt.                                  |
                     11:   | If you did not receive a copy of the PHP license and are unable to   |
                     12:   | obtain it through the world-wide-web, please send a note to          |
                     13:   | license@php.net so we can mail you a copy immediately.               |
                     14:   +----------------------------------------------------------------------+
                     15:   | Author: Ilia Alshanetsky <ilia@php.net>                              |
                     16:   +----------------------------------------------------------------------+
                     17: */
                     18: 
1.1.1.2   misho      19: /* $Id$ */
1.1       misho      20: 
                     21: #ifdef HAVE_CONFIG_H
                     22: #include "config.h"
                     23: #endif
                     24: #include "php.h"
                     25: 
                     26: #include <magic.h>
                     27: /* 
                     28:  * HOWMANY specifies the maximum offset libmagic will look at
                     29:  * this is currently hardcoded in the libmagic source but not exported
                     30:  */
                     31: #ifndef HOWMANY
                     32: #define HOWMANY 65536
                     33: #endif
                     34: 
                     35: #include "php_ini.h"
                     36: #include "ext/standard/info.h"
                     37: #include "ext/standard/file.h" /* needed for context stuff */
                     38: #include "php_fileinfo.h"
                     39: #include "fopen_wrappers.h" /* needed for is_url */
                     40: 
                     41: #ifndef _S_IFDIR
                     42: # define _S_IFDIR              S_IFDIR
                     43: #endif
                     44: 
                     45: /* {{{ macros and type definitions */
                     46: struct php_fileinfo {
                     47:        long options;
                     48:        struct magic_set *magic;
                     49: };
                     50: 
                     51: static zend_object_handlers finfo_object_handlers;
                     52: zend_class_entry *finfo_class_entry;
                     53: 
                     54: struct finfo_object {
                     55:        zend_object zo;
                     56:        struct php_fileinfo *ptr;
                     57: };
                     58: 
                     59: #define FILEINFO_DECLARE_INIT_OBJECT(object) \
                     60:        zval *object = getThis();
                     61: 
                     62: #define FILEINFO_REGISTER_OBJECT(_object, _ptr) \
                     63: { \
                     64:        struct finfo_object *obj; \
                     65:         obj = (struct finfo_object*)zend_object_store_get_object(_object TSRMLS_CC); \
                     66:         obj->ptr = _ptr; \
                     67: }
                     68: 
                     69: #define FILEINFO_FROM_OBJECT(finfo, object) \
                     70: { \
                     71:        struct finfo_object *obj = zend_object_store_get_object(object TSRMLS_CC); \
                     72:        finfo = obj->ptr; \
                     73:        if (!finfo) { \
                     74:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The invalid fileinfo object."); \
                     75:                RETURN_FALSE; \
                     76:        } \
                     77: }
                     78: 
1.1.1.2   misho      79: /* {{{ finfo_objects_free
1.1       misho      80:  */
1.1.1.2   misho      81: static void finfo_objects_free(void *object TSRMLS_DC)
1.1       misho      82: {
                     83:        struct finfo_object *intern = (struct finfo_object *) object;
                     84: 
                     85:        if (intern->ptr) {
                     86:                magic_close(intern->ptr->magic);
                     87:                efree(intern->ptr);
                     88:        }
                     89: 
                     90:        zend_object_std_dtor(&intern->zo TSRMLS_CC);
                     91:        efree(intern);
                     92: }
                     93: /* }}} */
                     94: 
                     95: /* {{{ finfo_objects_new
                     96:  */
                     97: PHP_FILEINFO_API zend_object_value finfo_objects_new(zend_class_entry *class_type TSRMLS_DC)
                     98: {
                     99:        zend_object_value retval;
                    100:        struct finfo_object *intern;
                    101: 
                    102:        intern = emalloc(sizeof(struct finfo_object));
                    103:        memset(intern, 0, sizeof(struct finfo_object));
                    104: 
                    105:        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
1.1.1.2   misho     106:        object_properties_init(&intern->zo, class_type);
1.1       misho     107: 
                    108:        intern->ptr = NULL;
                    109: 
1.1.1.2   misho     110:        retval.handle = zend_objects_store_put(intern, NULL,
                    111:                finfo_objects_free, NULL TSRMLS_CC);
1.1       misho     112:        retval.handlers = (zend_object_handlers *) &finfo_object_handlers;
                    113: 
                    114:        return retval;
                    115: }
                    116: /* }}} */
                    117: 
                    118: /* {{{ arginfo */
                    119: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_open, 0, 0, 0)
                    120:        ZEND_ARG_INFO(0, options)
                    121:        ZEND_ARG_INFO(0, arg)
                    122: ZEND_END_ARG_INFO()
                    123: 
                    124: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_close, 0, 0, 1)
                    125:        ZEND_ARG_INFO(0, finfo)
                    126: ZEND_END_ARG_INFO()
                    127: 
                    128: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_set_flags, 0, 0, 2)
                    129:        ZEND_ARG_INFO(0, finfo)
                    130:        ZEND_ARG_INFO(0, options)
                    131: ZEND_END_ARG_INFO()
                    132: 
                    133: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_set_flags, 0, 0, 1)
                    134:        ZEND_ARG_INFO(0, options)
                    135: ZEND_END_ARG_INFO()
                    136: 
                    137: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_file, 0, 0, 2)
                    138:        ZEND_ARG_INFO(0, finfo)
                    139:        ZEND_ARG_INFO(0, filename)
                    140:        ZEND_ARG_INFO(0, options)
                    141:        ZEND_ARG_INFO(0, context)
                    142: ZEND_END_ARG_INFO()
                    143: 
                    144: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_file, 0, 0, 1)
                    145:        ZEND_ARG_INFO(0, filename)
                    146:        ZEND_ARG_INFO(0, options)
                    147:        ZEND_ARG_INFO(0, context)
                    148: ZEND_END_ARG_INFO()
                    149: 
                    150: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_buffer, 0, 0, 2)
                    151:        ZEND_ARG_INFO(0, finfo)
                    152:        ZEND_ARG_INFO(0, string)
                    153:        ZEND_ARG_INFO(0, options)
                    154:        ZEND_ARG_INFO(0, context)
                    155: ZEND_END_ARG_INFO()
                    156: 
                    157: ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_buffer, 0, 0, 1)
                    158:        ZEND_ARG_INFO(0, string)
                    159:        ZEND_ARG_INFO(0, options)
                    160:        ZEND_ARG_INFO(0, context)
                    161: ZEND_END_ARG_INFO()
                    162: 
                    163: ZEND_BEGIN_ARG_INFO_EX(arginfo_mime_content_type, 0, 0, 1)
                    164:        ZEND_ARG_INFO(0, string)
                    165: ZEND_END_ARG_INFO()
                    166: /* }}} */
                    167: 
                    168: /* {{{ finfo_class_functions
                    169:  */
                    170: zend_function_entry finfo_class_functions[] = {
                    171:        ZEND_ME_MAPPING(finfo,          finfo_open,     arginfo_finfo_open, ZEND_ACC_PUBLIC)
                    172:        ZEND_ME_MAPPING(set_flags,      finfo_set_flags,arginfo_finfo_method_set_flags, ZEND_ACC_PUBLIC)
                    173:        ZEND_ME_MAPPING(file,           finfo_file,     arginfo_finfo_method_file, ZEND_ACC_PUBLIC)
                    174:        ZEND_ME_MAPPING(buffer,         finfo_buffer,   arginfo_finfo_method_buffer, ZEND_ACC_PUBLIC)
                    175:        PHP_FE_END
                    176: };
                    177: /* }}} */
                    178: 
                    179: #define FINFO_SET_OPTION(magic, options) \
                    180:        if (magic_setflags(magic, options) == -1) { \
                    181:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set option '%ld' %d:%s", \
                    182:                                options, magic_errno(magic), magic_error(magic)); \
                    183:                RETURN_FALSE; \
                    184:        }
                    185: 
                    186: /* True global resources - no need for thread safety here */
                    187: static int le_fileinfo;
                    188: /* }}} */
                    189: 
                    190: void finfo_resource_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
                    191: {
                    192:        if (rsrc->ptr) {
                    193:                struct php_fileinfo *finfo = (struct php_fileinfo *) rsrc->ptr;
                    194:                magic_close(finfo->magic);
                    195:                efree(rsrc->ptr);
                    196:                rsrc->ptr = NULL;
                    197:        }
                    198: }
                    199: /* }}} */
                    200: 
                    201: 
                    202: /* {{{ fileinfo_functions[]
                    203:  */
                    204: zend_function_entry fileinfo_functions[] = {
                    205:        PHP_FE(finfo_open,              arginfo_finfo_open)
                    206:        PHP_FE(finfo_close,             arginfo_finfo_close)
                    207:        PHP_FE(finfo_set_flags, arginfo_finfo_set_flags)
                    208:        PHP_FE(finfo_file,              arginfo_finfo_file)
                    209:        PHP_FE(finfo_buffer,    arginfo_finfo_buffer)
                    210:        PHP_FE(mime_content_type, arginfo_mime_content_type)
                    211:        {NULL, NULL, NULL}
                    212: };
                    213: /* }}} */
                    214: 
                    215: /* {{{ PHP_MINIT_FUNCTION
                    216:  */
                    217: PHP_MINIT_FUNCTION(finfo)
                    218: {
                    219:        zend_class_entry _finfo_class_entry;
                    220:        INIT_CLASS_ENTRY(_finfo_class_entry, "finfo", finfo_class_functions);
                    221:        _finfo_class_entry.create_object = finfo_objects_new;
                    222:        finfo_class_entry = zend_register_internal_class(&_finfo_class_entry TSRMLS_CC);
                    223: 
                    224:        /* copy the standard object handlers to you handler table */
                    225:        memcpy(&finfo_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
                    226: 
                    227:        le_fileinfo = zend_register_list_destructors_ex(finfo_resource_destructor, NULL, "file_info", module_number);
                    228: 
                    229:        REGISTER_LONG_CONSTANT("FILEINFO_NONE",                 MAGIC_NONE, CONST_CS|CONST_PERSISTENT);
                    230:        REGISTER_LONG_CONSTANT("FILEINFO_SYMLINK",              MAGIC_SYMLINK, CONST_CS|CONST_PERSISTENT);
                    231:        REGISTER_LONG_CONSTANT("FILEINFO_MIME",                 MAGIC_MIME, CONST_CS|CONST_PERSISTENT);
                    232:        REGISTER_LONG_CONSTANT("FILEINFO_MIME_TYPE",    MAGIC_MIME_TYPE, CONST_CS|CONST_PERSISTENT);
                    233:        REGISTER_LONG_CONSTANT("FILEINFO_MIME_ENCODING",MAGIC_MIME_ENCODING, CONST_CS|CONST_PERSISTENT);
                    234: /*     REGISTER_LONG_CONSTANT("FILEINFO_COMPRESS",             MAGIC_COMPRESS, CONST_CS|CONST_PERSISTENT); disabled, as it does fork now */
                    235:        REGISTER_LONG_CONSTANT("FILEINFO_DEVICES",              MAGIC_DEVICES, CONST_CS|CONST_PERSISTENT);
                    236:        REGISTER_LONG_CONSTANT("FILEINFO_CONTINUE",             MAGIC_CONTINUE, CONST_CS|CONST_PERSISTENT);
                    237: #ifdef MAGIC_PRESERVE_ATIME
                    238:        REGISTER_LONG_CONSTANT("FILEINFO_PRESERVE_ATIME",       MAGIC_PRESERVE_ATIME, CONST_CS|CONST_PERSISTENT);
                    239: #endif
                    240: #ifdef MAGIC_RAW
                    241:        REGISTER_LONG_CONSTANT("FILEINFO_RAW",                  MAGIC_RAW, CONST_CS|CONST_PERSISTENT);
                    242: #endif
                    243: 
                    244:        return SUCCESS;
                    245: }
                    246: /* }}} */
                    247: 
                    248: /* {{{ fileinfo_module_entry
                    249:  */
                    250: zend_module_entry fileinfo_module_entry = {
                    251:        STANDARD_MODULE_HEADER,
                    252:        "fileinfo",
                    253:        fileinfo_functions,
                    254:        PHP_MINIT(finfo),
                    255:        NULL,
                    256:        NULL,   
                    257:        NULL,
                    258:        PHP_MINFO(fileinfo),
                    259:        PHP_FILEINFO_VERSION,
                    260:        STANDARD_MODULE_PROPERTIES
                    261: };
                    262: /* }}} */
                    263: 
                    264: #ifdef COMPILE_DL_FILEINFO
                    265: ZEND_GET_MODULE(fileinfo)
                    266: #endif
                    267: 
                    268: /* {{{ PHP_MINFO_FUNCTION
                    269:  */
                    270: PHP_MINFO_FUNCTION(fileinfo)
                    271: {
                    272:        php_info_print_table_start();
1.1.1.3 ! misho     273:        php_info_print_table_row(2, "fileinfo support", "enabled");
1.1       misho     274:        php_info_print_table_row(2, "version", PHP_FILEINFO_VERSION);
                    275:        php_info_print_table_end();
                    276: }
                    277: /* }}} */
                    278: 
1.1.1.2   misho     279: #define FILEINFO_DESTROY_OBJECT(object)                                                        \
                    280:        do {                                                                                                            \
                    281:                if (object) {                                                                                   \
                    282:                        zend_object_store_ctor_failed(object TSRMLS_CC);        \
                    283:                        zval_dtor(object);                                                                      \
                    284:                        ZVAL_NULL(object);                                                                      \
                    285:                }                                                                                                               \
                    286:        } while (0)
                    287: 
1.1       misho     288: /* {{{ proto resource finfo_open([int options [, string arg]])
                    289:    Create a new fileinfo resource. */
                    290: PHP_FUNCTION(finfo_open)
                    291: {
                    292:        long options = MAGIC_NONE;
                    293:        char *file = NULL;
                    294:        int file_len = 0;
                    295:        struct php_fileinfo *finfo;
                    296:        FILEINFO_DECLARE_INIT_OBJECT(object)
                    297:        char resolved_path[MAXPATHLEN];
                    298: 
1.1.1.2   misho     299:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lp", &options, &file, &file_len) == FAILURE) {
                    300:                FILEINFO_DESTROY_OBJECT(object);
1.1       misho     301:                RETURN_FALSE;
                    302:        }
1.1.1.2   misho     303: 
1.1       misho     304:        if (object) {
                    305:                struct finfo_object *finfo_obj = (struct finfo_object*)zend_object_store_get_object(object TSRMLS_CC);
1.1.1.2   misho     306: 
1.1       misho     307:                if (finfo_obj->ptr) {
                    308:                        magic_close(finfo_obj->ptr->magic);
                    309:                        efree(finfo_obj->ptr);
                    310:                        finfo_obj->ptr = NULL;
                    311:                }
                    312:        }
                    313: 
                    314:        if (file_len == 0) {
                    315:                file = NULL;
                    316:        } else if (file && *file) { /* user specified file, perform open_basedir checks */
                    317: 
                    318: #if PHP_API_VERSION < 20100412
                    319:                if ((PG(safe_mode) && (!php_checkuid(file, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(file TSRMLS_CC)) {
                    320: #else
                    321:                if (php_check_open_basedir(file TSRMLS_CC)) {
                    322: #endif
1.1.1.2   misho     323:                        FILEINFO_DESTROY_OBJECT(object);
                    324:                        RETURN_FALSE;
                    325:                }
                    326:                if (!expand_filepath_with_mode(file, resolved_path, NULL, 0, CWD_EXPAND TSRMLS_CC)) {
                    327:                        FILEINFO_DESTROY_OBJECT(object);
1.1       misho     328:                        RETURN_FALSE;
                    329:                }
1.1.1.2   misho     330:                file = resolved_path;
1.1       misho     331:        }
                    332: 
                    333:        finfo = emalloc(sizeof(struct php_fileinfo));
                    334: 
                    335:        finfo->options = options;
                    336:        finfo->magic = magic_open(options);
                    337: 
                    338:        if (finfo->magic == NULL) {
                    339:                efree(finfo);
                    340:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid mode '%ld'.", options);
1.1.1.2   misho     341:                FILEINFO_DESTROY_OBJECT(object);
                    342:                RETURN_FALSE;
1.1       misho     343:        }
                    344: 
                    345:        if (magic_load(finfo->magic, file) == -1) {
                    346:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database at '%s'.", file);
                    347:                magic_close(finfo->magic);
                    348:                efree(finfo);
1.1.1.2   misho     349:                FILEINFO_DESTROY_OBJECT(object);
1.1       misho     350:                RETURN_FALSE;
1.1.1.2   misho     351:        }
1.1       misho     352: 
                    353:        if (object) {
                    354:                FILEINFO_REGISTER_OBJECT(object, finfo);
                    355:        } else {
                    356:                ZEND_REGISTER_RESOURCE(return_value, finfo, le_fileinfo);
1.1.1.2   misho     357:        }
1.1       misho     358: }
                    359: /* }}} */
                    360: 
                    361: /* {{{ proto resource finfo_close(resource finfo)
                    362:    Close fileinfo resource. */
                    363: PHP_FUNCTION(finfo_close)
                    364: {
                    365:        struct php_fileinfo *finfo;
                    366:        zval *zfinfo;
                    367: 
                    368:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zfinfo) == FAILURE) {
                    369:                RETURN_FALSE;
                    370:        }
                    371:        ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
                    372: 
                    373:        zend_list_delete(Z_RESVAL_P(zfinfo));
                    374: 
                    375:        RETURN_TRUE;
                    376: }
                    377: /* }}} */
                    378: 
                    379: /* {{{ proto bool finfo_set_flags(resource finfo, int options)
                    380:    Set libmagic configuration options. */
                    381: PHP_FUNCTION(finfo_set_flags)
                    382: {
                    383:        long options;
                    384:        struct php_fileinfo *finfo;
                    385:        zval *zfinfo;
                    386:        FILEINFO_DECLARE_INIT_OBJECT(object)
                    387: 
                    388:        if (object) {
                    389:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &options) == FAILURE) {
                    390:                        RETURN_FALSE;
                    391:                }
                    392:                FILEINFO_FROM_OBJECT(finfo, object);
                    393:        } else {
                    394:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zfinfo, &options) == FAILURE) {
                    395:                        RETURN_FALSE;
                    396:                }
                    397:                ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
                    398:        }
                    399: 
                    400:        FINFO_SET_OPTION(finfo->magic, options)
                    401:        finfo->options = options;
                    402: 
                    403:        RETURN_TRUE;
                    404: }
                    405: /* }}} */
                    406: 
                    407: #define FILEINFO_MODE_BUFFER 0
                    408: #define FILEINFO_MODE_STREAM 1
                    409: #define FILEINFO_MODE_FILE 2
                    410: 
                    411: static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu) /* {{{ */
                    412: {
                    413:        long options = 0;
                    414:        char *ret_val = NULL, *buffer = NULL;
                    415:        int buffer_len;
                    416:        struct php_fileinfo *finfo = NULL;
                    417:        zval *zfinfo, *zcontext = NULL;
                    418:        zval *what;
                    419:        char mime_directory[] = "directory";
                    420: 
                    421:        struct magic_set *magic = NULL;
                    422:        FILEINFO_DECLARE_INIT_OBJECT(object)
                    423: 
                    424:        if (mimetype_emu) {
                    425: 
                    426:                /* mime_content_type(..) emulation */
                    427:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &what) == FAILURE) {
                    428:                        return;
                    429:                }
                    430: 
                    431:                switch (Z_TYPE_P(what)) {
                    432:                        case IS_STRING:
                    433:                                buffer = Z_STRVAL_P(what);
                    434:                                buffer_len = Z_STRLEN_P(what);
                    435:                                mode = FILEINFO_MODE_FILE;
                    436:                                break;
                    437: 
                    438:                        case IS_RESOURCE:
                    439:                                mode = FILEINFO_MODE_STREAM;
                    440:                                break;
                    441: 
                    442:                        default:
                    443:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only process string or stream arguments");
                    444:                                RETURN_FALSE;
                    445:                }
                    446: 
                    447:                magic = magic_open(MAGIC_MIME_TYPE);
                    448:                if (magic_load(magic, NULL) == -1) {
                    449:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database.");
                    450:                        goto common;
                    451:                }
                    452:        } else if (object) {
                    453:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
                    454:                        RETURN_FALSE;
                    455:                }
                    456:                FILEINFO_FROM_OBJECT(finfo, object);
                    457:                magic = finfo->magic;
                    458:        } else {
                    459:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
                    460:                        RETURN_FALSE;
                    461:                }
                    462:                ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
                    463:                magic = finfo->magic;
                    464:        }       
                    465: 
                    466:        /* Set options for the current file/buffer. */
                    467:        if (options) {
                    468:                FINFO_SET_OPTION(magic, options)
                    469:        }
                    470: 
                    471:        switch (mode) {
                    472:                case FILEINFO_MODE_BUFFER:
                    473:                {
                    474:                        ret_val = (char *) magic_buffer(magic, buffer, buffer_len);
                    475:                        break;
                    476:                }
                    477: 
                    478:                case FILEINFO_MODE_STREAM:
                    479:                {
                    480:                                php_stream *stream;
                    481:                                off_t streampos;
                    482: 
                    483:                                php_stream_from_zval_no_verify(stream, &what);
                    484:                                if (!stream) {
                    485:                                        goto common;
                    486:                                }
                    487: 
                    488:                                streampos = php_stream_tell(stream); /* remember stream position for restoration */
                    489:                                php_stream_seek(stream, 0, SEEK_SET);
                    490: 
                    491:                                ret_val = (char *) magic_stream(magic, stream);
                    492: 
                    493:                                php_stream_seek(stream, streampos, SEEK_SET);
                    494:                                break;
                    495:                }
                    496: 
                    497:                case FILEINFO_MODE_FILE:
                    498:                {
                    499:                        /* determine if the file is a local file or remote URL */
                    500:                        char *tmp2;
                    501:                        php_stream_wrapper *wrap;
                    502:                        php_stream_statbuf ssb;
                    503: 
                    504:                        if (buffer == NULL || !*buffer) {
                    505:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty filename or path");
                    506:                                RETVAL_FALSE;
                    507:                                goto clean;
                    508:                        }
                    509: 
                    510:                        wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC);
                    511: 
                    512:                        if (wrap) {
1.1.1.2   misho     513:                                php_stream *stream;
1.1       misho     514:                                php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
1.1.1.2   misho     515: 
                    516: #ifdef PHP_WIN32
                    517:                                if (php_stream_stat_path_ex(buffer, 0, &ssb, context) == SUCCESS) {
                    518:                                        if (ssb.sb.st_mode & S_IFDIR) {
                    519:                                                ret_val = mime_directory;
                    520:                                                goto common;
                    521:                                        }
                    522:                                }
                    523: #endif
                    524: 
1.1       misho     525: #if PHP_API_VERSION < 20100412
1.1.1.2   misho     526:                                stream = php_stream_open_wrapper_ex(buffer, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
1.1       misho     527: #else
1.1.1.2   misho     528:                                stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
1.1       misho     529: #endif
                    530: 
                    531:                                if (!stream) {
                    532:                                        RETVAL_FALSE;
                    533:                                        goto clean;
                    534:                                }
                    535: 
                    536:                                if (php_stream_stat(stream, &ssb) == SUCCESS) {
                    537:                                        if (ssb.sb.st_mode & S_IFDIR) {
                    538:                                                ret_val = mime_directory;
                    539:                                        } else {
                    540:                                                ret_val = (char *)magic_stream(magic, stream);
                    541:                                        }
                    542:                                }
                    543: 
                    544:                                php_stream_close(stream);
                    545:                        }
                    546:                        break;
                    547:                }
                    548: 
                    549:                default:
                    550:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only process string or stream arguments");
                    551:        }
                    552: 
                    553: common:
                    554:        if (ret_val) {
                    555:                RETVAL_STRING(ret_val, 1);
                    556:        } else {
                    557:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
                    558:                RETVAL_FALSE;
                    559:        }
                    560: 
                    561: clean:
                    562:        if (mimetype_emu) {
                    563:                magic_close(magic);
                    564:        }
                    565: 
                    566:        /* Restore options */
                    567:        if (options) {
                    568:                FINFO_SET_OPTION(magic, finfo->options)
                    569:        }
                    570:        return;
                    571: }
                    572: /* }}} */
                    573: 
                    574: /* {{{ proto string finfo_file(resource finfo, char *file_name [, int options [, resource context]])
                    575:    Return information about a file. */
                    576: PHP_FUNCTION(finfo_file)
                    577: {
                    578:        _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_FILE, 0);
                    579: }
                    580: /* }}} */
                    581: 
                    582: /* {{{ proto string finfo_buffer(resource finfo, char *string [, int options [, resource context]])
                    583:    Return infromation about a string buffer. */
                    584: PHP_FUNCTION(finfo_buffer)
                    585: {
                    586:        _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_BUFFER, 0);
                    587: }
                    588: /* }}} */
                    589: 
                    590: /* {{{ proto string mime_content_type(string filename|resource stream)
                    591:    Return content-type for file */
                    592: PHP_FUNCTION(mime_content_type)
                    593: {
                    594:        _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1, 1);
                    595: }
                    596: /* }}} */
                    597: 
                    598: 
                    599: /*
                    600:  * Local variables:
                    601:  * tab-width: 4
                    602:  * c-basic-offset: 4
                    603:  * End:
                    604:  * vim600: noet sw=4 ts=4 fdm=marker
                    605:  * vim<600: noet sw=4 ts=4
                    606:  */

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