root/ext/fileinfo/fileinfo.c

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

DEFINITIONS

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

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 5                                                        |
   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 
  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         char magic_ver[5];
 273 
 274         (void)snprintf(magic_ver, 4, "%d", magic_version());
 275         magic_ver[4] = '\0';
 276 
 277         php_info_print_table_start();
 278         php_info_print_table_row(2, "fileinfo support", "enabled");
 279         php_info_print_table_row(2, "version", PHP_FILEINFO_VERSION);
 280         php_info_print_table_row(2, "libmagic", magic_ver);
 281         php_info_print_table_end();
 282 }
 283 /* }}} */
 284 
 285 #define FILEINFO_DESTROY_OBJECT(object)                                                 \
 286         do {                                                                                                            \
 287                 if (object) {                                                                                   \
 288                         zend_object_store_ctor_failed(object TSRMLS_CC);        \
 289                         zval_dtor(object);                                                                      \
 290                         ZVAL_NULL(object);                                                                      \
 291                 }                                                                                                               \
 292         } while (0)
 293 
 294 /* {{{ proto resource finfo_open([int options [, string arg]])
 295    Create a new fileinfo resource. */
 296 PHP_FUNCTION(finfo_open)
 297 {
 298         long options = MAGIC_NONE;
 299         char *file = NULL;
 300         int file_len = 0;
 301         struct php_fileinfo *finfo;
 302         FILEINFO_DECLARE_INIT_OBJECT(object)
 303         char resolved_path[MAXPATHLEN];
 304 
 305         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lp", &options, &file, &file_len) == FAILURE) {
 306                 FILEINFO_DESTROY_OBJECT(object);
 307                 RETURN_FALSE;
 308         }
 309 
 310         if (object) {
 311                 struct finfo_object *finfo_obj = (struct finfo_object*)zend_object_store_get_object(object TSRMLS_CC);
 312 
 313                 if (finfo_obj->ptr) {
 314                         magic_close(finfo_obj->ptr->magic);
 315                         efree(finfo_obj->ptr);
 316                         finfo_obj->ptr = NULL;
 317                 }
 318         }
 319 
 320         if (file_len == 0) {
 321                 file = NULL;
 322         } else if (file && *file) { /* user specified file, perform open_basedir checks */
 323 
 324                 if (php_check_open_basedir(file TSRMLS_CC)) {
 325                         FILEINFO_DESTROY_OBJECT(object);
 326                         RETURN_FALSE;
 327                 }
 328                 if (!expand_filepath_with_mode(file, resolved_path, NULL, 0, CWD_EXPAND TSRMLS_CC)) {
 329                         FILEINFO_DESTROY_OBJECT(object);
 330                         RETURN_FALSE;
 331                 }
 332                 file = resolved_path;
 333         }
 334 
 335         finfo = emalloc(sizeof(struct php_fileinfo));
 336 
 337         finfo->options = options;
 338         finfo->magic = magic_open(options);
 339 
 340         if (finfo->magic == NULL) {
 341                 efree(finfo);
 342                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid mode '%ld'.", options);
 343                 FILEINFO_DESTROY_OBJECT(object);
 344                 RETURN_FALSE;
 345         }
 346 
 347         if (magic_load(finfo->magic, file) == -1) {
 348                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database at '%s'.", file);
 349                 magic_close(finfo->magic);
 350                 efree(finfo);
 351                 FILEINFO_DESTROY_OBJECT(object);
 352                 RETURN_FALSE;
 353         }
 354 
 355         if (object) {
 356                 FILEINFO_REGISTER_OBJECT(object, finfo);
 357         } else {
 358                 ZEND_REGISTER_RESOURCE(return_value, finfo, le_fileinfo);
 359         }
 360 }
 361 /* }}} */
 362 
 363 /* {{{ proto resource finfo_close(resource finfo)
 364    Close fileinfo resource. */
 365 PHP_FUNCTION(finfo_close)
 366 {
 367         struct php_fileinfo *finfo;
 368         zval *zfinfo;
 369 
 370         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zfinfo) == FAILURE) {
 371                 RETURN_FALSE;
 372         }
 373         ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
 374 
 375         zend_list_delete(Z_RESVAL_P(zfinfo));
 376 
 377         RETURN_TRUE;
 378 }
 379 /* }}} */
 380 
 381 /* {{{ proto bool finfo_set_flags(resource finfo, int options)
 382    Set libmagic configuration options. */
 383 PHP_FUNCTION(finfo_set_flags)
 384 {
 385         long options;
 386         struct php_fileinfo *finfo;
 387         zval *zfinfo;
 388         FILEINFO_DECLARE_INIT_OBJECT(object)
 389 
 390         if (object) {
 391                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &options) == FAILURE) {
 392                         RETURN_FALSE;
 393                 }
 394                 FILEINFO_FROM_OBJECT(finfo, object);
 395         } else {
 396                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zfinfo, &options) == FAILURE) {
 397                         RETURN_FALSE;
 398                 }
 399                 ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
 400         }
 401 
 402         FINFO_SET_OPTION(finfo->magic, options)
 403         finfo->options = options;
 404 
 405         RETURN_TRUE;
 406 }
 407 /* }}} */
 408 
 409 #define FILEINFO_MODE_BUFFER 0
 410 #define FILEINFO_MODE_STREAM 1
 411 #define FILEINFO_MODE_FILE 2
 412 
 413 static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu) /* {{{ */
 414 {
 415         long options = 0;
 416         char *ret_val = NULL, *buffer = NULL;
 417         int buffer_len;
 418         struct php_fileinfo *finfo = NULL;
 419         zval *zfinfo, *zcontext = NULL;
 420         zval *what;
 421         char mime_directory[] = "directory";
 422 
 423         struct magic_set *magic = NULL;
 424         FILEINFO_DECLARE_INIT_OBJECT(object)
 425 
 426         if (mimetype_emu) {
 427 
 428                 /* mime_content_type(..) emulation */
 429                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &what) == FAILURE) {
 430                         return;
 431                 }
 432 
 433                 switch (Z_TYPE_P(what)) {
 434                         case IS_STRING:
 435                                 buffer = Z_STRVAL_P(what);
 436                                 buffer_len = Z_STRLEN_P(what);
 437                                 mode = FILEINFO_MODE_FILE;
 438                                 break;
 439 
 440                         case IS_RESOURCE:
 441                                 mode = FILEINFO_MODE_STREAM;
 442                                 break;
 443 
 444                         default:
 445                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only process string or stream arguments");
 446                                 RETURN_FALSE;
 447                 }
 448 
 449                 magic = magic_open(MAGIC_MIME_TYPE);
 450                 if (magic_load(magic, NULL) == -1) {
 451                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database.");
 452                         goto common;
 453                 }
 454         } else if (object) {
 455                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
 456                         RETURN_FALSE;
 457                 }
 458                 FILEINFO_FROM_OBJECT(finfo, object);
 459                 magic = finfo->magic;
 460         } else {
 461                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
 462                         RETURN_FALSE;
 463                 }
 464                 ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
 465                 magic = finfo->magic;
 466         }       
 467 
 468         /* Set options for the current file/buffer. */
 469         if (options) {
 470                 FINFO_SET_OPTION(magic, options)
 471         }
 472 
 473         switch (mode) {
 474                 case FILEINFO_MODE_BUFFER:
 475                 {
 476                         ret_val = (char *) magic_buffer(magic, buffer, buffer_len);
 477                         break;
 478                 }
 479 
 480                 case FILEINFO_MODE_STREAM:
 481                 {
 482                                 php_stream *stream;
 483                                 off_t streampos;
 484 
 485                                 php_stream_from_zval_no_verify(stream, &what);
 486                                 if (!stream) {
 487                                         goto common;
 488                                 }
 489 
 490                                 streampos = php_stream_tell(stream); /* remember stream position for restoration */
 491                                 php_stream_seek(stream, 0, SEEK_SET);
 492 
 493                                 ret_val = (char *) magic_stream(magic, stream);
 494 
 495                                 php_stream_seek(stream, streampos, SEEK_SET);
 496                                 break;
 497                 }
 498 
 499                 case FILEINFO_MODE_FILE:
 500                 {
 501                         /* determine if the file is a local file or remote URL */
 502                         const char *tmp2;
 503                         php_stream_wrapper *wrap;
 504                         php_stream_statbuf ssb;
 505 
 506                         if (buffer == NULL || !*buffer) {
 507                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty filename or path");
 508                                 RETVAL_FALSE;
 509                                 goto clean;
 510                         }
 511                         if (CHECK_NULL_PATH(buffer, buffer_len)) {
 512                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path");
 513                                 RETVAL_FALSE;
 514                                 goto clean;
 515                         }
 516 
 517                         wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC);
 518 
 519                         if (wrap) {
 520                                 php_stream *stream;
 521                                 php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
 522 
 523 #ifdef PHP_WIN32
 524                                 if (php_stream_stat_path_ex(buffer, 0, &ssb, context) == SUCCESS) {
 525                                         if (ssb.sb.st_mode & S_IFDIR) {
 526                                                 ret_val = mime_directory;
 527                                                 goto common;
 528                                         }
 529                                 }
 530 #endif
 531 
 532 #if PHP_API_VERSION < 20100412
 533                                 stream = php_stream_open_wrapper_ex(buffer, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
 534 #else
 535                                 stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
 536 #endif
 537 
 538                                 if (!stream) {
 539                                         RETVAL_FALSE;
 540                                         goto clean;
 541                                 }
 542 
 543                                 if (php_stream_stat(stream, &ssb) == SUCCESS) {
 544                                         if (ssb.sb.st_mode & S_IFDIR) {
 545                                                 ret_val = mime_directory;
 546                                         } else {
 547                                                 ret_val = (char *)magic_stream(magic, stream);
 548                                         }
 549                                 }
 550 
 551                                 php_stream_close(stream);
 552                         }
 553                         break;
 554                 }
 555 
 556                 default:
 557                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only process string or stream arguments");
 558         }
 559 
 560 common:
 561         if (ret_val) {
 562                 RETVAL_STRING(ret_val, 1);
 563         } else {
 564                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
 565                 RETVAL_FALSE;
 566         }
 567 
 568 clean:
 569         if (mimetype_emu) {
 570                 magic_close(magic);
 571         }
 572 
 573         /* Restore options */
 574         if (options) {
 575                 FINFO_SET_OPTION(magic, finfo->options)
 576         }
 577         return;
 578 }
 579 /* }}} */
 580 
 581 /* {{{ proto string finfo_file(resource finfo, char *file_name [, int options [, resource context]])
 582    Return information about a file. */
 583 PHP_FUNCTION(finfo_file)
 584 {
 585         _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_FILE, 0);
 586 }
 587 /* }}} */
 588 
 589 /* {{{ proto string finfo_buffer(resource finfo, char *string [, int options [, resource context]])
 590    Return infromation about a string buffer. */
 591 PHP_FUNCTION(finfo_buffer)
 592 {
 593         _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_BUFFER, 0);
 594 }
 595 /* }}} */
 596 
 597 /* {{{ proto string mime_content_type(string filename|resource stream)
 598    Return content-type for file */
 599 PHP_FUNCTION(mime_content_type)
 600 {
 601         _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1, 1);
 602 }
 603 /* }}} */
 604 
 605 
 606 /*
 607  * Local variables:
 608  * tab-width: 4
 609  * c-basic-offset: 4
 610  * End:
 611  * vim600: noet sw=4 ts=4 fdm=marker
 612  * vim<600: noet sw=4 ts=4
 613  */

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