1use crate::file_entry::FileEntry;
3use std::fs;
4use std::io;
5use std::os::unix::fs::{MetadataExt, PermissionsExt};
6use std::path::Path;
7
8pub fn read_directory(target_path: &Path, show_hidden: bool) -> io::Result<Vec<FileEntry>> {
9 let mut entries: Vec<FileEntry> = Vec::new();
10
11 for entry in fs::read_dir(target_path)? {
12 let entry = entry?;
13 let path = entry.path();
14
15 if !show_hidden {
17 if let Some(filename) = path.file_name() {
18 if let Some(name) = filename.to_str() {
19 if name.starts_with('.') {
20 continue;
21 }
22 }
23 }
24 }
25
26 let metadata = entry.metadata()?;
27 let is_dir = metadata.is_dir();
28 let is_executable = !is_dir && (metadata.permissions().mode() & 0o111) != 0;
29
30 let uid = metadata.uid();
32 let owner = get_username(uid);
33
34 let gid = metadata.gid();
36 let group = get_groupname(gid);
37
38 let nlink = metadata.nlink();
40
41 let modified = metadata
43 .modified()
44 .unwrap_or(std::time::SystemTime::UNIX_EPOCH);
45
46 let size = metadata.len();
48
49 entries.push(FileEntry {
50 path,
51 is_dir,
52 is_executable,
53 mode: metadata.permissions().mode(),
54 size,
55 modified,
56 owner,
57 group,
58 nlink,
59 });
60 }
61
62 Ok(entries)
63}
64
65fn get_username(uid: u32) -> String {
66 #[cfg(unix)]
68 {
69 use std::ffi::CStr;
70 unsafe {
71 let passwd = libc::getpwuid(uid);
72 if !passwd.is_null() {
73 let name = CStr::from_ptr((*passwd).pw_name);
74 if let Ok(name_str) = name.to_str() {
75 return name_str.to_string();
76 }
77 }
78 }
79 }
80 uid.to_string()
81}
82
83fn get_groupname(gid: u32) -> String {
84 #[cfg(unix)]
86 {
87 use std::ffi::CStr;
88 unsafe {
89 let group = libc::getgrgid(gid);
90 if !group.is_null() {
91 let name = CStr::from_ptr((*group).gr_name);
92 if let Ok(name_str) = name.to_str() {
93 return name_str.to_string();
94 }
95 }
96 }
97 }
98 gid.to_string()
99}