1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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 :
24 : /* $Id: file.c 290190 2009-11-03 21:21:34Z guenter $ */
25 :
26 : /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
27 :
28 : /* {{{ includes */
29 :
30 : #include "php.h"
31 : #include "php_globals.h"
32 : #include "ext/standard/flock_compat.h"
33 : #include "ext/standard/exec.h"
34 : #include "ext/standard/php_filestat.h"
35 : #include "php_open_temporary_file.h"
36 : #include "ext/standard/basic_functions.h"
37 : #include "php_ini.h"
38 : #include "php_smart_str.h"
39 :
40 : #include <stdio.h>
41 : #include <stdlib.h>
42 : #include <errno.h>
43 : #include <sys/types.h>
44 : #include <sys/stat.h>
45 : #include <fcntl.h>
46 :
47 : #ifdef PHP_WIN32
48 : # include <io.h>
49 : # define O_RDONLY _O_RDONLY
50 : # include "win32/param.h"
51 : # include "win32/winutil.h"
52 : # include "win32/fnmatch.h"
53 : #else
54 : # if HAVE_SYS_PARAM_H
55 : # include <sys/param.h>
56 : # endif
57 : # if HAVE_SYS_SELECT_H
58 : # include <sys/select.h>
59 : # endif
60 : # if defined(NETWARE) && defined(USE_WINSOCK)
61 : # include <novsock2.h>
62 : # else
63 : # include <sys/socket.h>
64 : # include <netinet/in.h>
65 : # include <netdb.h>
66 : # endif
67 : # if HAVE_ARPA_INET_H
68 : # include <arpa/inet.h>
69 : # endif
70 : #endif
71 :
72 : #include "ext/standard/head.h"
73 : #include "safe_mode.h"
74 : #include "php_string.h"
75 : #include "file.h"
76 :
77 : #if HAVE_PWD_H
78 : # ifdef PHP_WIN32
79 : # include "win32/pwd.h"
80 : # else
81 : # include <pwd.h>
82 : # endif
83 : #endif
84 :
85 : #ifdef HAVE_SYS_TIME_H
86 : # include <sys/time.h>
87 : #endif
88 :
89 : #include "fsock.h"
90 : #include "fopen_wrappers.h"
91 : #include "streamsfuncs.h"
92 : #include "php_globals.h"
93 :
94 : #ifdef HAVE_SYS_FILE_H
95 : # include <sys/file.h>
96 : #endif
97 :
98 : #if MISSING_FCLOSE_DECL
99 : extern int fclose(FILE *);
100 : #endif
101 :
102 : #ifdef HAVE_SYS_MMAN_H
103 : # include <sys/mman.h>
104 : #endif
105 :
106 : #include "scanf.h"
107 : #include "zend_API.h"
108 :
109 : #ifdef ZTS
110 : int file_globals_id;
111 : #else
112 : php_file_globals file_globals;
113 : #endif
114 :
115 : #if defined(HAVE_FNMATCH) && !defined(PHP_WIN32)
116 : # ifndef _GNU_SOURCE
117 : # define _GNU_SOURCE
118 : # endif
119 : # include <fnmatch.h>
120 : #endif
121 :
122 : #ifdef HAVE_WCHAR_H
123 : # include <wchar.h>
124 : #endif
125 :
126 : #ifndef S_ISDIR
127 : # define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
128 : #endif
129 : /* }}} */
130 :
131 : #define PHP_STREAM_TO_ZVAL(stream, arg) \
132 : php_stream_from_zval_no_verify(stream, arg); \
133 : if (stream == NULL) { \
134 : RETURN_FALSE; \
135 : }
136 :
137 : /* {{{ ZTS-stuff / Globals / Prototypes */
138 :
139 : /* sharing globals is *evil* */
140 : static int le_stream_context = FAILURE;
141 :
142 : PHPAPI int php_le_stream_context(void)
143 4377 : {
144 4377 : return le_stream_context;
145 : }
146 : /* }}} */
147 :
148 : /* {{{ Module-Stuff
149 : */
150 : static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
151 3545 : {
152 3545 : php_stream_context *context = (php_stream_context*)rsrc->ptr;
153 3545 : if (context->options) {
154 3545 : zval_ptr_dtor(&context->options);
155 3545 : context->options = NULL;
156 : }
157 3545 : php_stream_context_free(context);
158 3545 : }
159 :
160 : static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
161 17633 : {
162 17633 : FG(pclose_ret) = 0;
163 17633 : FG(user_stream_current_filename) = NULL;
164 17633 : FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
165 17633 : }
166 :
167 : static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
168 17665 : {
169 17665 : }
170 :
171 : PHP_INI_BEGIN()
172 : STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals)
173 : STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateLong, default_socket_timeout, php_file_globals, file_globals)
174 : STD_PHP_INI_ENTRY("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateLong, auto_detect_line_endings, php_file_globals, file_globals)
175 : PHP_INI_END()
176 :
177 : PHP_MINIT_FUNCTION(file)
178 17633 : {
179 17633 : le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
180 :
181 : #ifdef ZTS
182 : ts_allocate_id(&file_globals_id, sizeof(php_file_globals), (ts_allocate_ctor) file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
183 : #else
184 17633 : file_globals_ctor(&file_globals TSRMLS_CC);
185 : #endif
186 :
187 17633 : REGISTER_INI_ENTRIES();
188 :
189 17633 : REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
190 17633 : REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
191 17633 : REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
192 17633 : REGISTER_LONG_CONSTANT("LOCK_SH", PHP_LOCK_SH, CONST_CS | CONST_PERSISTENT);
193 17633 : REGISTER_LONG_CONSTANT("LOCK_EX", PHP_LOCK_EX, CONST_CS | CONST_PERSISTENT);
194 17633 : REGISTER_LONG_CONSTANT("LOCK_UN", PHP_LOCK_UN, CONST_CS | CONST_PERSISTENT);
195 17633 : REGISTER_LONG_CONSTANT("LOCK_NB", PHP_LOCK_NB, CONST_CS | CONST_PERSISTENT);
196 :
197 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT", PHP_STREAM_NOTIFY_CONNECT, CONST_CS | CONST_PERSISTENT);
198 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED", PHP_STREAM_NOTIFY_AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT);
199 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_RESULT", PHP_STREAM_NOTIFY_AUTH_RESULT, CONST_CS | CONST_PERSISTENT);
200 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_MIME_TYPE_IS", PHP_STREAM_NOTIFY_MIME_TYPE_IS, CONST_CS | CONST_PERSISTENT);
201 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FILE_SIZE_IS", PHP_STREAM_NOTIFY_FILE_SIZE_IS, CONST_CS | CONST_PERSISTENT);
202 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_REDIRECTED", PHP_STREAM_NOTIFY_REDIRECTED, CONST_CS | CONST_PERSISTENT);
203 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_PROGRESS", PHP_STREAM_NOTIFY_PROGRESS, CONST_CS | CONST_PERSISTENT);
204 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FAILURE", PHP_STREAM_NOTIFY_FAILURE, CONST_CS | CONST_PERSISTENT);
205 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_COMPLETED", PHP_STREAM_NOTIFY_COMPLETED, CONST_CS | CONST_PERSISTENT);
206 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_RESOLVE", PHP_STREAM_NOTIFY_RESOLVE, CONST_CS | CONST_PERSISTENT);
207 :
208 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_INFO", PHP_STREAM_NOTIFY_SEVERITY_INFO, CONST_CS | CONST_PERSISTENT);
209 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_WARN", PHP_STREAM_NOTIFY_SEVERITY_WARN, CONST_CS | CONST_PERSISTENT);
210 17633 : REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_ERR", PHP_STREAM_NOTIFY_SEVERITY_ERR, CONST_CS | CONST_PERSISTENT);
211 :
212 17633 : REGISTER_LONG_CONSTANT("STREAM_FILTER_READ", PHP_STREAM_FILTER_READ, CONST_CS | CONST_PERSISTENT);
213 17633 : REGISTER_LONG_CONSTANT("STREAM_FILTER_WRITE", PHP_STREAM_FILTER_WRITE, CONST_CS | CONST_PERSISTENT);
214 17633 : REGISTER_LONG_CONSTANT("STREAM_FILTER_ALL", PHP_STREAM_FILTER_ALL, CONST_CS | CONST_PERSISTENT);
215 :
216 17633 : REGISTER_LONG_CONSTANT("STREAM_CLIENT_PERSISTENT", PHP_STREAM_CLIENT_PERSISTENT, CONST_CS | CONST_PERSISTENT);
217 17633 : REGISTER_LONG_CONSTANT("STREAM_CLIENT_ASYNC_CONNECT", PHP_STREAM_CLIENT_ASYNC_CONNECT, CONST_CS | CONST_PERSISTENT);
218 17633 : REGISTER_LONG_CONSTANT("STREAM_CLIENT_CONNECT", PHP_STREAM_CLIENT_CONNECT, CONST_CS | CONST_PERSISTENT);
219 :
220 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_CLIENT", STREAM_CRYPTO_METHOD_SSLv2_CLIENT, CONST_CS|CONST_PERSISTENT);
221 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT);
222 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT);
223 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT);
224 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT);
225 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT);
226 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT);
227 17633 : REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT);
228 :
229 17633 : REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT);
230 17633 : REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT);
231 17633 : REGISTER_LONG_CONSTANT("STREAM_SHUT_RDWR", STREAM_SHUT_RDWR, CONST_CS|CONST_PERSISTENT);
232 :
233 : #ifdef PF_INET
234 17633 : REGISTER_LONG_CONSTANT("STREAM_PF_INET", PF_INET, CONST_CS|CONST_PERSISTENT);
235 : #elif defined(AF_INET)
236 : REGISTER_LONG_CONSTANT("STREAM_PF_INET", AF_INET, CONST_CS|CONST_PERSISTENT);
237 : #endif
238 :
239 : #ifdef PF_INET6
240 17633 : REGISTER_LONG_CONSTANT("STREAM_PF_INET6", PF_INET6, CONST_CS|CONST_PERSISTENT);
241 : #elif defined(AF_INET6)
242 : REGISTER_LONG_CONSTANT("STREAM_PF_INET6", AF_INET6, CONST_CS|CONST_PERSISTENT);
243 : #endif
244 :
245 : #ifdef PF_UNIX
246 17633 : REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", PF_UNIX, CONST_CS|CONST_PERSISTENT);
247 : #elif defined(AF_UNIX)
248 : REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", AF_UNIX, CONST_CS|CONST_PERSISTENT);
249 : #endif
250 :
251 : #ifdef IPPROTO_IP
252 : /* most people will use this one when calling socket() or socketpair() */
253 17633 : REGISTER_LONG_CONSTANT("STREAM_IPPROTO_IP", IPPROTO_IP, CONST_CS|CONST_PERSISTENT);
254 : #endif
255 :
256 : #ifdef IPPROTO_TCP
257 17633 : REGISTER_LONG_CONSTANT("STREAM_IPPROTO_TCP", IPPROTO_TCP, CONST_CS|CONST_PERSISTENT);
258 : #endif
259 :
260 : #ifdef IPPROTO_UDP
261 17633 : REGISTER_LONG_CONSTANT("STREAM_IPPROTO_UDP", IPPROTO_UDP, CONST_CS|CONST_PERSISTENT);
262 : #endif
263 :
264 : #ifdef IPPROTO_ICMP
265 17633 : REGISTER_LONG_CONSTANT("STREAM_IPPROTO_ICMP", IPPROTO_ICMP, CONST_CS|CONST_PERSISTENT);
266 : #endif
267 :
268 : #ifdef IPPROTO_RAW
269 17633 : REGISTER_LONG_CONSTANT("STREAM_IPPROTO_RAW", IPPROTO_RAW, CONST_CS|CONST_PERSISTENT);
270 : #endif
271 :
272 17633 : REGISTER_LONG_CONSTANT("STREAM_SOCK_STREAM", SOCK_STREAM, CONST_CS|CONST_PERSISTENT);
273 17633 : REGISTER_LONG_CONSTANT("STREAM_SOCK_DGRAM", SOCK_DGRAM, CONST_CS|CONST_PERSISTENT);
274 :
275 : #ifdef SOCK_RAW
276 17633 : REGISTER_LONG_CONSTANT("STREAM_SOCK_RAW", SOCK_RAW, CONST_CS|CONST_PERSISTENT);
277 : #endif
278 :
279 : #ifdef SOCK_SEQPACKET
280 17633 : REGISTER_LONG_CONSTANT("STREAM_SOCK_SEQPACKET", SOCK_SEQPACKET, CONST_CS|CONST_PERSISTENT);
281 : #endif
282 :
283 : #ifdef SOCK_RDM
284 17633 : REGISTER_LONG_CONSTANT("STREAM_SOCK_RDM", SOCK_RDM, CONST_CS|CONST_PERSISTENT);
285 : #endif
286 :
287 17633 : REGISTER_LONG_CONSTANT("STREAM_PEEK", STREAM_PEEK, CONST_CS | CONST_PERSISTENT);
288 17633 : REGISTER_LONG_CONSTANT("STREAM_OOB", STREAM_OOB, CONST_CS | CONST_PERSISTENT);
289 :
290 17633 : REGISTER_LONG_CONSTANT("STREAM_SERVER_BIND", STREAM_XPORT_BIND, CONST_CS | CONST_PERSISTENT);
291 17633 : REGISTER_LONG_CONSTANT("STREAM_SERVER_LISTEN", STREAM_XPORT_LISTEN, CONST_CS | CONST_PERSISTENT);
292 :
293 17633 : REGISTER_LONG_CONSTANT("FILE_USE_INCLUDE_PATH", PHP_FILE_USE_INCLUDE_PATH, CONST_CS | CONST_PERSISTENT);
294 17633 : REGISTER_LONG_CONSTANT("FILE_IGNORE_NEW_LINES", PHP_FILE_IGNORE_NEW_LINES, CONST_CS | CONST_PERSISTENT);
295 17633 : REGISTER_LONG_CONSTANT("FILE_SKIP_EMPTY_LINES", PHP_FILE_SKIP_EMPTY_LINES, CONST_CS | CONST_PERSISTENT);
296 17633 : REGISTER_LONG_CONSTANT("FILE_APPEND", PHP_FILE_APPEND, CONST_CS | CONST_PERSISTENT);
297 17633 : REGISTER_LONG_CONSTANT("FILE_NO_DEFAULT_CONTEXT", PHP_FILE_NO_DEFAULT_CONTEXT, CONST_CS | CONST_PERSISTENT);
298 :
299 17633 : REGISTER_LONG_CONSTANT("FILE_TEXT", 0, CONST_CS | CONST_PERSISTENT);
300 17633 : REGISTER_LONG_CONSTANT("FILE_BINARY", 0, CONST_CS | CONST_PERSISTENT);
301 :
302 : #ifdef HAVE_FNMATCH
303 17633 : REGISTER_LONG_CONSTANT("FNM_NOESCAPE", FNM_NOESCAPE, CONST_CS | CONST_PERSISTENT);
304 17633 : REGISTER_LONG_CONSTANT("FNM_PATHNAME", FNM_PATHNAME, CONST_CS | CONST_PERSISTENT);
305 17633 : REGISTER_LONG_CONSTANT("FNM_PERIOD", FNM_PERIOD, CONST_CS | CONST_PERSISTENT);
306 : # ifdef FNM_CASEFOLD /* a GNU extension */ /* TODO emulate if not available */
307 17633 : REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_CS | CONST_PERSISTENT);
308 : # endif
309 : #endif
310 :
311 17633 : return SUCCESS;
312 : }
313 : /* }}} */
314 :
315 : PHP_MSHUTDOWN_FUNCTION(file) /* {{{ */
316 17665 : {
317 : #ifndef ZTS
318 17665 : file_globals_dtor(&file_globals TSRMLS_CC);
319 : #endif
320 17665 : return SUCCESS;
321 : }
322 : /* }}} */
323 :
324 : static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
325 :
326 : /* {{{ proto bool flock(resource fp, int operation [, int &wouldblock])
327 : Portable file locking */
328 : PHP_FUNCTION(flock)
329 193 : {
330 193 : zval *arg1, *arg3 = NULL;
331 : int act;
332 : php_stream *stream;
333 193 : long operation = 0;
334 :
335 193 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) {
336 11 : return;
337 : }
338 :
339 182 : PHP_STREAM_TO_ZVAL(stream, &arg1);
340 :
341 180 : act = operation & 3;
342 180 : if (act < 1 || act > 3) {
343 5 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal operation argument");
344 5 : RETURN_FALSE;
345 : }
346 :
347 175 : if (arg3 && PZVAL_IS_REF(arg3)) {
348 144 : convert_to_long_ex(&arg3);
349 144 : Z_LVAL_P(arg3) = 0;
350 : }
351 :
352 : /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
353 175 : act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
354 175 : if (php_stream_lock(stream, act)) {
355 12 : if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
356 0 : Z_LVAL_P(arg3) = 1;
357 : }
358 12 : RETURN_FALSE;
359 : }
360 163 : RETURN_TRUE;
361 : }
362 : /* }}} */
363 :
364 : #define PHP_META_UNSAFE ".\\+*?[^]$() "
365 :
366 : /* {{{ proto array get_meta_tags(string filename [, bool use_include_path])
367 : Extracts all meta tag content attributes from a file and returns an array */
368 : PHP_FUNCTION(get_meta_tags)
369 8 : {
370 : char *filename;
371 : int filename_len;
372 8 : zend_bool use_include_path = 0;
373 8 : int in_tag = 0, done = 0;
374 8 : int looking_for_val = 0, have_name = 0, have_content = 0;
375 8 : int saw_name = 0, saw_content = 0;
376 8 : char *name = NULL, *value = NULL, *temp = NULL;
377 : php_meta_tags_token tok, tok_last;
378 : php_meta_tags_data md;
379 :
380 : /* Initiailize our structure */
381 8 : memset(&md, 0, sizeof(md));
382 :
383 : /* Parse arguments */
384 8 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &filename, &filename_len, &use_include_path) == FAILURE) {
385 0 : return;
386 : }
387 :
388 8 : md.stream = php_stream_open_wrapper(filename, "rb",
389 : (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
390 : NULL);
391 8 : if (!md.stream) {
392 0 : RETURN_FALSE;
393 : }
394 :
395 8 : array_init(return_value);
396 :
397 8 : tok_last = TOK_EOF;
398 :
399 220 : while (!done && (tok = php_next_meta_token(&md TSRMLS_CC)) != TOK_EOF) {
400 204 : if (tok == TOK_ID) {
401 45 : if (tok_last == TOK_OPENTAG) {
402 17 : md.in_meta = !strcasecmp("meta", md.token_data);
403 30 : } else if (tok_last == TOK_SLASH && in_tag) {
404 2 : if (strcasecmp("head", md.token_data) == 0) {
405 : /* We are done here! */
406 2 : done = 1;
407 : }
408 26 : } else if (tok_last == TOK_EQUAL && looking_for_val) {
409 0 : if (saw_name) {
410 0 : STR_FREE(name);
411 : /* Get the NAME attr (Single word attr, non-quoted) */
412 0 : temp = name = estrndup(md.token_data, md.token_len);
413 :
414 0 : while (temp && *temp) {
415 0 : if (strchr(PHP_META_UNSAFE, *temp)) {
416 0 : *temp = '_';
417 : }
418 0 : temp++;
419 : }
420 :
421 0 : have_name = 1;
422 0 : } else if (saw_content) {
423 0 : STR_FREE(value);
424 : /* Get the CONTENT attr (Single word attr, non-quoted) */
425 0 : if (PG(magic_quotes_runtime)) {
426 0 : value = php_addslashes(md.token_data, 0, &md.token_len, 0 TSRMLS_CC);
427 : } else {
428 0 : value = estrndup(md.token_data, md.token_len);
429 : }
430 :
431 0 : have_content = 1;
432 : }
433 :
434 0 : looking_for_val = 0;
435 : } else {
436 26 : if (md.in_meta) {
437 26 : if (strcasecmp("name", md.token_data) == 0) {
438 13 : saw_name = 1;
439 13 : saw_content = 0;
440 13 : looking_for_val = 1;
441 13 : } else if (strcasecmp("content", md.token_data) == 0) {
442 13 : saw_name = 0;
443 13 : saw_content = 1;
444 13 : looking_for_val = 1;
445 : }
446 : }
447 : }
448 185 : } else if (tok == TOK_STRING && tok_last == TOK_EQUAL && looking_for_val) {
449 26 : if (saw_name) {
450 13 : STR_FREE(name);
451 : /* Get the NAME attr (Quoted single/double) */
452 13 : temp = name = estrndup(md.token_data, md.token_len);
453 :
454 136 : while (temp && *temp) {
455 110 : if (strchr(PHP_META_UNSAFE, *temp)) {
456 2 : *temp = '_';
457 : }
458 110 : temp++;
459 : }
460 :
461 13 : have_name = 1;
462 13 : } else if (saw_content) {
463 13 : STR_FREE(value);
464 : /* Get the CONTENT attr (Single word attr, non-quoted) */
465 13 : if (PG(magic_quotes_runtime)) {
466 0 : value = php_addslashes(md.token_data, 0, &md.token_len, 0 TSRMLS_CC);
467 : } else {
468 13 : value = estrndup(md.token_data, md.token_len);
469 : }
470 :
471 13 : have_content = 1;
472 : }
473 :
474 26 : looking_for_val = 0;
475 133 : } else if (tok == TOK_OPENTAG) {
476 25 : if (looking_for_val) {
477 0 : looking_for_val = 0;
478 0 : have_name = saw_name = 0;
479 0 : have_content = saw_content = 0;
480 : }
481 25 : in_tag = 1;
482 108 : } else if (tok == TOK_CLOSETAG) {
483 13 : if (have_name) {
484 : /* For BC */
485 10 : php_strtolower(name, strlen(name));
486 10 : if (have_content) {
487 10 : add_assoc_string(return_value, name, value, 1);
488 : } else {
489 0 : add_assoc_string(return_value, name, "", 1);
490 : }
491 :
492 10 : efree(name);
493 10 : STR_FREE(value);
494 3 : } else if (have_content) {
495 0 : efree(value);
496 : }
497 :
498 13 : name = value = NULL;
499 :
500 : /* Reset all of our flags */
501 13 : in_tag = looking_for_val = 0;
502 13 : have_name = saw_name = 0;
503 13 : have_content = saw_content = 0;
504 13 : md.in_meta = 0;
505 : }
506 :
507 204 : tok_last = tok;
508 :
509 204 : if (md.token_data)
510 71 : efree(md.token_data);
511 :
512 204 : md.token_data = NULL;
513 : }
514 :
515 8 : STR_FREE(value);
516 8 : STR_FREE(name);
517 8 : php_stream_close(md.stream);
518 : }
519 : /* }}} */
520 :
521 : /* {{{ proto string file_get_contents(string filename [, bool use_include_path [, resource context [, long offset [, long maxlen]]]])
522 : Read the entire file into a string */
523 : PHP_FUNCTION(file_get_contents)
524 2300 : {
525 : char *filename;
526 : int filename_len;
527 : char *contents;
528 2300 : zend_bool use_include_path = 0;
529 : php_stream *stream;
530 : int len;
531 2300 : long offset = -1;
532 2300 : long maxlen = PHP_STREAM_COPY_ALL;
533 2300 : zval *zcontext = NULL;
534 2300 : php_stream_context *context = NULL;
535 :
536 : /* Parse arguments */
537 2300 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
538 61 : return;
539 : }
540 :
541 2239 : if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
542 5 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
543 5 : RETURN_FALSE;
544 : }
545 :
546 2234 : context = php_stream_context_from_zval(zcontext, 0);
547 :
548 2234 : stream = php_stream_open_wrapper_ex(filename, "rb",
549 : (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
550 : NULL, context);
551 2234 : if (!stream) {
552 50 : RETURN_FALSE;
553 : }
554 :
555 2184 : if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
556 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
557 1 : php_stream_close(stream);
558 1 : RETURN_FALSE;
559 : }
560 :
561 : /* uses mmap if possible */
562 2183 : if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
563 :
564 1809 : if (PG(magic_quotes_runtime)) {
565 3 : contents = php_addslashes(contents, len, &len, 1 TSRMLS_CC); /* 1 = free source string */
566 : }
567 :
568 1809 : RETVAL_STRINGL(contents, len, 0);
569 374 : } else if (len == 0) {
570 374 : RETVAL_EMPTY_STRING();
571 : } else {
572 0 : RETVAL_FALSE;
573 : }
574 :
575 2183 : php_stream_close(stream);
576 : }
577 : /* }}} */
578 :
579 : /* {{{ proto int file_put_contents(string file, mixed data [, int flags [, resource context]])
580 : Write/Create a file with contents data and return the number of bytes written */
581 : PHP_FUNCTION(file_put_contents)
582 22485 : {
583 : php_stream *stream;
584 : char *filename;
585 : int filename_len;
586 : zval *data;
587 22485 : int numbytes = 0;
588 22485 : long flags = 0;
589 22485 : zval *zcontext = NULL;
590 22485 : php_stream_context *context = NULL;
591 22485 : php_stream *srcstream = NULL;
592 22485 : char mode[3] = "wb";
593 :
594 22485 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|lr!", &filename, &filename_len, &data, &flags, &zcontext) == FAILURE) {
595 29 : return;
596 : }
597 :
598 22456 : if (Z_TYPE_P(data) == IS_RESOURCE) {
599 1 : php_stream_from_zval(srcstream, &data);
600 : }
601 :
602 22455 : context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
603 :
604 22455 : if (flags & PHP_FILE_APPEND) {
605 8 : mode[0] = 'a';
606 22447 : } else if (flags & LOCK_EX) {
607 : /* check to make sure we are dealing with a regular file */
608 0 : if (php_memnstr(filename, "://", sizeof("://") - 1, filename + filename_len)) {
609 0 : if (strncasecmp(filename, "file://", sizeof("file://") - 1)) {
610 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks may only be set for regular files");
611 0 : RETURN_FALSE;
612 : }
613 : }
614 0 : mode[0] = 'c';
615 : }
616 22455 : mode[2] = '\0';
617 :
618 22455 : stream = php_stream_open_wrapper_ex(filename, mode, ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
619 22455 : if (stream == NULL) {
620 21 : RETURN_FALSE;
621 : }
622 :
623 22434 : if (flags & LOCK_EX && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) {
624 0 : php_stream_close(stream);
625 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks are not supported for this stream");
626 0 : RETURN_FALSE;
627 : }
628 :
629 22434 : if (mode[0] == 'c') {
630 0 : php_stream_truncate_set_size(stream, 0);
631 : }
632 :
633 22434 : switch (Z_TYPE_P(data)) {
634 : case IS_RESOURCE: {
635 : size_t len;
636 0 : if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
637 0 : numbytes = -1;
638 : } else {
639 0 : numbytes = len;
640 : }
641 0 : break;
642 : }
643 : case IS_NULL:
644 : case IS_LONG:
645 : case IS_DOUBLE:
646 : case IS_BOOL:
647 : case IS_CONSTANT:
648 27 : convert_to_string_ex(&data);
649 :
650 : case IS_STRING:
651 22424 : if (Z_STRLEN_P(data)) {
652 18311 : numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
653 18311 : if (numbytes != Z_STRLEN_P(data)) {
654 0 : 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));
655 0 : numbytes = -1;
656 : }
657 : }
658 22424 : break;
659 :
660 : case IS_ARRAY:
661 6 : if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
662 : int bytes_written;
663 : zval **tmp;
664 : HashPosition pos;
665 :
666 5 : zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
667 75 : while (zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &tmp, &pos) == SUCCESS) {
668 65 : if (Z_TYPE_PP(tmp) != IS_STRING) {
669 12 : SEPARATE_ZVAL(tmp);
670 12 : convert_to_string(*tmp);
671 : }
672 65 : if (Z_STRLEN_PP(tmp)) {
673 64 : numbytes += Z_STRLEN_PP(tmp);
674 64 : bytes_written = php_stream_write(stream, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
675 64 : if (bytes_written < 0 || bytes_written != Z_STRLEN_PP(tmp)) {
676 0 : if (bytes_written < 0) {
677 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN_PP(tmp), filename);
678 : } else {
679 0 : 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));
680 : }
681 0 : numbytes = -1;
682 0 : break;
683 : }
684 : }
685 65 : zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos);
686 : }
687 : }
688 6 : break;
689 :
690 : case IS_OBJECT:
691 4 : if (Z_OBJ_HT_P(data) != NULL) {
692 : zval out;
693 :
694 4 : if (zend_std_cast_object_tostring(data, &out, IS_STRING TSRMLS_CC) == SUCCESS) {
695 2 : numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out));
696 2 : if (numbytes != Z_STRLEN(out)) {
697 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out));
698 0 : numbytes = -1;
699 : }
700 2 : zval_dtor(&out);
701 2 : break;
702 : }
703 : }
704 : default:
705 2 : numbytes = -1;
706 : break;
707 : }
708 22434 : php_stream_close(stream);
709 :
710 22434 : if (numbytes < 0) {
711 2 : RETURN_FALSE;
712 : }
713 :
714 22432 : RETURN_LONG(numbytes);
715 : }
716 : /* }}} */
717 :
718 : #define PHP_FILE_BUF_SIZE 80
719 :
720 : /* {{{ proto array file(string filename [, int flags[, resource context]])
721 : Read entire file into an array */
722 : PHP_FUNCTION(file)
723 233 : {
724 : char *filename;
725 : int filename_len;
726 233 : char *slashed, *target_buf=NULL, *p, *s, *e;
727 233 : register int i = 0;
728 : int target_len, len;
729 233 : char eol_marker = '\n';
730 233 : long flags = 0;
731 : zend_bool use_include_path;
732 : zend_bool include_new_line;
733 : zend_bool skip_blank_lines;
734 : php_stream *stream;
735 233 : zval *zcontext = NULL;
736 233 : php_stream_context *context = NULL;
737 :
738 : /* Parse arguments */
739 233 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr!", &filename, &filename_len, &flags, &zcontext) == FAILURE) {
740 45 : return;
741 : }
742 188 : if (flags < 0 || flags > (PHP_FILE_USE_INCLUDE_PATH | PHP_FILE_IGNORE_NEW_LINES | PHP_FILE_SKIP_EMPTY_LINES | PHP_FILE_NO_DEFAULT_CONTEXT)) {
743 12 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%ld' flag is not supported", flags);
744 12 : RETURN_FALSE;
745 : }
746 :
747 176 : use_include_path = flags & PHP_FILE_USE_INCLUDE_PATH;
748 176 : include_new_line = !(flags & PHP_FILE_IGNORE_NEW_LINES);
749 176 : skip_blank_lines = flags & PHP_FILE_SKIP_EMPTY_LINES;
750 :
751 176 : context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
752 :
753 176 : stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
754 176 : if (!stream) {
755 32 : RETURN_FALSE;
756 : }
757 :
758 : /* Initialize return array */
759 144 : array_init(return_value);
760 :
761 144 : if ((target_len = php_stream_copy_to_mem(stream, &target_buf, PHP_STREAM_COPY_ALL, 0))) {
762 141 : s = target_buf;
763 141 : e = target_buf + target_len;
764 :
765 141 : if (!(p = php_stream_locate_eol(stream, target_buf, target_len TSRMLS_CC))) {
766 20 : p = e;
767 20 : goto parse_eol;
768 : }
769 :
770 121 : if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
771 0 : eol_marker = '\r';
772 : }
773 :
774 : /* for performance reasons the code is duplicated, so that the if (include_new_line)
775 : * will not need to be done for every single line in the file. */
776 121 : if (include_new_line) {
777 : do {
778 1658 : p++;
779 1734 : parse_eol:
780 1734 : if (PG(magic_quotes_runtime)) {
781 : /* s is in target_buf which is freed at the end of the function */
782 0 : slashed = php_addslashes(s, (p-s), &len, 0 TSRMLS_CC);
783 0 : add_index_stringl(return_value, i++, slashed, len, 0);
784 : } else {
785 1734 : add_index_stringl(return_value, i++, estrndup(s, p-s), p-s, 0);
786 : }
787 1734 : s = p;
788 1734 : } while ((p = memchr(p, eol_marker, (e-p))));
789 : } else {
790 : do {
791 47 : int windows_eol = 0;
792 47 : if (p != target_buf && eol_marker == '\n' && *(p - 1) == '\r') {
793 6 : windows_eol++;
794 : }
795 47 : if (skip_blank_lines && !(p-s-windows_eol)) {
796 1 : s = ++p;
797 1 : continue;
798 : }
799 46 : if (PG(magic_quotes_runtime)) {
800 : /* s is in target_buf which is freed at the end of the function */
801 0 : slashed = php_addslashes(s, (p-s-windows_eol), &len, 0 TSRMLS_CC);
802 0 : add_index_stringl(return_value, i++, slashed, len, 0);
803 : } else {
804 46 : add_index_stringl(return_value, i++, estrndup(s, p-s-windows_eol), p-s-windows_eol, 0);
805 : }
806 46 : s = ++p;
807 47 : } while ((p = memchr(p, eol_marker, (e-p))));
808 : }
809 :
810 : /* handle any left overs of files without new lines */
811 197 : if (s != e) {
812 56 : p = e;
813 56 : goto parse_eol;
814 : }
815 : }
816 :
817 144 : if (target_buf) {
818 141 : efree(target_buf);
819 : }
820 144 : php_stream_close(stream);
821 : }
822 : /* }}} */
823 :
824 : /* {{{ proto string tempnam(string dir, string prefix)
825 : Create a unique filename in a directory */
826 : PHP_FUNCTION(tempnam)
827 701 : {
828 : char *dir, *prefix;
829 : int dir_len, prefix_len;
830 : size_t p_len;
831 : char *opened_path;
832 : char *p;
833 : int fd;
834 :
835 701 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
836 9 : return;
837 : }
838 :
839 692 : if (PG(safe_mode) &&(!php_checkuid(dir, NULL, CHECKUID_ALLOW_ONLY_DIR))) {
840 0 : RETURN_FALSE;
841 : }
842 :
843 692 : if (php_check_open_basedir(dir TSRMLS_CC)) {
844 7 : RETURN_FALSE;
845 : }
846 :
847 685 : php_basename(prefix, prefix_len, NULL, 0, &p, &p_len TSRMLS_CC);
848 685 : if (p_len > 64) {
849 0 : p[63] = '\0';
850 : }
851 :
852 685 : RETVAL_FALSE;
853 :
854 685 : if ((fd = php_open_temporary_fd(dir, p, &opened_path TSRMLS_CC)) >= 0) {
855 685 : close(fd);
856 685 : RETVAL_STRING(opened_path, 0);
857 : }
858 685 : efree(p);
859 : }
860 : /* }}} */
861 :
862 : /* {{{ proto resource tmpfile(void)
863 : Create a temporary file that will be deleted automatically after use */
864 : PHP_NAMED_FUNCTION(php_if_tmpfile)
865 68 : {
866 : php_stream *stream;
867 :
868 68 : if (zend_parse_parameters_none() == FAILURE) {
869 0 : return;
870 : }
871 :
872 68 : stream = php_stream_fopen_tmpfile();
873 :
874 68 : if (stream) {
875 68 : php_stream_to_zval(stream, return_value);
876 : } else {
877 0 : RETURN_FALSE;
878 : }
879 : }
880 : /* }}} */
881 :
882 : /* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]])
883 : Open a file or a URL and return a file pointer */
884 : PHP_NAMED_FUNCTION(php_if_fopen)
885 22113 : {
886 : char *filename, *mode;
887 : int filename_len, mode_len;
888 22113 : zend_bool use_include_path = 0;
889 22113 : zval *zcontext = NULL;
890 : php_stream *stream;
891 22113 : php_stream_context *context = NULL;
892 :
893 22113 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
894 43 : RETURN_FALSE;
895 : }
896 :
897 22070 : context = php_stream_context_from_zval(zcontext, 0);
898 :
899 22070 : stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
900 :
901 22069 : if (stream == NULL) {
902 86 : RETURN_FALSE;
903 : }
904 :
905 21983 : php_stream_to_zval(stream, return_value);
906 : }
907 : /* }}} */
908 :
909 : /* {{{ proto bool fclose(resource fp)
910 : Close an open file pointer */
911 : PHPAPI PHP_FUNCTION(fclose)
912 39378 : {
913 : zval *arg1;
914 : php_stream *stream;
915 :
916 39378 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
917 31 : RETURN_FALSE;
918 : }
919 :
920 39347 : PHP_STREAM_TO_ZVAL(stream, &arg1);
921 :
922 39346 : if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
923 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid stream resource", stream->rsrc_id);
924 0 : RETURN_FALSE;
925 : }
926 :
927 39346 : if (!stream->is_persistent) {
928 39346 : zend_list_delete(stream->rsrc_id);
929 : } else {
930 0 : php_stream_pclose(stream);
931 : }
932 :
933 39345 : RETURN_TRUE;
934 : }
935 : /* }}} */
936 :
937 : /* {{{ proto resource popen(string command, string mode)
938 : Execute a command and open either a read or a write pipe to it */
939 : PHP_FUNCTION(popen)
940 8 : {
941 : char *command, *mode;
942 : int command_len, mode_len;
943 : FILE *fp;
944 : php_stream *stream;
945 8 : char *posix_mode, *b, *buf = 0, *tmp;
946 :
947 8 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &command, &command_len, &mode, &mode_len) == FAILURE) {
948 2 : return;
949 : }
950 :
951 6 : posix_mode = estrndup(mode, mode_len);
952 : #ifndef PHP_WIN32
953 : {
954 6 : char *z = memchr(posix_mode, 'b', mode_len);
955 6 : if (z) {
956 1 : memmove(z, z + 1, mode_len - (z - posix_mode));
957 : }
958 : }
959 : #endif
960 6 : if (PG(safe_mode)){
961 0 : b = strchr(command, ' ');
962 0 : if (!b) {
963 0 : b = strrchr(command, '/');
964 : } else {
965 : char *c;
966 :
967 0 : c = command;
968 0 : while((*b != '/') && (b != c)) {
969 0 : b--;
970 : }
971 0 : if (b == c) {
972 0 : b = NULL;
973 : }
974 : }
975 :
976 0 : if (b) {
977 0 : spprintf(&buf, 0, "%s%s", PG(safe_mode_exec_dir), b);
978 : } else {
979 0 : spprintf(&buf, 0, "%s/%s", PG(safe_mode_exec_dir), command);
980 : }
981 :
982 0 : tmp = php_escape_shell_cmd(buf);
983 0 : fp = VCWD_POPEN(tmp, posix_mode);
984 0 : efree(tmp);
985 :
986 0 : if (!fp) {
987 0 : php_error_docref2(NULL TSRMLS_CC, buf, posix_mode, E_WARNING, "%s", strerror(errno));
988 0 : efree(posix_mode);
989 0 : efree(buf);
990 0 : RETURN_FALSE;
991 : }
992 :
993 0 : efree(buf);
994 :
995 : } else {
996 6 : fp = VCWD_POPEN(command, posix_mode);
997 6 : if (!fp) {
998 1 : php_error_docref2(NULL TSRMLS_CC, command, posix_mode, E_WARNING, "%s", strerror(errno));
999 1 : efree(posix_mode);
1000 1 : RETURN_FALSE;
1001 : }
1002 : }
1003 5 : stream = php_stream_fopen_from_pipe(fp, mode);
1004 :
1005 5 : if (stream == NULL) {
1006 0 : php_error_docref2(NULL TSRMLS_CC, command, mode, E_WARNING, "%s", strerror(errno));
1007 0 : RETVAL_FALSE;
1008 : } else {
1009 5 : php_stream_to_zval(stream, return_value);
1010 : }
1011 :
1012 5 : efree(posix_mode);
1013 : }
1014 : /* }}} */
1015 :
1016 : /* {{{ proto int pclose(resource fp)
1017 : Close a file pointer opened by popen() */
1018 : PHP_FUNCTION(pclose)
1019 37 : {
1020 : zval *arg1;
1021 : php_stream *stream;
1022 :
1023 37 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1024 32 : RETURN_FALSE;
1025 : }
1026 :
1027 5 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1028 :
1029 5 : zend_list_delete(stream->rsrc_id);
1030 5 : RETURN_LONG(FG(pclose_ret));
1031 : }
1032 : /* }}} */
1033 :
1034 : /* {{{ proto bool feof(resource fp)
1035 : Test for end-of-file on a file pointer */
1036 : PHPAPI PHP_FUNCTION(feof)
1037 1072528 : {
1038 : zval *arg1;
1039 : php_stream *stream;
1040 :
1041 1072528 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1042 13 : RETURN_FALSE;
1043 : }
1044 :
1045 1072515 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1046 :
1047 1072488 : if (php_stream_eof(stream)) {
1048 12824 : RETURN_TRUE;
1049 : } else {
1050 1059664 : RETURN_FALSE;
1051 : }
1052 : }
1053 : /* }}} */
1054 :
1055 : /* {{{ proto string fgets(resource fp[, int length])
1056 : Get a line from file pointer */
1057 : PHPAPI PHP_FUNCTION(fgets)
1058 1046445 : {
1059 : zval *arg1;
1060 1046445 : long len = 1024;
1061 1046445 : char *buf = NULL;
1062 1046445 : int argc = ZEND_NUM_ARGS();
1063 1046445 : size_t line_len = 0;
1064 : php_stream *stream;
1065 :
1066 1046445 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &len) == FAILURE) {
1067 13 : RETURN_FALSE;
1068 : }
1069 :
1070 1046432 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1071 :
1072 1046429 : if (argc == 1) {
1073 : /* ask streams to give us a buffer of an appropriate size */
1074 1041971 : buf = php_stream_get_line(stream, NULL, 0, &line_len);
1075 1041971 : if (buf == NULL) {
1076 9482 : goto exit_failed;
1077 : }
1078 4458 : } else if (argc > 1) {
1079 4458 : if (len <= 0) {
1080 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
1081 2 : RETURN_FALSE;
1082 : }
1083 :
1084 4456 : buf = ecalloc(len + 1, sizeof(char));
1085 4456 : if (php_stream_get_line(stream, buf, len, &line_len) == NULL) {
1086 2 : goto exit_failed;
1087 : }
1088 : }
1089 :
1090 1036943 : if (PG(magic_quotes_runtime)) {
1091 0 : Z_STRVAL_P(return_value) = php_addslashes(buf, line_len, &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
1092 0 : Z_TYPE_P(return_value) = IS_STRING;
1093 : } else {
1094 1036943 : ZVAL_STRINGL(return_value, buf, line_len, 0);
1095 : /* resize buffer if it's much larger than the result.
1096 : * Only needed if the user requested a buffer size. */
1097 1036943 : if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) {
1098 3947 : Z_STRVAL_P(return_value) = erealloc(buf, line_len + 1);
1099 : }
1100 : }
1101 1036943 : return;
1102 :
1103 9484 : exit_failed:
1104 9484 : RETVAL_FALSE;
1105 9484 : if (buf) {
1106 2 : efree(buf);
1107 : }
1108 : }
1109 : /* }}} */
1110 :
1111 : /* {{{ proto string fgetc(resource fp)
1112 : Get a character from file pointer */
1113 : PHPAPI PHP_FUNCTION(fgetc)
1114 377 : {
1115 : zval *arg1;
1116 : char buf[2];
1117 : int result;
1118 : php_stream *stream;
1119 :
1120 377 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1121 11 : RETURN_FALSE;
1122 : }
1123 :
1124 366 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1125 :
1126 365 : result = php_stream_getc(stream);
1127 :
1128 365 : if (result == EOF) {
1129 15 : RETVAL_FALSE;
1130 : } else {
1131 350 : buf[0] = result;
1132 350 : buf[1] = '\0';
1133 :
1134 350 : RETURN_STRINGL(buf, 1, 1);
1135 : }
1136 : }
1137 : /* }}} */
1138 :
1139 : /* {{{ proto string fgetss(resource fp [, int length [, string allowable_tags]])
1140 : Get a line from file pointer and strip HTML tags */
1141 : PHPAPI PHP_FUNCTION(fgetss)
1142 299 : {
1143 : zval *fd;
1144 299 : long bytes = 0;
1145 299 : size_t len = 0;
1146 : size_t actual_len, retval_len;
1147 299 : char *buf = NULL, *retval;
1148 : php_stream *stream;
1149 299 : char *allowed_tags=NULL;
1150 299 : int allowed_tags_len=0;
1151 :
1152 299 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) {
1153 9 : RETURN_FALSE;
1154 : }
1155 :
1156 290 : PHP_STREAM_TO_ZVAL(stream, &fd);
1157 :
1158 288 : if (ZEND_NUM_ARGS() >= 2) {
1159 227 : if (bytes <= 0) {
1160 4 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
1161 4 : RETURN_FALSE;
1162 : }
1163 :
1164 223 : len = (size_t) bytes;
1165 223 : buf = safe_emalloc(sizeof(char), (len + 1), 0);
1166 : /*needed because recv doesnt set null char at end*/
1167 223 : memset(buf, 0, len + 1);
1168 : }
1169 :
1170 284 : if ((retval = php_stream_get_line(stream, buf, len, &actual_len)) == NULL) {
1171 52 : if (buf != NULL) {
1172 21 : efree(buf);
1173 : }
1174 52 : RETURN_FALSE;
1175 : }
1176 :
1177 232 : retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len);
1178 :
1179 232 : RETURN_STRINGL(retval, retval_len, 0);
1180 : }
1181 : /* }}} */
1182 :
1183 : /* {{{ proto mixed fscanf(resource stream, string format [, string ...])
1184 : Implements a mostly ANSI compatible fscanf() */
1185 : PHP_FUNCTION(fscanf)
1186 8723 : {
1187 8723 : int result, format_len, type, argc = 0;
1188 8723 : zval ***args = NULL;
1189 : zval *file_handle;
1190 : char *buf, *format;
1191 : size_t len;
1192 : void *what;
1193 :
1194 8723 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs*", &file_handle, &format, &format_len, &args, &argc) == FAILURE) {
1195 5 : return;
1196 : }
1197 :
1198 8718 : what = zend_fetch_resource(&file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, php_file_le_stream(), php_file_le_pstream());
1199 :
1200 : /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
1201 : * with a leak if we have an invalid filehandle. This needs changing
1202 : * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */
1203 8718 : if (!what) {
1204 1 : if (args) {
1205 0 : efree(args);
1206 : }
1207 1 : RETURN_FALSE;
1208 : }
1209 :
1210 8717 : buf = php_stream_get_line((php_stream *) what, NULL, 0, &len);
1211 8717 : if (buf == NULL) {
1212 893 : if (args) {
1213 1 : efree(args);
1214 : }
1215 893 : RETURN_FALSE;
1216 : }
1217 :
1218 7824 : result = php_sscanf_internal(buf, format, argc, args, 0, &return_value TSRMLS_CC);
1219 :
1220 7824 : if (args) {
1221 7 : efree(args);
1222 : }
1223 7824 : efree(buf);
1224 :
1225 7824 : if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
1226 0 : WRONG_PARAM_COUNT;
1227 : }
1228 : }
1229 : /* }}} */
1230 :
1231 : /* {{{ proto int fwrite(resource fp, string str [, int length])
1232 : Binary-safe file write */
1233 : PHPAPI PHP_FUNCTION(fwrite)
1234 74779 : {
1235 : zval *arg1;
1236 : char *arg2;
1237 : int arg2len;
1238 : int ret;
1239 : int num_bytes;
1240 74779 : long arg3 = 0;
1241 74779 : char *buffer = NULL;
1242 : php_stream *stream;
1243 :
1244 74779 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &arg2, &arg2len, &arg3) == FAILURE) {
1245 35 : RETURN_FALSE;
1246 : }
1247 :
1248 74744 : if (ZEND_NUM_ARGS() == 2) {
1249 18265 : num_bytes = arg2len;
1250 : } else {
1251 56479 : num_bytes = MAX(0, MIN((int)arg3, arg2len));
1252 : }
1253 :
1254 74744 : if (!num_bytes) {
1255 31 : RETURN_LONG(0);
1256 : }
1257 :
1258 74713 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1259 :
1260 74712 : if (PG(magic_quotes_runtime)) {
1261 0 : buffer = estrndup(arg2, num_bytes);
1262 0 : php_stripslashes(buffer, &num_bytes TSRMLS_CC);
1263 : }
1264 :
1265 74712 : ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes);
1266 74712 : if (buffer) {
1267 0 : efree(buffer);
1268 : }
1269 :
1270 74712 : RETURN_LONG(ret);
1271 : }
1272 : /* }}} */
1273 :
1274 : /* {{{ proto bool fflush(resource fp)
1275 : Flushes output */
1276 : PHPAPI PHP_FUNCTION(fflush)
1277 229 : {
1278 : zval *arg1;
1279 : int ret;
1280 : php_stream *stream;
1281 :
1282 229 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1283 8 : RETURN_FALSE;
1284 : }
1285 :
1286 221 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1287 :
1288 221 : ret = php_stream_flush(stream);
1289 221 : if (ret) {
1290 0 : RETURN_FALSE;
1291 : }
1292 221 : RETURN_TRUE;
1293 : }
1294 : /* }}} */
1295 :
1296 : /* {{{ proto bool rewind(resource fp)
1297 : Rewind the position of a file pointer */
1298 : PHPAPI PHP_FUNCTION(rewind)
1299 3390 : {
1300 : zval *arg1;
1301 : php_stream *stream;
1302 :
1303 3390 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1304 13 : RETURN_FALSE;
1305 : }
1306 :
1307 3377 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1308 :
1309 3376 : if (-1 == php_stream_rewind(stream)) {
1310 2 : RETURN_FALSE;
1311 : }
1312 3374 : RETURN_TRUE;
1313 : }
1314 : /* }}} */
1315 :
1316 : /* {{{ proto int ftell(resource fp)
1317 : Get file pointer's read/write position */
1318 : PHPAPI PHP_FUNCTION(ftell)
1319 15039 : {
1320 : zval *arg1;
1321 : long ret;
1322 : php_stream *stream;
1323 :
1324 15039 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1325 11 : RETURN_FALSE;
1326 : }
1327 :
1328 15028 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1329 :
1330 15003 : ret = php_stream_tell(stream);
1331 15003 : if (ret == -1) {
1332 10 : RETURN_FALSE;
1333 : }
1334 14993 : RETURN_LONG(ret);
1335 : }
1336 : /* }}} */
1337 :
1338 : /* {{{ proto int fseek(resource fp, int offset [, int whence])
1339 : Seek on a file pointer */
1340 : PHPAPI PHP_FUNCTION(fseek)
1341 7665 : {
1342 : zval *arg1;
1343 7665 : long arg2, whence = SEEK_SET;
1344 : php_stream *stream;
1345 :
1346 7665 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &arg2, &whence) == FAILURE) {
1347 27 : RETURN_FALSE;
1348 : }
1349 :
1350 7638 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1351 :
1352 7637 : RETURN_LONG(php_stream_seek(stream, arg2, whence));
1353 : }
1354 : /* }}} */
1355 :
1356 : /* {{{ php_mkdir
1357 : */
1358 :
1359 : /* DEPRECATED APIs: Use php_stream_mkdir() instead */
1360 : PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC)
1361 1655 : {
1362 : int ret;
1363 :
1364 1655 : if (PG(safe_mode) && (!php_checkuid(dir, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
1365 0 : return -1;
1366 : }
1367 :
1368 1655 : if (php_check_open_basedir(dir TSRMLS_CC)) {
1369 0 : return -1;
1370 : }
1371 :
1372 1655 : if ((ret = VCWD_MKDIR(dir, (mode_t)mode)) < 0 && (options & REPORT_ERRORS)) {
1373 49 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
1374 : }
1375 :
1376 1655 : return ret;
1377 : }
1378 :
1379 : PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC)
1380 1655 : {
1381 1655 : return php_mkdir_ex(dir, mode, REPORT_ERRORS TSRMLS_CC);
1382 : }
1383 : /* }}} */
1384 :
1385 : /* {{{ proto bool mkdir(string pathname [, int mode [, bool recursive [, resource context]]])
1386 : Create a directory */
1387 : PHP_FUNCTION(mkdir)
1388 1708 : {
1389 : char *dir;
1390 : int dir_len;
1391 1708 : zval *zcontext = NULL;
1392 1708 : long mode = 0777;
1393 1708 : zend_bool recursive = 0;
1394 : php_stream_context *context;
1395 :
1396 1708 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbr", &dir, &dir_len, &mode, &recursive, &zcontext) == FAILURE) {
1397 50 : RETURN_FALSE;
1398 : }
1399 :
1400 1658 : context = php_stream_context_from_zval(zcontext, 0);
1401 :
1402 1658 : RETURN_BOOL(php_stream_mkdir(dir, mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
1403 : }
1404 : /* }}} */
1405 :
1406 : /* {{{ proto bool rmdir(string dirname[, resource context])
1407 : Remove a directory */
1408 : PHP_FUNCTION(rmdir)
1409 1725 : {
1410 : char *dir;
1411 : int dir_len;
1412 1725 : zval *zcontext = NULL;
1413 : php_stream_context *context;
1414 :
1415 1725 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
1416 32 : RETURN_FALSE;
1417 : }
1418 :
1419 1693 : context = php_stream_context_from_zval(zcontext, 0);
1420 :
1421 1693 : RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context));
1422 : }
1423 : /* }}} */
1424 :
1425 : /* {{{ proto int readfile(string filename [, bool use_include_path[, resource context]])
1426 : Output a file or a URL */
1427 : PHP_FUNCTION(readfile)
1428 460 : {
1429 : char *filename;
1430 : int filename_len;
1431 460 : int size = 0;
1432 460 : zend_bool use_include_path = 0;
1433 460 : zval *zcontext = NULL;
1434 : php_stream *stream;
1435 460 : php_stream_context *context = NULL;
1436 :
1437 460 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
1438 37 : RETURN_FALSE;
1439 : }
1440 :
1441 423 : context = php_stream_context_from_zval(zcontext, 0);
1442 :
1443 423 : stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
1444 423 : if (stream) {
1445 406 : size = php_stream_passthru(stream);
1446 406 : php_stream_close(stream);
1447 406 : RETURN_LONG(size);
1448 : }
1449 :
1450 17 : RETURN_FALSE;
1451 : }
1452 : /* }}} */
1453 :
1454 : /* {{{ proto int umask([int mask])
1455 : Return or change the umask */
1456 : PHP_FUNCTION(umask)
1457 2128 : {
1458 2128 : long arg1 = 0;
1459 : int oldumask;
1460 2128 : int arg_count = ZEND_NUM_ARGS();
1461 :
1462 2128 : oldumask = umask(077);
1463 :
1464 2128 : if (BG(umask) == -1) {
1465 6 : BG(umask) = oldumask;
1466 : }
1467 :
1468 2128 : if (arg_count == 0) {
1469 1050 : umask(oldumask);
1470 : } else {
1471 1078 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
1472 13 : RETURN_FALSE;
1473 : }
1474 1065 : umask(arg1);
1475 : }
1476 :
1477 2115 : RETURN_LONG(oldumask);
1478 : }
1479 : /* }}} */
1480 :
1481 : /* {{{ proto int fpassthru(resource fp)
1482 : Output all remaining data from a file pointer */
1483 : PHPAPI PHP_FUNCTION(fpassthru)
1484 139 : {
1485 : zval *arg1;
1486 : int size;
1487 : php_stream *stream;
1488 :
1489 139 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
1490 37 : RETURN_FALSE;
1491 : }
1492 :
1493 102 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1494 :
1495 102 : size = php_stream_passthru(stream);
1496 102 : RETURN_LONG(size);
1497 : }
1498 : /* }}} */
1499 :
1500 : /* {{{ proto bool rename(string old_name, string new_name[, resource context])
1501 : Rename a file */
1502 : PHP_FUNCTION(rename)
1503 133 : {
1504 : char *old_name, *new_name;
1505 : int old_name_len, new_name_len;
1506 133 : zval *zcontext = NULL;
1507 : php_stream_wrapper *wrapper;
1508 : php_stream_context *context;
1509 :
1510 133 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &old_name, &old_name_len, &new_name, &new_name_len, &zcontext) == FAILURE) {
1511 34 : RETURN_FALSE;
1512 : }
1513 :
1514 99 : wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0 TSRMLS_CC);
1515 :
1516 99 : if (!wrapper || !wrapper->wops) {
1517 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
1518 0 : RETURN_FALSE;
1519 : }
1520 :
1521 99 : if (!wrapper->wops->rename) {
1522 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s wrapper does not support renaming", wrapper->wops->label ? wrapper->wops->label : "Source");
1523 1 : RETURN_FALSE;
1524 : }
1525 :
1526 98 : if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0 TSRMLS_CC)) {
1527 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rename a file across wrapper types");
1528 1 : RETURN_FALSE;
1529 : }
1530 :
1531 97 : context = php_stream_context_from_zval(zcontext, 0);
1532 :
1533 97 : RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context TSRMLS_CC));
1534 : }
1535 : /* }}} */
1536 :
1537 : /* {{{ proto bool unlink(string filename[, context context])
1538 : Delete a file */
1539 : PHP_FUNCTION(unlink)
1540 169190 : {
1541 : char *filename;
1542 : int filename_len;
1543 : php_stream_wrapper *wrapper;
1544 169190 : zval *zcontext = NULL;
1545 169190 : php_stream_context *context = NULL;
1546 :
1547 169190 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &filename, &filename_len, &zcontext) == FAILURE) {
1548 36 : RETURN_FALSE;
1549 : }
1550 :
1551 169154 : context = php_stream_context_from_zval(zcontext, 0);
1552 :
1553 169154 : wrapper = php_stream_locate_url_wrapper(filename, NULL, 0 TSRMLS_CC);
1554 :
1555 169154 : if (!wrapper || !wrapper->wops) {
1556 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
1557 0 : RETURN_FALSE;
1558 : }
1559 :
1560 169154 : if (!wrapper->wops->unlink) {
1561 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
1562 1 : RETURN_FALSE;
1563 : }
1564 169153 : RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC));
1565 : }
1566 : /* }}} */
1567 :
1568 : /* {{{ proto bool ftruncate(resource fp, int size)
1569 : Truncate file to 'size' length */
1570 : PHP_NAMED_FUNCTION(php_if_ftruncate)
1571 388 : {
1572 : zval *fp;
1573 : long size;
1574 : php_stream *stream;
1575 :
1576 388 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &fp, &size) == FAILURE) {
1577 12 : RETURN_FALSE;
1578 : }
1579 :
1580 376 : PHP_STREAM_TO_ZVAL(stream, &fp);
1581 :
1582 375 : if (!php_stream_truncate_supported(stream)) {
1583 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream!");
1584 2 : RETURN_FALSE;
1585 : }
1586 :
1587 373 : RETURN_BOOL(0 == php_stream_truncate_set_size(stream, size));
1588 : }
1589 : /* }}} */
1590 :
1591 : /* {{{ proto array fstat(resource fp)
1592 : Stat() on a filehandle */
1593 : PHP_NAMED_FUNCTION(php_if_fstat)
1594 41 : {
1595 : zval *fp;
1596 : zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
1597 : *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
1598 : php_stream *stream;
1599 : php_stream_statbuf stat_ssb;
1600 : char *stat_sb_names[13] = {
1601 : "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
1602 : "size", "atime", "mtime", "ctime", "blksize", "blocks"
1603 41 : };
1604 :
1605 41 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &fp) == FAILURE) {
1606 31 : RETURN_FALSE;
1607 : }
1608 :
1609 10 : PHP_STREAM_TO_ZVAL(stream, &fp);
1610 :
1611 9 : if (php_stream_stat(stream, &stat_ssb)) {
1612 3 : RETURN_FALSE;
1613 : }
1614 :
1615 6 : array_init(return_value);
1616 :
1617 6 : MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev);
1618 6 : MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino);
1619 6 : MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode);
1620 6 : MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink);
1621 6 : MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid);
1622 6 : MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid);
1623 : #ifdef HAVE_ST_RDEV
1624 6 : MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev);
1625 : #else
1626 : MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
1627 : #endif
1628 6 : MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size);
1629 6 : MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime);
1630 6 : MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime);
1631 6 : MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime);
1632 : #ifdef HAVE_ST_BLKSIZE
1633 6 : MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize);
1634 : #else
1635 : MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
1636 : #endif
1637 : #ifdef HAVE_ST_BLOCKS
1638 6 : MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks);
1639 : #else
1640 : MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
1641 : #endif
1642 : /* Store numeric indexes in propper order */
1643 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
1644 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
1645 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
1646 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
1647 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
1648 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
1649 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
1650 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
1651 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
1652 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
1653 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
1654 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
1655 6 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
1656 :
1657 : /* Store string indexes referencing the same zval*/
1658 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *)&stat_dev, sizeof(zval *), NULL);
1659 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *)&stat_ino, sizeof(zval *), NULL);
1660 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *)&stat_mode, sizeof(zval *), NULL);
1661 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *)&stat_nlink, sizeof(zval *), NULL);
1662 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *)&stat_uid, sizeof(zval *), NULL);
1663 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *)&stat_gid, sizeof(zval *), NULL);
1664 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *)&stat_rdev, sizeof(zval *), NULL);
1665 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *)&stat_size, sizeof(zval *), NULL);
1666 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *)&stat_atime, sizeof(zval *), NULL);
1667 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *)&stat_mtime, sizeof(zval *), NULL);
1668 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *)&stat_ctime, sizeof(zval *), NULL);
1669 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *)&stat_blksize, sizeof(zval *), NULL);
1670 6 : zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *)&stat_blocks, sizeof(zval *), NULL);
1671 : }
1672 : /* }}} */
1673 :
1674 : /* {{{ proto bool copy(string source_file, string destination_file [, resource context])
1675 : Copy a file */
1676 : PHP_FUNCTION(copy)
1677 182 : {
1678 : char *source, *target;
1679 : int source_len, target_len;
1680 182 : zval *zcontext = NULL;
1681 : php_stream_context *context;
1682 :
1683 182 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &source, &source_len, &target, &target_len, &zcontext) == FAILURE) {
1684 3 : return;
1685 : }
1686 :
1687 179 : if (PG(safe_mode) &&(!php_checkuid(source, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
1688 0 : RETURN_FALSE;
1689 : }
1690 :
1691 179 : if (php_check_open_basedir(source TSRMLS_CC)) {
1692 1 : RETURN_FALSE;
1693 : }
1694 :
1695 178 : context = php_stream_context_from_zval(zcontext, 0);
1696 :
1697 178 : if (php_copy_file(source, target TSRMLS_CC) == SUCCESS) {
1698 149 : RETURN_TRUE;
1699 : } else {
1700 29 : RETURN_FALSE;
1701 : }
1702 : }
1703 : /* }}} */
1704 :
1705 : PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC) /* {{{ */
1706 178 : {
1707 178 : return php_copy_file_ex(src, dest, ENFORCE_SAFE_MODE TSRMLS_CC);
1708 : }
1709 : /* }}} */
1710 :
1711 : /* {{{ php_copy_file
1712 : */
1713 : PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC)
1714 178 : {
1715 178 : php_stream *srcstream = NULL, *deststream = NULL;
1716 178 : int ret = FAILURE;
1717 : php_stream_statbuf src_s, dest_s;
1718 :
1719 178 : switch (php_stream_stat_path_ex(src, 0, &src_s, NULL)) {
1720 : case -1:
1721 : /* non-statable stream */
1722 8 : goto safe_to_copy;
1723 : break;
1724 : case 0:
1725 : break;
1726 : default: /* failed to stat file, does not exist? */
1727 0 : return ret;
1728 : }
1729 170 : if (S_ISDIR(src_s.sb.st_mode)) {
1730 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument to copy() function cannot be a directory");
1731 2 : return FAILURE;
1732 : }
1733 :
1734 168 : switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, NULL)) {
1735 : case -1:
1736 : /* non-statable stream */
1737 157 : goto safe_to_copy;
1738 : break;
1739 : case 0:
1740 : break;
1741 : default: /* failed to stat file, does not exist? */
1742 0 : return ret;
1743 : }
1744 11 : if (S_ISDIR(dest_s.sb.st_mode)) {
1745 6 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument to copy() function cannot be a directory");
1746 6 : return FAILURE;
1747 : }
1748 5 : if (!src_s.sb.st_ino || !dest_s.sb.st_ino) {
1749 : goto no_stat;
1750 : }
1751 5 : if (src_s.sb.st_ino == dest_s.sb.st_ino && src_s.sb.st_dev == dest_s.sb.st_dev) {
1752 4 : return ret;
1753 : } else {
1754 : goto safe_to_copy;
1755 : }
1756 0 : no_stat:
1757 : {
1758 : char *sp, *dp;
1759 : int res;
1760 :
1761 0 : if ((sp = expand_filepath(src, NULL TSRMLS_CC)) == NULL) {
1762 0 : return ret;
1763 : }
1764 0 : if ((dp = expand_filepath(dest, NULL TSRMLS_CC)) == NULL) {
1765 0 : efree(sp);
1766 0 : goto safe_to_copy;
1767 : }
1768 :
1769 0 : res =
1770 : #ifndef PHP_WIN32
1771 : !strcmp(sp, dp);
1772 : #else
1773 : !strcasecmp(sp, dp);
1774 : #endif
1775 :
1776 0 : efree(sp);
1777 0 : efree(dp);
1778 0 : if (res) {
1779 0 : return ret;
1780 : }
1781 : }
1782 166 : safe_to_copy:
1783 :
1784 166 : srcstream = php_stream_open_wrapper(src, "rb", src_chk | REPORT_ERRORS, NULL);
1785 :
1786 166 : if (!srcstream) {
1787 6 : return ret;
1788 : }
1789 :
1790 160 : deststream = php_stream_open_wrapper(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
1791 :
1792 160 : if (srcstream && deststream) {
1793 149 : ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL, NULL);
1794 : }
1795 160 : if (srcstream) {
1796 160 : php_stream_close(srcstream);
1797 : }
1798 160 : if (deststream) {
1799 149 : php_stream_close(deststream);
1800 : }
1801 160 : return ret;
1802 : }
1803 : /* }}} */
1804 :
1805 : /* {{{ proto string fread(resource fp, int length)
1806 : Binary-safe file read */
1807 : PHPAPI PHP_FUNCTION(fread)
1808 714147 : {
1809 : zval *arg1;
1810 : long len;
1811 : php_stream *stream;
1812 :
1813 714147 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &len) == FAILURE) {
1814 12 : RETURN_FALSE;
1815 : }
1816 :
1817 714135 : PHP_STREAM_TO_ZVAL(stream, &arg1);
1818 :
1819 714132 : if (len <= 0) {
1820 4 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
1821 4 : RETURN_FALSE;
1822 : }
1823 :
1824 714128 : Z_STRVAL_P(return_value) = emalloc(len + 1);
1825 714128 : Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len);
1826 :
1827 : /* needed because recv/read/gzread doesnt put a null at the end*/
1828 714128 : Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
1829 :
1830 714128 : if (PG(magic_quotes_runtime)) {
1831 0 : Z_STRVAL_P(return_value) = php_addslashes(Z_STRVAL_P(return_value),
1832 : Z_STRLEN_P(return_value), &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
1833 : }
1834 714128 : Z_TYPE_P(return_value) = IS_STRING;
1835 : }
1836 : /* }}} */
1837 :
1838 : static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t len, const char delimiter TSRMLS_DC) /* {{{ */
1839 3945 : {
1840 : int inc_len;
1841 3945 : unsigned char last_chars[2] = { 0, 0 };
1842 :
1843 55103 : while (len > 0) {
1844 47213 : inc_len = (*ptr == '\0' ? 1: php_mblen(ptr, len));
1845 47213 : switch (inc_len) {
1846 : case -2:
1847 : case -1:
1848 0 : inc_len = 1;
1849 0 : php_mblen(NULL, 0);
1850 0 : break;
1851 : case 0:
1852 0 : goto quit_loop;
1853 : case 1:
1854 : default:
1855 47213 : last_chars[0] = last_chars[1];
1856 47213 : last_chars[1] = *ptr;
1857 : break;
1858 : }
1859 47213 : ptr += inc_len;
1860 47213 : len -= inc_len;
1861 : }
1862 3945 : quit_loop:
1863 3945 : switch (last_chars[1]) {
1864 : case '\n':
1865 1668 : if (last_chars[0] == '\r') {
1866 2 : return ptr - 2;
1867 : }
1868 : /* break is omitted intentionally */
1869 : case '\r':
1870 1666 : return ptr - 1;
1871 : }
1872 2277 : return ptr;
1873 : }
1874 : /* }}} */
1875 :
1876 : #define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field))
1877 :
1878 : /* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])
1879 : Format line as CSV and write to file pointer */
1880 : PHP_FUNCTION(fputcsv)
1881 1394 : {
1882 1394 : char delimiter = ','; /* allow this to be set as parameter */
1883 1394 : char enclosure = '"'; /* allow this to be set as parameter */
1884 1394 : const char escape_char = '\\';
1885 : php_stream *stream;
1886 : int ret;
1887 1394 : zval *fp = NULL, *fields = NULL, **field_tmp = NULL, field;
1888 1394 : char *delimiter_str = NULL, *enclosure_str = NULL;
1889 1394 : int delimiter_str_len = 0, enclosure_str_len = 0;
1890 : HashPosition pos;
1891 1394 : int count, i = 0;
1892 1394 : smart_str csvline = {0};
1893 :
1894 1394 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ss",
1895 : &fp, &fields, &delimiter_str, &delimiter_str_len,
1896 : &enclosure_str, &enclosure_str_len) == FAILURE) {
1897 14 : return;
1898 : }
1899 :
1900 1380 : if (delimiter_str != NULL) {
1901 : /* Make sure that there is at least one character in string */
1902 1215 : if (delimiter_str_len < 1) {
1903 216 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
1904 216 : RETURN_FALSE;
1905 999 : } else if (delimiter_str_len > 1) {
1906 243 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
1907 : }
1908 :
1909 : /* use first character from string */
1910 999 : delimiter = *delimiter_str;
1911 : }
1912 :
1913 1164 : if (enclosure_str != NULL) {
1914 675 : if (enclosure_str_len < 1) {
1915 108 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
1916 108 : RETURN_FALSE;
1917 567 : } else if (enclosure_str_len > 1) {
1918 135 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
1919 : }
1920 : /* use first character from string */
1921 567 : enclosure = *enclosure_str;
1922 : }
1923 :
1924 1056 : PHP_STREAM_TO_ZVAL(stream, &fp);
1925 :
1926 1056 : count = zend_hash_num_elements(Z_ARRVAL_P(fields));
1927 1056 : zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
1928 3231 : while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field_tmp, &pos) == SUCCESS) {
1929 1119 : field = **field_tmp;
1930 :
1931 1119 : if (Z_TYPE_PP(field_tmp) != IS_STRING) {
1932 5 : zval_copy_ctor(&field);
1933 5 : convert_to_string(&field);
1934 : }
1935 :
1936 : /* enclose a field that contains a delimiter, an enclosure character, or a newline */
1937 1744 : if (FPUTCSV_FLD_CHK(delimiter) ||
1938 : FPUTCSV_FLD_CHK(enclosure) ||
1939 : FPUTCSV_FLD_CHK(escape_char) ||
1940 : FPUTCSV_FLD_CHK('\n') ||
1941 : FPUTCSV_FLD_CHK('\r') ||
1942 : FPUTCSV_FLD_CHK('\t') ||
1943 : FPUTCSV_FLD_CHK(' ')
1944 : ) {
1945 625 : char *ch = Z_STRVAL(field);
1946 625 : char *end = ch + Z_STRLEN(field);
1947 625 : int escaped = 0;
1948 :
1949 625 : smart_str_appendc(&csvline, enclosure);
1950 11237 : while (ch < end) {
1951 9987 : if (*ch == escape_char) {
1952 16 : escaped = 1;
1953 11558 : } else if (!escaped && *ch == enclosure) {
1954 1587 : smart_str_appendc(&csvline, enclosure);
1955 : } else {
1956 8384 : escaped = 0;
1957 : }
1958 9987 : smart_str_appendc(&csvline, *ch);
1959 9987 : ch++;
1960 : }
1961 625 : smart_str_appendc(&csvline, enclosure);
1962 : } else {
1963 494 : smart_str_appendl(&csvline, Z_STRVAL(field), Z_STRLEN(field));
1964 : }
1965 :
1966 1119 : if (++i != count) {
1967 63 : smart_str_appendl(&csvline, &delimiter, 1);
1968 : }
1969 1119 : zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);
1970 :
1971 1119 : if (Z_TYPE_PP(field_tmp) != IS_STRING) {
1972 5 : zval_dtor(&field);
1973 : }
1974 : }
1975 :
1976 1056 : smart_str_appendc(&csvline, '\n');
1977 1056 : smart_str_0(&csvline);
1978 :
1979 1056 : if (!PG(magic_quotes_runtime)) {
1980 1056 : ret = php_stream_write(stream, csvline.c, csvline.len);
1981 : } else {
1982 0 : char *buffer = estrndup(csvline.c, csvline.len);
1983 0 : int len = csvline.len;
1984 0 : php_stripslashes(buffer, &len TSRMLS_CC);
1985 0 : ret = php_stream_write(stream, buffer, len);
1986 0 : efree(buffer);
1987 : }
1988 :
1989 1056 : smart_str_free(&csvline);
1990 :
1991 1056 : RETURN_LONG(ret);
1992 : }
1993 : /* }}} */
1994 :
1995 : /* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, string enclosure [, string escape]]]])
1996 : Get line from file pointer and parse for CSV fields */
1997 : PHP_FUNCTION(fgetcsv)
1998 3011 : {
1999 3011 : char delimiter = ','; /* allow this to be set as parameter */
2000 3011 : char enclosure = '"'; /* allow this to be set as parameter */
2001 3011 : char escape = '\\';
2002 :
2003 : /* first section exactly as php_fgetss */
2004 :
2005 3011 : long len = 0;
2006 : size_t buf_len;
2007 : char *buf;
2008 : php_stream *stream;
2009 :
2010 : {
2011 3011 : zval *fd, **len_zv = NULL;
2012 3011 : char *delimiter_str = NULL;
2013 3011 : int delimiter_str_len = 0;
2014 3011 : char *enclosure_str = NULL;
2015 3011 : int enclosure_str_len = 0;
2016 3011 : char *escape_str = NULL;
2017 3011 : int escape_str_len = 0;
2018 :
2019 3011 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|Zsss",
2020 : &fd, &len_zv, &delimiter_str, &delimiter_str_len,
2021 : &enclosure_str, &enclosure_str_len,
2022 : &escape_str, &escape_str_len) == FAILURE
2023 : ) {
2024 14 : return;
2025 : }
2026 :
2027 2997 : if (delimiter_str != NULL) {
2028 : /* Make sure that there is at least one character in string */
2029 2375 : if (delimiter_str_len < 1) {
2030 240 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
2031 240 : RETURN_FALSE;
2032 2135 : } else if (delimiter_str_len > 1) {
2033 195 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
2034 : }
2035 :
2036 : /* use first character from string */
2037 2135 : delimiter = delimiter_str[0];
2038 : }
2039 :
2040 2757 : if (enclosure_str != NULL) {
2041 1469 : if (enclosure_str_len < 1) {
2042 120 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
2043 120 : RETURN_FALSE;
2044 1349 : } else if (enclosure_str_len > 1) {
2045 120 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
2046 : }
2047 :
2048 : /* use first character from string */
2049 1349 : enclosure = enclosure_str[0];
2050 : }
2051 :
2052 2637 : if (escape_str != NULL) {
2053 1 : if (escape_str_len < 1) {
2054 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be character");
2055 0 : RETURN_FALSE;
2056 1 : } else if (escape_str_len > 1) {
2057 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "escape must be a single character");
2058 : }
2059 :
2060 1 : escape = escape_str[0];
2061 : }
2062 :
2063 4561 : if (len_zv != NULL && Z_TYPE_PP(len_zv) != IS_NULL) {
2064 2284 : convert_to_long_ex(len_zv);
2065 2284 : len = Z_LVAL_PP(len_zv);
2066 2284 : if (len < 0) {
2067 360 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative");
2068 360 : RETURN_FALSE;
2069 1924 : } else if (len == 0) {
2070 195 : len = -1;
2071 : }
2072 : } else {
2073 353 : len = -1;
2074 : }
2075 :
2076 2277 : PHP_STREAM_TO_ZVAL(stream, &fd);
2077 : }
2078 :
2079 2277 : if (len < 0) {
2080 548 : if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) {
2081 197 : RETURN_FALSE;
2082 : }
2083 : } else {
2084 1729 : buf = emalloc(len + 1);
2085 1729 : if (php_stream_get_line(stream, buf, len + 1, &buf_len) == NULL) {
2086 453 : efree(buf);
2087 453 : RETURN_FALSE;
2088 : }
2089 : }
2090 :
2091 1627 : php_fgetcsv(stream, delimiter, enclosure, escape, buf_len, buf, return_value TSRMLS_CC);
2092 : }
2093 : /* }}} */
2094 :
2095 : PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char escape_char, size_t buf_len, char *buf, zval *return_value TSRMLS_DC) /* {{{ */
2096 1657 : {
2097 : char *temp, *tptr, *bptr, *line_end, *limit;
2098 : size_t temp_len, line_end_len;
2099 : int inc_len;
2100 1657 : zend_bool first_field = 1;
2101 :
2102 : /* initialize internal state */
2103 1657 : php_mblen(NULL, 0);
2104 :
2105 : /* Now into new section that parses buf for delimiter/enclosure fields */
2106 :
2107 : /* Strip trailing space from buf, saving end of line in case required for enclosure field */
2108 :
2109 1657 : bptr = buf;
2110 1657 : tptr = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len, delimiter TSRMLS_CC);
2111 1657 : line_end_len = buf_len - (size_t)(tptr - buf);
2112 1657 : line_end = limit = tptr;
2113 :
2114 : /* reserve workspace for building each individual field */
2115 1657 : temp_len = buf_len;
2116 1657 : temp = emalloc(temp_len + line_end_len + 1);
2117 :
2118 : /* Initialize return array */
2119 1657 : array_init(return_value);
2120 :
2121 : /* Main loop to read CSV fields */
2122 : /* NB this routine will return a single null entry for a blank line */
2123 :
2124 : do {
2125 : char *comp_end, *hunk_begin;
2126 :
2127 3341 : tptr = temp;
2128 :
2129 : /* 1. Strip any leading space */
2130 : for (;;) {
2131 3352 : inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2132 3352 : switch (inc_len) {
2133 : case -2:
2134 : case -1:
2135 0 : inc_len = 1;
2136 0 : php_mblen(NULL, 0);
2137 0 : break;
2138 : case 0:
2139 173 : goto quit_loop_1;
2140 : case 1:
2141 3179 : if (!isspace((int)*(unsigned char *)bptr) || *bptr == delimiter) {
2142 : goto quit_loop_1;
2143 : }
2144 11 : break;
2145 : default:
2146 0 : goto quit_loop_1;
2147 : }
2148 11 : bptr += inc_len;
2149 11 : }
2150 :
2151 3341 : quit_loop_1:
2152 3341 : if (first_field && bptr == line_end) {
2153 32 : add_next_index_null(return_value);
2154 32 : break;
2155 : }
2156 3309 : first_field = 0;
2157 : /* 2. Read field, leaving bptr pointing at start of next field */
2158 4562 : if (inc_len != 0 && *bptr == enclosure) {
2159 1253 : int state = 0;
2160 :
2161 1253 : bptr++; /* move on to first character in field */
2162 1253 : hunk_begin = bptr;
2163 :
2164 : /* 2A. handle enclosure delimited field */
2165 : for (;;) {
2166 10881 : switch (inc_len) {
2167 : case 0:
2168 586 : switch (state) {
2169 : case 2:
2170 305 : memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2171 305 : tptr += (bptr - hunk_begin - 1);
2172 305 : hunk_begin = bptr;
2173 305 : goto quit_loop_2;
2174 :
2175 : case 1:
2176 0 : memcpy(tptr, hunk_begin, bptr - hunk_begin);
2177 0 : tptr += (bptr - hunk_begin);
2178 0 : hunk_begin = bptr;
2179 : /* break is omitted intentionally */
2180 :
2181 : case 0: {
2182 : char *new_buf;
2183 : size_t new_len;
2184 : char *new_temp;
2185 :
2186 281 : if (hunk_begin != line_end) {
2187 113 : memcpy(tptr, hunk_begin, bptr - hunk_begin);
2188 113 : tptr += (bptr - hunk_begin);
2189 113 : hunk_begin = bptr;
2190 : }
2191 :
2192 : /* add the embedded line end to the field */
2193 281 : memcpy(tptr, line_end, line_end_len);
2194 281 : tptr += line_end_len;
2195 :
2196 281 : if (stream == NULL) {
2197 0 : goto quit_loop_2;
2198 281 : } else if ((new_buf = php_stream_get_line(stream, NULL, 0, &new_len)) == NULL) {
2199 : /* we've got an unterminated enclosure,
2200 : * assign all the data from the start of
2201 : * the enclosure to end of data to the
2202 : * last element */
2203 49 : if ((size_t)temp_len > (size_t)(limit - buf)) {
2204 49 : goto quit_loop_2;
2205 : }
2206 0 : zval_dtor(return_value);
2207 0 : RETVAL_FALSE;
2208 0 : goto out;
2209 : }
2210 232 : temp_len += new_len;
2211 232 : new_temp = erealloc(temp, temp_len);
2212 232 : tptr = new_temp + (size_t)(tptr - temp);
2213 232 : temp = new_temp;
2214 :
2215 232 : efree(buf);
2216 232 : buf_len = new_len;
2217 232 : bptr = buf = new_buf;
2218 232 : hunk_begin = buf;
2219 :
2220 232 : line_end = limit = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len, delimiter TSRMLS_CC);
2221 232 : line_end_len = buf_len - (size_t)(limit - buf);
2222 :
2223 232 : state = 0;
2224 : } break;
2225 : }
2226 232 : break;
2227 :
2228 : case -2:
2229 : case -1:
2230 0 : php_mblen(NULL, 0);
2231 : /* break is omitted intentionally */
2232 : case 1:
2233 : /* we need to determine if the enclosure is
2234 : * 'real' or is it escaped */
2235 10295 : switch (state) {
2236 : case 1: /* escaped */
2237 27 : bptr++;
2238 27 : state = 0;
2239 27 : break;
2240 : case 2: /* embedded enclosure ? let's check it */
2241 1183 : if (*bptr != enclosure) {
2242 : /* real enclosure */
2243 899 : memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2244 899 : tptr += (bptr - hunk_begin - 1);
2245 899 : hunk_begin = bptr;
2246 899 : goto quit_loop_2;
2247 : }
2248 284 : memcpy(tptr, hunk_begin, bptr - hunk_begin);
2249 284 : tptr += (bptr - hunk_begin);
2250 284 : bptr++;
2251 284 : hunk_begin = bptr;
2252 284 : state = 0;
2253 284 : break;
2254 : default:
2255 9085 : if (*bptr == enclosure) {
2256 1488 : state = 2;
2257 7597 : } else if (*bptr == escape_char) {
2258 27 : state = 1;
2259 : }
2260 9085 : bptr++;
2261 : break;
2262 : }
2263 9396 : break;
2264 :
2265 : default:
2266 0 : switch (state) {
2267 : case 2:
2268 : /* real enclosure */
2269 0 : memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2270 0 : tptr += (bptr - hunk_begin - 1);
2271 0 : hunk_begin = bptr;
2272 0 : goto quit_loop_2;
2273 : case 1:
2274 0 : bptr += inc_len;
2275 0 : memcpy(tptr, hunk_begin, bptr - hunk_begin);
2276 0 : tptr += (bptr - hunk_begin);
2277 0 : hunk_begin = bptr;
2278 0 : break;
2279 : default:
2280 0 : bptr += inc_len;
2281 : break;
2282 : }
2283 : break;
2284 : }
2285 9628 : inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2286 9628 : }
2287 :
2288 3446 : quit_loop_2:
2289 : /* look up for a delimiter */
2290 : for (;;) {
2291 3446 : switch (inc_len) {
2292 : case 0:
2293 580 : goto quit_loop_3;
2294 :
2295 : case -2:
2296 : case -1:
2297 0 : inc_len = 1;
2298 0 : php_mblen(NULL, 0);
2299 : /* break is omitted intentionally */
2300 : case 1:
2301 2866 : if (*bptr == delimiter) {
2302 673 : goto quit_loop_3;
2303 : }
2304 : break;
2305 : default:
2306 : break;
2307 : }
2308 2193 : bptr += inc_len;
2309 2193 : inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2310 2193 : }
2311 :
2312 1253 : quit_loop_3:
2313 1253 : memcpy(tptr, hunk_begin, bptr - hunk_begin);
2314 1253 : tptr += (bptr - hunk_begin);
2315 1253 : bptr += inc_len;
2316 1253 : comp_end = tptr;
2317 : } else {
2318 : /* 2B. Handle non-enclosure field */
2319 :
2320 2056 : hunk_begin = bptr;
2321 :
2322 : for (;;) {
2323 17598 : switch (inc_len) {
2324 : case 0:
2325 1045 : goto quit_loop_4;
2326 : case -2:
2327 : case -1:
2328 0 : inc_len = 1;
2329 0 : php_mblen(NULL, 0);
2330 : /* break is omitted intentionally */
2331 : case 1:
2332 16553 : if (*bptr == delimiter) {
2333 1011 : goto quit_loop_4;
2334 : }
2335 : break;
2336 : default:
2337 : break;
2338 : }
2339 15542 : bptr += inc_len;
2340 15542 : inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
2341 15542 : }
2342 2056 : quit_loop_4:
2343 2056 : memcpy(tptr, hunk_begin, bptr - hunk_begin);
2344 2056 : tptr += (bptr - hunk_begin);
2345 :
2346 2056 : comp_end = (char *)php_fgetcsv_lookup_trailing_spaces(temp, tptr - temp, delimiter TSRMLS_CC);
2347 2056 : if (*bptr == delimiter) {
2348 1011 : bptr++;
2349 : }
2350 : }
2351 :
2352 : /* 3. Now pass our field back to php */
2353 3309 : *comp_end = '\0';
2354 3309 : add_next_index_stringl(return_value, temp, comp_end - temp, 1);
2355 3309 : } while (inc_len > 0);
2356 :
2357 1657 : out:
2358 1657 : efree(temp);
2359 1657 : if (stream) {
2360 1645 : efree(buf);
2361 : }
2362 1657 : }
2363 : /* }}} */
2364 :
2365 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2366 : /* {{{ proto string realpath(string path)
2367 : Return the resolved path */
2368 : PHP_FUNCTION(realpath)
2369 23457 : {
2370 : char *filename;
2371 : int filename_len;
2372 : char resolved_path_buff[MAXPATHLEN];
2373 :
2374 23457 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
2375 2 : return;
2376 : }
2377 :
2378 23455 : if (VCWD_REALPATH(filename, resolved_path_buff)) {
2379 23430 : if (PG(safe_mode) && (!php_checkuid(resolved_path_buff, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2380 0 : RETURN_FALSE;
2381 : }
2382 :
2383 23430 : if (php_check_open_basedir(resolved_path_buff TSRMLS_CC)) {
2384 0 : RETURN_FALSE;
2385 : }
2386 :
2387 : #ifdef ZTS
2388 : if (VCWD_ACCESS(resolved_path_buff, F_OK)) {
2389 : RETURN_FALSE;
2390 : }
2391 : #endif
2392 23430 : RETURN_STRING(resolved_path_buff, 1);
2393 : } else {
2394 25 : RETURN_FALSE;
2395 : }
2396 : }
2397 : /* }}} */
2398 : #endif
2399 :
2400 : /* See http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.2 */
2401 : #define PHP_META_HTML401_CHARS "-_.:"
2402 :
2403 : /* {{{ php_next_meta_token
2404 : Tokenizes an HTML file for get_meta_tags */
2405 : php_meta_tags_token php_next_meta_token(php_meta_tags_data *md TSRMLS_DC)
2406 210 : {
2407 210 : int ch = 0, compliment;
2408 : char buff[META_DEF_BUFSIZE + 1];
2409 :
2410 210 : memset((void *)buff, 0, META_DEF_BUFSIZE + 1);
2411 :
2412 210 : while (md->ulc || (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)))) {
2413 222 : if (php_stream_eof(md->stream)) {
2414 6 : break;
2415 : }
2416 :
2417 216 : if (md->ulc) {
2418 43 : ch = md->lc;
2419 43 : md->ulc = 0;
2420 : }
2421 :
2422 216 : switch (ch) {
2423 : case '<':
2424 25 : return TOK_OPENTAG;
2425 : break;
2426 :
2427 : case '>':
2428 13 : return TOK_CLOSETAG;
2429 : break;
2430 :
2431 : case '=':
2432 26 : return TOK_EQUAL;
2433 : break;
2434 : case '/':
2435 2 : return TOK_SLASH;
2436 : break;
2437 :
2438 : case '\'':
2439 : case '"':
2440 26 : compliment = ch;
2441 26 : md->token_len = 0;
2442 311 : while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && ch != compliment && ch != '<' && ch != '>') {
2443 259 : buff[(md->token_len)++] = ch;
2444 :
2445 259 : if (md->token_len == META_DEF_BUFSIZE) {
2446 0 : break;
2447 : }
2448 : }
2449 :
2450 26 : if (ch == '<' || ch == '>') {
2451 : /* Was just an apostrohpe */
2452 0 : md->ulc = 1;
2453 0 : md->lc = ch;
2454 : }
2455 :
2456 : /* We don't need to alloc unless we are in a meta tag */
2457 26 : if (md->in_meta) {
2458 26 : md->token_data = (char *) emalloc(md->token_len + 1);
2459 26 : memcpy(md->token_data, buff, md->token_len+1);
2460 : }
2461 :
2462 26 : return TOK_STRING;
2463 : break;
2464 :
2465 : case '\n':
2466 : case '\r':
2467 : case '\t':
2468 12 : break;
2469 :
2470 : case ' ':
2471 67 : return TOK_SPACE;
2472 : break;
2473 :
2474 : default:
2475 45 : if (isalnum(ch)) {
2476 45 : md->token_len = 0;
2477 45 : buff[(md->token_len)++] = ch;
2478 264 : while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && (isalnum(ch) || strchr(PHP_META_HTML401_CHARS, ch))) {
2479 174 : buff[(md->token_len)++] = ch;
2480 :
2481 174 : if (md->token_len == META_DEF_BUFSIZE) {
2482 0 : break;
2483 : }
2484 : }
2485 :
2486 : /* This is ugly, but we have to replace ungetc */
2487 45 : if (!isalpha(ch) && ch != '-') {
2488 45 : md->ulc = 1;
2489 45 : md->lc = ch;
2490 : }
2491 :
2492 45 : md->token_data = (char *) emalloc(md->token_len + 1);
2493 45 : memcpy(md->token_data, buff, md->token_len+1);
2494 :
2495 45 : return TOK_ID;
2496 : } else {
2497 0 : return TOK_OTHER;
2498 : }
2499 : break;
2500 : }
2501 : }
2502 :
2503 6 : return TOK_EOF;
2504 : }
2505 : /* }}} */
2506 :
2507 : #ifdef HAVE_FNMATCH
2508 : /* {{{ proto bool fnmatch(string pattern, string filename [, int flags])
2509 : Match filename against pattern */
2510 : PHP_FUNCTION(fnmatch)
2511 252 : {
2512 : char *pattern, *filename;
2513 : int pattern_len, filename_len;
2514 252 : long flags = 0;
2515 :
2516 252 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &pattern, &pattern_len, &filename, &filename_len, &flags) == FAILURE) {
2517 6 : return;
2518 : }
2519 :
2520 246 : if (filename_len >= MAXPATHLEN) {
2521 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN);
2522 0 : RETURN_FALSE;
2523 : }
2524 :
2525 246 : RETURN_BOOL( ! fnmatch( pattern, filename, flags ));
2526 : }
2527 : /* }}} */
2528 : #endif
2529 :
2530 : /* {{{ proto string sys_get_temp_dir()
2531 : Returns directory path used for temporary files */
2532 : PHP_FUNCTION(sys_get_temp_dir)
2533 583 : {
2534 583 : RETURN_STRING((char *)php_get_temporary_directory(), 1);
2535 : }
2536 : /* }}} */
2537 :
2538 : /*
2539 : * Local variables:
2540 : * tab-width: 4
2541 : * c-basic-offset: 4
2542 : * End:
2543 : * vim600: noet sw=4 ts=4 fdm=marker
2544 : * vim<600: noet sw=4 ts=4
2545 : */
|