mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
FileTransferResult
This commit is contained in:
@@ -62,15 +62,6 @@ pub struct FileTransferError {
|
|||||||
msg: Option<String>,
|
msg: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileTransferError {
|
|
||||||
/// ### kind
|
|
||||||
///
|
|
||||||
/// Returns the error kind
|
|
||||||
pub fn kind(&self) -> FileTransferErrorType {
|
|
||||||
self.code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ## FileTransferErrorType
|
/// ## FileTransferErrorType
|
||||||
///
|
///
|
||||||
/// FileTransferErrorType defines the possible errors available for a file transfer
|
/// FileTransferErrorType defines the possible errors available for a file transfer
|
||||||
@@ -118,6 +109,13 @@ impl FileTransferError {
|
|||||||
err.msg = Some(msg);
|
err.msg = Some(msg);
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### kind
|
||||||
|
///
|
||||||
|
/// Returns the error kind
|
||||||
|
pub fn kind(&self) -> FileTransferErrorType {
|
||||||
|
self.code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for FileTransferError {
|
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
|
/// ## FileTransfer
|
||||||
///
|
///
|
||||||
/// File transfer trait must be implemented by all the file transfers and defines the method used by a generic file transfer
|
/// 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
|
/// Connect to the remote server
|
||||||
/// Can return banner / welcome message on success
|
/// 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
|
||||||
///
|
///
|
||||||
/// Disconnect from the remote server
|
/// Disconnect from the remote server
|
||||||
fn disconnect(&mut self) -> Result<(), FileTransferError>;
|
fn disconnect(&mut self) -> FileTransferResult<()>;
|
||||||
|
|
||||||
/// ### is_connected
|
/// ### is_connected
|
||||||
///
|
///
|
||||||
@@ -153,50 +156,50 @@ pub trait FileTransfer {
|
|||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
|
|
||||||
fn pwd(&mut self) -> Result<PathBuf, FileTransferError>;
|
fn pwd(&mut self) -> FileTransferResult<PathBuf>;
|
||||||
|
|
||||||
/// ### change_dir
|
/// ### change_dir
|
||||||
///
|
///
|
||||||
/// Change working directory
|
/// Change working directory
|
||||||
|
|
||||||
fn change_dir(&mut self, dir: &Path) -> Result<PathBuf, FileTransferError>;
|
fn change_dir(&mut self, dir: &Path) -> FileTransferResult<PathBuf>;
|
||||||
|
|
||||||
/// ### copy
|
/// ### copy
|
||||||
///
|
///
|
||||||
/// Copy file to destination
|
/// 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_dir
|
||||||
///
|
///
|
||||||
/// List directory entries
|
/// 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
|
/// ### mkdir
|
||||||
///
|
///
|
||||||
/// Make directory
|
/// Make directory
|
||||||
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
|
/// 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
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// Remove a file or a directory
|
||||||
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError>;
|
fn remove(&mut self, file: &FsEntry) -> FileTransferResult<()>;
|
||||||
|
|
||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// 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
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// Stat file and return FsEntry
|
||||||
fn stat(&mut self, path: &Path) -> Result<FsEntry, FileTransferError>;
|
fn stat(&mut self, path: &Path) -> FileTransferResult<FsEntry>;
|
||||||
|
|
||||||
/// ### exec
|
/// ### exec
|
||||||
///
|
///
|
||||||
/// Execute a command on remote host
|
/// 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
|
/// ### send_file
|
||||||
///
|
///
|
||||||
@@ -209,7 +212,7 @@ pub trait FileTransfer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_local: &FsFile,
|
_local: &FsFile,
|
||||||
_file_name: &Path,
|
_file_name: &Path,
|
||||||
) -> Result<Box<dyn Write>, FileTransferError> {
|
) -> FileTransferResult<Box<dyn Write>> {
|
||||||
Err(FileTransferError::new(
|
Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
))
|
))
|
||||||
@@ -220,7 +223,7 @@ pub trait FileTransfer {
|
|||||||
/// Receive file from remote with provided name
|
/// Receive file from remote with provided name
|
||||||
/// Returns file and its size
|
/// Returns file and its size
|
||||||
/// By default returns unsupported feature
|
/// 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(
|
Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
))
|
))
|
||||||
@@ -234,7 +237,7 @@ pub trait FileTransfer {
|
|||||||
/// This is necessary for some protocols such as FTP.
|
/// 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.
|
/// You must call this method each time you want to finalize the write of the remote file.
|
||||||
/// By default this function returns already `Ok(())`
|
/// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +249,7 @@ pub trait FileTransfer {
|
|||||||
/// This mighe be necessary for some protocols.
|
/// This mighe be necessary for some protocols.
|
||||||
/// You must call this method each time you want to finalize the read of the remote file.
|
/// You must call this method each time you want to finalize the read of the remote file.
|
||||||
/// By default this function returns already `Ok(())`
|
/// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +265,7 @@ pub trait FileTransfer {
|
|||||||
src: &FsFile,
|
src: &FsFile,
|
||||||
dest: &Path,
|
dest: &Path,
|
||||||
mut reader: Box<dyn Read>,
|
mut reader: Box<dyn Read>,
|
||||||
) -> Result<(), FileTransferError> {
|
) -> FileTransferResult<()> {
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
let mut stream = self.send_file(src, dest)?;
|
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.
|
/// 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.
|
/// 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
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
let mut writer = File::create(dest).map_err(|e| {
|
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
|
/// Find files from current directory (in all subdirectories) whose name matches the provided search
|
||||||
/// Search supports wildcards ('?', '*')
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
// Starting from current directory, iter dir
|
// Starting from current directory, iter dir
|
||||||
@@ -335,11 +338,7 @@ pub trait FileTransfer {
|
|||||||
/// Search recursively in `dir` for file matching the wildcard.
|
/// 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 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
|
/// NOTE: don't call this method from outside; consider it as private
|
||||||
fn iter_search(
|
fn iter_search(&mut self, dir: &Path, filter: &WildMatch) -> FileTransferResult<Vec<FsEntry>> {
|
||||||
&mut self,
|
|
||||||
dir: &Path,
|
|
||||||
filter: &WildMatch,
|
|
||||||
) -> Result<Vec<FsEntry>, FileTransferError> {
|
|
||||||
let mut drained: Vec<FsEntry> = Vec::new();
|
let mut drained: Vec<FsEntry> = Vec::new();
|
||||||
// Scan directory
|
// Scan directory
|
||||||
match self.list_dir(dir) {
|
match self.list_dir(dir) {
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
|
use super::{
|
||||||
|
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
|
||||||
|
};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
||||||
use crate::utils::fmt::shadow_password;
|
use crate::utils::fmt::shadow_password;
|
||||||
use crate::utils::path;
|
use crate::utils::path;
|
||||||
@@ -178,7 +180,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Connect to the remote server
|
/// 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() {
|
let params = match params.generic_params() {
|
||||||
Some(params) => params,
|
Some(params) => params,
|
||||||
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
|
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
|
||||||
@@ -270,7 +272,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Disconnect from the remote server
|
/// Disconnect from the remote server
|
||||||
|
|
||||||
fn disconnect(&mut self) -> Result<(), FileTransferError> {
|
fn disconnect(&mut self) -> FileTransferResult<()> {
|
||||||
info!("Disconnecting from FTP server...");
|
info!("Disconnecting from FTP server...");
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
Some(stream) => match stream.quit() {
|
Some(stream) => match stream.quit() {
|
||||||
@@ -300,7 +302,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
|
|
||||||
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
|
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
|
||||||
info!("PWD");
|
info!("PWD");
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
Some(stream) => match stream.pwd() {
|
Some(stream) => match stream.pwd() {
|
||||||
@@ -320,7 +322,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Change working directory
|
/// 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);
|
let dir: PathBuf = Self::resolve(dir);
|
||||||
info!("Changing directory to {}", dir.display());
|
info!("Changing directory to {}", dir.display());
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
@@ -340,7 +342,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
/// ### copy
|
/// ### copy
|
||||||
///
|
///
|
||||||
/// Copy file to destination
|
/// 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
|
// FTP doesn't support file copy
|
||||||
debug!("COPY issues (will fail, since unsupported)");
|
debug!("COPY issues (will fail, since unsupported)");
|
||||||
Err(FileTransferError::new(
|
Err(FileTransferError::new(
|
||||||
@@ -352,7 +354,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// List directory entries
|
/// 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);
|
let dir: PathBuf = Self::resolve(path);
|
||||||
info!("LIST dir {}", dir.display());
|
info!("LIST dir {}", dir.display());
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
@@ -376,7 +378,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
/// ### mkdir
|
/// ### mkdir
|
||||||
///
|
///
|
||||||
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
|
/// 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);
|
let dir: PathBuf = Self::resolve(dir);
|
||||||
info!("MKDIR {}", dir.display());
|
info!("MKDIR {}", dir.display());
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
@@ -406,7 +408,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
/// ### remove
|
/// ### remove
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// 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() {
|
if self.stream.is_none() {
|
||||||
return Err(FileTransferError::new(
|
return Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UninitializedSession,
|
FileTransferErrorType::UninitializedSession,
|
||||||
@@ -493,7 +495,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// 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);
|
let dst: PathBuf = Self::resolve(dst);
|
||||||
info!(
|
info!(
|
||||||
"Renaming {} to {}",
|
"Renaming {} to {}",
|
||||||
@@ -525,7 +527,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
/// ### stat
|
/// ### stat
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// 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 {
|
match &mut self.stream {
|
||||||
Some(_) => Err(FileTransferError::new(
|
Some(_) => Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
@@ -539,7 +541,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
/// ### exec
|
/// ### exec
|
||||||
///
|
///
|
||||||
/// Execute a command on remote host
|
/// 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(
|
Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
))
|
))
|
||||||
@@ -555,7 +557,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_local: &FsFile,
|
_local: &FsFile,
|
||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
) -> Result<Box<dyn Write>, FileTransferError> {
|
) -> FileTransferResult<Box<dyn Write>> {
|
||||||
let file_name: PathBuf = Self::resolve(file_name);
|
let file_name: PathBuf = Self::resolve(file_name);
|
||||||
info!("Sending file {}", file_name.display());
|
info!("Sending file {}", file_name.display());
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
@@ -576,7 +578,7 @@ impl FileTransfer for FtpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Receive file from remote with provided name
|
/// Receive file from remote with provided name
|
||||||
/// Returns file and its size
|
/// 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());
|
info!("Receiving file {}", file.abs_path.display());
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
Some(stream) => match stream.retr_as_stream(&file.abs_path.as_path().to_string_lossy())
|
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.
|
/// 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.
|
/// 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.
|
/// 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");
|
info!("Finalizing put stream");
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
Some(stream) => match stream.finalize_put_stream(writable) {
|
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.
|
/// The purpose of this method is to finalize the connection with the peer when reading data.
|
||||||
/// This mighe be necessary for some protocols.
|
/// This mighe be necessary for some protocols.
|
||||||
/// You must call this method each time you want to finalize the read of the remote file.
|
/// 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");
|
info!("Finalizing get");
|
||||||
match &mut self.stream {
|
match &mut self.stream {
|
||||||
Some(stream) => match stream.finalize_retr_stream(readable) {
|
Some(stream) => match stream.finalize_retr_stream(readable) {
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
//! This module exposes all the file transfers supported by termscp
|
//! This module exposes all the file transfers supported by termscp
|
||||||
|
|
||||||
// -- import
|
// -- import
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
|
use super::{
|
||||||
|
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
|
||||||
|
};
|
||||||
|
|
||||||
// -- modules
|
// -- modules
|
||||||
mod ftp;
|
mod ftp;
|
||||||
|
|||||||
@@ -29,7 +29,9 @@
|
|||||||
mod object;
|
mod object;
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
|
use super::{
|
||||||
|
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
|
||||||
|
};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
||||||
use crate::utils::path;
|
use crate::utils::path;
|
||||||
use object::S3Object;
|
use object::S3Object;
|
||||||
@@ -64,7 +66,7 @@ impl S3FileTransfer {
|
|||||||
/// ### list_objects
|
/// ### list_objects
|
||||||
///
|
///
|
||||||
/// List objects contained in `p` path
|
/// 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
|
// Make path relative
|
||||||
let key: String = Self::fmt_path(p, list_dir);
|
let key: String = Self::fmt_path(p, list_dir);
|
||||||
debug!("Query list directory {}; key: {}", p.display(), key);
|
debug!("Query list directory {}; key: {}", p.display(), key);
|
||||||
@@ -74,7 +76,7 @@ impl S3FileTransfer {
|
|||||||
/// ### stat_object
|
/// ### stat_object
|
||||||
///
|
///
|
||||||
/// Stat an s3 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);
|
let key: String = Self::fmt_path(p, false);
|
||||||
debug!("Query stat object {}; key: {}", p.display(), key);
|
debug!("Query stat object {}; key: {}", p.display(), key);
|
||||||
let objects = self.query_objects(key, false)?;
|
let objects = self.query_objects(key, false)?;
|
||||||
@@ -100,7 +102,7 @@ impl S3FileTransfer {
|
|||||||
&self,
|
&self,
|
||||||
key: String,
|
key: String,
|
||||||
only_direct_children: bool,
|
only_direct_children: bool,
|
||||||
) -> Result<Vec<S3Object>, FileTransferError> {
|
) -> FileTransferResult<Vec<S3Object>> {
|
||||||
let results = self.bucket.as_ref().unwrap().list(key.clone(), None);
|
let results = self.bucket.as_ref().unwrap().list(key.clone(), None);
|
||||||
match results {
|
match results {
|
||||||
Ok(entries) => {
|
Ok(entries) => {
|
||||||
@@ -200,7 +202,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
///
|
///
|
||||||
/// Connect to the remote server
|
/// Connect to the remote server
|
||||||
/// Can return banner / welcome message on success
|
/// 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
|
// Verify parameters are S3
|
||||||
let params = match params.s3_params() {
|
let params = match params.s3_params() {
|
||||||
Some(params) => params,
|
Some(params) => params,
|
||||||
@@ -242,7 +244,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### disconnect
|
/// ### disconnect
|
||||||
///
|
///
|
||||||
/// Disconnect from the remote server
|
/// Disconnect from the remote server
|
||||||
fn disconnect(&mut self) -> Result<(), FileTransferError> {
|
fn disconnect(&mut self) -> FileTransferResult<()> {
|
||||||
info!("Disconnecting from S3 bucket...");
|
info!("Disconnecting from S3 bucket...");
|
||||||
match self.bucket.take() {
|
match self.bucket.take() {
|
||||||
Some(bucket) => {
|
Some(bucket) => {
|
||||||
@@ -265,7 +267,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### pwd
|
/// ### pwd
|
||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
|
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
|
||||||
info!("PWD");
|
info!("PWD");
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => Ok(self.wrkdir.clone()),
|
true => Ok(self.wrkdir.clone()),
|
||||||
@@ -278,7 +280,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### change_dir
|
/// ### change_dir
|
||||||
///
|
///
|
||||||
/// Change working directory
|
/// 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() {
|
match &self.bucket.is_some() {
|
||||||
true => {
|
true => {
|
||||||
// Always allow entering root
|
// Always allow entering root
|
||||||
@@ -315,7 +317,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### copy
|
/// ### copy
|
||||||
///
|
///
|
||||||
/// Copy file to destination
|
/// 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(
|
Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
))
|
))
|
||||||
@@ -324,7 +326,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### list_dir
|
/// ### list_dir
|
||||||
///
|
///
|
||||||
/// List directory entries
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => self
|
true => self
|
||||||
.list_objects(path, true)
|
.list_objects(path, true)
|
||||||
@@ -339,7 +341,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
///
|
///
|
||||||
/// Make directory
|
/// Make directory
|
||||||
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
|
/// 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 {
|
match &self.bucket {
|
||||||
Some(bucket) => {
|
Some(bucket) => {
|
||||||
let dir: String = Self::fmt_path(self.resolve(dir).as_path(), true);
|
let dir: String = Self::fmt_path(self.resolve(dir).as_path(), true);
|
||||||
@@ -373,7 +375,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### remove
|
/// ### remove
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// 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(
|
let path = Self::fmt_path(
|
||||||
path::diff_paths(file.get_abs_path(), &Path::new("/"))
|
path::diff_paths(file.get_abs_path(), &Path::new("/"))
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
@@ -397,7 +399,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// 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(
|
Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
))
|
))
|
||||||
@@ -406,7 +408,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### stat
|
/// ### stat
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
// First try as a "file"
|
// First try as a "file"
|
||||||
@@ -428,7 +430,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
/// ### exec
|
/// ### exec
|
||||||
///
|
///
|
||||||
/// Execute a command on remote host
|
/// 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(
|
Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UnsupportedFeature,
|
FileTransferErrorType::UnsupportedFeature,
|
||||||
))
|
))
|
||||||
@@ -446,7 +448,7 @@ impl FileTransfer for S3FileTransfer {
|
|||||||
_src: &FsFile,
|
_src: &FsFile,
|
||||||
dest: &Path,
|
dest: &Path,
|
||||||
mut reader: Box<dyn Read>,
|
mut reader: Box<dyn Read>,
|
||||||
) -> Result<(), FileTransferError> {
|
) -> FileTransferResult<()> {
|
||||||
match &mut self.bucket {
|
match &mut self.bucket {
|
||||||
Some(bucket) => {
|
Some(bucket) => {
|
||||||
let key = Self::fmt_path(dest, false);
|
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`
|
/// 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.
|
/// 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
|
/// 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 {
|
match &mut self.bucket {
|
||||||
Some(bucket) => {
|
Some(bucket) => {
|
||||||
let mut writer = File::create(dest).map_err(|e| {
|
let mut writer = File::create(dest).map_err(|e| {
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
// Locals
|
// Locals
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
|
use super::{
|
||||||
|
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
|
||||||
|
};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
||||||
use crate::system::sshkey_storage::SshKeyStorage;
|
use crate::system::sshkey_storage::SshKeyStorage;
|
||||||
use crate::utils::fmt::{fmt_time, shadow_password};
|
use crate::utils::fmt::{fmt_time, shadow_password};
|
||||||
@@ -278,7 +280,7 @@ impl ScpFileTransfer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
cmd: &str,
|
cmd: &str,
|
||||||
) -> Result<String, FileTransferError> {
|
) -> FileTransferResult<String> {
|
||||||
self.perform_shell_cmd(format!("cd \"{}\"; {}", path.display(), cmd).as_str())
|
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
|
/// Perform a shell command and read the output from shell
|
||||||
/// This operation is, obviously, blocking.
|
/// 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() {
|
match self.session.as_mut() {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
debug!("Running command: {}", cmd);
|
debug!("Running command: {}", cmd);
|
||||||
@@ -333,7 +335,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### connect
|
/// ### connect
|
||||||
///
|
///
|
||||||
/// Connect to the remote server
|
/// 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() {
|
let params = match params.generic_params() {
|
||||||
Some(params) => params,
|
Some(params) => params,
|
||||||
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
|
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
|
||||||
@@ -472,7 +474,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### disconnect
|
/// ### disconnect
|
||||||
///
|
///
|
||||||
/// Disconnect from the remote server
|
/// Disconnect from the remote server
|
||||||
fn disconnect(&mut self) -> Result<(), FileTransferError> {
|
fn disconnect(&mut self) -> FileTransferResult<()> {
|
||||||
info!("Disconnecting from remote...");
|
info!("Disconnecting from remote...");
|
||||||
match self.session.as_ref() {
|
match self.session.as_ref() {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
@@ -506,7 +508,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
|
|
||||||
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
|
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
|
||||||
info!("PWD: {}", self.wrkdir.display());
|
info!("PWD: {}", self.wrkdir.display());
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => Ok(self.wrkdir.clone()),
|
true => Ok(self.wrkdir.clone()),
|
||||||
@@ -520,7 +522,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Change working directory
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
let p: PathBuf = self.wrkdir.clone();
|
let p: PathBuf = self.wrkdir.clone();
|
||||||
@@ -564,7 +566,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### copy
|
/// ### copy
|
||||||
///
|
///
|
||||||
/// Copy file to destination
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
let dst: PathBuf = Self::resolve(dst);
|
let dst: PathBuf = Self::resolve(dst);
|
||||||
@@ -612,7 +614,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// List directory entries
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
// Send ls -l to path
|
// Send ls -l to path
|
||||||
@@ -657,7 +659,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Make directory
|
/// Make directory
|
||||||
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
let dir: PathBuf = Self::resolve(dir);
|
let dir: PathBuf = Self::resolve(dir);
|
||||||
@@ -703,7 +705,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### remove
|
/// ### remove
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// 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
|
// Yay, we have rm -rf here :D
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
@@ -741,7 +743,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
// Get path
|
// Get path
|
||||||
@@ -784,7 +786,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### stat
|
/// ### stat
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// 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);
|
let path: PathBuf = Self::absolutize(self.wrkdir.as_path(), path);
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
@@ -829,7 +831,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
/// ### exec
|
/// ### exec
|
||||||
///
|
///
|
||||||
/// Execute a command on remote host
|
/// 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() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
let p: PathBuf = self.wrkdir.clone();
|
let p: PathBuf = self.wrkdir.clone();
|
||||||
@@ -858,7 +860,7 @@ impl FileTransfer for ScpFileTransfer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
local: &FsFile,
|
local: &FsFile,
|
||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
) -> Result<Box<dyn Write>, FileTransferError> {
|
) -> FileTransferResult<Box<dyn Write>> {
|
||||||
match self.session.as_ref() {
|
match self.session.as_ref() {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
let file_name: PathBuf = Self::absolutize(self.wrkdir.as_path(), file_name);
|
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
|
/// Receive file from remote with provided name
|
||||||
/// Returns file and its size
|
/// 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() {
|
match self.session.as_ref() {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
info!("Receiving file {}", file.abs_path.display());
|
info!("Receiving file {}", file.abs_path.display());
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
// Locals
|
// Locals
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType, ProtocolParams};
|
use super::{
|
||||||
|
FileTransfer, FileTransferError, FileTransferErrorType, FileTransferResult, ProtocolParams,
|
||||||
|
};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
||||||
use crate::system::sshkey_storage::SshKeyStorage;
|
use crate::system::sshkey_storage::SshKeyStorage;
|
||||||
use crate::utils::fmt::{fmt_time, shadow_password};
|
use crate::utils::fmt::{fmt_time, shadow_password};
|
||||||
@@ -64,7 +66,7 @@ impl SftpFileTransfer {
|
|||||||
/// ### get_abs_path
|
/// ### get_abs_path
|
||||||
///
|
///
|
||||||
/// Get absolute path from path argument and check if it exists
|
/// 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() {
|
match p.is_relative() {
|
||||||
true => {
|
true => {
|
||||||
let mut root: PathBuf = self.wrkdir.clone();
|
let mut root: PathBuf = self.wrkdir.clone();
|
||||||
@@ -202,7 +204,7 @@ impl SftpFileTransfer {
|
|||||||
/// ### perform_shell_cmd_with
|
/// ### perform_shell_cmd_with
|
||||||
///
|
///
|
||||||
/// Perform a shell command, but change directory to specified path first
|
/// 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())
|
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
|
/// Perform a shell command and read the output from shell
|
||||||
/// This operation is, obviously, blocking.
|
/// 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() {
|
match self.session.as_mut() {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
// Create channel
|
// Create channel
|
||||||
@@ -257,7 +259,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### connect
|
/// ### connect
|
||||||
///
|
///
|
||||||
/// Connect to the remote server
|
/// 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() {
|
let params = match params.generic_params() {
|
||||||
Some(params) => params,
|
Some(params) => params,
|
||||||
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
|
None => return Err(FileTransferError::new(FileTransferErrorType::BadAddress)),
|
||||||
@@ -413,7 +415,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### disconnect
|
/// ### disconnect
|
||||||
///
|
///
|
||||||
/// Disconnect from the remote server
|
/// Disconnect from the remote server
|
||||||
fn disconnect(&mut self) -> Result<(), FileTransferError> {
|
fn disconnect(&mut self) -> FileTransferResult<()> {
|
||||||
info!("Disconnecting from remote...");
|
info!("Disconnecting from remote...");
|
||||||
match self.session.as_ref() {
|
match self.session.as_ref() {
|
||||||
Some(session) => {
|
Some(session) => {
|
||||||
@@ -447,7 +449,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### pwd
|
/// ### pwd
|
||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
|
fn pwd(&mut self) -> FileTransferResult<PathBuf> {
|
||||||
info!("PWD: {}", self.wrkdir.display());
|
info!("PWD: {}", self.wrkdir.display());
|
||||||
match self.sftp {
|
match self.sftp {
|
||||||
Some(_) => Ok(self.wrkdir.clone()),
|
Some(_) => Ok(self.wrkdir.clone()),
|
||||||
@@ -460,7 +462,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### change_dir
|
/// ### change_dir
|
||||||
///
|
///
|
||||||
/// Change working directory
|
/// 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() {
|
match self.sftp.as_ref() {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
// Change working directory
|
// Change working directory
|
||||||
@@ -477,7 +479,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### copy
|
/// ### copy
|
||||||
///
|
///
|
||||||
/// Copy file to destination
|
/// 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)
|
// NOTE: use SCP command to perform copy (UNSAFE)
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => {
|
true => {
|
||||||
@@ -523,7 +525,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### list_dir
|
/// ### list_dir
|
||||||
///
|
///
|
||||||
/// List directory entries
|
/// 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() {
|
match self.sftp.as_ref() {
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Get path
|
// Get path
|
||||||
@@ -556,7 +558,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
///
|
///
|
||||||
/// Make directory
|
/// Make directory
|
||||||
/// In case the directory already exists, it must return an Error of kind `FileTransferErrorType::DirectoryAlreadyExists`
|
/// 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() {
|
match self.sftp.as_ref() {
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Make directory
|
// Make directory
|
||||||
@@ -586,7 +588,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### remove
|
/// ### remove
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// 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() {
|
if self.sftp.is_none() {
|
||||||
return Err(FileTransferError::new(
|
return Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UninitializedSession,
|
FileTransferErrorType::UninitializedSession,
|
||||||
@@ -630,7 +632,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// 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() {
|
match self.sftp.as_ref() {
|
||||||
None => Err(FileTransferError::new(
|
None => Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UninitializedSession,
|
FileTransferErrorType::UninitializedSession,
|
||||||
@@ -659,7 +661,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### stat
|
/// ### stat
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// 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() {
|
match self.sftp.as_ref() {
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Get path
|
// Get path
|
||||||
@@ -683,7 +685,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### exec
|
/// ### exec
|
||||||
///
|
///
|
||||||
/// Execute a command on remote host
|
/// 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);
|
info!("Executing command {}", cmd);
|
||||||
match self.is_connected() {
|
match self.is_connected() {
|
||||||
true => match self.perform_shell_cmd_with_path(cmd) {
|
true => match self.perform_shell_cmd_with_path(cmd) {
|
||||||
@@ -708,7 +710,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
local: &FsFile,
|
local: &FsFile,
|
||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
) -> Result<Box<dyn Write>, FileTransferError> {
|
) -> FileTransferResult<Box<dyn Write>> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
None => Err(FileTransferError::new(
|
None => Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UninitializedSession,
|
FileTransferErrorType::UninitializedSession,
|
||||||
@@ -749,7 +751,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### recv_file
|
/// ### recv_file
|
||||||
///
|
///
|
||||||
/// Receive file from remote with provided name
|
/// 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() {
|
match self.sftp.as_ref() {
|
||||||
None => Err(FileTransferError::new(
|
None => Err(FileTransferError::new(
|
||||||
FileTransferErrorType::UninitializedSession,
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
|||||||
Reference in New Issue
Block a user