Apply file mode of file downloaded from remote
This commit is contained in:
parent
50b523f9f4
commit
900d9ac3c6
|
@ -19,6 +19,8 @@ Released on ??
|
|||
- Linux: `/home/alice/.config/termscp/bookmarks.toml`
|
||||
- Windows: `C:\Users\Alice\AppData\Roaming\termscp\bookmarks.toml`
|
||||
- MacOS: `/Users/Alice/Library/Application Support/termscp/bookmarks.toml`
|
||||
- Bugfix:
|
||||
- File mode of file on remote is now reported on local file after being downloaded (unix, linux, macos only)
|
||||
|
||||
## 0.1.3
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
use std::fs::{self, File, Metadata, OpenOptions};
|
||||
use std::fs::{self, File, Metadata, OpenOptions, set_permissions};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
// Metadata ext
|
||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
|
||||
// Locals
|
||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
||||
|
@ -379,6 +379,25 @@ impl Localhost {
|
|||
})
|
||||
}
|
||||
|
||||
/// ### chmod
|
||||
///
|
||||
/// Change file mode to file, according to UNIX permissions
|
||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||
pub fn chmod(&self, path: &Path, pex: (u8, u8, u8)) -> Result<(), HostError> {
|
||||
// Get metadta
|
||||
match fs::metadata(path) {
|
||||
Ok(metadata) => {
|
||||
let mut mpex = metadata.permissions();
|
||||
mpex.set_mode(self.mode_to_u32(pex));
|
||||
match set_permissions(path, mpex) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||
}
|
||||
}
|
||||
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||
}
|
||||
}
|
||||
|
||||
/// ### open_file_read
|
||||
///
|
||||
/// Open file for read
|
||||
|
@ -452,6 +471,14 @@ impl Localhost {
|
|||
let others: u8 = (mode & 0x7) as u8;
|
||||
(user, group, others)
|
||||
}
|
||||
|
||||
/// mode_to_u32
|
||||
///
|
||||
/// Convert owner,group,others to u32
|
||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||
fn mode_to_u32(&self, mode: (u8, u8, u8)) -> u32 {
|
||||
((mode.0 as u32) << 6) + ((mode.1 as u32) << 3) + mode.2 as u32
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -720,6 +747,25 @@ mod tests {
|
|||
.is_err());
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_host_chmod() {
|
||||
let tmpdir: tempfile::TempDir = tempfile::TempDir::new().unwrap();
|
||||
let file: tempfile::NamedTempFile = create_sample_file();
|
||||
let host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
|
||||
// mode_to_u32
|
||||
assert_eq!(host.mode_to_u32((6, 4, 4)), 0o644);
|
||||
assert_eq!(host.mode_to_u32((7, 7, 5)), 0o775);
|
||||
// Chmod to file
|
||||
assert!(host.chmod(file.path(), (7, 7, 5)).is_ok());
|
||||
// Chmod to dir
|
||||
assert!(host.chmod(tmpdir.path(), (7, 5, 0)).is_ok());
|
||||
// Error
|
||||
assert!(host
|
||||
.chmod(Path::new("/tmp/krgiogoiegj/kwrgnoerig"), (7, 7, 7))
|
||||
.is_err());
|
||||
}
|
||||
|
||||
/// ### create_sample_file
|
||||
///
|
||||
/// Create a sample file
|
||||
|
|
|
@ -518,6 +518,32 @@ impl FileTransferActivity {
|
|||
.as_str(),
|
||||
);
|
||||
}
|
||||
// Apply file mode to file
|
||||
#[cfg(any(
|
||||
target_os = "unix",
|
||||
target_os = "macos",
|
||||
target_os = "linux"
|
||||
))]
|
||||
if let Some(pex) = file.unix_pex {
|
||||
if let Err(err) = self
|
||||
.context
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.local
|
||||
.chmod(local_file_path.as_path(), pex)
|
||||
{
|
||||
self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not apply file mode {:?} to \"{}\": {}",
|
||||
pex,
|
||||
local_file_path.display(),
|
||||
err
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
}
|
||||
// Log
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
|
@ -588,6 +614,28 @@ impl FileTransferActivity {
|
|||
.mkdir_ex(local_dir_path.as_path(), true)
|
||||
{
|
||||
Ok(_) => {
|
||||
// Apply file mode to directory
|
||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
||||
if let Some(pex) = dir.unix_pex {
|
||||
if let Err(err) = self
|
||||
.context
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.local
|
||||
.chmod(local_dir_path.as_path(), pex)
|
||||
{
|
||||
self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not apply file mode {:?} to \"{}\": {}",
|
||||
pex,
|
||||
local_dir_path.display(),
|
||||
err
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
}
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
format!("Created directory \"{}\"", local_dir_path.display()).as_ref(),
|
||||
|
|
Loading…
Reference in a new issue