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