mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
Apply file mode of file downloaded from remote
This commit is contained in:
@@ -19,6 +19,8 @@ Released on ??
|
|||||||
- Linux: `/home/alice/.config/termscp/bookmarks.toml`
|
- Linux: `/home/alice/.config/termscp/bookmarks.toml`
|
||||||
- Windows: `C:\Users\Alice\AppData\Roaming\termscp\bookmarks.toml`
|
- Windows: `C:\Users\Alice\AppData\Roaming\termscp\bookmarks.toml`
|
||||||
- MacOS: `/Users/Alice/Library/Application Support/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
|
## 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::path::{Path, PathBuf};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
// Metadata ext
|
// Metadata ext
|
||||||
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
|
#[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
|
// Locals
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
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_read
|
||||||
///
|
///
|
||||||
/// Open file for read
|
/// Open file for read
|
||||||
@@ -452,6 +471,14 @@ impl Localhost {
|
|||||||
let others: u8 = (mode & 0x7) as u8;
|
let others: u8 = (mode & 0x7) as u8;
|
||||||
(user, group, others)
|
(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)]
|
#[cfg(test)]
|
||||||
@@ -720,6 +747,25 @@ mod tests {
|
|||||||
.is_err());
|
.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_sample_file
|
||||||
///
|
///
|
||||||
/// Create a sample file
|
/// Create a sample file
|
||||||
|
|||||||
@@ -518,6 +518,32 @@ impl FileTransferActivity {
|
|||||||
.as_str(),
|
.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
|
// Log
|
||||||
self.log(
|
self.log(
|
||||||
LogLevel::Info,
|
LogLevel::Info,
|
||||||
@@ -588,6 +614,28 @@ impl FileTransferActivity {
|
|||||||
.mkdir_ex(local_dir_path.as_path(), true)
|
.mkdir_ex(local_dir_path.as_path(), true)
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
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(
|
self.log(
|
||||||
LogLevel::Info,
|
LogLevel::Info,
|
||||||
format!("Created directory \"{}\"", local_dir_path.display()).as_ref(),
|
format!("Created directory \"{}\"", local_dir_path.display()).as_ref(),
|
||||||
|
|||||||
Reference in New Issue
Block a user