/// <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="ArgumentNullException">fileSystemInfo</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception> public void Upload(DirectoryInfo directoryInfo, string path) { if (directoryInfo == null) { throw new ArgumentNullException("directoryInfo"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentException("path"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // Send channel command request channel.SendExecRequest(string.Format("scp -rt \"{0}\"", path)); CheckReturnCode(input); InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc); SendData(channel, string.Format("D0755 0 {0}\n", Path.GetFileName(path))); CheckReturnCode(input); InternalUpload(channel, input, directoryInfo); SendData(channel, "E\n"); CheckReturnCode(input); } }
/// <summary> /// Uploads the specified stream to the remote host. /// </summary> /// <param name="source">Stream to upload.</param> /// <param name="path">Remote host file name.</param> public void Upload(Stream source, string path) { using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += delegate(object sender, ChannelDataEventArgs e) { input.Write(e.Data, 0, e.Data.Length); input.Flush(); }; channel.Open(); var pathEnd = path.LastIndexOfAny(new[] { '\\', '/' }); if (pathEnd != -1) { // split the path from the file var pathOnly = path.Substring(0, pathEnd); var fileOnly = path.Substring(pathEnd + 1); // Send channel command request channel.SendExecRequest(string.Format("scp -t \"{0}\"", pathOnly)); CheckReturnCode(input); path = fileOnly; } InternalUpload(channel, input, source, path); channel.Close(); } }
/// <summary> /// Uploads the specified file to the remote host. /// </summary> /// <param name="fileInfo">The file system info.</param> /// <param name="path">The path.</param> /// <exception cref="ArgumentNullException"><paramref name="fileInfo" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception> public void Upload(FileInfo fileInfo, string path) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentException("path"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); if (!channel.SendExecRequest(string.Format("scp -t \"{0}\"", path))) { throw new SshException("Secure copy execution request was rejected by the server. Please consult the server logs."); } CheckReturnCode(input); InternalUpload(channel, input, fileInfo, fileInfo.Name); } }
/// <summary> /// Uploads the specified file to the remote host. /// </summary> /// <param name="fileInfo">The file system info.</param> /// <param name="path">A relative or absolute path for the remote file.</param> /// <exception cref="ArgumentNullException"><paramref name="fileInfo" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="path" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is a zero-length <see cref="string"/>.</exception> /// <exception cref="ScpException">A directory with the specified path exists on the remote host.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Upload(FileInfo fileInfo, string path) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } var posixPath = PosixPath.CreateAbsoluteOrRelativeFilePath(path); using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // Pass only the directory part of the path to the server, and use the (hidden) -d option to signal // that we expect the target to be a directory. if (!channel.SendExecRequest(string.Format("scp -t -d {0}", _remotePathTransformation.Transform(posixPath.Directory)))) { throw SecureExecutionRequestRejectedException(); } CheckReturnCode(input); using (var source = fileInfo.OpenRead()) { UploadTimes(channel, input, fileInfo); UploadFileModeAndName(channel, input, source.Length, posixPath.File); UploadFileContent(channel, input, source, fileInfo.Name); } } }
/// <summary> /// Downloads the specified directory from the remote host to local directory. /// </summary> /// <param name="directoryName">Remote host directory name.</param> /// <param name="directoryInfo">Local directory information.</param> /// <exception cref="ArgumentException"><paramref name="directoryName"/> is <c>null</c> or empty.</exception> /// <exception cref="ArgumentNullException"><paramref name="directoryInfo"/> is <c>null</c>.</exception> /// <exception cref="ScpException">File or directory with the specified path does not exist on the remote host.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Download(string directoryName, DirectoryInfo directoryInfo) { if (string.IsNullOrEmpty(directoryName)) { throw new ArgumentException("directoryName"); } if (directoryInfo == null) { throw new ArgumentNullException("directoryInfo"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // Send channel command request if (!channel.SendExecRequest(string.Format("scp -prf {0}", _remotePathTransformation.Transform(directoryName)))) { throw SecureExecutionRequestRejectedException(); } // Send reply SendSuccessConfirmation(channel); InternalDownload(channel, input, directoryInfo); } }
/// <summary> /// Downloads the specified directory from the remote host to local directory. /// </summary> /// <param name="directoryName">Remote host directory name.</param> /// <param name="directoryInfo">Local directory information.</param> /// <exception cref="ArgumentException"><paramref name="directoryName"/> is <c>null</c> or empty.</exception> /// <exception cref="ArgumentNullException"><paramref name="directoryInfo"/> is <c>null</c>.</exception> public void Download(string directoryName, DirectoryInfo directoryInfo) { if (string.IsNullOrEmpty(directoryName)) { throw new ArgumentException("directoryName"); } if (directoryInfo == null) { throw new ArgumentNullException("directoryInfo"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // Send channel command request channel.SendExecRequest(string.Format("scp -prf \"{0}\"", directoryName)); SendConfirmation(channel); // Send reply InternalDownload(channel, input, directoryInfo); channel.Close(); } }
/// <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="ArgumentNullException">fileSystemInfo</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception> public void Upload(DirectoryInfo directoryInfo, string path) { if (directoryInfo == null) { throw new ArgumentNullException("directoryInfo"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentException("path"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // start recursive upload channel.SendExecRequest(string.Format("scp -rt \"{0}\"", path)); CheckReturnCode(input); // set last write and last access time on specified remote path InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc); SendData(channel, string.Format("D0755 0 {0}\n", ".")); CheckReturnCode(input); // recursively upload files and directories in specified remote path InternalUpload(channel, input, directoryInfo); // terminate upload of specified remote path SendData(channel, "E\n"); CheckReturnCode(input); } }
/// <summary> /// Uploads the specified directory to the remote host. /// </summary> /// <param name="directoryInfo">The directory info.</param> /// <param name="path">A relative or absolute path for the remote directory.</param> /// <exception cref="ArgumentNullException">fileSystemInfo</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception> /// <exception cref="ScpException"><paramref name="path"/> exists on the remote host, and is not a directory.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Upload(DirectoryInfo directoryInfo, string path) { if (directoryInfo == null) { throw new ArgumentNullException("directoryInfo"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentException("path"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // start recursive upload if (!channel.SendExecRequest(string.Format("scp -rt {0}", _remotePathTransformation.Transform(path)))) { throw SecureExecutionRequestRejectedException(); } CheckReturnCode(input); UploadTimes(channel, input, directoryInfo); UploadDirectoryModeAndName(channel, input, "."); UploadDirectoryContent(channel, input, directoryInfo); } }
/// <summary> /// Uploads the specified file to the remote host. /// </summary> /// <param name="fileInfo">The file system info.</param> /// <param name="path">A relative or absolute path for the remote file.</param> /// <exception cref="ArgumentNullException"><paramref name="fileInfo" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception> /// <exception cref="ScpException">A directory with the specified path exists on the remote host.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Upload(FileInfo fileInfo, string path) { if (fileInfo == null) { throw new ArgumentNullException("fileInfo"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentException("path"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); if (!channel.SendExecRequest(string.Format("scp -t {0}", _remotePathTransformation.Transform(path)))) { throw SecureExecutionRequestRejectedException(); } CheckReturnCode(input); using (var source = fileInfo.OpenRead()) { UploadTimes(channel, input, fileInfo); UploadFileModeAndName(channel, input, source.Length, string.Empty); UploadFileContent(channel, input, source, fileInfo.Name); } } }
/// <summary> /// Downloads the specified file from the remote host to the stream. /// </summary> /// <param name="filename">A relative or absolute path for the remote file.</param> /// <param name="destination">The <see cref="Stream"/> to download the remote file to.</param> /// <exception cref="ArgumentException"><paramref name="filename"/> is <c>null</c> or contains only whitespace characters.</exception> /// <exception cref="ArgumentNullException"><paramref name="destination"/> is <c>null</c>.</exception> /// <exception cref="ScpException"><paramref name="filename"/> exists on the remote host, and is not a regular file.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Download(string filename, Stream destination) { if (filename.IsNullOrWhiteSpace()) { throw new ArgumentException("filename"); } if (destination == null) { throw new ArgumentNullException("destination"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // Send channel command request if (!channel.SendExecRequest(string.Format("scp -f {0}", _remotePathTransformation.Transform(filename)))) { throw SecureExecutionRequestRejectedException(); } SendSuccessConfirmation(channel); // Send reply var message = ReadString(input); var match = FileInfoRe.Match(message); if (match.Success) { // Read file SendSuccessConfirmation(channel); // Send reply var length = long.Parse(match.Result("${length}")); var fileName = match.Result("${filename}"); InternalDownload(channel, input, destination, fileName, length); } else { SendErrorConfirmation(channel, string.Format("\"{0}\" is not valid protocol message.", message)); } } }
/// <summary> /// Uploads the specified stream to the remote host. /// </summary> /// <param name="source">The <see cref="Stream"/> to upload.</param> /// <param name="path">A relative or absolute path for the remote file.</param> /// <exception cref="ScpException">A directory with the specified path exists on the remote host.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Upload(Stream source, string path) { using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // pass the full path to ensure the server does not create the directory part // as a file in case the directory does not exist if (!channel.SendExecRequest(string.Format("scp -t {0}", _remotePathTransformation.Transform(path)))) { throw SecureExecutionRequestRejectedException(); } CheckReturnCode(input); // specify a zero-length file name to avoid creating a file with absolute // path '<path>/<filename part of path>' if directory '<path>' already exists UploadFileModeAndName(channel, input, source.Length, PosixPath.GetFileName(path)); UploadFileContent(channel, input, source, PosixPath.GetFileName(path)); } }
/// <summary> /// Uploads the specified directory to the remote host. /// </summary> /// <param name="directoryInfo">The directory info.</param> /// <param name="path">A relative or absolute path for the remote directory.</param> /// <exception cref="ArgumentNullException"><paramref name="directoryInfo"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="path"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is a zero-length string.</exception> /// <exception cref="ScpException"><paramref name="path"/> does not exist on the remote host, is not a directory or the user does not have the required permission.</exception> /// <exception cref="SshException">The secure copy execution request was rejected by the server.</exception> public void Upload(DirectoryInfo directoryInfo, string path) { if (directoryInfo == null) { throw new ArgumentNullException("directoryInfo"); } if (path == null) { throw new ArgumentNullException("path"); } if (path.Length == 0) { throw new ArgumentException("The path cannot be a zero-length string.", "path"); } using (var input = ServiceFactory.CreatePipeStream()) using (var channel = Session.CreateChannelSession()) { channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length); channel.Open(); // start copy with the following options: // -p preserve modification and access times // -r copy directories recursively // -d expect path to be a directory // -t copy to remote if (!channel.SendExecRequest(string.Format("scp -r -p -d -t {0}", _remotePathTransformation.Transform(path)))) { throw SecureExecutionRequestRejectedException(); } CheckReturnCode(input); UploadDirectoryContent(channel, input, directoryInfo); } }