|
|
|
@ -1,12 +1,39 @@
|
|
|
|
|
// +build linux
|
|
|
|
|
// +build linux,amd64
|
|
|
|
|
|
|
|
|
|
package gopsutil
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"bytes"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"os"
|
|
|
|
|
"syscall"
|
|
|
|
|
"unsafe"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type exit_status struct {
|
|
|
|
|
E_termination int16 // Process termination status.
|
|
|
|
|
E_exit int16 // Process exit status.
|
|
|
|
|
}
|
|
|
|
|
type timeval struct {
|
|
|
|
|
Tv_sec uint32 // Seconds.
|
|
|
|
|
Tv_usec uint32 // Microseconds.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type utmp struct {
|
|
|
|
|
Ut_type int16 // Type of login.
|
|
|
|
|
Ut_pid int32 // Process ID of login process.
|
|
|
|
|
Ut_line [32]byte // Devicename.
|
|
|
|
|
Ut_id [4]byte // Inittab ID.
|
|
|
|
|
Ut_user [32]byte // Username.
|
|
|
|
|
Ut_host [256]byte // Hostname for remote login.
|
|
|
|
|
Ut_exit exit_status // Exit status of a process marked
|
|
|
|
|
Ut_session int32 // Session ID, used for windowing.
|
|
|
|
|
Ut_tv timeval // Time entry was made.
|
|
|
|
|
Ut_addr_v6 [16]byte // Internet address of remote host.
|
|
|
|
|
Unused [20]byte // Reserved for future use. // original is 20
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func HostInfo() (HostInfoStat, error) {
|
|
|
|
|
ret := HostInfoStat{}
|
|
|
|
|
|
|
|
|
@ -19,11 +46,50 @@ func HostInfo() (HostInfoStat, error) {
|
|
|
|
|
return ret, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func Boot_time() (int64, error){
|
|
|
|
|
func Boot_time() (int64, error) {
|
|
|
|
|
sysinfo := &syscall.Sysinfo_t{}
|
|
|
|
|
if err := syscall.Sysinfo(sysinfo); err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return sysinfo.Uptime, 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_user[:]),
|
|
|
|
|
Terminal: byteToString(u.Ut_line[:]),
|
|
|
|
|
Host: byteToString(u.Ut_host[:]),
|
|
|
|
|
Started: int(u.Ut_tv.Tv_sec),
|
|
|
|
|
}
|
|
|
|
|
ret = append(ret, user)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret, nil
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|