diff options
-rw-r--r-- | ext/standard/basic_functions.c | 28 | ||||
-rw-r--r-- | ext/standard/dir.c | 78 | ||||
-rw-r--r-- | ext/standard/ftp_fopen_wrapper.c | 3 | ||||
-rw-r--r-- | ext/standard/http_fopen_wrapper.c | 3 | ||||
-rw-r--r-- | ext/standard/php_fopen_wrapper.c | 3 | ||||
-rw-r--r-- | ext/zlib/zlib.c | 7 | ||||
-rw-r--r-- | ext/zlib/zlib_fopen_wrapper.c | 5 | ||||
-rw-r--r-- | main/php.h | 9 | ||||
-rwxr-xr-x | main/php_streams.h | 31 | ||||
-rwxr-xr-x | main/streams.c | 269 | ||||
-rw-r--r-- | pear/scripts/pear.in | 1 | ||||
-rw-r--r-- | pear/scripts/pearize.in | 2 |
12 files changed, 296 insertions, 143 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 3a10750302..6a2ab33467 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -983,21 +983,14 @@ PHP_MINIT_FUNCTION(basic) PHP_MINIT(url_scanner_ex) (INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(proc_open) (INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(user_streams) (INIT_FUNC_ARGS_PASSTHRU); - if (PG(allow_url_fopen)) { - PHP_MINIT(user_streams) (INIT_FUNC_ARGS_PASSTHRU); - - if (FAILURE == php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC)) - return FAILURE; - if (FAILURE == php_register_url_stream_wrapper("php", &php_stream_php_wrapper TSRMLS_CC)) - return FAILURE; - if (FAILURE == php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC)) - return FAILURE; + php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC); + php_register_url_stream_wrapper("php", &php_stream_php_wrapper TSRMLS_CC); + php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC); # if HAVE_OPENSSL_EXT - if (FAILURE == php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC)) - return FAILURE; + php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC); # endif - } return SUCCESS; } @@ -1011,16 +1004,13 @@ PHP_MSHUTDOWN_FUNCTION(basic) basic_globals_dtor(&basic_globals TSRMLS_CC); #endif - if (PG(allow_url_fopen)) { - php_unregister_url_stream_wrapper("http" TSRMLS_CC); - php_unregister_url_stream_wrapper("ftp" TSRMLS_CC); - php_unregister_url_stream_wrapper("php" TSRMLS_CC); + php_unregister_url_stream_wrapper("http" TSRMLS_CC); + php_unregister_url_stream_wrapper("ftp" TSRMLS_CC); + php_unregister_url_stream_wrapper("php" TSRMLS_CC); # if HAVE_OPENSSL_EXT - php_unregister_url_stream_wrapper("https" TSRMLS_CC); + php_unregister_url_stream_wrapper("https" TSRMLS_CC); # endif - } - UNREGISTER_INI_ENTRIES(); PHP_MSHUTDOWN(regex) (SHUTDOWN_FUNC_ARGS_PASSTHRU); diff --git a/ext/standard/dir.c b/ext/standard/dir.c index a4eb21024f..e14eb56dae 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -22,7 +22,7 @@ #include "php.h" #include "fopen_wrappers.h" - +#include "file.h" #include "php_dir.h" #ifdef HAVE_DIRENT_H @@ -55,12 +55,14 @@ int dir_globals_id; php_dir_globals dir_globals; #endif +#if 0 typedef struct { int id; DIR *dir; } php_dir; static int le_dirp; +#endif static zend_class_entry *dir_class_entry_ptr; @@ -72,14 +74,14 @@ static zend_class_entry *dir_class_entry_ptr; php_error(E_WARNING, "unable to find my handle property"); \ RETURN_FALSE; \ } \ - ZEND_FETCH_RESOURCE(dirp, php_dir *, tmp, -1, "Directory", le_dirp); \ + ZEND_FETCH_RESOURCE(dirp, php_stream *, tmp, -1, "Directory", php_file_le_stream()); \ } else { \ - ZEND_FETCH_RESOURCE(dirp, php_dir *, 0, DIRG(default_dir), "Directory", le_dirp); \ + ZEND_FETCH_RESOURCE(dirp, php_stream *, 0, DIRG(default_dir), "Directory", php_file_le_stream()); \ } \ } else if ((ZEND_NUM_ARGS() != 1) || zend_get_parameters_ex(1, &id) == FAILURE) { \ WRONG_PARAM_COUNT; \ } else { \ - ZEND_FETCH_RESOURCE(dirp, php_dir *, id,-1, "Directory", le_dirp); \ + ZEND_FETCH_RESOURCE(dirp, php_stream *, id,-1, "Directory", php_file_le_stream()); \ } static zend_function_entry php_dir_class_functions[] = { @@ -103,15 +105,6 @@ static void php_set_default_dir(int id TSRMLS_DC) DIRG(default_dir) = id; } - -static void _dir_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - php_dir *dirp = (php_dir *)rsrc->ptr; - - closedir(dirp->dir); - efree(dirp); -} - PHP_RINIT_FUNCTION(dir) { DIRG(default_dir) = -1; @@ -123,8 +116,6 @@ PHP_MINIT_FUNCTION(dir) static char tmpstr[2]; zend_class_entry dir_class_entry; - le_dirp = zend_register_list_destructors_ex(_dir_dtor, NULL, "dir", module_number); - INIT_CLASS_ENTRY(dir_class_entry, "Directory", php_dir_class_functions); dir_class_entry_ptr = zend_register_internal_class(&dir_class_entry TSRMLS_CC); @@ -144,49 +135,29 @@ PHP_MINIT_FUNCTION(dir) static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject) { pval **arg; - php_dir *dirp; + php_stream *dirp; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg); - - if (php_check_open_basedir(Z_STRVAL_PP(arg) TSRMLS_CC)) { - RETURN_FALSE; - } - if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(arg), NULL, CHECKUID_ALLOW_ONLY_FILE))) { - RETURN_FALSE; - } - - dirp = emalloc(sizeof(php_dir)); - - dirp->dir = VCWD_OPENDIR(Z_STRVAL_PP(arg)); + dirp = php_stream_opendir(Z_STRVAL_PP(arg), ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); -#ifdef PHP_WIN32 - if (!dirp->dir || dirp->dir->finished) { - if (dirp->dir) { - closedir(dirp->dir); - } -#else - if (!dirp->dir) { -#endif - efree(dirp); - php_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno), errno); + if (dirp == NULL) { RETURN_FALSE; } - - dirp->id = zend_list_insert(dirp, le_dirp); - - php_set_default_dir(dirp->id TSRMLS_CC); + + php_set_default_dir(dirp->rsrc_id TSRMLS_CC); if (createobject) { object_init_ex(return_value, dir_class_entry_ptr); add_property_stringl(return_value, "path", Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), 1); - add_property_resource(return_value, "handle", dirp->id); - zend_list_addref(dirp->id); + add_property_resource(return_value, "handle", dirp->rsrc_id); + zend_list_addref(dirp->rsrc_id); /* might not be needed */ + php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */ } else { - RETURN_RESOURCE(dirp->id); + php_stream_to_zval(dirp, return_value); } } @@ -215,13 +186,13 @@ PHP_FUNCTION(getdir) PHP_FUNCTION(closedir) { pval **id, **tmp, *myself; - php_dir *dirp; + php_stream *dirp; FETCH_DIRP(); - zend_list_delete(dirp->id); + zend_list_delete(dirp->rsrc_id); - if (dirp->id == DIRG(default_dir)) { + if (dirp->rsrc_id == DIRG(default_dir)) { php_set_default_dir(-1 TSRMLS_CC); } } @@ -323,11 +294,11 @@ PHP_FUNCTION(getcwd) PHP_FUNCTION(rewinddir) { pval **id, **tmp, *myself; - php_dir *dirp; + php_stream *dirp; FETCH_DIRP(); - rewinddir(dirp->dir); + php_stream_rewinddir(dirp); } /* }}} */ @@ -337,14 +308,13 @@ PHP_FUNCTION(rewinddir) PHP_NAMED_FUNCTION(php_if_readdir) { pval **id, **tmp, *myself; - php_dir *dirp; - char entry[sizeof(struct dirent)+MAXPATHLEN]; - struct dirent *result = (struct dirent *)&entry; /* patch for libc5 readdir problems */ + php_stream *dirp; + php_stream_dirent entry; FETCH_DIRP(); - if (php_readdir_r(dirp->dir, (struct dirent *) entry, &result) == 0 && result) { - RETURN_STRINGL(result->d_name, strlen(result->d_name), 1); + if (php_stream_readdir(dirp, &entry)) { + RETURN_STRINGL(entry.d_name, strlen(entry.d_name), 1); } RETURN_FALSE; } diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 2f3db50593..f37b71e01c 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -97,7 +97,8 @@ static php_stream_wrapper_ops ftp_stream_wops = { php_stream_wrapper php_stream_ftp_wrapper = { &ftp_stream_wops, - NULL + NULL, + 1 /* is_url */ }; diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 994e60d719..05006f2517 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -367,7 +367,8 @@ static php_stream_wrapper_ops http_stream_wops = { php_stream_wrapper php_stream_http_wrapper = { &http_stream_wops, - NULL + NULL, + 1 /* is_url */ }; /* diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 6249aeae98..e2a9eea8b6 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -64,7 +64,8 @@ static php_stream_wrapper_ops php_stdio_wops = { php_stream_wrapper php_stream_php_wrapper = { &php_stdio_wops, - NULL + NULL, + 0, /* is_url */ }; diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 0ddb63e362..fb63e7d123 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -181,9 +181,7 @@ PHP_MINIT_FUNCTION(zlib) #ifdef ZTS ts_allocate_id(&zlib_globals_id, sizeof(zend_zlib_globals), (ts_allocate_ctor) php_zlib_init_globals, NULL); #endif - if(PG(allow_url_fopen)) { - php_register_url_stream_wrapper("zlib", &php_stream_gzip_wrapper TSRMLS_CC); - } + php_register_url_stream_wrapper("zlib", &php_stream_gzip_wrapper TSRMLS_CC); REGISTER_LONG_CONSTANT("FORCE_GZIP", CODING_GZIP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FORCE_DEFLATE", CODING_DEFLATE, CONST_CS | CONST_PERSISTENT); @@ -216,8 +214,7 @@ PHP_RINIT_FUNCTION(zlib) */ PHP_MSHUTDOWN_FUNCTION(zlib) { - if (PG(allow_url_fopen)) - php_unregister_url_stream_wrapper("zlib" TSRMLS_CC); + php_unregister_url_stream_wrapper("zlib" TSRMLS_CC); UNREGISTER_INI_ENTRIES(); diff --git a/ext/zlib/zlib_fopen_wrapper.c b/ext/zlib/zlib_fopen_wrapper.c index bdc2b5a882..0886689634 100644 --- a/ext/zlib/zlib_fopen_wrapper.c +++ b/ext/zlib/zlib_fopen_wrapper.c @@ -132,12 +132,15 @@ php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mod static php_stream_wrapper_ops gzip_stream_wops = { php_stream_gzopen, + NULL, + NULL, NULL }; php_stream_wrapper php_stream_gzip_wrapper = { &gzip_stream_wops, - NULL + NULL, + 0, /* is_url */ }; diff --git a/main/php.h b/main/php.h index 6784e06df9..026e5713e8 100644 --- a/main/php.h +++ b/main/php.h @@ -171,10 +171,6 @@ typedef unsigned int socklen_t; char *strerror(int); #endif -#include "php_streams.h" -#include "php_memory_streams.h" -#include "fopen_wrappers.h" - #if (REGEX == 1 || REGEX == 0) && !defined(NO_REGEX_EXTRA_H) #include "regex/regex_extra.h" #endif @@ -221,6 +217,11 @@ char *strerror(int); # endif #endif +#include "php_streams.h" +#include "php_memory_streams.h" +#include "fopen_wrappers.h" + + /* global variables */ extern pval *data; #if !defined(PHP_WIN32) diff --git a/main/php_streams.h b/main/php_streams.h index aaf7f01e17..af1bcefc23 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -104,6 +104,10 @@ typedef struct _php_stream_statbuf { /* extended info to go here some day */ } php_stream_statbuf; +typedef struct _php_stream_dirent { + char d_name[MAXPATHLEN]; +} php_stream_dirent; + #define PHP_STREAM_NOTIFIER_PROGRESS 1 typedef struct _php_stream_notifier { @@ -128,6 +132,7 @@ typedef struct _php_stream_wrapper_options { * to go here some day */ } php_stream_wrapper_options; +/* operations on streams that are file-handles */ typedef struct _php_stream_ops { /* stdio like functions - these are mandatory! */ size_t (*write)(php_stream *stream, const char *buf, size_t count TSRMLS_DC); @@ -146,22 +151,26 @@ typedef struct _php_stream_ops { typedef struct _php_stream_wrapper_ops { /* open/create a wrapped stream */ - php_stream *(*opener)(php_stream_wrapper *wrapper, char *filename, char *mode, + php_stream *(*stream_opener)(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); /* close/destroy a wrapped stream */ - int (*closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); + int (*stream_closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); /* stat a wrapped stream */ int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); /* stat a URL */ - int (*url_stat)(php_stream_wrapper *wrapper, php_stream_statbuf *ssb TSRMLS_DC); + int (*url_stat)(php_stream_wrapper *wrapper, char *url, php_stream_statbuf *ssb TSRMLS_DC); + /* open a "directory" stream */ + php_stream *(*dir_opener)(php_stream_wrapper *wrapper, char *filename, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); + } php_stream_wrapper_ops; struct _php_stream_wrapper { php_stream_wrapper_ops *wops; /* operations the wrapper can perform */ void *abstract; /* context for the wrapper */ + int is_url; /* so that PG(allow_url_fopen) can be respected */ }; - struct _php_stream { php_stream_ops *ops; void *abstract; /* convenience pointer for abstraction */ @@ -255,12 +264,24 @@ PHPAPI int _php_stream_puts(php_stream *stream, char *buf TSRMLS_DC); PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); #define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) +PHPAPI int _php_stream_stat_path(char *path, php_stream_statbuf *ssb TSRMLS_DC); +#define php_stream_stat_path(path, ssb) _php_stream_stat((path), (ssb) TSRMLS_CC) + +PHPAPI php_stream *_php_stream_opendir(char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC); +#define php_stream_opendir(path, options, context) _php_stream_opendir((path), (options), (context) STREAMS_CC TSRMLS_CC) +PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC); +#define php_stream_readdir(dirstream, dirent) _php_stream_readdir((dirstream), (dirent) TSRMLS_CC) +#define php_stream_closedir(dirstream) php_stream_close((dirstream)) +#define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) + + /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src). * Uses mmap if the src is a plain file and at offset 0 */ #define PHP_STREAM_COPY_ALL -1 PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC); #define php_stream_copy_to_stream(src, dest, maxlen) _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC) + /* read all data from stream and put into a buffer. Caller must free buffer when done. * The copy will use mmap if available. */ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen, @@ -364,7 +385,7 @@ PHPAPI FILE * _php_stream_open_wrapper_as_file(char * path, char * mode, int opt #define php_stream_open_wrapper_as_file(path, mode, options, opened_path) _php_stream_open_wrapper_as_file((path), (mode), (options), (opened_path) STREAMS_CC TSRMLS_CC) /* for user-space streams */ -extern php_stream_ops php_stream_userspace_ops; +PHPAPI extern php_stream_ops php_stream_userspace_ops; #define PHP_STREAM_IS_USERSPACE &php_stream_userspace_ops PHPAPI void php_stream_context_free(php_stream_context *context); diff --git a/main/streams.c b/main/streams.c index 84809d2b57..a6cfccddb8 100755 --- a/main/streams.c +++ b/main/streams.c @@ -45,6 +45,8 @@ #define STREAM_DEBUG 0 +#define STREAM_WRAPPER_PLAIN_FILES ((php_stream_wrapper*)-1) + /* {{{ some macros to help track leaks */ #if ZEND_DEBUG #define emalloc_rel_orig(size) \ @@ -134,8 +136,8 @@ fprintf(stderr, "stream_free: %s:%p in_free=%d opts=%08x\n", stream->ops->label, if (close_options & PHP_STREAM_FREE_RELEASE_STREAM) { - if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->closer) { - stream->wrapper->wops->closer(stream->wrapper, stream TSRMLS_CC); + if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->stream_closer) { + stream->wrapper->wops->stream_closer(stream->wrapper, stream TSRMLS_CC); stream->wrapper = NULL; } @@ -169,7 +171,7 @@ fprintf(stderr, "stream_free: %s:%p in_free=%d opts=%08x\n", stream->ops->label, /* {{{ generic stream operations */ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS_DC) { - return stream->ops->read(stream, buf, size TSRMLS_CC); + return stream->ops->read == NULL ? 0 : stream->ops->read(stream, buf, size TSRMLS_CC); } PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) @@ -177,7 +179,7 @@ PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) /* we define our stream reading function so that it must return EOF when an EOF condition occurs, when working in unbuffered mode and called with these args */ - return stream->ops->read(stream, NULL, 0 TSRMLS_CC) == EOF ? 1 : 0; + return stream->ops->read == NULL ? -1 : stream->ops->read(stream, NULL, 0 TSRMLS_CC) == EOF ? 1 : 0; } PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC) @@ -242,6 +244,8 @@ PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRML if (stream->ops->gets) { return stream->ops->gets(stream, buf, maxlen TSRMLS_CC); + } else if (stream->ops->read == NULL) { + return NULL; } else { /* unbuffered fgets - poor performance ! */ size_t n = 1; @@ -273,7 +277,7 @@ PHPAPI int _php_stream_flush(php_stream *stream TSRMLS_DC) PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { assert(stream); - if (buf == NULL || count == 0) + if (buf == NULL || count == 0 || stream->ops->write == NULL) return 0; return stream->ops->write(stream, buf, count TSRMLS_CC); } @@ -1037,45 +1041,145 @@ exit_success: /* {{{ wrapper init and registration */ int php_init_stream_wrappers(TSRMLS_D) { - if (PG(allow_url_fopen)) { - return zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1); - } - return SUCCESS; + return zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1); } int php_shutdown_stream_wrappers(TSRMLS_D) { - if (PG(allow_url_fopen)) { - zend_hash_destroy(&url_stream_wrappers_hash); - } + zend_hash_destroy(&url_stream_wrappers_hash); return SUCCESS; } PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) { - if (PG(allow_url_fopen)) { - return zend_hash_add(&url_stream_wrappers_hash, protocol, strlen(protocol), wrapper, sizeof(*wrapper), NULL); - } - return FAILURE; + if (!PG(allow_url_fopen) && wrapper->is_url) + return FAILURE; + + return zend_hash_add(&url_stream_wrappers_hash, protocol, strlen(protocol), wrapper, sizeof(*wrapper), NULL); } PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC) { - if (PG(allow_url_fopen)) { - return zend_hash_del(&url_stream_wrappers_hash, protocol, strlen(protocol)); - } - return SUCCESS; + return zend_hash_del(&url_stream_wrappers_hash, protocol, strlen(protocol)); } /* }}} */ -/* {{{ php_stream_open_url */ -static php_stream *php_stream_open_url(char *path, char *mode, int options, - char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + +static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { - php_stream_wrapper *wrapper; + DIR *dir = (DIR*)stream->abstract; + /* avoid libc5 readdir problems */ + char entry[sizeof(struct dirent)+MAXPATHLEN]; + struct dirent *result = (struct dirent *)&entry; + php_stream_dirent *ent = (php_stream_dirent*)buf; + + /* avoid problems if someone mis-uses the stream */ + if (count != sizeof(php_stream_dirent)) + return 0; + + if (php_readdir_r(dir, (struct dirent *)entry, &result) == 0 && result) { + PHP_STRLCPY(ent->d_name, result->d_name, sizeof(ent->d_name), strlen(result->d_name)); + return sizeof(php_stream_dirent); + } + return 0; +} + +static int php_plain_files_dirstream_close(php_stream *stream, int close_handle TSRMLS_DC) +{ + return closedir((DIR *)stream->abstract); +} + +static int php_plain_files_dirstream_rewind(php_stream *stream, off_t offset, int whence TSRMLS_DC) +{ + rewinddir((DIR *)stream->abstract); + return 0; +} + +static php_stream_ops php_plain_files_dirstream_ops = { + NULL, php_plain_files_dirstream_read, + php_plain_files_dirstream_close, NULL, + "dir", + php_plain_files_dirstream_rewind, + NULL, NULL, + NULL +}; + +static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, char *path, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +{ + DIR *dir = NULL; + php_stream *stream = NULL; + + if (php_check_open_basedir(path TSRMLS_CC)) { + return NULL; + } + + if (PG(safe_mode) &&(!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_FILE))) { + return NULL; + } + + dir = VCWD_OPENDIR(path); + +#ifdef PHP_WIN32 + if (dir && dir->finished) { + closedir(dir); + dir = NULL; + } +#endif + if (dir) { + stream = php_stream_alloc(&php_plain_files_dirstream_ops, dir, 0, mode); + if (stream == NULL) + closedir(dir); + } + + return stream; +} + + + +static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +{ + if ((options & USE_PATH) && PG(include_path) != NULL) { + return php_stream_fopen_with_path_rel(path, mode, PG(include_path), opened_path); + } + + if ((options & ENFORCE_SAFE_MODE) && PG(safe_mode) && (!php_checkuid(path, mode, CHECKUID_CHECK_MODE_PARAM))) + return NULL; + + return php_stream_fopen_rel(path, mode, opened_path); +} + +static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, php_stream_statbuf *ssb TSRMLS_DC) +{ + return VCWD_STAT(url, &ssb->sb); +} + +static php_stream_wrapper_ops php_plain_files_wrapper_ops = { + php_plain_files_stream_opener, + NULL, + NULL, + php_plain_files_url_stater, + php_plain_files_dir_opener +}; + +static php_stream_wrapper php_plain_files_wrapper = { + &php_plain_files_wrapper_ops, + NULL, + 0 +}; + +static php_stream_wrapper *locate_url_wrapper(char *path, char **path_for_open, int options TSRMLS_DC) +{ + php_stream_wrapper *wrapper = NULL; const char *p, *protocol = NULL; int n = 0; + *path_for_open = path; + + if (options & IGNORE_URL) + return &php_plain_files_wrapper; + for (p = path; isalnum((int)*p); p++) { n++; } @@ -1103,57 +1207,113 @@ static php_stream *php_stream_open_url(char *path, char *mode, int options, wrapper = NULL; protocol = NULL; } - if (wrapper) { - php_stream *stream = wrapper->wops->opener(wrapper, path, mode, options, opened_path, context STREAMS_REL_CC TSRMLS_CC); - if (stream) - stream->wrapper = wrapper; - return stream; - } } - if (!protocol || !strncasecmp(protocol, "file", n)) { if (protocol && path[n+1] == '/' && path[n+2] == '/') { zend_error(E_WARNING, "remote host file access not supported, %s", path); return NULL; } if (protocol) - path += n + 1; - + *path_for_open = path + n + 1; + /* fall back on regular file access */ - return php_stream_open_wrapper_rel(path, mode, (options & ~REPORT_ERRORS) | IGNORE_URL, - opened_path); + return &php_plain_files_wrapper; } - return NULL; + + if (wrapper && wrapper->is_url && !PG(allow_url_fopen)) { + zend_error(E_WARNING, "URL file-access is disabled in the server configuration"); + return NULL; + } + + return wrapper; +} + +PHPAPI int _php_stream_stat_path(char *path, php_stream_statbuf *ssb TSRMLS_DC) +{ + php_stream_wrapper *wrapper = NULL; + char *path_to_open = path; + + wrapper = locate_url_wrapper(path, &path_to_open, ENFORCE_SAFE_MODE TSRMLS_CC); + if (wrapper && wrapper->wops->url_stat) { + return wrapper->wops->url_stat(wrapper, path_to_open, ssb TSRMLS_CC); + } + return -1; +} + +/* {{{ php_stream_opendir */ +PHPAPI php_stream *_php_stream_opendir(char *path, int options, + php_stream_context *context STREAMS_DC TSRMLS_DC) +{ + php_stream *stream = NULL; + php_stream_wrapper *wrapper = NULL; + char *path_to_open; + + if (!path || !*path) + return NULL; + + path_to_open = path; + + wrapper = locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + + if (wrapper && wrapper->wops->dir_opener) { + stream = wrapper->wops->dir_opener(wrapper, + path_to_open, "r", options, NULL, + context STREAMS_REL_CC TSRMLS_CC); + + if (stream) + stream->wrapper = wrapper; + } + + if (stream == NULL && (options & REPORT_ERRORS)) { + char *tmp = estrdup(path); + char *msg; + + if (wrapper) + msg = strerror(errno); + else + msg = "no suitable wrapper could be found"; + + php_strip_url_passwd(tmp); + zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, msg); + efree(tmp); + } + return stream; } /* }}} */ +PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC) +{ + if (sizeof(php_stream_dirent) == php_stream_read(dirstream, (char*)ent, sizeof(php_stream_dirent))) + return ent; + + return NULL; +} + /* {{{ php_stream_open_wrapper_ex */ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; - + php_stream_wrapper *wrapper = NULL; + char *path_to_open; + if (opened_path) *opened_path = NULL; if (!path || !*path) return NULL; - if (PG(allow_url_fopen) && !(options & IGNORE_URL)) { - stream = php_stream_open_url(path, mode, options, opened_path, context STREAMS_REL_CC TSRMLS_CC); - goto out; - } + path_to_open = path; - if ((options & USE_PATH) && PG(include_path) != NULL) { - stream = php_stream_fopen_with_path_rel(path, mode, PG(include_path), opened_path); - goto out; - } + wrapper = locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); - if ((options & ENFORCE_SAFE_MODE) && PG(safe_mode) && (!php_checkuid(path, mode, CHECKUID_CHECK_MODE_PARAM))) - return NULL; - - stream = php_stream_fopen_rel(path, mode, opened_path); -out: + if (wrapper) { + stream = wrapper->wops->stream_opener(wrapper, + path_to_open, mode, options, + opened_path, context STREAMS_REL_CC TSRMLS_CC); + if (stream) + stream->wrapper = wrapper; + } if (stream != NULL && (options & STREAM_MUST_SEEK)) { php_stream *newstream; @@ -1179,8 +1339,15 @@ out: } if (stream == NULL && (options & REPORT_ERRORS)) { char *tmp = estrdup(path); + char *msg; + + if (wrapper) + msg = strerror(errno); + else + msg = "no suitable wrapper could be found"; + php_strip_url_passwd(tmp); - zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, strerror(errno)); + zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, msg); efree(tmp); } return stream; diff --git a/pear/scripts/pear.in b/pear/scripts/pear.in index a3361edf3f..dc2561d16b 100644 --- a/pear/scripts/pear.in +++ b/pear/scripts/pear.in @@ -186,5 +186,6 @@ function cmdHelp($command) * indent-tabs-mode: nil * End: */ +// vim600:syn=php ?> diff --git a/pear/scripts/pearize.in b/pear/scripts/pearize.in index 1a17d3f2d0..0a9beec459 100644 --- a/pear/scripts/pearize.in +++ b/pear/scripts/pearize.in @@ -1,6 +1,5 @@ #!@prefix@/bin/php -Cq <?php // -*- PHP -*- - main($argc, $argv, $_ENV); // {{{ main() @@ -222,4 +221,5 @@ function cdata_handler($xp, $data) * indent-tabs-mode: t * End: */ +// vim600:syn=php ?> |