pollita         Fri Dec 12 23:07:19 2003 EDT

  Modified files:              
    /php-src/main       php_streams.h 
    /php-src/main/streams       streams.c plain_wrapper.c userspace.c 
    /php-src/ext/standard       file.c ftp_fopen_wrapper.c 
                                http_fopen_wrapper.c php_fopen_wrapper.c 
    /php-src/ext/zlib   zlib_fopen_wrapper.c 
    /php-src/ext/bz2    bz2.c 
    /php-src/ext/curl   streams.c 
    /php-src    NEWS 
  Log:
  Route mkdir()/rmdir() via wrapper ops.
  Move current rmdir()/rmdir() code to plain_wrappers.c
  Implement mkdir()/rmdir() in ftp:// wrapper
  
  
Index: php-src/main/php_streams.h
diff -u php-src/main/php_streams.h:1.88 php-src/main/php_streams.h:1.89
--- php-src/main/php_streams.h:1.88     Fri Dec 12 18:05:16 2003
+++ php-src/main/php_streams.h  Fri Dec 12 23:07:13 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_streams.h,v 1.88 2003/12/12 23:05:16 pollita Exp $ */
+/* $Id: php_streams.h,v 1.89 2003/12/13 04:07:13 pollita Exp $ */
 
 #ifndef PHP_STREAMS_H
 #define PHP_STREAMS_H
@@ -151,6 +151,10 @@
 
        /* rename a file */
        int (*rename)(php_stream_wrapper *wrapper, char *url_from, char *url_to, int 
options, php_stream_context *context TSRMLS_DC);
+
+       /* Create/Remove directory */
+       int (*mkdir)(php_stream_wrapper *wrapper, char *url, int mode, int options, 
php_stream_context *context TSRMLS_DC);
+       int (*rmdir)(php_stream_wrapper *wrapper, char *url, int options, 
php_stream_context *context TSRMLS_DC);
 } php_stream_wrapper_ops;
 
 struct _php_stream_wrapper     {
@@ -308,6 +312,12 @@
 #define php_stream_stat_path(path, ssb)        _php_stream_stat_path((path), 0, 
(ssb), NULL TSRMLS_CC)
 #define php_stream_stat_path_ex(path, flags, ssb, context)     
_php_stream_stat_path((path), (flags), (ssb), (context) TSRMLS_CC)
 
+PHPAPI int _php_stream_mkdir(char *path, int mode, int options, php_stream_context 
*context TSRMLS_DC);
+#define php_stream_mkdir(path, mode, options, context) _php_stream_mkdir(path, mode, 
options, context TSRMLS_CC)
+
+PHPAPI int _php_stream_rmdir(char *path, int options, php_stream_context *context 
TSRMLS_DC);
+#define php_stream_rmdir(path, options, context)       _php_stream_rmdir(path, 
options, context 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);
@@ -320,6 +330,13 @@
 
 #define php_stream_set_chunk_size(stream, size) _php_stream_set_option((stream), 
PHP_STREAM_OPTION_SET_CHUNK_SIZE, (size), NULL TSRMLS_CC)
 
+/* Flags for mkdir method in wrapper ops */
+#define PHP_STREAM_MKDIR_RECURSIVE     1
+/* define REPORT ERRORS 8 (below) */
+
+/* Flags for rmdir method in wrapper ops */
+/* define REPORT_ERRORS 8 (below) */
+
 /* Flags for url_stat method in wrapper ops */
 #define PHP_STREAM_URL_STAT_LINK       1
 #define PHP_STREAM_URL_STAT_QUIET      2
Index: php-src/main/streams/streams.c
diff -u php-src/main/streams/streams.c:1.44 php-src/main/streams/streams.c:1.45
--- php-src/main/streams/streams.c:1.44 Fri Dec  5 08:41:02 2003
+++ php-src/main/streams/streams.c      Fri Dec 12 23:07:14 2003
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: streams.c,v 1.44 2003/12/05 13:41:02 wez Exp $ */
+/* $Id: streams.c,v 1.45 2003/12/13 04:07:14 pollita Exp $ */
 
 #define _GNU_SOURCE
 #include "php.h"
