use crate::file_entry::FileEntry;
use std::fs;
use std::io;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
pub fn read_directory(target_path: &Path, show_hidden: bool) -> io::Result<Vec<FileEntry>> {
let mut entries: Vec<FileEntry> = Vec::new();
for entry in fs::read_dir(target_path)? {
let entry = entry?;
let path = entry.path();
if !show_hidden {
if let Some(filename) = path.file_name() {
if filename.as_encoded_bytes().starts_with(b".") {
continue;
}
}
}
let metadata = entry.metadata()?;
let is_dir = metadata.is_dir();
let is_executable = !is_dir && (metadata.permissions().mode() & 0o111) != 0;
let uid = metadata.uid();
let owner = get_username(uid);
let gid = metadata.gid();
let group = get_groupname(gid);
let nlink = metadata.nlink();
let modified = metadata
.modified()
.unwrap_or(std::time::SystemTime::UNIX_EPOCH);
let size = metadata.len();
entries.push(FileEntry {
path: path.file_name().unwrap().to_os_string(),
is_dir,
is_executable,
mode: metadata.permissions().mode(),
size,
modified,
owner,
group,
nlink,
});
}
Ok(entries)
}
fn get_username(uid: u32) -> String {
#[cfg(unix)]
{
use std::ffi::CStr;
unsafe {
let passwd = libc::getpwuid(uid);
if !passwd.is_null() {
let name = CStr::from_ptr((*passwd).pw_name);
if let Ok(name_str) = name.to_str() {
return name_str.to_string();
}
}
}
}
uid.to_string()
}
fn get_groupname(gid: u32) -> String {
#[cfg(unix)]
{
use std::ffi::CStr;
unsafe {
let group = libc::getgrgid(gid);
if !group.is_null() {
let name = CStr::from_ptr((*group).gr_name);
if let Ok(name_str) = name.to_str() {
return name_str.to_string();
}
}
}
}
gid.to_string()
}