]> granicus.if.org Git - php/commitdiff
Route rename() via wrapper ops.
authorSara Golemon <pollita@php.net>
Fri, 12 Dec 2003 23:06:42 +0000 (23:06 +0000)
committerSara Golemon <pollita@php.net>
Fri, 12 Dec 2003 23:06:42 +0000 (23:06 +0000)
Move current rename() code to main/streams/plain_wrapper.c
Implement ftp/rename()
Implement userstreams/rename()

NEWS
ext/bz2/bz2.c
ext/curl/streams.c
ext/standard/file.c
ext/standard/ftp_fopen_wrapper.c
ext/standard/http_fopen_wrapper.c
ext/standard/php_fopen_wrapper.c
ext/zlib/zlib_fopen_wrapper.c
main/php_streams.h
main/streams/plain_wrapper.c
main/streams/userspace.c

diff --git a/NEWS b/NEWS
index 3f918616b277ed3136fedb49a2467ea355c9ddde..459881a6e1b2d0af76cff602d04a6febbbb5e3c7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,9 @@ PHP                                                                        NEWS
   . 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)
 - 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)
index aa2b021cf3aa74333f40b3e951708d077d381a3c..0e4620e06a6b96415e5a320256be53bc11db7bf1 100644 (file)
@@ -226,7 +226,8 @@ static php_stream_wrapper_ops bzip2_stream_wops = {
        NULL, /* stat */
        NULL, /* opendir */
        "BZip2",
-       NULL  /* unlink */
+       NULL, /* unlink */
+       NULL  /* rename */
 };
 
 php_stream_wrapper php_stream_bzip2_wrapper = {
index 5a3a9c84801743ae110c71d8824811eebc1d826d..54684688062425d4d1b16fa97889929b26b683c9 100644 (file)
@@ -362,7 +362,8 @@ static php_stream_wrapper_ops php_curl_wrapper_ops = {
        NULL, /* stat url */
        NULL, /* opendir */
        NULL, /* label */
-       NULL  /* unlink */
+       NULL, /* unlink */
+       NULL  /* rename */
 };
 
 php_stream_wrapper php_curl_wrapper = {
index c580714713b96b527a8e857f012d8ac7099af9d2..617a64ed5c5805b80a8b5421a32edaecc2eba9f8 100644 (file)
@@ -1437,48 +1437,40 @@ PHPAPI PHP_FUNCTION(fpassthru)
 }
 /* }}} */
 
-/* {{{ proto bool rename(string old_name, string new_name)
+/* {{{ proto bool rename(string old_name, string new_name[, resource context])
    Rename a file */
 PHP_FUNCTION(rename)
 {
-       zval **old_arg, **new_arg;
        char *old_name, *new_name;
-       int ret;
+       int old_name_len, new_name_len;
+       zval *zcontext = NULL;
+       php_stream_wrapper *wrapper;
+       php_stream_context *context;
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &old_arg, &new_arg) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &old_name, &old_name_len, &new_name, &new_name_len, &zcontext) == FAILURE) {
+               RETURN_FALSE;
        }
 
-       convert_to_string_ex(old_arg);
-       convert_to_string_ex(new_arg);
-
-       old_name = Z_STRVAL_PP(old_arg);
-       new_name = Z_STRVAL_PP(new_arg);
+       wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0 TSRMLS_CC);
 
-       if (PG(safe_mode) &&(!php_checkuid(old_name, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+       if (!wrapper || !wrapper->wops) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper.");
                RETURN_FALSE;
        }
 
-       if (php_check_open_basedir(old_name TSRMLS_CC)) {
+       if (!wrapper->wops->rename) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s wrapper does not support renaming.", wrapper->wops->label ? wrapper->wops->label : "Source");
                RETURN_FALSE;
        }
 
-       ret = VCWD_RENAME(old_name, new_name);
-
-       if (ret == -1) {
-#ifdef EXDEV
-               if (errno == EXDEV) {
-                       if (php_copy_file(old_name, new_name TSRMLS_CC) == SUCCESS) {
-                               VCWD_UNLINK(old_name);
-                               RETURN_TRUE;
-                       }
-               }
-#endif 
-               php_error_docref2(NULL TSRMLS_CC, old_name, new_name, E_WARNING, "%s", strerror(errno));
+       if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0 TSRMLS_CC)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rename a file across wrapper types.");
                RETURN_FALSE;
        }
 
-       RETURN_TRUE;
+       context = php_stream_context_from_zval(zcontext, 0);
+
+       RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context TSRMLS_CC));
 }
 /* }}} */
 
