FileTransferResult

This commit is contained in:
veeso 2021-09-10 20:58:26 +02:00
parent 1f115dea92
commit f69489fc8f
6 changed files with 108 additions and 99 deletions

View file

@ -62,15 +62,6 @@ pub struct FileTransferError {
msg: Option<String>,
}
impl FileTransferError {
/// ### kind
///
/// Returns the error kind
pub fn kind(&self) -> FileTransferErrorType {
self.code
}
}
/// ## FileTransferErrorType
///
/// FileTransferErrorType defines the possible errors available for a file transfer
@ -118,6 +109,13 @@ impl FileTransferError {
err.msg = Some(msg);
err
}
/// ### kind
///
/// Returns the error kind
pub fn kind(&self) -> FileTransferErrorType {
self.code
}
}
impl std::fmt::Display for FileTransferError {
@ -129,6 +127,11 @@ impl std::fmt::Display for FileTransferError {
}
}
/// ## FileTransferResult
///
/// Result type returned by a `FileTransfer` implementation
pub type FileTransferResult<T> = Result<T, FileTransferError>;
/// ## FileTransfer
///
/// File transfer trait must be implemented by all the file transfers and defines the method used by a generic file transfer
@ -137,12 +140,12 @@ pub trait FileTransfer {
///
/// Connect to the remote server
/// Can return banner / welcome message on success
fn connect(&mut self, params: &ProtocolParams) -> Result<Option<String>, FileTransferError>;
fn connect(&mut self, params: &ProtocolParams) -> FileTransferResult<Option<String>>;
/// ### disconnect
///
/// Disconnect from the remote server
fn disconnect(&mut self) -> Result<(), FileTransferError>;
fn disconnect(&mut self) -> FileTransferResult<()>;
/// ### is_connected
///
@ -153,50 +156,50 @@ pub trait FileTransfer {
///
/// Print working directory
fn pwd(&mut self) -> Result<PathBuf, FileTransferError>;
fn pwd(&mut self) -> FileTransferResult<PathBuf>;
/// ### change_dir
///
/// Change working directory
fn change_dir(&mut self, dir: &Path) -> Result<PathBuf, FileTransferError>;
fn change_dir(&mut self, dir: &Path) -> FileTransferResult<PathBuf>;
/// ### copy
///
/// Copy file to destination
fn copy(&mut self, src: &FsEntry, dst: &Path) -> Result<(), FileTransferError>;
fn copy(&mut self, src: &FsEntry, dst: &Path) -> FileTransferResult<()>;
/// ### list_dir
///
/// List directory entries
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError>;
fn list_dir(&mut self, path: &Path) -> FileTransferResult<Vec<FsEntry>>;
/// ### mkdir
///
/// Make directory
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError>;
fn mkdir(&mut self, dir: &Path) -> FileTransferResult<()>;
/// ### remove
///
/// Remove a file or a directory
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError>;
fn remove(&mut self, file: &FsEntry) -> FileTransferResult<()>;
/// ### rename
///
/// Rename file or a directory
fn rename(&mut self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError>;
fn rename(&mut self, file: &FsEntry, dst: &Path) -> FileTransferResult<()>;
/// ### stat
///
/// Stat file and return FsEntry
fn stat(&mut self, path: &Path) -> Result<FsEntry, FileTransferError>;
fn stat(&mut self, path: &Path) -> FileTransferResult<FsEntry>;
/// ### exec
///
/// Execute a command on remote host
fn exec(&mut self, cmd: &str) -> Result<String, FileTransferError>;
fn exec(&mut self, cmd: &str) -> FileTransferResult<String>;
/// ### send_file
///
@ -209,7 +212,7 @@ pub trait FileTransfer {
&mut self,
_local: &FsFile,
_file_name: &Path,
) -> Result<Box<dyn Write>, FileTransferError> {
) -> FileTransferResult<Box<dyn Write>> {
Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
))
@ -220,7 +223,7 @@ pub trait FileTransfer {
/// Receive file from remote with provided name
/// Returns file and its size
/// By default returns unsupported feature
fn recv_file(&mut self, _file: &FsFile) -> Result<Box<dyn Read>, FileTransferError> {
fn recv_file(&mut self, _file: &FsFile) -> FileTransferResult<Box<dyn Read>> {
Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
))
@ -234,7 +237,7 @@ pub trait FileTransfer {
/// This is necessary for some protocols such as FTP.
/// You must call this method each time you want to finalize the write of the remote file.
/// By default this function returns already `Ok(())`
fn on_sent(&mut self, _writable: Box<dyn Write>) -> Result<(), FileTransferError> {
fn on_sent(&mut self, _writable: Box<dyn Write>) -> FileTransferResult<()> {
Ok(())
}
@ -246,7 +249,7 @@ pub trait FileTransfer {
/// This mighe be necessary for some protocols.
/// You must call this method each time you want to finalize the read of the remote file.
/// By default this function returns already `Ok(())`
fn on_recv(&mut self, _readable: Box<dyn Read>) -> Result<(), FileTransferError> {
fn on_recv(&mut self, _readable: Box<dyn Read>) -> FileTransferResult<()> {
Ok(())
}
@ -262,7 +265,7 @@ pub trait FileTransfer {
src: &FsFile,
dest: &Path,
mut reader: Box<dyn Read>,
) -> Result<(), FileTransferError> {
) -> FileTransferResult<()> {
match self.is_connected() {
true => {
let mut stream = self.send_file(src, dest)?;
@ -285,7 +288,7 @@ pub trait FileTransfer {
/// If the function returns error kind() `UnsupportedFeature`, then he should call this function.
/// For safety reasons this function doesn't accept the `Write` trait, but the destination path.
/// By default this function uses the streams function to copy content from reader to writer
fn recv_file_wno_stream(&mut self, src: &FsFile, dest: &Path) -> Result<(), FileTransferError> {
fn recv_file_wno_stream(&mut self, src: &FsFile, dest: &Path) -> FileTransferResult<()> {
match self.is_connected() {
true => {
let mut writer = File::create(dest).map_err(|e| {
@ -315,7 +318,7 @@ pub trait FileTransfer {
///
/// Find files from current directory (in all subdirectories) whose name matches the provided search
/// Search supports wildcards ('?', '*')
fn find(&mut self, search: &str) -> Result<Vec<FsEntry>, FileTransferError> {
fn find(&mut self, search: &str) -> FileTransferResult<Vec<FsEntry>> {
match self.is_connected() {
true => {
// Starting from current directory, iter dir
@ -335,11 +338,7 @@ pub trait FileTransfer {
/// Search recursively in `dir` for file matching the wildcard.
/// NOTE: DON'T RE-IMPLEMENT THIS FUNCTION, unless the file transfer provides a faster way to do so
/// NOTE: don't call this method from outside; consider it as private
fn iter_search(
&mut self,
dir: &Path,
filter: &WildMatch,
) -> Result<Vec<FsEntry>, FileTransferError> {
fn iter_search(&mut self, dir: &Path, filter: &WildMatch) -> FileTransferResult<Vec<FsEntry>> {
let mut drained: Vec<FsEntry> = Vec::new();
// Scan directory
match self.list_dir(dir) {

View file

@ -25,7 +25,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
use super::{
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
};
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
use crate::utils::fmt::shadow_password;
use crate::utils::path;
@ -178,7 +180,7 @@ impl FileTransfer for FtpFileTransfer {
///
/// Connect to the remote server
fn connect(&mut self, params: &ProtocolParams) -> Result<Option<String>, FileTransferError> {
fn connect(&mut self, params: &ProtocolParams) -> FileTransferResult<Option<String>> {
let params = match params.generic_params() {
Some(params) => params,
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
@ -270,7 +272,7 @@ impl FileTransfer for FtpFileTransfer {
///
/// Disconnect from the remote server
fn disconnect(&mut self) -> Result<(), FileTransferError> {
fn disconnect(&mut self) -> FileTransferResult<()> {
info!("Disconnecting from FTP server...");
match &mut self.stream {
Some(stream) => match stream.quit() {
@ -300,7 +302,7 @@ impl FileTransfer for FtpFileTransfer {
///
/// Print working directory
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
info!("PWD");
match &mut self.stream {
Some(stream) => match stream.pwd() {
@ -320,7 +322,7 @@ impl FileTransfer for FtpFileTransfer {
///
/// Change working directory
fn change_dir(&mut self, dir: &Path) -> Result<PathBuf, FileTransferError> {
fn change_dir(&mut self, dir: &Path) -> FileTransferResult<PathBuf> {
let dir: PathBuf = Self::resolve(dir);
info!("Changing directory to {}", dir.display());
match &mut self.stream {
@ -340,7 +342,7 @@ impl FileTransfer for FtpFileTransfer {
/// ### copy
///
/// Copy file to destination
fn copy(&mut self, _src: &FsEntry, _dst: &Path) -> Result<(), FileTransferError> {
fn copy(&mut self, _src: &FsEntry, _dst: &Path) -> FileTransferResult<()> {
// FTP doesn't support file copy
debug!("COPY issues (will fail, since unsupported)");
Err(FileTransferError::new(
@ -352,7 +354,7 @@ impl FileTransfer for FtpFileTransfer {
///
/// List directory entries
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError> {
fn list_dir(&mut self, path: &Path) -> FileTransferResult<Vec<FsEntry>> {
let dir: PathBuf = Self::resolve(path);
info!("LIST dir {}", dir.display());
match &mut self.stream {
@ -376,7 +378,7 @@ impl FileTransfer for FtpFileTransfer {
/// ### mkdir
///
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError> {
fn mkdir(&mut self, dir: &Path) -> FileTransferResult<()> {
let dir: PathBuf = Self::resolve(dir);
info!("MKDIR {}", dir.display());
match &mut self.stream {
@ -406,7 +408,7 @@ impl FileTransfer for FtpFileTransfer {
/// ### remove
///
/// Remove a file or a directory
fn remove(&mut self, fsentry: &FsEntry) -> Result<(), FileTransferError> {
fn remove(&mut self, fsentry: &FsEntry) -> FileTransferResult<()> {
if self.stream.is_none() {
return Err(FileTransferError::new(
FileTransferErrorType::UninitializedSession,
@ -493,7 +495,7 @@ impl FileTransfer for FtpFileTransfer {
/// ### rename
///
/// Rename file or a directory
fn rename(&mut self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
fn rename(&mut self, file: &FsEntry, dst: &Path) -> FileTransferResult<()> {
let dst: PathBuf = Self::resolve(dst);
info!(
"Renaming {} to {}",
@ -525,7 +527,7 @@ impl FileTransfer for FtpFileTransfer {
/// ### stat
///
/// Stat file and return FsEntry
fn stat(&mut self, _path: &Path) -> Result<FsEntry, FileTransferError> {
fn stat(&mut self, _path: &Path) -> FileTransferResult<FsEntry> {
match &mut self.stream {
Some(_) => Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
@ -539,7 +541,7 @@ impl FileTransfer for FtpFileTransfer {
/// ### exec
///
/// Execute a command on remote host
fn exec(&mut self, _cmd: &str) -> Result<String, FileTransferError> {
fn exec(&mut self, _cmd: &str) -> FileTransferResult<String> {
Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
))
@ -555,7 +557,7 @@ impl FileTransfer for FtpFileTransfer {
&mut self,
_local: &FsFile,
file_name: &Path,
) -> Result<Box<dyn Write>, FileTransferError> {
) -> FileTransferResult<Box<dyn Write>> {
let file_name: PathBuf = Self::resolve(file_name);
info!("Sending file {}", file_name.display());
match &mut self.stream {
@ -576,7 +578,7 @@ impl FileTransfer for FtpFileTransfer {
///
/// Receive file from remote with provided name
/// Returns file and its size
fn recv_file(&mut self, file: &FsFile) -> Result<Box<dyn Read>, FileTransferError> {
fn recv_file(&mut self, file: &FsFile) -> FileTransferResult<Box<dyn Read>> {
info!("Receiving file {}", file.abs_path.display());
match &mut self.stream {
Some(stream) => match stream.retr_as_stream(&file.abs_path.as_path().to_string_lossy())
@ -600,7 +602,7 @@ impl FileTransfer for FtpFileTransfer {
/// The purpose of this method is to finalize the connection with the peer when writing data.
/// This is necessary for some protocols such as FTP.
/// You must call this method each time you want to finalize the write of the remote file.
fn on_sent(&mut self, writable: Box<dyn Write>) -> Result<(), FileTransferError> {
fn on_sent(&mut self, writable: Box<dyn Write>) -> FileTransferResult<()> {
info!("Finalizing put stream");
match &mut self.stream {
Some(stream) => match stream.finalize_put_stream(writable) {
@ -623,7 +625,7 @@ impl FileTransfer for FtpFileTransfer {
/// The purpose of this method is to finalize the connection with the peer when reading data.
/// This mighe be necessary for some protocols.
/// You must call this method each time you want to finalize the read of the remote file.
fn on_recv(&mut self, readable: Box<dyn Read>) -> Result<(), FileTransferError> {
fn on_recv(&mut self, readable: Box<dyn Read>) -> FileTransferResult<()> {
info!("Finalizing get");
match &mut self.stream {
Some(stream) => match stream.finalize_retr_stream(readable) {

View file

@ -3,7 +3,9 @@
//! This module exposes all the file transfers supported by termscp
// -- import
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
use super::{
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
};
// -- modules
mod ftp;

View file

@ -29,7 +29,9 @@
mod object;
// Locals
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
use super::{
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
};
use crate::fs::{FsDirectory, FsEntry, FsFile};
use crate::utils::path;
use object::S3Object;
@ -64,7 +66,7 @@ impl S3FileTransfer {
/// ### list_objects
///
/// List objects contained in `p` path
fn list_objects(&self, p: &Path, list_dir: bool) -> Result<Vec<S3Object>, FileTransferError> {
fn list_objects(&self, p: &Path, list_dir: bool) -> FileTransferResult<Vec<S3Object>> {
// Make path relative
let key: String = Self::fmt_path(p, list_dir);
debug!("Query list directory {}; key: {}", p.display(), key);
@ -74,7 +76,7 @@ impl S3FileTransfer {
/// ### stat_object
///
/// Stat an s3 object
fn stat_object(&self, p: &Path) -> Result<S3Object, FileTransferError> {
fn stat_object(&self, p: &Path) -> FileTransferResult<S3Object> {
let key: String = Self::fmt_path(p, false);
debug!("Query stat object {}; key: {}", p.display(), key);
let objects = self.query_objects(key, false)?;
@ -100,7 +102,7 @@ impl S3FileTransfer {
&self,
key: String,
only_direct_children: bool,
) -> Result<Vec<S3Object>, FileTransferError> {
) -> FileTransferResult<Vec<S3Object>> {
let results = self.bucket.as_ref().unwrap().list(key.clone(), None);
match results {
Ok(entries) => {
@ -200,7 +202,7 @@ impl FileTransfer for S3FileTransfer {
///
/// Connect to the remote server
/// Can return banner / welcome message on success
fn connect(&mut self, params: &ProtocolParams) -> Result<Option<String>, FileTransferError> {
fn connect(&mut self, params: &ProtocolParams) -> FileTransferResult<Option<String>> {
// Verify parameters are S3
let params = match params.s3_params() {
Some(params) => params,
@ -242,7 +244,7 @@ impl FileTransfer for S3FileTransfer {
/// ### disconnect
///
/// Disconnect from the remote server
fn disconnect(&mut self) -> Result<(), FileTransferError> {
fn disconnect(&mut self) -> FileTransferResult<()> {
info!("Disconnecting from S3 bucket...");
match self.bucket.take() {
Some(bucket) => {
@ -265,7 +267,7 @@ impl FileTransfer for S3FileTransfer {
/// ### pwd
///
/// Print working directory
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
info!("PWD");
match self.is_connected() {
true => Ok(self.wrkdir.clone()),
@ -278,7 +280,7 @@ impl FileTransfer for S3FileTransfer {
/// ### change_dir
///
/// Change working directory
fn change_dir(&mut self, dir: &Path) -> Result<PathBuf, FileTransferError> {
fn change_dir(&mut self, dir: &Path) -> FileTransferResult<PathBuf> {
match &self.bucket.is_some() {
true => {
// Always allow entering root
@ -315,7 +317,7 @@ impl FileTransfer for S3FileTransfer {
/// ### copy
///
/// Copy file to destination
fn copy(&mut self, _src: &FsEntry, _dst: &Path) -> Result<(), FileTransferError> {
fn copy(&mut self, _src: &FsEntry, _dst: &Path) -> FileTransferResult<()> {
Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
))
@ -324,7 +326,7 @@ impl FileTransfer for S3FileTransfer {
/// ### list_dir
///
/// List directory entries
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError> {
fn list_dir(&mut self, path: &Path) -> FileTransferResult<Vec<FsEntry>> {
match self.is_connected() {
true => self
.list_objects(path, true)
@ -339,7 +341,7 @@ impl FileTransfer for S3FileTransfer {
///
/// Make directory
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError> {
fn mkdir(&mut self, dir: &Path) -> FileTransferResult<()> {
match &self.bucket {
Some(bucket) => {
let dir: String = Self::fmt_path(self.resolve(dir).as_path(), true);
@ -373,7 +375,7 @@ impl FileTransfer for S3FileTransfer {
/// ### remove
///
/// Remove a file or a directory
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError> {
fn remove(&mut self, file: &FsEntry) -> FileTransferResult<()> {
let path = Self::fmt_path(
path::diff_paths(file.get_abs_path(), &Path::new("/"))
.unwrap_or_default()
@ -397,7 +399,7 @@ impl FileTransfer for S3FileTransfer {
/// ### rename
///
/// Rename file or a directory
fn rename(&mut self, _file: &FsEntry, _dst: &Path) -> Result<(), FileTransferError> {
fn rename(&mut self, _file: &FsEntry, _dst: &Path) -> FileTransferResult<()> {
Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
))
@ -406,7 +408,7 @@ impl FileTransfer for S3FileTransfer {
/// ### stat
///
/// Stat file and return FsEntry
fn stat(&mut self, p: &Path) -> Result<FsEntry, FileTransferError> {
fn stat(&mut self, p: &Path) -> FileTransferResult<FsEntry> {
match self.is_connected() {
true => {
// First try as a "file"
@ -428,7 +430,7 @@ impl FileTransfer for S3FileTransfer {
/// ### exec
///
/// Execute a command on remote host
fn exec(&mut self, _cmd: &str) -> Result<String, FileTransferError> {
fn exec(&mut self, _cmd: &str) -> FileTransferResult<String> {
Err(FileTransferError::new(
FileTransferErrorType::UnsupportedFeature,
))
@ -446,7 +448,7 @@ impl FileTransfer for S3FileTransfer {
_src: &FsFile,
dest: &Path,
mut reader: Box<dyn Read>,
) -> Result<(), FileTransferError> {
) -> FileTransferResult<()> {
match &mut self.bucket {
Some(bucket) => {
let key = Self::fmt_path(dest, false);
@ -474,7 +476,7 @@ impl FileTransfer for S3FileTransfer {
/// The developer implementing the filetransfer user should FIRST try with `send_file` followed by `on_sent`
/// If the function returns error kind() `UnsupportedFeature`, then he should call this function.
/// By default this function uses the streams function to copy content from reader to writer
fn recv_file_wno_stream(&mut self, src: &FsFile, dest: &Path) -> Result<(), FileTransferError> {
fn recv_file_wno_stream(&mut self, src: &FsFile, dest: &Path) -> FileTransferResult<()> {
match &mut self.bucket {
Some(bucket) => {
let mut writer = File::create(dest).map_err(|e| {

View file

@ -26,7 +26,9 @@
* SOFTWARE.
*/
// Locals
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
use super::{
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
};
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
use crate::system::sshkey_storage::SshKeyStorage;
use crate::utils::fmt::{fmt_time, shadow_password};
@ -278,7 +280,7 @@ impl ScpFileTransfer {
&mut self,
path: &Path,
cmd: &str,
) -> Result<String, FileTransferError> {
) -> FileTransferResult<String> {
self.perform_shell_cmd(format!("cd \"{}\"; {}", path.display(), cmd).as_str())
}
@ -286,7 +288,7 @@ impl ScpFileTransfer {
///
/// Perform a shell command and read the output from shell
/// This operation is, obviously, blocking.
fn perform_shell_cmd(&mut self, cmd: &str) -> Result<String, FileTransferError> {
fn perform_shell_cmd(&mut self, cmd: &str) -> FileTransferResult<String> {
match self.session.as_mut() {
Some(session) => {
debug!("Running command: {}", cmd);
@ -333,7 +335,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### connect
///
/// Connect to the remote server
fn connect(&mut self, params: &ProtocolParams) -> Result<Option<String>, FileTransferError> {
fn connect(&mut self, params: &ProtocolParams) -> FileTransferResult<Option<String>> {
let params = match params.generic_params() {
Some(params) => params,
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
@ -472,7 +474,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### disconnect
///
/// Disconnect from the remote server
fn disconnect(&mut self) -> Result<(), FileTransferError> {
fn disconnect(&mut self) -> FileTransferResult<()> {
info!("Disconnecting from remote...");
match self.session.as_ref() {
Some(session) => {
@ -506,7 +508,7 @@ impl FileTransfer for ScpFileTransfer {
///
/// Print working directory
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
info!("PWD: {}", self.wrkdir.display());
match self.is_connected() {
true => Ok(self.wrkdir.clone()),
@ -520,7 +522,7 @@ impl FileTransfer for ScpFileTransfer {
///
/// Change working directory
fn change_dir(&mut self, dir: &Path) -> Result<PathBuf, FileTransferError> {
fn change_dir(&mut self, dir: &Path) -> FileTransferResult<PathBuf> {
match self.is_connected() {
true => {
let p: PathBuf = self.wrkdir.clone();
@ -564,7 +566,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### copy
///
/// Copy file to destination
fn copy(&mut self, src: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
fn copy(&mut self, src: &FsEntry, dst: &Path) -> FileTransferResult<()> {
match self.is_connected() {
true => {
let dst: PathBuf = Self::resolve(dst);
@ -612,7 +614,7 @@ impl FileTransfer for ScpFileTransfer {
///
/// List directory entries
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError> {
fn list_dir(&mut self, path: &Path) -> FileTransferResult<Vec<FsEntry>> {
match self.is_connected() {
true => {
// Send ls -l to path
@ -657,7 +659,7 @@ impl FileTransfer for ScpFileTransfer {
///
/// Make directory
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError> {
fn mkdir(&mut self, dir: &Path) -> FileTransferResult<()> {
match self.is_connected() {
true => {
let dir: PathBuf = Self::resolve(dir);
@ -703,7 +705,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### remove
///
/// Remove a file or a directory
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError> {
fn remove(&mut self, file: &FsEntry) -> FileTransferResult<()> {
// Yay, we have rm -rf here :D
match self.is_connected() {
true => {
@ -741,7 +743,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### rename
///
/// Rename file or a directory
fn rename(&mut self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
fn rename(&mut self, file: &FsEntry, dst: &Path) -> FileTransferResult<()> {
match self.is_connected() {
true => {
// Get path
@ -784,7 +786,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### stat
///
/// Stat file and return FsEntry
fn stat(&mut self, path: &Path) -> Result<FsEntry, FileTransferError> {
fn stat(&mut self, path: &Path) -> FileTransferResult<FsEntry> {
let path: PathBuf = Self::absolutize(self.wrkdir.as_path(), path);
match self.is_connected() {
true => {
@ -829,7 +831,7 @@ impl FileTransfer for ScpFileTransfer {
/// ### exec
///
/// Execute a command on remote host
fn exec(&mut self, cmd: &str) -> Result<String, FileTransferError> {
fn exec(&mut self, cmd: &str) -> FileTransferResult<String> {
match self.is_connected() {
true => {
let p: PathBuf = self.wrkdir.clone();
@ -858,7 +860,7 @@ impl FileTransfer for ScpFileTransfer {
&mut self,
local: &FsFile,
file_name: &Path,
) -> Result<Box<dyn Write>, FileTransferError> {
) -> FileTransferResult<Box<dyn Write>> {
match self.session.as_ref() {
Some(session) => {
let file_name: PathBuf = Self::absolutize(self.wrkdir.as_path(), file_name);
@ -925,7 +927,7 @@ impl FileTransfer for ScpFileTransfer {
///
/// Receive file from remote with provided name
/// Returns file and its size
fn recv_file(&mut self, file: &FsFile) -> Result<Box<dyn Read>, FileTransferError> {
fn recv_file(&mut self, file: &FsFile) -> FileTransferResult<Box<dyn Read>> {
match self.session.as_ref() {
Some(session) => {
info!("Receiving file {}", file.abs_path.display());

View file

@ -26,7 +26,9 @@
* SOFTWARE.
*/
// Locals
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
use super::{
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
};
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
use crate::system::sshkey_storage::SshKeyStorage;
use crate::utils::fmt::{fmt_time, shadow_password};
@ -64,7 +66,7 @@ impl SftpFileTransfer {
/// ### get_abs_path
///
/// Get absolute path from path argument and check if it exists
fn get_remote_path(&self, p: &Path) -> Result<PathBuf, FileTransferError> {
fn get_remote_path(&self, p: &Path) -> FileTransferResult<PathBuf> {
match p.is_relative() {
true => {
let mut root: PathBuf = self.wrkdir.clone();
@ -202,7 +204,7 @@ impl SftpFileTransfer {
/// ### perform_shell_cmd_with
///
/// Perform a shell command, but change directory to specified path first
fn perform_shell_cmd_with_path(&mut self, cmd: &str) -> Result<String, FileTransferError> {
fn perform_shell_cmd_with_path(&mut self, cmd: &str) -> FileTransferResult<String> {
self.perform_shell_cmd(format!("cd \"{}\"; {}", self.wrkdir.display(), cmd).as_str())
}
@ -210,7 +212,7 @@ impl SftpFileTransfer {
///
/// Perform a shell command and read the output from shell
/// This operation is, obviously, blocking.
fn perform_shell_cmd(&mut self, cmd: &str) -> Result<String, FileTransferError> {
fn perform_shell_cmd(&mut self, cmd: &str) -> FileTransferResult<String> {
match self.session.as_mut() {
Some(session) => {
// Create channel
@ -257,7 +259,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### connect
///
/// Connect to the remote server
fn connect(&mut self, params: &ProtocolParams) -> Result<Option<String>, FileTransferError> {
fn connect(&mut self, params: &ProtocolParams) -> FileTransferResult<Option<String>> {
let params = match params.generic_params() {
Some(params) => params,
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
@ -413,7 +415,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### disconnect
///
/// Disconnect from the remote server
fn disconnect(&mut self) -> Result<(), FileTransferError> {
fn disconnect(&mut self) -> FileTransferResult<()> {
info!("Disconnecting from remote...");
match self.session.as_ref() {
Some(session) => {
@ -447,7 +449,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### pwd
///
/// Print working directory
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
info!("PWD: {}", self.wrkdir.display());
match self.sftp {
Some(_) => Ok(self.wrkdir.clone()),
@ -460,7 +462,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### change_dir
///
/// Change working directory
fn change_dir(&mut self, dir: &Path) -> Result<PathBuf, FileTransferError> {
fn change_dir(&mut self, dir: &Path) -> FileTransferResult<PathBuf> {
match self.sftp.as_ref() {
Some(_) => {
// Change working directory
@ -477,7 +479,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### copy
///
/// Copy file to destination
fn copy(&mut self, src: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
fn copy(&mut self, src: &FsEntry, dst: &Path) -> FileTransferResult<()> {
// NOTE: use SCP command to perform copy (UNSAFE)
match self.is_connected() {
true => {
@ -523,7 +525,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### list_dir
///
/// List directory entries
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError> {
fn list_dir(&mut self, path: &Path) -> FileTransferResult<Vec<FsEntry>> {
match self.sftp.as_ref() {
Some(sftp) => {
// Get path
@ -556,7 +558,7 @@ impl FileTransfer for SftpFileTransfer {
///
/// Make directory
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError> {
fn mkdir(&mut self, dir: &Path) -> FileTransferResult<()> {
match self.sftp.as_ref() {
Some(sftp) => {
// Make directory
@ -586,7 +588,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### remove
///
/// Remove a file or a directory
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError> {
fn remove(&mut self, file: &FsEntry) -> FileTransferResult<()> {
if self.sftp.is_none() {
return Err(FileTransferError::new(
FileTransferErrorType::UninitializedSession,
@ -630,7 +632,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### rename
///
/// Rename file or a directory
fn rename(&mut self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
fn rename(&mut self, file: &FsEntry, dst: &Path) -> FileTransferResult<()> {
match self.sftp.as_ref() {
None => Err(FileTransferError::new(
FileTransferErrorType::UninitializedSession,
@ -659,7 +661,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### stat
///
/// Stat file and return FsEntry
fn stat(&mut self, path: &Path) -> Result<FsEntry, FileTransferError> {
fn stat(&mut self, path: &Path) -> FileTransferResult<FsEntry> {
match self.sftp.as_ref() {
Some(sftp) => {
// Get path
@ -683,7 +685,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### exec
///
/// Execute a command on remote host
fn exec(&mut self, cmd: &str) -> Result<String, FileTransferError> {
fn exec(&mut self, cmd: &str) -> FileTransferResult<String> {
info!("Executing command {}", cmd);
match self.is_connected() {
true => match self.perform_shell_cmd_with_path(cmd) {
@ -708,7 +710,7 @@ impl FileTransfer for SftpFileTransfer {
&mut self,
local: &FsFile,
file_name: &Path,
) -> Result<Box<dyn Write>, FileTransferError> {
) -> FileTransferResult<Box<dyn Write>> {
match self.sftp.as_ref() {
None => Err(FileTransferError::new(
FileTransferErrorType::UninitializedSession,
@ -749,7 +751,7 @@ impl FileTransfer for SftpFileTransfer {
/// ### recv_file
///
/// Receive file from remote with provided name
fn recv_file(&mut self, file: &FsFile) -> Result<Box<dyn Read>, FileTransferError> {
fn recv_file(&mut self, file: &FsFile) -> FileTransferResult<Box<dyn Read>> {
match self.sftp.as_ref() {
None => Err(FileTransferError::new(
FileTransferErrorType::UninitializedSession,