1
2
3 package host
4
5 import (
6 "bytes"
7 "context"
8 "encoding/binary"
9 "errors"
10 "io/ioutil"
11 "os"
12 "os/exec"
13 "strings"
14 "unsafe"
15
16 "github.com/shirou/gopsutil/internal/common"
17 "github.com/shirou/gopsutil/process"
18 "golang.org/x/sys/unix"
19 )
20
21
22 const USER_PROCESS = 7
23
24 func HostIDWithContext(ctx context.Context) (string, error) {
25 ioreg, err := exec.LookPath("ioreg")
26 if err != nil {
27 return "", err
28 }
29
30 out, err := invoke.CommandWithContext(ctx, ioreg, "-rd1", "-c", "IOPlatformExpertDevice")
31 if err != nil {
32 return "", err
33 }
34
35 for _, line := range strings.Split(string(out), "\n") {
36 if strings.Contains(line, "IOPlatformUUID") {
37 parts := strings.SplitAfter(line, `" = "`)
38 if len(parts) == 2 {
39 uuid := strings.TrimRight(parts[1], `"`)
40 return strings.ToLower(uuid), nil
41 }
42 }
43 }
44
45 return "", errors.New("cannot find host id")
46 }
47
48 func numProcs(ctx context.Context) (uint64, error) {
49 procs, err := process.PidsWithContext(ctx)
50 if err != nil {
51 return 0, err
52 }
53 return uint64(len(procs)), nil
54 }
55
56 func UsersWithContext(ctx context.Context) ([]UserStat, error) {
57 utmpfile := "/var/run/utmpx"
58 var ret []UserStat
59
60 file, err := os.Open(utmpfile)
61 if err != nil {
62 return ret, err
63 }
64 defer file.Close()
65
66 buf, err := ioutil.ReadAll(file)
67 if err != nil {
68 return ret, err
69 }
70
71 u := Utmpx{}
72 entrySize := int(unsafe.Sizeof(u))
73 count := len(buf) / entrySize
74
75 for i := 0; i < count; i++ {
76 b := buf[i*entrySize : i*entrySize+entrySize]
77
78 var u Utmpx
79 br := bytes.NewReader(b)
80 err := binary.Read(br, binary.LittleEndian, &u)
81 if err != nil {
82 continue
83 }
84 if u.Type != USER_PROCESS {
85 continue
86 }
87 user := UserStat{
88 User: common.IntToString(u.User[:]),
89 Terminal: common.IntToString(u.Line[:]),
90 Host: common.IntToString(u.Host[:]),
91 Started: int(u.Tv.Sec),
92 }
93 ret = append(ret, user)
94 }
95
96 return ret, nil
97
98 }
99
100 func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
101 platform := ""
102 family := ""
103 pver := ""
104
105 sw_vers, err := exec.LookPath("sw_vers")
106 if err != nil {
107 return "", "", "", err
108 }
109
110 p, err := unix.Sysctl("kern.ostype")
111 if err == nil {
112 platform = strings.ToLower(p)
113 }
114
115 out, err := invoke.CommandWithContext(ctx, sw_vers, "-productVersion")
116 if err == nil {
117 pver = strings.ToLower(strings.TrimSpace(string(out)))
118 }
119
120
121 _, err = os.Stat("/System/Library/CoreServices/ServerVersion.plist")
122
123
124 if os.IsNotExist(err) {
125 family = "Standalone Workstation"
126 } else {
127 family = "Server"
128 }
129
130 return platform, family, pver, nil
131 }
132
133 func VirtualizationWithContext(ctx context.Context) (string, string, error) {
134 return "", "", common.ErrNotImplementedError
135 }
136
137 func KernelVersionWithContext(ctx context.Context) (string, error) {
138 version, err := unix.Sysctl("kern.osrelease")
139 return strings.ToLower(version), err
140 }
141
View as plain text