diff --git a/configure.ac b/configure.ac
index 41068a5d..6bc88cfd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,12 +74,6 @@ AC_CHECK_MEMBERS([struct utmp.ut_type,
struct utmp.ut_time,
struct utmp.ut_xtime,
struct utmp.ut_tv],,,[[#include <utmp.h>]])
-dnl There are dependencies:
-dnl If UTMPX has to be used, the utmp structure shall have a ut_id field.
-if test "$ac_cv_header_utmpx_h" = "yes" &&
- test "$ac_cv_member_struct_utmp_ut_id" != "yes"; then
- AC_MSG_ERROR(Systems with UTMPX and no ut_id field in the utmp structure are not supported)
-fi
AC_CHECK_MEMBERS([struct utmpx.ut_name,
struct utmpx.ut_host,
diff --git a/lib/prototypes.h b/lib/prototypes.h
index b7d48881..d9e7f6f4 100644
--- a/lib/prototypes.h
+++ b/lib/prototypes.h
@@ -416,17 +416,19 @@ extern int set_filesize_limit (int blocks);
extern int user_busy (const char *name, uid_t uid);
/* utmp.c */
+#ifndef USE_UTMPX
extern /*@null@*/struct utmp *get_current_utmp (void);
extern struct utmp *prepare_utmp (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut);
extern int setutmp (struct utmp *ut);
-#ifdef USE_UTMPX
+#else
+extern /*@null@*/struct utmpx *get_current_utmp (void);
extern struct utmpx *prepare_utmpx (const char *name,
const char *line,
const char *host,
- /*@null@*/const struct utmp *ut);
+ /*@null@*/const struct utmpx *ut);
extern int setutmpx (struct utmpx *utx);
#endif /* USE_UTMPX */
diff --git a/libmisc/utmp.c b/libmisc/utmp.c
index f5614a22..ba69cf61 100644
--- a/libmisc/utmp.c
+++ b/libmisc/utmp.c
@@ -35,10 +35,10 @@
#include "defines.h"
#include "prototypes.h"
-#include <utmp.h>
-
#ifdef USE_UTMPX
#include <utmpx.h>
+#else
+#include <utmp.h>
#endif
#include <assert.h>
@@ -97,6 +97,7 @@ static bool is_my_tty (const char *tty)
*
* Return NULL if no entries exist in utmp for the current process.
*/
+#ifndef USE_UTMPX
/*@null@*/ /*@only@*/struct utmp *get_current_utmp (void)
{
struct utmp *ut;
@@ -130,6 +131,36 @@ static bool is_my_tty (const char *tty)
return ret;
}
+#else
+/*@null@*/ /*@only*/struct utmpx *get_current_utmp(void)
+{
+ struct utmpx *ut;
+ struct utmpx *ret = NULL;
+
+ setutxent ();
+
+ /* Find the utmpx entry for this PID. */
+ while ((ut = getutxent ()) != NULL) {
+ if ( (ut->ut_pid == getpid ())
+ && ('\0' != ut->ut_id[0])
+ && ( (LOGIN_PROCESS == ut->ut_type)
+ || (USER_PROCESS == ut->ut_type))
+ && is_my_tty (ut->ut_line)) {
+ break;
+ }
+ }
+
+ if (NULL != ut) {
+ ret = (struct utmpx *) xmalloc (sizeof (*ret));
+ memcpy (ret, ut, sizeof (*ret));
+ }
+
+ endutxent ();
+
+ return ret;
+}
+#endif
+
#ifndef USE_PAM
/*
@@ -166,6 +197,7 @@ static void updwtmpx (const char *filename, const struct utmpx *utx)
#endif /* ! USE_PAM */
+#ifndef USE_UTMPX
/*
* prepare_utmp - prepare an utmp entry so that it can be logged in a
* utmp/wtmp file.
@@ -325,14 +357,14 @@ int setutmp (struct utmp *ut)
return err;
}
-#ifdef USE_UTMPX
+#else
/*
* prepare_utmpx - the UTMPX version for prepare_utmp
*/
/*@only@*/struct utmpx *prepare_utmpx (const char *name,
const char *line,
const char *host,
- /*@null@*/const struct utmp *ut)
+ /*@null@*/const struct utmpx *ut)
{
struct timeval tv;
char *hostname = NULL;
@@ -398,7 +430,7 @@ int setutmp (struct utmp *ut)
struct sockaddr_in *sa =
(struct sockaddr_in *) info->ai_addr;
#ifdef HAVE_STRUCT_UTMPX_UT_ADDR
- memcpy (utxent->ut_addr,
+ memcpy (&utxent->ut_addr,
&(sa->sin_addr),
MIN (sizeof (utxent->ut_addr),
sizeof (sa->sin_addr)));
diff --git a/src/login.c b/src/login.c
index e287cb0b..7677adf1 100644
--- a/src/login.c
+++ b/src/login.c
@@ -129,7 +129,12 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
static void update_utmp (const char *user,
const char *tty,
const char *host,
- /*@null@*/const struct utmp *utent);
+#ifdef USE_UTMPX
+ /*@null@*/const struct utmpx *utent
+#else
+ /*@null@*/const struct utmp *utent
+#endif
+ );
#ifndef USE_PAM
static struct faillog faillog;
@@ -481,17 +486,23 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
static void update_utmp (const char *user,
const char *tty,
const char *host,
- /*@null@*/const struct utmp *utent)
+#ifdef USE_UTMPX
+ /*@null@*/const struct utmpx *utent
+#else
+ /*@null@*/const struct utmp *utent
+#endif
+ )
{
- struct utmp *ut = prepare_utmp (user, tty, host, utent);
#ifdef USE_UTMPX
struct utmpx *utx = prepare_utmpx (user, tty, host, utent);
+#else
+ struct utmp *ut = prepare_utmp (user, tty, host, utent);
#endif /* USE_UTMPX */
+#ifndef USE_UTMPX
(void) setutmp (ut); /* make entry in the utmp & wtmp files */
free (ut);
-
-#ifdef USE_UTMPX
+#else
(void) setutmpx (utx); /* make entry in the utmpx & wtmpx files */
free (utx);
#endif /* USE_UTMPX */
@@ -539,7 +550,11 @@ int main (int argc, char **argv)
struct passwd *pwd = NULL;
char **envp = environ;
const char *failent_user;
+#ifdef USE_UTMPX
+ /*@null@*/struct utmpx *utent;
+#else
/*@null@*/struct utmp *utent;
+#endif
#ifdef USE_PAM
int retcode;
@@ -681,7 +696,7 @@ int main (int argc, char **argv)
if (rflg || hflg) {
cp = hostname;
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
+#if defined(HAVE_STRUCT_UTMP_UT_HOST) || defined(USE_UTMPX)
} else if ((NULL != utent) && ('\0' != utent->ut_host[0])) {
cp = utent->ut_host;
#endif /* HAVE_STRUCT_UTMP_UT_HOST */