Allow some utmpx fields to be optional

POSIX.1 doesn't define ut_host in struct utmpx. Also, Linux has support
for an exit status value in ut_exit. This commit adds conditional code
for both ut_host and ut_exit to maximise portability.
This commit is contained in:
matt335672 2023-06-29 17:27:06 +01:00
parent 04c67a5039
commit b53c683edf
5 changed files with 77 additions and 12 deletions

View File

@ -523,6 +523,10 @@ AC_CHECK_HEADER([X11/extensions/Xrandr.h], [],
if test "x$enable_utmp" = "xyes" if test "x$enable_utmp" = "xyes"
then then
AC_CHECK_HEADERS(utmp.h utmpx.h) AC_CHECK_HEADERS(utmp.h utmpx.h)
# Test for non-standard extensions in struct utmpx
AXRDP_CHECK_UTMPX_MEMBER_EXISTS([ut_host], [HAVE_UTMPX_UT_HOST])
AXRDP_CHECK_UTMPX_MEMBER_EXISTS([ut_exit], [HAVE_UTMPX_UT_EXIT])
fi fi
CFLAGS="$save_CFLAGS" CFLAGS="$save_CFLAGS"
@ -643,6 +647,11 @@ echo " vsock $enable_vsock"
echo " auth mechanism $auth_mech" echo " auth mechanism $auth_mech"
echo " rdpsndaudin $enable_rdpsndaudin" echo " rdpsndaudin $enable_rdpsndaudin"
echo " utmp support $enable_utmp" echo " utmp support $enable_utmp"
if test x$enable_utmp = xyes; then
echo " utmpx.ut_host $ac_cv_utmpx_has_ut_host"
echo " utmpx.ut_exit $ac_cv_utmpx_has_ut_exit"
fi
echo echo
echo " with imlib2 $use_imlib2" echo " with imlib2 $use_imlib2"
echo " with freetype2 $use_freetype2" echo " with freetype2 $use_freetype2"

43
m4/axrdp.m4 Normal file
View File

@ -0,0 +1,43 @@
# SYNOPSIS
#
# AXRDP_CHECK_UTMPX_MEMBER_EXISTS(MEMBER, COMPILE-DEFINE)
#
# EXAMPLE
#
# AXRDP_CHECK_UTMPX_MEMBER_EXISTS([ut_exit], [HAVE_UTMPX_UT_EXIT])
#
# DESCRIPTION
#
# If the member MEMBER exists in the utmpx struct, the COMPILE-DEFINE
# is set for the C compiler.
#
# The shell variable 'ac_cv_utmpx_has_$MEMBER' is set to 'yes' or 'no'
# and cached
#
AC_DEFUN([AXRDP_CHECK_UTMPX_MEMBER_EXISTS],
[
AS_VAR_PUSHDEF([x_var], [ac_cv_utmpx_has_$1])
AS_VAR_PUSHDEF([x_define], [$2])
AC_CACHE_CHECK(
[for $1 in struct utmpx],
[x_var],
[AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
# include <utmpx.h>
# include <stddef.h>
int main()
{
return offsetof(struct utmpx,$1);
}]])],
[AS_VAR_SET([x_var], [yes])],
[AS_VAR_SET([x_var], [no])])]
)
AS_VAR_IF(
[x_var],
[yes],
[AC_DEFINE([x_define], [1], [Define if '$1' is in struct utmpx.])])
AS_VAR_POPDEF([x_var])
AS_VAR_POPDEF([x_define])
])

View File

@ -888,7 +888,7 @@ session_process_child_exit(struct session_data *sd,
sd->win_mgr, sd->params.display, wm_wait_time); sd->win_mgr, sd->params.display, wm_wait_time);
} }
utmp_logout(sd->win_mgr, sd->params.display); utmp_logout(sd->win_mgr, sd->params.display, e);
sd->win_mgr = -1; sd->win_mgr = -1;
if (sd->x_server > 0) if (sd->x_server > 0)

View File

@ -48,10 +48,6 @@ enum add_xtmp_mode
#ifdef USE_UTMP #ifdef USE_UTMP
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
@ -80,7 +76,7 @@ typedef struct utmp _utmp;
static void static void
add_xtmp_entry(int pid, int display, const struct login_info *login_info, add_xtmp_entry(int pid, int display, const struct login_info *login_info,
enum add_xtmp_mode mode) enum add_xtmp_mode mode, const struct proc_exit_status *e)
{ {
#if USE_UTMP #if USE_UTMP
char idbuff[16]; char idbuff[16];
@ -102,10 +98,23 @@ add_xtmp_entry(int pid, int display, const struct login_info *login_info,
g_strncpy(ut.ut_id, idbuff, sizeof(ut.ut_id)); g_strncpy(ut.ut_id, idbuff, sizeof(ut.ut_id));
if (login_info != NULL) if (login_info != NULL)
{ {
g_strncpy(ut.ut_user, login_info->username , sizeof(ut.ut_user)); g_strncpy(ut.ut_user, login_info->username, sizeof(ut.ut_user));
#ifdef HAVE_UTMPX_UT_HOST
g_strncpy(ut.ut_host, login_info->ip_addr, sizeof(ut.ut_host)); g_strncpy(ut.ut_host, login_info->ip_addr, sizeof(ut.ut_host));
#endif
} }
#ifdef HAVE_UTMPX_UT_EXIT
if (e != NULL && e->reason == E_PXR_STATUS_CODE)
{
ut.ut_exit.e_exit = e->val;
}
else if (e != NULL && e->reason == E_PXR_SIGNAL)
{
ut.ut_exit.e_termination = e->val;
}
#endif
/* update the utmp file */ /* update the utmp file */
/* open utmp */ /* open utmp */
setutxent(); setutxent();
@ -124,15 +133,15 @@ utmp_login(int pid, int display, const struct login_info *login_info)
"adding login info for utmp: %d - %d - %s - %s", "adding login info for utmp: %d - %d - %s - %s",
pid, display, login_info->username, login_info->ip_addr); pid, display, login_info->username, login_info->ip_addr);
add_xtmp_entry(pid, display, login_info, MODE_LOGIN); add_xtmp_entry(pid, display, login_info, MODE_LOGIN, NULL);
} }
void void
utmp_logout(int pid, int display) utmp_logout(int pid, int display, const struct proc_exit_status *exit_status)
{ {
log_message(LOG_LEVEL_DEBUG, "adding logout info for utmp: %d - %d", log_message(LOG_LEVEL_DEBUG, "adding logout info for utmp: %d - %d",
pid, display); pid, display);
add_xtmp_entry(pid, display, NULL, MODE_LOGOUT); add_xtmp_entry(pid, display, NULL, MODE_LOGOUT, exit_status);
} }

View File

@ -27,6 +27,7 @@
#define SESSIONRECORD_H #define SESSIONRECORD_H
struct login_info; struct login_info;
struct proc_exit_status;
/** /**
* @brief Record login in utmp * @brief Record login in utmp
@ -35,14 +36,17 @@ struct login_info;
* @param display Display number * @param display Display number
* @param login_info Information about logged in user * @param login_info Information about logged in user
*/ */
void utmp_login(int pid, int display, const struct login_info *login_info); void
utmp_login(int pid, int display, const struct login_info *login_info);
/** /**
* @brief Record logout in utmp * @brief Record logout in utmp
* *
* @param pid PID of window manager * @param pid PID of window manager
* @param display Display number * @param display Display number
* @param exit_status Exit status of process
*/ */
void utmp_logout(int pid, int display); void
utmp_logout(int pid, int display, const struct proc_exit_status *exit_status);
#endif #endif