@@ -1457,6 +1457,36 @@
 }
 /* }}} */
 
+/* {{{ _php_stream_mkdir
+ */
+PHPAPI int _php_stream_mkdir(char *path, int mode, int options, php_stream_context 
*context TSRMLS_DC)
+{
+       php_stream_wrapper *wrapper = NULL;
+
+       wrapper = php_stream_locate_url_wrapper(path, NULL, ENFORCE_SAFE_MODE 
TSRMLS_CC);
+       if (!wrapper || !wrapper->wops || !wrapper->wops->mkdir) {
+               return 0;
+       }
+
+       return wrapper->wops->mkdir(wrapper, path, mode, options, context TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ _php_stream_rmdir
+ */
+PHPAPI int _php_stream_rmdir(char *path, int options, php_stream_context *context 
TSRMLS_DC)
+{
+       php_stream_wrapper *wrapper = NULL;
+
+       wrapper = php_stream_locate_url_wrapper(path, NULL, ENFORCE_SAFE_MODE 
TSRMLS_CC);
+       if (!wrapper || !wrapper->wops || !wrapper->wops->rmdir) {
+               return 0;
+       }
+
+       return wrapper->wops->rmdir(wrapper, path, options, context TSRMLS_CC);
+}
+/* }}} */
+
 /* {{{ _php_stream_stat_path */
 PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb, 
php_stream_context *context TSRMLS_DC)
 {
Index: php-src/main/streams/plain_wrapper.c
diff -u php-src/main/streams/plain_wrapper.c:1.31 
php-src/main/streams/plain_wrapper.c:1.32
--- php-src/main/streams/plain_wrapper.c:1.31   Fri Dec 12 18:05:17 2003
+++ php-src/main/streams/plain_wrapper.c        Fri Dec 12 23:07:14 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: plain_wrapper.c,v 1.31 2003/12/12 23:05:17 pollita Exp $ */
+/* $Id: plain_wrapper.c,v 1.32 2003/12/13 04:07:14 pollita Exp $ */
 
 #include "php.h"
 #include "php_globals.h"
@@ -999,6 +999,80 @@
        return 1;
 }
 
+static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mode, 
int options, php_stream_context *context TSRMLS_DC)
+{
+       int ret, recursive = options & PHP_STREAM_MKDIR_RECURSIVE;
+       char *p;
+
+       if ((p = strstr(dir, "://")) != NULL) {
+               dir = p + 3;
+       }
+
+       if (!recursive) {
+               ret = php_mkdir(dir, mode TSRMLS_CC);
+       } else {
+               /* we look for directory separator from the end of string, thus 
hopefuly reducing our work load */
+               char *e, *buf;
+               struct stat sb;
+               int dir_len = strlen(dir);
+
+               buf = estrndup(dir, dir_len);
+               e = buf + dir_len;
+
+               /* find a top level directory we need to create */
+               while ((p = strrchr(buf, DEFAULT_SLASH))) {
+                       *p = '\0';
+                       if (VCWD_STAT(buf, &sb) == 0) {
+                               *p = DEFAULT_SLASH;
+                               break;
+                       }
+               }
+               if (p == buf) {
+                       ret = php_mkdir(dir, mode TSRMLS_CC);
+               } else if (!(ret = php_mkdir(buf, mode TSRMLS_CC))) {
+                       if (!p) {
+                               p = buf;
+                       }
+                       /* create any needed directories if the creation of the 1st 
directory worked */
+                       while (++p != e) {
+                               if (*p == '\0' && *(p + 1) != '\0') {
+                                       *p = DEFAULT_SLASH;
+                                       if ((ret = VCWD_MKDIR(buf, (mode_t)mode)) < 0) 
{
+                                               php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "%s", strerror(errno));
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               efree(buf);
+       }
+       if (ret < 0) {
+               /* Failure */
+               return 0;
+       } else {
+               /* Success */
+               return 1;
+       }
+}
+
+static int php_plain_files_rmdir(php_stream_wrapper *wrapper, char *url, int options, 
php_stream_context *context TSRMLS_DC)
+{
+       if (PG(safe_mode) &&(!php_checkuid(url, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+               return 0;
+       }
+
+       if (php_check_open_basedir(url TSRMLS_CC)) {
+               return 0;
+       }
+
+       if (VCWD_RMDIR(url) < 0) {
+               php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", 
strerror(errno));
+               return 0;
+       }
+
+       return 1;
+}
+
 static php_stream_wrapper_ops php_plain_files_wrapper_ops = {
        php_plain_files_stream_opener,
        NULL,
@@ -1007,7 +1081,9 @@
        php_plain_files_dir_opener,
        "plainfile",
        php_plain_files_unlink,
-       php_plain_files_rename
+       php_plain_files_rename,
+       php_plain_files_mkdir,
+       php_plain_files_rmdir
 };
 
 php_stream_wrapper php_plain_files_wrapper = {
Index: php-src/main/streams/userspace.c
diff -u php-src/main/streams/userspace.c:1.14 php-src/main/streams/userspace.c:1.15
--- php-src/main/streams/userspace.c:1.14       Fri Dec 12 18:05:17 2003
+++ php-src/main/streams/userspace.c    Fri Dec 12 23:07:14 2003
@@ -13,10 +13,11 @@
    | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
    | Authors: Wez Furlong <[EMAIL PROTECTED]>                          |
+   |          Sara Golemon <[EMAIL PROTECTED]>                              |
    +----------------------------------------------------------------------+
 */
 
-/* $Id: userspace.c,v 1.14 2003/12/12 23:05:17 pollita Exp $ */
+/* $Id: userspace.c,v 1.15 2003/12/13 04:07:14 pollita Exp $ */
 
 #include "php.h"
 #include "php_globals.h"
@@ -35,6 +36,8 @@
 static int user_wrapper_stat_url(php_stream_wrapper *wrapper, char *url, int flags, 
php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC);
 static int user_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int options, 
php_stream_context *context TSRMLS_DC);
 static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char 
*url_to, int options, php_stream_context *context TSRMLS_DC);
+static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int 
options, php_stream_context *context TSRMLS_DC);
+static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, 
php_stream_context *context TSRMLS_DC);
 static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, 
char *mode,
                int options, char **opened_path, php_stream_context *context 
STREAMS_DC TSRMLS_DC);
 
