1
2
3
4
5 package oshi.driver.unix;
6
7 import java.time.LocalDateTime;
8 import java.time.Year;
9 import java.time.ZoneId;
10 import java.time.format.DateTimeFormatter;
11 import java.time.format.DateTimeFormatterBuilder;
12 import java.time.format.DateTimeParseException;
13 import java.time.temporal.ChronoField;
14 import java.time.temporal.ChronoUnit;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Locale;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import com.sun.jna.Platform;
22
23 import oshi.annotation.concurrent.ThreadSafe;
24 import oshi.software.os.OSSession;
25 import oshi.util.Constants;
26 import oshi.util.ExecutingCommand;
27
28
29
30
31 @ThreadSafe
32 public final class Who {
33
34
35
36 private static final Pattern WHO_FORMAT_LINUX = Pattern
37 .compile("(\\S+)\\s+(\\S+)\\s+(\\d{4}-\\d{2}-\\d{2})\\s+(\\d{2}:\\d{2})\\s*(?:\\((.+)\\))?");
38 private static final DateTimeFormatter WHO_DATE_FORMAT_LINUX = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm",
39 Locale.ROOT);
40
41
42 private static final Pattern WHO_FORMAT_UNIX = Pattern
43 .compile("(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\d+)\\s+(\\d{2}:\\d{2})\\s*(?:\\((.+)\\))?");
44 private static final DateTimeFormatter WHO_DATE_FORMAT_UNIX = new DateTimeFormatterBuilder()
45 .appendPattern("MMM d HH:mm").parseDefaulting(ChronoField.YEAR, Year.now(ZoneId.systemDefault()).getValue())
46 .toFormatter(Locale.US);
47
48 private Who() {
49 }
50
51
52
53
54
55
56 public static synchronized List<OSSession> queryWho() {
57 List<OSSession> whoList = new ArrayList<>();
58 List<String> who = ExecutingCommand.runNative("who");
59 for (String s : who) {
60 boolean matched = false;
61 if (Platform.isLinux()) {
62 matched = matchLinux(whoList, s);
63 }
64 if (!matched) {
65 matchUnix(whoList, s);
66 }
67 }
68 return whoList;
69 }
70
71
72
73
74
75
76
77
78 private static boolean matchLinux(List<OSSession> whoList, String s) {
79 Matcher m = WHO_FORMAT_LINUX.matcher(s);
80 if (m.matches()) {
81 try {
82 whoList.add(new OSSession(m.group(1), m.group(2),
83 LocalDateTime.parse(m.group(3) + " " + m.group(4), WHO_DATE_FORMAT_LINUX)
84 .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(),
85 m.group(5) == null ? Constants.UNKNOWN : m.group(5)));
86 return true;
87 } catch (DateTimeParseException | NullPointerException e) {
88
89 }
90 }
91 return false;
92 }
93
94
95
96
97
98
99
100
101 private static boolean matchUnix(List<OSSession> whoList, String s) {
102 Matcher m = WHO_FORMAT_UNIX.matcher(s);
103 if (m.matches()) {
104 try {
105
106 LocalDateTime login = LocalDateTime.parse(m.group(3) + " " + m.group(4) + " " + m.group(5),
107 WHO_DATE_FORMAT_UNIX);
108
109 if (login.isAfter(LocalDateTime.now(ZoneId.systemDefault()))) {
110 login = login.minus(1, ChronoUnit.YEARS);
111 }
112 long millis = login.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
113 whoList.add(new OSSession(m.group(1), m.group(2), millis, m.group(6) == null ? "" : m.group(6)));
114 return true;
115 } catch (DateTimeParseException | NullPointerException e) {
116
117 }
118 }
119 return false;
120 }
121 }