summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/basic_functions.c28
-rw-r--r--ext/standard/dir.c78
-rw-r--r--ext/standard/ftp_fopen_wrapper.c3
-rw-r--r--ext/standard/http_fopen_wrapper.c3
-rw-r--r--ext/standard/php_fopen_wrapper.c3
-rw-r--r--ext/zlib/zlib.c7
-rw-r--r--ext/zlib/zlib_fopen_wrapper.c5
-rw-r--r--main/php.h9
-rwxr-xr-xmain/php_streams.h31
-rwxr-xr-xmain/streams.c269
-rw-r--r--pear/scripts/pear.in1
-rw-r--r--pear/scripts/pearize.in2
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
?>