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.comIndex: 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 Group All rights reserved. |
Last updated: Wed Jan 15 13:01:29 2025 UTC |