Skip to main content

remotefs_ssh/ssh/
backend.rs

1//! Defines the main trait for SSH Backends to be used with the clients and the backend implementations
2//! to support different SSH libraries (e.g. libssh2, libssh)
3
4#[cfg(feature = "libssh")]
5#[cfg_attr(docsrs, doc(cfg(feature = "libssh")))]
6mod libssh;
7
8#[cfg(feature = "libssh2")]
9#[cfg_attr(docsrs, doc(cfg(feature = "libssh2")))]
10mod libssh2;
11#[cfg(feature = "russh")]
12#[cfg_attr(docsrs, doc(cfg(feature = "russh")))]
13mod russh;
14
15use std::io::{Read, Write};
16use std::path::{Path, PathBuf};
17
18use remotefs::fs::{Metadata, ReadStream, WriteStream};
19use remotefs::{File, RemoteResult};
20
21#[cfg(feature = "libssh")]
22#[cfg_attr(docsrs, doc(cfg(feature = "libssh")))]
23pub use self::libssh::LibSshSession;
24#[cfg(feature = "libssh2")]
25#[cfg_attr(docsrs, doc(cfg(feature = "libssh2")))]
26pub use self::libssh2::LibSsh2Session;
27#[cfg(feature = "russh")]
28#[cfg_attr(docsrs, doc(cfg(feature = "russh")))]
29pub use self::russh::{NoCheckServerKey, RusshSession};
30use crate::SshOpts;
31
32/// SSH session trait.
33///
34/// Provides SSH channel functions
35pub trait SshSession: Sized {
36    type Sftp: Sftp;
37
38    /// Connects to the SSH server and establishes a new [`SshSession`]
39    fn connect(opts: &SshOpts) -> RemoteResult<Self>;
40
41    /// Disconnect from the server
42    fn disconnect(&self) -> RemoteResult<()>;
43
44    /// Get the SSH server banner.
45    fn banner(&self) -> RemoteResult<Option<String>>;
46
47    /// Check if the session is authenticated.
48    fn authenticated(&self) -> RemoteResult<bool>;
49
50    /// Executes a command on the SSH server and returns the exit code and the output.
51    fn cmd<S>(&mut self, cmd: S) -> RemoteResult<(u32, String)>
52    where
53        S: AsRef<str>;
54
55    /// Executes a command on the SSH server at a specific path and returns the exit code and the output.
56    fn cmd_at<S>(&mut self, cmd: S, path: &Path) -> RemoteResult<(u32, String)>
57    where
58        S: AsRef<str>,
59    {
60        self.cmd(format!("cd \"{}\"; {}", path.display(), cmd.as_ref()))
61    }
62
63    /// Receives a file over SCP.
64    ///
65    /// Returns a channel can be read from server.
66    fn scp_recv(&self, path: &Path) -> RemoteResult<Box<dyn Read + Send>>;
67
68    /// Send a file over SCP.
69    ///
70    /// Returns a channel which can be written to send data
71    fn scp_send(
72        &self,
73        remote_path: &Path,
74        mode: i32,
75        size: u64,
76        times: Option<(u64, u64)>,
77    ) -> RemoteResult<Box<dyn Write + Send>>;
78
79    /// Returns a SFTP client
80    fn sftp(&self) -> RemoteResult<Self::Sftp>;
81}
82
83/// Sftp provider for a [`SshSession`] implementation via the [`SshSession::sftp`] method.
84pub trait Sftp {
85    /// Creates a new directory at the specified `path` with the given `mode`.
86    fn mkdir(&self, path: &Path, mode: i32) -> RemoteResult<()>;
87
88    /// Opens a file for reading at the specified `path`.
89    fn open_read(&self, path: &Path) -> RemoteResult<ReadStream>;
90
91    /// Open a file for write at the specified `path` with the given `flags`. If the file is created, set the mode.
92    fn open_write(&self, path: &Path, flags: WriteMode, mode: i32) -> RemoteResult<WriteStream>;
93
94    /// Lists the contents of a directory at `dirname` and returns the listed [`File`] for it.
95    fn readdir<T>(&self, dirname: T) -> RemoteResult<Vec<File>>
96    where
97        T: AsRef<Path>;
98
99    /// Resolve the real path for `path`.
100    #[allow(dead_code)]
101    fn realpath(&self, path: &Path) -> RemoteResult<PathBuf>;
102
103    /// Renames a file from `src` to `dest`.
104    fn rename(&self, src: &Path, dest: &Path) -> RemoteResult<()>;
105
106    /// Removes a directory at `path`.
107    fn rmdir(&self, path: &Path) -> RemoteResult<()>;
108
109    /// Set the [`Metadata`] for a file at `path`.
110    fn setstat(&self, path: &Path, metadata: Metadata) -> RemoteResult<()>;
111
112    /// Get the [`File`] metadata for a file.
113    fn stat(&self, filename: &Path) -> RemoteResult<File>;
114
115    /// Creates a symlink at `path` pointing to `target`.
116    fn symlink(&self, path: &Path, target: &Path) -> RemoteResult<()>;
117
118    /// Deletes a file at `path`.
119    fn unlink(&self, path: &Path) -> RemoteResult<()>;
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123/// Open modes for reading and writing files.
124pub enum WriteMode {
125    Append,
126    Truncate,
127}