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