Index: /trunk/Makefile.in
===================================================================
--- /trunk/Makefile.in	(revision 142)
+++ /trunk/Makefile.in	(revision 143)
@@ -1653,5 +1653,5 @@
 sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_mail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_kern.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h 
-sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h 
+sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h 
 sh_kern.o: $(srcsrc)/sh_kern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_kern.h sh_ks_xor.h $(srcinc)/sh_unix.h $(srcinc)/sh_hash.h 
 sh_suidchk.o: $(srcsrc)/sh_suidchk.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_hash.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_schedule.h $(srcinc)/sh_calls.h 
@@ -1695,5 +1695,5 @@
 sh_prelude_old.o: $(srcsrc)/sh_prelude_old.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_mem.h $(srcinc)/sh_cat.h $(srcinc)/sh_error_min.h $(srcinc)/sh_prelude.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h 
 sh_async.o: $(srcsrc)/sh_async.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h 
-sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/CuTest.h 
+sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
 sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_modules.h $(srcinc)/sh_calls.h 
+sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h $(srcinc)/sh_modules.h 
Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 142)
+++ /trunk/configure.ac	(revision 143)
@@ -13,5 +13,5 @@
 dnl start
 dnl
-AM_INIT_AUTOMAKE(samhain, 2.3.7)
+AM_INIT_AUTOMAKE(samhain, 2.4.0)
 AC_CANONICAL_HOST
 
Index: /trunk/depend.dep
===================================================================
--- /trunk/depend.dep	(revision 142)
+++ /trunk/depend.dep	(revision 143)
@@ -19,5 +19,5 @@
 sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_mail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_kern.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h 
-sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h 
+sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h 
 sh_kern.o: $(srcsrc)/sh_kern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_kern.h sh_ks_xor.h $(srcinc)/sh_unix.h $(srcinc)/sh_hash.h 
 sh_suidchk.o: $(srcsrc)/sh_suidchk.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_hash.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_schedule.h $(srcinc)/sh_calls.h 
@@ -61,5 +61,5 @@
 kern_head.o: $(srcsrc)/kern_head.c Makefile config.h $(srcinc)/kern_head.h $(srcinc)/kern_head.h 
 sh_async.o: $(srcsrc)/sh_async.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h 
-sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/CuTest.h 
+sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
 sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_modules.h $(srcinc)/sh_calls.h 
+sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h $(srcinc)/sh_modules.h 
Index: /trunk/depend.sum
===================================================================
--- /trunk/depend.sum	(revision 142)
+++ /trunk/depend.sum	(revision 143)
@@ -1,1 +1,1 @@
-836204565
+2519500817
Index: /trunk/include/samhain.h
===================================================================
--- /trunk/include/samhain.h	(revision 142)
+++ /trunk/include/samhain.h	(revision 143)
@@ -128,10 +128,8 @@
 };
 
-enum {
-  SH_MOD_ACTIVE    = 0, 
-  SH_MOD_THREAD    = 1,
-  SH_MOD_FAILED    = 2
-};
-
+#define SH_MOD_THREAD  1
+#define SH_MOD_ACTIVE  0
+#define SH_MOD_FAILED -1
+ 
 /* Flags for file status
  */
@@ -287,6 +285,7 @@
 extern volatile  int      sig_debug_switch;       /* SIGUSR1 */
 extern volatile  int      sig_suspend_switch;     /* SIGUSR2 */
-extern volatile  int      sh_global_suspend_flag; /* SIGUSR2 */
+extern volatile  int      sh_global_suspend_flag;
 extern volatile  int      sig_fresh_trail;        /* SIGIOT  */
+extern volatile  int      sh_thread_pause_flag;
 extern volatile  int      sig_config_read_again;  /* SIGHUP  */
 extern volatile  int      sig_terminate;          /* SIGQUIT */
