diff --git a/cpu_freebsd.go b/cpu_freebsd.go index 674e747d5527606e364a37f2994b377914fc2270..eb3a1a470af938c7d379491f508aea5c5bffafb3 100644 --- a/cpu_freebsd.go +++ b/cpu_freebsd.go @@ -2,10 +2,6 @@ package gopsutil -import ( - "fmt" -) - func Cpu_times() ([]CPU_TimesStat, error) { ret := make([]CPU_TimesStat, 0) diff --git a/host_freebsd.go b/host_freebsd.go index abe299b7a7db2207487bb9097094a70c6bb9e313..d5cc1e67501eba0d173c476117d87f9c62e0da32 100644 --- a/host_freebsd.go +++ b/host_freebsd.go @@ -3,11 +3,28 @@ package gopsutil import ( + "bytes" + "encoding/binary" + "io/ioutil" "os" "strconv" "strings" + "unsafe" ) +const ( + UT_NAMESIZE = 16 /* see MAXLOGNAME in */ + UT_LINESIZE = 8 + UT_HOSTSIZE = 16 +) + +type utmp struct { + Ut_line [UT_LINESIZE]byte + Ut_name [UT_NAMESIZE]byte + Ut_host [UT_HOSTSIZE]byte + Ut_time int32 +} + func HostInfo() (HostInfoStat, error) { ret := HostInfoStat{} @@ -35,3 +52,43 @@ func Boot_time() (int64, error) { return boottime, nil } + +func Users() ([]UserStat, error) { + utmpfile := "/var/run/utmp" + ret := make([]UserStat, 0) + + file, err := os.Open(utmpfile) + if err != nil { + return ret, err + } + + buf, err := ioutil.ReadAll(file) + if err != nil { + return ret, err + } + + u := utmp{} + entrySize := int(unsafe.Sizeof(u)) + count := len(buf) / entrySize + + for i := 0; i < count; i++ { + b := buf[i*entrySize : i*entrySize+entrySize] + + var u utmp + br := bytes.NewReader(b) + err := binary.Read(br, binary.LittleEndian, &u) + if err != nil { + continue + } + user := UserStat{ + User: byteToString(u.Ut_name[:]), + Terminal: byteToString(u.Ut_line[:]), + Host: byteToString(u.Ut_host[:]), + Started: int(u.Ut_time), + } + ret = append(ret, user) + } + + return ret, nil + +}