@@ -46,7 +49,9 @@
        user_wrapper_opendir,
        "user-space",
        user_wrapper_unlink,
-       user_wrapper_rename
+       user_wrapper_rename,
+       user_wrapper_mkdir,
+       user_wrapper_rmdir
 };
 
 
@@ -98,6 +103,8 @@
 #define USERSTREAM_STATURL     "url_stat"
 #define USERSTREAM_UNLINK      "unlink"
 #define USERSTREAM_RENAME      "rename"
+#define USERSTREAM_MKDIR       "mkdir"
+#define USERSTREAM_RMDIR       "rmdir"
 #define USERSTREAM_DIR_OPEN            "dir_opendir"
 #define USERSTREAM_DIR_READ            "dir_readdir"
 #define USERSTREAM_DIR_REWIND  "dir_rewinddir"
@@ -166,6 +173,16 @@
                return true / false;
        }
 
+       function mkdir($dir, $mode, $options)
+       {
+               return true / false;
+       }
+
+       function rmdir($dir, $options)
+       {
+               return true / false;
+       }
+
        function dir_opendir(string $url, int $options)
        {
                return true / false;
@@ -862,6 +879,139 @@
        return ret;
 }
 
+static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int 
options, php_stream_context *context TSRMLS_DC)
+{
+       struct php_user_stream_wrapper *uwrap = (struct 
php_user_stream_wrapper*)wrapper->abstract;
+       zval *zfilename, *zmode, *zoptions, *zfuncname, *zretval, *zcontext;
+       zval **args[3];
+       int call_result;
+       zval *object;
+       int ret = 0;
+
+       /* create an instance of our class */
+       ALLOC_ZVAL(object);
+       object_init_ex(object, uwrap->ce);
+       ZVAL_REFCOUNT(object) = 1;
+       PZVAL_IS_REF(object) = 1;
+
+       if (context) {
+               MAKE_STD_ZVAL(zcontext);
+               php_stream_context_to_zval(context, zcontext);
+               add_property_zval(object, "context", zcontext);
+               /* The object property should be the only reference,
+                  'get rid' of our local reference. */
+               zval_ptr_dtor(&zcontext);
+       } else {
+               add_property_null(object, "context");
+       }
+
+       /* call the unlink method */
+       MAKE_STD_ZVAL(zfilename);
+       ZVAL_STRING(zfilename, url, 1);
+       args[0] = &zfilename;
+
+       MAKE_STD_ZVAL(zmode);
+       ZVAL_LONG(zmode, mode);
+       args[1] = &zmode;
+
+       MAKE_STD_ZVAL(zoptions);
+       ZVAL_LONG(zoptions, options);
+       args[2] = &zoptions;
+
+       MAKE_STD_ZVAL(zfuncname);
+       ZVAL_STRING(zfuncname, USERSTREAM_MKDIR, 1);
+       
+       call_result = call_user_function_ex(NULL,
+                       &object,
+                       zfuncname,
+                       &zretval,
+                       3, args,
+                       0, NULL TSRMLS_CC);
+
+       if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) {
+               ret = Z_LVAL_P(zretval);
+       } else if (call_result == FAILURE) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_MKDIR " 
is not implemented!", uwrap->classname);
+       }
+
+       /* clean up */
+       zval_ptr_dtor(&object);
+       if (zretval) {
+               zval_ptr_dtor(&zretval);
+       }
+       
+       zval_ptr_dtor(&zfuncname);
+       zval_ptr_dtor(&zfilename);
+       zval_ptr_dtor(&zmode);
+       zval_ptr_dtor(&zoptions);
+
+       return ret;
+}
+
+static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, 
php_stream_context *context TSRMLS_DC)
+{
+       struct php_user_stream_wrapper *uwrap = (struct 
php_user_stream_wrapper*)wrapper->abstract;
+       zval *zfilename, *zmode, *zoptions, *zfuncname, *zretval, *zcontext;
+       zval **args[3];
+       int call_result;
+       zval *object;
+       int ret = 0;
+
+       /* create an instance of our class */
+       ALLOC_ZVAL(object);
+       object_init_ex(object, uwrap->ce);
+       ZVAL_REFCOUNT(object) = 1;
+       PZVAL_IS_REF(object) = 1;
+
+       if (context) {
+               MAKE_STD_ZVAL(zcontext);
+               php_stream_context_to_zval(context, zcontext);
+               add_property_zval(object, "context", zcontext);
+               /* The object property should be the only reference,
+                  'get rid' of our local reference. */
+               zval_ptr_dtor(&zcontext);
+       } else {
+               add_property_null(object, "context");
+       }
+
+       /* call the unlink method */
+       MAKE_STD_ZVAL(zfilename);
+       ZVAL_STRING(zfilename, url, 1);
+       args[0] = &zfilename;
+
+       MAKE_STD_ZVAL(zoptions);
+       ZVAL_LONG(zoptions, options);
+       args[1] = &zoptions;
+
+       MAKE_STD_ZVAL(zfuncname);
+       ZVAL_STRING(zfuncname, USERSTREAM_RMDIR, 1);
+       
+       call_result = call_user_function_ex(NULL,
+                       &object,
+                       zfuncname,
+                       &zretval,
+                       2, args,
+                       0, NULL TSRMLS_CC);
+
+       if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) {
+               ret = Z_LVAL_P(zretval);
+       } else if (call_result == FAILURE) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_RMDIR " 
is not implemented!", uwrap->classname);
+       }
+
+       /* clean up */
+       zval_ptr_dtor(&object);
+       if (zretval) {
+               zval_ptr_dtor(&zretval);
+       }
+       
+       zval_ptr_dtor(&zfuncname);
+       zval_ptr_dtor(&zfilename);
+       zval_ptr_dtor(&zoptions);
+
+       return ret;
+}
+
 static int user_wrapper_stat_url(php_stream_wrapper *wrapper, char *url, int flags, 
php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC)
 {
        struct php_user_stream_wrapper *uwrap = (struct 
php_user_stream_wrapper*)wrapper->abstract;
Index: php-src/ext/standard/file.c
diff -u php-src/ext/standard/file.c:1.369 php-src/ext/standard/file.c:1.370
--- php-src/ext/standard/file.c:1.369   Fri Dec 12 18:05:15 2003
+++ php-src/ext/standard/file.c Fri Dec 12 23:07:14 2003
@@ -21,7 +21,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: file.c,v 1.369 2003/12/12 23:05:15 pollita Exp $ */
+/* $Id: file.c,v 1.370 2003/12/13 04:07:14 pollita Exp $ */
 
 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
 
@@ -1273,93 +1273,42 @@
 }
 /* }}} */
 
