mod log; mod mounts; mod pid_one; mod host; use crate::log::{log_critical_error, log_warning, log_success}; use crate::mounts::fstab::FstabEntry; use crate::mounts::rescue; use crate::pid_one::check_pid; use crate::host::sethn::try_set_hostname; use std::process::Command; // RULE: I will not use .expect() and .unwrap() in this project. This causes panic, // which will affect stability. fn spawn_udev() -> Result<(), Box> { log_success("Spawning udev daemon."); let udevd_paths = [ "/sbin/udevd", "/usr/sbin/udevd", "/bin/udevd", "/usr/bin/udevd", ]; let udevd_path = udevd_paths .iter() .find(|path| std::path::Path::new(path).exists()) .ok_or("udevd not found in standard locations")?; let child = Command::new(udevd_path) .arg("--daemon") .spawn() .map_err(|e| format!("Failed to spawn udevd: {}", e))?; log_success(&format!("udevd started with PID: {}", child.id())); Command::new(udevd_path) .arg("--trigger") .output() .map_err(|e| format!("Failed to trigger udev: {}", e))?; Ok(()) } fn main() -> Result<(), Box> { println!("Initializing your system."); if let Err(e) = check_pid() { log_critical_error(&format!("Runned not as first process. init/src/pid_one.rs:8:8 - {}", e)); return Err(e); } match FstabEntry::parse_fstab("/etc/fstab") { Ok(entries) => { log_success("Sucessfully parsed /etc/fstab."); for entry in &entries { let _ = entry.mount(); } } Err(error) => { log_warning("Looks like fstab broken. Mounting all without reading /etc/fstab."); log_warning(&format!("Error:\n {}", error)); let _ = rescue::mount_system(); // Minimal mounts without fstab, because /etc/fstab needs fixes :) // Btw it should be used if fstab broken or has syntax-errors // TODO: If fstab contains syntax errors, mount everything else that does not contain them through it anyway. } } let _ = try_set_hostname(); match spawn_udev() { Ok(_) => log_success("Successfully started udev daemon."), Err(e) => log_critical_error(&format!("Failed to start udev daemon: {}", e)), } Ok(()) }