php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #56425 Problem with ssh2_scp_send
Submitted: 2005-06-23 05:58 UTC Modified: 2012-10-06 09:25 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: david dot richard at euroconnect dot fr Assigned: langemeijer (profile)
Status: Closed Package: ssh2 (PECL)
PHP Version: 4.3.4 OS: Red Hat Linux 7.3
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: david dot richard at euroconnect dot fr
New email:
PHP Version: OS:

 

 [2005-06-23 05:58 UTC] david dot richard at euroconnect dot fr
Description:
------------
I have encountered a problem with ssh2-0.8 and ssh2_scp_send command (it was working very well with ssh2-0.6).
The problem is, when I copy a file to the remote server, the result is always an empty file.

Somebody can help me ?

Thanks
David

Reproduce code:
---------------
<?php
	if( ($ssh = ssh2_connect("192.168.128.25" , 22)) ){
		if( ssh2_auth_password($ssh, user, password) ){
			ssh2_scp_send($ssh,"/complitepath/script.sh", "script.sh");
		}
	}
?>

Expected result:
----------------
The file may be copy to the remote host

Actual result:
--------------
The file is copy but it is empty

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-06-25 19:14 UTC] nospam at noreply dot com
Bug confirmed. PHP 5.0.4

It uploads a 200kb tarball just fine but wont upload a txt file with just the md5 in it
 [2005-07-16 03:17 UTC] cstdenis at ctgameinfo dot com
I'm experiencing something similar. The files transfer but are incomplete (about half size)
 [2005-07-16 03:37 UTC] cstdenis at ctgameinfo dot com
Workaround: 
Doesn't seem to occur with copy() combined with the ssh2.sftp:// wrapper.
 [2005-08-11 12:36 UTC] jrweir at gmail dot com
Bug confirmed in PHP 5.0.4 and 5.1b3 on Windows XP with Apache 2 and IIS 5
 [2005-08-11 13:53 UTC] jrweir at gmail dot com
cstdenis at ctgameinfo dot com's workaround does not work for Windows
 [2005-09-28 11:47 UTC] robert dot koch at owh dot com
I am experiencing similar transfer problems using the latest 
versions of libssh (libssh2-0.11) and ssh2 (ssh2-0.9) on 
Linux ASE 3.

When using the function below not all of a file will 
transfer to the destination server (Windows or Linux).

any help would be appreciated.

<code>
define("SCP_SERVER",	"<server>");
define("SCP_USER",		"<user>");
define("SCP_PASSWORD",	"<password>");
define("SCP_PATH",		"<path>");


function dat_xmit_file_scp($i_src_file_nm, $i_dst_file_nm)
{
	$methods = array('client_to_server'=>array
('comp'=>'none'),'server_to_client'=>array('comp'=>'none'));
	$connection = ssh2_connect(SCP_SERVER, 22, $methods) or 
die("Couldn't connect to ".SCP_SERVER);
	$rc=false;

	if (@ssh2_auth_password($connection, SCP_USER, 
SCP_PASSWORD))
	{
			print("i_src_file_nm:".
$i_src_file_nm."&nbsp;&nbsp;&nbsp;i_dst_file_nm:".SCP_PATH.u
rlencode($i_dst_file_nm)."<br />");
			$rc = ssh2_scp_send($connection, $i_src_file_nm, 
SCP_PATH.urlencode($i_dst_file_nm), 0644);
	}
	unset($connection);

	$desc = (($rc !== false)? ("Upload Successful:\n" . 
$i_dst_file_nm )
							: "Upload Failed: " . 
$i_dst_file_nm);

	$status = array("result"=>$rc, "desc"=>$desc);
	return ($status);
}
</code>
 [2005-11-03 08:53 UTC] graham1 dot simpson at hsbcib dot com
Can confirm file truncation occurs with RedHat AS3.0 running php v5.0.4 and libssh2 v0.11.
 [2006-09-29 13:33 UTC] kmillecam at webwiseone dot com
I had the same problem with empty files.

Was able to work around it by adding an exit command to the end of my script:

ssh2_scp_send($scpconnection, $scpsource, $scptarget, 0774);
$stream = ssh2_exec($scpconnection, 'exit');
 [2006-11-22 08:54 UTC] bate@php.net
I had the same problem with a 29 byte link test text file.
it wasnt copied. a bug file (100mb) was also copied but there are some missing bytes (~30) at the beginning. Maybe this helps.
 [2007-02-27 07:46 UTC] cristi at ghioc dot com
This is what I had to do to copy a txt file from a Windows/php command line through to a cygwin (linux emulator for windows):


copy winscp3.exe in the php's folder

<? 
//we'll get rid of the extension and then rename it back to .txt once it's copied
$file = $path.$filename;
rename ( $file , str_replace ( ".txt" , "" , $file ));
$file =  str_replace ( ".txt" , "" , $file );


//in the php source create a temp winscp script file
			$tempfile = 'tempscript.txt';
			$somecontent = "# Automatically answer all prompts negatively not to stall
