sysinfo/unix/linux/
motherboard.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fs::{read, read_to_string};
4
5pub(crate) struct MotherboardInner;
6
7impl MotherboardInner {
8    pub(crate) fn new() -> Option<Self> {
9        Some(Self)
10    }
11
12    pub(crate) fn asset_tag(&self) -> Option<String> {
13        read_to_string("/sys/devices/virtual/dmi/id/board_asset_tag")
14            .ok()
15            .map(|s| s.trim().to_owned())
16    }
17
18    pub(crate) fn name(&self) -> Option<String> {
19        read_to_string("/sys/devices/virtual/dmi/id/board_name")
20            .ok()
21            .or_else(|| {
22                read_to_string("/proc/device-tree/board")
23                    .ok()
24                    .or_else(|| Some(parse_device_tree_compatible()?.1))
25            })
26            .map(|s| s.trim().to_owned())
27    }
28
29    pub(crate) fn vendor_name(&self) -> Option<String> {
30        read_to_string("/sys/devices/virtual/dmi/id/board_vendor")
31            .ok()
32            .or_else(|| Some(parse_device_tree_compatible()?.0))
33            .map(|s| s.trim().to_owned())
34    }
35
36    pub(crate) fn version(&self) -> Option<String> {
37        read_to_string("/sys/devices/virtual/dmi/id/board_version")
38            .ok()
39            .map(|s| s.trim().to_owned())
40    }
41
42    pub(crate) fn serial_number(&self) -> Option<String> {
43        read_to_string("/sys/devices/virtual/dmi/id/board_serial")
44            .ok()
45            .map(|s| s.trim().to_owned())
46    }
47}
48
49// Parses the first entry of the file `/proc/device-tree/compatible`, to extract the vendor and
50// motherboard name. This file contains several `\0` separated strings; the first one include the
51// vendor and the motherboard name, separated by a comma.
52//
53// According to the specification: https://github.com/devicetree-org/devicetree-specification
54// a compatible string must contain only one comma.
55fn parse_device_tree_compatible() -> Option<(String, String)> {
56    let bytes = read("/proc/device-tree/compatible").ok()?;
57    let first_line = bytes.split(|&b| b == 0).next()?;
58    std::str::from_utf8(first_line)
59        .ok()?
60        .split_once(',')
61        .map(|(a, b)| (a.to_owned(), b.to_owned()))
62}