|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patch ssh2_scp_send_path for ssh2 Bug #62807Patch version 2012-08-13 12:27 UTC Return to Bug #62807 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: chopins.xiao@gmail.com
Index: ssh2_fopen_wrappers.c
===================================================================
--- ssh2_fopen_wrappers.c (版本 327101)
+++ ssh2_fopen_wrappers.c (工作副本)
@@ -32,79 +32,21 @@
static size_t php_ssh2_channel_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
{
php_ssh2_channel_data *abstract = (php_ssh2_channel_data*)stream->abstract;
- size_t writestate;
- LIBSSH2_SESSION *session;
libssh2_channel_set_blocking(abstract->channel, abstract->is_blocking);
- session = (LIBSSH2_SESSION *)zend_fetch_resource(NULL TSRMLS_CC, abstract->session_rsrc, PHP_SSH2_SESSION_RES_NAME, NULL, 1, le_ssh2_session);
-
-#ifdef PHP_SSH2_SESSION_TIMEOUT
- if (abstract->is_blocking) {
- libssh2_session_set_timeout(session, abstract->timeout);
- }
-#endif
-
- writestate = libssh2_channel_write_ex(abstract->channel, abstract->streamid, buf, count);
-
-#ifdef PHP_SSH2_SESSION_TIMEOUT
- if (abstract->is_blocking) {
- libssh2_session_set_timeout(session, 0);
- }
-#endif
- if (writestate == LIBSSH2_ERROR_EAGAIN) {
- writestate = 0;
- }
-
- if (writestate < 0) {
- char *error_msg = NULL;
- if (libssh2_session_last_error(session, &error_msg, NULL, 0) == writestate) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failure '%s' (%ld)", error_msg, writestate);
- }
-
- stream->eof = 1;
- writestate = 0;
- }
-
- return writestate;
+ return libssh2_channel_write_ex(abstract->channel, abstract->streamid, buf, count);
}
static size_t php_ssh2_channel_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
{
php_ssh2_channel_data *abstract = (php_ssh2_channel_data*)stream->abstract;
ssize_t readstate;
- LIBSSH2_SESSION *session;
stream->eof = libssh2_channel_eof(abstract->channel);
libssh2_channel_set_blocking(abstract->channel, abstract->is_blocking);
- session = (LIBSSH2_SESSION *)zend_fetch_resource(NULL TSRMLS_CC, abstract->session_rsrc, PHP_SSH2_SESSION_RES_NAME, NULL, 1, le_ssh2_session);
-
-#ifdef PHP_SSH2_SESSION_TIMEOUT
- if (abstract->is_blocking) {
- libssh2_session_set_timeout(session, abstract->timeout);
- }
-#endif
-
+
readstate = libssh2_channel_read_ex(abstract->channel, abstract->streamid, buf, count);
-
-#ifdef PHP_SSH2_SESSION_TIMEOUT
- if (abstract->is_blocking) {
- libssh2_session_set_timeout(session, 0);
- }
-#endif
- if (readstate == LIBSSH2_ERROR_EAGAIN) {
- readstate = 0;
- }
-
- if (readstate < 0) {
- char *error_msg = NULL;
- if (libssh2_session_last_error(session, &error_msg, NULL, 0) == readstate) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failure '%s' (%ld)", error_msg, readstate);
- }
-
- stream->eof = 1;
- readstate = 0;
- }
- return readstate;
+ return (readstate < 0 ? 0 : readstate);
}
static int php_ssh2_channel_stream_close(php_stream *stream, int close_handle TSRMLS_DC)
@@ -143,18 +85,6 @@
abstract->is_blocking = value;
return ret;
break;
-
- case PHP_STREAM_OPTION_READ_TIMEOUT:
- ret = abstract->timeout;
-#ifdef PHP_SSH2_SESSION_TIMEOUT
- struct timeval tv = *(struct timeval*)ptrparam;
- abstract->timeout = tv.tv_sec * 1000 + (tv.tv_usec / 1000);
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "No support for ssh2 stream timeout. Please recompile with libssh2 >= 1.2.9");
-#endif
- return ret;
- break;
-
#if PHP_MAJOR_VERSION >= 5
case PHP_STREAM_OPTION_CHECK_LIVENESS:
return stream->eof = libssh2_channel_eof(abstract->channel);
@@ -217,15 +147,7 @@
if (!resource->host) {
return NULL;
}
-
- /*
- Find resource->path in the path string, then copy the entire string from the original path.
- This includes ?query#fragment in the path string
- */
- s = resource->path;
- resource->path = estrdup(strstr(path, resource->path));
- efree(s);
-
+
/* Look for a resource ID to reuse a session */
s = resource->host;
if (strncmp(resource->host, "Resource id #", sizeof("Resource id #") - 1) == 0) {
@@ -522,7 +444,6 @@
channel_data->channel = channel;
channel_data->streamid = 0;
channel_data->is_blocking = 0;
- channel_data->timeout = 0;
channel_data->session_rsrc = resource_id;
channel_data->refcount = NULL;
@@ -673,12 +594,12 @@
int argc = ZEND_NUM_ARGS();
if (argc == 5) {
- php_error_docref(NULL TSRMLS_CC, E_ERROR, "width specified without height parameter");
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "width specified without height paramter");
RETURN_FALSE;
}
if (zend_parse_parameters(argc TSRMLS_CC, "r|sa!lll", &zsession, &term, &term_len, &environment, &width, &height, &type) == FAILURE) {
- return;
+ RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(session, LIBSSH2_SESSION*, &zsession, -1, PHP_SSH2_SESSION_RES_NAME, le_ssh2_session);
@@ -768,7 +689,6 @@
channel_data->channel = channel;
channel_data->streamid = 0;
channel_data->is_blocking = 0;
- channel_data->timeout = 0;
channel_data->session_rsrc = resource_id;
channel_data->refcount = NULL;
@@ -896,7 +816,7 @@
int term_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z!z!lll", &zsession, &command, &command_len, &zpty, &environment, &width, &height, &type) == FAILURE) {
- return;
+ RETURN_FALSE;
}
if (zpty && Z_TYPE_P(zpty) == IS_ARRAY) {
@@ -957,7 +877,6 @@
channel_data->channel = channel;
channel_data->streamid = 0;
channel_data->is_blocking = 0;
- channel_data->timeout = 0;
channel_data->session_rsrc = resource_id;
channel_data->refcount = NULL;
@@ -1031,7 +950,7 @@
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &zsession, &remote_filename, &remote_filename_len,
&local_filename, &local_filename_len) == FAILURE) {
- return;
+ RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(session, LIBSSH2_SESSION*, &zsession, -1, PHP_SSH2_SESSION_RES_NAME, le_ssh2_session);
@@ -1086,14 +1005,19 @@
long create_mode = 0644;
php_stream_statbuf ssb;
int argc = ZEND_NUM_ARGS();
+ ssize_t write_size;
+ int nfds = 1;
+ struct timeval timeout;
+ int select_number;
+ fd_set writefd;
+ int ssh_fd;
if (zend_parse_parameters(argc TSRMLS_CC, "rss|l", &zsession, &local_filename, &local_filename_len,
&remote_filename, &remote_filename_len, &create_mode) == FAILURE) {
- return;
+ RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(session, LIBSSH2_SESSION*, &zsession, -1, PHP_SSH2_SESSION_RES_NAME, le_ssh2_session);
-
local_file = php_stream_open_wrapper(local_filename, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
if (!local_file) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to read source file");
@@ -1120,36 +1044,60 @@
php_stream_close(local_file);
RETURN_FALSE;
}
- libssh2_channel_set_blocking(remote_file, 1);
+ libssh2_channel_set_blocking(remote_file, 1);
+ int send_none = 1;
+ char buffer[8192];
+ size_t toread;
+ size_t bytesread;
while (ssb.sb.st_size) {
- char buffer[8192];
- size_t toread = MIN(8192, ssb.sb.st_size);
- size_t bytesread = php_stream_read(local_file, buffer, toread);
-
+ if(send_none == 1) {
+ toread = MIN(8192, ssb.sb.st_size);
+ bytesread = php_stream_read(local_file, buffer, toread);
+ }
if (bytesread <= 0 || bytesread > toread) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed copying file 2");
php_stream_close(local_file);
libssh2_channel_free(remote_file);
RETURN_FALSE;
}
-
- size_t sent = 0;
- size_t justsent = 0;
-
- while (bytesread - sent > 0) {
- if ((justsent = libssh2_channel_write(remote_file, (buffer + sent), bytesread - sent)) < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed copying file");
- php_stream_close(local_file);
- libssh2_channel_free(remote_file);
- RETURN_FALSE;
+ write_size = libssh2_channel_write(remote_file, buffer, bytesread);
+ if(write_size < 0) {
+ switch(write_size) {
+ case LIBSSH2_ERROR_EAGAIN:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"System tcpsendspace is full");
+ break;
+ case LIBSSH2_ERROR_ALLOC:
+ php_error_docref(NULL TSRMLS_CC,E_WARNING,"An internal memory allocation call failed");
+ break;
+ case LIBSSH2_ERROR_SOCKET_SEND:
+ php_error_docref(NULL TSRMLS_CC,E_WARNING,"Unable to send data on socket");
+ break;
+ case LIBSSH2_ERROR_CHANNEL_CLOSED:
+ php_error_docref(NULL TSRMLS_CC,E_WARNING,"The channel has been closed");
+ break;
+ case LIBSSH2_ERROR_CHANNEL_EOF_SENT:
+ php_error_docref(NULL TSRMLS_CC,E_WARNING,"The channel has been requested to be closed");
+ break;
+ break;
}
- sent = sent + justsent;
+ RETURN_FALSE;
}
+ if(LIBSSH2_ERROR_NONE == write_size || LIBSSH2_ERROR_EAGAIN == write_size) {
+ send_none = 0;
+ continue;
+ } else {
+ send_none = 1;
+ }
+ if (write_size != bytesread) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed copying file");
+ php_stream_close(local_file);
+ libssh2_channel_free(remote_file);
+ RETURN_FALSE;
+ }
ssb.sb.st_size -= bytesread;
}
- libssh2_channel_flush_ex(remote_file, LIBSSH2_CHANNEL_FLUSH_ALL);
php_stream_close(local_file);
libssh2_channel_free(remote_file);
RETURN_TRUE;
@@ -1180,7 +1128,6 @@
channel_data->channel = channel;
channel_data->streamid = 0;
channel_data->is_blocking = 0;
- channel_data->timeout = 0;
channel_data->session_rsrc = resource_id;
channel_data->refcount = NULL;
@@ -1275,7 +1222,7 @@
long port;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsl", &zsession, &host, &host_len, &port) == FAILURE) {
- return;
+ RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(session, LIBSSH2_SESSION*, &zsession, -1, PHP_SSH2_SESSION_RES_NAME, le_ssh2_session);
@@ -1307,7 +1254,7 @@
long streamid;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zparent, &streamid) == FAILURE) {
- return;
+ RETURN_FALSE;
}
if (streamid < 0) {
|
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 19:00:01 2025 UTC |