fileinfo.c 16 KB

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