|  | @@ -18,15 +18,19 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |      public partial class ScpClient
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          private static Regex _rootPath = new Regex(@"^(/|[A-Z][:])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  | -        /// Uploads the specified file or directory to the remote host.
 | 
	
		
			
				|  |  | +        /// Uploads the specified file to the remote host.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  | -        /// <param name="fileInfo">Local file to upload.</param>
 | 
	
		
			
				|  |  | -        /// <param name="filename">Remote host file name.</param>
 | 
	
		
			
				|  |  | -        /// <exception cref="ArgumentNullException"><paramref name="fileInfo"/> or <paramref name="filename"/> is null.</exception>
 | 
	
		
			
				|  |  | -        public void Upload(FileSystemInfo fileSystemInfo, string path)
 | 
	
		
			
				|  |  | +        /// <param name="fileInfo">The file system info.</param>
 | 
	
		
			
				|  |  | +        /// <param name="path">The path.</param>
 | 
	
		
			
				|  |  | +        /// <exception cref="System.ArgumentNullException">fileSystemInfo</exception>
 | 
	
		
			
				|  |  | +        /// <exception cref="System.ArgumentException">path</exception>
 | 
	
		
			
				|  |  | +        /// <exception cref="System.NotSupportedException"></exception>
 | 
	
		
			
				|  |  | +        /// <exception cref="ArgumentNullException"><paramref name="fileInfo" /> or <paramref name="filename" /> is null.</exception>
 | 
	
		
			
				|  |  | +        public void Upload(FileInfo fileInfo, string path)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if (fileSystemInfo == null)
 | 
	
		
			
				|  |  | +            if (fileInfo == null)
 | 
	
		
			
				|  |  |                  throw new ArgumentNullException("fileSystemInfo");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              if (string.IsNullOrEmpty(path))
 | 
	
	
		
			
				|  | @@ -43,56 +47,54 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  channel.Open();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                var isRootPath = _rootPath.Match(path);
 | 
	
		
			
				|  |  | +                //  Send channel command request
 | 
	
		
			
				|  |  | +                channel.SendExecRequest(string.Format("scp -t \"{0}\"", path));
 | 
	
		
			
				|  |  | +                this.CheckReturnCode(input);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                var pathParts = path.Split('\\', '/');
 | 
	
		
			
				|  |  | -                var targetPath = path;
 | 
	
		
			
				|  |  | +                this.InternalUpload(channel, input, fileInfo, fileInfo.Name);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if (isRootPath.Success)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    //  Send channel command request
 | 
	
		
			
				|  |  | -                    channel.SendExecRequest(string.Format("scp -rt \"{0}\"", path));
 | 
	
		
			
				|  |  | -                    this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    targetPath = pathParts.Last();
 | 
	
		
			
				|  |  | +                channel.Close();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    //  Send channel command request
 | 
	
		
			
				|  |  | -                    channel.SendExecRequest(string.Format("scp -rt \"{0}\"", pathParts[0]));
 | 
	
		
			
				|  |  | -                    this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | +        /// <summary>
 | 
	
		
			
				|  |  | +        /// Uploads the specified directory to the remote host.
 | 
	
		
			
				|  |  | +        /// </summary>
 | 
	
		
			
				|  |  | +        /// <param name="directoryInfo">The directory info.</param>
 | 
	
		
			
				|  |  | +        /// <param name="path">The path.</param>
 | 
	
		
			
				|  |  | +        /// <exception cref="System.ArgumentNullException">fileSystemInfo</exception>
 | 
	
		
			
				|  |  | +        /// <exception cref="System.ArgumentException">path</exception>
 | 
	
		
			
				|  |  | +        public void Upload(DirectoryInfo directoryInfo, string path)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            if (directoryInfo == null)
 | 
	
		
			
				|  |  | +                throw new ArgumentNullException("fileSystemInfo");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    //  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 (string.IsNullOrEmpty(path))
 | 
	
		
			
				|  |  | +                throw new ArgumentException("path");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if (fileSystemInfo is FileInfo)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    this.InternalUpload(channel, input, fileSystemInfo as FileInfo, targetPath);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else if (fileSystemInfo is DirectoryInfo)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    this.InternalUpload(channel, input, fileSystemInfo as DirectoryInfo, targetPath);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else
 | 
	
		
			
				|  |  | +            using (var input = new PipeStream())
 | 
	
		
			
				|  |  | +            using (var channel = this.Session.CreateChannel<ChannelSession>())
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                channel.DataReceived += delegate(object sender, Common.ChannelDataEventArgs e)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    throw new NotSupportedException(string.Format("Type '{0}' is not supported.", fileSystemInfo.GetType().FullName));
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +                    input.Write(e.Data, 0, e.Data.Length);
 | 
	
		
			
				|  |  | +                    input.Flush();
 | 
	
		
			
				|  |  | +                };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if (!isRootPath.Success)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    //  Finish directory structure
 | 
	
		
			
				|  |  | -                    for (int i = 0; i < pathParts.Length - 1; i++)
 | 
	
		
			
				|  |  | -                    {
 | 
	
		
			
				|  |  | -                        this.SendData(channel, "E\n");
 | 
	
		
			
				|  |  | -                        this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +                channel.Open();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                //  Send channel command request
 | 
	
		
			
				|  |  | +                channel.SendExecRequest(string.Format("scp -rt \"{0}\"", path));
 | 
	
		
			
				|  |  | +                this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                this.InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc);
 | 
	
		
			
				|  |  | +                this.SendData(channel, string.Format("D0755 0 {0}\n", Path.GetFileName(path)));
 | 
	
		
			
				|  |  | +                this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                this.InternalUpload(channel, input, directoryInfo as DirectoryInfo, directoryInfo.Name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                this.SendData(channel, "E\n");
 | 
	
		
			
				|  |  | +                this.CheckReturnCode(input);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  channel.Close();
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -177,12 +179,8 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private void InternalUpload(ChannelSession channel, PipeStream input, DirectoryInfo directoryInfo, string directoryName)
 | 
	
		
			
				|  |  | +        private void InternalUpload(ChannelSession channel, Stream input, DirectoryInfo directoryInfo, string directoryName)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            this.InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc);
 | 
	
		
			
				|  |  | -            this.SendData(channel, string.Format("D0755 0 {0}\n", directoryName));
 | 
	
		
			
				|  |  | -            this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |              //  Upload files
 | 
	
		
			
				|  |  |              var files = directoryInfo.GetFiles();
 | 
	
		
			
				|  |  |              foreach (var file in files)
 | 
	
	
		
			
				|  | @@ -194,11 +192,15 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              var directories = directoryInfo.GetDirectories();
 | 
	
		
			
				|  |  |              foreach (var directory in directories)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | +                this.InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc);
 | 
	
		
			
				|  |  | +                this.SendData(channel, string.Format("D0755 0 {0}\n", directory.Name));
 | 
	
		
			
				|  |  | +                this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  this.InternalUpload(channel, input, directory, directory.Name);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            this.SendData(channel, "E\n");
 | 
	
		
			
				|  |  | -            this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | +                this.SendData(channel, "E\n");
 | 
	
		
			
				|  |  | +                this.CheckReturnCode(input);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          private void InternalDownload(ChannelSession channel, Stream input, FileSystemInfo fileSystemInfo)
 |