-/* {{{ proto bool mkdir(string pathname [, int mode [, bool recursive])
+/* {{{ proto bool mkdir(string pathname [, int mode [, bool recursive [, resource 
context]]])
    Create a directory */
 PHP_FUNCTION(mkdir)
 {
-       int dir_len, ret;
-       long mode = 0777;
-       char *dir;
+       zval *zcontext = NULL;
+       long dir_len, mode = 0777;
        zend_bool recursive = 0;
+       char *dir;
+       php_stream_context *context;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &dir, &dir_len, 
&mode, &recursive) == FAILURE) {
-               return;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbr", &dir, &dir_len, 
&mode, &recursive, &zcontext) == FAILURE) {
+               RETURN_FALSE;
        }
 
-       if (!recursive) {
-               ret = php_mkdir(dir, mode TSRMLS_CC);
-       } else {
-               /* we look for directory separator from the end of string, thus 
hopefuly reducing our work load */
-               char *p, *e, *buf;
-               struct stat sb;
-               
-               buf = estrndup(dir, dir_len);
-               e = buf + dir_len;
-               
-               /* find a top level directory we need to create */
-               while ((p = strrchr(buf, DEFAULT_SLASH))) {
-                       *p = '\0';
-                       if (VCWD_STAT(buf, &sb) == 0) {
-                               *p = DEFAULT_SLASH;
-                               break;
-                       }
-               }
-               if (p == buf) {
-                       ret = php_mkdir(dir, mode TSRMLS_CC);
-               } else if (!(ret = php_mkdir(buf, mode TSRMLS_CC))) {
-                       if (!p) {
-                               p = buf;
-                       }
-                       /* create any needed directories if the creation of the 1st 
directory worked */
-                       while (++p != e) {
-                               if (*p == '\0' && *(p + 1) != '\0') {
-                                       *p = DEFAULT_SLASH;
-                                       if ((ret = VCWD_MKDIR(buf, (mode_t)mode)) < 0) 
{
-                                               php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "%s", strerror(errno));
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               efree(buf);
-       }
+       context = php_stream_context_from_zval(zcontext, 0);
 
-       if (ret < 0) {
-               RETURN_FALSE;
-       } else {
-               RETURN_TRUE;
-       }
+       RETURN_BOOL(php_stream_mkdir(dir, mode, (recursive ? 
PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context));
 }
 /* }}} */
 
-/* {{{ proto bool rmdir(string dirname)
+/* {{{ proto bool rmdir(string dirname[, resource context])
    Remove a directory */
 PHP_FUNCTION(rmdir)
 {
-       zval **arg1;
-       int ret;
-
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       }
-
-       convert_to_string_ex(arg1);
-
-       if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(arg1), NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
-               RETURN_FALSE;
-       }
+       char *dir;
+       long dir_len;
+       zval *zcontext = NULL;
+       php_stream_context *context;
 
-       if (php_check_open_basedir(Z_STRVAL_PP(arg1) TSRMLS_CC)) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, 
&zcontext) == FAILURE) {
                RETURN_FALSE;
        }
 
