mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Route mkdir()/rmdir() via wrapper ops.
Move current rmdir()/rmdir() code to plain_wrappers.c Implement mkdir()/rmdir() in ftp:// wrapper
This commit is contained in:
parent
bef6368dee
commit
c56647833b
12 changed files with 457 additions and 79 deletions
6
NEWS
6
NEWS
|
@ -25,9 +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)
|
||||
- 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)
|
||||
|
|
|
@ -227,7 +227,9 @@ static php_stream_wrapper_ops bzip2_stream_wops = {
|
|||
NULL, /* opendir */
|
||||
"BZip2",
|
||||
NULL, /* unlink */
|
||||
NULL /* rename */
|
||||
NULL, /* rename */
|
||||
NULL, /* mkdir */
|
||||
NULL /* rmdir */
|
||||
};
|
||||
|
||||
php_stream_wrapper php_stream_bzip2_wrapper = {
|
||||
|
|
|
@ -363,7 +363,9 @@ static php_stream_wrapper_ops php_curl_wrapper_ops = {
|
|||
NULL, /* opendir */
|
||||
NULL, /* label */
|
||||
NULL, /* unlink */
|
||||
NULL /* rename */
|
||||
NULL, /* rename */
|
||||
NULL, /* mkdir */
|
||||
NULL /* rmdir */
|
||||
};
|
||||
|
||||
php_stream_wrapper php_curl_wrapper = {
|
||||
|
|
|
@ -1273,93 +1273,42 @@ PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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 (!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);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbr", &dir, &dir_len, &mode, &recursive, &zcontext) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
context = php_stream_context_from_zval(zcontext, 0);
|
||||
|
||||
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;
|
||||
char *dir;
|
||||
long dir_len;
|
||||
zval *zcontext = NULL;
|
||||
php_stream_context *context;
|
||||
|
||||
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))) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dir, &dir_len, &zcontext) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(Z_STRVAL_PP(arg1) TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
context = php_stream_context_from_zval(zcontext, 0);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
RETURN_TRUE;
|
||||
RETURN_BOOL(php_stream_rmdir(dir, REPORT_ERRORS, context));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -925,6 +925,150 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, char *url_from, ch
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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 @@ static php_stream_wrapper_ops ftp_stream_wops = {
|
|||
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 = {
|
||||
|
|
|
@ -544,6 +544,8 @@ static php_stream_wrapper_ops http_stream_wops = {
|
|||
"HTTP",
|
||||
NULL, /* unlink */
|
||||
NULL, /* rename */
|
||||
NULL, /* mkdir */
|
||||
NULL /* rmdir */
|
||||
};
|
||||
|
||||
PHPAPI php_stream_wrapper php_stream_http_wrapper = {
|
||||
|
|
|
@ -234,7 +234,9 @@ static php_stream_wrapper_ops php_stdio_wops = {
|
|||
NULL, /* opendir */
|
||||
"PHP",
|
||||
NULL, /* unlink */
|
||||
NULL /* rename */
|
||||
NULL, /* rename */
|
||||
NULL, /* mkdir */
|
||||
NULL /* rmdir */
|
||||
};
|
||||
|
||||
php_stream_wrapper php_stream_php_wrapper = {
|
||||
|
|
|
@ -161,7 +161,9 @@ static php_stream_wrapper_ops gzip_stream_wops = {
|
|||
NULL, /* opendir */
|
||||
"ZLIB",
|
||||
NULL, /* unlink */
|
||||
NULL /* rename */
|
||||
NULL, /* rename */
|
||||
NULL, /* mkdir */
|
||||
NULL /* rmdir */
|
||||
};
|
||||
|
||||
php_stream_wrapper php_stream_gzip_wrapper = {
|
||||
|
|
|
@ -151,6 +151,10 @@ typedef struct _php_stream_wrapper_ops {
|
|||
|
||||
/* 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 @@ PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb,
|
|||
#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 @@ PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, voi
|
|||
|
||||
#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
|
||||
|
|
|
@ -999,6 +999,80 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, c
|
|||
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 @@ static php_stream_wrapper_ops php_plain_files_wrapper_ops = {
|
|||
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 = {
|
||||
|
|
|
@ -1457,6 +1457,36 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _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)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Wez Furlong <wez@thebrainroom.com> |
|
||||
| Sara Golemon <pollita@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -35,6 +36,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena
|
|||
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 @@ static php_stream_wrapper_ops user_stream_wops = {
|
|||
user_wrapper_opendir,
|
||||
"user-space",
|
||||
user_wrapper_unlink,
|
||||
user_wrapper_rename
|
||||
user_wrapper_rename,
|
||||
user_wrapper_mkdir,
|
||||
user_wrapper_rmdir
|
||||
};
|
||||
|
||||
|
||||
|
@ -98,6 +103,8 @@ typedef struct _php_userstream_data php_userstream_data_t;
|
|||
#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 @@ typedef struct _php_userstream_data php_userstream_data_t;
|
|||
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 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
|
|||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue