aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 5e978d42eddbc1cc4bb85c7378e3cc4797ce41d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use anyhow::bail;
use std::fs::{self, File};
use std::io::{self, Write};
use std::os::fd::AsFd;
use std::process::Command;
use std::thread;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

fn null() -> anyhow::Result<File> {
    Ok(File::open("/dev/null")?)
}

fn start() -> anyhow::Result<()> {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
    writeln!(&mut stdout, "Starting rustkrazy")?;

    for service in fs::read_dir("/bin")? {
        let service = service?;
        let service_name = match service.file_name().into_string() {
            Ok(v) => v,
            Err(_) => bail!("[ ERROR ] invalid unicode in file name"),
        };

        if service_name == "init" {
            continue;
        }

        let mut cmd = Command::new(service.path());
        cmd.stderr(null()?).stdin(null()?).stdout(null()?);

        match cmd.spawn() {
            Ok(_) => {
                stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
                writeln!(&mut stdout, "[  OK   ] Starting {}", service_name)?;

                stdout.reset()?;
                stdout.flush()?;

                cmd.stderr(io::stderr().as_fd().try_clone_to_owned()?);
                cmd.stdin(io::stdin().as_fd().try_clone_to_owned()?);
                cmd.stdout(io::stdout().as_fd().try_clone_to_owned()?);
            }
            Err(e) => {
                stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?;
                writeln!(&mut stdout, "[ ERROR ] Starting {}: {}", service_name, e)?;

                stdout.reset()?;
                stdout.flush()?;
            }
        }
    }

    Ok(())
}

fn main() {
    match start() {
        Ok(_) => {}
        Err(e) => {
            let mut stdout = StandardStream::stdout(ColorChoice::Always);

            match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red))) {
                Ok(_) => match writeln!(&mut stdout, "[ ERROR ] {}", e) {
                    Ok(_) => {}
                    Err(_) => println!("[ ERROR ] {}", e),
                },
                Err(_) => {
                    println!("[ ERROR ] {}", e);
                }
            }
        }
    }

    loop {
        thread::yield_now();
    }
}