-       ret = VCWD_RMDIR(Z_STRVAL_PP(arg1));
-       if (ret < 0) {
-               php_error_docref1(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), E_WARNING, "%s", 
strerror(errno));
-               RETURN_FALSE;
-       }
+       context = php_stream_context_from_zval(zcontext, 0);
 
-       RETURN_TRUE;
+       RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context));
 }
 /* }}} */
 
Index: php-src/ext/standard/ftp_fopen_wrapper.c
diff -u php-src/ext/standard/ftp_fopen_wrapper.c:1.69 
php-src/ext/standard/ftp_fopen_wrapper.c:1.70
--- php-src/ext/standard/ftp_fopen_wrapper.c:1.69       Fri Dec 12 18:05:15 2003
+++ php-src/ext/standard/ftp_fopen_wrapper.c    Fri Dec 12 23:07:15 2003
@@ -18,7 +18,7 @@
    |          Sara Golemon <[EMAIL PROTECTED]>                              |
    +----------------------------------------------------------------------+
  */
-/* $Id: ftp_fopen_wrapper.c,v 1.69 2003/12/12 23:05:15 pollita Exp $ */
+/* $Id: ftp_fopen_wrapper.c,v 1.70 2003/12/13 04:07:15 pollita Exp $ */
 
 #include "php.h"
 #include "php_globals.h"
