PageRenderTime 43ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/standard/file.c

http://github.com/infusion/PHP
C | 2575 lines | 1983 code | 375 blank | 217 comment | 453 complexity | 0fbb3ae579bdd1a7fee34d44c4bcb648 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2011 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 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_01.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. | Authors: Rasmus Lerdorf <rasmus@php.net> |
  16. | Stig Bakken <ssb@php.net> |
  17. | Andi Gutmans <andi@zend.com> |
  18. | Zeev Suraski <zeev@zend.com> |
  19. | PHP 4.0 patches by Thies C. Arntzen (thies@thieso.net) |
  20. | PHP streams by Wez Furlong (wez@thebrainroom.com) |
  21. +----------------------------------------------------------------------+
  22. */
  23. /* $Id: file.c 306939 2011-01-01 02:19:59Z felipe $ */
  24. /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
  25. /* {{{ includes */
  26. #include "php.h"
  27. #include "php_globals.h"
  28. #include "ext/standard/flock_compat.h"
  29. #include "ext/standard/exec.h"
  30. #include "ext/standard/php_filestat.h"
  31. #include "php_open_temporary_file.h"
  32. #include "ext/standard/basic_functions.h"
  33. #include "php_ini.h"
  34. #include "php_smart_str.h"
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <errno.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40. #include <fcntl.h>
  41. #ifdef PHP_WIN32
  42. # include <io.h>
  43. # define O_RDONLY _O_RDONLY
  44. # include "win32/param.h"
  45. # include "win32/winutil.h"
  46. # include "win32/fnmatch.h"
  47. #else
  48. # if HAVE_SYS_PARAM_H
  49. # include <sys/param.h>
  50. # endif
  51. # if HAVE_SYS_SELECT_H
  52. # include <sys/select.h>
  53. # endif
  54. # if defined(NETWARE) && defined(USE_WINSOCK)
  55. # include <novsock2.h>
  56. # else
  57. # include <sys/socket.h>
  58. # include <netinet/in.h>
  59. # include <netdb.h>
  60. # endif
  61. # if HAVE_ARPA_INET_H
  62. # include <arpa/inet.h>
  63. # endif
  64. #endif
  65. #include "ext/standard/head.h"
  66. #include "php_string.h"
  67. #include "file.h"
  68. #if HAVE_PWD_H
  69. # ifdef PHP_WIN32
  70. # include "win32/pwd.h"
  71. # else
  72. # include <pwd.h>
  73. # endif
  74. #endif
  75. #ifdef HAVE_SYS_TIME_H
  76. # include <sys/time.h>
  77. #endif
  78. #include "fsock.h"
  79. #include "fopen_wrappers.h"
  80. #include "streamsfuncs.h"
  81. #include "php_globals.h"
  82. #ifdef HAVE_SYS_FILE_H
  83. # include <sys/file.h>
  84. #endif
  85. #if MISSING_FCLOSE_DECL
  86. extern int fclose(FILE *);
  87. #endif
  88. #ifdef HAVE_SYS_MMAN_H
  89. # include <sys/mman.h>
  90. #endif
  91. #include "scanf.h"
  92. #include "zend_API.h"
  93. #ifdef ZTS
  94. int file_globals_id;
  95. #else
  96. php_file_globals file_globals;
  97. #endif
  98. #if defined(HAVE_FNMATCH) && !defined(PHP_WIN32)
  99. # ifndef _GNU_SOURCE
  100. # define _GNU_SOURCE
  101. # endif
  102. # include <fnmatch.h>
  103. #endif
  104. #ifdef HAVE_WCHAR_H
  105. # include <wchar.h>
  106. #endif
  107. #ifndef S_ISDIR
  108. # define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
  109. #endif
  110. /* }}} */
  111. #define PHP_STREAM_TO_ZVAL(stream, arg) \
  112. php_stream_from_zval_no_verify(stream, arg); \
  113. if (stream == NULL) { \
  114. RETURN_FALSE; \
  115. }
  116. /* {{{ ZTS-stuff / Globals / Prototypes */
  117. /* sharing globals is *evil* */
  118. static int le_stream_context = FAILURE;
  119. PHPAPI int php_le_stream_context(void)
  120. {
  121. return le_stream_context;
  122. }
  123. /* }}} */
  124. /* {{{ Module-Stuff
  125. */
  126. static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
  127. {
  128. php_stream_context *context = (php_stream_context*)rsrc->ptr;
  129. if (context->options) {
  130. zval_ptr_dtor(&context->options);
  131. context->options = NULL;
  132. }
  133. php_stream_context_free(context);
  134. }
  135. static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
  136. {
  137. FG(pclose_ret) = 0;
  138. FG(user_stream_current_filename) = NULL;
  139. FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
  140. }
  141. static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
  142. {
  143. }
  144. PHP_INI_BEGIN()
  145. STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals)
  146. PHP_INI_ENTRY("from", NULL, PHP_INI_ALL, NULL)
  147. STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateLong, default_socket_timeout, php_file_globals, file_globals)
  148. STD_PHP_INI_ENTRY("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateLong, auto_detect_line_endings, php_file_globals, file_globals)
  149. PHP_INI_END()
  150. PHP_MINIT_FUNCTION(file)
  151. {
  152. le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
  153. #ifdef ZTS
  154. ts_allocate_id(&file_globals_id, sizeof(php_file_globals), (ts_allocate_ctor) file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
  155. #else
  156. file_globals_ctor(&file_globals TSRMLS_CC);
  157. #endif
  158. REGISTER_INI_ENTRIES();
  159. REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
  160. REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
  161. REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
  162. REGISTER_LONG_CONSTANT("LOCK_SH", PHP_LOCK_SH, CONST_CS | CONST_PERSISTENT);
  163. REGISTER_LONG_CONSTANT("LOCK_EX", PHP_LOCK_EX, CONST_CS | CONST_PERSISTENT);
  164. REGISTER_LONG_CONSTANT("LOCK_UN", PHP_LOCK_UN, CONST_CS | CONST_PERSISTENT);
  165. REGISTER_LONG_CONSTANT("LOCK_NB", PHP_LOCK_NB, CONST_CS | CONST_PERSISTENT);
  166. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT", PHP_STREAM_NOTIFY_CONNECT, CONST_CS | CONST_PERSISTENT);
  167. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED", PHP_STREAM_NOTIFY_AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT);
  168. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_RESULT", PHP_STREAM_NOTIFY_AUTH_RESULT, CONST_CS | CONST_PERSISTENT);
  169. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_MIME_TYPE_IS", PHP_STREAM_NOTIFY_MIME_TYPE_IS, CONST_CS | CONST_PERSISTENT);
  170. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FILE_SIZE_IS", PHP_STREAM_NOTIFY_FILE_SIZE_IS, CONST_CS | CONST_PERSISTENT);
  171. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_REDIRECTED", PHP_STREAM_NOTIFY_REDIRECTED, CONST_CS | CONST_PERSISTENT);
  172. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_PROGRESS", PHP_STREAM_NOTIFY_PROGRESS, CONST_CS | CONST_PERSISTENT);
  173. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FAILURE", PHP_STREAM_NOTIFY_FAILURE, CONST_CS | CONST_PERSISTENT);
  174. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_COMPLETED", PHP_STREAM_NOTIFY_COMPLETED, CONST_CS | CONST_PERSISTENT);
  175. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_RESOLVE", PHP_STREAM_NOTIFY_RESOLVE, CONST_CS | CONST_PERSISTENT);
  176. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_INFO", PHP_STREAM_NOTIFY_SEVERITY_INFO, CONST_CS | CONST_PERSISTENT);
  177. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_WARN", PHP_STREAM_NOTIFY_SEVERITY_WARN, CONST_CS | CONST_PERSISTENT);
  178. REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_ERR", PHP_STREAM_NOTIFY_SEVERITY_ERR, CONST_CS | CONST_PERSISTENT);
  179. REGISTER_LONG_CONSTANT("STREAM_FILTER_READ", PHP_STREAM_FILTER_READ, CONST_CS | CONST_PERSISTENT);
  180. REGISTER_LONG_CONSTANT("STREAM_FILTER_WRITE", PHP_STREAM_FILTER_WRITE, CONST_CS | CONST_PERSISTENT);
  181. REGISTER_LONG_CONSTANT("STREAM_FILTER_ALL", PHP_STREAM_FILTER_ALL, CONST_CS | CONST_PERSISTENT);
  182. REGISTER_LONG_CONSTANT("STREAM_CLIENT_PERSISTENT", PHP_STREAM_CLIENT_PERSISTENT, CONST_CS | CONST_PERSISTENT);
  183. REGISTER_LONG_CONSTANT("STREAM_CLIENT_ASYNC_CONNECT", PHP_STREAM_CLIENT_ASYNC_CONNECT, CONST_CS | CONST_PERSISTENT);
  184. REGISTER_LONG_CONSTANT("STREAM_CLIENT_CONNECT", PHP_STREAM_CLIENT_CONNECT, CONST_CS | CONST_PERSISTENT);
  185. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_CLIENT", STREAM_CRYPTO_METHOD_SSLv2_CLIENT, CONST_CS|CONST_PERSISTENT);
  186. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT);
  187. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT);
  188. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT);
  189. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT);
  190. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT);
  191. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT);
  192. REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT);
  193. REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT);
  194. REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT);
  195. REGISTER_LONG_CONSTANT("STREAM_SHUT_RDWR", STREAM_SHUT_RDWR, CONST_CS|CONST_PERSISTENT);
  196. #ifdef PF_INET
  197. REGISTER_LONG_CONSTANT("STREAM_PF_INET", PF_INET, CONST_CS|CONST_PERSISTENT);
  198. #elif defined(AF_INET)
  199. REGISTER_LONG_CONSTANT("STREAM_PF_INET", AF_INET, CONST_CS|CONST_PERSISTENT);
  200. #endif
  201. #ifdef PF_INET6
  202. REGISTER_LONG_CONSTANT("STREAM_PF_INET6", PF_INET6, CONST_CS|CONST_PERSISTENT);
  203. #elif defined(AF_INET6)
  204. REGISTER_LONG_CONSTANT("STREAM_PF_INET6", AF_INET6, CONST_CS|CONST_PERSISTENT);
  205. #endif
  206. #ifdef PF_UNIX
  207. REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", PF_UNIX, CONST_CS|CONST_PERSISTENT);
  208. #elif defined(AF_UNIX)
  209. REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", AF_UNIX, CONST_CS|CONST_PERSISTENT);
  210. #endif
  211. #ifdef IPPROTO_IP
  212. /* most people will use this one when calling socket() or socketpair() */
  213. REGISTER_LONG_CONSTANT("STREAM_IPPROTO_IP", IPPROTO_IP, CONST_CS|CONST_PERSISTENT);
  214. #endif
  215. #ifdef IPPROTO_TCP
  216. REGISTER_LONG_CONSTANT("STREAM_IPPROTO_TCP", IPPROTO_TCP, CONST_CS|CONST_PERSISTENT);
  217. #endif
  218. #ifdef IPPROTO_UDP
  219. REGISTER_LONG_CONSTANT("STREAM_IPPROTO_UDP", IPPROTO_UDP, CONST_CS|CONST_PERSISTENT);
  220. #endif
  221. #ifdef IPPROTO_ICMP
  222. REGISTER_LONG_CONSTANT("STREAM_IPPROTO_ICMP", IPPROTO_ICMP, CONST_CS|CONST_PERSISTENT);
  223. #endif
  224. #ifdef IPPROTO_RAW
  225. REGISTER_LONG_CONSTANT("STREAM_IPPROTO_RAW", IPPROTO_RAW, CONST_CS|CONST_PERSISTENT);
  226. #endif
  227. REGISTER_LONG_CONSTANT("STREAM_SOCK_STREAM", SOCK_STREAM, CONST_CS|CONST_PERSISTENT);
  228. REGISTER_LONG_CONSTANT("STREAM_SOCK_DGRAM", SOCK_DGRAM, CONST_CS|CONST_PERSISTENT);
  229. #ifdef SOCK_RAW
  230. REGISTER_LONG_CONSTANT("STREAM_SOCK_RAW", SOCK_RAW, CONST_CS|CONST_PERSISTENT);
  231. #endif
  232. #ifdef SOCK_SEQPACKET
  233. REGISTER_LONG_CONSTANT("STREAM_SOCK_SEQPACKET", SOCK_SEQPACKET, CONST_CS|CONST_PERSISTENT);
  234. #endif
  235. #ifdef SOCK_RDM
  236. REGISTER_LONG_CONSTANT("STREAM_SOCK_RDM", SOCK_RDM, CONST_CS|CONST_PERSISTENT);
  237. #endif
  238. REGISTER_LONG_CONSTANT("STREAM_PEEK", STREAM_PEEK, CONST_CS | CONST_PERSISTENT);
  239. REGISTER_LONG_CONSTANT("STREAM_OOB", STREAM_OOB, CONST_CS | CONST_PERSISTENT);
  240. REGISTER_LONG_CONSTANT("STREAM_SERVER_BIND", STREAM_XPORT_BIND, CONST_CS | CONST_PERSISTENT);
  241. REGISTER_LONG_CONSTANT("STREAM_SERVER_LISTEN", STREAM_XPORT_LISTEN, CONST_CS | CONST_PERSISTENT);
  242. REGISTER_LONG_CONSTANT("FILE_USE_INCLUDE_PATH", PHP_FILE_USE_INCLUDE_PATH, CONST_CS | CONST_PERSISTENT);
  243. REGISTER_LONG_CONSTANT("FILE_IGNORE_NEW_LINES", PHP_FILE_IGNORE_NEW_LINES, CONST_CS | CONST_PERSISTENT);
  244. REGISTER_LONG_CONSTANT("FILE_SKIP_EMPTY_LINES", PHP_FILE_SKIP_EMPTY_LINES, CONST_CS | CONST_PERSISTENT);
  245. REGISTER_LONG_CONSTANT("FILE_APPEND", PHP_FILE_APPEND, CONST_CS | CONST_PERSISTENT);
  246. REGISTER_LONG_CONSTANT("FILE_NO_DEFAULT_CONTEXT", PHP_FILE_NO_DEFAULT_CONTEXT, CONST_CS | CONST_PERSISTENT);
  247. REGISTER_LONG_CONSTANT("FILE_TEXT", 0, CONST_CS | CONST_PERSISTENT);
  248. REGISTER_LONG_CONSTANT("FILE_BINARY", 0, CONST_CS | CONST_PERSISTENT);
  249. #ifdef HAVE_FNMATCH
  250. REGISTER_LONG_CONSTANT("FNM_NOESCAPE", FNM_NOESCAPE, CONST_CS | CONST_PERSISTENT);
  251. REGISTER_LONG_CONSTANT("FNM_PATHNAME", FNM_PATHNAME, CONST_CS | CONST_PERSISTENT);
  252. REGISTER_LONG_CONSTANT("FNM_PERIOD", FNM_PERIOD, CONST_CS | CONST_PERSISTENT);
  253. # ifdef FNM_CASEFOLD /* a GNU extension */ /* TODO emulate if not available */
  254. REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_CS | CONST_PERSISTENT);
  255. # endif
  256. #endif
  257. return SUCCESS;
  258. }
  259. /* }}} */
  260. PHP_MSHUTDOWN_FUNCTION(file) /* {{{ */
  261. {
  262. #ifndef ZTS
  263. file_globals_dtor(&file_globals TSRMLS_CC);
  264. #endif
  265. return SUCCESS;
  266. }
  267. /* }}} */
  268. static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
  269. /* {{{ proto bool flock(resource fp, int operation [, int &wouldblock])
  270. Portable file locking */
  271. PHP_FUNCTION(flock)
  272. {
  273. zval *arg1, *arg3 = NULL;
  274. int act;
  275. php_stream *stream;
  276. long operation = 0;
  277. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) {
  278. return;
  279. }
  280. PHP_STREAM_TO_ZVAL(stream, &arg1);
  281. act = operation & 3;
  282. if (act < 1 || act > 3) {
  283. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal operation argument");
  284. RETURN_FALSE;
  285. }
  286. if (arg3 && PZVAL_IS_REF(arg3)) {
  287. convert_to_long_ex(&arg3);
  288. Z_LVAL_P(arg3) = 0;
  289. }
  290. /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
  291. act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
  292. if (php_stream_lock(stream, act)) {
  293. if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
  294. Z_LVAL_P(arg3) = 1;
  295. }
  296. RETURN_FALSE;
  297. }
  298. RETURN_TRUE;
  299. }
  300. /* }}} */
  301. #define PHP_META_UNSAFE ".\\+*?[^]$() "
  302. /* {{{ proto array get_meta_tags(string filename [, bool use_include_path])
  303. Extracts all meta tag content attributes from a file and returns an array */
  304. PHP_FUNCTION(get_meta_tags)
  305. {
  306. char *filename;
  307. int filename_len;
  308. zend_bool use_include_path = 0;
  309. int in_tag = 0, done = 0;
  310. int looking_for_val = 0, have_name = 0, have_content = 0;
  311. int saw_name = 0, saw_content = 0;
  312. char *name = NULL, *value = NULL, *temp = NULL;
  313. php_meta_tags_token tok, tok_last;
  314. php_meta_tags_data md;
  315. /* Initiailize our structure */
  316. memset(&md, 0, sizeof(md));
  317. /* Parse arguments */
  318. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &filename, &filename_len, &use_include_path) == FAILURE) {
  319. return;
  320. }
  321. if (strlen(filename) != filename_len) {
  322. RETURN_FALSE;
  323. }
  324. md.stream = php_stream_open_wrapper(filename, "rb",
  325. (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
  326. NULL);
  327. if (!md.stream) {
  328. RETURN_FALSE;
  329. }
  330. array_init(return_value);
  331. tok_last = TOK_EOF;
  332. while (!done && (tok = php_next_meta_token(&md TSRMLS_CC)) != TOK_EOF) {
  333. if (tok == TOK_ID) {
  334. if (tok_last == TOK_OPENTAG) {
  335. md.in_meta = !strcasecmp("meta", md.token_data);
  336. } else if (tok_last == TOK_SLASH && in_tag) {
  337. if (strcasecmp("head", md.token_data) == 0) {
  338. /* We are done here! */
  339. done = 1;
  340. }
  341. } else if (tok_last == TOK_EQUAL && looking_for_val) {
  342. if (saw_name) {
  343. STR_FREE(name);
  344. /* Get the NAME attr (Single word attr, non-quoted) */
  345. temp = name = estrndup(md.token_data, md.token_len);
  346. while (temp && *temp) {
  347. if (strchr(PHP_META_UNSAFE, *temp)) {
  348. *temp = '_';
  349. }
  350. temp++;
  351. }
  352. have_name = 1;
  353. } else if (saw_content) {
  354. STR_FREE(value);
  355. /* Get the CONTENT attr (Single word attr, non-quoted) */
  356. {
  357. value = estrndup(md.token_data, md.token_len);
  358. }
  359. have_content = 1;
  360. }
  361. looking_for_val = 0;
  362. } else {
  363. if (md.in_meta) {
  364. if (strcasecmp("name", md.token_data) == 0) {
  365. saw_name = 1;
  366. saw_content = 0;
  367. looking_for_val = 1;
  368. } else if (strcasecmp("content", md.token_data) == 0) {
  369. saw_name = 0;
  370. saw_content = 1;
  371. looking_for_val = 1;
  372. }
  373. }
  374. }
  375. } else if (tok == TOK_STRING && tok_last == TOK_EQUAL && looking_for_val) {
  376. if (saw_name) {
  377. STR_FREE(name);
  378. /* Get the NAME attr (Quoted single/double) */
  379. temp = name = estrndup(md.token_data, md.token_len);
  380. while (temp && *temp) {
  381. if (strchr(PHP_META_UNSAFE, *temp)) {
  382. *temp = '_';
  383. }
  384. temp++;
  385. }
  386. have_name = 1;
  387. } else if (saw_content) {
  388. STR_FREE(value);
  389. /* Get the CONTENT attr (Single word attr, non-quoted) */
  390. {
  391. value = estrndup(md.token_data, md.token_len);
  392. }
  393. have_content = 1;
  394. }
  395. looking_for_val = 0;
  396. } else if (tok == TOK_OPENTAG) {
  397. if (looking_for_val) {
  398. looking_for_val = 0;
  399. have_name = saw_name = 0;
  400. have_content = saw_content = 0;
  401. }
  402. in_tag = 1;
  403. } else if (tok == TOK_CLOSETAG) {
  404. if (have_name) {
  405. /* For BC */
  406. php_strtolower(name, strlen(name));
  407. if (have_content) {
  408. add_assoc_string(return_value, name, value, 1);
  409. } else {
  410. add_assoc_string(return_value, name, "", 1);
  411. }
  412. efree(name);
  413. STR_FREE(value);
  414. } else if (have_content) {
  415. efree(value);
  416. }
  417. name = value = NULL;
  418. /* Reset all of our flags */
  419. in_tag = looking_for_val = 0;
  420. have_name = saw_name = 0;
  421. have_content = saw_content = 0;
  422. md.in_meta = 0;
  423. }
  424. tok_last = tok;
  425. if (md.token_data)
  426. efree(md.token_data);
  427. md.token_data = NULL;
  428. }
  429. STR_FREE(value);
  430. STR_FREE(name);
  431. php_stream_close(md.stream);
  432. }
  433. /* }}} */
  434. /* {{{ proto string file_get_contents(string filename [, bool use_include_path [, resource context [, long offset [, long maxlen]]]])
  435. Read the entire file into a string */
  436. PHP_FUNCTION(file_get_contents)
  437. {
  438. char *filename;
  439. int filename_len;
  440. char *contents;
  441. zend_bool use_include_path = 0;
  442. php_stream *stream;
  443. int len;
  444. long offset = -1;
  445. long maxlen = PHP_STREAM_COPY_ALL;
  446. zval *zcontext = NULL;
  447. php_stream_context *context = NULL;
  448. /* Parse arguments */
  449. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
  450. return;
  451. }
  452. if (strlen(filename) != filename_len) {
  453. RETURN_FALSE;
  454. }
  455. if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
  456. php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
  457. RETURN_FALSE;
  458. }
  459. context = php_stream_context_from_zval(zcontext, 0);
  460. stream = php_stream_open_wrapper_ex(filename, "rb",
  461. (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
  462. NULL, context);
  463. if (!stream) {
  464. RETURN_FALSE;
  465. }
  466. if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
  467. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
  468. php_stream_close(stream);
  469. RETURN_FALSE;
  470. }
  471. if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
  472. RETVAL_STRINGL(contents, len, 0);
  473. } else if (len == 0) {
  474. RETVAL_EMPTY_STRING();
  475. } else {
  476. RETVAL_FALSE;
  477. }
  478. php_stream_close(stream);
  479. }
  480. /* }}} */
  481. /* {{{ proto int file_put_contents(string file, mixed data [, int flags [, resource context]])
  482. Write/Create a file with contents data and return the number of bytes written */
  483. PHP_FUNCTION(file_put_contents)
  484. {
  485. php_stream *stream;
  486. char *filename;
  487. int filename_len;
  488. zval *data;
  489. int numbytes = 0;
  490. long flags = 0;
  491. zval *zcontext = NULL;
  492. php_stream_context *context = NULL;
  493. php_stream *srcstream = NULL;
  494. char mode[3] = "wb";
  495. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|lr!", &filename, &filename_len, &data, &flags, &zcontext) == FAILURE) {
  496. return;
  497. }
  498. if (strlen(filename) != filename_len) {
  499. RETURN_FALSE;
  500. }
  501. if (Z_TYPE_P(data) == IS_RESOURCE) {
  502. php_stream_from_zval(srcstream, &data);
  503. }
  504. context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
  505. if (flags & PHP_FILE_APPEND) {
  506. mode[0] = 'a';
  507. } else if (flags & LOCK_EX) {
  508. /* check to make sure we are dealing with a regular file */
  509. if (php_memnstr(filename, "://", sizeof("://") - 1, filename + filename_len)) {
  510. if (strncasecmp(filename, "file://", sizeof("file://") - 1)) {
  511. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks may only be set for regular files");
  512. RETURN_FALSE;
  513. }
  514. }
  515. mode[0] = 'c';
  516. }
  517. mode[2] = '\0';
  518. stream = php_stream_open_wrapper_ex(filename, mode, ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
  519. if (stream == NULL) {
  520. RETURN_FALSE;
  521. }
  522. if (flags & LOCK_EX && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) {
  523. php_stream_close(stream);
  524. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks are not supported for this stream");
  525. RETURN_FALSE;
  526. }
  527. if (mode[0] == 'c') {
  528. php_stream_truncate_set_size(stream, 0);
  529. }
  530. switch (Z_TYPE_P(data)) {
  531. case IS_RESOURCE: {
  532. size_t len;
  533. if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
  534. numbytes = -1;
  535. } else {
  536. numbytes = len;
  537. }
  538. break;
  539. }
  540. case IS_NULL:
  541. case IS_LONG:
  542. case IS_DOUBLE:
  543. case IS_BOOL:
  544. case IS_CONSTANT:
  545. convert_to_string_ex(&data);
  546. case IS_STRING:
  547. if (Z_STRLEN_P(data)) {
  548. numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
  549. if (numbytes != Z_STRLEN_P(data)) {
  550. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data));
  551. numbytes = -1;
  552. }
  553. }
  554. break;
  555. case IS_ARRAY:
  556. if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
  557. int bytes_written;
  558. zval **tmp;
  559. HashPosition pos;
  560. zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
  561. while (zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &tmp, &pos) == SUCCESS) {
  562. if (Z_TYPE_PP(tmp) != IS_STRING) {
  563. SEPARATE_ZVAL(tmp);
  564. convert_to_string(*tmp);
  565. }
  566. if (Z_STRLEN_PP(tmp)) {
  567. numbytes += Z_STRLEN_PP(tmp);
  568. bytes_written = php_stream_write(stream, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
  569. if (bytes_written < 0 || bytes_written != Z_STRLEN_PP(tmp)) {
  570. if (bytes_written < 0) {
  571. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN_PP(tmp), filename);
  572. } else {
  573. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", bytes_written, Z_STRLEN_PP(tmp));
  574. }
  575. numbytes = -1;
  576. break;
  577. }
  578. }
  579. zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos);
  580. }
  581. }
  582. break;
  583. case IS_OBJECT:
  584. if (Z_OBJ_HT_P(data) != NULL) {
  585. zval out;
  586. if (zend_std_cast_object_tostring(data, &out, IS_STRING TSRMLS_CC) == SUCCESS) {
  587. numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out));
  588. if (numbytes != Z_STRLEN(out)) {
  589. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out));
  590. numbytes = -1;
  591. }
  592. zval_dtor(&out);
  593. break;
  594. }
  595. }
  596. default:
  597. numbytes = -1;
  598. break;
  599. }
  600. php_stream_close(stream);
  601. if (numbytes < 0) {
  602. RETURN_FALSE;
  603. }
  604. RETURN_LONG(numbytes);
  605. }
  606. /* }}} */
  607. #define PHP_FILE_BUF_SIZE 80
  608. /* {{{ proto array file(string filename [, int flags[, resource context]])
  609. Read entire file into an array */
  610. PHP_FUNCTION(file)
  611. {
  612. char *filename;
  613. int filename_len;
  614. char *slashed, *target_buf=NULL, *p, *s, *e;
  615. register int i = 0;
  616. int target_len, len;
  617. char eol_marker = '\n';
  618. long flags = 0;
  619. zend_bool use_include_path;
  620. zend_bool include_new_line;
  621. zend_bool skip_blank_lines;
  622. php_stream *stream;
  623. zval *zcontext = NULL;
  624. php_stream_context *context = NULL;
  625. /* Parse arguments */
  626. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr!", &filename, &filename_len, &flags, &zcontext) == FAILURE) {
  627. return;
  628. }
  629. if (strlen(filename) != filename_len) {
  630. RETURN_FALSE;
  631. }
  632. if (flags < 0 || flags > (PHP_FILE_USE_INCLUDE_PATH | PHP_FILE_IGNORE_NEW_LINES | PHP_FILE_SKIP_EMPTY_LINES | PHP_FILE_NO_DEFAULT_CONTEXT)) {
  633. php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%ld' flag is not supported", flags);
  634. RETURN_FALSE;
  635. }
  636. use_include_path = flags & PHP_FILE_USE_INCLUDE_PATH;
  637. include_new_line = !(flags & PHP_FILE_IGNORE_NEW_LINES);
  638. skip_blank_lines = flags & PHP_FILE_SKIP_EMPTY_LINES;
  639. context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
  640. stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
  641. if (!stream) {
  642. RETURN_FALSE;
  643. }
  644. /* Initialize return array */
  645. array_init(return_value);
  646. if ((target_len = php_stream_copy_to_mem(stream, &target_buf, PHP_STREAM_COPY_ALL, 0))) {
  647. s = target_buf;
  648. e = target_buf + target_len;
  649. if (!(p = php_stream_locate_eol(stream, target_buf, target_len TSRMLS_CC))) {
  650. p = e;
  651. goto parse_eol;
  652. }
  653. if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
  654. eol_marker = '\r';
  655. }
  656. /* for performance reasons the code is duplicated, so that the if (include_new_line)
  657. * will not need to be done for every single line in the file. */
  658. if (include_new_line) {
  659. do {
  660. p++;
  661. parse_eol:
  662. {
  663. add_index_stringl(return_value, i++, estrndup(s, p-s), p-s, 0);
  664. }
  665. s = p;
  666. } while ((p = memchr(p, eol_marker, (e-p))));
  667. } else {
  668. do {
  669. int windows_eol = 0;
  670. if (p != target_buf && eol_marker == '\n' && *(p - 1) == '\r') {
  671. windows_eol++;
  672. }
  673. if (skip_blank_lines && !(p-s-windows_eol)) {
  674. s = ++p;
  675. continue;
  676. }
  677. {
  678. add_index_stringl(return_value, i++, estrndup(s, p-s-windows_eol), p-s-windows_eol, 0);
  679. }
  680. s = ++p;
  681. } while ((p = memchr(p, eol_marker, (e-p))));
  682. }
  683. /* handle any left overs of files without new lines */
  684. if (s != e) {
  685. p = e;
  686. goto parse_eol;
  687. }
  688. }
  689. if (target_buf) {
  690. efree(target_buf);
  691. }
  692. php_stream_close(stream);
  693. }
  694. /* }}} */
  695. /* {{{ proto string tempnam(string dir, string prefix)
  696. Create a unique filename in a directory */
  697. PHP_FUNCTION(tempnam)
  698. {
  699. char *dir, *prefix;
  700. int dir_len, prefix_len;
  701. size_t p_len;
  702. char *opened_path;
  703. char *p;
  704. int fd;
  705. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
  706. return;
  707. }
  708. if (strlen(dir) != dir_len) {
  709. RETURN_FALSE;
  710. }
  711. if (strlen(prefix) != prefix_len) {
  712. RETURN_FALSE;
  713. }
  714. if (php_check_open_basedir(dir TSRMLS_CC)) {
  715. RETURN_FALSE;
  716. }
  717. php_basename(prefix, prefix_len, NULL, 0, &p, &p_len TSRMLS_CC);
  718. if (p_len > 64) {
  719. p[63] = '\0';
  720. }
  721. RETVAL_FALSE;
  722. if ((fd = php_open_temporary_fd(dir, p, &opened_path TSRMLS_CC)) >= 0) {
  723. close(fd);
  724. RETVAL_STRING(opened_path, 0);
  725. }
  726. efree(p);
  727. }
  728. /* }}} */
  729. /* {{{ proto resource tmpfile(void)
  730. Create a temporary file that will be deleted automatically after use */
  731. PHP_NAMED_FUNCTION(php_if_tmpfile)
  732. {
  733. php_stream *stream;
  734. if (zend_parse_parameters_none() == FAILURE) {
  735. return;
  736. }
  737. stream = php_stream_fopen_tmpfile();
  738. if (stream) {
  739. php_stream_to_zval(stream, return_value);
  740. } else {
  741. RETURN_FALSE;
  742. }
  743. }
  744. /* }}} */
  745. /* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]])
  746. Open a file or a URL and return a file pointer */
  747. PHP_NAMED_FUNCTION(php_if_fopen)
  748. {
  749. char *filename, *mode;
  750. int filename_len, mode_len;
  751. zend_bool use_include_path = 0;
  752. zval *zcontext = NULL;
  753. php_stream *stream;
  754. php_stream_context *context = NULL;
  755. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
  756. RETURN_FALSE;
  757. }
  758. if (strlen(filename) != filename_len) {
  759. RETURN_FALSE;
  760. }
  761. context = php_stream_context_from_zval(zcontext, 0);
  762. stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
  763. if (stream == NULL) {
  764. RETURN_FALSE;
  765. }
  766. php_stream_to_zval(stream, return_value);
  767. }
  768. /* }}} */
  769. /* {{{ proto bool fclose(resource fp)
  770. Close an open file pointer */
  771. PHPAPI PHP_FUNCTION(fclose)
  772. {
  773. zval *arg1;
  774. php_stream *stream;
  775. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  776. RETURN_FALSE;
  777. }
  778. PHP_STREAM_TO_ZVAL(stream, &arg1);
  779. if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
  780. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid stream resource", stream->rsrc_id);
  781. RETURN_FALSE;
  782. }
  783. if (!stream->is_persistent) {
  784. zend_list_delete(stream->rsrc_id);
  785. } else {
  786. php_stream_pclose(stream);
  787. }
  788. RETURN_TRUE;
  789. }
  790. /* }}} */
  791. /* {{{ proto resource popen(string command, string mode)
  792. Execute a command and open either a read or a write pipe to it */
  793. PHP_FUNCTION(popen)
  794. {
  795. char *command, *mode;
  796. int command_len, mode_len;
  797. FILE *fp;
  798. php_stream *stream;
  799. char *posix_mode, *b, *buf = 0, *tmp;
  800. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &command, &command_len, &mode, &mode_len) == FAILURE) {
  801. return;
  802. }
  803. posix_mode = estrndup(mode, mode_len);
  804. #ifndef PHP_WIN32
  805. {
  806. char *z = memchr(posix_mode, 'b', mode_len);
  807. if (z) {
  808. memmove(z, z + 1, mode_len - (z - posix_mode));
  809. }
  810. }
  811. #endif
  812. {
  813. fp = VCWD_POPEN(command, posix_mode);
  814. if (!fp) {
  815. php_error_docref2(NULL TSRMLS_CC, command, posix_mode, E_WARNING, "%s", strerror(errno));
  816. efree(posix_mode);
  817. RETURN_FALSE;
  818. }
  819. }
  820. stream = php_stream_fopen_from_pipe(fp, mode);
  821. if (stream == NULL) {
  822. php_error_docref2(NULL TSRMLS_CC, command, mode, E_WARNING, "%s", strerror(errno));
  823. RETVAL_FALSE;
  824. } else {
  825. php_stream_to_zval(stream, return_value);
  826. }
  827. efree(posix_mode);
  828. }
  829. /* }}} */
  830. /* {{{ proto int pclose(resource fp)
  831. Close a file pointer opened by popen() */
  832. PHP_FUNCTION(pclose)
  833. {
  834. zval *arg1;
  835. php_stream *stream;
  836. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  837. RETURN_FALSE;
  838. }
  839. PHP_STREAM_TO_ZVAL(stream, &arg1);
  840. zend_list_delete(stream->rsrc_id);
  841. RETURN_LONG(FG(pclose_ret));
  842. }
  843. /* }}} */
  844. /* {{{ proto bool feof(resource fp)
  845. Test for end-of-file on a file pointer */
  846. PHPAPI PHP_FUNCTION(feof)
  847. {
  848. zval *arg1;
  849. php_stream *stream;
  850. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  851. RETURN_FALSE;
  852. }
  853. PHP_STREAM_TO_ZVAL(stream, &arg1);
  854. if (php_stream_eof(stream)) {
  855. RETURN_TRUE;
  856. } else {
  857. RETURN_FALSE;
  858. }
  859. }
  860. /* }}} */
  861. /* {{{ proto string fgets(resource fp[, int length])
  862. Get a line from file pointer */
  863. PHPAPI PHP_FUNCTION(fgets)
  864. {
  865. zval *arg1;
  866. long len = 1024;
  867. char *buf = NULL;
  868. int argc = ZEND_NUM_ARGS();
  869. size_t line_len = 0;
  870. php_stream *stream;
  871. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &len) == FAILURE) {
  872. RETURN_FALSE;
  873. }
  874. PHP_STREAM_TO_ZVAL(stream, &arg1);
  875. if (argc == 1) {
  876. /* ask streams to give us a buffer of an appropriate size */
  877. buf = php_stream_get_line(stream, NULL, 0, &line_len);
  878. if (buf == NULL) {
  879. goto exit_failed;
  880. }
  881. } else if (argc > 1) {
  882. if (len <= 0) {
  883. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
  884. RETURN_FALSE;
  885. }
  886. buf = ecalloc(len + 1, sizeof(char));
  887. if (php_stream_get_line(stream, buf, len, &line_len) == NULL) {
  888. goto exit_failed;
  889. }
  890. }
  891. {
  892. ZVAL_STRINGL(return_value, buf, line_len, 0);
  893. /* resize buffer if it's much larger than the result.
  894. * Only needed if the user requested a buffer size. */
  895. if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) {
  896. Z_STRVAL_P(return_value) = erealloc(buf, line_len + 1);
  897. }
  898. }
  899. return;
  900. exit_failed:
  901. RETVAL_FALSE;
  902. if (buf) {
  903. efree(buf);
  904. }
  905. }
  906. /* }}} */
  907. /* {{{ proto string fgetc(resource fp)
  908. Get a character from file pointer */
  909. PHPAPI PHP_FUNCTION(fgetc)
  910. {
  911. zval *arg1;
  912. char buf[2];
  913. int result;
  914. php_stream *stream;
  915. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  916. RETURN_FALSE;
  917. }
  918. PHP_STREAM_TO_ZVAL(stream, &arg1);
  919. result = php_stream_getc(stream);
  920. if (result == EOF) {
  921. RETVAL_FALSE;
  922. } else {
  923. buf[0] = result;
  924. buf[1] = '\0';
  925. RETURN_STRINGL(buf, 1, 1);
  926. }
  927. }
  928. /* }}} */
  929. /* {{{ proto string fgetss(resource fp [, int length [, string allowable_tags]])
  930. Get a line from file pointer and strip HTML tags */
  931. PHPAPI PHP_FUNCTION(fgetss)
  932. {
  933. zval *fd;
  934. long bytes = 0;
  935. size_t len = 0;
  936. size_t actual_len, retval_len;
  937. char *buf = NULL, *retval;
  938. php_stream *stream;
  939. char *allowed_tags=NULL;
  940. int allowed_tags_len=0;
  941. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) {
  942. RETURN_FALSE;
  943. }
  944. PHP_STREAM_TO_ZVAL(stream, &fd);
  945. if (ZEND_NUM_ARGS() >= 2) {
  946. if (bytes <= 0) {
  947. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
  948. RETURN_FALSE;
  949. }
  950. len = (size_t) bytes;
  951. buf = safe_emalloc(sizeof(char), (len + 1), 0);
  952. /*needed because recv doesnt set null char at end*/
  953. memset(buf, 0, len + 1);
  954. }
  955. if ((retval = php_stream_get_line(stream, buf, len, &actual_len)) == NULL) {
  956. if (buf != NULL) {
  957. efree(buf);
  958. }
  959. RETURN_FALSE;
  960. }
  961. retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len);
  962. RETURN_STRINGL(retval, retval_len, 0);
  963. }
  964. /* }}} */
  965. /* {{{ proto mixed fscanf(resource stream, string format [, string ...])
  966. Implements a mostly ANSI compatible fscanf() */
  967. PHP_FUNCTION(fscanf)
  968. {
  969. int result, format_len, type, argc = 0;
  970. zval ***args = NULL;
  971. zval *file_handle;
  972. char *buf, *format;
  973. size_t len;
  974. void *what;
  975. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs*", &file_handle, &format, &format_len, &args, &argc) == FAILURE) {
  976. return;
  977. }
  978. what = zend_fetch_resource(&file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, php_file_le_stream(), php_file_le_pstream());
  979. /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
  980. * with a leak if we have an invalid filehandle. This needs changing
  981. * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */
  982. if (!what) {
  983. if (args) {
  984. efree(args);
  985. }
  986. RETURN_FALSE;
  987. }
  988. buf = php_stream_get_line((php_stream *) what, NULL, 0, &len);
  989. if (buf == NULL) {
  990. if (args) {
  991. efree(args);
  992. }
  993. RETURN_FALSE;
  994. }
  995. result = php_sscanf_internal(buf, format, argc, args, 0, &return_value TSRMLS_CC);
  996. if (args) {
  997. efree(args);
  998. }
  999. efree(buf);
  1000. if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
  1001. WRONG_PARAM_COUNT;
  1002. }
  1003. }
  1004. /* }}} */
  1005. /* {{{ proto int fwrite(resource fp, string str [, int length])
  1006. Binary-safe file write */
  1007. PHPAPI PHP_FUNCTION(fwrite)
  1008. {
  1009. zval *arg1;
  1010. char *arg2;
  1011. int arg2len;
  1012. int ret;
  1013. int num_bytes;
  1014. long arg3 = 0;
  1015. char *buffer = NULL;
  1016. php_stream *stream;
  1017. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &arg2, &arg2len, &arg3) == FAILURE) {
  1018. RETURN_FALSE;
  1019. }
  1020. if (ZEND_NUM_ARGS() == 2) {
  1021. num_bytes = arg2len;
  1022. } else {
  1023. num_bytes = MAX(0, MIN((int)arg3, arg2len));
  1024. }
  1025. if (!num_bytes) {
  1026. RETURN_LONG(0);
  1027. }
  1028. PHP_STREAM_TO_ZVAL(stream, &arg1);
  1029. ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes);
  1030. if (buffer) {
  1031. efree(buffer);
  1032. }
  1033. RETURN_LONG(ret);
  1034. }
  1035. /* }}} */
  1036. /* {{{ proto int ob_fwrite(resource fp[, int length])
  1037. Binary-safe file write from ob buffer */
  1038. PHPAPI PHP_FUNCTION(ob_fwrite)
  1039. {
  1040. zval *ress;
  1041. long len = 0;
  1042. php_stream *stream;
  1043. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &ress, &len) == FAILURE) {
  1044. return;
  1045. }
  1046. if (!OG(ob_nesting_level)) {
  1047. php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
  1048. RETURN_FALSE;
  1049. }
  1050. if (0 <= len) {
  1051. len = OG(active_ob_buffer).text_length;
  1052. }
  1053. if (len <= 0) {
  1054. RETURN_LONG(0);
  1055. }
  1056. PHP_STREAM_TO_ZVAL(stream, &ress);
  1057. RETURN_LONG(php_stream_write(stream, OG(active_ob_buffer).buffer, len));
  1058. }
  1059. /* }}} */
  1060. /* {{{ proto bool fflush(resource fp)
  1061. Flushes output */
  1062. PHPAPI PHP_FUNCTION(fflush)
  1063. {
  1064. zval *arg1;
  1065. int ret;
  1066. php_stream *stream;
  1067. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  1068. RETURN_FALSE;
  1069. }
  1070. PHP_STREAM_TO_ZVAL(stream, &arg1);
  1071. ret = php_stream_flush(stream);
  1072. if (ret) {
  1073. RETURN_FALSE;
  1074. }
  1075. RETURN_TRUE;
  1076. }
  1077. /* }}} */
  1078. /* {{{ proto bool rewind(resource fp)
  1079. Rewind the position of a file pointer */
  1080. PHPAPI PHP_FUNCTION(rewind)
  1081. {
  1082. zval *arg1;
  1083. php_stream *stream;
  1084. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  1085. RETURN_FALSE;
  1086. }
  1087. PHP_STREAM_TO_ZVAL(stream, &arg1);
  1088. if (-1 == php_stream_rewind(stream)) {
  1089. RETURN_FALSE;
  1090. }
  1091. RETURN_TRUE;
  1092. }
  1093. /* }}} */
  1094. /* {{{ proto int ftell(resource fp)
  1095. Get file pointer's read/write position */
  1096. PHPAPI PHP_FUNCTION(ftell)
  1097. {
  1098. zval *arg1;
  1099. long ret;
  1100. php_stream *stream;
  1101. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  1102. RETURN_FALSE;
  1103. }
  1104. PHP_STREAM_TO_ZVAL(stream, &arg1);
  1105. ret = php_stream_tell(stream);
  1106. if (ret == -1) {
  1107. RETURN_FALSE;
  1108. }
  1109. RETURN_LONG(ret);
  1110. }
  1111. /* }}} */
  1112. /* {{{ proto int fseek(resource fp, int offset [, int whence])
  1113. Seek on a file pointer */
  1114. PHPAPI PHP_FUNCTION(fseek)
  1115. {
  1116. zval *arg1;
  1117. long arg2, whence = SEEK_SET;
  1118. php_stream *stream;
  1119. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &arg2, &whence) == FAILURE) {
  1120. RETURN_FALSE;
  1121. }
  1122. PHP_STREAM_TO_ZVAL(stream, &arg1);
  1123. RETURN_LONG(php_stream_seek(stream, arg2, whence));
  1124. }
  1125. /* }}} */
  1126. /* {{{ php_mkdir
  1127. */
  1128. /* DEPRECATED APIs: Use php_stream_mkdir() instead */
  1129. PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC)
  1130. {
  1131. int ret;
  1132. if (php_check_open_basedir(dir TSRMLS_CC)) {
  1133. return -1;
  1134. }
  1135. if ((ret = VCWD_MKDIR(dir, (mode_t)mode)) < 0 && (options & REPORT_ERRORS)) {
  1136. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
  1137. }
  1138. return ret;
  1139. }
  1140. PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC)
  1141. {
  1142. return php_mkdir_ex(dir, mode, REPORT_ERRORS TSRMLS_CC);
  1143. }
  1144. /* }}} */
  1145. /* {{{ proto bool mkdir(string pathname [, int mode [, bool recursive [, resource context]]])
  1146. Create a directory */
  1147. PHP_FUNCTION(mkdir)
  1148. {
  1149. char *dir;
  1150. int dir_len;
  1151. zval *zcontext = NULL;
  1152. long mode = 0777;
  1153. zend_bool recursive = 0;
  1154. php_stream_context *context;
  1155. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbr", &dir, &dir_len, &mode, &recursive, &zcontext) == FAILURE) {
  1156. RETURN_FALSE;
  1157. }
  1158. if (strlen(dir) != dir_len) {
  1159. RETURN_FALSE;
  1160. }
  1161. context = php_stream_context_from_zval(zcontext, 0);
  1162. RETURN_BOOL(php_stream_mkdir(dir, mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
  1163. }
  1164. /* }}} */
  1165. /* {{{ proto bool rmdir(string dirname[, resource context])
  1166. Remove a directory */
  1167. PHP_FUNCTION(rmdir)
  1168. {
  1169. char *dir;
  1170. int dir_len;
  1171. zval *zcontext = NULL;
  1172. php_stream_context *context;
  1173. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
  1174. RETURN_FALSE;
  1175. }
  1176. if (strlen(dir) != dir_len) {
  1177. RETURN_FALSE;
  1178. }
  1179. context = php_stream_context_from_zval(zcontext, 0);
  1180. RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context));
  1181. }
  1182. /* }}} */
  1183. /* {{{ proto int readfile(string filename [, bool use_include_path[, resource context]])
  1184. Output a file or a URL */
  1185. PHP_FUNCTION(readfile)
  1186. {
  1187. char *filename;
  1188. int filename_len;
  1189. int size = 0;
  1190. zend_bool use_include_path = 0;
  1191. zval *zcontext = NULL;
  1192. php_stream *stream;
  1193. php_stream_context *context = NULL;
  1194. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
  1195. RETURN_FALSE;
  1196. }
  1197. if (strlen(filename) != filename_len) {
  1198. RETURN_FALSE;
  1199. }
  1200. context = php_stream_context_from_zval(zcontext, 0);
  1201. stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
  1202. if (stream) {
  1203. size = php_stream_passthru(stream);
  1204. php_stream_close(stream);
  1205. RETURN_LONG(size);
  1206. }
  1207. RETURN_FALSE;
  1208. }
  1209. /* }}} */
  1210. /* {{{ proto int umask([int mask])
  1211. Return or change the umask */
  1212. PHP_FUNCTION(umask)
  1213. {
  1214. long arg1 = 0;
  1215. int oldumask;
  1216. int arg_count = ZEND_NUM_ARGS();
  1217. oldumask = umask(077);
  1218. if (BG(umask) == -1) {
  1219. BG(umask) = oldumask;
  1220. }
  1221. if (arg_count == 0) {
  1222. umask(oldumask);
  1223. } else {
  1224. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
  1225. RETURN_FALSE;
  1226. }
  1227. umask(arg1);
  1228. }
  1229. RETURN_LONG(oldumask);
  1230. }
  1231. /* }}} */
  1232. /* {{{ proto int fpassthru(resource fp)
  1233. Output all remaining data from a file pointer */
  1234. PHPAPI PHP_FUNCTION(fpassthru)
  1235. {
  1236. zval *arg1;
  1237. int size;
  1238. php_stream *stream;
  1239. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
  1240. RETURN_FALSE;
  1241. }
  1242. PHP_STREAM_TO_ZVAL(stream, &arg1);
  1243. size = php_stream_passthru(stream);
  1244. RETURN_LONG(size);
  1245. }
  1246. /* }}} */
  1247. /* {{{ proto bool rename(string old_name, string new_name[, resource context])
  1248. Rename a file */
  1249. PHP_FUNCTION(rename)
  1250. {
  1251. char *old_name, *new_name;
  1252. int old_name_len, new_name_len;
  1253. zval *zcontext = NULL;
  1254. php_stream_wrapper *wrapper;
  1255. php_stream_context *context;
  1256. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &old_name, &old_name_len, &new_name, &new_name_len, &zcontext) == FAILURE) {
  1257. RETURN_FALSE;
  1258. }
  1259. if (strlen(old_name) != old_name_len) {
  1260. RETURN_FALSE;
  1261. }
  1262. if (strlen(new_name) != new_name_len) {
  1263. RETURN_FALSE;
  1264. }
  1265. wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0 TSRMLS_CC);
  1266. if (!wrapper || !wrapper->wops) {
  1267. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
  1268. RETURN_FALSE;
  1269. }
  1270. if (!wrapper->wops->rename) {
  1271. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s wrapper does not support renaming", wrapper->wops->label ? wrapper->wops->label : "Source");
  1272. RETURN_FALSE;
  1273. }
  1274. if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0 TSRMLS_CC)) {
  1275. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rename a file across wrapper types");
  1276. RETURN_FALSE;
  1277. }
  1278. context = php_stream_context_from_zval(zcontext, 0);
  1279. RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context TSRMLS_CC));
  1280. }
  1281. /* }}} */
  1282. /* {{{ proto bool unlink(string filename[, context context])
  1283. Delete a file */
  1284. PHP_FUNCTION(unlink)
  1285. {
  1286. char *filename;
  1287. int filename_len;
  1288. php_stream_wrapper *wrapper;
  1289. zval *zcontext = NULL;
  1290. php_stream_context *context = NULL;
  1291. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &filename, &filename_len, &zcontext) == FAILURE) {
  1292. RETURN_FALSE;
  1293. }
  1294. if (strlen(filename) != filename_len) {
  1295. RETURN_FALSE;
  1296. }
  1297. context = php_stream_context_from_zval(zcontext, 0);
  1298. wrapper = php_stream_locate_url_wrapper(filename, NULL, 0 TSRMLS_CC);
  1299. if (!wrapper || !wrapper->wops) {
  1300. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
  1301. RETURN_FALSE;
  1302. }
  1303. if (!wrapper->wops->unlink) {
  1304. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
  1305. RETURN_FALSE;
  1306. }
  1307. RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC));
  1308. }
  1309. /* }}} */
  1310. /* {{{ proto bool ftruncate(resource fp, int size)
  1311. Truncate file to 'size' length */
  1312. PHP_NAMED_FUNCTION(php_if_ftruncate)
  1313. {
  1314. zval *fp;
  1315. long size;
  1316. php_stream *stream;
  1317. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &fp, &size) == FAILURE) {
  1318. RETURN_FALSE;
  1319. }
  1320. PHP_STREAM_TO_ZVAL(stream, &fp);
  1321. if (!php_stream_truncate_supported(stream)) {
  1322. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream!");
  1323. RETURN_FALSE;
  1324. }
  1325. RETURN_BOOL(0 == php_stream_truncate_set_size(stream, size));
  1326. }
  1327. /* }}} */
  1328. /* {{{ proto array fstat(resource fp)
  1329. Stat() on a filehandle */
  1330. PHP_NAMED_FUNCTION(php_if_fstat)
  1331. {
  1332. zval *fp;
  1333. zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
  1334. *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
  1335. php_stream *stream;
  1336. php_stream_statbuf stat_ssb;
  1337. char *stat_sb_names[13] = {
  1338. "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
  1339. "size", "atime", "mtime", "ctime", "blksize", "blocks"
  1340. };
  1341. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &fp) == FAILURE) {
  1342. RETURN_FALSE;
  1343. }
  1344. PHP_STREAM_TO_ZVAL(stream, &fp);
  1345. if (php_stream_stat(stream, &stat_ssb)) {
  1346. RETURN_FALSE;
  1347. }
  1348. array_init(return_value);
  1349. MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev);
  1350. MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino);
  1351. MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode);
  1352. MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink);
  1353. MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid);
  1354. MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid);
  1355. #ifdef HAVE_ST_RDEV
  1356. MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev);
  1357. #else
  1358. MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
  1359. #endif
  1360. MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size);
  1361. MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime);
  1362. MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime);
  1363. MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime);
  1364. #ifdef HAVE_ST_BLKSIZE
  1365. MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize);
  1366. #else
  1367. MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
  1368. #endif
  1369. #ifdef HAVE_ST_BLOCKS
  1370. MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks);
  1371. #else
  1372. MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
  1373. #endif
  1374. /* Store numeric indexes in propper order */
  1375. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
  1376. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
  1377. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
  1378. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
  1379. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
  1380. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
  1381. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
  1382. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
  1383. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
  1384. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
  1385. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
  1386. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
  1387. zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
  1388. /* Store string indexes referencing the same zval*/
  1389. zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *)&stat_dev, sizeof(zval *), NULL);
  1390. zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *)&stat_ino, sizeof(zval *), NULL);
  1391. zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *)&stat_mode, sizeof(zval *), NULL);
  1392. zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *)&stat_nlink, sizeof(zval *), NULL);
  1393. zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *)&stat_uid, sizeof(zval *), NULL);
  1394. zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *)&stat_gid, sizeof(zval *), NULL);
  1395. zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *)&stat_rdev, sizeof(zval *), NULL);
  1396. zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *)&stat_size, sizeof(zval *), NULL);
  1397. zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *)&stat_atime, sizeof(zval *), NULL);
  1398. zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *)&stat_mtime, sizeof(zval *), NULL);
  1399. zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *)&stat_ctime, sizeof(zval *), NULL);
  1400. zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *)&stat_blksize, sizeof(zval *), NULL);
  1401. zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *)&stat_blocks, sizeof(zval *), NULL);
  1402. }
  1403. /* }}} */
  1404. /* {{{ proto bool copy(string source_file, string destination_file [, resource context])
  1405. Copy a file */
  1406. PHP_FUNCTION(copy)
  1407. {
  1408. char *source, *target;
  1409. int source_len, target_len;
  1410. zval *zcontext = NULL;
  1411. php_stream_context *context;
  1412. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &source, &source_len, &target, &target_len, &zcontext) == FAILURE) {
  1413. return;
  1414. }
  1415. if (strlen(source) != source_len) {
  1416. RETURN_FALSE;
  1417. }
  1418. if (strlen(target) != target_len) {
  1419. RETURN_FALSE;
  1420. }
  1421. if (php_check_open_basedir(source TSRMLS_CC)) {
  1422. RETURN_FALSE;
  1423. }
  1424. context = php_stream_context_from_zval(zcontext, 0);
  1425. if (php_copy_file_ctx(source, target, 0, context TSRMLS_CC) == SUCCESS) {
  1426. RETURN_TRUE;
  1427. } else {
  1428. RETURN_FALSE;
  1429. }
  1430. }
  1431. /* }}} */
  1432. /* {{{ php_copy_file
  1433. */
  1434. PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC)
  1435. {
  1436. return php_copy_file_ctx(src, dest, ENFORCE_SAFE_MODE, NULL TSRMLS_CC);
  1437. }
  1438. /* }}} */
  1439. /* {{{ php_copy_file_ex
  1440. */
  1441. PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC)
  1442. {
  1443. return php_copy_file_ctx(src, dest, ENFORCE_SAFE_MODE, NULL TSRMLS_CC);
  1444. }
  1445. /* }}} */
  1446. /* {{{ php_copy_file_ctx
  1447. */
  1448. PHPAPI int php_copy_file_ctx(char *src, char *dest, int src_chk, php_stream_context *context TSRMLS_DC)
  1449. {
  1450. php_stream *srcstream = NULL, *deststream = NULL;
  1451. int ret = FAILURE;
  1452. php_stream_statbuf src_s, dest_s;
  1453. switch (php_stream_stat_path_ex(src, 0, &src_s, context)) {
  1454. case -1:
  1455. /* non-statable stream */
  1456. goto safe_to_copy;
  1457. break;
  1458. case 0:
  1459. break;
  1460. default: /* failed to stat file, does not exist? */
  1461. return ret;
  1462. }
  1463. if (S_ISDIR(src_s.sb.st_mode)) {
  1464. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument to copy() function cannot be a directory");
  1465. return FAILURE;
  1466. }
  1467. switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, context)) {
  1468. case -1:
  1469. /* non-statable stream */
  1470. goto safe_to_copy;
  1471. break;
  1472. case 0:
  1473. break;
  1474. default: /* failed to stat file, does not exist? */
  1475. return ret;
  1476. }
  1477. if (S_ISDIR(dest_s.sb.st_mode)) {
  1478. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument t…

Large files files are truncated, but you can click here to view the full file