Back to index

php5  5.3.10
file.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
00016    |          Stig Bakken <ssb@php.net>                                   |
00017    |          Andi Gutmans <andi@zend.com>                                |
00018    |          Zeev Suraski <zeev@zend.com>                                |
00019    | PHP 4.0 patches by Thies C. Arntzen (thies@thieso.net)               |
00020    | PHP streams by Wez Furlong (wez@thebrainroom.com)                    |
00021    +----------------------------------------------------------------------+
00022 */
00023 
00024 /* $Id: file.c 321634 2012-01-01 13:15:04Z felipe $ */
00025 
00026 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
00027 
00028 /* {{{ includes */
00029 
00030 #include "php.h"
00031 #include "php_globals.h"
00032 #include "ext/standard/flock_compat.h"
00033 #include "ext/standard/exec.h"
00034 #include "ext/standard/php_filestat.h"
00035 #include "php_open_temporary_file.h"
00036 #include "ext/standard/basic_functions.h"
00037 #include "php_ini.h"
00038 #include "php_smart_str.h"
00039 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <errno.h>
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <fcntl.h>
00046 
00047 #ifdef PHP_WIN32
00048 # include <io.h>
00049 # define O_RDONLY _O_RDONLY
00050 # include "win32/param.h"
00051 # include "win32/winutil.h"
00052 # include "win32/fnmatch.h"
00053 #else
00054 # if HAVE_SYS_PARAM_H
00055 #  include <sys/param.h>
00056 # endif
00057 # if HAVE_SYS_SELECT_H
00058 #  include <sys/select.h>
00059 # endif
00060 # if defined(NETWARE) && defined(USE_WINSOCK)
00061 #  include <novsock2.h>
00062 # else
00063 #  include <sys/socket.h>
00064 #  include <netinet/in.h>
00065 #  include <netdb.h>
00066 # endif
00067 # if HAVE_ARPA_INET_H
00068 #  include <arpa/inet.h>
00069 # endif
00070 #endif
00071 
00072 #include "ext/standard/head.h"
00073 #include "safe_mode.h"
00074 #include "php_string.h"
00075 #include "file.h"
00076 
00077 #if HAVE_PWD_H
00078 # ifdef PHP_WIN32
00079 #  include "win32/pwd.h"
00080 # else
00081 #  include <pwd.h>
00082 # endif
00083 #endif
00084 
00085 #ifdef HAVE_SYS_TIME_H
00086 # include <sys/time.h>
00087 #endif
00088 
00089 #include "fsock.h"
00090 #include "fopen_wrappers.h"
00091 #include "streamsfuncs.h"
00092 #include "php_globals.h"
00093 
00094 #ifdef HAVE_SYS_FILE_H
00095 # include <sys/file.h>
00096 #endif
00097 
00098 #if MISSING_FCLOSE_DECL
00099 extern int fclose(FILE *);
00100 #endif
00101 
00102 #ifdef HAVE_SYS_MMAN_H
00103 # include <sys/mman.h>
00104 #endif
00105 
00106 #include "scanf.h"
00107 #include "zend_API.h"
00108 
00109 #ifdef ZTS
00110 int file_globals_id;
00111 #else
00112 php_file_globals file_globals;
00113 #endif
00114 
00115 #if defined(HAVE_FNMATCH) && !defined(PHP_WIN32)
00116 # ifndef _GNU_SOURCE
00117 #  define _GNU_SOURCE
00118 # endif
00119 # include <fnmatch.h>
00120 #endif
00121 
00122 #ifdef HAVE_WCHAR_H
00123 # include <wchar.h>
00124 #endif
00125 
00126 #ifndef S_ISDIR
00127 # define S_ISDIR(mode)      (((mode)&S_IFMT) == S_IFDIR)
00128 #endif
00129 /* }}} */
00130 
00131 #define PHP_STREAM_TO_ZVAL(stream, arg) \
00132        php_stream_from_zval_no_verify(stream, arg); \
00133        if (stream == NULL) {       \
00134               RETURN_FALSE; \
00135        }
00136 
00137 /* {{{ ZTS-stuff / Globals / Prototypes */
00138 
00139 /* sharing globals is *evil* */           
00140 static int le_stream_context = FAILURE;
00141 
00142 PHPAPI int php_le_stream_context(void)
00143 {
00144        return le_stream_context;
00145 }
00146 /* }}} */
00147 
00148 /* {{{ Module-Stuff
00149 */
00150 static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
00151 {
00152        php_stream_context *context = (php_stream_context*)rsrc->ptr;
00153        if (context->options) {
00154               zval_ptr_dtor(&context->options);
00155               context->options = NULL;
00156        }
00157        php_stream_context_free(context);
00158 }
00159 
00160 static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
00161 {
00162        FG(pclose_ret) = 0;
00163        FG(user_stream_current_filename) = NULL;
00164        FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
00165 }
00166 
00167 static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
00168 {
00169 }
00170 
00171 PHP_INI_BEGIN()
00172        STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals)
00173        PHP_INI_ENTRY("from", NULL, PHP_INI_ALL, NULL)
00174        STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateLong, default_socket_timeout, php_file_globals, file_globals)
00175        STD_PHP_INI_ENTRY("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateLong, auto_detect_line_endings, php_file_globals, file_globals)
00176 PHP_INI_END()
00177 
00178 PHP_MINIT_FUNCTION(file)
00179 {
00180        le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
00181 
00182 #ifdef ZTS
00183        ts_allocate_id(&file_globals_id, sizeof(php_file_globals), (ts_allocate_ctor) file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
00184 #else
00185        file_globals_ctor(&file_globals TSRMLS_CC);
00186 #endif
00187 
00188        REGISTER_INI_ENTRIES();
00189 
00190        REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
00191        REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
00192        REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
00193        REGISTER_LONG_CONSTANT("LOCK_SH", PHP_LOCK_SH, CONST_CS | CONST_PERSISTENT);
00194        REGISTER_LONG_CONSTANT("LOCK_EX", PHP_LOCK_EX, CONST_CS | CONST_PERSISTENT);
00195        REGISTER_LONG_CONSTANT("LOCK_UN", PHP_LOCK_UN, CONST_CS | CONST_PERSISTENT);
00196        REGISTER_LONG_CONSTANT("LOCK_NB", PHP_LOCK_NB, CONST_CS | CONST_PERSISTENT);
00197 
00198        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT",                PHP_STREAM_NOTIFY_CONNECT,                CONST_CS | CONST_PERSISTENT);
00199        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED",   PHP_STREAM_NOTIFY_AUTH_REQUIRED,   CONST_CS | CONST_PERSISTENT);
00200        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_RESULT",            PHP_STREAM_NOTIFY_AUTH_RESULT,            CONST_CS | CONST_PERSISTENT);
00201        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_MIME_TYPE_IS",    PHP_STREAM_NOTIFY_MIME_TYPE_IS,           CONST_CS | CONST_PERSISTENT);
00202        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FILE_SIZE_IS",    PHP_STREAM_NOTIFY_FILE_SIZE_IS,           CONST_CS | CONST_PERSISTENT);
00203        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_REDIRECTED",             PHP_STREAM_NOTIFY_REDIRECTED,             CONST_CS | CONST_PERSISTENT);
00204        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_PROGRESS",        PHP_STREAM_NOTIFY_PROGRESS,               CONST_CS | CONST_PERSISTENT);
00205        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FAILURE",                PHP_STREAM_NOTIFY_FAILURE,                CONST_CS | CONST_PERSISTENT);
00206        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_COMPLETED",              PHP_STREAM_NOTIFY_COMPLETED,              CONST_CS | CONST_PERSISTENT);
00207        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_RESOLVE",                PHP_STREAM_NOTIFY_RESOLVE,                CONST_CS | CONST_PERSISTENT);
00208 
00209        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_INFO",   PHP_STREAM_NOTIFY_SEVERITY_INFO,   CONST_CS | CONST_PERSISTENT);
00210        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_WARN",   PHP_STREAM_NOTIFY_SEVERITY_WARN,   CONST_CS | CONST_PERSISTENT);
00211        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_ERR",    PHP_STREAM_NOTIFY_SEVERITY_ERR,           CONST_CS | CONST_PERSISTENT);
00212 
00213        REGISTER_LONG_CONSTANT("STREAM_FILTER_READ",                   PHP_STREAM_FILTER_READ,                          CONST_CS | CONST_PERSISTENT);
00214        REGISTER_LONG_CONSTANT("STREAM_FILTER_WRITE",                  PHP_STREAM_FILTER_WRITE,                  CONST_CS | CONST_PERSISTENT);
00215        REGISTER_LONG_CONSTANT("STREAM_FILTER_ALL",                           PHP_STREAM_FILTER_ALL,                           CONST_CS | CONST_PERSISTENT);
00216 
00217        REGISTER_LONG_CONSTANT("STREAM_CLIENT_PERSISTENT",             PHP_STREAM_CLIENT_PERSISTENT,             CONST_CS | CONST_PERSISTENT);
00218        REGISTER_LONG_CONSTANT("STREAM_CLIENT_ASYNC_CONNECT",   PHP_STREAM_CLIENT_ASYNC_CONNECT,   CONST_CS | CONST_PERSISTENT);
00219        REGISTER_LONG_CONSTANT("STREAM_CLIENT_CONNECT",                PHP_STREAM_CLIENT_CONNECT,  CONST_CS | CONST_PERSISTENT);
00220 
00221        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_CLIENT",           STREAM_CRYPTO_METHOD_SSLv2_CLIENT, CONST_CS|CONST_PERSISTENT);
00222        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT",           STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT);
00223        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT",   STREAM_CRYPTO_METHOD_SSLv23_CLIENT,       CONST_CS|CONST_PERSISTENT);
00224        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT",             STREAM_CRYPTO_METHOD_TLS_CLIENT,   CONST_CS|CONST_PERSISTENT);
00225        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER",           STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT);
00226        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER",           STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT);
00227        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER",   STREAM_CRYPTO_METHOD_SSLv23_SERVER,       CONST_CS|CONST_PERSISTENT);
00228        REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER",             STREAM_CRYPTO_METHOD_TLS_SERVER,   CONST_CS|CONST_PERSISTENT);
00229 
00230        REGISTER_LONG_CONSTANT("STREAM_SHUT_RD",  STREAM_SHUT_RD,             CONST_CS|CONST_PERSISTENT);
00231        REGISTER_LONG_CONSTANT("STREAM_SHUT_WR",  STREAM_SHUT_WR,             CONST_CS|CONST_PERSISTENT);
00232        REGISTER_LONG_CONSTANT("STREAM_SHUT_RDWR",       STREAM_SHUT_RDWR,    CONST_CS|CONST_PERSISTENT);
00233 
00234 #ifdef PF_INET
00235        REGISTER_LONG_CONSTANT("STREAM_PF_INET", PF_INET, CONST_CS|CONST_PERSISTENT);
00236 #elif defined(AF_INET)
00237        REGISTER_LONG_CONSTANT("STREAM_PF_INET", AF_INET, CONST_CS|CONST_PERSISTENT);
00238 #endif
00239 
00240 #ifdef PF_INET6
00241        REGISTER_LONG_CONSTANT("STREAM_PF_INET6", PF_INET6, CONST_CS|CONST_PERSISTENT);
00242 #elif defined(AF_INET6)
00243        REGISTER_LONG_CONSTANT("STREAM_PF_INET6", AF_INET6, CONST_CS|CONST_PERSISTENT);
00244 #endif
00245 
00246 #ifdef PF_UNIX
00247        REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", PF_UNIX, CONST_CS|CONST_PERSISTENT);
00248 #elif defined(AF_UNIX)
00249        REGISTER_LONG_CONSTANT("STREAM_PF_UNIX", AF_UNIX, CONST_CS|CONST_PERSISTENT);
00250 #endif
00251 
00252 #ifdef IPPROTO_IP
00253        /* most people will use this one when calling socket() or socketpair() */
00254        REGISTER_LONG_CONSTANT("STREAM_IPPROTO_IP", IPPROTO_IP, CONST_CS|CONST_PERSISTENT);
00255 #endif
00256 
00257 #ifdef IPPROTO_TCP
00258        REGISTER_LONG_CONSTANT("STREAM_IPPROTO_TCP", IPPROTO_TCP, CONST_CS|CONST_PERSISTENT);
00259 #endif
00260 
00261 #ifdef IPPROTO_UDP
00262        REGISTER_LONG_CONSTANT("STREAM_IPPROTO_UDP", IPPROTO_UDP, CONST_CS|CONST_PERSISTENT);
00263 #endif
00264 
00265 #ifdef IPPROTO_ICMP
00266        REGISTER_LONG_CONSTANT("STREAM_IPPROTO_ICMP", IPPROTO_ICMP, CONST_CS|CONST_PERSISTENT);
00267 #endif
00268 
00269 #ifdef IPPROTO_RAW
00270        REGISTER_LONG_CONSTANT("STREAM_IPPROTO_RAW", IPPROTO_RAW, CONST_CS|CONST_PERSISTENT);
00271 #endif
00272 
00273        REGISTER_LONG_CONSTANT("STREAM_SOCK_STREAM", SOCK_STREAM, CONST_CS|CONST_PERSISTENT);
00274        REGISTER_LONG_CONSTANT("STREAM_SOCK_DGRAM", SOCK_DGRAM, CONST_CS|CONST_PERSISTENT);
00275 
00276 #ifdef SOCK_RAW
00277        REGISTER_LONG_CONSTANT("STREAM_SOCK_RAW", SOCK_RAW, CONST_CS|CONST_PERSISTENT);
00278 #endif
00279 
00280 #ifdef SOCK_SEQPACKET
00281        REGISTER_LONG_CONSTANT("STREAM_SOCK_SEQPACKET", SOCK_SEQPACKET, CONST_CS|CONST_PERSISTENT);
00282 #endif
00283 
00284 #ifdef SOCK_RDM
00285        REGISTER_LONG_CONSTANT("STREAM_SOCK_RDM", SOCK_RDM, CONST_CS|CONST_PERSISTENT);
00286 #endif
00287 
00288        REGISTER_LONG_CONSTANT("STREAM_PEEK", STREAM_PEEK, CONST_CS | CONST_PERSISTENT);
00289        REGISTER_LONG_CONSTANT("STREAM_OOB",  STREAM_OOB, CONST_CS | CONST_PERSISTENT);
00290 
00291        REGISTER_LONG_CONSTANT("STREAM_SERVER_BIND",                   STREAM_XPORT_BIND,                               CONST_CS | CONST_PERSISTENT);
00292        REGISTER_LONG_CONSTANT("STREAM_SERVER_LISTEN",                 STREAM_XPORT_LISTEN,                      CONST_CS | CONST_PERSISTENT);
00293 
00294        REGISTER_LONG_CONSTANT("FILE_USE_INCLUDE_PATH",                PHP_FILE_USE_INCLUDE_PATH,                CONST_CS | CONST_PERSISTENT);
00295        REGISTER_LONG_CONSTANT("FILE_IGNORE_NEW_LINES",                PHP_FILE_IGNORE_NEW_LINES,                CONST_CS | CONST_PERSISTENT);
00296        REGISTER_LONG_CONSTANT("FILE_SKIP_EMPTY_LINES",                PHP_FILE_SKIP_EMPTY_LINES,                CONST_CS | CONST_PERSISTENT);
00297        REGISTER_LONG_CONSTANT("FILE_APPEND",                                 PHP_FILE_APPEND,                                 CONST_CS | CONST_PERSISTENT);
00298        REGISTER_LONG_CONSTANT("FILE_NO_DEFAULT_CONTEXT",              PHP_FILE_NO_DEFAULT_CONTEXT,              CONST_CS | CONST_PERSISTENT);
00299 
00300        REGISTER_LONG_CONSTANT("FILE_TEXT",                                          0,                                                             CONST_CS | CONST_PERSISTENT);
00301        REGISTER_LONG_CONSTANT("FILE_BINARY",                                 0,                                                             CONST_CS | CONST_PERSISTENT);
00302 
00303 #ifdef HAVE_FNMATCH
00304        REGISTER_LONG_CONSTANT("FNM_NOESCAPE", FNM_NOESCAPE, CONST_CS | CONST_PERSISTENT);
00305        REGISTER_LONG_CONSTANT("FNM_PATHNAME", FNM_PATHNAME, CONST_CS | CONST_PERSISTENT);
00306        REGISTER_LONG_CONSTANT("FNM_PERIOD",   FNM_PERIOD,   CONST_CS | CONST_PERSISTENT);
00307 # ifdef FNM_CASEFOLD /* a GNU extension */ /* TODO emulate if not available */
00308        REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_CS | CONST_PERSISTENT);
00309 # endif
00310 #endif
00311 
00312        return SUCCESS;
00313 }
00314 /* }}} */
00315 
00316 PHP_MSHUTDOWN_FUNCTION(file) /* {{{ */
00317 {
00318 #ifndef ZTS
00319        file_globals_dtor(&file_globals TSRMLS_CC);
00320 #endif
00321        return SUCCESS;
00322 }
00323 /* }}} */
00324 
00325 static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
00326 
00327 /* {{{ proto bool flock(resource fp, int operation [, int &wouldblock])
00328    Portable file locking */
00329 PHP_FUNCTION(flock)
00330 {
00331        zval *arg1, *arg3 = NULL;
00332        int act;
00333        php_stream *stream;
00334        long operation = 0;
00335 
00336        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) {
00337               return;
00338        }
00339 
00340        PHP_STREAM_TO_ZVAL(stream, &arg1);
00341 
00342        act = operation & 3;
00343        if (act < 1 || act > 3) {
00344               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal operation argument");
00345               RETURN_FALSE;
00346        }
00347 
00348        if (arg3 && PZVAL_IS_REF(arg3)) {
00349               convert_to_long_ex(&arg3);
00350               Z_LVAL_P(arg3) = 0;
00351        }
00352 
00353        /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
00354        act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
00355        if (php_stream_lock(stream, act)) {
00356               if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
00357                      Z_LVAL_P(arg3) = 1;
00358               }
00359               RETURN_FALSE;
00360        }
00361        RETURN_TRUE;
00362 }
00363 /* }}} */
00364 
00365 #define PHP_META_UNSAFE ".\\+*?[^]$() "
00366 
00367 /* {{{ proto array get_meta_tags(string filename [, bool use_include_path])
00368    Extracts all meta tag content attributes from a file and returns an array */
00369 PHP_FUNCTION(get_meta_tags)
00370 {
00371        char *filename;
00372        int filename_len;
00373        zend_bool use_include_path = 0;
00374        int in_tag = 0, done = 0;
00375        int looking_for_val = 0, have_name = 0, have_content = 0;
00376        int saw_name = 0, saw_content = 0;
00377        char *name = NULL, *value = NULL, *temp = NULL;
00378        php_meta_tags_token tok, tok_last;
00379        php_meta_tags_data md;
00380 
00381        /* Initiailize our structure */
00382        memset(&md, 0, sizeof(md));
00383 
00384        /* Parse arguments */
00385        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &filename, &filename_len, &use_include_path) == FAILURE) {
00386               return;
00387        }
00388 
00389        if (strlen(filename) != filename_len) {
00390               RETURN_FALSE;
00391        }
00392 
00393        md.stream = php_stream_open_wrapper(filename, "rb",
00394                      (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
00395                      NULL);
00396        if (!md.stream)      {
00397               RETURN_FALSE;
00398        }
00399 
00400        array_init(return_value);
00401 
00402        tok_last = TOK_EOF;
00403 
00404        while (!done && (tok = php_next_meta_token(&md TSRMLS_CC)) != TOK_EOF) {
00405               if (tok == TOK_ID) {
00406                      if (tok_last == TOK_OPENTAG) {
00407                             md.in_meta = !strcasecmp("meta", md.token_data);
00408                      } else if (tok_last == TOK_SLASH && in_tag) {
00409                             if (strcasecmp("head", md.token_data) == 0) {
00410                                    /* We are done here! */
00411                                    done = 1;
00412                             }
00413                      } else if (tok_last == TOK_EQUAL && looking_for_val) {
00414                             if (saw_name) {
00415                                    STR_FREE(name);
00416                                    /* Get the NAME attr (Single word attr, non-quoted) */
00417                                    temp = name = estrndup(md.token_data, md.token_len);
00418 
00419                                    while (temp && *temp) {
00420                                           if (strchr(PHP_META_UNSAFE, *temp)) {
00421                                                  *temp = '_';
00422                                           }
00423                                           temp++;
00424                                    }
00425 
00426                                    have_name = 1;
00427                             } else if (saw_content) {
00428                                    STR_FREE(value);
00429                                    /* Get the CONTENT attr (Single word attr, non-quoted) */
00430                                    if (PG(magic_quotes_runtime)) {
00431                                           value = php_addslashes(md.token_data, 0, &md.token_len, 0 TSRMLS_CC);
00432                                    } else {
00433                                           value = estrndup(md.token_data, md.token_len);
00434                                    }
00435 
00436                                    have_content = 1;
00437                             }
00438 
00439                             looking_for_val = 0;
00440                      } else {
00441                             if (md.in_meta) {
00442                                    if (strcasecmp("name", md.token_data) == 0) {
00443                                           saw_name = 1;
00444                                           saw_content = 0;
00445                                           looking_for_val = 1;
00446                                    } else if (strcasecmp("content", md.token_data) == 0) {
00447                                           saw_name = 0;
00448                                           saw_content = 1;
00449                                           looking_for_val = 1;
00450                                    }
00451                             }
00452                      }
00453               } else if (tok == TOK_STRING && tok_last == TOK_EQUAL && looking_for_val) {
00454                      if (saw_name) {
00455                             STR_FREE(name);
00456                             /* Get the NAME attr (Quoted single/double) */
00457                             temp = name = estrndup(md.token_data, md.token_len);
00458 
00459                             while (temp && *temp) {
00460                                    if (strchr(PHP_META_UNSAFE, *temp)) {
00461                                           *temp = '_';
00462                                    }
00463                                    temp++;
00464                             }
00465 
00466                             have_name = 1;
00467                      } else if (saw_content) {
00468                             STR_FREE(value);
00469                             /* Get the CONTENT attr (Single word attr, non-quoted) */
00470                             if (PG(magic_quotes_runtime)) {
00471                                    value = php_addslashes(md.token_data, 0, &md.token_len, 0 TSRMLS_CC);
00472                             } else {
00473                                    value = estrndup(md.token_data, md.token_len);
00474                             }
00475 
00476                             have_content = 1;
00477                      }
00478 
00479                      looking_for_val = 0;
00480               } else if (tok == TOK_OPENTAG) {
00481                      if (looking_for_val) {
00482                             looking_for_val = 0;
00483                             have_name = saw_name = 0;
00484                             have_content = saw_content = 0;
00485                      }
00486                      in_tag = 1;
00487               } else if (tok == TOK_CLOSETAG) {
00488                      if (have_name) {
00489                             /* For BC */
00490                             php_strtolower(name, strlen(name));
00491                             if (have_content) {
00492                                    add_assoc_string(return_value, name, value, 1);
00493                             } else {
00494                                    add_assoc_string(return_value, name, "", 1);
00495                             }
00496 
00497                             efree(name);
00498                             STR_FREE(value);
00499                      } else if (have_content) {
00500                             efree(value);
00501                      }
00502 
00503                      name = value = NULL;
00504 
00505                      /* Reset all of our flags */
00506                      in_tag = looking_for_val = 0;
00507                      have_name = saw_name = 0;
00508                      have_content = saw_content = 0;
00509                      md.in_meta = 0;
00510               }
00511 
00512               tok_last = tok;
00513 
00514               if (md.token_data)
00515                      efree(md.token_data);
00516 
00517               md.token_data = NULL;
00518        }
00519 
00520        STR_FREE(value);
00521        STR_FREE(name);
00522        php_stream_close(md.stream);
00523 }
00524 /* }}} */
00525 
00526 /* {{{ proto string file_get_contents(string filename [, bool use_include_path [, resource context [, long offset [, long maxlen]]]])
00527    Read the entire file into a string */
00528 PHP_FUNCTION(file_get_contents)
00529 {
00530        char *filename;
00531        int filename_len;
00532        char *contents;
00533        zend_bool use_include_path = 0;
00534        php_stream *stream;
00535        int len;
00536        long offset = -1;
00537        long maxlen = PHP_STREAM_COPY_ALL;
00538        zval *zcontext = NULL;
00539        php_stream_context *context = NULL;
00540 
00541        /* Parse arguments */
00542        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
00543               return;
00544        }
00545 
00546        if (strlen(filename) != filename_len) {
00547               RETURN_FALSE;
00548        }
00549 
00550        if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
00551               php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
00552               RETURN_FALSE;
00553        }
00554 
00555        context = php_stream_context_from_zval(zcontext, 0);
00556 
00557        stream = php_stream_open_wrapper_ex(filename, "rb",
00558                             (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
00559                             NULL, context);
00560        if (!stream) {
00561               RETURN_FALSE;
00562        }
00563 
00564        if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
00565               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
00566               php_stream_close(stream);
00567               RETURN_FALSE;
00568        }
00569 
00570        if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
00571 
00572               if (PG(magic_quotes_runtime)) {
00573                      contents = php_addslashes(contents, len, &len, 1 TSRMLS_CC); /* 1 = free source string */
00574               }
00575 
00576               RETVAL_STRINGL(contents, len, 0);
00577        } else if (len == 0) {
00578               RETVAL_EMPTY_STRING();
00579        } else {
00580               RETVAL_FALSE;
00581        }
00582 
00583        php_stream_close(stream);
00584 }
00585 /* }}} */
00586 
00587 /* {{{ proto int file_put_contents(string file, mixed data [, int flags [, resource context]])
00588    Write/Create a file with contents data and return the number of bytes written */
00589 PHP_FUNCTION(file_put_contents)
00590 {
00591        php_stream *stream;
00592        char *filename;
00593        int filename_len;
00594        zval *data;
00595        int numbytes = 0;
00596        long flags = 0;
00597        zval *zcontext = NULL;
00598        php_stream_context *context = NULL;
00599        php_stream *srcstream = NULL;
00600        char mode[3] = "wb";
00601 
00602        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|lr!", &filename, &filename_len, &data, &flags, &zcontext) == FAILURE) {
00603               return;
00604        }
00605 
00606        if (strlen(filename) != filename_len) {
00607               RETURN_FALSE;
00608        }
00609 
00610        if (Z_TYPE_P(data) == IS_RESOURCE) {
00611               php_stream_from_zval(srcstream, &data);
00612        }
00613 
00614        context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
00615 
00616        if (flags & PHP_FILE_APPEND) {
00617               mode[0] = 'a';
00618        } else if (flags & LOCK_EX) {
00619               /* check to make sure we are dealing with a regular file */
00620               if (php_memnstr(filename, "://", sizeof("://") - 1, filename + filename_len)) {
00621                      if (strncasecmp(filename, "file://", sizeof("file://") - 1)) {
00622                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks may only be set for regular files");
00623                             RETURN_FALSE;
00624                      }
00625               }
00626               mode[0] = 'c';
00627        }
00628        mode[2] = '\0';
00629 
00630        stream = php_stream_open_wrapper_ex(filename, mode, ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
00631        if (stream == NULL) {
00632               RETURN_FALSE;
00633        }
00634 
00635        if (flags & LOCK_EX && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) {
00636               php_stream_close(stream);
00637               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks are not supported for this stream");
00638               RETURN_FALSE;
00639        }
00640 
00641        if (mode[0] == 'c') {
00642               php_stream_truncate_set_size(stream, 0);
00643        }
00644 
00645        switch (Z_TYPE_P(data)) {
00646               case IS_RESOURCE: {
00647                      size_t len;
00648                      if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
00649                             numbytes = -1;
00650                      } else {
00651                             numbytes = len;
00652                      }
00653                      break;
00654               }
00655               case IS_NULL:
00656               case IS_LONG:
00657               case IS_DOUBLE:
00658               case IS_BOOL:
00659               case IS_CONSTANT:
00660                      convert_to_string_ex(&data);
00661 
00662               case IS_STRING:
00663                      if (Z_STRLEN_P(data)) {
00664                             numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
00665                             if (numbytes != Z_STRLEN_P(data)) {
00666                                    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));
00667                                    numbytes = -1;
00668                             }
00669                      }
00670                      break;
00671 
00672               case IS_ARRAY:
00673                      if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
00674                             int bytes_written;
00675                             zval **tmp;
00676                             HashPosition pos;
00677 
00678                             zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
00679                             while (zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &tmp, &pos) == SUCCESS) {
00680                                    if (Z_TYPE_PP(tmp) != IS_STRING) {
00681                                           SEPARATE_ZVAL(tmp);
00682                                           convert_to_string(*tmp);
00683                                    }
00684                                    if (Z_STRLEN_PP(tmp)) {
00685                                           numbytes += Z_STRLEN_PP(tmp);
00686                                           bytes_written = php_stream_write(stream, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
00687                                           if (bytes_written < 0 || bytes_written != Z_STRLEN_PP(tmp)) {
00688                                                  if (bytes_written < 0) {
00689                                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN_PP(tmp), filename);
00690                                                  } else {
00691                                                         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));
00692                                                  }
00693                                                  numbytes = -1;
00694                                                  break;
00695                                           }
00696                                    }
00697                                    zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos);
00698                             }
00699                      }
00700                      break;
00701 
00702               case IS_OBJECT:
00703                      if (Z_OBJ_HT_P(data) != NULL) {
00704                             zval out;
00705 
00706                             if (zend_std_cast_object_tostring(data, &out, IS_STRING TSRMLS_CC) == SUCCESS) {
00707                                    numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out));
00708                                    if (numbytes != Z_STRLEN(out)) {
00709                                           php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out));
00710                                           numbytes = -1;
00711                                    }
00712                                    zval_dtor(&out);
00713                                    break;
00714                             }
00715                      }
00716               default:
00717                      numbytes = -1;
00718                      break;
00719        }
00720        php_stream_close(stream);
00721 
00722        if (numbytes < 0) {
00723               RETURN_FALSE;
00724        }
00725 
00726        RETURN_LONG(numbytes);
00727 }
00728 /* }}} */
00729 
00730 #define PHP_FILE_BUF_SIZE   80
00731 
00732 /* {{{ proto array file(string filename [, int flags[, resource context]])
00733    Read entire file into an array */
00734 PHP_FUNCTION(file)
00735 {
00736        char *filename;
00737        int filename_len;
00738        char *slashed, *target_buf=NULL, *p, *s, *e;
00739        register int i = 0;
00740        int target_len, len;
00741        char eol_marker = '\n';
00742        long flags = 0;
00743        zend_bool use_include_path;
00744        zend_bool include_new_line;
00745        zend_bool skip_blank_lines;
00746        php_stream *stream;
00747        zval *zcontext = NULL;
00748        php_stream_context *context = NULL;
00749 
00750        /* Parse arguments */
00751        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr!", &filename, &filename_len, &flags, &zcontext) == FAILURE) {
00752               return;
00753        }
00754 
00755        if (strlen(filename) != filename_len) {
00756               RETURN_FALSE;
00757        }
00758 
00759        if (flags < 0 || flags > (PHP_FILE_USE_INCLUDE_PATH | PHP_FILE_IGNORE_NEW_LINES | PHP_FILE_SKIP_EMPTY_LINES | PHP_FILE_NO_DEFAULT_CONTEXT)) {
00760               php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%ld' flag is not supported", flags);
00761               RETURN_FALSE;
00762        }
00763 
00764        use_include_path = flags & PHP_FILE_USE_INCLUDE_PATH;
00765        include_new_line = !(flags & PHP_FILE_IGNORE_NEW_LINES);
00766        skip_blank_lines = flags & PHP_FILE_SKIP_EMPTY_LINES;
00767 
00768        context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
00769 
00770        stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
00771        if (!stream) {
00772               RETURN_FALSE;
00773        }
00774 
00775        /* Initialize return array */
00776        array_init(return_value);
00777 
00778        if ((target_len = php_stream_copy_to_mem(stream, &target_buf, PHP_STREAM_COPY_ALL, 0))) {
00779               s = target_buf;
00780               e = target_buf + target_len;
00781 
00782               if (!(p = php_stream_locate_eol(stream, target_buf, target_len TSRMLS_CC))) {
00783                      p = e;
00784                      goto parse_eol;
00785               }
00786 
00787               if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
00788                      eol_marker = '\r';
00789               }
00790 
00791               /* for performance reasons the code is duplicated, so that the if (include_new_line)
00792                * will not need to be done for every single line in the file. */
00793               if (include_new_line) {
00794                      do {
00795                             p++;
00796 parse_eol:
00797                             if (PG(magic_quotes_runtime)) {
00798                                    /* s is in target_buf which is freed at the end of the function */
00799                                    slashed = php_addslashes(s, (p-s), &len, 0 TSRMLS_CC);
00800                                    add_index_stringl(return_value, i++, slashed, len, 0);
00801                             } else {
00802                                    add_index_stringl(return_value, i++, estrndup(s, p-s), p-s, 0);
00803                             }
00804                             s = p;
00805                      } while ((p = memchr(p, eol_marker, (e-p))));
00806               } else {
00807                      do {
00808                             int windows_eol = 0;
00809                             if (p != target_buf && eol_marker == '\n' && *(p - 1) == '\r') {
00810                                    windows_eol++;
00811                             }
00812                             if (skip_blank_lines && !(p-s-windows_eol)) {
00813                                    s = ++p;
00814                                    continue;
00815                             }
00816                             if (PG(magic_quotes_runtime)) {
00817                                    /* s is in target_buf which is freed at the end of the function */
00818                                    slashed = php_addslashes(s, (p-s-windows_eol), &len, 0 TSRMLS_CC);
00819                                    add_index_stringl(return_value, i++, slashed, len, 0);
00820                             } else {
00821                                    add_index_stringl(return_value, i++, estrndup(s, p-s-windows_eol), p-s-windows_eol, 0);
00822                             }
00823                             s = ++p;
00824                      } while ((p = memchr(p, eol_marker, (e-p))));
00825               }
00826 
00827               /* handle any left overs of files without new lines */
00828               if (s != e) {
00829                      p = e;
00830                      goto parse_eol;
00831               }
00832        }
00833 
00834        if (target_buf) {
00835               efree(target_buf);
00836        }
00837        php_stream_close(stream);
00838 }
00839 /* }}} */
00840 
00841 /* {{{ proto string tempnam(string dir, string prefix)
00842    Create a unique filename in a directory */
00843 PHP_FUNCTION(tempnam)
00844 {
00845        char *dir, *prefix;
00846        int dir_len, prefix_len;
00847        size_t p_len;
00848        char *opened_path;
00849        char *p;
00850        int fd;
00851 
00852        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) {
00853               return;
00854        }
00855 
00856        if (strlen(dir) != dir_len) {
00857               RETURN_FALSE;
00858        }
00859 
00860        if (strlen(prefix) != prefix_len) {
00861               RETURN_FALSE;
00862        }
00863 
00864        if (PG(safe_mode) &&(!php_checkuid(dir, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
00865               RETURN_FALSE;
00866        }
00867 
00868        if (php_check_open_basedir(dir TSRMLS_CC)) {
00869               RETURN_FALSE;
00870        }
00871 
00872        php_basename(prefix, prefix_len, NULL, 0, &p, &p_len TSRMLS_CC);
00873        if (p_len > 64) {
00874               p[63] = '\0';
00875        }
00876        
00877        RETVAL_FALSE;
00878 
00879        if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) {
00880               close(fd);
00881               RETVAL_STRING(opened_path, 0);
00882        }
00883        efree(p);
00884 }
00885 /* }}} */
00886 
00887 /* {{{ proto resource tmpfile(void)
00888    Create a temporary file that will be deleted automatically after use */
00889 PHP_NAMED_FUNCTION(php_if_tmpfile)
00890 {
00891        php_stream *stream;
00892 
00893        if (zend_parse_parameters_none() == FAILURE) {
00894               return;
00895        }
00896 
00897        stream = php_stream_fopen_tmpfile();
00898 
00899        if (stream) {
00900               php_stream_to_zval(stream, return_value);
00901        } else {
00902               RETURN_FALSE;
00903        }
00904 }
00905 /* }}} */
00906 
00907 /* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]])
00908    Open a file or a URL and return a file pointer */
00909 PHP_NAMED_FUNCTION(php_if_fopen)
00910 {
00911        char *filename, *mode;
00912        int filename_len, mode_len;
00913        zend_bool use_include_path = 0;
00914        zval *zcontext = NULL;
00915        php_stream *stream;
00916        php_stream_context *context = NULL;
00917 
00918        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
00919               RETURN_FALSE;
00920        }
00921 
00922        if (strlen(filename) != filename_len) {
00923               RETURN_FALSE;
00924        }
00925 
00926        context = php_stream_context_from_zval(zcontext, 0);
00927 
00928        stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
00929 
00930        if (stream == NULL) {
00931               RETURN_FALSE;
00932        }
00933 
00934        php_stream_to_zval(stream, return_value);
00935 }
00936 /* }}} */
00937 
00938 /* {{{ proto bool fclose(resource fp)
00939    Close an open file pointer */
00940 PHPAPI PHP_FUNCTION(fclose)
00941 {
00942        zval *arg1;
00943        php_stream *stream;
00944 
00945        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
00946               RETURN_FALSE;
00947        }
00948 
00949        PHP_STREAM_TO_ZVAL(stream, &arg1);
00950 
00951        if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
00952               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid stream resource", stream->rsrc_id);
00953               RETURN_FALSE;
00954        }
00955 
00956        if (!stream->is_persistent) {
00957               zend_list_delete(stream->rsrc_id);
00958        } else {
00959               php_stream_pclose(stream);
00960        }
00961 
00962        RETURN_TRUE;
00963 }
00964 /* }}} */
00965 
00966 /* {{{ proto resource popen(string command, string mode)
00967    Execute a command and open either a read or a write pipe to it */
00968 PHP_FUNCTION(popen)
00969 {
00970        char *command, *mode;
00971        int command_len, mode_len;
00972        FILE *fp;
00973        php_stream *stream;
00974        char *posix_mode, *b, *buf = 0, *tmp;
00975 
00976        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &command, &command_len, &mode, &mode_len) == FAILURE) {
00977               return;
00978        }
00979 
00980        posix_mode = estrndup(mode, mode_len);
00981 #ifndef PHP_WIN32
00982        {
00983               char *z = memchr(posix_mode, 'b', mode_len);
00984               if (z) {
00985                      memmove(z, z + 1, mode_len - (z - posix_mode));
00986               }
00987        }
00988 #endif
00989        if (PG(safe_mode)){
00990               b = strchr(command, ' ');
00991               if (!b) {
00992                      b = strrchr(command, '/');
00993               } else {
00994                      char *c;
00995 
00996                      c = command;
00997                      while((*b != '/') && (b != c)) {
00998                             b--;
00999                      }
01000                      if (b == c) {
01001                             b = NULL;
01002                      }
01003               }
01004 
01005               if (b) {
01006                      spprintf(&buf, 0, "%s%s", PG(safe_mode_exec_dir), b);
01007               } else {
01008                      spprintf(&buf, 0, "%s/%s", PG(safe_mode_exec_dir), command);
01009               }
01010 
01011               tmp = php_escape_shell_cmd(buf);
01012               fp = VCWD_POPEN(tmp, posix_mode);
01013               efree(tmp);
01014 
01015               if (!fp) {
01016                      php_error_docref2(NULL TSRMLS_CC, buf, posix_mode, E_WARNING, "%s", strerror(errno));
01017                      efree(posix_mode);
01018                      efree(buf);
01019                      RETURN_FALSE;
01020               }
01021 
01022               efree(buf);
01023 
01024        } else {
01025               fp = VCWD_POPEN(command, posix_mode);
01026               if (!fp) {
01027                      php_error_docref2(NULL TSRMLS_CC, command, posix_mode, E_WARNING, "%s", strerror(errno));
01028                      efree(posix_mode);
01029                      RETURN_FALSE;
01030               }
01031        }
01032        stream = php_stream_fopen_from_pipe(fp, mode);
01033 
01034        if (stream == NULL)  {
01035               php_error_docref2(NULL TSRMLS_CC, command, mode, E_WARNING, "%s", strerror(errno));
01036               RETVAL_FALSE;
01037        } else {
01038               php_stream_to_zval(stream, return_value);
01039        }
01040 
01041        efree(posix_mode);
01042 }
01043 /* }}} */
01044 
01045 /* {{{ proto int pclose(resource fp)
01046    Close a file pointer opened by popen() */
01047 PHP_FUNCTION(pclose)
01048 {
01049        zval *arg1;
01050        php_stream *stream;
01051 
01052        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01053               RETURN_FALSE;
01054        }
01055 
01056        PHP_STREAM_TO_ZVAL(stream, &arg1);
01057 
01058        zend_list_delete(stream->rsrc_id);
01059        RETURN_LONG(FG(pclose_ret));
01060 }
01061 /* }}} */
01062 
01063 /* {{{ proto bool feof(resource fp)
01064    Test for end-of-file on a file pointer */
01065 PHPAPI PHP_FUNCTION(feof)
01066 {
01067        zval *arg1;
01068        php_stream *stream;
01069 
01070        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01071               RETURN_FALSE;
01072        }
01073 
01074        PHP_STREAM_TO_ZVAL(stream, &arg1);
01075 
01076        if (php_stream_eof(stream)) {
01077               RETURN_TRUE;
01078        } else {
01079               RETURN_FALSE;
01080        }
01081 }
01082 /* }}} */
01083 
01084 /* {{{ proto string fgets(resource fp[, int length])
01085    Get a line from file pointer */
01086 PHPAPI PHP_FUNCTION(fgets)
01087 {
01088        zval *arg1;
01089        long len = 1024;
01090        char *buf = NULL;
01091        int argc = ZEND_NUM_ARGS();
01092        size_t line_len = 0;
01093        php_stream *stream;
01094 
01095        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &len) == FAILURE) {
01096               RETURN_FALSE;
01097        }
01098 
01099        PHP_STREAM_TO_ZVAL(stream, &arg1);
01100 
01101        if (argc == 1) {
01102               /* ask streams to give us a buffer of an appropriate size */
01103               buf = php_stream_get_line(stream, NULL, 0, &line_len);
01104               if (buf == NULL) {
01105                      goto exit_failed;
01106               }
01107        } else if (argc > 1) {
01108               if (len <= 0) {
01109                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
01110                      RETURN_FALSE;
01111               }
01112 
01113               buf = ecalloc(len + 1, sizeof(char));
01114               if (php_stream_get_line(stream, buf, len, &line_len) == NULL) {
01115                      goto exit_failed;
01116               }
01117        }
01118 
01119        if (PG(magic_quotes_runtime)) {
01120               Z_STRVAL_P(return_value) = php_addslashes(buf, line_len, &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
01121               Z_TYPE_P(return_value) = IS_STRING;
01122        } else {
01123               ZVAL_STRINGL(return_value, buf, line_len, 0);
01124               /* resize buffer if it's much larger than the result.
01125                * Only needed if the user requested a buffer size. */
01126               if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) {
01127                      Z_STRVAL_P(return_value) = erealloc(buf, line_len + 1);
01128               }
01129        }
01130        return;
01131 
01132 exit_failed:
01133        RETVAL_FALSE;
01134        if (buf) {
01135               efree(buf);
01136        }
01137 }
01138 /* }}} */
01139 
01140 /* {{{ proto string fgetc(resource fp)
01141    Get a character from file pointer */
01142 PHPAPI PHP_FUNCTION(fgetc)
01143 {
01144        zval *arg1;
01145        char buf[2];
01146        int result;
01147        php_stream *stream;
01148 
01149        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01150               RETURN_FALSE;
01151        }
01152 
01153        PHP_STREAM_TO_ZVAL(stream, &arg1);
01154 
01155        result = php_stream_getc(stream);
01156 
01157        if (result == EOF) {
01158               RETVAL_FALSE;
01159        } else {
01160               buf[0] = result;
01161               buf[1] = '\0';
01162 
01163               RETURN_STRINGL(buf, 1, 1);
01164        }
01165 }
01166 /* }}} */
01167 
01168 /* {{{ proto string fgetss(resource fp [, int length [, string allowable_tags]])
01169    Get a line from file pointer and strip HTML tags */
01170 PHPAPI PHP_FUNCTION(fgetss)
01171 {
01172        zval *fd;
01173        long bytes = 0;
01174        size_t len = 0;
01175        size_t actual_len, retval_len;
01176        char *buf = NULL, *retval;
01177        php_stream *stream;
01178        char *allowed_tags=NULL;
01179        int allowed_tags_len=0;
01180 
01181        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) {
01182               RETURN_FALSE;
01183        }
01184 
01185        PHP_STREAM_TO_ZVAL(stream, &fd);
01186 
01187        if (ZEND_NUM_ARGS() >= 2) {
01188               if (bytes <= 0) {
01189                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
01190                      RETURN_FALSE;
01191               }
01192 
01193               len = (size_t) bytes;
01194               buf = safe_emalloc(sizeof(char), (len + 1), 0);
01195               /*needed because recv doesnt set null char at end*/
01196               memset(buf, 0, len + 1);
01197        }
01198 
01199        if ((retval = php_stream_get_line(stream, buf, len, &actual_len)) == NULL)   {
01200               if (buf != NULL) {
01201                      efree(buf);
01202               }
01203               RETURN_FALSE;
01204        }
01205 
01206        retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len);
01207 
01208        RETURN_STRINGL(retval, retval_len, 0);
01209 }
01210 /* }}} */
01211 
01212 /* {{{ proto mixed fscanf(resource stream, string format [, string ...])
01213    Implements a mostly ANSI compatible fscanf() */
01214 PHP_FUNCTION(fscanf)
01215 {
01216        int result, format_len, type, argc = 0;
01217        zval ***args = NULL;
01218        zval *file_handle;
01219        char *buf, *format;
01220        size_t len;
01221        void *what;
01222 
01223        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs*", &file_handle, &format, &format_len, &args, &argc) == FAILURE) {
01224               return;
01225        }
01226 
01227        what = zend_fetch_resource(&file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, php_file_le_stream(), php_file_le_pstream());
01228 
01229        /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
01230         * with a leak if we have an invalid filehandle. This needs changing
01231         * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */
01232        if (!what) {
01233               if (args) {
01234                      efree(args);
01235               }
01236               RETURN_FALSE;
01237        }
01238 
01239        buf = php_stream_get_line((php_stream *) what, NULL, 0, &len);
01240        if (buf == NULL) {
01241               if (args) {
01242                      efree(args);
01243               }
01244               RETURN_FALSE;
01245        }
01246 
01247        result = php_sscanf_internal(buf, format, argc, args, 0, &return_value TSRMLS_CC);
01248 
01249        if (args) {
01250               efree(args);
01251        }
01252        efree(buf);
01253 
01254        if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
01255               WRONG_PARAM_COUNT;
01256        }
01257 }
01258 /* }}} */
01259 
01260 /* {{{ proto int fwrite(resource fp, string str [, int length])
01261    Binary-safe file write */
01262 PHPAPI PHP_FUNCTION(fwrite)
01263 {
01264        zval *arg1;
01265        char *arg2;
01266        int arg2len;
01267        int ret;
01268        int num_bytes;
01269        long arg3 = 0;
01270        char *buffer = NULL;
01271        php_stream *stream;
01272 
01273        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &arg2, &arg2len, &arg3) == FAILURE) {
01274               RETURN_FALSE;
01275        }
01276 
01277        if (ZEND_NUM_ARGS() == 2) {
01278               num_bytes = arg2len;
01279        } else {
01280               num_bytes = MAX(0, MIN((int)arg3, arg2len));
01281        }
01282 
01283        if (!num_bytes) {
01284               RETURN_LONG(0);
01285        }
01286 
01287        PHP_STREAM_TO_ZVAL(stream, &arg1);
01288 
01289        if (PG(magic_quotes_runtime)) {
01290               buffer = estrndup(arg2, num_bytes);
01291               php_stripslashes(buffer, &num_bytes TSRMLS_CC);
01292        }
01293 
01294        ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes);
01295        if (buffer) {
01296               efree(buffer);
01297        }
01298 
01299        RETURN_LONG(ret);
01300 }
01301 /* }}} */
01302 
01303 /* {{{ proto bool fflush(resource fp)
01304    Flushes output */
01305 PHPAPI PHP_FUNCTION(fflush)
01306 {
01307        zval *arg1;
01308        int ret;
01309        php_stream *stream;
01310 
01311        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01312               RETURN_FALSE;
01313        }
01314 
01315        PHP_STREAM_TO_ZVAL(stream, &arg1);
01316 
01317        ret = php_stream_flush(stream);
01318        if (ret) {
01319               RETURN_FALSE;
01320        }
01321        RETURN_TRUE;
01322 }
01323 /* }}} */
01324 
01325 /* {{{ proto bool rewind(resource fp)
01326    Rewind the position of a file pointer */
01327 PHPAPI PHP_FUNCTION(rewind)
01328 {
01329        zval *arg1;
01330        php_stream *stream;
01331 
01332        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01333               RETURN_FALSE;
01334        }
01335 
01336        PHP_STREAM_TO_ZVAL(stream, &arg1);
01337 
01338        if (-1 == php_stream_rewind(stream)) {
01339               RETURN_FALSE;
01340        }
01341        RETURN_TRUE;
01342 }
01343 /* }}} */
01344 
01345 /* {{{ proto int ftell(resource fp)
01346    Get file pointer's read/write position */
01347 PHPAPI PHP_FUNCTION(ftell)
01348 {
01349        zval *arg1;
01350        long ret;
01351        php_stream *stream;
01352 
01353        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01354               RETURN_FALSE;
01355        }
01356 
01357        PHP_STREAM_TO_ZVAL(stream, &arg1);
01358 
01359        ret = php_stream_tell(stream);
01360        if (ret == -1)       {
01361               RETURN_FALSE;
01362        }
01363        RETURN_LONG(ret);
01364 }
01365 /* }}} */
01366 
01367 /* {{{ proto int fseek(resource fp, int offset [, int whence])
01368    Seek on a file pointer */
01369 PHPAPI PHP_FUNCTION(fseek)
01370 {
01371        zval *arg1;
01372        long arg2, whence = SEEK_SET;
01373        php_stream *stream;
01374 
01375        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &arg2, &whence) == FAILURE) {
01376               RETURN_FALSE;
01377        }
01378 
01379        PHP_STREAM_TO_ZVAL(stream, &arg1);
01380 
01381        RETURN_LONG(php_stream_seek(stream, arg2, whence));
01382 }
01383 /* }}} */
01384 
01385 /* {{{ php_mkdir
01386 */
01387 
01388 /* DEPRECATED APIs: Use php_stream_mkdir() instead */
01389 PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC)
01390 {
01391        int ret;
01392 
01393        if (PG(safe_mode) && (!php_checkuid(dir, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
01394               return -1;
01395        }
01396 
01397        if (php_check_open_basedir(dir TSRMLS_CC)) {
01398               return -1;
01399        }
01400 
01401        if ((ret = VCWD_MKDIR(dir, (mode_t)mode)) < 0 && (options & REPORT_ERRORS)) {
01402               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
01403        }
01404 
01405        return ret;
01406 }
01407 
01408 PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC)
01409 {
01410        return php_mkdir_ex(dir, mode, REPORT_ERRORS TSRMLS_CC);
01411 }
01412 /* }}} */
01413 
01414 /* {{{ proto bool mkdir(string pathname [, int mode [, bool recursive [, resource context]]])
01415    Create a directory */
01416 PHP_FUNCTION(mkdir)
01417 {
01418        char *dir;
01419        int dir_len;
01420        zval *zcontext = NULL;
01421        long mode = 0777;
01422        zend_bool recursive = 0;
01423        php_stream_context *context;
01424 
01425        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbr", &dir, &dir_len, &mode, &recursive, &zcontext) == FAILURE) {
01426               RETURN_FALSE;
01427        }
01428 
01429        if (strlen(dir) != dir_len) {
01430               RETURN_FALSE;
01431        }
01432 
01433        context = php_stream_context_from_zval(zcontext, 0);
01434 
01435        RETURN_BOOL(php_stream_mkdir(dir, mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
01436 }
01437 /* }}} */
01438 
01439 /* {{{ proto bool rmdir(string dirname[, resource context])
01440    Remove a directory */
01441 PHP_FUNCTION(rmdir)
01442 {
01443        char *dir;
01444        int dir_len;
01445        zval *zcontext = NULL;
01446        php_stream_context *context;
01447 
01448        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
01449               RETURN_FALSE;
01450        }
01451 
01452        if (strlen(dir) != dir_len) {
01453               RETURN_FALSE;
01454        }
01455 
01456        context = php_stream_context_from_zval(zcontext, 0);
01457 
01458        RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context));
01459 }
01460 /* }}} */
01461 
01462 /* {{{ proto int readfile(string filename [, bool use_include_path[, resource context]])
01463    Output a file or a URL */
01464 PHP_FUNCTION(readfile)
01465 {
01466        char *filename;
01467        int filename_len;
01468        int size = 0;
01469        zend_bool use_include_path = 0;
01470        zval *zcontext = NULL;
01471        php_stream *stream;
01472        php_stream_context *context = NULL;
01473 
01474        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
01475               RETURN_FALSE;
01476        }
01477 
01478        if (strlen(filename) != filename_len) {
01479               RETURN_FALSE;
01480        }
01481 
01482        context = php_stream_context_from_zval(zcontext, 0);
01483 
01484        stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
01485        if (stream) {
01486               size = php_stream_passthru(stream);
01487               php_stream_close(stream);
01488               RETURN_LONG(size);
01489        }
01490 
01491        RETURN_FALSE;
01492 }
01493 /* }}} */
01494 
01495 /* {{{ proto int umask([int mask])
01496    Return or change the umask */
01497 PHP_FUNCTION(umask)
01498 {
01499        long arg1 = 0;
01500        int oldumask;
01501        
01502        oldumask = umask(077);
01503 
01504        if (BG(umask) == -1) {
01505               BG(umask) = oldumask;
01506        }
01507        
01508        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
01509               RETURN_FALSE;
01510        }
01511 
01512        if (ZEND_NUM_ARGS() == 0) {
01513               umask(oldumask);
01514        } else {
01515               umask(arg1);
01516        }
01517 
01518        RETURN_LONG(oldumask);
01519 }
01520 /* }}} */
01521 
01522 /* {{{ proto int fpassthru(resource fp)
01523    Output all remaining data from a file pointer */
01524 PHPAPI PHP_FUNCTION(fpassthru)
01525 {
01526        zval *arg1;
01527        int size;
01528        php_stream *stream;
01529 
01530        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
01531               RETURN_FALSE;
01532        }
01533 
01534        PHP_STREAM_TO_ZVAL(stream, &arg1);
01535 
01536        size = php_stream_passthru(stream);
01537        RETURN_LONG(size);
01538 }
01539 /* }}} */
01540 
01541 /* {{{ proto bool rename(string old_name, string new_name[, resource context])
01542    Rename a file */
01543 PHP_FUNCTION(rename)
01544 {
01545        char *old_name, *new_name;
01546        int old_name_len, new_name_len;
01547        zval *zcontext = NULL;
01548        php_stream_wrapper *wrapper;
01549        php_stream_context *context;
01550 
01551        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &old_name, &old_name_len, &new_name, &new_name_len, &zcontext) == FAILURE) {
01552               RETURN_FALSE;
01553        }
01554 
01555        if (strlen(old_name) != old_name_len) {
01556               RETURN_FALSE;
01557        }
01558 
01559        if (strlen(new_name) != new_name_len) {
01560               RETURN_FALSE;
01561        }
01562 
01563        wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0 TSRMLS_CC);
01564 
01565        if (!wrapper || !wrapper->wops) {
01566               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
01567               RETURN_FALSE;
01568        }
01569 
01570        if (!wrapper->wops->rename) {
01571               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s wrapper does not support renaming", wrapper->wops->label ? wrapper->wops->label : "Source");
01572               RETURN_FALSE;
01573        }
01574 
01575        if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0 TSRMLS_CC)) {
01576               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rename a file across wrapper types");
01577               RETURN_FALSE;
01578        }
01579 
01580        context = php_stream_context_from_zval(zcontext, 0);
01581 
01582        RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context TSRMLS_CC));
01583 }
01584 /* }}} */
01585 
01586 /* {{{ proto bool unlink(string filename[, context context])
01587    Delete a file */
01588 PHP_FUNCTION(unlink)
01589 {
01590        char *filename;
01591        int filename_len;
01592        php_stream_wrapper *wrapper;
01593        zval *zcontext = NULL;
01594        php_stream_context *context = NULL;
01595 
01596        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &filename, &filename_len, &zcontext) == FAILURE) {
01597               RETURN_FALSE;
01598        }
01599 
01600        if (strlen(filename) != filename_len) {
01601               RETURN_FALSE;
01602        }
01603 
01604        context = php_stream_context_from_zval(zcontext, 0);
01605 
01606        wrapper = php_stream_locate_url_wrapper(filename, NULL, 0 TSRMLS_CC);
01607 
01608        if (!wrapper || !wrapper->wops) {
01609               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper");
01610               RETURN_FALSE;
01611        }
01612 
01613        if (!wrapper->wops->unlink) {
01614               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
01615               RETURN_FALSE;
01616        }
01617        RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC));
01618 }
01619 /* }}} */
01620 
01621 /* {{{ proto bool ftruncate(resource fp, int size)
01622    Truncate file to 'size' length */
01623 PHP_NAMED_FUNCTION(php_if_ftruncate)
01624 {
01625        zval *fp;
01626        long size;
01627        php_stream *stream;
01628 
01629        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &fp, &size) == FAILURE) {
01630               RETURN_FALSE;
01631        }
01632 
01633        PHP_STREAM_TO_ZVAL(stream, &fp);
01634 
01635        if (!php_stream_truncate_supported(stream)) {
01636               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream!");
01637               RETURN_FALSE;
01638        }
01639 
01640        RETURN_BOOL(0 == php_stream_truncate_set_size(stream, size));
01641 }
01642 /* }}} */
01643 
01644 /* {{{ proto array fstat(resource fp)
01645    Stat() on a filehandle */
01646 PHP_NAMED_FUNCTION(php_if_fstat)
01647 {
01648        zval *fp;
01649        zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
01650                *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
01651        php_stream *stream;
01652        php_stream_statbuf stat_ssb;
01653        char *stat_sb_names[13] = {
01654               "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
01655               "size", "atime", "mtime", "ctime", "blksize", "blocks"
01656        };
01657 
01658        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &fp) == FAILURE) {
01659               RETURN_FALSE;
01660        }
01661 
01662        PHP_STREAM_TO_ZVAL(stream, &fp);
01663 
01664        if (php_stream_stat(stream, &stat_ssb)) {
01665               RETURN_FALSE;
01666        }
01667 
01668        array_init(return_value);
01669 
01670        MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev);
01671        MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino);
01672        MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode);
01673        MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink);
01674        MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid);
01675        MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid);
01676 #ifdef HAVE_ST_RDEV
01677        MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev);
01678 #else
01679        MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
01680 #endif
01681        MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size);
01682        MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime);
01683        MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime);
01684        MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime);
01685 #ifdef HAVE_ST_BLKSIZE
01686        MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize);
01687 #else
01688        MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
01689 #endif
01690 #ifdef HAVE_ST_BLOCKS
01691        MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks);
01692 #else
01693        MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
01694 #endif
01695        /* Store numeric indexes in propper order */
01696        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
01697        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
01698        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
01699        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
01700        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
01701        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
01702        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
01703        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
01704        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
01705        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
01706        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
01707        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
01708        zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
01709 
01710        /* Store string indexes referencing the same zval*/
01711        zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *)&stat_dev, sizeof(zval *), NULL);
01712        zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *)&stat_ino, sizeof(zval *), NULL);
01713        zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *)&stat_mode, sizeof(zval *), NULL);
01714        zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *)&stat_nlink, sizeof(zval *), NULL);
01715        zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *)&stat_uid, sizeof(zval *), NULL);
01716        zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *)&stat_gid, sizeof(zval *), NULL);
01717        zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *)&stat_rdev, sizeof(zval *), NULL);
01718        zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *)&stat_size, sizeof(zval *), NULL);
01719        zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *)&stat_atime, sizeof(zval *), NULL);
01720        zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *)&stat_mtime, sizeof(zval *), NULL);
01721        zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *)&stat_ctime, sizeof(zval *), NULL);
01722        zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *)&stat_blksize, sizeof(zval *), NULL);
01723        zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *)&stat_blocks, sizeof(zval *), NULL);
01724 }
01725 /* }}} */
01726 
01727 /* {{{ proto bool copy(string source_file, string destination_file [, resource context])
01728    Copy a file */
01729 PHP_FUNCTION(copy)
01730 {
01731        char *source, *target;
01732        int source_len, target_len;
01733        zval *zcontext = NULL;
01734        php_stream_context *context;
01735 
01736        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &source, &source_len, &target, &target_len, &zcontext) == FAILURE) {
01737               return;
01738        }
01739 
01740        if (strlen(source) != source_len) {
01741               RETURN_FALSE;
01742        }
01743 
01744        if (strlen(target) != target_len) {
01745               RETURN_FALSE;
01746        }
01747 
01748        if (PG(safe_mode) &&(!php_checkuid(source, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
01749               RETURN_FALSE;
01750        }
01751 
01752        if (php_check_open_basedir(source TSRMLS_CC)) {
01753               RETURN_FALSE;
01754        }
01755 
01756        context = php_stream_context_from_zval(zcontext, 0);
01757 
01758        if (php_copy_file_ctx(source, target, 0, context TSRMLS_CC) == SUCCESS) {
01759               RETURN_TRUE;
01760        } else {
01761               RETURN_FALSE;
01762        }
01763 }
01764 /* }}} */
01765 
01766 /* {{{ php_copy_file
01767  */
01768 PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC)
01769 {
01770        return php_copy_file_ctx(src, dest, ENFORCE_SAFE_MODE, NULL TSRMLS_CC);
01771 }
01772 /* }}} */
01773 
01774 /* {{{ php_copy_file_ex
01775  */
01776 PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC)
01777 {
01778        return php_copy_file_ctx(src, dest, ENFORCE_SAFE_MODE, NULL TSRMLS_CC);
01779 }
01780 /* }}} */
01781 
01782 /* {{{ php_copy_file_ctx
01783  */
01784 PHPAPI int php_copy_file_ctx(char *src, char *dest, int src_chk, php_stream_context *context TSRMLS_DC)
01785 {
01786        php_stream *srcstream = NULL, *deststream = NULL;
01787        int ret = FAILURE;
01788        php_stream_statbuf src_s, dest_s;
01789 
01790        switch (php_stream_stat_path_ex(src, 0, &src_s, context)) {
01791               case -1:
01792                      /* non-statable stream */
01793                      goto safe_to_copy;
01794                      break;
01795               case 0:
01796                      break;
01797               default: /* failed to stat file, does not exist? */
01798                      return ret;
01799        }
01800        if (S_ISDIR(src_s.sb.st_mode)) {
01801               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument to copy() function cannot be a directory");
01802               return FAILURE;
01803        }
01804 
01805        switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, context)) {
01806               case -1:
01807                      /* non-statable stream */
01808                      goto safe_to_copy;
01809                      break;
01810               case 0:
01811                      break;
01812               default: /* failed to stat file, does not exist? */
01813                      return ret;
01814        }
01815        if (S_ISDIR(dest_s.sb.st_mode)) {
01816               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument to copy() function cannot be a directory");
01817               return FAILURE;
01818        }
01819        if (!src_s.sb.st_ino || !dest_s.sb.st_ino) {
01820               goto no_stat;
01821        }
01822        if (src_s.sb.st_ino == dest_s.sb.st_ino && src_s.sb.st_dev == dest_s.sb.st_dev) {
01823               return ret;
01824        } else {
01825               goto safe_to_copy;
01826        }
01827 no_stat:
01828        {
01829               char *sp, *dp;
01830               int res;
01831 
01832               if ((sp = expand_filepath(src, NULL TSRMLS_CC)) == NULL) {
01833                      return ret;
01834               }
01835               if ((dp = expand_filepath(dest, NULL TSRMLS_CC)) == NULL) {
01836                      efree(sp);
01837                      goto safe_to_copy;
01838               }
01839 
01840               res =
01841 #ifndef PHP_WIN32
01842                      !strcmp(sp, dp);
01843 #else
01844                      !strcasecmp(sp, dp);
01845 #endif
01846 
01847               efree(sp);
01848               efree(dp);
01849               if (res) {
01850                      return ret;
01851               }
01852        }
01853 safe_to_copy:
01854 
01855        srcstream = php_stream_open_wrapper_ex(src, "rb", src_chk | REPORT_ERRORS, NULL, context);
01856 
01857        if (!srcstream) {
01858               return ret;
01859        }
01860 
01861        deststream = php_stream_open_wrapper_ex(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
01862 
01863        if (srcstream && deststream) {
01864               ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL, NULL);
01865        }
01866        if (srcstream) {
01867               php_stream_close(srcstream);
01868        }
01869        if (deststream) {
01870               php_stream_close(deststream);
01871        }
01872        return ret;
01873 }
01874 /* }}} */
01875 
01876 /* {{{ proto string fread(resource fp, int length)
01877    Binary-safe file read */
01878 PHPAPI PHP_FUNCTION(fread)
01879 {
01880        zval *arg1;
01881        long len;
01882        php_stream *stream;
01883 
01884        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &len) == FAILURE) {
01885               RETURN_FALSE;
01886        }
01887 
01888        PHP_STREAM_TO_ZVAL(stream, &arg1);
01889 
01890        if (len <= 0) {
01891               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
01892               RETURN_FALSE;
01893        }
01894 
01895        Z_STRVAL_P(return_value) = emalloc(len + 1);
01896        Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len);
01897 
01898        /* needed because recv/read/gzread doesnt put a null at the end*/
01899        Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
01900 
01901        if (PG(magic_quotes_runtime)) {
01902               Z_STRVAL_P(return_value) = php_addslashes(Z_STRVAL_P(return_value),
01903                             Z_STRLEN_P(return_value), &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
01904        }
01905        Z_TYPE_P(return_value) = IS_STRING;
01906 }
01907 /* }}} */
01908 
01909 static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t len, const char delimiter TSRMLS_DC) /* {{{ */
01910 {
01911        int inc_len;
01912        unsigned char last_chars[2] = { 0, 0 };
01913 
01914        while (len > 0) {
01915               inc_len = (*ptr == '\0' ? 1: php_mblen(ptr, len));
01916               switch (inc_len) {
01917                      case -2:
01918                      case -1:
01919                             inc_len = 1;
01920                             php_mblen(NULL, 0);
01921                             break;
01922                      case 0:
01923                             goto quit_loop;
01924                      case 1:
01925                      default:
01926                             last_chars[0] = last_chars[1];
01927                             last_chars[1] = *ptr;
01928                             break;
01929               }
01930               ptr += inc_len;
01931               len -= inc_len;
01932        }
01933 quit_loop:
01934        switch (last_chars[1]) {
01935               case '\n':
01936                      if (last_chars[0] == '\r') {
01937                             return ptr - 2;
01938                      }
01939                      /* break is omitted intentionally */
01940               case '\r':
01941                      return ptr - 1;
01942        }
01943        return ptr;
01944 }
01945 /* }}} */
01946 
01947 #define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field))
01948 
01949 /* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])
01950    Format line as CSV and write to file pointer */
01951 PHP_FUNCTION(fputcsv)
01952 {
01953        char delimiter = ',';       /* allow this to be set as parameter */
01954        char enclosure = '"';       /* allow this to be set as parameter */
01955        const char escape_char = '\\';
01956        php_stream *stream;
01957        int ret;
01958        zval *fp = NULL, *fields = NULL, **field_tmp = NULL, field;
01959        char *delimiter_str = NULL, *enclosure_str = NULL;
01960        int delimiter_str_len = 0, enclosure_str_len = 0;
01961        HashPosition pos;
01962        int count, i = 0;
01963        smart_str csvline = {0};
01964 
01965        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ss",
01966                      &fp, &fields, &delimiter_str, &delimiter_str_len,
01967                      &enclosure_str, &enclosure_str_len) == FAILURE) {
01968               return;
01969        }
01970 
01971        if (delimiter_str != NULL) {
01972               /* Make sure that there is at least one character in string */
01973               if (delimiter_str_len < 1) {
01974                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
01975                      RETURN_FALSE;
01976               } else if (delimiter_str_len > 1) {
01977                      php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
01978               }
01979 
01980               /* use first character from string */
01981               delimiter = *delimiter_str;
01982        }
01983 
01984        if (enclosure_str != NULL) {
01985               if (enclosure_str_len < 1) {
01986                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
01987                      RETURN_FALSE;
01988               } else if (enclosure_str_len > 1) {
01989                      php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
01990               }
01991               /* use first character from string */
01992               enclosure = *enclosure_str;
01993        }
01994 
01995        PHP_STREAM_TO_ZVAL(stream, &fp);
01996 
01997        count = zend_hash_num_elements(Z_ARRVAL_P(fields));
01998        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
01999        while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field_tmp, &pos) == SUCCESS) {
02000               field = **field_tmp;
02001 
02002               if (Z_TYPE_PP(field_tmp) != IS_STRING) {
02003                      zval_copy_ctor(&field);
02004                      convert_to_string(&field);
02005               }
02006 
02007               /* enclose a field that contains a delimiter, an enclosure character, or a newline */
02008               if (FPUTCSV_FLD_CHK(delimiter) ||
02009                      FPUTCSV_FLD_CHK(enclosure) ||
02010                      FPUTCSV_FLD_CHK(escape_char) ||
02011                      FPUTCSV_FLD_CHK('\n') ||
02012                      FPUTCSV_FLD_CHK('\r') ||
02013                      FPUTCSV_FLD_CHK('\t') ||
02014                      FPUTCSV_FLD_CHK(' ')
02015               ) {
02016                      char *ch = Z_STRVAL(field);
02017                      char *end = ch + Z_STRLEN(field);
02018                      int escaped = 0;
02019 
02020                      smart_str_appendc(&csvline, enclosure);
02021                      while (ch < end) {
02022                             if (*ch == escape_char) {
02023                                    escaped = 1;
02024                             } else if (!escaped && *ch == enclosure) {
02025                                    smart_str_appendc(&csvline, enclosure);
02026                             } else {
02027                                    escaped = 0;
02028                             }
02029                             smart_str_appendc(&csvline, *ch);
02030                             ch++;
02031                      }
02032                      smart_str_appendc(&csvline, enclosure);
02033               } else {
02034                      smart_str_appendl(&csvline, Z_STRVAL(field), Z_STRLEN(field));
02035               }
02036 
02037               if (++i != count) {
02038                      smart_str_appendl(&csvline, &delimiter, 1);
02039               }
02040               zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);
02041 
02042               if (Z_TYPE_PP(field_tmp) != IS_STRING) {
02043                      zval_dtor(&field);
02044               }
02045        }
02046 
02047        smart_str_appendc(&csvline, '\n');
02048        smart_str_0(&csvline);
02049 
02050        if (!PG(magic_quotes_runtime)) {
02051               ret = php_stream_write(stream, csvline.c, csvline.len);
02052        } else {
02053               char *buffer = estrndup(csvline.c, csvline.len);
02054               int len = csvline.len;
02055               php_stripslashes(buffer, &len TSRMLS_CC);
02056               ret = php_stream_write(stream, buffer, len);
02057               efree(buffer);
02058        }
02059 
02060        smart_str_free(&csvline);
02061 
02062        RETURN_LONG(ret);
02063 }
02064 /* }}} */
02065 
02066 /* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, string enclosure [, string escape]]]])
02067    Get line from file pointer and parse for CSV fields */
02068 PHP_FUNCTION(fgetcsv)
02069 {
02070        char delimiter = ',';       /* allow this to be set as parameter */
02071        char enclosure = '"';       /* allow this to be set as parameter */
02072        char escape = '\\';
02073 
02074        /* first section exactly as php_fgetss */
02075 
02076        long len = 0;
02077        size_t buf_len;
02078        char *buf;
02079        php_stream *stream;
02080 
02081        {
02082               zval *fd, **len_zv = NULL;
02083               char *delimiter_str = NULL;
02084               int delimiter_str_len = 0;
02085               char *enclosure_str = NULL;
02086               int enclosure_str_len = 0;
02087               char *escape_str = NULL;
02088               int escape_str_len = 0;
02089 
02090               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|Zsss",
02091                      &fd, &len_zv, &delimiter_str, &delimiter_str_len,
02092                      &enclosure_str, &enclosure_str_len,
02093                      &escape_str, &escape_str_len) == FAILURE
02094               ) {
02095                      return;
02096               }
02097 
02098               if (delimiter_str != NULL) {
02099                      /* Make sure that there is at least one character in string */
02100                      if (delimiter_str_len < 1) {
02101                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
02102                             RETURN_FALSE;
02103                      } else if (delimiter_str_len > 1) {
02104                             php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be a single character");
02105                      }
02106 
02107                      /* use first character from string */
02108                      delimiter = delimiter_str[0];
02109               }
02110 
02111               if (enclosure_str != NULL) {
02112                      if (enclosure_str_len < 1) {
02113                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
02114                             RETURN_FALSE;
02115                      } else if (enclosure_str_len > 1) {
02116                             php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be a single character");
02117                      }
02118 
02119                      /* use first character from string */
02120                      enclosure = enclosure_str[0];
02121               }
02122 
02123               if (escape_str != NULL) {
02124                      if (escape_str_len < 1) {
02125                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be character");
02126                             RETURN_FALSE;
02127                      } else if (escape_str_len > 1) {
02128                             php_error_docref(NULL TSRMLS_CC, E_NOTICE, "escape must be a single character");
02129                      }
02130 
02131                      escape = escape_str[0];
02132               }
02133 
02134               if (len_zv != NULL && Z_TYPE_PP(len_zv) != IS_NULL) {
02135                      convert_to_long_ex(len_zv);
02136                      len = Z_LVAL_PP(len_zv);
02137                      if (len < 0) {
02138                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative");
02139                             RETURN_FALSE;
02140                      } else if (len == 0) {
02141                             len = -1;
02142                      }
02143               } else {
02144                      len = -1;
02145               }
02146 
02147               PHP_STREAM_TO_ZVAL(stream, &fd);
02148        }
02149 
02150        if (len < 0) {
02151               if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) {
02152                      RETURN_FALSE;
02153               }
02154        } else {
02155               buf = emalloc(len + 1);
02156               if (php_stream_get_line(stream, buf, len + 1, &buf_len) == NULL) {
02157                      efree(buf);
02158                      RETURN_FALSE;
02159               }
02160        }
02161 
02162        php_fgetcsv(stream, delimiter, enclosure, escape, buf_len, buf, return_value TSRMLS_CC);
02163 }
02164 /* }}} */
02165 
02166 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) /* {{{ */
02167 {
02168        char *temp, *tptr, *bptr, *line_end, *limit;
02169        size_t temp_len, line_end_len;
02170        int inc_len;
02171        zend_bool first_field = 1;
02172 
02173        /* initialize internal state */
02174        php_mblen(NULL, 0);
02175 
02176        /* Now into new section that parses buf for delimiter/enclosure fields */
02177 
02178        /* Strip trailing space from buf, saving end of line in case required for enclosure field */
02179 
02180        bptr = buf;
02181        tptr = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len, delimiter TSRMLS_CC);
02182        line_end_len = buf_len - (size_t)(tptr - buf);
02183        line_end = limit = tptr;
02184 
02185        /* reserve workspace for building each individual field */
02186        temp_len = buf_len;
02187        temp = emalloc(temp_len + line_end_len + 1);
02188 
02189        /* Initialize return array */
02190        array_init(return_value);
02191 
02192        /* Main loop to read CSV fields */
02193        /* NB this routine will return a single null entry for a blank line */
02194 
02195        do {
02196               char *comp_end, *hunk_begin;
02197 
02198               tptr = temp;
02199               inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
02200               if (inc_len == 1) {
02201                      char *tmp = bptr;
02202                      while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) {
02203                             tmp++;
02204                      }
02205                      if (*tmp == enclosure) {
02206                             bptr = tmp;
02207                      }
02208               }
02209 
02210               if (first_field && bptr == line_end) {
02211                      add_next_index_null(return_value);
02212                      break;
02213               }
02214               first_field = 0;
02215               /* 2. Read field, leaving bptr pointing at start of next field */
02216               if (inc_len != 0 && *bptr == enclosure) {
02217                      int state = 0;
02218 
02219                      bptr++;       /* move on to first character in field */
02220                      hunk_begin = bptr;
02221 
02222                      /* 2A. handle enclosure delimited field */
02223                      for (;;) {
02224                             switch (inc_len) {
02225                                    case 0:
02226                                           switch (state) {
02227                                                  case 2:
02228                                                         memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
02229                                                         tptr += (bptr - hunk_begin - 1);
02230                                                         hunk_begin = bptr;
02231                                                         goto quit_loop_2;
02232 
02233                                                  case 1:
02234                                                         memcpy(tptr, hunk_begin, bptr - hunk_begin);
02235                                                         tptr += (bptr - hunk_begin);
02236                                                         hunk_begin = bptr;
02237                                                         /* break is omitted intentionally */
02238 
02239                                                  case 0: {
02240                                                         char *new_buf;
02241                                                         size_t new_len;
02242                                                         char *new_temp;
02243 
02244                                                         if (hunk_begin != line_end) {
02245                                                                memcpy(tptr, hunk_begin, bptr - hunk_begin);
02246                                                                tptr += (bptr - hunk_begin);
02247                                                                hunk_begin = bptr;
02248                                                         }
02249 
02250                                                         /* add the embedded line end to the field */
02251                                                         memcpy(tptr, line_end, line_end_len);
02252                                                         tptr += line_end_len;
02253 
02254                                                         if (stream == NULL) {
02255                                                                goto quit_loop_2;
02256                                                         } else if ((new_buf = php_stream_get_line(stream, NULL, 0, &new_len)) == NULL) {
02257                                                                /* we've got an unterminated enclosure,
02258                                                                 * assign all the data from the start of
02259                                                                 * the enclosure to end of data to the
02260                                                                 * last element */
02261                                                                if ((size_t)temp_len > (size_t)(limit - buf)) {
02262                                                                       goto quit_loop_2;
02263                                                                }
02264                                                                zval_dtor(return_value);
02265                                                                RETVAL_FALSE;
02266                                                                goto out;
02267                                                         }
02268                                                         temp_len += new_len;
02269                                                         new_temp = erealloc(temp, temp_len);
02270                                                         tptr = new_temp + (size_t)(tptr - temp);
02271                                                         temp = new_temp;
02272 
02273                                                         efree(buf);
02274                                                         buf_len = new_len;
02275                                                         bptr = buf = new_buf;
02276                                                         hunk_begin = buf;
02277 
02278                                                         line_end = limit = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len, delimiter TSRMLS_CC);
02279                                                         line_end_len = buf_len - (size_t)(limit - buf);
02280 
02281                                                         state = 0;
02282                                                  } break;
02283                                           }
02284                                           break;
02285 
02286                                    case -2:
02287                                    case -1:
02288                                           php_mblen(NULL, 0);
02289                                           /* break is omitted intentionally */
02290                                    case 1:
02291                                           /* we need to determine if the enclosure is
02292                                            * 'real' or is it escaped */
02293                                           switch (state) {
02294                                                  case 1: /* escaped */
02295                                                         bptr++;
02296                                                         state = 0;
02297                                                         break;
02298                                                  case 2: /* embedded enclosure ? let's check it */
02299                                                         if (*bptr != enclosure) {
02300                                                                /* real enclosure */
02301                                                                memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
02302                                                                tptr += (bptr - hunk_begin - 1);
02303                                                                hunk_begin = bptr;
02304                                                                goto quit_loop_2;
02305                                                         }
02306                                                         memcpy(tptr, hunk_begin, bptr - hunk_begin);
02307                                                         tptr += (bptr - hunk_begin);
02308                                                         bptr++;
02309                                                         hunk_begin = bptr;
02310                                                         state = 0;
02311                                                         break;
02312                                                  default:
02313                                                         if (*bptr == enclosure) {
02314                                                                state = 2;
02315                                                         } else if (*bptr == escape_char) {
02316                                                                state = 1;
02317                                                         }
02318                                                         bptr++;
02319                                                         break;
02320                                           }
02321                                           break;
02322 
02323                                    default:
02324                                           switch (state) {
02325                                                  case 2:
02326                                                         /* real enclosure */
02327                                                         memcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
02328                                                         tptr += (bptr - hunk_begin - 1);
02329                                                         hunk_begin = bptr;
02330                                                         goto quit_loop_2;
02331                                                  case 1:
02332                                                         bptr += inc_len;
02333                                                         memcpy(tptr, hunk_begin, bptr - hunk_begin);
02334                                                         tptr += (bptr - hunk_begin);
02335                                                         hunk_begin = bptr;
02336                                                         break;
02337                                                  default:
02338                                                         bptr += inc_len;
02339                                                         break;
02340                                           }
02341                                           break;
02342                             }
02343                             inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
02344                      }
02345 
02346               quit_loop_2:
02347                      /* look up for a delimiter */
02348                      for (;;) {
02349                             switch (inc_len) {
02350                                    case 0:
02351                                           goto quit_loop_3;
02352 
02353                                    case -2:
02354                                    case -1:
02355                                           inc_len = 1;
02356                                           php_mblen(NULL, 0);
02357                                           /* break is omitted intentionally */
02358                                    case 1:
02359                                           if (*bptr == delimiter) {
02360                                                  goto quit_loop_3;
02361                                           }
02362                                           break;
02363                                    default:
02364                                           break;
02365                             }
02366                             bptr += inc_len;
02367                             inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
02368                      }
02369 
02370               quit_loop_3:
02371                      memcpy(tptr, hunk_begin, bptr - hunk_begin);
02372                      tptr += (bptr - hunk_begin);
02373                      bptr += inc_len;
02374                      comp_end = tptr;
02375               } else {
02376                      /* 2B. Handle non-enclosure field */
02377 
02378                      hunk_begin = bptr;
02379 
02380                      for (;;) {
02381                             switch (inc_len) {
02382                                    case 0:
02383                                           goto quit_loop_4;
02384                                    case -2:
02385                                    case -1:
02386                                           inc_len = 1;
02387                                           php_mblen(NULL, 0);
02388                                           /* break is omitted intentionally */
02389                                    case 1:
02390                                           if (*bptr == delimiter) {
02391                                                  goto quit_loop_4;
02392                                           }
02393                                           break;
02394                                    default:
02395                                           break;
02396                             }
02397                             bptr += inc_len;
02398                             inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0);
02399                      }
02400               quit_loop_4:
02401                      memcpy(tptr, hunk_begin, bptr - hunk_begin);
02402                      tptr += (bptr - hunk_begin);
02403 
02404                      comp_end = (char *)php_fgetcsv_lookup_trailing_spaces(temp, tptr - temp, delimiter TSRMLS_CC);
02405                      if (*bptr == delimiter) {
02406                             bptr++;
02407                      }
02408               }
02409 
02410               /* 3. Now pass our field back to php */
02411               *comp_end = '\0';
02412               add_next_index_stringl(return_value, temp, comp_end - temp, 1);
02413        } while (inc_len > 0);
02414 
02415 out:
02416        efree(temp);
02417        if (stream) {
02418               efree(buf);
02419        }
02420 }
02421 /* }}} */
02422 
02423 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
02424 /* {{{ proto string realpath(string path)
02425    Return the resolved path */
02426 PHP_FUNCTION(realpath)
02427 {
02428        char *filename;
02429        int filename_len;
02430        char resolved_path_buff[MAXPATHLEN];
02431 
02432        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
02433               return;
02434        }
02435 
02436        if (strlen(filename) != filename_len) {
02437               RETURN_FALSE;
02438        }
02439 
02440        if (VCWD_REALPATH(filename, resolved_path_buff)) {
02441               if (PG(safe_mode) && (!php_checkuid(resolved_path_buff, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
02442                      RETURN_FALSE;
02443               }
02444 
02445               if (php_check_open_basedir(resolved_path_buff TSRMLS_CC)) {
02446                      RETURN_FALSE;
02447               }
02448 
02449 #ifdef ZTS
02450               if (VCWD_ACCESS(resolved_path_buff, F_OK)) {
02451                      RETURN_FALSE;
02452               }
02453 #endif
02454               RETURN_STRING(resolved_path_buff, 1);
02455        } else {
02456               RETURN_FALSE;
02457        }
02458 }
02459 /* }}} */
02460 #endif
02461 
02462 /* See http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.2 */
02463 #define PHP_META_HTML401_CHARS "-_.:"
02464 
02465 /* {{{ php_next_meta_token
02466    Tokenizes an HTML file for get_meta_tags */
02467 php_meta_tags_token php_next_meta_token(php_meta_tags_data *md TSRMLS_DC)
02468 {
02469        int ch = 0, compliment;
02470        char buff[META_DEF_BUFSIZE + 1];
02471 
02472        memset((void *)buff, 0, META_DEF_BUFSIZE + 1);
02473 
02474        while (md->ulc || (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)))) {
02475               if (php_stream_eof(md->stream)) {
02476                      break;
02477               }
02478 
02479               if (md->ulc) {
02480                      ch = md->lc;
02481                      md->ulc = 0;
02482               }
02483 
02484               switch (ch) {
02485                      case '<':
02486                             return TOK_OPENTAG;
02487                             break;
02488 
02489                      case '>':
02490                             return TOK_CLOSETAG;
02491                             break;
02492 
02493                      case '=':
02494                             return TOK_EQUAL;
02495                             break;
02496                      case '/':
02497                             return TOK_SLASH;
02498                             break;
02499 
02500                      case '\'':
02501                      case '"':
02502                             compliment = ch;
02503                             md->token_len = 0;
02504                             while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && ch != compliment && ch != '<' && ch != '>') {
02505                                    buff[(md->token_len)++] = ch;
02506 
02507                                    if (md->token_len == META_DEF_BUFSIZE) {
02508                                           break;
02509                                    }
02510                             }
02511 
02512                             if (ch == '<' || ch == '>') {
02513                                    /* Was just an apostrohpe */
02514                                    md->ulc = 1;
02515                                    md->lc = ch;
02516                             }
02517 
02518                             /* We don't need to alloc unless we are in a meta tag */
02519                             if (md->in_meta) {
02520                                    md->token_data = (char *) emalloc(md->token_len + 1);
02521                                    memcpy(md->token_data, buff, md->token_len+1);
02522                             }
02523 
02524                             return TOK_STRING;
02525                             break;
02526 
02527                      case '\n':
02528                      case '\r':
02529                      case '\t':
02530                             break;
02531 
02532                      case ' ':
02533                             return TOK_SPACE;
02534                             break;
02535 
02536                      default:
02537                             if (isalnum(ch)) {
02538                                    md->token_len = 0;
02539                                    buff[(md->token_len)++] = ch;
02540                                    while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && (isalnum(ch) || strchr(PHP_META_HTML401_CHARS, ch))) {
02541                                           buff[(md->token_len)++] = ch;
02542 
02543                                           if (md->token_len == META_DEF_BUFSIZE) {
02544                                                  break;
02545                                           }
02546                                    }
02547 
02548                                    /* This is ugly, but we have to replace ungetc */
02549                                    if (!isalpha(ch) && ch != '-') {
02550                                           md->ulc = 1;
02551                                           md->lc = ch;
02552                                    }
02553 
02554                                    md->token_data = (char *) emalloc(md->token_len + 1);
02555                                    memcpy(md->token_data, buff, md->token_len+1);
02556 
02557                                    return TOK_ID;
02558                             } else {
02559                                    return TOK_OTHER;
02560                             }
02561                             break;
02562               }
02563        }
02564 
02565        return TOK_EOF;
02566 }
02567 /* }}} */
02568 
02569 #ifdef HAVE_FNMATCH
02570 /* {{{ proto bool fnmatch(string pattern, string filename [, int flags])
02571    Match filename against pattern */
02572 PHP_FUNCTION(fnmatch)
02573 {
02574        char *pattern, *filename;
02575        int pattern_len, filename_len;
02576        long flags = 0;
02577 
02578        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &pattern, &pattern_len, &filename, &filename_len, &flags) == FAILURE) {
02579               return;
02580        }
02581 
02582        if (strlen(pattern) != pattern_len) {
02583               RETURN_FALSE;
02584        }
02585 
02586        if (strlen(filename) != filename_len) {
02587               RETURN_FALSE;
02588        }
02589        
02590        if (filename_len >= MAXPATHLEN) {
02591               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN);
02592               RETURN_FALSE;
02593        }
02594        if (pattern_len >= MAXPATHLEN) {
02595               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
02596               RETURN_FALSE;
02597        }
02598 
02599        RETURN_BOOL( ! fnmatch( pattern, filename, flags ));
02600 }
02601 /* }}} */
02602 #endif
02603 
02604 /* {{{ proto string sys_get_temp_dir()
02605    Returns directory path used for temporary files */
02606 PHP_FUNCTION(sys_get_temp_dir)
02607 {
02608        if (zend_parse_parameters_none() == FAILURE) {
02609               return;
02610        }
02611        RETURN_STRING((char *)php_get_temporary_directory(), 1);
02612 }
02613 /* }}} */
02614 
02615 /*
02616  * Local variables:
02617  * tab-width: 4
02618  * c-basic-offset: 4
02619  * End:
02620  * vim600: noet sw=4 ts=4 fdm=marker
02621  * vim<600: noet sw=4 ts=4
02622  */