diff --git a/configure.ac b/configure.ac index 10ad70cf..aaedf529 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 ]]) -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 - #ifdef USE_UTMPX #include +#else +#include #endif #include @@ -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 */