View Javadoc
1   /*
2    * Copyright 2020-2023 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.driver.linux;
6   
7   import static oshi.jna.platform.unix.CLibrary.LOGIN_PROCESS;
8   import static oshi.jna.platform.unix.CLibrary.USER_PROCESS;
9   import static oshi.util.Util.isSessionValid;
10  
11  import java.nio.charset.Charset;
12  import java.util.ArrayList;
13  import java.util.List;
14  
15  import com.sun.jna.Native;
16  
17  import oshi.annotation.concurrent.ThreadSafe;
18  import oshi.jna.platform.linux.LinuxLibc;
19  import oshi.jna.platform.linux.LinuxLibc.LinuxUtmpx;
20  import oshi.software.os.OSSession;
21  import oshi.util.ParseUtil;
22  
23  /**
24   * Utility to query logged in users.
25   */
26  @ThreadSafe
27  public final class Who {
28  
29      private static final LinuxLibc LIBC = LinuxLibc.INSTANCE;
30  
31      private Who() {
32      }
33  
34      /**
35       * Query {@code getutxent} to get logged in users.
36       *
37       * @return A list of logged in user sessions
38       */
39      public static synchronized List<OSSession> queryUtxent() {
40          List<OSSession> whoList = new ArrayList<>();
41          LinuxUtmpx ut;
42          // Rewind
43          LIBC.setutxent();
44          try {
45              // Iterate
46              while ((ut = LIBC.getutxent()) != null) {
47                  if (ut.ut_type == USER_PROCESS || ut.ut_type == LOGIN_PROCESS) {
48                      String user = Native.toString(ut.ut_user, Charset.defaultCharset());
49                      String device = Native.toString(ut.ut_line, Charset.defaultCharset());
50                      String host = ParseUtil.parseUtAddrV6toIP(ut.ut_addr_v6);
51                      long loginTime = ut.ut_tv.tv_sec * 1000L + ut.ut_tv.tv_usec / 1000L;
52                      // Sanity check. If errors, default to who command line
53                      if (!isSessionValid(user, device, loginTime)) {
54                          return oshi.driver.unix.Who.queryWho();
55                      }
56                      whoList.add(new OSSession(user, device, loginTime, host));
57                  }
58              }
59          } finally {
60              // Close
61              LIBC.endutxent();
62          }
63          return whoList;
64      }
65  }