SftpClient
Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Renci.SshNet
{
[NullableContext(1)]
[Nullable(0)]
public class SftpClient : BaseClient, ISftpClient, IBaseClient, IDisposable
{
private static readonly Encoding Utf8NoBOM = new UTF8Encoding(false, true);
[Nullable(2)]
private ISftpSession _sftpSession;
private int _operationTimeout;
private uint _bufferSize;
public TimeSpan OperationTimeout {
get {
return TimeSpan.FromMilliseconds(_operationTimeout, 0);
}
set {
_operationTimeout = value.AsTimeout("OperationTimeout");
ISftpSession sftpSession = _sftpSession;
if (sftpSession != null)
sftpSession.OperationTimeout = _operationTimeout;
}
}
public uint BufferSize {
get {
CheckDisposed();
return _bufferSize;
}
set {
CheckDisposed();
_bufferSize = value;
}
}
public override bool IsConnected {
get {
if (base.IsConnected)
return _sftpSession?.IsOpen ?? false;
return false;
}
}
public string WorkingDirectory {
get {
CheckDisposed();
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
return _sftpSession.WorkingDirectory;
}
}
public int ProtocolVersion {
get {
CheckDisposed();
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
return (int)_sftpSession.ProtocolVersion;
}
}
[Nullable(2)]
internal ISftpSession SftpSession {
[NullableContext(2)]
get {
return _sftpSession;
}
}
public SftpClient(ConnectionInfo connectionInfo)
: this(connectionInfo, false)
{
}
public SftpClient(string host, int port, string username, string password)
: this(new PasswordConnectionInfo(host, port, username, password), true)
{
}
public SftpClient(string host, string username, string password)
: this(host, 22, username, password)
{
}
public SftpClient(string host, int port, string username, params IPrivateKeySource[] keyFiles)
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
{
}
public SftpClient(string host, string username, params IPrivateKeySource[] keyFiles)
: this(host, 22, username, keyFiles)
{
}
private SftpClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo)
: this(connectionInfo, ownsConnectionInfo, new ServiceFactory())
{
}
internal SftpClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, IServiceFactory serviceFactory)
: base(connectionInfo, ownsConnectionInfo, serviceFactory)
{
_operationTimeout = -1;
_bufferSize = 32768;
}
public void ChangeDirectory(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
_sftpSession.ChangeDirectory(path);
}
public Task ChangeDirectoryAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
{
CheckDisposed();
ThrowHelper.ThrowIfNull(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
cancellationToken.ThrowIfCancellationRequested();
return _sftpSession.ChangeDirectoryAsync(path, cancellationToken);
}
public void ChangePermissions(string path, short mode)
{
Get(path).SetPermissions(mode);
}
public void CreateDirectory(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestMkDir(canonicalPath);
}
[AsyncStateMachine(typeof(<CreateDirectoryAsync>d__29))]
public Task CreateDirectoryAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
{
<CreateDirectoryAsync>d__29 stateMachine = default(<CreateDirectoryAsync>d__29);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void DeleteDirectory(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestRmDir(canonicalPath);
}
[AsyncStateMachine(typeof(<DeleteDirectoryAsync>d__31))]
public Task DeleteDirectoryAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
{
<DeleteDirectoryAsync>d__31 stateMachine = default(<DeleteDirectoryAsync>d__31);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void DeleteFile(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestRemove(canonicalPath);
}
[AsyncStateMachine(typeof(<DeleteFileAsync>d__33))]
public Task DeleteFileAsync(string path, CancellationToken cancellationToken)
{
<DeleteFileAsync>d__33 stateMachine = default(<DeleteFileAsync>d__33);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void RenameFile(string oldPath, string newPath)
{
RenameFile(oldPath, newPath, false);
}
public void RenameFile(string oldPath, string newPath, bool isPosix)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(oldPath, "oldPath");
ThrowHelper.ThrowIfNull(newPath, "newPath");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(oldPath);
string canonicalPath2 = _sftpSession.GetCanonicalPath(newPath);
if (isPosix)
_sftpSession.RequestPosixRename(canonicalPath, canonicalPath2);
else
_sftpSession.RequestRename(canonicalPath, canonicalPath2);
}
[AsyncStateMachine(typeof(<RenameFileAsync>d__36))]
public Task RenameFileAsync(string oldPath, string newPath, CancellationToken cancellationToken)
{
<RenameFileAsync>d__36 stateMachine = default(<RenameFileAsync>d__36);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.oldPath = oldPath;
stateMachine.newPath = newPath;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void SymbolicLink(string path, string linkPath)
{
CheckDisposed();
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
ThrowHelper.ThrowIfNullOrWhiteSpace(linkPath, "linkPath");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
string canonicalPath2 = _sftpSession.GetCanonicalPath(linkPath);
_sftpSession.RequestSymLink(canonicalPath, canonicalPath2);
}
public IEnumerable<ISftpFile> ListDirectory(string path, [Nullable(2)] Action<int> listCallback = null)
{
CheckDisposed();
return InternalListDirectory(path, null, listCallback);
}
[AsyncIteratorStateMachine(typeof(<ListDirectoryAsync>d__39))]
public IAsyncEnumerable<ISftpFile> ListDirectoryAsync(string path, [EnumeratorCancellation] CancellationToken cancellationToken)
{
<ListDirectoryAsync>d__39 <ListDirectoryAsync>d__ = new <ListDirectoryAsync>d__39(-2);
<ListDirectoryAsync>d__.<>4__this = this;
<ListDirectoryAsync>d__.<>3__path = path;
<ListDirectoryAsync>d__.<>3__cancellationToken = cancellationToken;
return <ListDirectoryAsync>d__;
}
[NullableContext(2)]
[return: Nullable(1)]
public IAsyncResult BeginListDirectory([Nullable(1)] string path, AsyncCallback asyncCallback, object state, Action<int> listCallback = null)
{
CheckDisposed();
SftpListDirectoryAsyncResult asyncResult = new SftpListDirectoryAsyncResult(asyncCallback, state);
ThreadAbstraction.ExecuteThread(delegate {
try {
List<ISftpFile> result = InternalListDirectory(path, asyncResult, listCallback);
asyncResult.SetAsCompleted(result, false);
} catch (Exception exception) {
asyncResult.SetAsCompleted(exception, false);
}
});
return asyncResult;
}
public IEnumerable<ISftpFile> EndListDirectory(IAsyncResult asyncResult)
{
SftpListDirectoryAsyncResult sftpListDirectoryAsyncResult = asyncResult as SftpListDirectoryAsyncResult;
if (sftpListDirectoryAsyncResult == null || sftpListDirectoryAsyncResult.EndInvokeCalled)
throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
return sftpListDirectoryAsyncResult.EndInvoke();
}
public ISftpFile Get(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
SftpFileAttributes attributes = _sftpSession.RequestLStat(canonicalPath);
return new SftpFile(_sftpSession, canonicalPath, attributes);
}
[AsyncStateMachine(typeof(<GetAsync>d__43))]
public Task<ISftpFile> GetAsync(string path, CancellationToken cancellationToken)
{
<GetAsync>d__43 stateMachine = default(<GetAsync>d__43);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<ISftpFile>.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public bool Exists(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
if (_sftpSession != null) {
string canonicalPath = _sftpSession.GetCanonicalPath(path);
try {
_sftpSession.RequestLStat(canonicalPath);
return true;
} catch (SftpPathNotFoundException) {
return false;
}
}
throw new SshConnectionException("Client not connected.");
}
[AsyncStateMachine(typeof(<ExistsAsync>d__45))]
public Task<bool> ExistsAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
{
<ExistsAsync>d__45 stateMachine = default(<ExistsAsync>d__45);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<bool>.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void DownloadFile(string path, Stream output, [Nullable(2)] Action<ulong> downloadCallback = null)
{
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
ThrowHelper.ThrowIfNull(output, "output");
CheckDisposed();
InternalDownloadFile(path, output, null, downloadCallback, false, CancellationToken.None).GetAwaiter().GetResult();
}
public Task DownloadFileAsync(string path, Stream output, CancellationToken cancellationToken = default(CancellationToken))
{
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
ThrowHelper.ThrowIfNull(output, "output");
CheckDisposed();
return InternalDownloadFile(path, output, null, null, true, cancellationToken);
}
public IAsyncResult BeginDownloadFile(string path, Stream output)
{
return BeginDownloadFile(path, output, null, null, null);
}
public IAsyncResult BeginDownloadFile(string path, Stream output, [Nullable(2)] AsyncCallback asyncCallback)
{
return BeginDownloadFile(path, output, asyncCallback, null, null);
}
public IAsyncResult BeginDownloadFile(string path, Stream output, [Nullable(2)] AsyncCallback asyncCallback, [Nullable(2)] object state, [Nullable(2)] Action<ulong> downloadCallback = null)
{
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
ThrowHelper.ThrowIfNull(output, "output");
CheckDisposed();
SftpDownloadAsyncResult asyncResult = new SftpDownloadAsyncResult(asyncCallback, state);
object obj;
((<>c__DisplayClass50_0)obj).<BeginDownloadFile>g__DoDownloadAndSetResult|0();
return asyncResult;
}
public void EndDownloadFile(IAsyncResult asyncResult)
{
SftpDownloadAsyncResult sftpDownloadAsyncResult = asyncResult as SftpDownloadAsyncResult;
if (sftpDownloadAsyncResult == null || sftpDownloadAsyncResult.EndInvokeCalled)
throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
sftpDownloadAsyncResult.EndInvoke();
}
public void UploadFile(Stream input, string path, [Nullable(2)] Action<ulong> uploadCallback = null)
{
UploadFile(input, path, true, uploadCallback);
}
public void UploadFile(Stream input, string path, bool canOverride, [Nullable(2)] Action<ulong> uploadCallback = null)
{
ThrowHelper.ThrowIfNull(input, "input");
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
CheckDisposed();
Flags flags = Flags.Write | Flags.Truncate;
flags = ((!canOverride) ? (flags | Flags.CreateNew) : (flags | Flags.CreateNewOrOpen));
InternalUploadFile(input, path, flags, null, uploadCallback, false, CancellationToken.None).GetAwaiter().GetResult();
}
public Task UploadFileAsync(Stream input, string path, CancellationToken cancellationToken = default(CancellationToken))
{
ThrowHelper.ThrowIfNull(input, "input");
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
CheckDisposed();
return InternalUploadFile(input, path, Flags.Write | Flags.CreateNewOrOpen | Flags.Truncate, null, null, true, cancellationToken);
}
public IAsyncResult BeginUploadFile(Stream input, string path)
{
return BeginUploadFile(input, path, true, null, null, null);
}
public IAsyncResult BeginUploadFile(Stream input, string path, [Nullable(2)] AsyncCallback asyncCallback)
{
return BeginUploadFile(input, path, true, asyncCallback, null, null);
}
public IAsyncResult BeginUploadFile(Stream input, string path, [Nullable(2)] AsyncCallback asyncCallback, [Nullable(2)] object state, [Nullable(2)] Action<ulong> uploadCallback = null)
{
return BeginUploadFile(input, path, true, asyncCallback, state, uploadCallback);
}
public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, [Nullable(2)] AsyncCallback asyncCallback, [Nullable(2)] object state, [Nullable(2)] Action<ulong> uploadCallback = null)
{
ThrowHelper.ThrowIfNull(input, "input");
ThrowHelper.ThrowIfNullOrWhiteSpace(path, "path");
CheckDisposed();
Flags flags = Flags.Write | Flags.Truncate;
if (canOverride)
flags |= Flags.CreateNewOrOpen;
else
flags |= Flags.CreateNew;
SftpUploadAsyncResult asyncResult = new SftpUploadAsyncResult(asyncCallback, state);
<>c__DisplayClass58_0 <>c__DisplayClass58_;
<>c__DisplayClass58_.<BeginUploadFile>g__DoUploadAndSetResult|0();
return asyncResult;
}
public void EndUploadFile(IAsyncResult asyncResult)
{
SftpUploadAsyncResult sftpUploadAsyncResult = asyncResult as SftpUploadAsyncResult;
if (sftpUploadAsyncResult == null || sftpUploadAsyncResult.EndInvokeCalled)
throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
sftpUploadAsyncResult.EndInvoke();
}
public SftpFileSystemInformation GetStatus(string path)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
return _sftpSession.RequestStatVfs(canonicalPath);
}
[AsyncStateMachine(typeof(<GetStatusAsync>d__61))]
public Task<SftpFileSystemInformation> GetStatusAsync(string path, CancellationToken cancellationToken)
{
<GetStatusAsync>d__61 stateMachine = default(<GetStatusAsync>d__61);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<SftpFileSystemInformation>.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void AppendAllLines(string path, IEnumerable<string> contents)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(contents, "contents");
using (StreamWriter streamWriter = AppendText(path)) {
foreach (string content in contents) {
streamWriter.WriteLine(content);
}
}
}
public void AppendAllLines(string path, IEnumerable<string> contents, Encoding encoding)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(contents, "contents");
using (StreamWriter streamWriter = AppendText(path, encoding)) {
foreach (string content in contents) {
streamWriter.WriteLine(content);
}
}
}
public void AppendAllText(string path, string contents)
{
using (StreamWriter streamWriter = AppendText(path))
streamWriter.Write(contents);
}
public void AppendAllText(string path, string contents, Encoding encoding)
{
using (StreamWriter streamWriter = AppendText(path, encoding))
streamWriter.Write(contents);
}
public StreamWriter AppendText(string path)
{
return AppendText(path, Utf8NoBOM);
}
public StreamWriter AppendText(string path, Encoding encoding)
{
CheckDisposed();
ThrowHelper.ThrowIfNull(encoding, "encoding");
return new StreamWriter(Open(path, FileMode.Append, FileAccess.Write), encoding);
}
public SftpFileStream Create(string path)
{
return Create(path, (int)_bufferSize);
}
public SftpFileStream Create(string path, int bufferSize)
{
CheckDisposed();
return SftpFileStream.Open(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize, false);
}
public StreamWriter CreateText(string path)
{
return CreateText(path, Utf8NoBOM);
}
public StreamWriter CreateText(string path, Encoding encoding)
{
CheckDisposed();
return new StreamWriter(Open(path, FileMode.Create, FileAccess.Write), encoding);
}
public void Delete(string path)
{
Get(path).Delete();
}
[AsyncStateMachine(typeof(<DeleteAsync>d__73))]
public Task DeleteAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
{
<DeleteAsync>d__73 stateMachine = default(<DeleteAsync>d__73);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public DateTime GetLastAccessTime(string path)
{
return Get(path).LastAccessTime;
}
public DateTime GetLastAccessTimeUtc(string path)
{
return GetLastAccessTime(path).ToUniversalTime();
}
public DateTime GetLastWriteTime(string path)
{
return Get(path).LastWriteTime;
}
public DateTime GetLastWriteTimeUtc(string path)
{
return GetLastWriteTime(path).ToUniversalTime();
}
public SftpFileStream Open(string path, FileMode mode)
{
return Open(path, mode, FileAccess.ReadWrite);
}
public SftpFileStream Open(string path, FileMode mode, FileAccess access)
{
CheckDisposed();
return SftpFileStream.Open(_sftpSession, path, mode, access, (int)_bufferSize, false);
}
public Task<SftpFileStream> OpenAsync(string path, FileMode mode, FileAccess access, CancellationToken cancellationToken)
{
CheckDisposed();
return SftpFileStream.OpenAsync(_sftpSession, path, mode, access, (int)_bufferSize, cancellationToken, false);
}
public SftpFileStream OpenRead(string path)
{
return Open(path, FileMode.Open, FileAccess.Read);
}
public StreamReader OpenText(string path)
{
return new StreamReader(OpenRead(path), Encoding.UTF8);
}
public SftpFileStream OpenWrite(string path)
{
return Open(path, FileMode.OpenOrCreate, FileAccess.Write);
}
public byte[] ReadAllBytes(string path)
{
using (SftpFileStream sftpFileStream = OpenRead(path)) {
byte[] array;
if (sftpFileStream.CanSeek) {
array = new byte[sftpFileStream.Length];
sftpFileStream.ReadExactly(array, 0, array.Length);
} else {
MemoryStream memoryStream = new MemoryStream();
sftpFileStream.CopyTo(memoryStream);
array = memoryStream.ToArray();
}
return array;
}
}
public string[] ReadAllLines(string path)
{
return ReadAllLines(path, Encoding.UTF8);
}
public string[] ReadAllLines(string path, Encoding encoding)
{
return ReadLines(path, encoding).ToArray();
}
public string ReadAllText(string path)
{
return ReadAllText(path, Encoding.UTF8);
}
public string ReadAllText(string path, Encoding encoding)
{
using (StreamReader streamReader = new StreamReader(OpenRead(path), encoding))
return streamReader.ReadToEnd();
}
public IEnumerable<string> ReadLines(string path)
{
return ReadLines(path, Encoding.UTF8);
}
public IEnumerable<string> ReadLines(string path, Encoding encoding)
{
ThrowHelper.ThrowIfNull(path, "path");
object obj;
return ((<>c__DisplayClass90_0)obj).<ReadLines>g__Enumerate|0();
}
public void SetLastAccessTime(string path, DateTime lastAccessTime)
{
SftpFileAttributes attributes = GetAttributes(path);
attributes.LastAccessTime = lastAccessTime;
SetAttributes(path, attributes);
}
public void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc)
{
SftpFileAttributes attributes = GetAttributes(path);
attributes.LastAccessTimeUtc = lastAccessTimeUtc;
SetAttributes(path, attributes);
}
public void SetLastWriteTime(string path, DateTime lastWriteTime)
{
SftpFileAttributes attributes = GetAttributes(path);
attributes.LastWriteTime = lastWriteTime;
SetAttributes(path, attributes);
}
public void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc)
{
SftpFileAttributes attributes = GetAttributes(path);
attributes.LastWriteTimeUtc = lastWriteTimeUtc;
SetAttributes(path, attributes);
}
public void WriteAllBytes(string path, byte[] bytes)
{
ThrowHelper.ThrowIfNull(bytes, "bytes");
UploadFile(new MemoryStream(bytes), path, null);
}
public void WriteAllLines(string path, IEnumerable<string> contents)
{
WriteAllLines(path, contents, Utf8NoBOM);
}
public void WriteAllLines(string path, string[] contents)
{
WriteAllLines(path, contents, Utf8NoBOM);
}
public void WriteAllLines(string path, IEnumerable<string> contents, Encoding encoding)
{
using (StreamWriter streamWriter = CreateText(path, encoding)) {
foreach (string content in contents) {
streamWriter.WriteLine(content);
}
}
}
public void WriteAllLines(string path, string[] contents, Encoding encoding)
{
WriteAllLines(path, (IEnumerable<string>)contents, encoding);
}
public void WriteAllText(string path, string contents)
{
using (StreamWriter streamWriter = CreateText(path))
streamWriter.Write(contents);
}
public void WriteAllText(string path, string contents, Encoding encoding)
{
using (StreamWriter streamWriter = CreateText(path, encoding))
streamWriter.Write(contents);
}
public SftpFileAttributes GetAttributes(string path)
{
CheckDisposed();
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
return _sftpSession.RequestLStat(canonicalPath);
}
[AsyncStateMachine(typeof(<GetAttributesAsync>d__103))]
public Task<SftpFileAttributes> GetAttributesAsync(string path, CancellationToken cancellationToken)
{
<GetAttributesAsync>d__103 stateMachine = default(<GetAttributesAsync>d__103);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<SftpFileAttributes>.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public void SetAttributes(string path, SftpFileAttributes fileAttributes)
{
CheckDisposed();
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestSetStat(canonicalPath, fileAttributes);
}
public IEnumerable<FileInfo> SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern)
{
ThrowHelper.ThrowIfNull(sourcePath, "sourcePath");
ThrowHelper.ThrowIfNullOrWhiteSpace(destinationPath, "destinationPath");
return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, null);
}
public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, [Nullable(2)] AsyncCallback asyncCallback, [Nullable(2)] object state)
{
ThrowHelper.ThrowIfNull(sourcePath, "sourcePath");
ThrowHelper.ThrowIfNullOrWhiteSpace(destinationPath, "destinationPath");
ThrowHelper.ThrowIfNull(searchPattern, "searchPattern");
SftpSynchronizeDirectoriesAsyncResult asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state);
ThreadAbstraction.ExecuteThread(delegate {
try {
List<FileInfo> result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult);
asyncResult.SetAsCompleted(result, false);
} catch (Exception exception) {
asyncResult.SetAsCompleted(exception, false);
}
});
return asyncResult;
}
public IEnumerable<FileInfo> EndSynchronizeDirectories(IAsyncResult asyncResult)
{
SftpSynchronizeDirectoriesAsyncResult sftpSynchronizeDirectoriesAsyncResult = asyncResult as SftpSynchronizeDirectoriesAsyncResult;
if (sftpSynchronizeDirectoriesAsyncResult == null || sftpSynchronizeDirectoriesAsyncResult.EndInvokeCalled)
throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
return sftpSynchronizeDirectoriesAsyncResult.EndInvoke();
}
private List<FileInfo> InternalSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, [Nullable(2)] SftpSynchronizeDirectoriesAsyncResult asyncResult)
{
if (!Directory.Exists(sourcePath))
throw new FileNotFoundException($"""{sourcePath}");
List<FileInfo> list = new List<FileInfo>();
using (IEnumerator<FileInfo> enumerator = new DirectoryInfo(sourcePath).EnumerateFiles(searchPattern).GetEnumerator()) {
if (enumerator.MoveNext()) {
List<ISftpFile> list2 = InternalListDirectory(destinationPath, null, null);
Dictionary<string, ISftpFile> dictionary = new Dictionary<string, ISftpFile>();
foreach (ISftpFile item in list2) {
if (!item.IsDirectory)
dictionary.Add(item.Name, item);
}
do {
FileInfo current2 = enumerator.Current;
if (current2 != null) {
bool flag = true;
if (dictionary.TryGetValue(current2.Name, out ISftpFile value))
flag = (current2.Length != value.Length);
if (flag) {
string text = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", destinationPath, current2.Name);
try {
using (FileStream input = File.OpenRead(current2.FullName))
InternalUploadFile(input, text, Flags.Write | Flags.CreateNewOrOpen | Flags.Truncate, null, null, false, CancellationToken.None).GetAwaiter().GetResult();
list.Add(current2);
asyncResult?.Update(list.Count);
} catch (Exception innerException) {
throw new SshException("Failed to upload " + current2.FullName + " to " + text, innerException);
}
}
}
} while (enumerator.MoveNext());
return list;
}
return list;
}
}
private List<ISftpFile> InternalListDirectory(string path, [Nullable(2)] SftpListDirectoryAsyncResult asyncResult, [Nullable(2)] Action<int> listCallback)
{
ThrowHelper.ThrowIfNull(path, "path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
byte[] handle = _sftpSession.RequestOpenDir(canonicalPath);
string text = canonicalPath;
if (!text.EndsWith('/'))
text = $"{canonicalPath}""";
List<ISftpFile> result = new List<ISftpFile>();
for (KeyValuePair<string, SftpFileAttributes>[] array = _sftpSession.RequestReadDir(handle); array != null; array = _sftpSession.RequestReadDir(handle)) {
KeyValuePair<string, SftpFileAttributes>[] array2 = array;
for (int i = 0; i < array2.Length; i++) {
KeyValuePair<string, SftpFileAttributes> keyValuePair = array2[i];
result.Add(new SftpFile(_sftpSession, string.Format(CultureInfo.InvariantCulture, "{0}{1}", text, keyValuePair.Key), keyValuePair.Value));
}
asyncResult?.Update(result.Count);
if (listCallback != null)
ThreadAbstraction.ExecuteThread(delegate {
listCallback(result.Count);
});
}
_sftpSession.RequestClose(handle);
return result;
}
[AsyncStateMachine(typeof(<InternalDownloadFile>d__110))]
private Task InternalDownloadFile(string path, Stream output, [Nullable(2)] SftpDownloadAsyncResult asyncResult, [Nullable(2)] Action<ulong> downloadCallback, bool isAsync, CancellationToken cancellationToken)
{
<InternalDownloadFile>d__110 stateMachine = default(<InternalDownloadFile>d__110);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.path = path;
stateMachine.output = output;
stateMachine.asyncResult = asyncResult;
stateMachine.downloadCallback = downloadCallback;
stateMachine.isAsync = isAsync;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<InternalUploadFile>d__111))]
private Task InternalUploadFile(Stream input, string path, Flags flags, [Nullable(2)] SftpUploadAsyncResult asyncResult, [Nullable(2)] Action<ulong> uploadCallback, bool isAsync, CancellationToken cancellationToken)
{
<InternalUploadFile>d__111 stateMachine = default(<InternalUploadFile>d__111);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.input = input;
stateMachine.path = path;
stateMachine.flags = flags;
stateMachine.asyncResult = asyncResult;
stateMachine.uploadCallback = uploadCallback;
stateMachine.isAsync = isAsync;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
protected override void OnConnected()
{
base.OnConnected();
_sftpSession?.Dispose();
_sftpSession = CreateAndConnectToSftpSession();
}
protected override void OnDisconnecting()
{
base.OnDisconnecting();
ISftpSession sftpSession = _sftpSession;
if (sftpSession != null) {
_sftpSession = null;
sftpSession.Dispose();
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing) {
ISftpSession sftpSession = _sftpSession;
if (sftpSession != null) {
_sftpSession = null;
sftpSession.Dispose();
}
}
}
private ISftpSession CreateAndConnectToSftpSession()
{
ISftpSession sftpSession = base.ServiceFactory.CreateSftpSession(base.Session, _operationTimeout, base.ConnectionInfo.Encoding, base.ServiceFactory.CreateSftpResponseFactory());
try {
sftpSession.Connect();
return sftpSession;
} catch {
sftpSession.Dispose();
throw;
}
}
}
}