0 votes
by (120 points)
edited

Hello, I trying your .NET library. When I connected on SFTP server, i need copy files from server to another directory on the server (this directory is mapped disk array). Is it possible? Have you any idea? Thanx a lot.

Applies to: Rebex SFTP

1 Answer

+2 votes
by (144k points)
edited

Although this operation (copy a file located at the server to another directory at the server) is not supported by the SFTP protocol (and Rebex SFTP), it is often possible to achieve it by utilizing the fact that SFTP runs over SSH. This makes it possible to use SSH's "remote execute" feature to run arbitrary commands at the server (if it was configured to allow that, of course).

To give it a try, use the following class:

C#

public class SftpCommandRunner
{
    public static string RunCommand(Sftp sftp, string command)
    {
        SshChannel channel = null;
        try
        {
            // start an exec session
            channel = sftp.Session.OpenSession();
            channel.RequestExec(command);

            // receive all response
            StringBuilder response = new StringBuilder();
            byte[] buffer = new byte[4096];
            while (channel.State == SshChannelState.Connected)
            {
                if (!channel.Poll(sftp.Timeout * 1000, SocketSelectMode.SelectRead))
                    break;

                int n = channel.Receive(buffer, 0, buffer.Length);
                response.Append(Encoding.Default.GetString(buffer, 0, n));
            }

            return response.ToString().TrimEnd();
        }
        finally
        {
            if (channel != null)
                channel.Close();
        }
    }
}

VB.NET

Public Class SftpCommandRunner
    Public Shared Function RunCommand(ByVal sftp As Sftp, ByVal command As String) As String
        Dim channel As SshChannel = Nothing
        Try
            ''# start an exec session
            channel = sftp.Session.OpenSession()
            channel.RequestExec(command)

            ''# receive all response
            Dim response As New StringBuilder()
            Dim buffer As Byte() = New Byte(4095) {}
            While channel.State = SshChannelState.Connected
                If Not channel.Poll(sftp.Timeout * 1000, SocketSelectMode.SelectRead) Then
                    Exit While
                End If

                Dim n As Integer = channel.Receive(buffer, 0, buffer.Length)
                response.Append(Encoding.[Default].GetString(buffer, 0, n))
            End While

            Return response.ToString().TrimEnd()
        Finally
            If channel IsNot Nothing Then
                channel.Close()
            End If
        End Try
    End Function
End Class

To copy a file located at the server to another directory, establish an SFTP connection and call SftpCommandRunner.RunCommand, supplying your Sftp objecet and a command to it. For Unix-like OS, the command would be "cp source_path destination_path". For Windows OS, use "copy" instead of "cp".

Does this work for you?

...