use crate::log::{log_success, log_warning}; use std::ffi::CString; use std::fs::{create_dir, metadata}; use std::os::unix::fs::MetadataExt; fn check_mount_point_permissions(path: &str) -> Result<(), Box> { if !std::path::Path::new(path).exists() { create_dir(path)?; } let meta = metadata(path)?; if !meta.is_dir() { return Err(format!("Mount point {} is not a directory", path).into()); } // TODO // let mode = meta.mode(); let uid = meta.uid(); if uid != 0 { log_warning(&format!("Warning: Mount point {} not owned by root", path)); } Ok(()) } pub fn mount_system() -> Result<(), Box> { let mounts: &[(&str, &str, Option<&str>)] = &[ ("/proc", "proc", None), ("/sys", "sysfs", None), ("/dev", "devtmpfs", Some("devtmpfs")), ("/tmp", "tmpfs", None), ("/run", "tmpfs", None), ]; unsafe { for &(target, fstype, source) in mounts { if let Err(e) = check_mount_point_permissions(target) { log_warning(&format!("Permission check failed for {}: {}", target, e)); } let target_c = CString::new(target)?; let fstype_c = CString::new(fstype)?; // let source_c = source.map(|s| CString::new(s).map_err(|e| )); let source_c = match source { Some(s) => match CString::new(s) { Ok(c_string) => Some(c_string), Err(null_err) => { log_warning(&format!("Source string contains NULL bytes (\\0), skipping: {}", null_err)); continue; } }, None => None }; let source_ptr = source_c.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()); let ret = libc::syscall( libc::SYS_mount, source_ptr, target_c.as_ptr(), fstype_c.as_ptr(), 0 as libc::c_ulong, std::ptr::null::(), ); if ret != 0 { return Err(format!( "Failed to mount {}: {}", target, std::io::Error::last_os_error() ) .into()); } log_success(&format!("Mounting {}...", target)); } } Ok(()) }