From f5ad9fd03bc3a33aa001be04d8fd42a4d86680e8 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Wed, 3 Feb 2021 04:09:48 +0200 Subject: [PATCH] Revert "generic: do not rely on login()/loginx() and logout()/logoutx()" This reverts commit cf68640e131ebffa90bbb71025b56d7fcc99c020. --- ConfigureChecks.cmake | 22 +++++++++++++++- config-pty.h.cmake | 2 ++ kpty/kpty.cpp | 61 +++++++++++++++++++++---------------------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index a0e91a8f..85bf2037 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -92,12 +92,32 @@ if (UNIX) check_include_files(sys/filio.h HAVE_SYS_FILIO_H) set(UTIL_LIBRARY) - check_function_exists(getutxent HAVE_UTMPX) + + check_function_exists(login login_in_libc) + if (NOT login_in_libc) + check_library_exists(util login "" login_in_libutil) + if (login_in_libutil) + set(UTIL_LIBRARY util) + endif (login_in_libutil) + endif (NOT login_in_libc) + if (CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin OR CMAKE_SYSTEM_NAME MATCHES GNU/FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL GNU) + set (HAVE_UTMPX) + else (CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin OR CMAKE_SYSTEM_NAME MATCHES GNU/FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL GNU) + check_function_exists(getutxent HAVE_UTMPX) + endif (CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin OR CMAKE_SYSTEM_NAME MATCHES GNU/FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL GNU) if (HAVE_UTMPX) set(utmp utmpx) + if (login_in_libutil) + check_library_exists(util loginx "" HAVE_LOGINX) + endif (login_in_libutil) else (HAVE_UTMPX) set(utmp utmp) endif (HAVE_UTMPX) + if (login_in_libc OR login_in_libutil) + set(HAVE_LOGIN 1) + else (login_in_libc OR login_in_libutil) + set(HAVE_LOGIN) + endif (login_in_libc OR login_in_libutil) check_struct_has_member("struct ${utmp}" "ut_type" "${utmp}.h" HAVE_STRUCT_UTMP_UT_TYPE) check_struct_has_member("struct ${utmp}" "ut_pid" "${utmp}.h" HAVE_STRUCT_UTMP_UT_PID) check_struct_has_member("struct ${utmp}" "ut_session" "${utmp}.h" HAVE_STRUCT_UTMP_UT_SESSION) diff --git a/config-pty.h.cmake b/config-pty.h.cmake index e025726a..4412761f 100644 --- a/config-pty.h.cmake +++ b/config-pty.h.cmake @@ -17,7 +17,9 @@ #cmakedefine HAVE_SYS_STROPTS_H 1 #cmakedefine HAVE_SYS_FILIO_H 1 +#cmakedefine HAVE_LOGIN 1 #cmakedefine HAVE_UTMPX 1 +#cmakedefine HAVE_LOGINX 1 #cmakedefine HAVE_STRUCT_UTMP_UT_TYPE 1 #cmakedefine HAVE_STRUCT_UTMP_UT_PID 1 #cmakedefine HAVE_STRUCT_UTMP_UT_SESSION 1 diff --git a/kpty/kpty.cpp b/kpty/kpty.cpp index 4a7d3358..9bf507ef 100644 --- a/kpty/kpty.cpp +++ b/kpty/kpty.cpp @@ -464,7 +464,7 @@ void KPty::login(const char *user, const char *remotehost) // note: strncpy without terminators _is_ correct here. man 4 utmp if (user) - strncpy(l_struct.ut_user, user, sizeof(l_struct.ut_user)); + strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name)); if (remotehost) { strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host)); @@ -487,15 +487,14 @@ void KPty::login(const char *user, const char *remotehost) #endif #ifdef HAVE_UTMPX - // due to binary hacks ut_tv members must be set explicitly - struct timeval tod; - gettimeofday(&tod, 0); - l_struct.ut_tv.tv_sec = tod.tv_sec; - l_struct.ut_tv.tv_usec = tod.tv_usec; + gettimeofday(&l_struct.ut_tv, 0); #else l_struct.ut_time = time(0); #endif + // on Linux login() fills these, atleast on NetBSD that is not the case and + // the utmp/utmpx struct values must be filled before calling + // loginx()/login() #ifdef HAVE_STRUCT_UTMP_UT_TYPE l_struct.ut_type = USER_PROCESS; #endif @@ -506,16 +505,16 @@ void KPty::login(const char *user, const char *remotehost) l_struct.ut_session = getsid(0); #endif -#ifdef HAVE_UTMPX -# ifdef _PATH_UTMPX +#if defined(HAVE_LOGINX) + ::loginx(&l_struct); +#elif defined(HAVE_LOGIN) + ::login(&l_struct); +#elif defined(HAVE_UTMPX) utmpxname(_PATH_UTMPX); -# endif setutxent(); pututxline(&l_struct); endutxent(); -# ifdef _PATH_WTMPX updwtmpx(_PATH_WTMPX, &l_struct); -# endif #else utmpname(_PATH_UTMP); setutent(); @@ -539,48 +538,48 @@ void KPty::logout() str_ptr = sl_ptr + 1; } #endif -#ifdef HAVE_UTMPX - struct utmpx l_struct, *ut; +#if defined(HAVE_LOGINX) + ::logoutx(str_ptr, 0, DEAD_PROCESS); +#elif defined(HAVE_LOGIN) + ::logout(str_ptr); #else +# ifdef HAVE_UTMPX + struct utmpx l_struct, *ut; +# else struct utmp l_struct, *ut; -#endif +# endif memset(&l_struct, 0, sizeof(l_struct)); strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line)); -#ifdef HAVE_UTMPX -# ifdef _PATH_UTMPX +# ifdef HAVE_UTMPX utmpxname(_PATH_UTMPX); -# endif setutxent(); if ((ut = getutxline(&l_struct))) { -#else +# else utmpname(_PATH_UTMP); setutent(); if ((ut = getutline(&l_struct))) { -#endif - memset(ut->ut_user, 0, sizeof(*ut->ut_user)); +# endif + memset(ut->ut_name, 0, sizeof(*ut->ut_name)); memset(ut->ut_host, 0, sizeof(*ut->ut_host)); -#ifdef HAVE_STRUCT_UTMP_UT_SYSLEN +# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN ut->ut_syslen = 0; -#endif -#ifdef HAVE_STRUCT_UTMP_UT_TYPE +# endif +# ifdef HAVE_STRUCT_UTMP_UT_TYPE ut->ut_type = DEAD_PROCESS; -#endif -#ifdef HAVE_UTMPX - // due to binary hacks ut_tv members must be set explicitly - struct timeval tod; - gettimeofday(&tod, 0); - ut->ut_tv.tv_sec = tod.tv_sec; - ut->ut_tv.tv_usec = tod.tv_usec; +# endif +# ifdef HAVE_UTMPX + gettimeofday(&(ut->ut_tv), 0); pututxline(ut); } endutxent(); -#else +# else ut->ut_time = time(0); pututline(ut); } endutent(); +# endif #endif }