summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock110
-rw-r--r--init/src/main.rs26
-rw-r--r--init/src/mounts/fstab.rs164
-rw-r--r--init/src/rescue/initrd.rs0
-rw-r--r--vegilctl/Cargo.toml1
5 files changed, 256 insertions, 45 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 72ac239..42405ad 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,6 +3,89 @@
version = 4
[[package]]
+name = "anstream"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys",
+]
+
+[[package]]
+name = "clap"
+version = "4.5.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
+dependencies = [
+ "clap_builder",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
+
+[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -21,14 +104,41 @@ dependencies = [
]
[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+
+[[package]]
name = "libc"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
+name = "once_cell_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
name = "vegilctl"
version = "0.1.0"
+dependencies = [
+ "clap",
+]
[[package]]
name = "windows-link"
diff --git a/init/src/main.rs b/init/src/main.rs
index 1138ccf..e944424 100644
--- a/init/src/main.rs
+++ b/init/src/main.rs
@@ -1,10 +1,36 @@
mod mounts;
mod pid_one;
+use crate::mounts::fstab::FstabEntry;
+use crate::mounts::rescue;
use crate::pid_one::check_pid;
+// RULE: I will not use .expect() and .unwrap() in this project. This causes panic,
+// which will affect stability.
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Initializing your system.");
check_pid().expect("\x1b[31m * \x1b[0m Runned not as first process. init/src/pid_one.rs:8:8");
+
+ match FstabEntry::parse_fstab("/etc/fstab") {
+ Ok(entries) => {
+ println!("\x1b[32m * \x1b[0m Sucessfully parsed /etc/fstab.");
+ for entry in &entries {
+ let _ = entry.mount();
+ }
+ },
+ Err(error) => {
+ println!("\x1b[33m * \x1b[0m Looks like fstab broken. Mounting all without reading /etc/fstab.");
+ println!("\x1b[33m * \x1b[0m 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.
+ }
+ }
+
+
+
Ok(())
}
diff --git a/init/src/mounts/fstab.rs b/init/src/mounts/fstab.rs
index 0765cfd..919607c 100644
--- a/init/src/mounts/fstab.rs
+++ b/init/src/mounts/fstab.rs
@@ -1,5 +1,6 @@
use libc::{self};
use std::ffi::CString;
+use std::{fs, fmt};
#[derive(Debug)]
pub struct FstabEntry {
@@ -11,62 +12,128 @@ pub struct FstabEntry {
pub pass: u32,
}
-fn parse_mount_options(
- options: &str,
-) -> Result<(libc::c_ulong, Option<String>), Box<dyn std::error::Error>> {
- let mut flags = 0;
- let mut data_parts = Vec::new();
-
- for opt in options.split(',') {
- match opt {
- "defaults" => { /* handled by not setting any restrictive flags */ }
- "ro" => flags |= libc::MS_RDONLY,
- "rw" => flags &= !libc::MS_RDONLY,
- "noexec" => flags |= libc::MS_NOEXEC,
- "nosuid" => flags |= libc::MS_NOSUID,
- "nodev" => flags |= libc::MS_NODEV,
- "sync" => flags |= libc::MS_SYNCHRONOUS,
- "dirsync" => flags |= libc::MS_DIRSYNC,
- "bind" => flags |= libc::MS_BIND,
- "rbind" => flags |= libc::MS_BIND | libc::MS_REC,
- "remount" => flags |= libc::MS_REMOUNT,
- _ => {
- if !opt.is_empty() {
- data_parts.push(opt);
+impl fmt::Display for FstabEntry {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{} {} {} {} {} {}",
+ self.source, self.mountpoint, self.fstype, self.options, self.dump, self.pass
+ )
+ }
+}
+
+impl FstabEntry {
+ fn parse_line(line: &str) -> Result<Self, Box<dyn std::error::Error>> {
+ let line = line.trim();
+
+ if line.is_empty() || line.starts_with('#') {
+ return Err("Empty line or comment".into());
+ }
+
+ let parts: Vec<&str> = line.split_whitespace().collect();
+
+ if parts.len() != 6 {
+ return Err(format!("Invalid number of fields in fstab entry: {}", line).into());
+ }
+
+ let source = parts[0].to_string();
+ let mountpoint = parts[1].to_string();
+ let fstype = parts[2].to_string();
+ let options = parts[3].to_string();
+
+ let dump = parts[4].parse::<u32>().map_err(|e| {
+ format!("Failed to parse dump field '{}': {}", parts[4], e)
+ })?;
+
+ let pass = parts[5].parse::<u32>().map_err(|e| {
+ format!("Failed to parse pass field '{}': {}", parts[5], e)
+ })?;
+
+ Ok(FstabEntry {
+ source,
+ mountpoint,
+ fstype,
+ options,
+ dump,
+ pass,
+ })
+ }
+
+ pub fn parse_fstab(path: &str) -> Result<Vec<FstabEntry>, Box<dyn std::error::Error>> {
+ let content = fs::read_to_string(path)?;
+
+ let mut entries = Vec::new();
+ for line in content.lines() {
+ match Self::parse_line(line) {
+ Ok(entry) => entries.push(entry),
+ Err(_) => {
+ println!("\x1b[32m * \x1b[0m Warning: Skipping invalid fstab line: {}", line);
+ continue;
}
}
}
+
+ Ok(entries)
}
- let data = if data_parts.is_empty() {
- None
- } else {
- Some(data_parts.join(","))
- };
+ pub fn parse_mount_options(
+ &self,
+ ) -> Result<(libc::c_ulong, Option<String>), Box<dyn std::error::Error>> {
+ let mut flags = 0;
+ let mut data_parts = Vec::new();
+ let options = &self.options;
- Ok((flags, data))
-}
+ for opt in options.split(',') {
+ match opt {
+ "defaults" => { /* handled by not setting any restrictive flags */ }
+ "ro" => flags |= libc::MS_RDONLY,
+ "rw" => flags &= !libc::MS_RDONLY,
+ "noexec" => flags |= libc::MS_NOEXEC,
+ "nosuid" => flags |= libc::MS_NOSUID,
+ "nodev" => flags |= libc::MS_NODEV,
+ "sync" => flags |= libc::MS_SYNCHRONOUS,
+ "dirsync" => flags |= libc::MS_DIRSYNC,
+ "bind" => flags |= libc::MS_BIND,
+ "rbind" => flags |= libc::MS_BIND | libc::MS_REC,
+ "remount" => flags |= libc::MS_REMOUNT,
+ _ => {
+ if !opt.is_empty() {
+ data_parts.push(opt);
+ }
+ }
+ }
+ }
+
+ let data = if data_parts.is_empty() {
+ None
+ } else {
+ Some(data_parts.join(","))
+ };
+
+ Ok((flags, data))
+ }
-pub fn mount_from_fstab(entries: &[FstabEntry]) -> Result<(), Box<dyn std::error::Error>> {
- for entry in entries {
- if entry.fstype == "swap" {
- println!("Skipping swap: {}", entry.source);
- continue;
+ pub fn mount(&self) -> Result<(), Box<dyn std::error::Error>> {
+ println!("\x1b[32m * \x1b[0m Started mounting {} from {}", self.mountpoint, self.source);
+
+ if self.fstype == "swap" {
+ println!("\x1b[30m * \x1b[0m Skipping swap: {}", self.source);
+ return Ok(());
}
- if entry.mountpoint == "none" {
- continue;
+ if self.mountpoint == "none" {
+ return Ok(());
}
- if entry.options.contains("noauto") {
- continue;
+ if self.options.contains("noauto") {
+ return Ok(());
}
- let (flags, data) = parse_mount_options(&entry.options)?;
+ let (flags, data) = self.parse_mount_options()?;
- let source_c = CString::new(&*entry.source)?;
- let target_c = CString::new(&*entry.mountpoint)?;
- let fstype_c = CString::new(&*entry.fstype)?;
+ let source_c = CString::new(&*self.source)?;
+ let target_c = CString::new(&*self.mountpoint)?;
+ let fstype_c = CString::new(&*self.fstype)?;
let data_c = data.map(|s| CString::new(s).expect("\x1b[31m * \x1b[0m Something went wrong while mounting partitions. You are going to rescue mode..."));
let data_ptr = data_c
@@ -87,12 +154,19 @@ pub fn mount_from_fstab(entries: &[FstabEntry]) -> Result<(), Box<dyn std::error
if ret != 0 {
eprintln!(
"\x1b[31m * \x1b[0m Failed to mount {}: {}",
- entry.mountpoint,
+ self.mountpoint,
std::io::Error::last_os_error()
);
} else {
- println!("\x1b[32m * \x1b[0m Mounted {}", entry.mountpoint);
+ println!("\x1b[32m * \x1b[0m Mounted {}", self.mountpoint);
+ }
+ Ok(())
+ }
+
+ pub fn mount_from_fstab(entries: &[FstabEntry]) -> Result<(), Box<dyn std::error::Error>> {
+ for entry in entries {
+ entry.mount()?;
}
+ Ok(())
}
- Ok(())
} \ No newline at end of file
diff --git a/init/src/rescue/initrd.rs b/init/src/rescue/initrd.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/init/src/rescue/initrd.rs
diff --git a/vegilctl/Cargo.toml b/vegilctl/Cargo.toml
index 035764a..73077a8 100644
--- a/vegilctl/Cargo.toml
+++ b/vegilctl/Cargo.toml
@@ -5,3 +5,4 @@ edition = "2024"
description = "Vegil init user control."
[dependencies]
+clap = "4.5.53"