File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / fileinfo / fileinfo.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:48 2014 UTC (10 years, 6 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:   +----------------------------------------------------------------------+
    3:   | PHP Version 5                                                        |
    4:   +----------------------------------------------------------------------+
    5:   | Copyright (c) 1997-2014 The PHP Group                                |
    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: 
   19: /* $Id: fileinfo.c,v 1.1.1.4 2014/06/15 20:03:48 misho Exp $ */
   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: 
   79: /* {{{ finfo_objects_free
   80:  */
   81: static void finfo_objects_free(void *object TSRMLS_DC)
   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);
  106: 	object_properties_init(&intern->zo, class_type);
  107: 
  108: 	intern->ptr = NULL;
  109: 
  110: 	retval.handle = zend_objects_store_put(intern, NULL,
  111: 		finfo_objects_free, NULL TSRMLS_CC);
  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();
  273: 	php_info_print_table_row(2, "fileinfo support", "enabled");
  274: 	php_info_print_table_row(2, "version", PHP_FILEINFO_VERSION);
  275: 	php_info_print_table_end();
  276: }
  277: /* }}} */
  278: 
  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: 
  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: 
  299: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lp", &options, &file, &file_len) == FAILURE) {
  300: 		FILEINFO_DESTROY_OBJECT(object);
  301: 		RETURN_FALSE;
  302: 	}
  303: 
  304: 	if (object) {
  305: 		struct finfo_object *finfo_obj = (struct finfo_object*)zend_object_store_get_object(object TSRMLS_CC);
  306: 
  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
  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);
  328: 			RETURN_FALSE;
  329: 		}
  330: 		file = resolved_path;
  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);
  341: 		FILEINFO_DESTROY_OBJECT(object);
  342: 		RETURN_FALSE;
  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);
  349: 		FILEINFO_DESTROY_OBJECT(object);
  350: 		RETURN_FALSE;
  351: 	}
  352: 
  353: 	if (object) {
  354: 		FILEINFO_REGISTER_OBJECT(object, finfo);
  355: 	} else {
  356: 		ZEND_REGISTER_RESOURCE(return_value, finfo, le_fileinfo);
  357: 	}
  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) {
  513: 				php_stream *stream;
  514: 				php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
  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: 
  525: #if PHP_API_VERSION < 20100412
  526: 				stream = php_stream_open_wrapper_ex(buffer, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
  527: #else
  528: 				stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
  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>