Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12
  1. #1
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Angry ssh2_scp_send() Function returns TRUE but actually failed!

    I've been scouring the Internet trying to find a solution to this, but it simply doesn't make any sense. I am using the ssh2_scp_send() function to transfer files to a remote server. Connecting to the server and authenticating the user all work just fine. It's when I use this function to actually transfer the file, that's when things begin to get weird.

    As the title says, the function returns TRUE (and I used the === equality operator just to be sure), which according the PHP manual means that it was successful in transferring the file.

    PHP: ssh2_scp_send - Manual

    However, when I go into the remote directory where files should have been transferred to, it is empty! I deleted the directory at one point and still it returned TRUE! How can it claim success when the directory didn't even exist? I am pulling my hair out over this. See below for the code in question.

    PHP Code:
    //Connect to remote server
            
    echo 'Attempting to connect to '.$remote_host.'<br />';
            if(
    $connection ssh2_connect($remote_host$remote_port))
            {
                echo 
    'Authenticating user '.$remote_user.' . . . <br />';
                if(
    ssh2_auth_password($connection$remote_user$remote_pw))
                {
                    echo 
    'There are this many files: '.count($file_names).'<br />';
                    
    //Transfer each file
                    
    for($i=0$i count($file_names); ++$i)
                    {
                        echo 
    'Transferring file '.$file_names[$i].' . . .<br />';
                        if((
    ssh2_scp_send($connection$local_folder.$file_names[$i], $remote_folder.$file_names[$i], 0644)) === TRUE)
                        {
                            echo 
    'Transfer successful!<br />';
                        }
                        else
                        {
                            echo 
    'Transfer failed! <br />';
                            return 
    3;
                        }
                        if(
    $this->debug)
                        {
                            echo 
    'Transferring from <br />';
                            
    var_dump($local_folder.$file_names[$i]);
                            echo 
    'To remote directory <br />';
                            
    var_dump($remote_folder.$file_names[$i]);
                        }
                    }
                }
                else
                {
                    echo 
    'Authentication failed!<br />';
                    return 
    2;
                }
            }
            else
            {
                echo 
    'Connection to '.$remote_host.' failed!<br />';
                return 
    1;
            }

            return 
    0
    Any insight would be appreciated!

  • #2
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Thread bump

  • #3
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Identical operators are not actually required; the function is only capable of two results: true and false (or 0 and not 0). The identical is used when you have a function such as strpos where a failure results in false, but the first match is the character position in the array which is 0. PHP *should* (IMO) have used -1 as a failure condition, but at least the language does differentiate between boolean and integers.

    Enable the debug on the object and capture what's in the from and to locations. Also add to it: printf('Running location: %s', getcwd()); and post all the relevant output created in this block of code.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #4
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Fou-Lu View Post
    Identical operators are not actually required; the function is only capable of two results: true and false (or 0 and not 0). The identical is used when you have a function such as strpos where a failure results in false, but the first match is the character position in the array which is 0. PHP *should* (IMO) have used -1 as a failure condition, but at least the language does differentiate between boolean and integers.

    Enable the debug on the object and capture what's in the from and to locations. Also add to it: printf('Running location: %s', getcwd()); and post all the relevant output created in this block of code.
    Hello Fou-Lu,

    Thanks for responding. You are right that I didn't need to use the identical operator, and originally I didn't. I changed it later on when I was trying to figure out the source of the error, and figured I should cover all my bases.

    Anyway, I added to the debug code above so that it is now:
    PHP Code:
    if($this->debug)
    {
        
    printf('Running location: %s'getcwd());
        echo 
    '<br />Transferring from <br />';
        
    var_dump($local_folder.$file_names[$i]);
        echo 
    'To remote directory <br />';
        
    var_dump($remote_folder.$file_names[$i]);    

    This was the output:
    Code:
    Running location: /var/www/html
    Transferring from 
    string './uploads/Grid.gif' (length=18)
    To remote directory 
    string '/var/www/html/remote/Grid.gif' (length=29)

  • #5
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    So the file you are moving is from /var/www/html/uploads/Grid.gif on server A to /var/www/html/remote/Grid.gif on server B.
    The function is returning successful, but the file is never found in /var/www/html/remote on ServerB. The only thing that I can think of off hand is that the location isn't the same as where you're looking at.
    After the upload, why not try a simple ssh2_exec($connection, 'ls ' . $remote_folder); to see what the list shows (you'll need to fetch from the stream from the looks of it)?

    Potentially a silly question, but these are two different servers right? I just noticed the similar, but not identical path names.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #6
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Fou-Lu View Post
    Potentially a silly question, but these are two different servers right? I just noticed the similar, but not identical path names.
    Excellent question actually, and something I forgot to mention earlier. It is the same server making a request to itself. You might think this is pointless, and that I could just move the file with some mv or cp commands, but it was for a proof of concept sort of thing. I wanted to make sure that I could connect to another server and transfer the file and that SSH was properly set. I had the same reservations as you might be having about this, but my manager told me that this was a valid way to check if we could transfer files. Now based on your experience, would you say he was right or wrong? His justification for this was that if a server could ping itself, it should be able to remotely connect to itself and transfer files using the SSH/SCP protocol.

    I'll give a shot printing the directory contents and get back to you soon with those results.

  • #7
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    My experience with SCP and PHP is 0. I have never used the ssh2 library with PHP in the past, I can only base my information off of the API itself (which has somewhat useful documentation considering that its a PECL package). So I'm afraid I cannot comment on if that would be an issue; personally I wouldn't think it is. There is no issue with using an ssh terminal to yourself, I'm just not 100% sure about the SCP protocol in regards to moving a file from local to local (again, I still can't see it *not* working). The only suggestion there would be to connect to another owned machine to treat as the remote.

    In that case, I'd try going the other way. See what happens if you attempt to read a file from the "remote" side into the "local" side.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #8
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Fou-Lu View Post
    After the upload, why not try a simple ssh2_exec($connection, 'ls ' . $remote_folder); to see what the list shows (you'll need to fetch from the stream from the looks of it)?
    After the file was "successfully" uploaded, I added the following code to the list the contents of the directory (FYI, I Googled it so I don't know if this is the "proper" way to do it).
    PHP Code:
    if((ssh2_scp_send($connection$local_folder.$file_names[$i], $remote_folder.$file_names[$i], 0644)) === TRUE)
    {
        echo 
    'Transfer successful!<br />';
        
    $stream ssh2_exec($connection'ls ' $remote_folder);
        
    stream_set_blocking($streamtrue);
        
    $a = array();
        while(
    $o=fgets($stream)) 
        {
            
    $a[]=$o;
        }
        echo 
    "<pre>";
        
    print_r($a);
        echo 
    "</pre>";

    This prints an empty array, which means the directory itself is empty.
    Code:
    Array
    (
    )
    Suspecting that maybe the directory was wrong, I manually put in a test file into the remote directory, but the ls command found it. So I guess that proves that I am at least looking at the same directory that I am trying to transfer to.

    Code:
    Array
    (
        [0] => test_file.txt
    
    )
    I am going to ask my manager if I can get access to another (different) server and see if I can transfer between the two instead of trying to transfer from a server to itself. I'll get back to you when I have some results. Thanks for your help so far, though!

  • #9
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Whats the chmod on the directory, and who owns it? Is this the same user you've used for the ssh credentials?
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #10
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Fou-Lu View Post
    Whats the chmod on the directory, and who owns it? Is this the same user you've used for the ssh credentials?
    Originally, the owner was apache (the user that was running the PHP script). I changed the owner to the user that was logging in remotely via SSH instead, but still have the same result.

    I just got access to another server, and will try connecting to it soon, rather than connecting the same server to itself. I'll get back to you shortly with the results.

  • #11
    New Coder The Noob Coder's Avatar
    Join Date
    Jul 2012
    Location
    The City that Never Sleeps
    Posts
    99
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by The Noob Coder View Post
    I just got access to another server, and will try connecting to it soon, rather than connecting the same server to itself. I'll get back to you shortly with the results.
    Argh! Still the same result. I successfully connected to a completely different server, the functions returns TRUE and still the file wasn't actually transferred. (I ran the ls command to be sure.)

    Fou-Lu, if you wouldn't mind, could you please elaborate on what you meant by the following:
    In that case, I'd try going the other way. See what happens if you attempt to read a file from the "remote" side into the "local" side.
    This is the only thing I have not tried up to this point. Thanks!

  • #12
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    Flip the logic, put a file in place and attempt to retrieve it using the ssh2_scp_recv function instead. Its almost identical, but the idea is backwards, you'll move a file from remote to local.

    To me everything seems to cycle around privilege on the machine. The function itself doesn't dictate what it considers to be successful in the documentation. For a comparison, things like the mail function return true so long as the sendmail accepts the email. Beyond that, there's no guarantee the email well be sent. I'm wondering if there's something similar involved here.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •