use super::{Root, RootType};
#[cfg(not(target_arch = "wasm32"))]
use libc::statvfs;
use std::{fs::File, io::BufRead, io::BufReader};
pub(super) fn get_os_roots() -> Vec<Root> {
#[cfg(target_arch = "wasm32")]
{
return Vec::new();
}
#[cfg(not(target_arch = "wasm32"))]
{
let mut roots = Vec::new();
if let Ok(file) = File::open("/etc/mtab") {
let reader = BufReader::new(file);
for line in reader.lines() {
if let Ok(line) = line {
let fields: Vec<&str> = line.split_whitespace().collect();
if fields.len() > 1 {
let device_name = fields[0];
let mount_point = fields[1];
let mut stats: statvfs = unsafe { std::mem::zeroed() };
let c_mount_point = std::ffi::CString::new(mount_point).unwrap();
let result = unsafe { statvfs(c_mount_point.as_ptr(), &mut stats) };
if result == 0 {
let total_size = stats.f_blocks as u64 * stats.f_frsize as u64;
let free_space = stats.f_bfree as u64 * stats.f_frsize as u64;
let root_type = if mount_point.starts_with("/media") || mount_point.starts_with("/mnt") {
RootType::Removable
} else if mount_point.starts_with("/dev") {
RootType::RamDisk
} else if mount_point.starts_with("/run") {
RootType::Network
} else {
RootType::Fixed
};
roots.push(Root {
path: mount_point.to_string(),
size: total_size,
free_space,
root_type,
name: device_name.to_string(),
});
}
}
}
}
} else {
eprintln!("Failed to open /etc/mtab");
}
roots
}
}
#[test]
fn test_os_roots() {
let roots = get_os_roots();
println!("{:?}", roots);
}