mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
Filetransfer all mutable
This commit is contained in:
@@ -54,7 +54,7 @@ pub struct FileTransferError {
|
|||||||
/// ## FileTransferErrorType
|
/// ## FileTransferErrorType
|
||||||
///
|
///
|
||||||
/// FileTransferErrorType defines the possible errors available for a file transfer
|
/// FileTransferErrorType defines the possible errors available for a file transfer
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum FileTransferErrorType {
|
pub enum FileTransferErrorType {
|
||||||
AuthenticationFailed,
|
AuthenticationFailed,
|
||||||
BadAddress,
|
BadAddress,
|
||||||
@@ -150,7 +150,7 @@ pub trait FileTransfer {
|
|||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
|
|
||||||
fn pwd(&self) -> Result<PathBuf, FileTransferError>;
|
fn pwd(&mut self) -> Result<PathBuf, FileTransferError>;
|
||||||
|
|
||||||
/// ### change_dir
|
/// ### change_dir
|
||||||
///
|
///
|
||||||
@@ -162,27 +162,27 @@ pub trait FileTransfer {
|
|||||||
///
|
///
|
||||||
/// List directory entries
|
/// List directory entries
|
||||||
|
|
||||||
fn list_dir(&self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError>;
|
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError>;
|
||||||
|
|
||||||
/// ### mkdir
|
/// ### mkdir
|
||||||
///
|
///
|
||||||
/// Make directory
|
/// Make directory
|
||||||
fn mkdir(&self, dir: &Path) -> Result<(), FileTransferError>;
|
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError>;
|
||||||
|
|
||||||
/// ### remove
|
/// ### remove
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// Remove a file or a directory
|
||||||
fn remove(&self, file: &FsEntry) -> Result<(), FileTransferError>;
|
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError>;
|
||||||
|
|
||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// Rename file or a directory
|
||||||
fn rename(&self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError>;
|
fn rename(&mut self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError>;
|
||||||
|
|
||||||
/// ### stat
|
/// ### stat
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// Stat file and return FsEntry
|
||||||
fn stat(&self, path: &Path) -> Result<FsEntry, FileTransferError>;
|
fn stat(&mut self, path: &Path) -> Result<FsEntry, FileTransferError>;
|
||||||
|
|
||||||
/// ### send_file
|
/// ### send_file
|
||||||
///
|
///
|
||||||
@@ -190,11 +190,11 @@ pub trait FileTransfer {
|
|||||||
/// File name is referred to the name of the file as it will be saved
|
/// File name is referred to the name of the file as it will be saved
|
||||||
/// Data contains the file data
|
/// Data contains the file data
|
||||||
/// Returns file and its size
|
/// Returns file and its size
|
||||||
fn send_file(&self, file_name: &Path) -> Result<Box<dyn Write>, FileTransferError>;
|
fn send_file(&mut self, file_name: &Path) -> Result<Box<dyn Write>, FileTransferError>;
|
||||||
|
|
||||||
/// ### recv_file
|
/// ### recv_file
|
||||||
///
|
///
|
||||||
/// 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(&self, file_name: &Path) -> Result<Box<dyn Read>, FileTransferError>;
|
fn recv_file(&mut self, file_name: &Path) -> Result<Box<dyn Read>, FileTransferError>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,17 +69,28 @@ impl SftpFileTransfer {
|
|||||||
match self.sftp.as_ref().unwrap().realpath(root.as_path()) {
|
match self.sftp.as_ref().unwrap().realpath(root.as_path()) {
|
||||||
Ok(p) => match self.sftp.as_ref().unwrap().stat(p.as_path()) {
|
Ok(p) => match self.sftp.as_ref().unwrap().stat(p.as_path()) {
|
||||||
Ok(_) => Ok(PathBuf::from(p)),
|
Ok(_) => Ok(PathBuf::from(p)),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::NoSuchFileOrDirectory, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::NoSuchFileOrDirectory,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::NoSuchFileOrDirectory, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::NoSuchFileOrDirectory,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false => match self.sftp.as_ref().unwrap().realpath(p) {
|
false => match self.sftp.as_ref().unwrap().realpath(p) {
|
||||||
Ok(p) => match self.sftp.as_ref().unwrap().stat(p.as_path()) {
|
Ok(p) => match self.sftp.as_ref().unwrap().stat(p.as_path()) {
|
||||||
Ok(_) => Ok(PathBuf::from(p)),
|
Ok(_) => Ok(PathBuf::from(p)),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::NoSuchFileOrDirectory, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::NoSuchFileOrDirectory,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
Err(_) => Err(FileTransferError::new(FileTransferErrorType::NoSuchFileOrDirectory)),
|
Err(_) => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::NoSuchFileOrDirectory,
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,37 +199,63 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
// Setup tcp stream
|
// Setup tcp stream
|
||||||
let tcp: TcpStream = match TcpStream::connect(format!("{}:{}", address, port)) {
|
let tcp: TcpStream = match TcpStream::connect(format!("{}:{}", address, port)) {
|
||||||
Ok(stream) => stream,
|
Ok(stream) => stream,
|
||||||
Err(err) => return Err(FileTransferError::new_ex(FileTransferErrorType::BadAddress, format!("{}", err))),
|
Err(err) => {
|
||||||
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::BadAddress,
|
||||||
|
format!("{}", err),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Create session
|
// Create session
|
||||||
let mut session: Session = match Session::new() {
|
let mut session: Session = match Session::new() {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(err) => return Err(FileTransferError::new_ex(FileTransferErrorType::ConnectionError, format!("{}", err))),
|
Err(err) => {
|
||||||
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::ConnectionError,
|
||||||
|
format!("{}", err),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Set TCP stream
|
// Set TCP stream
|
||||||
session.set_tcp_stream(tcp);
|
session.set_tcp_stream(tcp);
|
||||||
// Open connection
|
// Open connection
|
||||||
if let Err(err) = session.handshake() {
|
if let Err(err) = session.handshake() {
|
||||||
return Err(FileTransferError::new_ex(FileTransferErrorType::ConnectionError, format!("{}", err)));
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::ConnectionError,
|
||||||
|
format!("{}", err),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
// Try authentication
|
// Try authentication
|
||||||
if let Err(err) = session.userauth_password(
|
if let Err(err) = session.userauth_password(
|
||||||
username.unwrap_or(String::from("")).as_str(),
|
username.unwrap_or(String::from("")).as_str(),
|
||||||
password.unwrap_or(String::from("")).as_str(),
|
password.unwrap_or(String::from("")).as_str(),
|
||||||
) {
|
) {
|
||||||
return Err(FileTransferError::new_ex(FileTransferErrorType::AuthenticationFailed, format!("{}", err)));
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::AuthenticationFailed,
|
||||||
|
format!("{}", err),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
// Set blocking to true
|
// Set blocking to true
|
||||||
session.set_blocking(true);
|
session.set_blocking(true);
|
||||||
// Get Sftp client
|
// Get Sftp client
|
||||||
let sftp: Sftp = match session.sftp() {
|
let sftp: Sftp = match session.sftp() {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(err) => return Err(FileTransferError::new_ex(FileTransferErrorType::ProtocolError, format!("{}", err))),
|
Err(err) => {
|
||||||
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::ProtocolError,
|
||||||
|
format!("{}", err),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Get working directory
|
// Get working directory
|
||||||
self.wrkdir = match sftp.realpath(PathBuf::from(".").as_path()) {
|
self.wrkdir = match sftp.realpath(PathBuf::from(".").as_path()) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(err) => return Err(FileTransferError::new_ex(FileTransferErrorType::ProtocolError, format!("{}", err))),
|
Err(err) => {
|
||||||
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::ProtocolError,
|
||||||
|
format!("{}", err),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Set session
|
// Set session
|
||||||
self.session = Some(session);
|
self.session = Some(session);
|
||||||
@@ -241,10 +278,15 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
self.sftp = None;
|
self.sftp = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::ConnectionError, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::ConnectionError,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,10 +300,12 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### pwd
|
/// ### pwd
|
||||||
///
|
///
|
||||||
/// Print working directory
|
/// Print working directory
|
||||||
fn pwd(&self) -> Result<PathBuf, FileTransferError> {
|
fn pwd(&mut self) -> Result<PathBuf, FileTransferError> {
|
||||||
match self.sftp {
|
match self.sftp {
|
||||||
Some(_) => Ok(self.wrkdir.clone()),
|
Some(_) => Ok(self.wrkdir.clone()),
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,14 +322,16 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
};
|
};
|
||||||
Ok(self.wrkdir.clone())
|
Ok(self.wrkdir.clone())
|
||||||
}
|
}
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### list_dir
|
/// ### list_dir
|
||||||
///
|
///
|
||||||
/// List directory entries
|
/// List directory entries
|
||||||
fn list_dir(&self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError> {
|
fn list_dir(&mut self, path: &Path) -> Result<Vec<FsEntry>, FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Get path
|
// Get path
|
||||||
@@ -295,7 +341,12 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
};
|
};
|
||||||
// Get files
|
// Get files
|
||||||
match sftp.readdir(dir.as_path()) {
|
match sftp.readdir(dir.as_path()) {
|
||||||
Err(err) => return Err(FileTransferError::new_ex(FileTransferErrorType::DirStatFailed, format!("{}", err))),
|
Err(err) => {
|
||||||
|
return Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::DirStatFailed,
|
||||||
|
format!("{}", err),
|
||||||
|
))
|
||||||
|
}
|
||||||
Ok(files) => {
|
Ok(files) => {
|
||||||
// Allocate vector
|
// Allocate vector
|
||||||
let mut entries: Vec<FsEntry> = Vec::with_capacity(files.len());
|
let mut entries: Vec<FsEntry> = Vec::with_capacity(files.len());
|
||||||
@@ -307,63 +358,74 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### mkdir
|
/// ### mkdir
|
||||||
///
|
///
|
||||||
/// Make directory
|
/// Make directory
|
||||||
fn mkdir(&self, dir: &Path) -> Result<(), FileTransferError> {
|
fn mkdir(&mut self, dir: &Path) -> Result<(), FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Make directory
|
// Make directory
|
||||||
let path: PathBuf = self.get_abs_path(PathBuf::from(dir).as_path());
|
let path: PathBuf = self.get_abs_path(PathBuf::from(dir).as_path());
|
||||||
match sftp.mkdir(path.as_path(), 0o775) {
|
match sftp.mkdir(path.as_path(), 0o775) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::FileCreateDenied, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::FileCreateDenied,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### remove
|
/// ### remove
|
||||||
///
|
///
|
||||||
/// Remove a file or a directory
|
/// Remove a file or a directory
|
||||||
fn remove(&self, file: &FsEntry) -> Result<(), FileTransferError> {
|
fn remove(&mut self, file: &FsEntry) -> Result<(), FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
if self.sftp.is_none() {
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
return Err(FileTransferError::new(
|
||||||
Some(sftp) => {
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
));
|
||||||
|
}
|
||||||
// Match if file is a file or a directory
|
// Match if file is a file or a directory
|
||||||
match file {
|
match file {
|
||||||
FsEntry::File(f) => {
|
FsEntry::File(f) => {
|
||||||
// Remove file
|
// Remove file
|
||||||
match sftp.unlink(f.abs_path.as_path()) {
|
match self.sftp.as_ref().unwrap().unlink(f.abs_path.as_path()) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::PexError, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::PexError,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FsEntry::Directory(d) => {
|
FsEntry::Directory(d) => {
|
||||||
// Remove recursively
|
// Remove recursively
|
||||||
// Get directory files
|
// Get directory files
|
||||||
match self.list_dir(d.abs_path.as_path()) {
|
let directory_content: Vec<FsEntry> = match self.list_dir(d.abs_path.as_path()) {
|
||||||
Ok(entries) => {
|
Ok(entries) => entries,
|
||||||
// Remove each entry
|
Err(err) => return Err(err),
|
||||||
for entry in entries {
|
};
|
||||||
|
for entry in directory_content.iter() {
|
||||||
if let Err(err) = self.remove(&entry) {
|
if let Err(err) = self.remove(&entry) {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finally remove directory
|
// Finally remove directory
|
||||||
match sftp.rmdir(d.abs_path.as_path()) {
|
match self.sftp.as_ref().unwrap().rmdir(d.abs_path.as_path()) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::PexError, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
}
|
FileTransferErrorType::PexError,
|
||||||
}
|
format!("{}", err),
|
||||||
Err(err) => return Err(err),
|
)),
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,9 +434,11 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### rename
|
/// ### rename
|
||||||
///
|
///
|
||||||
/// Rename file or a directory
|
/// Rename file or a directory
|
||||||
fn rename(&self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
|
fn rename(&mut self, file: &FsEntry, dst: &Path) -> Result<(), FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Resolve destination path
|
// Resolve destination path
|
||||||
let abs_dst: PathBuf = self.get_abs_path(dst);
|
let abs_dst: PathBuf = self.get_abs_path(dst);
|
||||||
@@ -385,7 +449,10 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
};
|
};
|
||||||
match sftp.rename(abs_src.as_path(), abs_dst.as_path(), None) {
|
match sftp.rename(abs_src.as_path(), abs_dst.as_path(), None) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::FileCreateDenied, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::FileCreateDenied,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +461,7 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// ### stat
|
/// ### stat
|
||||||
///
|
///
|
||||||
/// Stat file and return FsEntry
|
/// Stat file and return FsEntry
|
||||||
fn stat(&self, path: &Path) -> Result<FsEntry, FileTransferError> {
|
fn stat(&mut self, path: &Path) -> Result<FsEntry, FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Get path
|
// Get path
|
||||||
@@ -405,10 +472,15 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
// Get file
|
// Get file
|
||||||
match sftp.stat(dir.as_path()) {
|
match sftp.stat(dir.as_path()) {
|
||||||
Ok(metadata) => Ok(self.make_fsentry(dir.as_path(), &metadata)),
|
Ok(metadata) => Ok(self.make_fsentry(dir.as_path(), &metadata)),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::NoSuchFileOrDirectory, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::NoSuchFileOrDirectory,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,14 +489,19 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
/// Send file to remote
|
/// Send file to remote
|
||||||
/// File name is referred to the name of the file as it will be saved
|
/// File name is referred to the name of the file as it will be saved
|
||||||
/// Data contains the file data
|
/// Data contains the file data
|
||||||
fn send_file(&self, file_name: &Path) -> Result<Box<dyn Write>, FileTransferError> {
|
fn send_file(&mut self, file_name: &Path) -> Result<Box<dyn Write>, FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
let remote_path: PathBuf = self.get_abs_path(file_name);
|
let remote_path: PathBuf = self.get_abs_path(file_name);
|
||||||
match sftp.create(remote_path.as_path()) {
|
match sftp.create(remote_path.as_path()) {
|
||||||
Ok(file) => Ok(Box::new(file)),
|
Ok(file) => Ok(Box::new(file)),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::FileCreateDenied, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::FileCreateDenied,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,9 +510,11 @@ 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(&self, file_name: &Path) -> Result<Box<dyn Read>, FileTransferError> {
|
fn recv_file(&mut self, file_name: &Path) -> Result<Box<dyn Read>, FileTransferError> {
|
||||||
match self.sftp.as_ref() {
|
match self.sftp.as_ref() {
|
||||||
None => Err(FileTransferError::new(FileTransferErrorType::UninitializedSession)),
|
None => Err(FileTransferError::new(
|
||||||
|
FileTransferErrorType::UninitializedSession,
|
||||||
|
)),
|
||||||
Some(sftp) => {
|
Some(sftp) => {
|
||||||
// Get remote file name
|
// Get remote file name
|
||||||
let remote_path: PathBuf = match self.get_remote_path(file_name) {
|
let remote_path: PathBuf = match self.get_remote_path(file_name) {
|
||||||
@@ -445,7 +524,10 @@ impl FileTransfer for SftpFileTransfer {
|
|||||||
// Open remote file
|
// Open remote file
|
||||||
match sftp.open(remote_path.as_path()) {
|
match sftp.open(remote_path.as_path()) {
|
||||||
Ok(file) => Ok(Box::new(file)),
|
Ok(file) => Ok(Box::new(file)),
|
||||||
Err(err) => Err(FileTransferError::new_ex(FileTransferErrorType::NoSuchFileOrDirectory, format!("{}", err))),
|
Err(err) => Err(FileTransferError::new_ex(
|
||||||
|
FileTransferErrorType::NoSuchFileOrDirectory,
|
||||||
|
format!("{}", err),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -633,7 +715,10 @@ mod tests {
|
|||||||
assert!(client.session.is_some());
|
assert!(client.session.is_some());
|
||||||
assert!(client.sftp.is_some());
|
assert!(client.sftp.is_some());
|
||||||
assert_eq!(client.wrkdir, PathBuf::from("/"));
|
assert_eq!(client.wrkdir, PathBuf::from("/"));
|
||||||
let file: FsEntry = client.stat(PathBuf::from("readme.txt").as_path()).ok().unwrap();
|
let file: FsEntry = client
|
||||||
|
.stat(PathBuf::from("readme.txt").as_path())
|
||||||
|
.ok()
|
||||||
|
.unwrap();
|
||||||
if let FsEntry::File(file) = file {
|
if let FsEntry::File(file) = file {
|
||||||
assert_eq!(file.abs_path, PathBuf::from("/readme.txt"));
|
assert_eq!(file.abs_path, PathBuf::from("/readme.txt"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user