root/ext/fileinfo/fileinfo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_finfo_fetch_object
  2. finfo_objects_free
  3. finfo_objects_new
  4. finfo_resource_destructor
  5. PHP_MINIT_FUNCTION
  6. ZEND_GET_MODULE
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. PHP_FUNCTION
  10. _php_finfo_get_type
  11. PHP_FUNCTION
  12. PHP_FUNCTION
  13. PHP_FUNCTION

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

/* [<][>][^][v][top][bottom][index][help] */