Return to file.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
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: */