Index: trunk/src/sh_utmp.c
===================================================================
--- trunk/src/sh_utmp.c	(revision 571)
+++ trunk/src/sh_utmp.c	(revision 573)
@@ -141,39 +141,28 @@
 #ifdef HAVE_UTMPX_H
 
-#ifndef _PATH_UTMP
-#ifdef   UTMPX_FILE
-#define _PATH_UTMP   UTMPX_FILE
-#else  
+#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 UTMPX_FILE in the file config.h 
 #endif
-#endif
-#ifndef _PATH_WTMP
-#ifdef   WTMPX_FILE
-#define _PATH_WTMP   WTMPX_FILE
-#else
-#error  You must define WTMPX_FILE in the file config.h
-#endif
-#endif
-
-#else
-
-#ifndef _PATH_UTMP
-#ifdef   UTMP_FILE
-#define _PATH_UTMP   UTMP_FILE
+
+#else
+
+#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];
@@ -184,16 +173,10 @@
 } 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;
@@ -258,10 +241,16 @@
 }
 
-
-#if defined (HAVE_SETUTENT) && defined (USE_SETUTENT)
-
-#ifdef HAVE_UTMPX_H
-
-#define sh_utmp_utmpname     utmpxname
+#if defined(HAVE_UTMPX_H) && defined(HAVE_GETUTXENT)
+#define USE_SETUTENT 1
+#elif defined(HAVE_GETUTENT)
+#define USE_SETUTENT 1
+#endif
+
+
+#if defined (USE_SETUTENT)
+
+#ifdef HAVE_UTMPX_H 
+
+#define sh_utmp_utmpname(a)  (void)(a)
 #define sh_utmp_setutent     setutxent
 #define sh_utmp_endutent     endutxent
@@ -292,10 +281,6 @@
 
 static FILE * sh_utmpfile = NULL;
-static char   sh_utmppath[80] = _PATH_UTMP;
-
-/* sh_utmp_feed_forward is for optimizing
- * (fseek instead of getutent loop)
- */
-static long   sh_utmp_feed_forward = 0;
+static char   sh_utmppath[80] = SH_PATH_UTMP;
+
 
 static void sh_utmp_utmpname(const char * str)
@@ -308,5 +293,5 @@
     }
 
-  (void) sl_strlcpy (sh_utmppath, str, 80);
+  (void) sl_strlcpy (sh_utmppath, str, sizeof(sh_utmppath));
   SL_RET0(_("sh_utmp_utmpname"));
 }
@@ -344,9 +329,4 @@
     }
   (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"));
@@ -388,61 +368,4 @@
 }
 
-#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
@@ -511,7 +434,5 @@
   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"));
@@ -618,5 +539,5 @@
        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);
     }
@@ -657,5 +578,5 @@
   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"));
@@ -737,5 +658,5 @@
 }
 
-#ifdef HAVE_UTTYPE
+
 struct login_ct {
   char name[UT_NAMESIZE+1];
@@ -817,5 +738,4 @@
 }
 
-#endif
 
 
@@ -826,5 +746,5 @@
  */
 
-#ifdef HAVE_UTTYPE  
+#include <ctype.h>
 static int sh_utmp_is_virtual (char * in_utline, char * in_uthost)
 {
@@ -833,5 +753,5 @@
       in_utline != NULL   &&
       in_uthost[0] == ':' && 
-      in_uthost[1] == '0' && 
+      isdigit((int) in_uthost[1]) && 
       0 == sl_strncmp(in_utline, _("pts/"), 4))
     {
@@ -841,5 +761,137 @@
   return 0;
 }
-#endif
+
+
+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
@@ -852,31 +904,17 @@
 
 
-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
   volatile int    status;
-#endif
-
-  SL_ENTER(_("sh_utmp_addlogin"));
+
+
+  SL_ENTER(_("sh_utmp_checklogin"));
 
   if (ut->ut_line[0] == '\0')
-    SL_RET0(_("sh_utmp_addlogin"));
-
-  /* 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, 0, sizeof(struct SH_UTMP_S));
-      SL_RET0(_("sh_utmp_addlogin"));
-    }
-  memcpy (&save_utmp, ut, sizeof(struct SH_UTMP_S));
+    SL_RET0(_("sh_utmp_checklogin"));
 
   /* Take the address to keep gcc from putting them into registers. 
@@ -890,5 +928,6 @@
   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;
@@ -896,5 +935,5 @@
     }
 
-#ifdef HAVE_UTTYPE  
+
   while (username != NULL) 
     {
@@ -903,232 +942,68 @@
       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;
+    }
+  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;
+    }
+  else
+    {
+      /* we have it on record and something has changed */
+      if (0 == sh_utmp_is_virtual(user->ut_tty, user->ut_host))
 	{
-	  user = SH_ALLOC(sizeof(struct log_user));
-	  user->next       = userlist;
-	  userlist         = (struct log_user *) user;
+	  /* 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);
 	}
-      (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);
+    }
+
+  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
-      (void) sl_strlcpy((char*)(user->ut_host), ut->ut_host, UT_HOSTSIZE+1);
-#else
-      user->ut_host[0] = '\0';
+  (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;
-
-      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);
-	  }
+  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 */
+    {
+      /* add this username to the list of logged in users */
+      status = sh_utmp_login_a(user->name);
       
-      sh_utmp_login_morechecks(ut);
-      goto out;
-    }
-
-
-  /* ---------  LOGOUT ---------------- */
-  else if (ut->ut_name[0] == '\0'
-	   || ut->ut_type == DEAD_PROCESS  /* solaris does not clear ut_name */
-	   )
-    {
-      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
-	{
-	  (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);
-	}
-      goto out;
-    }
-
-  /* default */
+      sh_utmp_log_one(ShUtmpLoginSolo, user, status);
+      
+    }
+  else if (0 == sh_utmp_is_virtual(user->ut_tty, (char*)user->ut_host))
+    {
+      /* 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;
 
-  /* #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);
-#ifdef HAVE_UTHOST
-      sl_strlcpy(user->ut_host, ut->ut_host, UT_HOSTSIZE+1);
-#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,
-#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,
-		       1
-		       );
-      SH_MUTEX_UNLOCK(mutex_thread_nolog);
-      sh_utmp_login_morechecks(ut);
-    }
-  else  /* probably a logout */
-    {
-      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;
-    }
-
-#endif
 
  out:
@@ -1136,18 +1011,16 @@
   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"));
@@ -1156,5 +1029,5 @@
    */
   do {
-    val_retry = /*@-unrecog@*/lstat ( mode_path[mode], &buf)/*@+unrecog@*/;
+    val_retry = /*@-unrecog@*/lstat ( utmp_path, &buf)/*@+unrecog@*/;
   } while (val_retry < 0 && errno == EINTR);
 
@@ -1164,61 +1037,25 @@
       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
+  /* check 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
-   */
-  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
-    }
-
-  if (mode < 2)
-    lastsize = buf.st_size;
-
-  if (buf.st_size == 0) 
-    SL_RET0(_("sh_utmp_check_internal"));
-
-  sh_utmp_utmpname(mode_path[mode]);
+      SL_RET0(_("sh_utmp_check_internal"));
+    }
+  else
+    lastmod = buf.st_mtime;
+
+  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();
@@ -1226,23 +1063,15 @@
       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
-#endif
-		      ))
-      sh_utmp_addlogin (ut);
-    ++this_read;
+	&& ut->ut_type == USER_PROCESS
+#endif
+	)
+      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"));
