exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / readutmp.h
blobdcfd44dbbc96e5428ed015224e04b9b82c911743
1 /* Declarations for GNU's read utmp module.
3 Copyright (C) 1992-2007, 2009-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
18 /* Written by jla; revised by djm */
20 #ifndef __READUTMP_H__
21 #define __READUTMP_H__
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
30 #include "idx.h"
32 #include <stdlib.h>
33 #include <sys/types.h>
34 #include <time.h>
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
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
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
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
64 /* Type of entries returned by read_utmp on all platforms. */
65 struct gl_utmp
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;
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)
90 /* Type of entry returned by read_utmp(). */
91 typedef struct gl_utmp STRUCT_UTMP;
93 /* Size of the UT_USER (ut) member, or -1 if unbounded. */
94 enum { UT_USER_SIZE = -1 };
96 /* Size of the ut->ut_id member, or -1 if unbounded. */
97 enum { UT_ID_SIZE = -1 };
99 /* Size of the ut->ut_line member, or -1 if unbounded. */
100 enum { UT_LINE_SIZE = -1 };
102 /* Size of the ut->ut_host member, or -1 if unbounded. */
103 enum { UT_HOST_SIZE = -1 };
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. */
111 #if HAVE_UTMPX_H
113 /* <utmpx.h> defines 'struct utmpx' with the following fields:
115 Field Type Platforms
116 ---------- ------ ---------
117 ⎡ ut_user char[] glibc, musl, macOS, FreeBSD, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
118 ⎣ ut_name char[] NetBSD, Minix
119 ut_id char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
120 ut_line char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
121 ut_pid pid_t glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
122 ut_type short glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
123 ⎡ ut_tv struct glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
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, Android
127 ut_exit struct glibc, musl, NetBSD, Minix, HP-UX, IRIX, Solaris, Android
128 { e_termination; e_exit; }
129 ut_session [long] int glibc, musl, NetBSD, Minix, IRIX, Solaris, Android
130 ⎡ ut_addr [long] int HP-UX, Cygwin
131 ⎢ ut_addr_v6 [u]int[4] glibc, musl, Android
132 ⎣ ut_ss struct sockaddr_storage NetBSD, Minix
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
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
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. */
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 # elif defined __ANDROID__ /* Android */
181 /* As of Android NDK r26, the getutxent, setutxent functions are no-ops.
182 Therefore we can ignore the file name. */
183 # define UTMP_NAME_FUNCTION(x) ((void) (x))
184 # endif
186 #elif HAVE_UTMP_H
188 /* <utmp.h> defines 'struct utmp' with the following fields:
190 Field Type Platforms
191 ---------- ------ ---------
192 ⎡ ut_user char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
193 ⎣ ut_name char[] macOS, old FreeBSD, NetBSD, OpenBSD, Minix
194 ut_id char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
195 ut_line char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
196 ut_pid pid_t glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
197 ut_type short glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
198 ⎡ ut_tv struct glibc, musl, Android
199 ⎢ { tv_sec; tv_usec; }
200 ⎣ ut_time time_t macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
201 ut_host char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Cygwin, Android
202 ut_exit struct glibc, musl, AIX, HP-UX, IRIX, Solaris, Android
203 { e_termination; e_exit; }
204 ut_session [long] int glibc, musl, Android
205 ⎡ ut_addr [long] int HP-UX, Cygwin
206 ⎣ ut_addr_v6 [u]int[4] glibc, musl, Android
209 # define UTMP_STRUCT_NAME utmp
210 # define SET_UTMP_ENT setutent
211 # define GET_UTMP_ENT getutent
212 # define END_UTMP_ENT endutent
213 # ifdef HAVE_UTMPNAME /* glibc, musl, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android */
214 # define UTMP_NAME_FUNCTION utmpname
215 # endif
217 #endif
219 /* Evaluates to 1 if gl_utmp's ut_id field may ever have a non-zero value. */
220 #define HAVE_STRUCT_XTMP_UT_ID \
221 (READUTMP_USE_SYSTEMD \
222 || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_ID : HAVE_STRUCT_UTMP_UT_ID))
224 /* Evaluates to 1 if gl_utmp's ut_pid field may ever have a non-zero value. */
225 #define HAVE_STRUCT_XTMP_UT_PID \
226 (READUTMP_USE_SYSTEMD \
227 || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_PID : HAVE_STRUCT_UTMP_UT_PID))
229 /* Evaluates to 1 if gl_utmp's ut_host field may ever be non-empty. */
230 #define HAVE_STRUCT_XTMP_UT_HOST \
231 (READUTMP_USE_SYSTEMD \
232 || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_HOST : HAVE_STRUCT_UTMP_UT_HOST))
234 /* Definition of UTMP_FILE.
235 On glibc systems, UTMP_FILE is "/var/run/utmp". */
236 #if !defined UTMP_FILE && defined _PATH_UTMP
237 # define UTMP_FILE _PATH_UTMP
238 #endif
239 #ifdef UTMPX_FILE /* Solaris, SysVr4 */
240 # undef UTMP_FILE
241 # define UTMP_FILE UTMPX_FILE
242 #endif
243 #ifndef UTMP_FILE
244 # define UTMP_FILE "/etc/utmp"
245 #endif
247 /* Definition of WTMP_FILE.
248 On glibc systems, UTMP_FILE is "/var/log/wtmp". */
249 #if !defined WTMP_FILE && defined _PATH_WTMP
250 # define WTMP_FILE _PATH_WTMP
251 #endif
252 #ifdef WTMPX_FILE /* Solaris, SysVr4 */
253 # undef WTMP_FILE
254 # define WTMP_FILE WTMPX_FILE
255 #endif
256 #ifndef WTMP_FILE
257 # define WTMP_FILE "/etc/wtmp"
258 #endif
260 /* In early versions of Android, <utmp.h> did not define BOOT_TIME, only
261 USER_PROCESS. We need to use the value that is defined in newer versions
262 of Android. */
263 #if defined __ANDROID__ && !defined BOOT_TIME
264 # define BOOT_TIME 2
265 #endif
267 /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have
268 the BOOT_TIME and USER_PROCESS macros. But we want to support them in
269 'struct gl_utmp'. */
270 #if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE)
271 # define BOOT_TIME 2
272 # define USER_PROCESS 0
273 #endif
275 /* Macros that test (UT)->ut_type. */
276 #ifdef BOOT_TIME
277 # define UT_TYPE_BOOT_TIME(UT) ((UT)->ut_type == BOOT_TIME)
278 #else
279 # define UT_TYPE_BOOT_TIME(UT) 0
280 #endif
281 #ifdef USER_PROCESS
282 # define UT_TYPE_USER_PROCESS(UT) ((UT)->ut_type == USER_PROCESS)
283 #else
284 # define UT_TYPE_USER_PROCESS(UT) 0
285 #endif
287 /* Determines whether an entry *UT corresponds to a user process. */
288 #define IS_USER_PROCESS(UT) \
289 ((UT)->ut_user[0] && UT_TYPE_USER_PROCESS (UT))
291 /* Define if read_utmp is not just a dummy. */
292 #if READUTMP_USE_SYSTEMD || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ || defined _WIN32
293 # define READ_UTMP_SUPPORTED 1
294 #endif
296 /* Options for read_utmp. */
297 enum
299 READ_UTMP_CHECK_PIDS = 1,
300 READ_UTMP_USER_PROCESS = 2,
301 READ_UTMP_BOOT_TIME = 4,
302 READ_UTMP_NO_BOOT_TIME = 8
305 /* Return a copy of (UT)->ut_user, without trailing spaces,
306 as a freshly allocated string. */
307 char *extract_trimmed_name (const STRUCT_UTMP *ut)
308 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
309 _GL_ATTRIBUTE_RETURNS_NONNULL;
311 /* Read the utmp entries corresponding to file FILE into freshly-
312 malloc'd storage, set *UTMP_BUF to that pointer, set *N_ENTRIES to
313 the number of entries, and return zero. If there is any error,
314 return -1, setting errno, and don't modify the parameters.
315 A good candidate for FILE is UTMP_FILE.
316 If OPTIONS & READ_UTMP_CHECK_PIDS is nonzero, omit entries whose
317 process-IDs do not currently exist.
318 If OPTIONS & READ_UTMP_USER_PROCESS is nonzero, omit entries which
319 do not correspond to a user process.
320 If OPTIONS & READ_UTMP_BOOT_TIME is nonzero, omit all entries except
321 the one that contains the boot time.
322 If OPTIONS & READ_UTMP_NO_BOOT_TIME is nonzero, omit the boot time
323 entries.
325 This function is not multithread-safe, since on many platforms it
326 invokes the functions setutxent, getutxent, endutxent. These
327 functions are needed because they may lock FILE (so that we don't
328 read garbage when a concurrent process writes to FILE), but their
329 drawback is that they have a common global state. */
330 int read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
331 int options);
334 #ifdef __cplusplus
336 #endif
338 #endif /* __READUTMP_H__ */