/
dmi.go
107 lines (99 loc) · 2.11 KB
/
dmi.go
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"bufio"
"io"
"reflect"
"regexp"
"strings"
)
var (
alpha = regexp.MustCompile("^[A-Za-z]+")
skip = regexp.MustCompile("^([0-9]+|#|SMBIOS|Table)")
ws = regexp.MustCompile("[\t ]+")
)
type memoryDevice struct {
Size string
Locator string
Speed string
manufacturer string
SerialNumber string
AssetTag string
PartNumber string
ConfiguredClockSpeed string
}
type baseBoardInformation struct {
manufacturer string
ProductName string
Version string
SerialNumber string
AssetTag string
LocationInChassis string
ChassisHandle string
Type string
}
type systemPowerSupply struct {
Location string
manufacturer string
SerialNumber string
AssetTag string
ModelPartNumber string
}
type systemInfo struct {
Motherboard baseBoardInformation
Memory []*memoryDevice
Power []*systemPowerSupply
}
func (sys *systemInfo) AddLine(part interface{}, line string) {
colon := strings.Index(line, ":")
if colon < 0 {
return
}
label := ws.ReplaceAllString(line[:colon], "")
colon++
value := strings.TrimSpace(line[colon:])
p := reflect.ValueOf(part)
val := reflect.Indirect(p)
f := val.FieldByName(label)
if f.IsValid() {
f.SetString(value)
}
}
func parseDMI(src io.Reader) *systemInfo {
sys := new(systemInfo)
reader := bufio.NewReader(src)
var part interface{}
for {
line, err := reader.ReadString('\n')
if err != nil {
break
}
if len(strings.TrimSpace(line)) == 0 {
continue
}
if skip.MatchString(line) {
continue
}
if alpha.MatchString(line) {
line = strings.TrimSpace(line)
switch {
case line == "Memory Device":
m := new(memoryDevice)
sys.Memory = append(sys.Memory, m)
part = m
case line == "System Power Supply":
p := new(systemPowerSupply)
sys.Power = append(sys.Power, p)
part = p
case line == "Base Board Information":
part = &sys.Motherboard
default:
part = nil
}
continue
}
if part != nil {
sys.AddLine(part, line)
}
}
return sys
}