@@ -925,6 +925,150 @@
 }
 /* }}} */
 
+/* {{{ php_stream_ftp_mkdir
+ */
+static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int 
options, php_stream_context *context TSRMLS_DC)
+{
+       php_stream *stream = NULL;
+       php_url *resource = NULL;
+       int result, recursive = options & PHP_STREAM_MKDIR_RECURSIVE;
+       char tmp_line[512];
+
+       stream = php_ftp_fopen_connect(wrapper, url, "r", 0, NULL, NULL, NULL, 
&resource, NULL, NULL TSRMLS_CC);
+       if (!stream) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to connect 
to %s", url);
+               }
+               goto mkdir_errexit;
+       }
+
+       if (resource->path == NULL) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path 
provided in %s", url);
+               }
+               goto mkdir_errexit;
+       }
+
+       if (!recursive) {
+               php_stream_printf(stream TSRMLS_CC, "MKD %s\r\n", resource->path);
+               result = GET_FTP_RESULT(stream);
+    } else {
+        /* we look for directory separator from the end of string, thus hopefuly 
reducing our work load */
+        char *p, *e, *buf;
+
+        buf = estrdup(resource->path);
+        e = buf + strlen(buf);
+
+        /* find a top level directory we need to create */
+        while ((p = strrchr(buf, '/'))) {
+            *p = '\0';
+                       php_stream_printf(stream TSRMLS_CC, "CWD %s\r\n", buf);
+                       result = GET_FTP_RESULT(stream);
+                       if (result >= 200 && result <= 299) {
+                               *p = '/';
+                               break;
+                       }
+        }
+        if (p == buf) {
+                       php_stream_printf(stream TSRMLS_CC, "MKD %s\r\n", 
resource->path);
+                       result = GET_FTP_RESULT(stream);
+        } else {
+                       php_stream_printf(stream TSRMLS_CC, "MKD %s\r\n", buf);
+                       result = GET_FTP_RESULT(stream);
+                       if (result >= 200 && result <= 299) {
+                               if (!p) {
+                                       p = buf;
+                               }
+                               /* create any needed directories if the creation of 
the 1st directory worked */
+                               while (++p != e) {
+                                       if (*p == '\0' && *(p + 1) != '\0') {
+                                               *p = '/';
+                                               php_stream_printf(stream TSRMLS_CC, 
"MKD %s\r\n", buf);
+                                               result = GET_FTP_RESULT(stream);
+                                               if (result < 200 || result > 299) {
+                                                       if (options & REPORT_ERRORS) {
+                                                               php_error_docref(NULL 
TSRMLS_CC, E_WARNING, "%s", tmp_line);
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+        efree(buf);
+    }
+
+       php_url_free(resource);
+       php_stream_close(stream);
+
+       if (result < 200 || result > 299) {
+               /* Failure */
+               return 0;
+       }
+
+       return 1;
+
+ mkdir_errexit:
+       if (resource) {
+               php_url_free(resource);
+       }
+       if (stream) {
+               php_stream_close(stream);
+       }
+       return 0;
+}
+/* }}} */
+
+/* {{{ php_stream_ftp_rmdir
+ */
+static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, char *url, int options, 
php_stream_context *context TSRMLS_DC)
+{
+       php_stream *stream = NULL;
+       php_url *resource = NULL;
+       int result;
+       char tmp_line[512];
+
+       stream = php_ftp_fopen_connect(wrapper, url, "r", 0, NULL, NULL, NULL, 
&resource, NULL, NULL TSRMLS_CC);
+       if (!stream) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to connect 
to %s", url);
+               }
+               goto rmdir_errexit;
+       }
+
+       if (resource->path == NULL) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path 
provided in %s", url);
+               }
+               goto rmdir_errexit;
+       }
+
+       php_stream_printf(stream TSRMLS_CC, "RMD %s\r\n", resource->path);
+       result = GET_FTP_RESULT(stream);
+
+       if (result < 200 || result > 299) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tmp_line);
+               }
+               goto rmdir_errexit;
+       }
+
+       php_url_free(resource);
+       php_stream_close(stream);
+
+       return 1;
+
+ rmdir_errexit:
+       if (resource) {
+               php_url_free(resource);
+       }
+       if (stream) {
+               php_stream_close(stream);
+       }
+       return 0;
+}
+/* }}} */
+
 static php_stream_wrapper_ops ftp_stream_wops = {
        php_stream_url_wrap_ftp,
        php_stream_ftp_stream_close, /* stream_close */
@@ -933,7 +1077,9 @@
        php_stream_ftp_opendir, /* opendir */
        "FTP",
        php_stream_ftp_unlink, /* unlink */
-       php_stream_ftp_rename  /* rename */
+       php_stream_ftp_rename, /* rename */
+       php_stream_ftp_mkdir,  /* mkdir */
+       php_stream_ftp_rmdir   /* rmdir */
 };
 
 PHPAPI php_stream_wrapper php_stream_ftp_wrapper =     {
Index: php-src/ext/standard/http_fopen_wrapper.c
diff -u php-src/ext/standard/http_fopen_wrapper.c:1.78 
php-src/ext/standard/http_fopen_wrapper.c:1.79
--- php-src/ext/standard/http_fopen_wrapper.c:1.78      Fri Dec 12 18:05:15 2003
+++ php-src/ext/standard/http_fopen_wrapper.c   Fri Dec 12 23:07:15 2003
@@ -18,7 +18,7 @@
    |          Wez Furlong <[EMAIL PROTECTED]>                          |
    +----------------------------------------------------------------------+
  */
-/* $Id: http_fopen_wrapper.c,v 1.78 2003/12/12 23:05:15 pollita Exp $ */ 
+/* $Id: http_fopen_wrapper.c,v 1.79 2003/12/13 04:07:15 pollita Exp $ */ 
 
 #include "php.h"
 #include "php_globals.h"
@@ -544,6 +544,8 @@
        "HTTP",
        NULL, /* unlink */
        NULL, /* rename */
+       NULL, /* mkdir */
+       NULL  /* rmdir */
 };
 
 PHPAPI php_stream_wrapper php_stream_http_wrapper =    {
Index: php-src/ext/standard/php_fopen_wrapper.c
diff -u php-src/ext/standard/php_fopen_wrapper.c:1.41 
php-src/ext/standard/php_fopen_wrapper.c:1.42
--- php-src/ext/standard/php_fopen_wrapper.c:1.41       Fri Dec 12 18:05:15 2003
+++ php-src/ext/standard/php_fopen_wrapper.c    Fri Dec 12 23:07:15 2003
@@ -17,7 +17,7 @@
    |          Hartmut Holzgraefe <[EMAIL PROTECTED]>                       |
    +----------------------------------------------------------------------+
  */
-/* $Id: php_fopen_wrapper.c,v 1.41 2003/12/12 23:05:15 pollita Exp $ */
+/* $Id: php_fopen_wrapper.c,v 1.42 2003/12/13 04:07:15 pollita Exp $ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -234,7 +234,9 @@
        NULL, /* opendir */
        "PHP",
        NULL, /* unlink */
-       NULL  /* rename */
+       NULL, /* rename */
+       NULL, /* mkdir */
+       NULL  /* rmdir */
 };
 
 php_stream_wrapper php_stream_php_wrapper =    {
Index: php-src/ext/zlib/zlib_fopen_wrapper.c
diff -u php-src/ext/zlib/zlib_fopen_wrapper.c:1.42 
php-src/ext/zlib/zlib_fopen_wrapper.c:1.43
--- php-src/ext/zlib/zlib_fopen_wrapper.c:1.42  Fri Dec 12 18:05:18 2003
+++ php-src/ext/zlib/zlib_fopen_wrapper.c       Fri Dec 12 23:07:15 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: zlib_fopen_wrapper.c,v 1.42 2003/12/12 23:05:18 pollita Exp $ */
+/* $Id: zlib_fopen_wrapper.c,v 1.43 2003/12/13 04:07:15 pollita Exp $ */
 
 #define _GNU_SOURCE
 
@@ -161,7 +161,9 @@
        NULL, /* opendir */
        "ZLIB",
        NULL, /* unlink */
-       NULL  /* rename */
+       NULL, /* rename */
+       NULL, /* mkdir */
+       NULL  /* rmdir */
 };
 
 php_stream_wrapper php_stream_gzip_wrapper =   {
Index: php-src/ext/bz2/bz2.c
diff -u php-src/ext/bz2/bz2.c:1.4 php-src/ext/bz2/bz2.c:1.5
--- php-src/ext/bz2/bz2.c:1.4   Fri Dec 12 18:05:18 2003
+++ php-src/ext/bz2/bz2.c       Fri Dec 12 23:07:16 2003
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
  
-/* $Id: bz2.c,v 1.4 2003/12/12 23:05:18 pollita Exp $ */
+/* $Id: bz2.c,v 1.5 2003/12/13 04:07:16 pollita Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -227,7 +227,9 @@
        NULL, /* opendir */
        "BZip2",
        NULL, /* unlink */
-       NULL  /* rename */
+       NULL, /* rename */
+       NULL, /* mkdir */
+       NULL  /* rmdir */
 };
 
 php_stream_wrapper php_stream_bzip2_wrapper = {
Index: php-src/ext/curl/streams.c
diff -u php-src/ext/curl/streams.c:1.10 php-src/ext/curl/streams.c:1.11
--- php-src/ext/curl/streams.c:1.10     Fri Dec 12 18:05:19 2003
+++ php-src/ext/curl/streams.c  Fri Dec 12 23:07:17 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: streams.c,v 1.10 2003/12/12 23:05:19 pollita Exp $ */
+/* $Id: streams.c,v 1.11 2003/12/13 04:07:17 pollita Exp $ */
 
 /* This file implements cURL based wrappers.
  * NOTE: If you are implementing your own streams that are intended to
@@ -363,7 +363,9 @@
        NULL, /* opendir */
        NULL, /* label */
        NULL, /* unlink */
-       NULL  /* rename */
+       NULL, /* rename */
+       NULL, /* mkdir */
+       NULL  /* rmdir */
 };
 
 php_stream_wrapper php_curl_wrapper = {
Index: php-src/NEWS
diff -u php-src/NEWS:1.1531 php-src/NEWS:1.1532
--- php-src/NEWS:1.1531 Fri Dec 12 18:06:42 2003
+++ php-src/NEWS        Fri Dec 12 23:07:18 2003
@@ -25,9 +25,9 @@
   . stream_socket_sendto() and stream_socket_recvfrom(). (Wez)
   . iconv_mime_decode_headers(). (Moriyoshi)
   . get_declared_interfaces(). (Andrey, Marcus)
-- Added rename() support to userstreams. (Sara)
-- Added rename() support to ftp:// wrapper. (Sara)
-- Changed rename() to be routed via streams API. (Sara)
+- Added rename(), rmdir(), and mkdir() support to userstreams. (Sara)
+- Added rename(), rmdir(), and mkdir() support to ftp:// wrapper. (Sara)
+- Changed rename(), rmdir(), and mkdir() to be routed via streams API. (Sara)
 - Changed stat() and family to be routed via streams API. (Sara)
 - Fixed include_once() / require_once() on Windows to honor case-insensitivity
   of files. (Andi)

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to