# the script on errors
option batch on
# Disable overwrite confirmations that conflict with the previous
option confirm off
# Connect using a password
open ".$user.":".$pwd."@".$server."
# Change remote directory
# cd /blah/
# Force binary mode transfer
# option transfer binary
# Upload the file to current working directory
put ".$file."
# rename the file to a .txt remotely
mv  ".str_replace ( ".txt" , "" , $filename )." ".$filename."
# Disconnect
close
# Exit WinSCP
exit\n";
			
		
			   if (!$handle = fopen($tempfile, 'w')) {
			         echo "Cannot open file ($tempfile)";
			         exit;
			   }
			
			   // Write $somecontent to our opened file.
			   if (fwrite($handle, $somecontent) === FALSE) {
			       echo "Cannot write to file ($tempfile)";
			       exit;
			   }
			
			   //echo "Success, wrote ($somecontent) to file ($tempfile)";
			
			   fclose($handle);



$command1 = "winscp3.exe /console /script=tempscript.txt";
	//run command
	$result = system($command1);
	echo $result;
	//delete temp file
	unlink($tempfile);
	//rename file back to txt
	rename ( $file , $file.".txt");


?>

hope this will help someone
Cris.
 [2007-04-27 10:27 UTC] gian at nexta dot com
Hi,
The problem seems to be a buffer not flushed in the ssh2_scp_send function. Try to send any kind of file and then another "stub" file (eg. from /tmp/dummyfile.txt to remote /tmp/dummyfile.txt): the first real file will be saved correctly. It looks that when calling ssh2_scp_send for just one file.. it does not flush the buffers. It sometimes works with bigger files (eg. 200k tarballs) since buffer has to be committed. Hope this help developers. Hint: there is no ssh2_DISconnect function as opposed to ssh2_connect. Maybe it could be defined and used to flush buffers. I wrote mine by just sending a dummy file..
 [2007-05-16 15:35 UTC] joethielen at familyandyouth dot org
I am having the same problem on Using PHP-5.2.1, libssh2 2.0.14, on Mandriva 2007.1.  I send files that are 28K or so, and only 24K or so get transferred.


Thank you to "gian at nexta dot com".  I followed his advice and followed sending my primary file with another very small file, and that seemed to fix the situation for now.
 [2007-07-03 04:22 UTC] jani dot ollikainen at pronetko dot fi
Works with libssh2 version 0.15 without workaround:
$stream = ssh2_exec($connection, 'exit');
 [2008-05-14 08:45 UTC] volkirik at yahoo dot com dot tr
If you dont want to execute "exit" command or use unset() function; you can patch ssh2 extension:

Open ssh2.c

1) Add following lines before " PHP_FUNCTION(ssh2_fingerprint) " and after " /* }}} */ "


/* {{{ proto resource ssh2_disconnect(resource session)
 * Close the SSH server connection and return a true on success, false on error
 */
PHP_FUNCTION(ssh2_disconnect)
{
	zval *zsession;

	/* check & parse parameters */
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zsession) == FAILURE) {
		RETURN_FALSE;
	}

	/* decrease the refcount and call destructor if needed */
	if (zend_list_delete(Z_LVAL_P(zsession)) == FAILURE) {
		RETURN_FALSE;
	}

	/* destruct pointer */
	zval_ptr_dtor(&zsession);

	RETURN_TRUE;
}
/* }}} */



2) Declare the ssh2_disconnect() function again by adding a line after the existing PHP_FE() line.

find following line :

	PHP_FE(ssh2_connect,						NULL)

after add:

	PHP_FE(ssh2_disconnect,						NULL)


Important Note: Do it only if you know what you do.

You should close all streams before calling ssh2_disconnect()
 [2009-04-03 09:29 UTC] thomas dot vequaud at gmail dot com
I have got the following error mesage : "ssh2_scp_send() Failure creating remote file"
Folder exists, chmod is correct, I can create a new file manually with Filezilla and same username/password... I have absolutely no reason to get this error.
 [2009-12-04 04:37 UTC] antonio dot garcia at stl dot es
On solaris 10 i have the same problem. Sending the same file 
sometimes the file is send complete but other times the 
destination file size is random.

rw-r--r--   1 oracle   oinstall  139264 Dec  4 10:21 
prc_cancel.test0
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test1
-rw-r--r--   1 oracle   oinstall  139264 Dec  4 10:21 
prc_cancel.test2
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test3
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test4
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test5
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test6
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test7
-rw-r--r--   1 oracle   oinstall  160575 Dec  4 10:21 
prc_cancel.test8
 [2010-07-09 10:11 UTC] nospam dot thanks at hopethishelpssomeone dot com
I've spent the better part of the morning trying to diagnose 
failures on ssh2_scp_send.  My conclusion is that this package 
is not fully compatible with newer versions of LibSSH2.

I had success using LibSSH2 1.1 ... if you're having troubles 
too, try reverting to LibSSH 1.1
 [2010-09-21 20:00 UTC] samxnguyen at gmail dot com
calling ssh2_exec($ssh, 'exit') doesn't fix the problem for 
me, nor does unsetting the ssh2 resource (although it appears 
to make the problem occur less)