Index: /trunk/include/sh_pthread.h
===================================================================
--- /trunk/include/sh_pthread.h	(revision 142)
+++ /trunk/include/sh_pthread.h	(revision 143)
@@ -38,7 +38,4 @@
 #if defined(HAVE_PTHREAD_MUTEX_RECURSIVE)
 
-/* On GNU C, it's an enum, thus the alternative implementation 
- * below is used.
- */
 #define SH_MUTEX_RECURSIVE(M)                                          \
 static pthread_mutex_t M;                                              \
@@ -46,4 +43,5 @@
 {                                                                      \
   pthread_mutexattr_t   mta;                                           \
+  pthread_mutexattr_init(&mta);                                        \
   pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);            \
   pthread_mutex_init(&(M), &mta);                                      \
@@ -115,4 +113,6 @@
 SH_MUTEX_EXTERN(mutex_pwent);
 SH_MUTEX_EXTERN(mutex_readdir);
+/* Prevent threads from logging while we are in suspend */
+SH_MUTEX_EXTERN(mutex_thread_nolog);
 
 /*
@@ -120,4 +120,13 @@
  */
 extern int sh_g_thread();
+
+
+/*
+ * ----   Functions for threaded modules   ----
+ */
+int sh_pthread_create(void *(*start_routine)(void*), void *arg);
+int sh_pthread_cancel_all(void);
+void sh_threaded_module_reconf(void *arg);
+void * sh_threaded_module_run(void *arg);
 
 #else
Index: /trunk/src/samhain.c
===================================================================
--- /trunk/src/samhain.c	(revision 142)
+++ /trunk/src/samhain.c	(revision 143)
@@ -114,4 +114,5 @@
 volatile  int      sh_global_suspend_flag;
 volatile  int      sig_fresh_trail;        /* SIGIOT  */
+volatile  int      sh_thread_pause_flag = S_FALSE;
 volatile  int      sig_config_read_again;  /* SIGHUP  */
 volatile  int      sig_terminate;          /* SIGQUIT */
@@ -1724,4 +1725,6 @@
 	      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_RECONF);
 
+	      sh_thread_pause_flag = S_TRUE;
+
 #if defined(WITH_EXTERNAL)
 	      /* delete list of external tasks
@@ -1793,4 +1796,6 @@
 		  sh.flag.loop     = S_FALSE;
 		}
+
+	      sh_thread_pause_flag = S_FALSE;
 
 	      /* --- Initialize modules. ---
@@ -1829,17 +1834,24 @@
 	  if (sig_fresh_trail == 1) /* SIGIOT */
 	    {
-	      /* Logfile access 
-	       */
+	      if (sh_global_suspend_flag == 0)
+		{
+		  SH_MUTEX_LOCK(mutex_thread_nolog);
+
+		  /* Logfile access 
+		   */
 #ifdef SH_USE_XML
-	      (void) sh_log_file (NULL, NULL);
-#endif
-	      TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
-	      sh_error_only_stderr (S_TRUE);
-	      (void) sh_unix_rm_lock_file(sh.srvlog.name);
-	      (void) retry_msleep(3, 0);
-	      sh.flag.log_start = S_TRUE;
-	      sh_error_only_stderr (S_FALSE);
-	      sig_fresh_trail       = 0;
-	      --sig_raised;
+		  (void) sh_log_file (NULL, NULL);
+#endif
+		  TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
+		  sh_error_only_stderr (S_TRUE);
+		  (void) sh_unix_rm_lock_file(sh.srvlog.name);
+		  (void) retry_msleep(3, 0);
+		  sh.flag.log_start = S_TRUE;
+		  sh_error_only_stderr (S_FALSE);
+		  sh_thread_pause_flag = S_FALSE;
+		  sig_fresh_trail       = 0;
+		  --sig_raised;
+		  SH_MUTEX_UNLOCK(mutex_thread_nolog);
+		}
 	    }
 	  
