mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
Improved abs paths in host
This commit is contained in:
@@ -136,7 +136,8 @@ impl Localhost {
|
|||||||
/// ### change_wrkdir
|
/// ### change_wrkdir
|
||||||
///
|
///
|
||||||
/// Change working directory with the new provided directory
|
/// Change working directory with the new provided directory
|
||||||
pub fn change_wrkdir(&mut self, new_dir: PathBuf) -> Result<PathBuf, HostError> {
|
pub fn change_wrkdir(&mut self, new_dir: &Path) -> Result<PathBuf, HostError> {
|
||||||
|
let new_dir: PathBuf = self.to_abs_path(new_dir);
|
||||||
// Check whether directory exists
|
// Check whether directory exists
|
||||||
if !self.file_exists(new_dir.as_path()) {
|
if !self.file_exists(new_dir.as_path()) {
|
||||||
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
||||||
@@ -168,14 +169,7 @@ impl Localhost {
|
|||||||
/// Extended option version of makedir.
|
/// Extended option version of makedir.
|
||||||
/// ignex: don't report error if directory already exists
|
/// ignex: don't report error if directory already exists
|
||||||
pub fn mkdir_ex(&mut self, dir_name: &Path, ignex: bool) -> Result<(), HostError> {
|
pub fn mkdir_ex(&mut self, dir_name: &Path, ignex: bool) -> Result<(), HostError> {
|
||||||
let dir_path: PathBuf = match dir_name.is_absolute() {
|
let dir_path: PathBuf = self.to_abs_path(dir_name);
|
||||||
true => PathBuf::from(dir_name),
|
|
||||||
false => {
|
|
||||||
let mut dir_path: PathBuf = self.wrkdir.clone();
|
|
||||||
dir_path.push(dir_name);
|
|
||||||
dir_path
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// If dir already exists, return Error
|
// If dir already exists, return Error
|
||||||
if dir_path.exists() {
|
if dir_path.exists() {
|
||||||
match ignex {
|
match ignex {
|
||||||
@@ -253,14 +247,7 @@ impl Localhost {
|
|||||||
/// Copy file to destination path
|
/// Copy file to destination path
|
||||||
pub fn copy(&mut self, entry: &FsEntry, dst: &Path) -> Result<(), HostError> {
|
pub fn copy(&mut self, entry: &FsEntry, dst: &Path) -> Result<(), HostError> {
|
||||||
// Get absolute path of dest
|
// Get absolute path of dest
|
||||||
let dst: PathBuf = match dst.is_absolute() {
|
let dst: PathBuf = self.to_abs_path(dst);
|
||||||
true => PathBuf::from(dst),
|
|
||||||
false => {
|
|
||||||
let mut p: PathBuf = self.wrkdir.clone();
|
|
||||||
p.push(dst);
|
|
||||||
p
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Match entry
|
// Match entry
|
||||||
match entry {
|
match entry {
|
||||||
FsEntry::File(file) => {
|
FsEntry::File(file) => {
|
||||||
@@ -325,7 +312,8 @@ impl Localhost {
|
|||||||
/// Stat file and create a FsEntry
|
/// Stat file and create a FsEntry
|
||||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||||
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
||||||
let attr: Metadata = match fs::metadata(path) {
|
let path: PathBuf = self.to_abs_path(path);
|
||||||
|
let attr: Metadata = match fs::metadata(path.as_path()) {
|
||||||
Ok(metadata) => metadata,
|
Ok(metadata) => metadata,
|
||||||
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
};
|
};
|
||||||
@@ -334,12 +322,12 @@ impl Localhost {
|
|||||||
Ok(match path.is_dir() {
|
Ok(match path.is_dir() {
|
||||||
true => FsEntry::Directory(FsDirectory {
|
true => FsEntry::Directory(FsDirectory {
|
||||||
name: file_name,
|
name: file_name,
|
||||||
abs_path: PathBuf::from(path),
|
abs_path: path.clone(),
|
||||||
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
readonly: attr.permissions().readonly(),
|
readonly: attr.permissions().readonly(),
|
||||||
symlink: match fs::read_link(path) {
|
symlink: match fs::read_link(path.as_path()) {
|
||||||
Ok(p) => match self.stat(p.as_path()) {
|
Ok(p) => match self.stat(p.as_path()) {
|
||||||
Ok(entry) => Some(Box::new(entry)),
|
Ok(entry) => Some(Box::new(entry)),
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
@@ -358,14 +346,14 @@ impl Localhost {
|
|||||||
};
|
};
|
||||||
FsEntry::File(FsFile {
|
FsEntry::File(FsFile {
|
||||||
name: file_name,
|
name: file_name,
|
||||||
abs_path: PathBuf::from(path),
|
abs_path: path.clone(),
|
||||||
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
readonly: attr.permissions().readonly(),
|
readonly: attr.permissions().readonly(),
|
||||||
size: attr.len() as usize,
|
size: attr.len() as usize,
|
||||||
ftype: extension,
|
ftype: extension,
|
||||||
symlink: match fs::read_link(path) {
|
symlink: match fs::read_link(path.as_path()) {
|
||||||
Ok(p) => match self.stat(p.as_path()) {
|
Ok(p) => match self.stat(p.as_path()) {
|
||||||
Ok(entry) => Some(Box::new(entry)),
|
Ok(entry) => Some(Box::new(entry)),
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
@@ -386,7 +374,8 @@ impl Localhost {
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
||||||
let attr: Metadata = match fs::metadata(path) {
|
let path: PathBuf = self.to_abs_path(path);
|
||||||
|
let attr: Metadata = match fs::metadata(path.as_path()) {
|
||||||
Ok(metadata) => metadata,
|
Ok(metadata) => metadata,
|
||||||
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
};
|
};
|
||||||
@@ -395,12 +384,12 @@ impl Localhost {
|
|||||||
Ok(match path.is_dir() {
|
Ok(match path.is_dir() {
|
||||||
true => FsEntry::Directory(FsDirectory {
|
true => FsEntry::Directory(FsDirectory {
|
||||||
name: file_name,
|
name: file_name,
|
||||||
abs_path: PathBuf::from(path),
|
abs_path: path.clone(),
|
||||||
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
readonly: attr.permissions().readonly(),
|
readonly: attr.permissions().readonly(),
|
||||||
symlink: match fs::read_link(path) {
|
symlink: match fs::read_link(path.as_path()) {
|
||||||
Ok(p) => match self.stat(p.as_path()) {
|
Ok(p) => match self.stat(p.as_path()) {
|
||||||
Ok(entry) => Some(Box::new(entry)),
|
Ok(entry) => Some(Box::new(entry)),
|
||||||
Err(_) => None, // Ignore errors
|
Err(_) => None, // Ignore errors
|
||||||
@@ -419,14 +408,14 @@ impl Localhost {
|
|||||||
};
|
};
|
||||||
FsEntry::File(FsFile {
|
FsEntry::File(FsFile {
|
||||||
name: file_name,
|
name: file_name,
|
||||||
abs_path: PathBuf::from(path),
|
abs_path: path.clone(),
|
||||||
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_change_time: attr.modified().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
last_access_time: attr.accessed().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
creation_time: attr.created().unwrap_or(SystemTime::UNIX_EPOCH),
|
||||||
readonly: attr.permissions().readonly(),
|
readonly: attr.permissions().readonly(),
|
||||||
size: attr.len() as usize,
|
size: attr.len() as usize,
|
||||||
ftype: extension,
|
ftype: extension,
|
||||||
symlink: match fs::read_link(path) {
|
symlink: match fs::read_link(path.as_path()) {
|
||||||
Ok(p) => match self.stat(p.as_path()) {
|
Ok(p) => match self.stat(p.as_path()) {
|
||||||
Ok(entry) => Some(Box::new(entry)),
|
Ok(entry) => Some(Box::new(entry)),
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
@@ -446,12 +435,13 @@ impl Localhost {
|
|||||||
/// Change file mode to file, according to UNIX permissions
|
/// Change file mode to file, according to UNIX permissions
|
||||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||||
pub fn chmod(&self, path: &Path, pex: (u8, u8, u8)) -> Result<(), HostError> {
|
pub fn chmod(&self, path: &Path, pex: (u8, u8, u8)) -> Result<(), HostError> {
|
||||||
|
let path: PathBuf = self.to_abs_path(path);
|
||||||
// Get metadta
|
// Get metadta
|
||||||
match fs::metadata(path) {
|
match fs::metadata(path.as_path()) {
|
||||||
Ok(metadata) => {
|
Ok(metadata) => {
|
||||||
let mut mpex = metadata.permissions();
|
let mut mpex = metadata.permissions();
|
||||||
mpex.set_mode(self.mode_to_u32(pex));
|
mpex.set_mode(self.mode_to_u32(pex));
|
||||||
match set_permissions(path, mpex) {
|
match set_permissions(path.as_path(), mpex) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
}
|
}
|
||||||
@@ -464,14 +454,15 @@ impl Localhost {
|
|||||||
///
|
///
|
||||||
/// Open file for read
|
/// Open file for read
|
||||||
pub fn open_file_read(&self, file: &Path) -> Result<File, HostError> {
|
pub fn open_file_read(&self, file: &Path) -> Result<File, HostError> {
|
||||||
if !self.file_exists(file) {
|
let file: PathBuf = self.to_abs_path(file);
|
||||||
|
if !self.file_exists(file.as_path()) {
|
||||||
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
||||||
}
|
}
|
||||||
match OpenOptions::new()
|
match OpenOptions::new()
|
||||||
.create(false)
|
.create(false)
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(false)
|
.write(false)
|
||||||
.open(file)
|
.open(file.as_path())
|
||||||
{
|
{
|
||||||
Ok(f) => Ok(f),
|
Ok(f) => Ok(f),
|
||||||
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
@@ -482,14 +473,15 @@ impl Localhost {
|
|||||||
///
|
///
|
||||||
/// Open file for write
|
/// Open file for write
|
||||||
pub fn open_file_write(&self, file: &Path) -> Result<File, HostError> {
|
pub fn open_file_write(&self, file: &Path) -> Result<File, HostError> {
|
||||||
|
let file: PathBuf = self.to_abs_path(file);
|
||||||
match OpenOptions::new()
|
match OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.open(file)
|
.open(file.as_path())
|
||||||
{
|
{
|
||||||
Ok(f) => Ok(f),
|
Ok(f) => Ok(f),
|
||||||
Err(err) => match self.file_exists(file) {
|
Err(err) => match self.file_exists(file.as_path()) {
|
||||||
true => Err(HostError::new(HostErrorType::ReadonlyFile, Some(err))),
|
true => Err(HostError::new(HostErrorType::ReadonlyFile, Some(err))),
|
||||||
false => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
false => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
},
|
},
|
||||||
@@ -541,6 +533,21 @@ impl Localhost {
|
|||||||
fn mode_to_u32(&self, mode: (u8, u8, u8)) -> u32 {
|
fn mode_to_u32(&self, mode: (u8, u8, u8)) -> u32 {
|
||||||
((mode.0 as u32) << 6) + ((mode.1 as u32) << 3) + mode.2 as u32
|
((mode.0 as u32) << 6) + ((mode.1 as u32) << 3) + mode.2 as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### to_abs_path
|
||||||
|
///
|
||||||
|
/// Convert path to absolute path
|
||||||
|
fn to_abs_path(&self, p: &Path) -> PathBuf {
|
||||||
|
// Convert to abs path
|
||||||
|
match p.is_relative() {
|
||||||
|
true => {
|
||||||
|
let mut path: PathBuf = self.wrkdir.clone();
|
||||||
|
path.push(p);
|
||||||
|
path
|
||||||
|
}
|
||||||
|
false => PathBuf::from(p),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -623,7 +630,7 @@ mod tests {
|
|||||||
fn test_host_localhost_change_dir() {
|
fn test_host_localhost_change_dir() {
|
||||||
let mut host: Localhost = Localhost::new(PathBuf::from("/dev")).ok().unwrap();
|
let mut host: Localhost = Localhost::new(PathBuf::from("/dev")).ok().unwrap();
|
||||||
let new_dir: PathBuf = PathBuf::from("/dev");
|
let new_dir: PathBuf = PathBuf::from("/dev");
|
||||||
assert!(host.change_wrkdir(new_dir.clone()).is_ok());
|
assert!(host.change_wrkdir(new_dir.as_path()).is_ok());
|
||||||
// Verify new files
|
// Verify new files
|
||||||
// Scan dir
|
// Scan dir
|
||||||
let entries = std::fs::read_dir(PathBuf::from(new_dir).as_path()).unwrap();
|
let entries = std::fs::read_dir(PathBuf::from(new_dir).as_path()).unwrap();
|
||||||
@@ -640,7 +647,7 @@ mod tests {
|
|||||||
fn test_host_localhost_change_dir_failed() {
|
fn test_host_localhost_change_dir_failed() {
|
||||||
let mut host: Localhost = Localhost::new(PathBuf::from("/bin")).ok().unwrap();
|
let mut host: Localhost = Localhost::new(PathBuf::from("/bin")).ok().unwrap();
|
||||||
let new_dir: PathBuf = PathBuf::from("/omar/gabber/123/456");
|
let new_dir: PathBuf = PathBuf::from("/omar/gabber/123/456");
|
||||||
assert!(host.change_wrkdir(new_dir.clone()).is_ok());
|
assert!(host.change_wrkdir(new_dir.as_path()).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -931,6 +938,7 @@ mod tests {
|
|||||||
// Verify dir_dest contains foo.txt
|
// Verify dir_dest contains foo.txt
|
||||||
let mut test_file_path: PathBuf = dir_dest.clone();
|
let mut test_file_path: PathBuf = dir_dest.clone();
|
||||||
test_file_path.push("foo.txt");
|
test_file_path.push("foo.txt");
|
||||||
|
println!("{:?}", host.scan_dir(tmpdir.path()).ok().unwrap());
|
||||||
assert!(host.stat(test_file_path.as_path()).is_ok());
|
assert!(host.stat(test_file_path.as_path()).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -655,13 +655,7 @@ impl FileTransferActivity {
|
|||||||
// Get current directory
|
// Get current directory
|
||||||
let prev_dir: PathBuf = self.local.wrkdir.clone();
|
let prev_dir: PathBuf = self.local.wrkdir.clone();
|
||||||
// Change directory
|
// Change directory
|
||||||
match self
|
match self.context.as_mut().unwrap().local.change_wrkdir(path) {
|
||||||
.context
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.local
|
|
||||||
.change_wrkdir(PathBuf::from(path))
|
|
||||||
{
|
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
self.log(
|
self.log(
|
||||||
LogLevel::Info,
|
LogLevel::Info,
|
||||||
|
|||||||
Reference in New Issue
Block a user