1 /* Declarations for GNU's read utmp module. 2 3 Copyright (C) 1992-2007, 2009-2023 Free Software Foundation, Inc. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 17 18 /* Written by jla; revised by djm */ 19 20 #ifndef __READUTMP_H__ 21 #define __READUTMP_H__ 22 23 /* This file uses _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_RETURNS_NONNULL, 24 HAVE_UTMP_H, HAVE_UTMPX_H, HAVE_STRUCT_UTMP_*, HAVE_STRUCT_UTMPX_*, 25 HAVE_UTMPNAME, HAVE_UTMPXNAME. */ 26 #if !_GL_CONFIG_H_INCLUDED 27 # error "Please include config.h first." 28 #endif 29 30 #include "idx.h" 31 32 #include <stdlib.h> 33 #include <sys/types.h> 34 #include <time.h> 35 36 /* AIX 4.3.3 has both utmp.h and utmpx.h, but only struct utmp 37 has the ut_exit member. */ 38 #if (HAVE_UTMPX_H && HAVE_UTMP_H && HAVE_STRUCT_UTMP_UT_EXIT \ 39 && ! HAVE_STRUCT_UTMPX_UT_EXIT) 40 # undef HAVE_UTMPX_H 41 #endif 42 43 /* HPUX 10.20 needs utmp.h, for the definition of e.g., UTMP_FILE. */ 44 #if HAVE_UTMP_H 45 # include <utmp.h> 46 #endif 47 48 /* Needed for BOOT_TIME and USER_PROCESS. */ 49 #if HAVE_UTMPX_H 50 # if defined _THREAD_SAFE && defined UTMP_DATA_INIT 51 /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE 52 defined, work around the duplicate struct utmp_data declaration. */ 53 # define utmp_data gl_aix_4_3_workaround_utmp_data 54 # endif 55 # include <utmpx.h> 56 #endif 57 58 59 #ifdef __cplusplus 60 extern "C" { 61 #endif 62 63 64 /* Type of entries returned by read_utmp on all platforms. */ 65 struct gl_utmp 66 { 67 /* All 'char *' here are of arbitrary length and point to storage 68 with lifetime equal to that of this struct. */ 69 char *ut_user; /* User name */ 70 char *ut_id; /* Session ID */ 71 char *ut_line; /* seat / device */ 72 char *ut_host; /* for remote sessions: user@host or host, 73 for local sessions: the X11 display :N */ 74 struct timespec ut_ts; /* time */ 75 pid_t ut_pid; /* process ID of ? */ 76 pid_t ut_session; /* process ID of session leader */ 77 short ut_type; /* BOOT_TIME, USER_PROCESS, or other */ 78 struct { int e_termination; int e_exit; } ut_exit; 79 }; 80 81 /* The following types, macros, and constants describe the 'struct gl_utmp'. */ 82 #define UT_USER(UT) ((UT)->ut_user) 83 #define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec) 84 #define UT_PID(UT) ((UT)->ut_pid) 85 #define UT_TYPE_EQ(UT, V) ((UT)->ut_type == (V)) 86 #define UT_TYPE_NOT_DEFINED 0 87 #define UT_EXIT_E_TERMINATION(UT) ((UT)->ut_exit.e_termination) 88 #define UT_EXIT_E_EXIT(UT) ((UT)->ut_exit.e_exit) 89 90 /* Type of entry returned by read_utmp(). */ 91 typedef struct gl_utmp STRUCT_UTMP; 92 93 /* Size of the UT_USER (ut) member, or -1 if unbounded. */ 94 enum { UT_USER_SIZE = -1 }; 95 96 /* Size of the ut->ut_id member, or -1 if unbounded. */ 97 enum { UT_ID_SIZE = -1 }; 98 99 /* Size of the ut->ut_line member, or -1 if unbounded. */ 100 enum { UT_LINE_SIZE = -1 }; 101 102 /* Size of the ut->ut_host member, or -1 if unbounded. */ 103 enum { UT_HOST_SIZE = -1 }; 104 105 106 /* When read_utmp accesses a file (as opposed to fetching the information 107 from systemd), it uses the following low-level types and macros. 108 Keep them here, rather than moving them into readutmp.c, for backward 109 compatibility. */ 110 111 #if HAVE_UTMPX_H 112 113 /* <utmpx.h> defines 'struct utmpx' with the following fields: 114 115 Field Type Platforms 116 ---------- ------ --------- 117 ⎡ ut_user char[] glibc, musl, macOS, FreeBSD, AIX, HP-UX, IRIX, Solaris, Cygwin 118 ⎣ ut_name char[] NetBSD, Minix 119 ut_id char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 120 ut_line char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 121 ut_pid pid_t glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 122 ut_type short glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 123 ⎡ ut_tv struct glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 124 ⎢ { tv_sec; tv_usec; } 125 ⎣ ut_time time_t Cygwin 126 ut_host char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 127 ut_exit struct glibc, musl, NetBSD, Minix, HP-UX, IRIX, Solaris 128 { e_termination; e_exit; } 129 ut_session [long] int glibc, musl, NetBSD, Minix, IRIX, Solaris 130 ⎡ ut_addr [long] int HP-UX, Cygwin 131 ⎢ ut_addr_v6 [u]int[4] glibc, musl 132 ⎣ ut_ss struct sockaddr_storage NetBSD, Minix 133 */ 134 135 # if __GLIBC__ && _TIME_BITS == 64 136 /* This is a near-copy of glibc's struct utmpx, which stops working 137 after the year 2038. Unlike the glibc version, struct utmpx32 138 describes the file format even if time_t is 64 bits. */ 139 #define _GL_UT_USER_SIZE sizeof (((struct utmpx *) 0)->ut_user) 140 #define _GL_UT_ID_SIZE sizeof (((struct utmpx *) 0)->ut_id) 141 #define _GL_UT_LINE_SIZE sizeof (((struct utmpx *) 0)->ut_line) 142 #define _GL_UT_HOST_SIZE sizeof (((struct utmpx *) 0)->ut_host) 143 struct utmpx32 144 { 145 short int ut_type; /* Type of login. */ 146 pid_t ut_pid; /* Process ID of login process. */ 147 char ut_line[_GL_UT_LINE_SIZE]; /* Devicename. */ 148 char ut_id[_GL_UT_ID_SIZE]; /* Inittab ID. */ 149 char ut_user[_GL_UT_USER_SIZE]; /* Username. */ 150 char ut_host[_GL_UT_HOST_SIZE]; /* Hostname for remote login. */ 151 struct __exit_status ut_exit; /* Exit status of a process marked 152 as DEAD_PROCESS. */ 153 /* The fields ut_session and ut_tv must be the same size when compiled 154 32- and 64-bit. This allows files and shared memory to be shared 155 between 32- and 64-bit applications. */ 156 int ut_session; /* Session ID, used for windowing. */ 157 struct 158 { 159 /* Seconds. Unsigned not signed, as glibc did not exist before 1970, 160 and if the format is still in use after 2038 its timestamps 161 will surely have the sign bit on. This hack stops working 162 at 2106-02-07 06:28:16 UTC. */ 163 unsigned int tv_sec; 164 int tv_usec; /* Microseconds. */ 165 } ut_tv; /* Time entry was made. */ 166 int ut_addr_v6[4]; /* Internet address of remote host. */ 167 char ut_reserved[20]; /* Reserved for future use. */ 168 }; 169 # define UTMP_STRUCT_NAME utmpx32 170 # else 171 # define UTMP_STRUCT_NAME utmpx 172 # endif 173 # define SET_UTMP_ENT setutxent 174 # define GET_UTMP_ENT getutxent 175 # define END_UTMP_ENT endutxent 176 # ifdef HAVE_UTMPXNAME /* glibc, musl, macOS, NetBSD, Minix, IRIX, Solaris, Cygwin */ 177 # define UTMP_NAME_FUNCTION utmpxname 178 # elif defined UTXDB_ACTIVE /* FreeBSD */ 179 # define UTMP_NAME_FUNCTION(x) setutxdb (UTXDB_ACTIVE, x) 180 # endif 181 182 #elif HAVE_UTMP_H 183 184 /* <utmp.h> defines 'struct utmp' with the following fields: 185 186 Field Type Platforms 187 ---------- ------ --------- 188 ⎡ ut_user char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android 189 ⎣ ut_name char[] macOS, old FreeBSD, NetBSD, OpenBSD, Minix 190 ut_id char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android 191 ut_line char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android 192 ut_pid pid_t glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android 193 ut_type short glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android 194 ⎡ ut_tv struct glibc, musl, Android 195 ⎢ { tv_sec; tv_usec; } 196 ⎣ ut_time time_t macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin 197 ut_host char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Cygwin, Android 198 ut_exit struct glibc, musl, AIX, HP-UX, IRIX, Solaris, Android 199 { e_termination; e_exit; } 200 ut_session [long] int glibc, musl, Android 201 ⎡ ut_addr [long] int HP-UX, Cygwin 202 ⎣ ut_addr_v6 [u]int[4] glibc, musl, Android 203 */ 204 205 # define UTMP_STRUCT_NAME utmp 206 # define SET_UTMP_ENT setutent 207 # define GET_UTMP_ENT getutent 208 # define END_UTMP_ENT endutent 209 # ifdef HAVE_UTMPNAME /* glibc, musl, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android */ 210 # define UTMP_NAME_FUNCTION utmpname 211 # endif 212 213 #endif 214 215 /* Evaluates to 1 if gl_utmp's ut_id field may ever have a non-zero value. */ 216 #define HAVE_STRUCT_XTMP_UT_ID \ 217 (READUTMP_USE_SYSTEMD \ 218 || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_ID : HAVE_STRUCT_UTMP_UT_ID)) 219 220 /* Evaluates to 1 if gl_utmp's ut_pid field may ever have a non-zero value. */ 221 #define HAVE_STRUCT_XTMP_UT_PID \ 222 (READUTMP_USE_SYSTEMD \ 223 || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_PID : HAVE_STRUCT_UTMP_UT_PID)) 224 225 /* Evaluates to 1 if gl_utmp's ut_host field may ever be non-empty. */ 226 #define HAVE_STRUCT_XTMP_UT_HOST \ 227 (READUTMP_USE_SYSTEMD \ 228 || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_HOST : HAVE_STRUCT_UTMP_UT_HOST)) 229 230 /* Definition of UTMP_FILE. 231 On glibc systems, UTMP_FILE is "/var/run/utmp". */ 232 #if !defined UTMP_FILE && defined _PATH_UTMP 233 # define UTMP_FILE _PATH_UTMP 234 #endif 235 #ifdef UTMPX_FILE /* Solaris, SysVr4 */ 236 # undef UTMP_FILE 237 # define UTMP_FILE UTMPX_FILE 238 #endif 239 #ifndef UTMP_FILE 240 # define UTMP_FILE "/etc/utmp" 241 #endif 242 243 /* Definition of WTMP_FILE. 244 On glibc systems, UTMP_FILE is "/var/log/wtmp". */ 245 #if !defined WTMP_FILE && defined _PATH_WTMP 246 # define WTMP_FILE _PATH_WTMP 247 #endif 248 #ifdef WTMPX_FILE /* Solaris, SysVr4 */ 249 # undef WTMP_FILE 250 # define WTMP_FILE WTMPX_FILE 251 #endif 252 #ifndef WTMP_FILE 253 # define WTMP_FILE "/etc/wtmp" 254 #endif 255 256 /* In early versions of Android, <utmp.h> did not define BOOT_TIME, only 257 USER_PROCESS. We need to use the value that is defined in newer versions 258 of Android. */ 259 #if defined __ANDROID__ && !defined BOOT_TIME 260 # define BOOT_TIME 2 261 #endif 262 263 /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have 264 the BOOT_TIME and USER_PROCESS macros. But we want to support them in 265 'struct gl_utmp'. */ 266 #if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) 267 # define BOOT_TIME 2 268 # define USER_PROCESS 0 269 #endif 270 271 /* Macros that test (UT)->ut_type. */ 272 #ifdef BOOT_TIME 273 # define UT_TYPE_BOOT_TIME(UT) ((UT)->ut_type == BOOT_TIME) 274 #else 275 # define UT_TYPE_BOOT_TIME(UT) 0 276 #endif 277 #ifdef USER_PROCESS 278 # define UT_TYPE_USER_PROCESS(UT) ((UT)->ut_type == USER_PROCESS) 279 #else 280 # define UT_TYPE_USER_PROCESS(UT) 0 281 #endif 282 283 /* Determines whether an entry *UT corresponds to a user process. */ 284 #define IS_USER_PROCESS(UT) \ 285 ((UT)->ut_user[0] && UT_TYPE_USER_PROCESS (UT)) 286 287 /* Define if read_utmp is not just a dummy. */ 288 #if READUTMP_USE_SYSTEMD || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ || defined _WIN32 289 # define READ_UTMP_SUPPORTED 1 290 #endif 291 292 /* Options for read_utmp. */ 293 enum 294 { 295 READ_UTMP_CHECK_PIDS = 1, 296 READ_UTMP_USER_PROCESS = 2, 297 READ_UTMP_BOOT_TIME = 4, 298 READ_UTMP_NO_BOOT_TIME = 8 299 }; 300 301 /* Return a copy of (UT)->ut_user, without trailing spaces, 302 as a freshly allocated string. */ 303 char *extract_trimmed_name (const STRUCT_UTMP *ut) 304 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE 305 _GL_ATTRIBUTE_RETURNS_NONNULL; 306 307 /* Read the utmp entries corresponding to file FILE into freshly- 308 malloc'd storage, set *UTMP_BUF to that pointer, set *N_ENTRIES to 309 the number of entries, and return zero. If there is any error, 310 return -1, setting errno, and don't modify the parameters. 311 A good candidate for FILE is UTMP_FILE. 312 If OPTIONS & READ_UTMP_CHECK_PIDS is nonzero, omit entries whose 313 process-IDs do not currently exist. 314 If OPTIONS & READ_UTMP_USER_PROCESS is nonzero, omit entries which 315 do not correspond to a user process. 316 If OPTIONS & READ_UTMP_BOOT_TIME is nonzero, omit all entries except 317 the one that contains the boot time. 318 If OPTIONS & READ_UTMP_NO_BOOT_TIME is nonzero, omit the boot time 319 entries. 320 321 This function is not multithread-safe, since on many platforms it 322 invokes the functions setutxent, getutxent, endutxent. These 323 functions are needed because they may lock FILE (so that we don't 324 read garbage when a concurrent process writes to FILE), but their 325 drawback is that they have a common global state. */ 326 int read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, 327 int options); 328 329 330 #ifdef __cplusplus 331 } 332 #endif 333 334 #endif /* __READUTMP_H__ */