Replaced u8 pex with UnixPex struct
This commit is contained in:
parent
32ab0267fb
commit
92b081c076
|
@ -26,7 +26,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType};
|
use super::{FileTransfer, FileTransferError, FileTransferErrorType};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
||||||
use crate::utils::fmt::shadow_password;
|
use crate::utils::fmt::shadow_password;
|
||||||
|
|
||||||
// Includes
|
// Includes
|
||||||
|
@ -158,32 +158,25 @@ impl FtpFileTransfer {
|
||||||
/// ### query_unix_pex
|
/// ### query_unix_pex
|
||||||
///
|
///
|
||||||
/// Returns unix pex in tuple of values
|
/// Returns unix pex in tuple of values
|
||||||
fn query_unix_pex(f: &File) -> (u8, u8, u8) {
|
fn query_unix_pex(f: &File) -> (UnixPex, UnixPex, UnixPex) {
|
||||||
(
|
(
|
||||||
Self::pex_to_byte(
|
UnixPex::new(
|
||||||
f.can_read(PosixPexQuery::Owner),
|
f.can_read(PosixPexQuery::Owner),
|
||||||
f.can_write(PosixPexQuery::Owner),
|
f.can_write(PosixPexQuery::Owner),
|
||||||
f.can_execute(PosixPexQuery::Owner),
|
f.can_execute(PosixPexQuery::Owner),
|
||||||
),
|
),
|
||||||
Self::pex_to_byte(
|
UnixPex::new(
|
||||||
f.can_read(PosixPexQuery::Group),
|
f.can_read(PosixPexQuery::Group),
|
||||||
f.can_write(PosixPexQuery::Group),
|
f.can_write(PosixPexQuery::Group),
|
||||||
f.can_execute(PosixPexQuery::Group),
|
f.can_execute(PosixPexQuery::Group),
|
||||||
),
|
),
|
||||||
Self::pex_to_byte(
|
UnixPex::new(
|
||||||
f.can_read(PosixPexQuery::Others),
|
f.can_read(PosixPexQuery::Others),
|
||||||
f.can_write(PosixPexQuery::Others),
|
f.can_write(PosixPexQuery::Others),
|
||||||
f.can_execute(PosixPexQuery::Others),
|
f.can_execute(PosixPexQuery::Others),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### pex_to_byte
|
|
||||||
///
|
|
||||||
/// Convert unix permissions to byte value
|
|
||||||
fn pex_to_byte(read: bool, write: bool, exec: bool) -> u8 {
|
|
||||||
((read as u8) << 2) + ((write as u8) << 1) + (exec as u8)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileTransfer for FtpFileTransfer {
|
impl FileTransfer for FtpFileTransfer {
|
||||||
|
@ -775,7 +768,7 @@ mod tests {
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert!(ftp
|
assert!(ftp
|
||||||
.rename(&dummy, PathBuf::from("/a/b/c").as_path())
|
.rename(&dummy, PathBuf::from("/a/b/c").as_path())
|
||||||
|
@ -874,7 +867,10 @@ mod tests {
|
||||||
assert!(file.symlink.is_none());
|
assert!(file.symlink.is_none());
|
||||||
assert_eq!(file.user, None);
|
assert_eq!(file.user, None);
|
||||||
assert_eq!(file.group, None);
|
assert_eq!(file.group, None);
|
||||||
assert_eq!(file.unix_pex.unwrap(), (6, 6, 4));
|
assert_eq!(
|
||||||
|
file.unix_pex.unwrap(),
|
||||||
|
(UnixPex::from(6), UnixPex::from(6), UnixPex::from(4))
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
file.last_access_time
|
file.last_access_time
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
|
@ -930,7 +926,7 @@ mod tests {
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
};
|
};
|
||||||
let mut ftp: FtpFileTransfer = FtpFileTransfer::new(false);
|
let mut ftp: FtpFileTransfer = FtpFileTransfer::new(false);
|
||||||
assert!(ftp.change_dir(Path::new("/tmp")).is_err());
|
assert!(ftp.change_dir(Path::new("/tmp")).is_err());
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
// Locals
|
// Locals
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType};
|
use super::{FileTransfer, FileTransferError, FileTransferErrorType};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
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};
|
||||||
use crate::utils::parser::parse_lstime;
|
use crate::utils::parser::parse_lstime;
|
||||||
|
@ -128,7 +128,11 @@ impl ScpFileTransfer {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get unix pex
|
// Get unix pex
|
||||||
let unix_pex = (pex(0..3), pex(3..6), pex(6..9));
|
let unix_pex = (
|
||||||
|
UnixPex::from(pex(0..3)),
|
||||||
|
UnixPex::from(pex(3..6)),
|
||||||
|
UnixPex::from(pex(6..9)),
|
||||||
|
);
|
||||||
|
|
||||||
// Parse mtime and convert to SystemTime
|
// Parse mtime and convert to SystemTime
|
||||||
let mtime: SystemTime = match parse_lstime(
|
let mtime: SystemTime = match parse_lstime(
|
||||||
|
@ -873,7 +877,11 @@ impl FileTransfer for ScpFileTransfer {
|
||||||
// Calculate file mode
|
// Calculate file mode
|
||||||
let mode: i32 = match local.unix_pex {
|
let mode: i32 = match local.unix_pex {
|
||||||
None => 0o644,
|
None => 0o644,
|
||||||
Some((u, g, o)) => ((u as i32) << 6) + ((g as i32) << 3) + (o as i32),
|
Some((u, g, o)) => {
|
||||||
|
((u.as_byte() as i32) << 6)
|
||||||
|
+ ((g.as_byte() as i32) << 3)
|
||||||
|
+ (o.as_byte() as i32)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Calculate mtime, atime
|
// Calculate mtime, atime
|
||||||
let times: (u64, u64) = {
|
let times: (u64, u64) = {
|
||||||
|
@ -1126,7 +1134,7 @@ mod tests {
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert!(client
|
assert!(client
|
||||||
.rename(&dummy, PathBuf::from("/a/b/c").as_path())
|
.rename(&dummy, PathBuf::from("/a/b/c").as_path())
|
||||||
|
@ -1239,7 +1247,10 @@ mod tests {
|
||||||
.unwrap_file();
|
.unwrap_file();
|
||||||
assert_eq!(entry.name.as_str(), "Cargo.toml");
|
assert_eq!(entry.name.as_str(), "Cargo.toml");
|
||||||
assert_eq!(entry.abs_path, PathBuf::from("/tmp/Cargo.toml"));
|
assert_eq!(entry.abs_path, PathBuf::from("/tmp/Cargo.toml"));
|
||||||
assert_eq!(entry.unix_pex.unwrap(), (6, 4, 4));
|
assert_eq!(
|
||||||
|
entry.unix_pex.unwrap(),
|
||||||
|
(UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))
|
||||||
|
);
|
||||||
assert_eq!(entry.size, 2056);
|
assert_eq!(entry.size, 2056);
|
||||||
assert_eq!(entry.ftype.unwrap().as_str(), "toml");
|
assert_eq!(entry.ftype.unwrap().as_str(), "toml");
|
||||||
assert!(entry.symlink.is_none());
|
assert!(entry.symlink.is_none());
|
||||||
|
@ -1254,7 +1265,10 @@ mod tests {
|
||||||
.unwrap_file();
|
.unwrap_file();
|
||||||
assert_eq!(entry.name.as_str(), "CODE_OF_CONDUCT.md");
|
assert_eq!(entry.name.as_str(), "CODE_OF_CONDUCT.md");
|
||||||
assert_eq!(entry.abs_path, PathBuf::from("/tmp/CODE_OF_CONDUCT.md"));
|
assert_eq!(entry.abs_path, PathBuf::from("/tmp/CODE_OF_CONDUCT.md"));
|
||||||
assert_eq!(entry.unix_pex.unwrap(), (6, 6, 6));
|
assert_eq!(
|
||||||
|
entry.unix_pex.unwrap(),
|
||||||
|
(UnixPex::from(6), UnixPex::from(6), UnixPex::from(6))
|
||||||
|
);
|
||||||
assert_eq!(entry.size, 3368);
|
assert_eq!(entry.size, 3368);
|
||||||
assert_eq!(entry.ftype.unwrap().as_str(), "md");
|
assert_eq!(entry.ftype.unwrap().as_str(), "md");
|
||||||
assert!(entry.symlink.is_none());
|
assert!(entry.symlink.is_none());
|
||||||
|
@ -1269,7 +1283,10 @@ mod tests {
|
||||||
.unwrap_dir();
|
.unwrap_dir();
|
||||||
assert_eq!(entry.name.as_str(), "docs");
|
assert_eq!(entry.name.as_str(), "docs");
|
||||||
assert_eq!(entry.abs_path, PathBuf::from("/tmp/docs"));
|
assert_eq!(entry.abs_path, PathBuf::from("/tmp/docs"));
|
||||||
assert_eq!(entry.unix_pex.unwrap(), (7, 5, 5));
|
assert_eq!(
|
||||||
|
entry.unix_pex.unwrap(),
|
||||||
|
(UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))
|
||||||
|
);
|
||||||
assert!(entry.symlink.is_none());
|
assert!(entry.symlink.is_none());
|
||||||
// Short metadata
|
// Short metadata
|
||||||
assert!(client
|
assert!(client
|
||||||
|
@ -1320,7 +1337,7 @@ mod tests {
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
};
|
};
|
||||||
let mut scp: ScpFileTransfer = ScpFileTransfer::new(SshKeyStorage::empty());
|
let mut scp: ScpFileTransfer = ScpFileTransfer::new(SshKeyStorage::empty());
|
||||||
assert!(scp.change_dir(Path::new("/tmp")).is_err());
|
assert!(scp.change_dir(Path::new("/tmp")).is_err());
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
// Locals
|
// Locals
|
||||||
use super::{FileTransfer, FileTransferError, FileTransferErrorType};
|
use super::{FileTransfer, FileTransferError, FileTransferErrorType};
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
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};
|
||||||
|
|
||||||
|
@ -126,11 +126,11 @@ impl SftpFileTransfer {
|
||||||
.map(|ext| String::from(ext.to_str().unwrap_or("")));
|
.map(|ext| String::from(ext.to_str().unwrap_or("")));
|
||||||
let uid: Option<u32> = metadata.uid;
|
let uid: Option<u32> = metadata.uid;
|
||||||
let gid: Option<u32> = metadata.gid;
|
let gid: Option<u32> = metadata.gid;
|
||||||
let pex: Option<(u8, u8, u8)> = metadata.perm.map(|x| {
|
let pex: Option<(UnixPex, UnixPex, UnixPex)> = metadata.perm.map(|x| {
|
||||||
(
|
(
|
||||||
((x >> 6) & 0x7) as u8,
|
UnixPex::from(((x >> 6) & 0x7) as u8),
|
||||||
((x >> 3) & 0x7) as u8,
|
UnixPex::from(((x >> 3) & 0x7) as u8),
|
||||||
(x & 0x7) as u8,
|
UnixPex::from((x & 0x7) as u8),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let size: u64 = metadata.size.unwrap_or(0);
|
let size: u64 = metadata.size.unwrap_or(0);
|
||||||
|
@ -720,7 +720,7 @@ impl FileTransfer for SftpFileTransfer {
|
||||||
// Calculate file mode
|
// Calculate file mode
|
||||||
let mode: i32 = match local.unix_pex {
|
let mode: i32 = match local.unix_pex {
|
||||||
None => 0o644,
|
None => 0o644,
|
||||||
Some((u, g, o)) => ((u as i32) << 6) + ((g as i32) << 3) + (o as i32),
|
Some((u, g, o)) => ((u.as_byte() as i32) << 6) + ((g.as_byte() as i32) << 3) + (o.as_byte() as i32),
|
||||||
};
|
};
|
||||||
debug!("File mode {:?}", mode);
|
debug!("File mode {:?}", mode);
|
||||||
match sftp.open_mode(
|
match sftp.open_mode(
|
||||||
|
@ -924,7 +924,7 @@ mod tests {
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert!(client
|
assert!(client
|
||||||
.rename(&dummy, PathBuf::from("/a/b/c").as_path())
|
.rename(&dummy, PathBuf::from("/a/b/c").as_path())
|
||||||
|
@ -1072,7 +1072,7 @@ mod tests {
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
};
|
};
|
||||||
let mut sftp: SftpFileTransfer = SftpFileTransfer::new(SshKeyStorage::empty());
|
let mut sftp: SftpFileTransfer = SftpFileTransfer::new(SshKeyStorage::empty());
|
||||||
assert!(sftp.change_dir(Path::new("/tmp")).is_err());
|
assert!(sftp.change_dir(Path::new("/tmp")).is_err());
|
||||||
|
|
|
@ -354,7 +354,9 @@ impl Formatter {
|
||||||
pex.push(file_type);
|
pex.push(file_type);
|
||||||
match fsentry.get_unix_pex() {
|
match fsentry.get_unix_pex() {
|
||||||
None => pex.push_str("?????????"),
|
None => pex.push_str("?????????"),
|
||||||
Some((owner, group, others)) => pex.push_str(fmt_pex(owner, group, others).as_str()),
|
Some((owner, group, others)) => pex.push_str(
|
||||||
|
format!("{}{}{}", fmt_pex(owner), fmt_pex(group), fmt_pex(others)).as_str(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
// Add to cur str, prefix and the key value
|
// Add to cur str, prefix and the key value
|
||||||
format!("{}{}{:10}", cur_str, prefix, pex)
|
format!("{}{}{:10}", cur_str, prefix, pex)
|
||||||
|
@ -533,7 +535,7 @@ impl Formatter {
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::fs::{FsDirectory, FsFile};
|
use crate::fs::{FsDirectory, FsFile, UnixPex};
|
||||||
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -553,10 +555,10 @@ mod tests {
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
let prefix: String = String::from("h");
|
let prefix: String = String::from("h");
|
||||||
let mut callchain: CallChainBlock = CallChainBlock::new(dummy_fmt, prefix, None, None);
|
let mut callchain: CallChainBlock = CallChainBlock::new(dummy_fmt, prefix, None, None);
|
||||||
|
@ -593,10 +595,10 @@ mod tests {
|
||||||
creation_time: t,
|
creation_time: t,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -623,10 +625,10 @@ mod tests {
|
||||||
creation_time: t,
|
creation_time: t,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -718,10 +720,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -797,7 +799,7 @@ mod tests {
|
||||||
symlink: Some(Box::new(pointer)), // UNIX only
|
symlink: Some(Box::new(pointer)), // UNIX only
|
||||||
user: None, // UNIX only
|
user: None, // UNIX only
|
||||||
group: None, // UNIX only
|
group: None, // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(formatter.fmt(&entry), format!(
|
assert_eq!(formatter.fmt(&entry), format!(
|
||||||
"projects/ -> project.info 0 0 lrwxr-xr-x {} {} {}",
|
"projects/ -> project.info 0 0 lrwxr-xr-x {} {} {}",
|
||||||
|
@ -812,10 +814,10 @@ mod tests {
|
||||||
last_change_time: t,
|
last_change_time: t,
|
||||||
last_access_time: t,
|
last_access_time: t,
|
||||||
creation_time: t,
|
creation_time: t,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: None, // UNIX only
|
user: None, // UNIX only
|
||||||
group: None, // UNIX only
|
group: None, // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(formatter.fmt(&entry), format!(
|
assert_eq!(formatter.fmt(&entry), format!(
|
||||||
"projects/ 0 0 drwxr-xr-x {} {} {}",
|
"projects/ 0 0 drwxr-xr-x {} {} {}",
|
||||||
|
@ -848,7 +850,7 @@ mod tests {
|
||||||
symlink: Some(Box::new(pointer)), // UNIX only
|
symlink: Some(Box::new(pointer)), // UNIX only
|
||||||
user: None, // UNIX only
|
user: None, // UNIX only
|
||||||
group: None, // UNIX only
|
group: None, // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(formatter.fmt(&entry), format!(
|
assert_eq!(formatter.fmt(&entry), format!(
|
||||||
"bar.txt -> project.info 0 0 lrw-r--r-- 8.2 KB {} {} {}",
|
"bar.txt -> project.info 0 0 lrw-r--r-- 8.2 KB {} {} {}",
|
||||||
|
@ -865,10 +867,10 @@ mod tests {
|
||||||
creation_time: t,
|
creation_time: t,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: None, // UNIX only
|
user: None, // UNIX only
|
||||||
group: None, // UNIX only
|
group: None, // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(formatter.fmt(&entry), format!(
|
assert_eq!(formatter.fmt(&entry), format!(
|
||||||
"bar.txt 0 0 -rw-r--r-- 8.2 KB {} {} {}",
|
"bar.txt 0 0 -rw-r--r-- 8.2 KB {} {} {}",
|
||||||
|
|
|
@ -363,7 +363,7 @@ impl FromStr for GroupDirs {
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::fs::{FsDirectory, FsFile};
|
use crate::fs::{FsDirectory, FsFile, UnixPex};
|
||||||
use crate::utils::fmt::fmt_time;
|
use crate::utils::fmt::fmt_time;
|
||||||
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
@ -587,10 +587,10 @@ mod tests {
|
||||||
creation_time: t,
|
creation_time: t,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -669,11 +669,11 @@ mod tests {
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 64,
|
size: 64,
|
||||||
ftype: None, // File type
|
ftype: None, // File type
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
}),
|
}),
|
||||||
true => FsEntry::Directory(FsDirectory {
|
true => FsEntry::Directory(FsDirectory {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
@ -681,10 +681,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,11 +699,11 @@ mod tests {
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: size,
|
size: size,
|
||||||
ftype: None, // File type
|
ftype: None, // File type
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
}),
|
}),
|
||||||
true => FsEntry::Directory(FsDirectory {
|
true => FsEntry::Directory(FsDirectory {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
@ -711,10 +711,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
199
src/fs/mod.rs
199
src/fs/mod.rs
|
@ -52,10 +52,10 @@ pub struct FsDirectory {
|
||||||
pub last_change_time: SystemTime,
|
pub last_change_time: SystemTime,
|
||||||
pub last_access_time: SystemTime,
|
pub last_access_time: SystemTime,
|
||||||
pub creation_time: SystemTime,
|
pub creation_time: SystemTime,
|
||||||
pub symlink: Option<Box<FsEntry>>, // UNIX only
|
pub symlink: Option<Box<FsEntry>>, // UNIX only
|
||||||
pub user: Option<u32>, // UNIX only
|
pub user: Option<u32>, // UNIX only
|
||||||
pub group: Option<u32>, // UNIX only
|
pub group: Option<u32>, // UNIX only
|
||||||
pub unix_pex: Option<(u8, u8, u8)>, // UNIX only
|
pub unix_pex: Option<(UnixPex, UnixPex, UnixPex)>, // UNIX only
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### FsFile
|
/// ### FsFile
|
||||||
|
@ -70,11 +70,72 @@ pub struct FsFile {
|
||||||
pub last_access_time: SystemTime,
|
pub last_access_time: SystemTime,
|
||||||
pub creation_time: SystemTime,
|
pub creation_time: SystemTime,
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
pub ftype: Option<String>, // File type
|
pub ftype: Option<String>, // File type
|
||||||
pub symlink: Option<Box<FsEntry>>, // UNIX only
|
pub symlink: Option<Box<FsEntry>>, // UNIX only
|
||||||
pub user: Option<u32>, // UNIX only
|
pub user: Option<u32>, // UNIX only
|
||||||
pub group: Option<u32>, // UNIX only
|
pub group: Option<u32>, // UNIX only
|
||||||
pub unix_pex: Option<(u8, u8, u8)>, // UNIX only
|
pub unix_pex: Option<(UnixPex, UnixPex, UnixPex)>, // UNIX only
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ## UnixPex
|
||||||
|
///
|
||||||
|
/// Describes the permissions on POSIX system.
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
pub struct UnixPex {
|
||||||
|
read: bool,
|
||||||
|
write: bool,
|
||||||
|
execute: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnixPex {
|
||||||
|
/// ### new
|
||||||
|
///
|
||||||
|
/// Instantiates a new `UnixPex`
|
||||||
|
pub fn new(read: bool, write: bool, execute: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
read,
|
||||||
|
write,
|
||||||
|
execute,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### can_read
|
||||||
|
///
|
||||||
|
/// Returns whether user can read
|
||||||
|
pub fn can_read(&self) -> bool {
|
||||||
|
self.read
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### can_write
|
||||||
|
///
|
||||||
|
/// Returns whether user can write
|
||||||
|
pub fn can_write(&self) -> bool {
|
||||||
|
self.write
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### can_execute
|
||||||
|
///
|
||||||
|
/// Returns whether user can execute
|
||||||
|
pub fn can_execute(&self) -> bool {
|
||||||
|
self.execute
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### as_byte
|
||||||
|
///
|
||||||
|
/// Convert permission to byte as on POSIX systems
|
||||||
|
pub fn as_byte(&self) -> u8 {
|
||||||
|
((self.read as u8) << 2) + ((self.write as u8) << 1) + (self.execute as u8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for UnixPex {
|
||||||
|
fn from(bits: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
read: ((bits >> 2) & 0x01) != 0,
|
||||||
|
write: ((bits >> 1) & 0x01) != 0,
|
||||||
|
execute: (bits & 0x01) != 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FsEntry {
|
impl FsEntry {
|
||||||
|
@ -171,7 +232,7 @@ impl FsEntry {
|
||||||
/// ### get_unix_pex
|
/// ### get_unix_pex
|
||||||
///
|
///
|
||||||
/// Get unix pex from `FsEntry`
|
/// Get unix pex from `FsEntry`
|
||||||
pub fn get_unix_pex(&self) -> Option<(u8, u8, u8)> {
|
pub fn get_unix_pex(&self) -> Option<(UnixPex, UnixPex, UnixPex)> {
|
||||||
match self {
|
match self {
|
||||||
FsEntry::Directory(dir) => dir.unix_pex,
|
FsEntry::Directory(dir) => dir.unix_pex,
|
||||||
FsEntry::File(file) => file.unix_pex,
|
FsEntry::File(file) => file.unix_pex,
|
||||||
|
@ -262,10 +323,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(entry.get_abs_path(), PathBuf::from("/foo"));
|
assert_eq!(entry.get_abs_path(), PathBuf::from("/foo"));
|
||||||
assert_eq!(entry.get_name(), String::from("foo"));
|
assert_eq!(entry.get_name(), String::from("foo"));
|
||||||
|
@ -279,7 +340,10 @@ mod tests {
|
||||||
assert_eq!(entry.is_symlink(), false);
|
assert_eq!(entry.is_symlink(), false);
|
||||||
assert_eq!(entry.is_dir(), true);
|
assert_eq!(entry.is_dir(), true);
|
||||||
assert_eq!(entry.is_file(), false);
|
assert_eq!(entry.is_file(), false);
|
||||||
assert_eq!(entry.get_unix_pex(), Some((7, 5, 5)));
|
assert_eq!(
|
||||||
|
entry.get_unix_pex(),
|
||||||
|
Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5)))
|
||||||
|
);
|
||||||
assert_eq!(entry.unwrap_dir().abs_path, PathBuf::from("/foo"));
|
assert_eq!(entry.unwrap_dir().abs_path, PathBuf::from("/foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,10 +358,10 @@ mod tests {
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(entry.get_abs_path(), PathBuf::from("/bar.txt"));
|
assert_eq!(entry.get_abs_path(), PathBuf::from("/bar.txt"));
|
||||||
assert_eq!(entry.get_name(), String::from("bar.txt"));
|
assert_eq!(entry.get_name(), String::from("bar.txt"));
|
||||||
|
@ -308,7 +372,10 @@ mod tests {
|
||||||
assert_eq!(entry.get_ftype(), Some(String::from("txt")));
|
assert_eq!(entry.get_ftype(), Some(String::from("txt")));
|
||||||
assert_eq!(entry.get_user(), Some(0));
|
assert_eq!(entry.get_user(), Some(0));
|
||||||
assert_eq!(entry.get_group(), Some(0));
|
assert_eq!(entry.get_group(), Some(0));
|
||||||
assert_eq!(entry.get_unix_pex(), Some((6, 4, 4)));
|
assert_eq!(
|
||||||
|
entry.get_unix_pex(),
|
||||||
|
Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4)))
|
||||||
|
);
|
||||||
assert_eq!(entry.is_symlink(), false);
|
assert_eq!(entry.is_symlink(), false);
|
||||||
assert_eq!(entry.is_dir(), false);
|
assert_eq!(entry.is_dir(), false);
|
||||||
assert_eq!(entry.is_file(), true);
|
assert_eq!(entry.is_file(), true);
|
||||||
|
@ -327,10 +394,10 @@ mod tests {
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
entry.unwrap_dir();
|
entry.unwrap_dir();
|
||||||
}
|
}
|
||||||
|
@ -345,10 +412,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
entry.unwrap_file();
|
entry.unwrap_file();
|
||||||
}
|
}
|
||||||
|
@ -364,10 +431,10 @@ mod tests {
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(entry.is_hidden(), false);
|
assert_eq!(entry.is_hidden(), false);
|
||||||
let entry: FsEntry = FsEntry::File(FsFile {
|
let entry: FsEntry = FsEntry::File(FsFile {
|
||||||
|
@ -378,10 +445,10 @@ mod tests {
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(entry.is_hidden(), true);
|
assert_eq!(entry.is_hidden(), true);
|
||||||
let entry: FsEntry = FsEntry::Directory(FsDirectory {
|
let entry: FsEntry = FsEntry::Directory(FsDirectory {
|
||||||
|
@ -390,10 +457,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(entry.is_hidden(), true);
|
assert_eq!(entry.is_hidden(), true);
|
||||||
}
|
}
|
||||||
|
@ -410,10 +477,10 @@ mod tests {
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
size: 8192,
|
size: 8192,
|
||||||
ftype: Some(String::from("txt")),
|
ftype: Some(String::from("txt")),
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
});
|
});
|
||||||
// Symlink is None...
|
// Symlink is None...
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -427,10 +494,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 5, 5)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(5), UnixPex::from(5))), // UNIX only
|
||||||
});
|
});
|
||||||
assert_eq!(entry.get_realfile().get_abs_path(), PathBuf::from("/foo"));
|
assert_eq!(entry.get_realfile().get_abs_path(), PathBuf::from("/foo"));
|
||||||
}
|
}
|
||||||
|
@ -446,10 +513,10 @@ mod tests {
|
||||||
last_change_time: t_now,
|
last_change_time: t_now,
|
||||||
last_access_time: t_now,
|
last_access_time: t_now,
|
||||||
creation_time: t_now,
|
creation_time: t_now,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((7, 7, 7)), // UNIX only
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(7), UnixPex::from(7))), // UNIX only
|
||||||
});
|
});
|
||||||
let entry_child: FsEntry = FsEntry::Directory(FsDirectory {
|
let entry_child: FsEntry = FsEntry::Directory(FsDirectory {
|
||||||
name: String::from("projects"),
|
name: String::from("projects"),
|
||||||
|
@ -460,7 +527,7 @@ mod tests {
|
||||||
symlink: Some(Box::new(entry_target)),
|
symlink: Some(Box::new(entry_target)),
|
||||||
user: Some(0),
|
user: Some(0),
|
||||||
group: Some(0),
|
group: Some(0),
|
||||||
unix_pex: Some((7, 7, 7)),
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(7), UnixPex::from(7))),
|
||||||
});
|
});
|
||||||
let entry_root: FsEntry = FsEntry::File(FsFile {
|
let entry_root: FsEntry = FsEntry::File(FsFile {
|
||||||
name: String::from("projects"),
|
name: String::from("projects"),
|
||||||
|
@ -473,7 +540,7 @@ mod tests {
|
||||||
symlink: Some(Box::new(entry_child)),
|
symlink: Some(Box::new(entry_child)),
|
||||||
user: Some(0),
|
user: Some(0),
|
||||||
group: Some(0),
|
group: Some(0),
|
||||||
unix_pex: Some((7, 7, 7)),
|
unix_pex: Some((UnixPex::from(7), UnixPex::from(7), UnixPex::from(7))),
|
||||||
});
|
});
|
||||||
assert_eq!(entry_root.is_symlink(), true);
|
assert_eq!(entry_root.is_symlink(), true);
|
||||||
// get real file
|
// get real file
|
||||||
|
@ -484,4 +551,28 @@ mod tests {
|
||||||
PathBuf::from("/home/cvisintin/projects")
|
PathBuf::from("/home/cvisintin/projects")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unix_pex() {
|
||||||
|
let pex: UnixPex = UnixPex::from(4);
|
||||||
|
assert_eq!(pex.can_read(), true);
|
||||||
|
assert_eq!(pex.can_write(), false);
|
||||||
|
assert_eq!(pex.can_execute(), false);
|
||||||
|
let pex: UnixPex = UnixPex::from(0);
|
||||||
|
assert_eq!(pex.can_read(), false);
|
||||||
|
assert_eq!(pex.can_write(), false);
|
||||||
|
assert_eq!(pex.can_execute(), false);
|
||||||
|
let pex: UnixPex = UnixPex::from(3);
|
||||||
|
assert_eq!(pex.can_read(), false);
|
||||||
|
assert_eq!(pex.can_write(), true);
|
||||||
|
assert_eq!(pex.can_execute(), true);
|
||||||
|
let pex: UnixPex = UnixPex::from(7);
|
||||||
|
assert_eq!(pex.can_read(), true);
|
||||||
|
assert_eq!(pex.can_write(), true);
|
||||||
|
assert_eq!(pex.can_execute(), true);
|
||||||
|
let pex: UnixPex = UnixPex::from(3);
|
||||||
|
assert_eq!(pex.as_byte(), 3);
|
||||||
|
let pex: UnixPex = UnixPex::from(7);
|
||||||
|
assert_eq!(pex.as_byte(), 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ use std::fs::set_permissions;
|
||||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
use crate::fs::{FsDirectory, FsEntry, FsFile};
|
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
||||||
|
|
||||||
/// ## HostErrorType
|
/// ## HostErrorType
|
||||||
///
|
///
|
||||||
|
@ -784,10 +784,10 @@ impl Localhost {
|
||||||
///
|
///
|
||||||
/// Return string with format xxxxxx to tuple of permissions (user, group, others)
|
/// Return string with format xxxxxx to tuple of permissions (user, group, others)
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
fn u32_to_mode(&self, mode: u32) -> (u8, u8, u8) {
|
fn u32_to_mode(&self, mode: u32) -> (UnixPex, UnixPex, UnixPex) {
|
||||||
let user: u8 = ((mode >> 6) & 0x7) as u8;
|
let user: UnixPex = UnixPex::from(((mode >> 6) & 0x7) as u8);
|
||||||
let group: u8 = ((mode >> 3) & 0x7) as u8;
|
let group: UnixPex = UnixPex::from(((mode >> 3) & 0x7) as u8);
|
||||||
let others: u8 = (mode & 0x7) as u8;
|
let others: UnixPex = UnixPex::from((mode & 0x7) as u8);
|
||||||
(user, group, others)
|
(user, group, others)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -707,13 +707,16 @@ impl FileTransferActivity {
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "linux"
|
target_os = "linux"
|
||||||
))]
|
))]
|
||||||
if let Some(pex) = dir.unix_pex {
|
if let Some((owner, group, others)) = dir.unix_pex {
|
||||||
if let Err(err) = self.host.chmod(local_dir_path.as_path(), pex) {
|
if let Err(err) = self.host.chmod(
|
||||||
|
local_dir_path.as_path(),
|
||||||
|
(owner.as_byte(), group.as_byte(), others.as_byte()),
|
||||||
|
) {
|
||||||
self.log(
|
self.log(
|
||||||
LogLevel::Error,
|
LogLevel::Error,
|
||||||
format!(
|
format!(
|
||||||
"Could not apply file mode {:?} to \"{}\": {}",
|
"Could not apply file mode {:?} to \"{}\": {}",
|
||||||
pex,
|
(owner.as_byte(), group.as_byte(), others.as_byte()),
|
||||||
local_dir_path.display(),
|
local_dir_path.display(),
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
@ -874,13 +877,16 @@ impl FileTransferActivity {
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "linux"
|
target_os = "linux"
|
||||||
))]
|
))]
|
||||||
if let Some(pex) = remote.unix_pex {
|
if let Some((owner, group, others)) = remote.unix_pex {
|
||||||
if let Err(err) = self.host.chmod(local, pex) {
|
if let Err(err) = self
|
||||||
|
.host
|
||||||
|
.chmod(local, (owner.as_byte(), group.as_byte(), others.as_byte()))
|
||||||
|
{
|
||||||
self.log(
|
self.log(
|
||||||
LogLevel::Error,
|
LogLevel::Error,
|
||||||
format!(
|
format!(
|
||||||
"Could not apply file mode {:?} to \"{}\": {}",
|
"Could not apply file mode {:?} to \"{}\": {}",
|
||||||
pex,
|
(owner.as_byte(), group.as_byte(), others.as_byte()),
|
||||||
local.display(),
|
local.display(),
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
* 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 crate::fs::UnixPex;
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
@ -32,55 +34,23 @@ use tuirealm::tui::style::Color;
|
||||||
|
|
||||||
/// ### fmt_pex
|
/// ### fmt_pex
|
||||||
///
|
///
|
||||||
/// Convert 3 bytes of permissions value into ls notation (e.g. rwx-wx--x)
|
/// Convert permissions bytes of permissions value into ls notation (e.g. rwx,-wx,--x)
|
||||||
pub fn fmt_pex(owner: u8, group: u8, others: u8) -> String {
|
pub fn fmt_pex(pex: UnixPex) -> String {
|
||||||
let mut mode: String = String::with_capacity(9);
|
format!(
|
||||||
let read: u8 = (owner >> 2) & 0x1;
|
"{}{}{}",
|
||||||
let write: u8 = (owner >> 1) & 0x1;
|
match pex.can_read() {
|
||||||
let exec: u8 = owner & 0x1;
|
true => 'r',
|
||||||
mode.push_str(match read {
|
false => '-',
|
||||||
1 => "r",
|
},
|
||||||
_ => "-",
|
match pex.can_write() {
|
||||||
});
|
true => 'w',
|
||||||
mode.push_str(match write {
|
false => '-',
|
||||||
1 => "w",
|
},
|
||||||
_ => "-",
|
match pex.can_execute() {
|
||||||
});
|
true => 'x',
|
||||||
mode.push_str(match exec {
|
false => '-',
|
||||||
1 => "x",
|
}
|
||||||
_ => "-",
|
)
|
||||||
});
|
|
||||||
let read: u8 = (group >> 2) & 0x1;
|
|
||||||
let write: u8 = (group >> 1) & 0x1;
|
|
||||||
let exec: u8 = group & 0x1;
|
|
||||||
mode.push_str(match read {
|
|
||||||
1 => "r",
|
|
||||||
_ => "-",
|
|
||||||
});
|
|
||||||
mode.push_str(match write {
|
|
||||||
1 => "w",
|
|
||||||
_ => "-",
|
|
||||||
});
|
|
||||||
mode.push_str(match exec {
|
|
||||||
1 => "x",
|
|
||||||
_ => "-",
|
|
||||||
});
|
|
||||||
let read: u8 = (others >> 2) & 0x1;
|
|
||||||
let write: u8 = (others >> 1) & 0x1;
|
|
||||||
let exec: u8 = others & 0x1;
|
|
||||||
mode.push_str(match read {
|
|
||||||
1 => "r",
|
|
||||||
_ => "-",
|
|
||||||
});
|
|
||||||
mode.push_str(match write {
|
|
||||||
1 => "w",
|
|
||||||
_ => "-",
|
|
||||||
});
|
|
||||||
mode.push_str(match exec {
|
|
||||||
1 => "x",
|
|
||||||
_ => "-",
|
|
||||||
});
|
|
||||||
mode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### instant_to_str
|
/// ### instant_to_str
|
||||||
|
@ -326,14 +296,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_utils_fmt_pex() {
|
fn test_utils_fmt_pex() {
|
||||||
assert_eq!(fmt_pex(7, 7, 7), String::from("rwxrwxrwx"));
|
assert_eq!(fmt_pex(UnixPex::from(7)), String::from("rwx"));
|
||||||
assert_eq!(fmt_pex(7, 5, 5), String::from("rwxr-xr-x"));
|
assert_eq!(fmt_pex(UnixPex::from(5)), String::from("r-xr-x"));
|
||||||
assert_eq!(fmt_pex(6, 6, 6), String::from("rw-rw-rw-"));
|
assert_eq!(fmt_pex(UnixPex::from(6)), String::from("rw-"));
|
||||||
assert_eq!(fmt_pex(6, 4, 4), String::from("rw-r--r--"));
|
|
||||||
assert_eq!(fmt_pex(6, 0, 0), String::from("rw-------"));
|
|
||||||
assert_eq!(fmt_pex(0, 0, 0), String::from("---------"));
|
|
||||||
assert_eq!(fmt_pex(4, 4, 4), String::from("r--r--r--"));
|
|
||||||
assert_eq!(fmt_pex(1, 2, 1), String::from("--x-w---x"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
* 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 crate::fs::{FsDirectory, FsEntry, FsFile};
|
use crate::fs::{FsDirectory, FsEntry, FsFile, UnixPex};
|
||||||
// ext
|
// ext
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
#[cfg(feature = "with-containers")]
|
#[cfg(feature = "with-containers")]
|
||||||
|
@ -53,11 +53,11 @@ pub fn create_sample_file_entry() -> (FsFile, NamedTempFile) {
|
||||||
last_access_time: SystemTime::UNIX_EPOCH,
|
last_access_time: SystemTime::UNIX_EPOCH,
|
||||||
creation_time: SystemTime::UNIX_EPOCH,
|
creation_time: SystemTime::UNIX_EPOCH,
|
||||||
size: 127,
|
size: 127,
|
||||||
ftype: None, // File type
|
ftype: None, // File type
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
},
|
},
|
||||||
tmpfile,
|
tmpfile,
|
||||||
)
|
)
|
||||||
|
@ -161,10 +161,10 @@ pub fn make_fsentry(path: PathBuf, is_dir: bool) -> FsEntry {
|
||||||
last_change_time: SystemTime::UNIX_EPOCH,
|
last_change_time: SystemTime::UNIX_EPOCH,
|
||||||
last_access_time: SystemTime::UNIX_EPOCH,
|
last_access_time: SystemTime::UNIX_EPOCH,
|
||||||
creation_time: SystemTime::UNIX_EPOCH,
|
creation_time: SystemTime::UNIX_EPOCH,
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
}),
|
}),
|
||||||
false => FsEntry::File(FsFile {
|
false => FsEntry::File(FsFile {
|
||||||
name: path.file_name().unwrap().to_string_lossy().to_string(),
|
name: path.file_name().unwrap().to_string_lossy().to_string(),
|
||||||
|
@ -173,11 +173,11 @@ pub fn make_fsentry(path: PathBuf, is_dir: bool) -> FsEntry {
|
||||||
last_access_time: SystemTime::UNIX_EPOCH,
|
last_access_time: SystemTime::UNIX_EPOCH,
|
||||||
creation_time: SystemTime::UNIX_EPOCH,
|
creation_time: SystemTime::UNIX_EPOCH,
|
||||||
size: 127,
|
size: 127,
|
||||||
ftype: None, // File type
|
ftype: None, // File type
|
||||||
symlink: None, // UNIX only
|
symlink: None, // UNIX only
|
||||||
user: Some(0), // UNIX only
|
user: Some(0), // UNIX only
|
||||||
group: Some(0), // UNIX only
|
group: Some(0), // UNIX only
|
||||||
unix_pex: Some((6, 4, 4)), // UNIX only
|
unix_pex: Some((UnixPex::from(6), UnixPex::from(4), UnixPex::from(4))), // UNIX only
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue