root/lib/readutmp.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


     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__ */

/* [<][>][^][v][top][bottom][index][help] */