-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser_info.go
94 lines (87 loc) · 2.57 KB
/
user_info.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
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"regexp"
"runtime"
"strings"
)
// getActiveUsers retrieves a map of active users and their terminals.
func getActiveUsers() (map[string][]string, error) {
out, err := exec.Command("ps", "aux").Output()
if err != nil {
return nil, err
}
activeUsers := make(map[string][]string)
lines := strings.Split(string(out), "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) > 1 {
user := fields[0]
tty := fields[6]
if strings.HasPrefix(tty, "pts") {
if _, found := activeUsers[tty]; !found {
activeUsers[tty] = []string{}
}
fullUserName, err := getFullUserName(user)
if err == nil {
user = fullUserName
}
if !contains(activeUsers[tty], user) {
activeUsers[tty] = append(activeUsers[tty], user)
}
}
}
}
return activeUsers, nil
}
// getFullUserName retrieves the full username from /etc/passwd.
func getFullUserName(shortName string) (string, error) {
file, err := os.Open("/etc/passwd")
if err != nil {
return shortName, err
}
defer file.Close()
trimmedShortName := strings.TrimSuffix(shortName, "+")
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
parts := strings.Split(line, ":")
if len(parts) > 0 {
userName := parts[0]
if strings.HasPrefix(userName, trimmedShortName) {
return userName, nil
}
}
}
if err := scanner.Err(); err != nil {
return shortName, err
}
return shortName, nil
}
// getCurrentPTS retrieves the current terminal (PTS).
func getCurrentPTS() (string, error) {
if runtime.GOOS == "linux" {
tty, err := os.Readlink("/proc/self/fd/0")
if err != nil {
return "", err
}
re := regexp.MustCompile(`(pts/\d+|ttyS?\d*)`)
pts := re.FindString(tty)
if pts == "" {
return "", fmt.Errorf("could not parse PTS")
}
return pts, nil
} else if runtime.GOOS == "darwin" {
ttyNumber := os.Getenv("_P9K_SSH_TTY")
re := regexp.MustCompile(`(ttys?\d*)`)
pts := re.FindString(ttyNumber)
if ttyNumber == "" {
return "not available", nil
}
return pts, nil
}
return "", fmt.Errorf("unsupported platform")
}