SftpClient
Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
using Renci.SshNet.Sftp.Responses;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Renci.SshNet
{
public class SftpClient : BaseClient, ISftpClient, IBaseClient, IDisposable
{
private static readonly Encoding Utf8NoBOM = new UTF8Encoding(false, true);
private ISftpSession _sftpSession;
private int _operationTimeout;
private uint _bufferSize;
public TimeSpan OperationTimeout {
get {
CheckDisposed();
return TimeSpan.FromMilliseconds((double)_operationTimeout);
}
set {
CheckDisposed();
double totalMilliseconds = value.TotalMilliseconds;
if ((totalMilliseconds < -1 || totalMilliseconds > 2147483647) ? true : false)
throw new ArgumentOutOfRangeException("value", "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
_operationTimeout = (int)totalMilliseconds;
}
}
public uint BufferSize {
get {
CheckDisposed();
return _bufferSize;
}
set {
CheckDisposed();
_bufferSize = value;
}
}
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;
}
}
internal ISftpSession SftpSession => _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();
if (path == null)
throw new ArgumentNullException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
_sftpSession.ChangeDirectory(path);
}
public void ChangePermissions(string path, short mode)
{
Get(path).SetPermissions(mode);
}
public void CreateDirectory(string path)
{
CheckDisposed();
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException(path);
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestMkDir(canonicalPath);
}
public void DeleteDirectory(string path)
{
CheckDisposed();
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestRmDir(canonicalPath);
}
public void DeleteFile(string path)
{
CheckDisposed();
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
_sftpSession.RequestRemove(canonicalPath);
}
[AsyncStateMachine(typeof(<DeleteFileAsync>d__28))]
public Task DeleteFileAsync(string path, CancellationToken cancellationToken)
{
<DeleteFileAsync>d__28 stateMachine = default(<DeleteFileAsync>d__28);
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();
if (oldPath == null)
throw new ArgumentNullException("oldPath");
if (newPath == null)
throw new ArgumentNullException("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__31))]
public Task RenameFileAsync(string oldPath, string newPath, CancellationToken cancellationToken)
{
<RenameFileAsync>d__31 stateMachine = default(<RenameFileAsync>d__31);
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();
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
if (string.IsNullOrWhiteSpace(linkPath))
throw new ArgumentException("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, Action<int> listCallback = null)
{
CheckDisposed();
return InternalListDirectory(path, null, listCallback);
}
[AsyncIteratorStateMachine(typeof(<ListDirectoryAsync>d__34))]
public IAsyncEnumerable<ISftpFile> ListDirectoryAsync(string path, [EnumeratorCancellation] CancellationToken cancellationToken)
{
<ListDirectoryAsync>d__34 <ListDirectoryAsync>d__ = new <ListDirectoryAsync>d__34(-2);
<ListDirectoryAsync>d__.<>4__this = this;
<ListDirectoryAsync>d__.<>3__path = path;
<ListDirectoryAsync>d__.<>3__cancellationToken = cancellationToken;
return <ListDirectoryAsync>d__;
}
public IAsyncResult BeginListDirectory(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();
if (path == null)
throw new ArgumentNullException("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);
}
public bool Exists(string path)
{
CheckDisposed();
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("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.");
}
public void DownloadFile(string path, Stream output, Action<ulong> downloadCallback = null)
{
CheckDisposed();
InternalDownloadFile(path, output, null, downloadCallback);
}
public IAsyncResult BeginDownloadFile(string path, Stream output)
{
return BeginDownloadFile(path, output, null, null, null);
}
public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback asyncCallback)
{
return BeginDownloadFile(path, output, asyncCallback, null, null);
}
public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback asyncCallback, object state, Action<ulong> downloadCallback = null)
{
CheckDisposed();
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
if (output == null)
throw new ArgumentNullException("output");
SftpDownloadAsyncResult asyncResult = new SftpDownloadAsyncResult(asyncCallback, state);
ThreadAbstraction.ExecuteThread(delegate {
try {
InternalDownloadFile(path, output, asyncResult, downloadCallback);
asyncResult.SetAsCompleted(null, false);
} catch (Exception exception) {
asyncResult.SetAsCompleted(exception, false);
}
});
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, Action<ulong> uploadCallback = null)
{
UploadFile(input, path, true, uploadCallback);
}
public void UploadFile(Stream input, string path, bool canOverride, Action<ulong> uploadCallback = null)
{
CheckDisposed();
Flags flags = Flags.Write | Flags.Truncate;
flags = ((!canOverride) ? (flags | Flags.CreateNew) : (flags | Flags.CreateNewOrOpen));
InternalUploadFile(input, path, flags, null, uploadCallback);
}
public IAsyncResult BeginUploadFile(Stream input, string path)
{
return BeginUploadFile(input, path, true, null, null, null);
}
public IAsyncResult BeginUploadFile(Stream input, string path, AsyncCallback asyncCallback)
{
return BeginUploadFile(input, path, true, asyncCallback, null, null);
}
public IAsyncResult BeginUploadFile(Stream input, string path, AsyncCallback asyncCallback, object state, Action<ulong> uploadCallback = null)
{
return BeginUploadFile(input, path, true, asyncCallback, state, uploadCallback);
}
public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, AsyncCallback asyncCallback, object state, Action<ulong> uploadCallback = null)
{
CheckDisposed();
if (input == null)
throw new ArgumentNullException("input");
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
Flags flags = Flags.Write | Flags.Truncate;
if (canOverride)
flags |= Flags.CreateNewOrOpen;
else
flags |= Flags.CreateNew;
SftpUploadAsyncResult asyncResult = new SftpUploadAsyncResult(asyncCallback, state);
ThreadAbstraction.ExecuteThread(delegate {
try {
InternalUploadFile(input, path, flags, asyncResult, uploadCallback);
asyncResult.SetAsCompleted(null, false);
} catch (Exception exception) {
asyncResult.SetAsCompleted(exception, false);
}
});
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 SftpFileSytemInformation GetStatus(string path)
{
CheckDisposed();
if (path == null)
throw new ArgumentNullException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
return _sftpSession.RequestStatVfs(canonicalPath, false);
}
[AsyncStateMachine(typeof(<GetStatusAsync>d__52))]
public Task<SftpFileSytemInformation> GetStatusAsync(string path, CancellationToken cancellationToken)
{
<GetStatusAsync>d__52 stateMachine = default(<GetStatusAsync>d__52);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<SftpFileSytemInformation>.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();
if (contents == null)
throw new ArgumentNullException("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();
if (contents == null)
throw new ArgumentNullException("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();
if (encoding == null)
throw new ArgumentNullException("encoding");
return new StreamWriter(new SftpFileStream(_sftpSession, path, FileMode.Append, FileAccess.Write, (int)_bufferSize), encoding);
}
public SftpFileStream Create(string path)
{
CheckDisposed();
return new SftpFileStream(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, (int)_bufferSize);
}
public SftpFileStream Create(string path, int bufferSize)
{
CheckDisposed();
return new SftpFileStream(_sftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize);
}
public StreamWriter CreateText(string path)
{
return CreateText(path, Utf8NoBOM);
}
public StreamWriter CreateText(string path, Encoding encoding)
{
CheckDisposed();
return new StreamWriter(OpenWrite(path), encoding);
}
public void Delete(string path)
{
Get(path).Delete();
}
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 new SftpFileStream(_sftpSession, path, mode, access, (int)_bufferSize);
}
public Task<SftpFileStream> OpenAsync(string path, FileMode mode, FileAccess access, CancellationToken cancellationToken)
{
CheckDisposed();
if (path == null)
throw new ArgumentNullException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
cancellationToken.ThrowIfCancellationRequested();
return SftpFileStream.OpenAsync(_sftpSession, path, mode, access, (int)_bufferSize, cancellationToken);
}
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)
{
CheckDisposed();
return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int)_bufferSize);
}
public byte[] ReadAllBytes(string path)
{
using (SftpFileStream sftpFileStream = OpenRead(path)) {
byte[] array = new byte[sftpFileStream.Length];
sftpFileStream.Read(array, 0, array.Length);
return array;
}
}
public string[] ReadAllLines(string path)
{
return ReadAllLines(path, Encoding.UTF8);
}
public string[] ReadAllLines(string path, Encoding encoding)
{
List<string> list = new List<string>();
using (StreamReader streamReader = new StreamReader(OpenRead(path), encoding)) {
while (!streamReader.EndOfStream) {
list.Add(streamReader.ReadLine());
}
}
return list.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 ReadAllLines(path);
}
public IEnumerable<string> ReadLines(string path, Encoding encoding)
{
return ReadAllLines(path, encoding);
}
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)
{
using (SftpFileStream sftpFileStream = OpenWrite(path))
sftpFileStream.Write(bytes, 0, bytes.Length);
}
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)
{
using (StreamWriter streamWriter = CreateText(path, encoding)) {
foreach (string value in contents) {
streamWriter.WriteLine(value);
}
}
}
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);
}
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)
{
if (sourcePath == null)
throw new ArgumentNullException("sourcePath");
if (string.IsNullOrWhiteSpace(destinationPath))
throw new ArgumentException("destinationPath");
return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, null);
}
public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, AsyncCallback asyncCallback, object state)
{
if (sourcePath == null)
throw new ArgumentNullException("sourcePath");
if (string.IsNullOrWhiteSpace(destinationPath))
throw new ArgumentException("destDir");
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, SftpSynchronizeDirectoriesAsyncResult asynchResult)
{
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);
list.Add(current2);
asynchResult?.Update(list.Count);
} catch (Exception inner) {
throw new SshException("Failed to upload " + current2.FullName + " to " + text, inner);
}
}
}
} while (enumerator.MoveNext());
return list;
}
return list;
}
}
private List<ISftpFile> InternalListDirectory(string path, SftpListDirectoryAsyncResult asyncResult, Action<int> listCallback)
{
if (path == null)
throw new ArgumentNullException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
byte[] handle = _sftpSession.RequestOpenDir(canonicalPath, false);
string text = canonicalPath;
if (!text.EndsWith("/", StringComparison.Ordinal))
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;
}
private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncResult asyncResult, Action<ulong> downloadCallback)
{
if (output == null)
throw new ArgumentNullException("output");
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
using (ISftpFileReader sftpFileReader = base.ServiceFactory.CreateSftpFileReader(canonicalPath, _sftpSession, _bufferSize)) {
ulong num = 0;
while (asyncResult == null || !asyncResult.IsDownloadCanceled) {
byte[] array = sftpFileReader.Read();
if (array.Length == 0)
break;
output.Write(array, 0, array.Length);
num = (ulong)((long)num + (long)array.Length);
asyncResult?.Update(num);
if (downloadCallback != null) {
ulong downloadOffset = num;
ThreadAbstraction.ExecuteThread(delegate {
downloadCallback(downloadOffset);
});
}
}
}
}
private void InternalUploadFile(Stream input, string path, Flags flags, SftpUploadAsyncResult asyncResult, Action<ulong> uploadCallback)
{
if (input == null)
throw new ArgumentNullException("input");
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
string canonicalPath = _sftpSession.GetCanonicalPath(path);
byte[] handle = _sftpSession.RequestOpen(canonicalPath, flags, false);
ulong num = 0;
byte[] array = new byte[_sftpSession.CalculateOptimalWriteLength(_bufferSize, handle)];
int num2 = input.Read(array, 0, array.Length);
int expectedResponses = 0;
AutoResetEvent responseReceivedWaitHandle = new AutoResetEvent(false);
while (asyncResult == null || !asyncResult.IsUploadCanceled) {
if (num2 > 0) {
ulong writtenBytes = (ulong)((long)num + (long)num2);
_sftpSession.RequestWrite(handle, num, array, 0, num2, null, delegate(SftpStatusResponse s) {
if (s.StatusCode == StatusCodes.Ok) {
Interlocked.Decrement(ref expectedResponses);
responseReceivedWaitHandle.Set();
asyncResult?.Update(writtenBytes);
if (uploadCallback != null)
ThreadAbstraction.ExecuteThread(delegate {
uploadCallback(writtenBytes);
});
}
});
Interlocked.Increment(ref expectedResponses);
num = (ulong)((long)num + (long)num2);
num2 = input.Read(array, 0, array.Length);
} else if (expectedResponses > 0) {
_sftpSession.WaitOnHandle(responseReceivedWaitHandle, _operationTimeout);
}
if (expectedResponses <= 0 && num2 <= 0)
break;
}
_sftpSession.RequestClose(handle);
responseReceivedWaitHandle.Dispose();
}
protected override void OnConnected()
{
base.OnConnected();
_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;
}
}
}
}