index 9674a0ca80d08d7939c1206f552dfce931f7040c..ca7e086f41ab3760ce1d35acc52e36276b204ee6 100644 (file)
@@ -842,6 +842,89 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, char *url, int opt
 }
 /* }}} */
 
+/* {{{ php_stream_ftp_rename
+ */
+static int php_stream_ftp_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC)
+{
+       php_stream *stream = NULL;
+       php_url *resource_from = NULL, *resource_to = NULL;
+       int result;
+       char tmp_line[512];
+
+       resource_from = php_url_parse(url_from);
+       resource_to = php_url_parse(url_to);
+       /* Must be same scheme (ftp/ftp or ftps/ftps), same host, and same port 
+               (or a 21/0 0/21 combination which is also "same") 
+          Also require paths to/from */
+       if (!resource_from ||
+               !resource_to ||
+               !resource_from->scheme ||
+               !resource_to->scheme ||
+               strcmp(resource_from->scheme, resource_to->scheme) ||
+               !resource_from->host ||
+               !resource_to->host ||
+               strcmp(resource_from->host, resource_to->host) ||
+               (resource_from->port != resource_to->port && 
+                resource_from->port * resource_to->port != 0 && 
+                resource_from->port + resource_to->port != 21) ||
+               !resource_from->path ||
+               !resource_to->path) {
+               goto rename_errexit;
+       }
+
+       stream = php_ftp_fopen_connect(wrapper, url_from, "r", 0, NULL, NULL, NULL, NULL, NULL, NULL TSRMLS_CC);
+       if (!stream) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to connect to %s", resource_from->host);
+               }
+               goto rename_errexit;
+       }
+
+       /* Rename FROM */
+       php_stream_write_string(stream, "RNFR ");
+       php_stream_write_string(stream, resource_from->path);
+       php_stream_write_string(stream, "\r\n");
+
+       result = GET_FTP_RESULT(stream);
+       if (result < 300 || result > 399) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error Renaming file: %s", tmp_line);
+               }
+               goto rename_errexit;
+       }
+
+       /* Rename TO */
+       php_stream_write_string(stream, "RNTO ");
+       php_stream_write_string(stream, resource_to->path);
+       php_stream_write_string(stream, "\r\n");
+
+       result = GET_FTP_RESULT(stream);
+       if (result < 200 || result > 299) {
+               if (options & REPORT_ERRORS) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error Renaming file: %s", tmp_line);
+               }
+               goto rename_errexit;
+       }
+
+       php_url_free(resource_from);
+       php_url_free(resource_to);
+       php_stream_close(stream);
+       return 1;
+
+ rename_errexit:
+       if (resource_from) {
+               php_url_free(resource_from);
+       }
+       if (resource_to) {
+               php_url_free(resource_to);
+       }
+       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 */
@@ -849,7 +932,8 @@ static php_stream_wrapper_ops ftp_stream_wops = {
        php_stream_ftp_url_stat, /* stat_url */
        php_stream_ftp_opendir, /* opendir */
        "FTP",
-       php_stream_ftp_unlink /* unlink */
+       php_stream_ftp_unlink, /* unlink */
+       php_stream_ftp_rename  /* rename */
 };
 
 PHPAPI php_stream_wrapper php_stream_ftp_wrapper =     {
index f8e9068a9e03944c1694c1e02c24f13243171bf2..28c78fd0e93a27d40486e4adfcdd061d2dc7e72d 100644 (file)
@@ -542,7 +542,8 @@ static php_stream_wrapper_ops http_stream_wops = {
        NULL, /* stat_url */
        NULL, /* opendir */
        "HTTP",
-       NULL /* unlink */
+       NULL, /* unlink */
+       NULL, /* rename */
 };
 
 PHPAPI php_stream_wrapper php_stream_http_wrapper =    {
index 32d205ba726db1f61261d9ff577186364229e8cf..9dc6eb138498af6b1fb8f79ebd08375fc8bb62eb 100644 (file)
@@ -233,7 +233,8 @@ static php_stream_wrapper_ops php_stdio_wops = {
        NULL, /* stat */
        NULL, /* opendir */
        "PHP",
-       NULL /* unlink */
+       NULL, /* unlink */
+       NULL  /* rename */
 };
 
 php_stream_wrapper php_stream_php_wrapper =    {
index 32dc3c1cc8034e8b7749ef7100480e27b127acfa..e5358e97e63d4e5702d32cf0afff4abb7b5f322c 100644 (file)
@@ -160,7 +160,8 @@ static php_stream_wrapper_ops gzip_stream_wops = {
        NULL, /* stat_url */
        NULL, /* opendir */
        "ZLIB",
-       NULL /* unlink */
+       NULL, /* unlink */
+       NULL  /* rename */
 };
 
 php_stream_wrapper php_stream_gzip_wrapper =   {
index 5451b8382f09b97a4270323efd9bc514975bdd79..f3d2ceedcb2f82092a56edbc04fc9a90c2707b44 100755 (executable)
@@ -148,6 +148,9 @@ typedef struct _php_stream_wrapper_ops {
 
        /* delete a file */
        int (*unlink)(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC);
+
+       /* rename a file */
+       int (*rename)(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC);
 } php_stream_wrapper_ops;
 
 struct _php_stream_wrapper     {
index 008e2833677a59bedb94422c45334f14f89d263f..3e2f67b57fb8fd2c129c8bd18abd657d06734852 100644 (file)
@@ -956,6 +956,49 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, char *url, int op
        return 1;
 }
 
+static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC)
+{
+       char *p;
+       int ret;
+
+       if (!url_from || !url_to) {
+               return 0;
+       }
+
+       if ((p = strstr(url_from, "://")) != NULL) {
+               url_from = p + 3;
+       }
+
+       if ((p = strstr(url_to, "://")) != NULL) {
+               url_to = p + 3;
+       }
+
+       if (PG(safe_mode) &&(!php_checkuid(url_from, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+               return 0;
+       }
+
+       if (php_check_open_basedir(url_from TSRMLS_CC)) {
+               return 0;
+       }
+
+       ret = VCWD_RENAME(url_from, url_to);
+
+       if (ret == -1) {
+#ifdef EXDEV
+               if (errno == EXDEV) {
+                       if (php_copy_file(url_from, url_to TSRMLS_CC) == SUCCESS) {
+                               VCWD_UNLINK(url_from);
+                               return 1;
+                       }
+               }
+#endif
+               php_error_docref2(NULL TSRMLS_CC, url_from, url_to, 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,
@@ -963,7 +1006,8 @@ static php_stream_wrapper_ops php_plain_files_wrapper_ops = {
        php_plain_files_url_stater,
        php_plain_files_dir_opener,
        "plainfile",
-       php_plain_files_unlink
+       php_plain_files_unlink,
+       php_plain_files_rename
 };
 
 php_stream_wrapper php_plain_files_wrapper = {
index ecacfb73b604eda10a38a0abbac08dd9f5aaf0fa..2176229248b0460e052904c6d263b50fad27c698 100644 (file)
@@ -34,6 +34,7 @@ struct php_user_stream_wrapper {
 static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
 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 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);
 
@@ -44,7 +45,8 @@ static php_stream_wrapper_ops user_stream_wops = {
        user_wrapper_stat_url,
        user_wrapper_opendir,
        "user-space",
-       user_wrapper_unlink
+       user_wrapper_unlink,
+       user_wrapper_rename
 };
 
 
@@ -95,6 +97,7 @@ typedef struct _php_userstream_data php_userstream_data_t;
 #define USERSTREAM_STAT                "stream_stat"
 #define USERSTREAM_STATURL     "url_stat"
 #define USERSTREAM_UNLINK      "unlink"
+#define USERSTREAM_RENAME      "rename"
 #define USERSTREAM_DIR_OPEN            "dir_opendir"
 #define USERSTREAM_DIR_READ            "dir_readdir"
 #define USERSTREAM_DIR_REWIND  "dir_rewinddir"
@@ -158,6 +161,11 @@ typedef struct _php_userstream_data php_userstream_data_t;
                return true / false;
        }
 
+       function rename(string $from, string $to)
+       {
+               return true / false;
+       }
+
        function dir_opendir(string $url, int $options)
        {
                return true / false;
@@ -791,6 +799,69 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio
        return ret;
 }
 
+static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC)
+{
+       struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;
+       zval *zold_name, *znew_name, *zfuncname, *zretval, *zcontext;
+       zval **args[2];
+       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 rename method */
+       MAKE_STD_ZVAL(zold_name);
+       ZVAL_STRING(zold_name, url_from, 1);
+       args[0] = &zold_name;
+
+       MAKE_STD_ZVAL(znew_name);
+       ZVAL_STRING(znew_name, url_to, 1);
+       args[1] = &znew_name;
+
+       MAKE_STD_ZVAL(zfuncname);
+       ZVAL_STRING(zfuncname, USERSTREAM_RENAME, 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_RENAME " is not implemented!", uwrap->classname);
+       }
+
+       /* clean up */
+       zval_ptr_dtor(&object);
+       if (zretval)
+               zval_ptr_dtor(&zretval);
+       
+       zval_ptr_dtor(&zfuncname);
+       zval_ptr_dtor(&zold_name);
+       zval_ptr_dtor(&znew_name);
+
+       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;