@@ -1863,10 +1875,12 @@
 	    {
 	      TPT((0, FIL__, __LINE__, _("msg=<Suspend switch.>\n")));
-	      if (sh_global_suspend_flag == 1) {
-		sh_global_suspend_flag = 0;
-	      } else {
+	      if (sh_global_suspend_flag != 1) {
+		SH_MUTEX_LOCK_UNSAFE(mutex_thread_nolog);
+		sh_global_suspend_flag = 1;
 		sh_error_handle((-1), FIL__, __LINE__, 0, MSG_SUSPEND, 
 				sh.prg_name);
-		sh_global_suspend_flag = 1;
+	      } else {
+		sh_global_suspend_flag = 0;
+		SH_MUTEX_UNLOCK_UNSAFE(mutex_thread_nolog);
 	      }
 	      --sig_suspend_switch;
Index: /trunk/src/sh_kern.c
===================================================================
--- /trunk/src/sh_kern.c	(revision 142)
+++ /trunk/src/sh_kern.c	(revision 143)
@@ -968,8 +968,13 @@
   if (df)
     {
-      SH_MUTEX_LOCK(mutex_readdir);
-
-      while (NULL != (entry = readdir(df)))
+      while (1)
 	{
+	  SH_MUTEX_LOCK(mutex_readdir);
+	  entry = readdir(df);
+	  SH_MUTEX_UNLOCK(mutex_readdir);
+
+	  if (entry == NULL)
+	    break;
+
 	  if (0 == strcmp(entry->d_name, ".") && 
 	      0 == strcmp(entry->d_name, ".."))
@@ -981,6 +986,4 @@
 	  SH_FREE(pcipath);
 	}
-
-      SH_MUTEX_UNLOCK(mutex_readdir);
 
       closedir(df);
Index: /trunk/src/sh_mem.c
===================================================================
--- /trunk/src/sh_mem.c	(revision 142)
+++ /trunk/src/sh_mem.c	(revision 143)
@@ -108,9 +108,5 @@
 
 #ifdef HAVE_PTHREAD
-
 SH_MUTEX_RECURSIVE(mutex_mem);
-
-#else
-#define MEM_MUTEX_INIT ((void)0)
 #endif
 
Index: /trunk/src/sh_processcheck.c
===================================================================
--- /trunk/src/sh_processcheck.c	(revision 142)
+++ /trunk/src/sh_processcheck.c	(revision 143)
@@ -64,4 +64,5 @@
 #include "sh_extern.h"
 #include "sh_calls.h"
+#include "sh_pthread.h"
 
 #ifdef SH_USE_PROCESSCHECK
@@ -70,5 +71,5 @@
 
 #ifdef __linux__
-#define HAVE_THREADS
+#define PS_THREADS
 #endif
 
@@ -76,4 +77,6 @@
  */
 #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
+
+SH_MUTEX_STATIC(mutex_proc_check, PTHREAD_MUTEX_INITIALIZER);
 
 /* sh_prochk_maxpid is one more than the largest pid
@@ -405,7 +408,9 @@
 	  if (S_FALSE == is_in_list(&list_missing, list->str, 0))
 	    {
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
 			      MSG_PCK_MISS,
 			      list->str);
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	    }
 	}
@@ -424,7 +429,9 @@
 		{
 		  tmp = sh_util_safe_name (list->str);
+		  SH_MUTEX_LOCK(mutex_thread_nolog);
 		  sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
 				  MSG_PCK_MISS, 
 				  tmp);
+		  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		  SH_FREE(tmp);
 		}
@@ -458,6 +465,8 @@
     {
       regerror(status, &(new->preg), errbuf, sizeof(errbuf));
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, status, MSG_E_SUBGEN, 
-		      errbuf, _("sh_processes_runps"));
+		      errbuf, _("sh_processes_add_process"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SH_FREE(new->str);
       SH_FREE(new);
@@ -578,6 +587,8 @@
   if (val <= 0)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
 		       _("process check interval"), c);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       retval = -1;
     }
@@ -826,4 +837,5 @@
 	      char errbuf[SH_ERRBUF_SIZE];
 
+	      /* SH_MUTEX_LOCK(mutex_thread_nolog) is in caller */
 	      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, errno, MSG_E_SUBGEN,
 			      sh_error_message(errno, errbuf, sizeof(errbuf)),
@@ -848,5 +860,7 @@
 	      if (flag_err_debug == SL_TRUE)
 		{
-		  sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, num, MSG_E_SUBGEN,
+		  /* SH_MUTEX_LOCK(mutex_thread_nolog) is in caller */
+		  sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, num, 
+				  MSG_E_SUBGEN,
 				  tstr,
 				  _("sh_processes_readps"));
@@ -880,5 +894,5 @@
 	  else if (isspace(cc))
 	    {
-#ifdef HAVE_THREADS
+#ifdef PS_THREADS
 	      num  = 0;
 	      line = SKIP_WS2;
@@ -979,5 +993,5 @@
   if (!sh_prochk_psarg)
     {
-#ifdef HAVE_THREADS
+#ifdef PS_THREADS
       (void) sh_ext_tas_add_argv(&task,  _("-eT"));
 #else
@@ -996,4 +1010,5 @@
   if (status != 0)
     {
+      /* SH_MUTEX_LOCK(mutex_thread_nolog) is in caller */
       sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 
 		      _("Could not open pipe"), _("sh_processes_runps"));
@@ -1037,11 +1052,15 @@
   if (!res)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 
 		      _("Internal error: NULL argument"), 
 		      _("sh_process_check_int"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SL_RETURN ((-1), _("sh_process_check_int"));
     }
 
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   sh_processes_runps (res, NULL, 0, SH_PR_PS, 0);
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
   for (i = sh_prochk_minpid; i != sh_prochk_maxpid; ++i)
     {
@@ -1049,5 +1068,7 @@
       res[j] = sh_processes_check ((pid_t) i, res[j]);
     }
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   sh_processes_runps (res, NULL, 0, SH_PR_PS2, 0);
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 
   /* Evaluate results
@@ -1084,6 +1105,8 @@
 	  if ((res[j] & SH_PR_PS_ANY) && (res[j] & SH_PR_ANY))
 	    {
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_PCK_OK, 
 			      (unsigned long) i, tests);
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	    }
 
@@ -1105,20 +1128,27 @@
 		      char * safe;
 
+		      SH_MUTEX_LOCK(mutex_thread_nolog);
 		      aout = get_user_and_path ((pid_t) i, user, sizeof(user));
+		      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 
 		      if (aout)
 			{
 			  safe = sh_util_safe_name (aout);
+			  SH_MUTEX_LOCK(mutex_thread_nolog);
 			  sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
 					  MSG_PCK_P_HIDDEN,
 					  (unsigned long) i, tests, safe, user);
+			  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 			  SH_FREE(safe);
 			  SH_FREE(aout);
 			}
 		      else
-			sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
-					MSG_PCK_HIDDEN,
-					(unsigned long) i, tests);
-			
+			{
+			  SH_MUTEX_LOCK(mutex_thread_nolog);
+			  sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
+					  MSG_PCK_HIDDEN,
+					  (unsigned long) i, tests);
+			  SH_MUTEX_UNLOCK(mutex_thread_nolog);
+			}
 		    }
 		}
@@ -1134,7 +1164,9 @@
 		  if (S_FALSE == is_in_list(&list_fake, NULL, i))
 		    {
+		      SH_MUTEX_LOCK(mutex_thread_nolog);
 		      sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
 				      MSG_PCK_FAKE, 
 				      (unsigned long) i, tests);
+		      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		    }
 		}
@@ -1150,7 +1182,6 @@
 /* Initialise. 
  */
-int sh_prochk_init(struct mod_type * arg) 
-{
-  (void) arg;
+static int sh_prochk_init_internal() 
+{
   SL_ENTER(_("sh_prochk_init"));
 
@@ -1179,4 +1210,19 @@
 }
 
+int sh_prochk_init (struct mod_type * arg)
+{
+  if (ShProchkActive == S_FALSE)
+    return SH_MOD_FAILED;
+#ifdef HAVE_PTHREAD
+  if (arg != NULL && arg->initval < 0 && sh.flag.isdaemon == S_TRUE)
+    {
+      if (0 == sh_pthread_create(sh_threaded_module_run, (void *)arg))
+	return SH_MOD_THREAD;
+      else
+	return SH_MOD_FAILED;
+    }
+#endif
+  return sh_prochk_init_internal();
+}
 
 int sh_prochk_timer(time_t tcurrent) 
@@ -1199,9 +1245,12 @@
   SL_ENTER(_("sh_prochk_check"));
 
+  SH_MUTEX_LOCK(mutex_proc_check);
   if( ShProchkActive != S_FALSE )
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_PCK_CHECK, 
 		      (unsigned long) sh_prochk_minpid, 
 		      (unsigned long) (sh_prochk_maxpid-1));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 
       if (sh_prochk_res) {
@@ -1220,4 +1269,5 @@
       clean_list (&list_fake);
     }
+  SH_MUTEX_UNLOCK(mutex_proc_check);
 
   SL_RETURN(status, _("sh_prochk_check"));
@@ -1254,4 +1304,5 @@
   SL_ENTER(_("sh_prochk_reconf"));
 
+  SH_MUTEX_LOCK(mutex_proc_check);
   userdef_maxpid     = 0;
   sh_prochk_maxpid   = 0x8000;
@@ -1271,4 +1322,5 @@
     SH_FREE(sh_prochk_pspath);
   sh_prochk_pspath = NULL;
+  SH_MUTEX_UNLOCK(mutex_proc_check);
 
   SL_RETURN(0, _("sh_prochk_reconf"));
Index: /trunk/src/sh_pthread.c
===================================================================
--- /trunk/src/sh_pthread.c	(revision 142)
+++ /trunk/src/sh_pthread.c	(revision 143)
@@ -8,9 +8,11 @@
 #include "sh_calls.h"
 #include "sh_modules.h"
-
-SH_MUTEX_INIT(mutex_skey,   PTHREAD_MUTEX_INITIALIZER);
-SH_MUTEX_INIT(mutex_resolv, PTHREAD_MUTEX_INITIALIZER);
-SH_MUTEX_INIT(mutex_pwent,  PTHREAD_MUTEX_INITIALIZER);
-SH_MUTEX_INIT(mutex_readdir,PTHREAD_MUTEX_INITIALIZER);
+extern volatile  int      sh_thread_pause_flag;
+
+SH_MUTEX_INIT(mutex_skey,         PTHREAD_MUTEX_INITIALIZER);
+SH_MUTEX_INIT(mutex_resolv,       PTHREAD_MUTEX_INITIALIZER);
+SH_MUTEX_INIT(mutex_pwent,        PTHREAD_MUTEX_INITIALIZER);
+SH_MUTEX_INIT(mutex_readdir,      PTHREAD_MUTEX_INITIALIZER);
+SH_MUTEX_INIT(mutex_thread_nolog, PTHREAD_MUTEX_INITIALIZER);
 
 void sh_pthread_mutex_unlock (void *arg)
@@ -136,4 +138,10 @@
 /* ---- Utility functions for modules ----
  */
+
+#undef  S_TRUE
+#define S_TRUE    1
+#undef  S_FALSE
+#define S_FALSE   0
+
 void sh_threaded_module_cleanup(void *arg)
 {
@@ -162,5 +170,6 @@
 	  while (1)
 	    {
-	      if (0 != this_module->mod_timer(time(NULL)))
+	      if (sh_thread_pause_flag != S_TRUE && 
+		  0 != this_module->mod_timer(time(NULL)))
 		{
 		  /* If module has been de-activated on reconfigure,
@@ -172,6 +181,6 @@
 		    break;
 		  pthread_testcancel();
-		  retry_msleep(1,0);
 		}
+	      retry_msleep(1,0);
 	    }
 
Index: /trunk/src/sh_suidchk.c
===================================================================
--- /trunk/src/sh_suidchk.c	(revision 142)
+++ /trunk/src/sh_suidchk.c	(revision 143)
@@ -874,8 +874,4 @@
   do {
 
-    if (sig_urgent > 0) {
-      SL_RETURN( (0), _("sh_suidchk_check_internal"));
-    }
-
     thisEntry = readdir (thisDir);
 
@@ -905,4 +901,8 @@
     if (!dirlist)
       break;
+
+    if (sig_urgent > 0) {
+      SL_RETURN( (0), _("sh_suidchk_check_internal"));
+    }
 
     tmpcat = SH_ALLOC(PATH_MAX);
Index: /trunk/src/sh_tools.c
===================================================================
--- /trunk/src/sh_tools.c	(revision 142)
+++ /trunk/src/sh_tools.c	(revision 143)
@@ -522,4 +522,6 @@
 #endif
 	{
+	  host_name = NULL;
+
 	  SH_MUTEX_LOCK(mutex_resolv);
 
@@ -596,9 +598,8 @@
 			}
 		    }
-
-		  SH_FREE(host_name);
 		}
 	    }
 	  SH_MUTEX_UNLOCK(mutex_resolv);
+	  if (host_name) SH_FREE(host_name);
 	}
   
Index: /trunk/src/sh_unix.c
===================================================================
--- /trunk/src/sh_unix.c	(revision 142)
+++ /trunk/src/sh_unix.c	(revision 143)
@@ -4221,5 +4221,6 @@
   if (0 != page_locking)
     {
-      SL_RETURN((-1), _("sh_unix_mlock"));
+      status = -1;
+      goto exit_mlock;
     }
 
@@ -4284,5 +4285,5 @@
 	  SH_FREE(page_list);
 	  page_locking = 0;
-	  SL_RETURN((status), _("sh_unix_mlock"));
+	  goto exit_mlock;
 	}
       page_list->next = sh_page_locked;
@@ -4292,4 +4293,6 @@
     }
   page_locking = 0;
+
+ exit_mlock:
   SH_MUTEX_UNLOCK_UNSAFE(mutex_mlock);
 
@@ -4332,5 +4335,6 @@
   if (0 != page_locking)
     {
-      SL_RETURN((-1), _("sh_unix_munlock"));
+      status = -1;
+      goto exit_munlock;
     }
   page_locking = 1;
@@ -4437,6 +4441,7 @@
 
   page_locking = 0;
+
+ exit_munlock:
   SH_MUTEX_UNLOCK_UNSAFE(mutex_mlock);
-
   SL_RETURN((status), _("sh_unix_munlock"));
 }
Index: /trunk/src/sh_utmp.c
===================================================================
--- /trunk/src/sh_utmp.c	(revision 142)
+++ /trunk/src/sh_utmp.c	(revision 143)
@@ -79,5 +79,7 @@
 #include "sh_modules.h"
 #include "sh_utmp.h"
-
+#include "sh_pthread.h"
+
+SH_MUTEX_EXTERN(mutex_thread_nolog);
 
 #ifdef TM_IN_SYS_TIME
@@ -300,6 +302,8 @@
   if (sh_utmpfile == NULL) 
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       fd = (int) aud_open (FIL__, __LINE__, SL_NOPRIV, 
 			   sh_utmppath, O_RDONLY, 0);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       if (fd >= 0)
 	{
@@ -313,6 +317,8 @@
 	{
 	  error = errno;
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, error, MSG_E_ACCESS,
 			   (long) sh.real.uid, sh_utmppath);
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SL_RET0(_("sh_utmp_setutent"));
 	}
@@ -489,5 +495,5 @@
     return SH_MOD_FAILED;
 #ifdef HAVE_PTHREAD
-  if (arg != NULL && arg->initval < 0)
+  if (arg != NULL && arg->initval < 0 && sh.flag.isdaemon == S_TRUE)
     {
       if (0 == sh_pthread_create(sh_threaded_module_run, (void *)arg))
@@ -559,5 +565,7 @@
   if (ShUtmpActive == BAD)
     SL_RETURN( (-1), _("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);
 
@@ -579,5 +587,7 @@
   tmp[0] = '='; tmp[1] = '\0';
   (void) sl_strlcat (tmp, c, 32);
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   retval = sh_error_set_level (tmp, &ShUtmpLoginSolo);
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
   SL_RETURN(retval, _("sh_utmp_set_login_solo"));
 }
@@ -591,5 +601,7 @@
   tmp[0] = '='; tmp[1] = '\0';
   (void) sl_strlcat (tmp, c, 32);
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   retval = sh_error_set_level (tmp, &ShUtmpLoginMulti);
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
   SL_RETURN(retval, _("sh_utmp_set_login_multi"));
 }
@@ -603,5 +615,7 @@
   tmp[0] = '='; tmp[1] = '\0';
   (void) sl_strlcat (tmp, c, 32);
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   retval = sh_error_set_level (tmp, &ShUtmpLogout);
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
   SL_RETURN(retval, _("sh_utmp_set_logout_good"));
 }
@@ -616,6 +630,8 @@
   if (val <= 0)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
 		       _("utmp timer"), c);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       retval = -1;
     }
@@ -823,4 +839,5 @@
 	  ) {
 	status = sh_utmp_login_a(user->name);
+	SH_MUTEX_LOCK(mutex_thread_nolog);
 	(void) sh_unix_time (user->time, ttt, TIM_MAX);
 	sh_error_handle( ShUtmpLoginSolo, FIL__, __LINE__, 0,
@@ -843,8 +860,10 @@
 			 status
 			 );
+	SH_MUTEX_UNLOCK(mutex_thread_nolog);
       } else
 	if (0 != sh_utmp_is_virtual(ut->ut_line, user->ut_host))
 	  {       
 	    status = sh_utmp_login_a(user->name);
+	    SH_MUTEX_LOCK(mutex_thread_nolog);
 	    (void) sh_unix_time (user->time, ttt, TIM_MAX);
 	    sh_error_handle( ShUtmpLoginMulti, FIL__, __LINE__, 0,
@@ -867,4 +886,5 @@
 			     status
 			     );
+	    SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  }
       
@@ -882,4 +902,5 @@
 	{
 	  status = sh_utmp_login_r(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,
@@ -902,4 +923,5 @@
 			   status
 			   );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  userold->next = user->next;
 	  if (user == userlist)
@@ -912,4 +934,5 @@
 	{
 	  (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,
@@ -918,4 +941,5 @@
 			   ttt, 0
 			   );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	}
       SL_RET0(_("sh_utmp_addlogin"));
@@ -943,7 +967,6 @@
       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)
@@ -965,10 +988,11 @@
 		       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)
@@ -990,4 +1014,5 @@
 		       1
 		       );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       sh_utmp_logout_morechecks(user);
       userold->next = user->next;
@@ -1014,4 +1039,5 @@
   struct SH_UTMP_S * ut;
   unsigned long this_read = 0;
+  int           val_retry;
 
   SL_ENTER(_("sh_utmp_check_internal"));
@@ -1019,9 +1045,15 @@
   /* error if no access
    */
-  if (0 != retry_lstat(FIL__, __LINE__, mode_path[mode], &buf)) 
+  do {
+    val_retry = /*@-unrecog@*/lstat ( mode_path[mode], &buf)/*@+unrecog@*/;
+  } while (val_retry < 0 && errno == EINTR);
+
+  if (0 != val_retry) 
     {
       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]);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SL_RET0(_("sh_utmp_check_internal"));
     }
@@ -1043,6 +1075,8 @@
   if (/*@-usedef@*/buf.st_size < lastsize/*@+usedef@*/ && mode < 2) 
     { 
+      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
