summaryrefslogtreecommitdiffstats
path: root/src/sh_utmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sh_utmp.c')
-rw-r--r--src/sh_utmp.c639
1 files changed, 234 insertions, 405 deletions
diff --git a/src/sh_utmp.c b/src/sh_utmp.c
index 5c72209..444779b 100644
--- a/src/sh_utmp.c
+++ b/src/sh_utmp.c
@@ -140,41 +140,30 @@ SH_MUTEX_EXTERN(mutex_thread_nolog);
#ifdef HAVE_UTMPX_H
-#ifndef _PATH_UTMP
-#ifdef UTMPX_FILE
-#define _PATH_UTMP UTMPX_FILE
-#else
-#error You must define UTMPX_FILE in the file config.h
-#endif
-#endif
-#ifndef _PATH_WTMP
-#ifdef WTMPX_FILE
-#define _PATH_WTMP WTMPX_FILE
+#if defined(_PATH_UTMPX)
+#define SH_PATH_UTMP _PATH_UTMPX
+#elif defined(UTMPX_FILE)
+#define SH_PATH_UTMP UTMPX_FILE
+#elif defined(_PATH_UTMP)
+#define SH_PATH_UTMP _PATH_UTMP
#else
-#error You must define WTMPX_FILE in the file config.h
-#endif
+#error You must define UTMPX_FILE in the file config.h
#endif
#else
-#ifndef _PATH_UTMP
-#ifdef UTMP_FILE
-#define _PATH_UTMP UTMP_FILE
+#if defined(_PATH_UTMP)
+#define SH_PATH_UTMP _PATH_UTMP
+#elif defined(UTMP_FILE)
+#define SH_PATH_UTMP UTMP_FILE
#else
#error You must define UTMP_FILE in the file config.h
#endif
-#endif
-#ifndef _PATH_WTMP
-#ifdef WTMP_FILE
-#define _PATH_WTMP WTMP_FILE
-#else
-#error You must define WTMP_FILE in the file config.h
-#endif
-#endif
#endif
typedef struct log_user {
+ time_t last_checked;
char ut_tty[UT_LINESIZE+1];
char name[UT_NAMESIZE+1];
char ut_host[UT_HOSTSIZE+1];
@@ -183,18 +172,12 @@ typedef struct log_user {
struct log_user * next;
} blah_utmp;
-#ifdef HAVE_UTTYPE
-static char terminated_line[UT_HOSTSIZE];
-#endif
-
-static char * mode_path[] = { _PATH_WTMP, _PATH_WTMP, _PATH_UTMP };
-
-static struct SH_UTMP_S save_utmp;
+static char * utmp_path = SH_PATH_UTMP;
static void sh_utmp_logout_morechecks(struct log_user * user);
static void sh_utmp_login_morechecks(struct SH_UTMP_S * ut);
-static void sh_utmp_addlogin (struct SH_UTMP_S * ut);
-static void sh_utmp_check_internal(int mode);
+static void sh_utmp_checklogin (struct SH_UTMP_S * ut, time_t start_read);
+static void sh_utmp_check_internal();
static int ShUtmpLoginSolo = SH_ERR_INFO;
static int ShUtmpLoginMulti = SH_ERR_WARN;
@@ -257,12 +240,18 @@ static void set_defaults(void)
return;
}
+#if defined(HAVE_UTMPX_H) && defined(HAVE_GETUTXENT)
+#define USE_SETUTENT 1
+#elif defined(HAVE_GETUTENT)
+#define USE_SETUTENT 1
+#endif
-#if defined (HAVE_SETUTENT) && defined (USE_SETUTENT)
-#ifdef HAVE_UTMPX_H
+#if defined (USE_SETUTENT)
-#define sh_utmp_utmpname utmpxname
+#ifdef HAVE_UTMPX_H
+
+#define sh_utmp_utmpname(a) (void)(a)
#define sh_utmp_setutent setutxent
#define sh_utmp_endutent endutxent
#define sh_utmp_getutent getutxent
@@ -291,12 +280,8 @@ static void set_defaults(void)
*/
static FILE * sh_utmpfile = NULL;
-static char sh_utmppath[80] = _PATH_UTMP;
+static char sh_utmppath[80] = SH_PATH_UTMP;
-/* sh_utmp_feed_forward is for optimizing
- * (fseek instead of getutent loop)
- */
-static long sh_utmp_feed_forward = 0;
static void sh_utmp_utmpname(const char * str)
{
@@ -307,7 +292,7 @@ static void sh_utmp_utmpname(const char * str)
sh_utmpfile = NULL;
}
- (void) sl_strlcpy (sh_utmppath, str, 80);
+ (void) sl_strlcpy (sh_utmppath, str, sizeof(sh_utmppath));
SL_RET0(_("sh_utmp_utmpname"));
}
@@ -343,11 +328,6 @@ static void sh_utmp_setutent(void)
}
}
(void) fseek (sh_utmpfile, 0L, SEEK_SET);
- if (-1 == fseek (sh_utmpfile, sh_utmp_feed_forward, SEEK_CUR))
- {
- sh_utmp_feed_forward = 0; /* modified Apr 4, 2004 */
- (void) fseek (sh_utmpfile, 0L, SEEK_SET);
- }
clearerr (sh_utmpfile);
SL_RET0(_("sh_utmp_setutent"));
}
@@ -387,63 +367,6 @@ static struct SH_UTMP_S * sh_utmp_getutent(void)
SL_RETURN(&out, _("sh_utmp_getutent"));
}
-#ifdef USE_UNUSED
-
-static struct SH_UTMP_S * sh_utmp_getutline(struct SH_UTMP_S * ut)
-{
- struct SH_UTMP_S * out;
-
- while (1) {
- if ((out = sh_utmp_getutent()) == NULL) {
- return NULL;
- }
-#ifdef HAVE_UTTYPE
- if (out->ut_type == USER_PROCESS || out->ut_type == LOGIN_PROCESS)
- if (sl_strcmp(ut->ut_line, out->ut_line) == 0)
- return out;
-#else
- if ( 0 != sl_strncmp (out->ut_name, "reboot", 6) &&
- 0 != sl_strncmp (out->ut_name, "shutdown", 8) &&
- 0 != sl_strncmp (out->ut_name, "date", 4) )
- return out;
-#endif
- }
- return NULL;
-}
-
-static struct SH_UTMP_S * sh_utmp_getutid(struct SH_UTMP_S * ut)
-{
-#ifdef HAVE_UTTYPE
- struct SH_UTMP_S * out;
-
- if (ut->ut_type == RUN_LVL || ut->ut_type == BOOT_TIME ||
- ut->ut_type == NEW_TIME || ut->ut_type == OLD_TIME)
- {
- while (1) {
- if ((out = sh_utmp_getutent()) == NULL) {
- return NULL;
- }
- if (out->ut_type == ut->ut_type)
- return out;
- }
- }
- else if (ut->ut_type == INIT_PROCESS || ut->ut_type == LOGIN_PROCESS ||
- ut->ut_type == USER_PROCESS || ut->ut_type == DEAD_PROCESS )
- {
- while (1) {
- if ((out = sh_utmp_getutent()) == NULL) {
- return NULL;
- }
- if (sl_strcmp(ut->ut_id, out->ut_id) == 0)
- return out;
- }
- }
-#endif
- return NULL;
-}
-/* #ifdef USE_UNUSED */
-#endif
-
/* #ifdef HAVE_SETUTENT */
#endif
@@ -510,9 +433,7 @@ static int sh_utmp_init_internal (void)
}
lastcheck = time (NULL);
userlist = NULL;
- memset (&save_utmp, 0, sizeof(struct SH_UTMP_S));
- sh_utmp_check_internal (2); /* current logins */
- sh_utmp_check_internal (0);
+ sh_utmp_check_internal (); /* current logins */
init_done = 1;
SL_RETURN( (0), _("sh_utmp_init"));
}
@@ -617,7 +538,7 @@ int sh_utmp_timer (time_t tcurrent)
if ( (sh.flag.isdaemon == S_TRUE || sh.flag.loop == S_TRUE) &&
sh.flag.checkSum != SH_CHECK_INIT )
{
- sh_inotify_wait_for_change(mode_path[1], &inotify_watch,
+ sh_inotify_wait_for_change(utmp_path, &inotify_watch,
&errnum, ShUtmpInterval);
}
@@ -656,7 +577,7 @@ int sh_utmp_check ()
SH_MUTEX_LOCK(mutex_thread_nolog);
sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_UT_CHECK);
SH_MUTEX_UNLOCK(mutex_thread_nolog);
- sh_utmp_check_internal (1);
+ sh_utmp_check_internal ();
SL_RETURN(0, _("sh_utmp_check"));
}
@@ -736,7 +657,7 @@ int sh_utmp_set_login_activate (const char * c)
SL_RETURN(i, _("sh_utmp_set_login_activate"));
}
-#ifdef HAVE_UTTYPE
+
struct login_ct {
char name[UT_NAMESIZE+1];
int nlogin;
@@ -816,7 +737,6 @@ static int sh_utmp_login_r(char * str)
return 0;
}
-#endif
/* for each login:
@@ -825,14 +745,14 @@ static int sh_utmp_login_r(char * str)
* - link user.ut_record -> log_record
*/
-#ifdef HAVE_UTTYPE
+#include <ctype.h>
static int sh_utmp_is_virtual (char * in_utline, char * in_uthost)
{
if (in_uthost != NULL &&
in_utline != NULL &&
in_uthost[0] == ':' &&
- in_uthost[1] == '0' &&
+ isdigit((int) in_uthost[1]) &&
0 == sl_strncmp(in_utline, _("pts/"), 4))
{
return 1;
@@ -840,7 +760,139 @@ static int sh_utmp_is_virtual (char * in_utline, char * in_uthost)
return 0;
}
+
+
+static void sh_utmp_log_out(int sev, struct log_user * user, int n)
+{
+ char ttt[TIM_MAX];
+
+ SH_MUTEX_LOCK(mutex_thread_nolog);
+ (void) sh_unix_time (user->time, ttt, TIM_MAX);
+ sh_error_handle( sev, FIL__, __LINE__, 0,
+#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
+ MSG_UT_LG3X,
+#elif defined(HAVE_UTHOST)
+ MSG_UT_LG3A,
+#else
+ MSG_UT_LG3B,
+#endif
+ user->name,
+ user->ut_tty,
+#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
+ user->ut_host,
+ user->ut_ship,
+#elif defined(HAVE_UTHOST)
+ user->ut_host,
+#endif
+ ttt,
+ n
+ );
+ SH_MUTEX_UNLOCK(mutex_thread_nolog);
+}
+
+static void sh_utmp_log_multi(int sev, struct log_user * user, int n)
+{
+ char ttt[TIM_MAX];
+
+ SH_MUTEX_LOCK(mutex_thread_nolog);
+ (void) sh_unix_time (user->time, ttt, TIM_MAX);
+ sh_error_handle( sev, FIL__, __LINE__, 0,
+#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
+ MSG_UT_LG2X,
+#elif defined(HAVE_UTHOST)
+ MSG_UT_LG2A,
+#else
+ MSG_UT_LG2B,
+#endif
+ user->name,
+ user->ut_tty,
+#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
+ user->ut_host,
+ user->ut_ship,
+#elif defined(HAVE_UTHOST)
+ user->ut_host,
+#endif
+ ttt,
+ n
+ );
+ SH_MUTEX_UNLOCK(mutex_thread_nolog);
+}
+
+static void sh_utmp_log_one(int sev, struct log_user * user, int n)
+{
+ char ttt[TIM_MAX];
+
+ SH_MUTEX_LOCK(mutex_thread_nolog);
+ (void) sh_unix_time (user->time, ttt, TIM_MAX);
+ sh_error_handle( sev, FIL__, __LINE__, 0,
+#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
+ MSG_UT_LG1X,
+#elif defined(HAVE_UTHOST)
+ MSG_UT_LG1A,
+#else
+ MSG_UT_LG1B,
+#endif
+ user->name,
+ user->ut_tty,
+#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
+ user->ut_host,
+ user->ut_ship,
+#elif defined(HAVE_UTHOST)
+ user->ut_host,
#endif
+ ttt,
+ n
+ );
+ SH_MUTEX_UNLOCK(mutex_thread_nolog);
+}
+
+static void sh_utmp_purge_old (time_t start_read)
+{
+ struct log_user * user = userlist;
+ struct log_user * userold = userlist;
+ volatile int status;
+
+ /* ------- find old entries --------
+ */
+ while (user != NULL)
+ {
+ if (user->last_checked < start_read)
+ {
+ /* report logout */
+ if (0 == sh_utmp_is_virtual(user->ut_tty, user->ut_host))
+ {
+ /* reference count down on list of logged in users */
+ status = sh_utmp_login_r(user->name);
+
+ sh_utmp_log_out(ShUtmpLogout, user, status);
+ sh_utmp_logout_morechecks((struct log_user *)user);
+ }
+
+ /* remove entry */
+ if (userold == user && userold == userlist)
+ {
+ /* first element in userlist, advance userlist & userold */
+ userold = user->next;
+ userlist = user->next;
+ SH_FREE((struct log_user *)user);
+ user = userlist;
+ }
+ else
+ {
+ /* other element in userlist, cut it out */
+ userold->next = user->next;
+ SH_FREE((struct log_user *)user);
+ user = userold->next;
+ }
+ }
+ else
+ {
+ userold = user;
+ user = user->next;
+ }
+ }
+ return;
+}
/* These variables are not used anywhere. They only exist
* to assign &userold, &user to them, which keeps gcc from
@@ -851,33 +903,19 @@ void * sh_dummy_850_userold = NULL;
void * sh_dummy_851_user = NULL;
-static void sh_utmp_addlogin (struct SH_UTMP_S * ut)
+static void sh_utmp_checklogin (struct SH_UTMP_S * ut, time_t start_read)
{
struct log_user * user = userlist;
struct log_user * userold = userlist;
-#ifdef HAVE_UTTYPE
- struct log_user * username = userlist;
-#endif
- char ttt[TIM_MAX];
-#ifdef HAVE_UTTYPE
+ struct log_user * username = userlist;
volatile int status;
-#endif
- SL_ENTER(_("sh_utmp_addlogin"));
- if (ut->ut_line[0] == '\0')
- SL_RET0(_("sh_utmp_addlogin"));
+ SL_ENTER(_("sh_utmp_checklogin"));
- /* for some stupid reason, AIX repeats the wtmp entry for logouts
- * with ssh
- */
- if (memcmp (&save_utmp, ut, sizeof(struct SH_UTMP_S)) == 0)
- {
- memset(&save_utmp, (int) '\0', sizeof(struct SH_UTMP_S));
- SL_RET0(_("sh_utmp_addlogin"));
- }
- memcpy (&save_utmp, ut, sizeof(struct SH_UTMP_S));
+ if (ut->ut_line[0] == '\0')
+ SL_RET0(_("sh_utmp_checklogin"));
/* Take the address to keep gcc from putting them into registers.
* Avoids the 'clobbered by longjmp' warning.
@@ -889,273 +927,108 @@ static void sh_utmp_addlogin (struct SH_UTMP_S * ut)
*/
while (user != NULL)
{
- if (0 == sl_strncmp((char*)(user->ut_tty), ut->ut_line, UT_LINESIZE) )
+ if (0 == sl_strncmp(user->ut_tty, ut->ut_line, UT_LINESIZE) &&
+ 0 == sl_strncmp(user->name, ut->ut_name, UT_NAMESIZE))
break;
userold = user;
user = user->next;
}
-#ifdef HAVE_UTTYPE
+
while (username != NULL)
{
if (0 == sl_strncmp(username->name, ut->ut_name, UT_NAMESIZE) )
break;
username = username->next;
}
-#endif
+
-#ifdef HAVE_UTTYPE
- /* ---------- LOGIN -------------- */
- if (ut->ut_type == USER_PROCESS)
+ if (user == NULL)
{
- if (user == NULL)
- {
- user = SH_ALLOC(sizeof(struct log_user));
- user->next = userlist;
- userlist = (struct log_user *) user;
- }
- (void) sl_strlcpy((char*)(user->ut_tty), ut->ut_line, UT_LINESIZE+1);
- (void) sl_strlcpy((char*)(user->name), ut->ut_name, UT_NAMESIZE+1);
-#ifdef HAVE_UTHOST
- (void) sl_strlcpy((char*)(user->ut_host), ut->ut_host, UT_HOSTSIZE+1);
-#else
- user->ut_host[0] = '\0';
-#endif
-#ifdef HAVE_UTADDR
-#ifdef HAVE_UTADDR_V6
- my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
-#else
- my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
-#endif
-#endif
- user->time = ut->ut_time;
-
- if (username == NULL /* not yet logged in */
- || 0 == sl_strncmp(ut->ut_line, _("ttyp"), 4) /* in virt. console */
- || 0 == sl_strncmp(ut->ut_line, _("ttyq"), 4) /* in virt. console */
- ) {
- status = sh_utmp_login_a((char*)user->name);
- SH_MUTEX_LOCK(mutex_thread_nolog);
- (void) sh_unix_time (user->time, ttt, TIM_MAX);
- sh_error_handle( ShUtmpLoginSolo, FIL__, __LINE__, 0,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- MSG_UT_LG1X,
-#elif defined(HAVE_UTHOST)
- MSG_UT_LG1A,
-#else
- MSG_UT_LG1B,
-#endif
- user->name,
- user->ut_tty,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- user->ut_host,
- user->ut_ship,
-#elif defined(HAVE_UTHOST)
- user->ut_host,
-#endif
- ttt,
- status
- );
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
- } else
- if (0 == sh_utmp_is_virtual(ut->ut_line, (char*)user->ut_host))
- {
- status = sh_utmp_login_a((char*)user->name);
- SH_MUTEX_LOCK(mutex_thread_nolog);
- (void) sh_unix_time (user->time, ttt, TIM_MAX);
- sh_error_handle( ShUtmpLoginMulti, FIL__, __LINE__, 0,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- MSG_UT_LG2X,
-#elif defined(HAVE_UTHOST)
- MSG_UT_LG2A,
-#else
- MSG_UT_LG2B,
-#endif
- user->name,
- user->ut_tty,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- user->ut_host,
- user->ut_ship,
-#elif defined(HAVE_UTHOST)
- user->ut_host,
-#endif
- ttt,
- status
- );
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
- }
-
- sh_utmp_login_morechecks(ut);
+ user = SH_ALLOC(sizeof(struct log_user));
+ user->next = userlist;
+ userlist = (struct log_user *) user;
+ }
+ else if ( (user->time == ut->ut_time) &&
+ 0 == sl_strcmp (user->name, ut->ut_name))
+ {
+ /* we have it on record and nothing has changed */
+ user->last_checked = start_read;
goto out;
}
-
-
- /* --------- LOGOUT ---------------- */
- else if (ut->ut_name[0] == '\0'
- || ut->ut_type == DEAD_PROCESS /* solaris does not clear ut_name */
- )
+ else
{
- if (user != NULL)
- {
-#if defined(__linux__)
- if (0 == sh_utmp_is_virtual(ut->ut_line, (char*)user->ut_host)) {
-#endif
- status = sh_utmp_login_r((char*)user->name);
- SH_MUTEX_LOCK(mutex_thread_nolog);
- (void) sh_unix_time (ut->ut_time, ttt, TIM_MAX);
- sh_error_handle( ShUtmpLogout, FIL__, __LINE__, 0,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- MSG_UT_LG3X,
-#elif defined(HAVE_UTHOST)
- MSG_UT_LG3A,
-#else
- MSG_UT_LG3B,
-#endif
- user->name,
- user->ut_tty,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- user->ut_host,
- user->ut_ship,
-#elif defined(HAVE_UTHOST)
- user->ut_host,
-#endif
- ttt,
- status
- );
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
- userold->next = user->next;
- if (user == userlist)
- userlist = user->next;
- sh_utmp_logout_morechecks((struct log_user *)user);
- SH_FREE((struct log_user *)user);
- user = NULL;
-#if defined(__linux__)
- }
-#endif
- }
- else
+ /* we have it on record and something has changed */
+ if (0 == sh_utmp_is_virtual(user->ut_tty, user->ut_host))
{
- (void) sl_strlcpy(terminated_line, ut->ut_line, UT_HOSTSIZE);
- SH_MUTEX_LOCK(mutex_thread_nolog);
- (void) sh_unix_time (ut->ut_time, ttt, TIM_MAX);
- sh_error_handle( ShUtmpLogout, FIL__, __LINE__, 0,
- MSG_UT_LG3C,
- terminated_line,
- ttt, 0
- );
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
+ /* reference count down on list of logged in users */
+ status = sh_utmp_login_r(user->name);
+
+ sh_utmp_log_out(ShUtmpLogout, user, status);
+ sh_utmp_logout_morechecks((struct log_user *)user);
}
- goto out;
}
- /* default */
- goto out;
-
- /* #ifdef HAVE_UTTYPE */
-#else
-
- if (user == NULL) /* probably a login */
- {
- user = SH_ALLOC(sizeof(struct log_user));
- sl_strlcpy(user->ut_tty, ut->ut_line, UT_LINESIZE+1);
- sl_strlcpy(user->name, ut->ut_name, UT_NAMESIZE+1);
+ user->last_checked = start_read;
+
+ (void) sl_strlcpy(user->ut_tty, ut->ut_line, UT_LINESIZE+1);
+ (void) sl_strlcpy(user->name, ut->ut_name, UT_NAMESIZE+1);
#ifdef HAVE_UTHOST
- sl_strlcpy(user->ut_host, ut->ut_host, UT_HOSTSIZE+1);
+ (void) sl_strlcpy(user->ut_host, ut->ut_host, UT_HOSTSIZE+1);
+#else
+ user->ut_host[0] = '\0';
#endif
#ifdef HAVE_UTADDR
#ifdef HAVE_UTADDR_V6
- my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
-#else
- my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
-#endif
-#endif
- user->time = ut->ut_time;
- user->next = userlist;
- userlist = user;
-
- SH_MUTEX_LOCK(mutex_thread_nolog);
- (void) sh_unix_time (user->time, ttt, TIM_MAX);
- sh_error_handle( ShUtmpLoginSolo, FIL__, __LINE__, 0,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- MSG_UT_LG1X,
-#elif defined(HAVE_UTHOST)
- MSG_UT_LG1A,
+ my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
#else
- MSG_UT_LG1B,
+ my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
#endif
- user->name,
- user->ut_tty,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- user->ut_host,
- user->ut_ship,
-#elif defined(HAVE_UTHOST)
- user->ut_host,
#endif
- ttt,
- 1
- );
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
- sh_utmp_login_morechecks(ut);
+ user->time = ut->ut_time;
+
+ if (username == NULL) /* not yet logged in */
+ {
+ /* add this username to the list of logged in users */
+ status = sh_utmp_login_a(user->name);
+
+ sh_utmp_log_one(ShUtmpLoginSolo, user, status);
+
}
- else /* probably a logout */
+ else if (0 == sh_utmp_is_virtual(user->ut_tty, (char*)user->ut_host))
{
- SH_MUTEX_LOCK(mutex_thread_nolog);
- (void) sh_unix_time (ut->ut_time, ttt, TIM_MAX);
- sh_error_handle( ShUtmpLogout, FIL__, __LINE__, 0,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- MSG_UT_LG2X,
-#elif defined(HAVE_UTHOST)
- MSG_UT_LG2A,
-#else
- MSG_UT_LG2B,
-#endif
- user->name,
- user->ut_tty,
-#if defined(HAVE_UTHOST) && defined(HAVE_UTADDR)
- user->ut_host,
- user->ut_ship,
-#elif defined(HAVE_UTHOST)
- user->ut_host,
-#endif
- ttt,
- 1
- );
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
- sh_utmp_logout_morechecks(user);
- userold->next = user->next;
- if (user == userlist) /* inserted Apr 4, 2004 */
- userlist = user->next;
- SH_FREE(user);
- user = NULL;
+ /* add this username to the list of logged in users */
+ status = sh_utmp_login_a((char*)user->name);
+
+ sh_utmp_log_multi(ShUtmpLoginMulti, user, status);
}
+ sh_utmp_login_morechecks(ut);
+ goto out;
-#endif
out:
sh_dummy_851_user = NULL;
sh_dummy_850_userold = NULL;
- SL_RET0(_("sh_utmp_addlogin"));
+ SL_RET0(_("sh_utmp_checklogin"));
}
static time_t lastmod = 0;
-static off_t lastsize = 0;
-static unsigned long lastread = 0;
-static void sh_utmp_check_internal (int mode)
+static void sh_utmp_check_internal ()
{
struct stat buf;
int error;
struct SH_UTMP_S * ut;
- unsigned long this_read;
int val_retry;
+ time_t start_read;
SL_ENTER(_("sh_utmp_check_internal"));
/* error if no access
*/
do {
- val_retry = /*@-unrecog@*/lstat ( mode_path[mode], &buf)/*@+unrecog@*/;
+ val_retry = /*@-unrecog@*/lstat ( utmp_path, &buf)/*@+unrecog@*/;
} while (val_retry < 0 && errno == EINTR);
if (0 != val_retry)
@@ -1163,87 +1036,43 @@ static void sh_utmp_check_internal (int mode)
error = errno;
SH_MUTEX_LOCK(mutex_thread_nolog);
sh_error_handle((-1), FIL__, __LINE__, error, MSG_E_ACCESS,
- (long) sh.real.uid, mode_path[mode]);
+ (long) sh.real.uid, utmp_path);
SH_MUTEX_UNLOCK(mutex_thread_nolog);
SL_RET0(_("sh_utmp_check_internal"));
}
- /* modification time
- */
- if (mode < 2)
- {
- if (/*@-usedef@*/buf.st_mtime <= lastmod/*@+usedef@*/)
- {
- SL_RET0(_("sh_utmp_check_internal"));
- }
- else
- lastmod = buf.st_mtime;
- }
-
- /* file size
+ /* check modification time
*/
- if (/*@-usedef@*/buf.st_size < lastsize/*@+usedef@*/ && mode < 2)
+ if (/*@-usedef@*/buf.st_mtime <= lastmod/*@+usedef@*/)
{
- SH_MUTEX_LOCK(mutex_thread_nolog);
- sh_error_handle((-1), FIL__, __LINE__, 0, MSG_UT_ROT,
- mode_path[mode]);
- SH_MUTEX_UNLOCK(mutex_thread_nolog);
- lastread = 0;
-#ifndef USE_SETUTENT
- sh_utmp_feed_forward = 0L;
-#endif
+ SL_RET0(_("sh_utmp_check_internal"));
}
+ else
+ lastmod = buf.st_mtime;
- if (mode < 2)
- lastsize = buf.st_size;
-
- if (buf.st_size == 0)
- SL_RET0(_("sh_utmp_check_internal"));
-
- sh_utmp_utmpname(mode_path[mode]);
+ sh_utmp_utmpname(utmp_path);
sh_utmp_setutent();
- /*
- * feed forward if initializing
- * we need to do this here
- */
- this_read = 0;
-
- if (mode < 2)
- {
- while (this_read < lastread) {
- (void) sh_utmp_getutent();
- ++this_read;
- }
- }
-
/* start reading
*/
- this_read = 0;
+ start_read = time(NULL);
+
while (1 == 1) {
ut = sh_utmp_getutent();
if (ut == NULL)
break;
/* modified: ut_user --> ut_name */
- if (mode == 1 || (mode == 2 && ut->ut_name[0] != '\0'
+ if (ut->ut_name[0] != '\0'
#ifdef HAVE_UTTYPE
- && ut->ut_type != DEAD_PROCESS
+ && ut->ut_type == USER_PROCESS
#endif
- ))
- sh_utmp_addlogin (ut);
- ++this_read;
+ )
+ sh_utmp_checklogin (ut, start_read);
}
sh_utmp_endutent();
- if (mode < 2)
- {
- lastread += this_read;
-#ifndef USE_SETUTENT
- sh_utmp_feed_forward += (long) (this_read * sizeof(struct SH_UTMP_S));
- lastread = 0;
-#endif
- }
+ sh_utmp_purge_old (start_read);
SL_RET0(_("sh_utmp_check_internal"));
}