From e1b2d13a990127fcc80753564f49fe170d68986b Mon Sep 17 00:00:00 2001 From: olegkap_cp Date: Sat, 2 Feb 2013 15:41:52 +0000 Subject: [PATCH] Fix SCP to handle root path --- .../Renci.SshNet/ConnectionInfo.cs | 3 ++ Renci.SshClient/Renci.SshNet/ScpClient.NET.cs | 46 +++++++++++++------ Renci.SshClient/Renci.SshNet/ScpClient.cs | 2 +- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs b/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs index 7be7b20a..be923202 100644 --- a/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs +++ b/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs @@ -264,6 +264,9 @@ namespace Renci.SshNet if (username.IsNullOrWhiteSpace()) throw new ArgumentException("username"); + if (authenticationMethods == null || authenticationMethods.Length < 1) + throw new ArgumentException("authenticationMethods"); + // Set default connection values this.Timeout = TimeSpan.FromSeconds(30); this.RetryAttempts = 10; diff --git a/Renci.SshClient/Renci.SshNet/ScpClient.NET.cs b/Renci.SshClient/Renci.SshNet/ScpClient.NET.cs index da56e230..4b5c80cf 100644 --- a/Renci.SshClient/Renci.SshNet/ScpClient.NET.cs +++ b/Renci.SshClient/Renci.SshNet/ScpClient.NET.cs @@ -17,6 +17,7 @@ namespace Renci.SshNet /// public partial class ScpClient { + private Regex _rootPath = new Regex(@"^(/|[A-Z][:])", RegexOptions.Compiled | RegexOptions.IgnoreCase); /// /// Uploads the specified file or directory to the remote host. /// @@ -42,38 +43,55 @@ namespace Renci.SshNet channel.Open(); + var isRootPath = _rootPath.Match(path); + var pathParts = path.Split('\\', '/'); + var targetPath = path; - // Send channel command request - channel.SendExecRequest(string.Format("scp -rt \"{0}\"", pathParts[0])); - this.CheckReturnCode(input); - - // Prepare directory structure - for (int i = 0; i < pathParts.Length - 1; i++) + if (isRootPath.Success) { - this.InternalSetTimestamp(channel, input, fileSystemInfo.LastWriteTimeUtc, fileSystemInfo.LastAccessTimeUtc); - this.SendData(channel, string.Format("D0755 0 {0}\n", pathParts[i])); + // Send channel command request + channel.SendExecRequest(string.Format("scp -rt \"{0}\"", path)); this.CheckReturnCode(input); } + else + { + targetPath = pathParts.Last(); + + // Send channel command request + channel.SendExecRequest(string.Format("scp -rt \"{0}\"", pathParts[0])); + this.CheckReturnCode(input); + + // Prepare directory structure + for (int i = 0; i < pathParts.Length - 1; i++) + { + this.InternalSetTimestamp(channel, input, fileSystemInfo.LastWriteTimeUtc, fileSystemInfo.LastAccessTimeUtc); + this.SendData(channel, string.Format("D0755 0 {0}\n", pathParts[i])); + this.CheckReturnCode(input); + } + } if (fileSystemInfo is FileInfo) { - this.InternalUpload(channel, input, fileSystemInfo as FileInfo, pathParts.Last()); + this.InternalUpload(channel, input, fileSystemInfo as FileInfo, targetPath); } else if (fileSystemInfo is DirectoryInfo) { - this.InternalUpload(channel, input, fileSystemInfo as DirectoryInfo, pathParts.Last()); + this.InternalUpload(channel, input, fileSystemInfo as DirectoryInfo, targetPath); } else { throw new NotSupportedException(string.Format("Type '{0}' is not supported.", fileSystemInfo.GetType().FullName)); } - // Finish directory structure - for (int i = 0; i < pathParts.Length - 1; i++) + if (!isRootPath.Success) { - this.SendData(channel, "E\n"); - this.CheckReturnCode(input); + // Finish directory structure + for (int i = 0; i < pathParts.Length - 1; i++) + { + this.SendData(channel, "E\n"); + this.CheckReturnCode(input); + } } channel.Close(); diff --git a/Renci.SshClient/Renci.SshNet/ScpClient.cs b/Renci.SshClient/Renci.SshNet/ScpClient.cs index 34bb5194..718095ce 100644 --- a/Renci.SshClient/Renci.SshNet/ScpClient.cs +++ b/Renci.SshClient/Renci.SshNet/ScpClient.cs @@ -249,7 +249,7 @@ namespace Renci.SshNet { var length = source.Length; - this.SendData(channel, string.Format("C0644 {0} {1}\n", length, filename)); + this.SendData(channel, string.Format("C0644 {0} {1}\n", length, Path.GetFileName(filename))); var buffer = new byte[this.BufferSize];