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
use clap::Parser;
use rustutils_runnable::Runnable;
use std::error::Error;
use std::io::Write;
use std::os::unix::ffi::OsStrExt;

/// Print system information.
#[derive(Parser, Clone, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct Uname {
    /// Print all information
    #[clap(short, long)]
    all: bool,
    /// Print the kernel name
    #[clap(short = 's', long)]
    kernel_name: bool,
    /// Print the network node hostname
    #[clap(short, long, alias = "nodename")]
    node_name: bool,
    /// Print the kernel release
    #[clap(short = 'r', long)]
    kernel_release: bool,
    /// Print the kernel version
    #[clap(short = 'v', long)]
    kernel_version: bool,
    /// Print the machine hardware name
    #[clap(short, long)]
    machine: bool,
    /// Print the processor type
    #[clap(short, long)]
    processor: bool,
    /// Print the hardware platform
    #[clap(short = 'i', long)]
    hardware_platform: bool,
    /// Print the operating system
    #[clap(short, long)]
    operating_system: bool,
    /// Format the output as JSON
    #[clap(short, long)]
    json: bool,
}

impl Runnable for Uname {
    fn run(&self) -> Result<(), Box<dyn Error>> {
        let uname = nix::sys::utsname::uname()?;
        let mut output = vec![];
        if self.kernel_name || self.all {
            output.push(uname.sysname());
        }

        if self.node_name || self.all {
            output.push(uname.nodename());
        }

        if self.kernel_release || self.all {
            output.push(uname.release());
        }

        if self.kernel_version || self.all {
            output.push(uname.version());
        }

        if self.machine || self.all {
            output.push(uname.machine());
        }

        let mut stdout = std::io::stdout();
        for string in &output {
            stdout.write_all(b" ")?;
            stdout.write_all(string.as_bytes())?;
        }
        stdout.write_all(b"\n")?;

        Ok(())
    }
}