Add a working implementation of host.Users() for AIX

pull/1651/head
Dylan Myers 1 year ago
parent d551997afb
commit bd42769f87

@ -4,9 +4,7 @@
package host package host
import ( import (
"bytes"
"context" "context"
"encoding/binary"
"errors" "errors"
"strconv" "strconv"
"strings" "strings"
@ -81,30 +79,40 @@ func UptimeWithContext(ctx context.Context) (uint64, error) {
return uint64(total_time), nil return uint64(total_time), nil
} }
// This is probably broken, it doesn't seem to work even with CGO // This is a weak implementation due to the limitations on retrieving this data in AIX
func UsersWithContext(ctx context.Context) ([]UserStat, error) { func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat var ret []UserStat
ut, err := invoke.CommandWithContext(ctx, "w").Output() out, err := invoke.CommandWithContext(ctx, "w").Output()
if err != nil {
for i := 0; i < count; i++ { return nil, err
b := buf[i*sizeOfUtmp : (i+1)*sizeOfUtmp] }
lines := strings.Split(string(out), "\n")
if len(lines) < 3 {
return []UserStat{}, common.ErrNotImplementedError
}
var u utmp hf := strings.Fields(lines[1]) // headers
br := bytes.NewReader(b) for l := 2; l < len(lines)-1; l++ {
err := binary.Read(br, binary.LittleEndian, &u) v := strings.Fields(lines[l]) // values
if err != nil { us := &UserStat{}
continue for i, header := range hf {
// We're done in any of these use cases
if i >= len(v) || v[0] == "-" {
break
}
if t, err := strconv.ParseFloat(v[i], 64); err == nil {
switch header {
case `User`:
us.User = t
case `tty`:
us.Terminal = t
}
}
} }
if u.Type != user_PROCESS {
continue // Valid User data, so append it
} ret = append(ret, *us)
user := UserStat{
User: common.IntToString(u.User[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(u.Tv.Sec),
}
ret = append(ret, user)
} }
return ret, nil return ret, nil

Loading…
Cancel
Save