From 344ee27b279f4c05bd0bf7aaf47f40274ffd518e Mon Sep 17 00:00:00 2001 From: darkgallium Date: Sun, 14 Jun 2020 01:02:16 +0200 Subject: [PATCH] initial commit --- .gitignore | 1 + Cargo.lock | 422 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 14 ++ config.toml | 6 + src/main.rs | 119 +++++++++++ src/processes.rs | 69 +++++++ src/svc.rs | 36 ++++ svc/networkmanager.toml | 4 + 8 files changed, 671 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 config.toml create mode 100644 src/main.rs create mode 100644 src/processes.rs create mode 100644 src/svc.rs create mode 100644 svc/networkmanager.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..064a1b1 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,422 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arc-swap" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bytes" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" + +[[package]] +name = "cc" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures-core" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" + +[[package]] +name = "hermit-abi" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" +dependencies = [ + "libc", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "mini" +version = "0.1.0" +dependencies = [ + "nix", + "serde", + "signal-hook", + "tokio", + "toml", +] + +[[package]] +name = "mio" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.1", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +dependencies = [ + "log", + "mio", + "miow 0.3.5", + "winapi 0.3.8", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +dependencies = [ + "iovec", + "libc", + "mio", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "miow" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" +dependencies = [ + "socket2", + "winapi 0.3.8", +] + +[[package]] +name = "net2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "nix" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "void", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" + +[[package]] +name = "proc-macro2" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "serde" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "signal-hook" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ff2db2112d6c761e12522c65f7768548bd6e8cd23d2a9dae162520626629bd6" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +dependencies = [ + "arc-swap", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "socket2" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.8", +] + +[[package]] +name = "syn" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tokio" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-named-pipes", + "mio-uds", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "slab", + "tokio-macros", + "winapi 0.3.8", +] + +[[package]] +name = "tokio-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b029316 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "mini" +version = "0.1.0" +authors = ["darkgallium "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +signal-hook = "0.1.15" +nix = "0.17.0" +toml = "0.5" +serde = { version = "1.0", features = ["derive"] } +tokio = { version = "0.2", features = ["full"] } diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..a73cc45 --- /dev/null +++ b/config.toml @@ -0,0 +1,6 @@ +keymap = 'fr' + +modules = [ + "r8169", + "rtl8821ae" +] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..de1a5e2 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,119 @@ +mod processes; +mod svc; + +use std::fs; +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; +use std::process; +use std::error::Error; +use signal_hook::{SIGINT, SIGCHLD, SIGALRM, SIGUSR1}; +use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus}; +use nix::sys::reboot::{reboot, RebootMode}; +use nix::sys::signal::Signal; +use nix::sys::signal::kill; +use nix::unistd::Pid; + +fn sigint_handler() { + println!("Received signal SIGINT"); + process::exit(0); +} + +fn reap_handler() { + loop { + match waitpid(Some(Pid::from_raw(-1)), Some(WaitPidFlag::WNOHANG)) { + Ok(WaitStatus::Exited(_pid, _code)) => return, + Err(e) => { + eprintln!("could not reap, error is {}", e); + return + }, + _ => continue + } + } + +} + +fn set_hostname() { + let path = Path::new("/proc/sys/kernel/hostname"); + let display = path.display(); + + let mut file = match File::create(&path) { + Err(why) => panic!("couldn't create {}: {}", display, why), + Ok(file) => file, + }; + + match file.write_all("octogone".as_bytes()) { + Err(why) => panic!("couldn't write to {}: {}", display, why), + Ok(_) => (), + } +} + +async fn launch_services() { + let services = svc::get_services(); + + for s in services { + println!("starting {}", s.name); + let args: Vec<&str> = s.start.args.iter().map(|e| e.as_str()).collect(); + processes::run(&s.start.command, &args[..]).await; + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + + + println!("mini, the bare minimum init by darkgallium"); + println!(); + + println!("remount /"); + processes::run_wait("mount", ["-o", "remount", "/"].as_ref()).await; + + println!("set hostname"); + set_hostname(); + + println!("mount all partitions"); + processes::run_wait("mount", ["-a"].as_ref()).await; + processes::run("swapon", ["-a"].as_ref()).await; + + println!("load udev"); + processes::run_wait("/usr/lib/systemd/systemd-udevd", ["-d"].as_ref()).await; + processes::run("udevadm", ["trigger", "--action=add", "--type=subsystems"].as_ref()).await; + processes::run("udevadm", ["trigger", "--action=add", "--type=devices"].as_ref()).await; + processes::run("udevadm", ["settle"].as_ref()).await; + + println!("setting keymap"); + processes::run("loadkeys", ["fr-latin9"].as_ref()).await; + + println!("load dbus"); + processes::run_wait("mkdir", ["/run/dbus"].as_ref()).await; + processes::run_wait("dbus-daemon", ["--system"].as_ref()).await; // a lot of services depend on dbus being on + + println!("now loading your services"); + launch_services().await; + + unsafe { signal_hook::register(SIGINT, sigint_handler) }?; + let sigchld_handle = unsafe { signal_hook::register(SIGCHLD, reap_handler) }?; + + println!("end bootstrap, launching your terminals"); + + // TODO: spawn a thread by tty and join threads at end + processes::sync_run_wait("agetty", ["--noclear", "tty1"].as_ref()); + + signal_hook::unregister(sigchld_handle); + + println!("killing remaining processes"); + let pids = processes::get_all_pids(); + + for pid in pids { + kill(Pid::from_raw(pid), Signal::SIGKILL); + } + + println!("unmounting all partitions"); + processes::run_wait("swapoff", ["-a"].as_ref()).await; + processes::run_wait("umount", ["-a", "-f"].as_ref()).await; + + println!("end pre-shutdown routines"); + reboot(RebootMode::RB_POWER_OFF); + + Ok(()) +} diff --git a/src/processes.rs b/src/processes.rs new file mode 100644 index 0000000..c2034df --- /dev/null +++ b/src/processes.rs @@ -0,0 +1,69 @@ +use std::fs; +use std::process::{Stdio, Command}; +use tokio::process::Command as AsyncCommand; +use tokio::process::Child as AsyncChild; + +pub fn get_all_pids() -> Vec { + let mut pids = Vec::::new(); + let files = fs::read_dir("/proc/").unwrap(); + + for entry in files { + let path = entry.unwrap().path(); + if path.is_dir() { + if let Some(name) = path.file_name() { + let name = name.to_str().unwrap(); + match name.parse::() { + Ok(pid) => { + if pid > 1 { + let content = fs::read_to_string(format!("/proc/{}/cmdline", pid)); + match content { + Ok(cmdline) => { + //if cmdline != "" { + pids.push(pid); + //} + }, + Err(_) => {} + } + } + }, + + Err(_) => {} + } + } + } + } + + pids +} + +pub fn sync_run_wait(path: &str, args: &[&str]) { + let mut child = Command::new(path) + .env("PATH", "/sbin:/bin:/usr/bin") + .args(args) + .spawn() + .unwrap(); + + child.wait().unwrap(); + () +} + + +pub async fn run(path: &str, args: &[&str]) -> AsyncChild { + AsyncCommand::new(path) + .env("PATH", "/sbin:/bin:/usr/bin") + .args(args) + .stdout(Stdio::null()) + .spawn() + .unwrap() +} + +pub async fn run_wait(path: &str, args: &[&str]) { + let child = AsyncCommand::new(path) + .env("PATH", "/sbin:/bin:/usr/bin") + .args(args) + .spawn() + .unwrap(); + + child.await.unwrap(); + () +} diff --git a/src/svc.rs b/src/svc.rs new file mode 100644 index 0000000..6c5b56d --- /dev/null +++ b/src/svc.rs @@ -0,0 +1,36 @@ +use std::fs; +use serde::Deserialize; +use toml; + +#[derive(Deserialize, Debug)] +pub struct Service { + pub name: String, + pub start: Start, + pub stop: Option, +} + +#[derive(Deserialize, Debug)] +pub struct Start { + pub command: String, + pub args: Vec +} + +#[derive(Deserialize, Debug)] +pub struct Stop { + pub command: String, + pub args: Vec +} + +pub fn get_services() -> Vec { + let mut services = Vec::new(); + let paths = fs::read_dir("/etc/mini/").unwrap(); + + for path in paths { + // TODO: check ext + let svc_file_contents = fs::read_to_string(path.unwrap().path()).unwrap(); + let svc : Service = toml::from_str(&svc_file_contents).unwrap(); + services.push(svc); + } + + services +} diff --git a/svc/networkmanager.toml b/svc/networkmanager.toml new file mode 100644 index 0000000..33ee2db --- /dev/null +++ b/svc/networkmanager.toml @@ -0,0 +1,4 @@ +name = 'NetworkManager' +[start] +command = 'NetworkManager' +args = []