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    fn realpath(&self, path: &Path) -> RemoteResult<PathBuf>;
101
102    /// Renames a file from `src` to `dest`.
103    fn rename(&self, src: &Path, dest: &Path) -> RemoteResult<()>;
104
105    /// Removes a directory at `path`.
106    fn rmdir(&self, path: &Path) -> RemoteResult<()>;
107
108    /// Set the [`Metadata`] for a file at `path`.
109    fn setstat(&self, path: &Path, metadata: Metadata) -> RemoteResult<()>;
110
111    /// Get the [`File`] metadata for a file.
112    fn stat(&self, filename: &Path) -> RemoteResult<File>;
113
114    /// Creates a symlink at `path` pointing to `target`.
115    fn symlink(&self, path: &Path, target: &Path) -> RemoteResult<()>;
116
117    /// Deletes a file at `path`.
118    fn unlink(&self, path: &Path) -> RemoteResult<()>;
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq)]
122/// Open modes for reading and writing files.
123pub enum WriteMode {
124    Append,
125    Truncate,
126}