]> granicus.if.org Git - php/commitdiff
Always initialize wrappers, regardless of PG(allow_url_fopen).
authorWez Furlong <wez@php.net>
Tue, 16 Apr 2002 22:14:27 +0000 (22:14 +0000)
committerWez Furlong <wez@php.net>
Tue, 16 Apr 2002 22:14:27 +0000 (22:14 +0000)
Add is_url field to wrapper structure; the stream wrapper openers
will disallow opening is is_url && !PG(allow_url_fopen).
Add infrastructure for stat($url) and opendir($url).
Tidy up/centralize code that locates and instantiates wrappers for the
various operations.
Implement opendir for plain files.
Make the PHP opendir and dir functions use the streams implementations.
Add modelines for syntax highlighting the pear scripts in vim

12 files changed:
ext/standard/basic_functions.c
ext/standard/dir.c
ext/standard/ftp_fopen_wrapper.c
ext/standard/http_fopen_wrapper.c
ext/standard/php_fopen_wrapper.c
ext/zlib/zlib.c
ext/zlib/zlib_fopen_wrapper.c
main/php.h
main/php_streams.h
main/streams.c
pear/scripts/pear.in
pear/scripts/pearize.in

index 3a1075030282f1ff98e0f94342369464ea6c1750..6a2ab33467f830ee89fe28b671750dcd715d7034 100644 (file)
@@ -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);
index a4eb21024f9eae735b67b9668d8d45d53ce2df82..e14eb56daeb1534a2f468b1902e18b3cb15061ed 100644 (file)
@@ -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;
 }
index 2f3db505936f5f27d08ea214a6793ca8bc7e6ef0..f37b71e01c63cbfda98be3709e1eb693c42d1bbb 100644 (file)
@@ -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 */
 };
 
 
index 994e60d719f000a5275abf2bc2f560d077fdb239..05006f2517762bcc28a76e1ba71dd1f62f5c6c5c 100644 (file)
@@ -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 */
 };
 
 /*
index 6249aeae984349fea322863a5526ad04a347a8aa..e2a9eea8b6598621baa70cef49118fc80a8fe790 100644 (file)
@@ -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 */
 };
 
 
index 0ddb63e362cf5ab2d2cf2997ca26034f4061351d..fb63e7d12300f6945b91c499270e5424ef20a960 100644 (file)
@@ -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();
 
index bdc2b5a8822c1baf7d6725a983479827e5940d77..0886689634e847feee3187bf556e6a1da1082f0a 100644 (file)
@@ -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 */
 };
 
 
index 6784e06df94d5c4b826eadc62e20a5d6bd14c323..026e5713e80bacfb59619c7ce4808c6b74c5034e 100644 (file)
@@ -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)
index aaf7f01e176e63174b500db809b52edefe7ded66..af1bcefc23913835dbce28d59e458b9d0ec3cc1a 100755 (executable)
@@ -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);
index 84809d2b576da2f4be5c9f5ee3a7486b8fd6a7a2..a6cfccddb84d3be845eab29675d9056e93a5935c 100755 (executable)
@@ -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;
index a3361edf3fa519fdeadd416aefeedfe480d8dd37..dc2561d16bcf4281d69f627668c52269c4ede035 100644 (file)
@@ -186,5 +186,6 @@ function cmdHelp($command)
  * indent-tabs-mode: nil
  * End:
  */
+// vim600:syn=php
 
 ?>
index 1a17d3f2d083db142e40bd58c02a6f3f3dc0f66b..0a9beec459f3cc39a911409cc007232e39946dea 100644 (file)
@@ -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
 ?>