diff --git a/Directory.Packages.props b/Directory.Packages.props index d455a8a3b..d40252fbd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -23,5 +23,6 @@ + diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 9b7af1590..f28d7b3db 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -47,6 +47,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 947139f84..b834c6bde 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -23,7 +23,7 @@ namespace Renci.SshNet /// /// Implementation of the SSH File Transfer Protocol (SFTP) over SSH. /// - public class SftpClient : BaseClient, ISftpClient + public partial class SftpClient : BaseClient, ISftpClient { private static readonly Encoding Utf8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); @@ -284,41 +284,8 @@ internal SftpClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, ISer #endregion Constructors - /// - /// Changes remote directory to path. - /// - /// New directory path. - /// is . - /// Client is not connected. - /// Permission to change directory denied by remote host. -or- A SSH command was denied by the server. - /// was not found on the remote host. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. - public void ChangeDirectory(string path) - { - CheckDisposed(); - ArgumentNullException.ThrowIfNull(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - _sftpSession.ChangeDirectory(path); - } - - /// - /// Asynchronously requests to change the current working directory to the specified path. - /// - /// The new working directory. - /// The token to monitor for cancellation requests. - /// A that tracks the asynchronous change working directory request. - /// is . - /// Client is not connected. - /// Permission to change directory denied by remote host. -or- A SSH command was denied by the server. - /// was not found on the remote host. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public Task ChangeDirectoryAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); @@ -351,41 +318,8 @@ public void ChangePermissions(string path, short mode) file.SetPermissions(mode); } - /// - /// Creates remote directory specified by path. - /// - /// Directory path to create. - /// is or contains only whitespace characters. - /// Client is not connected. - /// Permission to create the directory was denied by the remote host. -or- A SSH command was denied by the server. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. - public void CreateDirectory(string path) - { - CheckDisposed(); - ArgumentException.ThrowIfNullOrWhiteSpace(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - _sftpSession.RequestMkDir(fullPath); - } - - /// - /// Asynchronously requests to create a remote directory specified by path. - /// - /// Directory path to create. - /// The to observe. - /// A that represents the asynchronous create directory operation. - /// is or contains only whitespace characters. - /// Client is not connected. - /// Permission to create the directory was denied by the remote host. -or- A SSH command was denied by the server. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task CreateDirectoryAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); @@ -401,32 +335,8 @@ public async Task CreateDirectoryAsync(string path, CancellationToken cancellati await _sftpSession.RequestMkDirAsync(fullPath, cancellationToken).ConfigureAwait(false); } - /// - /// Deletes remote directory specified by path. - /// - /// Directory to be deleted path. - /// is or contains only whitespace characters. - /// Client is not connected. - /// was not found on the remote host. - /// Permission to delete the directory was denied by the remote host. -or- A SSH command was denied by the server. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. - public void DeleteDirectory(string path) - { - CheckDisposed(); - ArgumentException.ThrowIfNullOrWhiteSpace(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - _sftpSession.RequestRmDir(fullPath); - } - /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task DeleteDirectoryAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); @@ -444,32 +354,8 @@ public async Task DeleteDirectoryAsync(string path, CancellationToken cancellati await _sftpSession.RequestRmDirAsync(fullPath, cancellationToken).ConfigureAwait(false); } - /// - /// Deletes remote file specified by path. - /// - /// File to be deleted path. - /// is or contains only whitespace characters. - /// Client is not connected. - /// was not found on the remote host. - /// Permission to delete the file was denied by the remote host. -or- A SSH command was denied by the server. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. - public void DeleteFile(string path) - { - CheckDisposed(); - ArgumentException.ThrowIfNullOrWhiteSpace(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - _sftpSession.RequestRemove(fullPath); - } - /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task DeleteFileAsync(string path, CancellationToken cancellationToken) { CheckDisposed(); @@ -725,47 +611,8 @@ public IEnumerable EndListDirectory(IAsyncResult asyncResult) return ar.EndInvoke(); } - /// - /// Gets reference to remote file or directory. - /// - /// The path. - /// - /// A reference to file object. - /// - /// Client is not connected. - /// was not found on the remote host. - /// is . - /// The method was called after the client was disposed. - public ISftpFile Get(string path) - { - CheckDisposed(); - ArgumentNullException.ThrowIfNull(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - var attributes = _sftpSession.RequestLStat(fullPath); - - return new SftpFile(_sftpSession, fullPath, attributes); - } - - /// - /// Gets reference to remote file or directory. - /// - /// The path. - /// The to observe. - /// - /// A that represents the get operation. - /// The task result contains the reference to file object. - /// - /// Client is not connected. - /// was not found on the remote host. - /// is . - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task GetAsync(string path, CancellationToken cancellationToken) { CheckDisposed(); @@ -785,74 +632,8 @@ public async Task GetAsync(string path, CancellationToken cancellatio return new SftpFile(_sftpSession, fullPath, attributes); } - /// - /// Checks whether file or directory exists. - /// - /// The path. - /// - /// if directory or file exists; otherwise . - /// - /// is or contains only whitespace characters. - /// Client is not connected. - /// Permission to perform the operation was denied by the remote host. -or- A SSH command was denied by the server. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. - public bool Exists(string path) - { - CheckDisposed(); - ArgumentException.ThrowIfNullOrWhiteSpace(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - /* - * Using SSH_FXP_REALPATH is not an alternative as the SFTP specification has not always - * been clear on how the server should respond when the specified path is not present on - * the server: - * - * SSH 1 to 4: - * No mention of how the server should respond if the path is not present on the server. - * - * SSH 5: - * The server SHOULD fail the request if the path is not present on the server. - * - * SSH 6: - * Draft 06: The server SHOULD fail the request if the path is not present on the server. - * Draft 07 to 13: The server MUST NOT fail the request if the path does not exist. - * - * Note that SSH 6 (draft 06 and forward) allows for more control options, but we - * currently only support up to v3. - */ - - try - { - _ = _sftpSession.RequestLStat(fullPath); - return true; - } - catch (SftpPathNotFoundException) - { - return false; - } - } - - /// - /// Checks whether file or directory exists. - /// - /// The path. - /// The to observe. - /// - /// A that represents the exists operation. - /// The task result contains if directory or file exists; otherwise . - /// - /// is or contains only whitespace characters. - /// Client is not connected. - /// Permission to perform the operation was denied by the remote host. -or- A SSH command was denied by the server. - /// A SSH error where is the message from the remote host. - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task ExistsAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); @@ -1335,43 +1116,8 @@ public void EndUploadFile(IAsyncResult asyncResult) ar.EndInvoke(); } - /// - /// Gets status using statvfs@openssh.com request. - /// - /// The path. - /// - /// A instance that contains file status information. - /// - /// Client is not connected. - /// is . - /// The method was called after the client was disposed. - public SftpFileSystemInformation GetStatus(string path) - { - CheckDisposed(); - ArgumentNullException.ThrowIfNull(path); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - return _sftpSession.RequestStatVfs(fullPath); - } - - /// - /// Asynchronously gets status using statvfs@openssh.com request. - /// - /// The path. - /// The to observe. - /// - /// A that represents the status operation. - /// The task result contains the instance that contains file status information. - /// - /// Client is not connected. - /// is . - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task GetStatusAsync(string path, CancellationToken cancellationToken) { CheckDisposed(); @@ -1572,21 +1318,8 @@ public StreamWriter CreateText(string path, Encoding encoding) return new StreamWriter(Open(path, FileMode.Create, FileAccess.Write), encoding); } - /// - /// Deletes the specified file or directory. - /// - /// The name of the file or directory to be deleted. Wildcard characters are not supported. - /// is . - /// Client is not connected. - /// was not found on the remote host. - /// The method was called after the client was disposed. - public void Delete(string path) - { - var file = Get(path); - file.Delete(); - } - /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task DeleteAsync(string path, CancellationToken cancellationToken = default) { var file = await GetAsync(path, cancellationToken).ConfigureAwait(false); @@ -1677,39 +1410,8 @@ public SftpFileStream Open(string path, FileMode mode) return Open(path, mode, FileAccess.ReadWrite); } - /// - /// Opens a on the specified path, with the specified mode and access. - /// - /// The file to open. - /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. - /// A value that specifies the operations that can be performed on the file. - /// - /// An unshared that provides access to the specified file, with the specified mode and access. - /// - /// is . - /// Client is not connected. - /// The method was called after the client was disposed. - public SftpFileStream Open(string path, FileMode mode, FileAccess access) - { - CheckDisposed(); - - return SftpFileStream.Open(_sftpSession, path, mode, access, (int)_bufferSize); - } - - /// - /// Asynchronously opens a on the specified path, with the specified mode and access. - /// - /// The file to open. - /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. - /// A value that specifies the operations that can be performed on the file. - /// The to observe. - /// - /// A that represents the asynchronous open operation. - /// The task result contains the that provides access to the specified file, with the specified mode and access. - /// - /// is . - /// Client is not connected. - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public Task OpenAsync(string path, FileMode mode, FileAccess access, CancellationToken cancellationToken) { CheckDisposed(); @@ -2023,44 +1725,8 @@ public void WriteAllText(string path, string contents, Encoding encoding) } } - /// - /// Gets the of the file on the path. - /// - /// The path to the file. - /// - /// The of the file on the path. - /// - /// is . - /// Client is not connected. - /// was not found on the remote host. - /// The method was called after the client was disposed. - public SftpFileAttributes GetAttributes(string path) - { - CheckDisposed(); - - if (_sftpSession is null) - { - throw new SshConnectionException("Client not connected."); - } - - var fullPath = _sftpSession.GetCanonicalPath(path); - - return _sftpSession.RequestLStat(fullPath); - } - - /// - /// Gets the of the file on the path. - /// - /// The path to the file. - /// The to observe. - /// - /// A that represents the attribute retrieval operation. - /// The task result contains the of the file on the path. - /// - /// is . - /// Client is not connected. - /// was not found on the remote host. - /// The method was called after the client was disposed. + /// + [Zomp.SyncMethodGenerator.CreateSyncVersion] public async Task GetAttributesAsync(string path, CancellationToken cancellationToken) { CheckDisposed();