Centos 5.5
libssh2-1.2.7
PECL/ssh2-0.11
php-5.2.10
 [2011-07-26 10:01 UTC] cedric dot roussel at dila dot gouv dot fr
Hello,

I have resolved the issue of copying a file of a size superior to 128 kbytes with the ssh2_send_scp php function. I compared bit of source code from an example found on the libssh2 web site to the ssh2 php package bit of source code that call the ssh2_send_scp() function and made things work! 

The error was in the loop used to read the local file data stream and on the method used to write this stream in the ssh2 channel.

May be this has been corrected in the last daily build but I can provide a patch if needed. 

Regards

Cedric
 [2011-08-05 21:32 UTC] msanpedro at digitronsoftware dot net
Cedric,

I am interested in your patch if possible?  Any assistance is 
appreciate.  I am experiencing the exact same problem.

Marc
 [2011-09-28 13:18 UTC] kacarstensen at csupomona dot edu
A user on our php installation reported that ssh2_scp_send would sometimes fail to write data to the remote target, which is similar to many of the issues reported by others on this ticket. The following diff (lightly tested on our installation, not guaranteed to be correct) fixes the issue in our case:

--- ssh2-0.11.2/ssh2_fopen_wrappers.c	2010-11-03 15:24:33.000000000 -0700
+++ ssh2-0.11.2-new/ssh2_fopen_wrappers.c	2011-09-28 09:35:35.000000000 -0700
@@ -1047,13 +1047,19 @@
 			libssh2_channel_free(remote_file);
 			RETURN_FALSE;
 		}
+		size_t sent = 0;
+		size_t justsent = 0;
 
-		if (bytesread != libssh2_channel_write(remote_file, buffer, bytesread)) {
-			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed copying file");
-			php_stream_close(local_file);
-			libssh2_channel_free(remote_file);
-			RETURN_FALSE;
+		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;
+			}
+			sent = sent + justsent;
 		}
+
 		ssb.sb.st_size -= bytesread;
 	}
 
I'd be interested in seeing/knowing if that's similar to what Cedric did.
 [2012-02-09 08:06 UTC] aleksey at wepay dot com
We had to add flush to solve the problem

--- ssh2-0.11.3/ssh2_fopen_wrappers.c.orig      2011-09-27 13:05:05.000000000 -0700
+++ ssh2-0.11.3/ssh2_fopen_wrappers.c   2012-02-08 23:40:13.000000000 -0800
@@ -1052,13 +1052,19 @@
                        libssh2_channel_free(remote_file);
                        RETURN_FALSE;
                }
+               size_t sent = 0;
+               size_t justsent = 0;

-               if (bytesread != libssh2_channel_write(remote_file, buffer, bytesread)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed copying file");
-                       php_stream_close(local_file);
-                       libssh2_channel_free(remote_file);
-                       RETURN_FALSE;
+               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;
+                       }
+                       sent = sent + justsent;
                }
+
                ssb.sb.st_size -= bytesread;
        }

--- ssh2-0.11.3/ssh2_fopen_wrappers.c   2012-02-08 23:42:12.000000000 -0800
+++ ssh2-0.11.3/ssh2_fopen_wrappers.c.new       2012-02-08 23:58:59.000000000 -0800
@@ -1068,6 +1068,7 @@
                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;
 [2012-02-23 14:23 UTC] george dot sallows at pearson dot com
We had to change the line in the fix from:
if ((justsent = libssh2_channel_write(remote_file, (buffer + sent), bytesread - sent)) <= 0) {

to:
if ((justsent = libssh2_channel_write(remote_file, (buffer + sent), bytesread - sent)) < 0) {

as in our case for some reason (probably network timing) the write was returning 0 as it hadn't had time to write anything from the buffer.
As there was no error condition here, just continuing and retrying solved the problem.

During debugging it also helped to change the error message in this new piece of code to  "Failed copying file. Destination write failed" as this distinguishes it from a possible read failure message earlier that otherwise had the same message.
 [2012-06-13 19:32 UTC] langemeijer@php.net
Automatic comment from SVN on behalf of langemeijer
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=326163
Log: Fix for bug #56425
 [2012-06-13 19:44 UTC] langemeijer@php.net
I've committed the patch provided by kacarstensen, improved by aleksey and fixed 
by george sallows into SVN. Thank you guys!

I wonder if anyone else who has stumbled upon this bug before can verify that 
this bug is solved with the latest svn version. Please try. If you can't figure 
out how to compile the svn version, please contact me by email, not in this bug.

Positive or negative test reports in the ticket please!
 [2012-06-13 19:45 UTC] langemeijer@php.net
-Status: Open +Status: Feedback
 [2012-10-06 09:25 UTC] langemeijer@php.net
As I stated above: fixed in svn.

Also I've made ssh2_scp_send a little more verbose when an error occurs.

Marking the issue as closed
 [2012-10-06 09:25 UTC] langemeijer@php.net
-Status: Feedback +Status: Closed -Assigned To: +Assigned To: langemeijer
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Nov 19 00:01:39 2019 UTC