Index: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in	(revision 139)
+++ trunk/Makefile.in	(revision 140)
@@ -1638,5 +1638,5 @@
 sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
-sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
+sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
 sh_files.o: $(srcsrc)/sh_files.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/zAVLTree.h 
 sh_getopt.o: $(srcsrc)/sh_getopt.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_getopt.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h 
@@ -1652,5 +1652,5 @@
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h 
 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_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_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_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 
@@ -1697,3 +1697,3 @@
 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_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 
+sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_modules.h $(srcinc)/sh_calls.h 
Index: trunk/depend.dep
===================================================================
--- trunk/depend.dep	(revision 139)
+++ trunk/depend.dep	(revision 140)
@@ -4,5 +4,5 @@
 sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
-sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
+sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
 sh_files.o: $(srcsrc)/sh_files.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/zAVLTree.h 
 sh_getopt.o: $(srcsrc)/sh_getopt.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_getopt.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h 
@@ -18,5 +18,5 @@
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h 
 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_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_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_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 
@@ -63,3 +63,3 @@
 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_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 
+sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_modules.h $(srcinc)/sh_calls.h 
Index: trunk/depend.sum
===================================================================
--- trunk/depend.sum	(revision 139)
+++ trunk/depend.sum	(revision 140)
@@ -1,1 +1,1 @@
-754800869
+836204565
Index: trunk/include/samhain.h
===================================================================
--- trunk/include/samhain.h	(revision 139)
+++ trunk/include/samhain.h	(revision 140)
@@ -126,4 +126,10 @@
   SH_CHECK_INIT    = 1,
   SH_CHECK_CHECK   = 2
+};
+
+enum {
+  SH_MOD_ACTIVE    = 0, 
+  SH_MOD_THREAD    = 1,
+  SH_MOD_FAILED    = 2
 };
 
Index: trunk/include/sh_kern.h
===================================================================
--- trunk/include/sh_kern.h	(revision 139)
+++ trunk/include/sh_kern.h	(revision 140)
@@ -6,5 +6,5 @@
 
 #ifdef SH_USE_KERN
-int sh_kern_init  (void);
+int sh_kern_init  (struct mod_type * arg);
 int sh_kern_timer (time_t tcurrent);
 int sh_kern_check (void);
Index: trunk/include/sh_modules.h
===================================================================
--- trunk/include/sh_modules.h	(revision 139)
+++ trunk/include/sh_modules.h	(revision 140)
@@ -3,4 +3,5 @@
 #define SH_MODULE_H
 
+#include "sh_pthread.h"
 
 typedef struct rconf
@@ -19,5 +20,5 @@
 
   /* The initialization function. Return 0 on success.         */
-  int (* mod_init)    (void);  
+  int (* mod_init)    (struct mod_type * arg);  
                              
   /* The timer function. Return 0 if NOT time to check.        */
@@ -39,4 +40,6 @@
   sh_rconf * conf_table; 
 
+  SH_MUTEX(mod_mutex);
+
 } sh_mtype;
 
Index: trunk/include/sh_mounts.h
===================================================================
--- trunk/include/sh_mounts.h	(revision 139)
+++ trunk/include/sh_mounts.h	(revision 140)
@@ -11,5 +11,5 @@
 
 #ifdef SH_USE_MOUNTS
-int sh_mounts_init  (void);
+int sh_mounts_init  (struct mod_type * arg);
 int sh_mounts_timer (time_t tcurrent);
 int sh_mounts_check (void);
Index: trunk/include/sh_portcheck.h
===================================================================
--- trunk/include/sh_portcheck.h	(revision 139)
+++ trunk/include/sh_portcheck.h	(revision 140)
@@ -3,5 +3,5 @@
 #define SH_PORTCHECK_H
 
-int sh_portchk_init(void);
+int sh_portchk_init(struct mod_type * arg);
 int sh_portchk_timer(time_t tcurrent);
 int sh_portchk_check(void);
Index: trunk/include/sh_processcheck.h
===================================================================
--- trunk/include/sh_processcheck.h	(revision 139)
+++ trunk/include/sh_processcheck.h	(revision 140)
@@ -3,5 +3,5 @@
 #define SH_PROCESSCHECK_H
 
-int sh_prochk_init(void);
+int sh_prochk_init(struct mod_type * arg);
 int sh_prochk_timer(time_t tcurrent);
 int sh_prochk_check(void);
Index: trunk/include/sh_pthread.h
===================================================================
--- trunk/include/sh_pthread.h	(revision 139)
+++ trunk/include/sh_pthread.h	(revision 140)
@@ -123,4 +123,5 @@
 #else
 
+#define PTHREAD_MUTEX_INITIALIZER               NULL
 #define SH_MUTEX(M)				void *SH_MUTEX_DUMMY_ ## M
 #define SH_MUTEX_INIT(M,I)			extern void *SH_MUTEX_DUMMY_ ## M
Index: trunk/include/sh_suidchk.h
===================================================================
--- trunk/include/sh_suidchk.h	(revision 139)
+++ trunk/include/sh_suidchk.h	(revision 140)
@@ -6,5 +6,5 @@
 
 #ifdef SH_USE_SUIDCHK
-int sh_suidchk_init  (void);
+int sh_suidchk_init  (struct mod_type * arg);
 int sh_suidchk_timer (time_t tcurrent);
 int sh_suidchk_check (void);
Index: trunk/include/sh_userfiles.h
===================================================================
--- trunk/include/sh_userfiles.h	(revision 139)
+++ trunk/include/sh_userfiles.h	(revision 140)
@@ -9,5 +9,5 @@
 
 #ifdef SH_USE_USERFILES
-int sh_userfiles_init  (void);
+int sh_userfiles_init  (struct mod_type * arg);
 int sh_userfiles_timer (time_t tcurrent);
 int sh_userfiles_check (void);
Index: trunk/include/sh_utmp.h
===================================================================
--- trunk/include/sh_utmp.h	(revision 139)
+++ trunk/include/sh_utmp.h	(revision 140)
@@ -6,5 +6,5 @@
 
 #ifdef SH_USE_UTMP
-int sh_utmp_init  (void);
+int sh_utmp_init  (struct mod_type * arg);
 int sh_utmp_timer (time_t tcurrent);
 int sh_utmp_check (void);
Index: trunk/src/samhain.c
===================================================================
--- trunk/src/samhain.c	(revision 139)
+++ trunk/src/samhain.c	(revision 140)
@@ -1637,5 +1637,5 @@
   for (modnum = 0; modList[modnum].name != NULL; ++modnum) 
     {
-      if (0 != (status = modList[modnum].mod_init()))
+      if ( 0 != (status = modList[modnum].mod_init(&(modList[modnum]))) )
 	{
 	  if (status == (-1)) {
@@ -1795,5 +1795,5 @@
 	      for (modnum = 0; modList[modnum].name != NULL; ++modnum) 
 		{
-		  if (0 != (status = modList[modnum].mod_init()))
+		  if (0 != (status = modList[modnum].mod_init(&(modList[modnum]))))
 		    {
 		      if (status == (-1)) {
Index: trunk/src/sh_error.c
===================================================================
--- trunk/src/sh_error.c	(revision 139)
+++ trunk/src/sh_error.c	(revision 140)
@@ -56,4 +56,5 @@
 #include "sh_forward.h"
 #include "sh_prelude.h"
+#include "sh_pthread.h"
 
 #if defined(WITH_DATABASE)
@@ -857,4 +858,6 @@
  **********************************************************/
 
+SH_MUTEX_RECURSIVE(mutex_err_handle);
+
 void sh_error_handle (int sev, char * file, long line, 
 		      long status, unsigned long msg_id, ...)
@@ -868,7 +871,7 @@
 
   int    flag_inet  = S_FALSE;
+
+#ifdef SH_WITH_SERVER
   int    class_inet = clt_class;      /* initialize from global */
-
-#ifdef SH_WITH_SERVER
   char   local_inet_peer[SH_MINIBUF];
 #endif
@@ -908,4 +911,7 @@
   SL_ENTER(_("sh_error_handle"));
 
+  SH_MUTEX_RECURSIVE_INIT(mutex_err_handle);
+  SH_MUTEX_RECURSIVE_LOCK(mutex_err_handle);
+
 #ifdef SH_WITH_SERVER
   /* copy the global string into a local array
@@ -918,29 +924,30 @@
   else
     local_inet_peer[0] = '\0';
-#endif
 
   clt_class = (-1);      /* reset global */
+#endif
+
 
   if (own_block == 1)
     {
-      SL_RET0(_("sh_error_handle"));
+      goto exit_here;
     }
 
   /* --- Initialize to default values. ---
    */
-  own_block = 1;
   if (IsInitialized == BAD) 
     (void) sh_error_init();
-  own_block = 0;
-
-  /* --- Consistency checks. ---
-   */
-  own_block = 1;
+
+  /* Returns pointer to (constant|thread-specific) static memory
+   */
   fmt = /*@i@*/get_format (msg_id, &severity, &class);
-  own_block = 0;
-
+
+#ifdef SH_WITH_SERVER
   if (class_inet != (-1))
     class = (unsigned int) class_inet;
-
+#endif
+
+  /* --- Consistency check. ---
+   */
   ASSERT((fmt != NULL), _("fmt != NULL"))
   if (fmt == NULL)
@@ -949,5 +956,5 @@
 	      _("ERROR: msg=<NULL format>, file=<%s>, line=<%ld>\n"), 
 	      file, line);
-      SL_RET0(_("sh_error_handle"));
+      goto exit_here;
     }
 
@@ -995,10 +1002,10 @@
        )
     {
-      SL_RET0(_("sh_error_handle"));
+      goto exit_here;
     }
 
   if ((severity & SH_ERR_NOT) != 0)
     {
-      SL_RET0(_("sh_error_handle"));
+      goto exit_here;
     }
 
@@ -1017,11 +1024,8 @@
   lmsg->line     = line;
   lmsg->status   = status;
-  own_block = 0;
-
 
   /* Format the log message with timestamp etc.
    * Allocate lmsg->msg
    */
-  own_block = 1;
   va_start (vl, msg_id);
   (void) sh_error_string (lmsg, vl);
@@ -1311,4 +1315,8 @@
   SH_FREE( lmsg );
   own_block = 0;
+
+ exit_here:
+
+  SH_MUTEX_RECURSIVE_UNLOCK(mutex_err_handle);
 
   /*@i@*/SL_RET0(_("sh_error_handle"));
Index: trunk/src/sh_kern.c
===================================================================
--- trunk/src/sh_kern.c	(revision 139)
+++ trunk/src/sh_kern.c	(revision 140)
@@ -1754,5 +1754,5 @@
 static int AddressReconf = 0;
 
-int sh_kern_init ()
+int sh_kern_init (struct mod_type * arg)
 {
 #if defined(HOST_IS_LINUX)
@@ -1760,4 +1760,5 @@
   char         * str;
 #endif
+  (void) arg;
 
   SL_ENTER(_("sh_kern_init"));
Index: trunk/src/sh_mem.c
===================================================================
--- trunk/src/sh_mem.c	(revision 139)
+++ trunk/src/sh_mem.c	(revision 140)
@@ -256,8 +256,4 @@
 	  eblock = 1;
 	  (void) safe_logger (0, 0, NULL);
-	  /*
-	  sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM,
-			   file, line);
-	  */
 	  eblock = 0;
 	}
@@ -348,8 +344,4 @@
 	  eblock = 1;
 	  (void) safe_logger(0, 0, NULL);
-	  /*
-	  sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM,
-			   file, line);
-	  */
 	  eblock = 0;
 	}
@@ -491,7 +483,4 @@
 	  eblock = 1;
 	  (void) safe_logger(0, 0, NULL);
-	  /*
-	  sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_MMEM);
-	  */
 	  eblock = 0;
 	}
Index: trunk/src/sh_modules.c
===================================================================
--- trunk/src/sh_modules.c	(revision 139)
+++ trunk/src/sh_modules.c	(revision 140)
@@ -7,4 +7,5 @@
 
 #include "sh_modules.h"
+#include "sh_pthread.h"
 
 #include "sh_utmp.h"
@@ -29,4 +30,5 @@
     N_("[Utmp]"),
     sh_utmp_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -44,4 +46,5 @@
     N_("[Mounts]"),
     sh_mounts_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -59,4 +62,5 @@
     N_("[UserFiles]"),
     sh_userfiles_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -74,4 +78,5 @@
     N_("[Kernel]"),
     sh_kern_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -89,4 +94,5 @@
     N_("[SuidCheck]"),
     sh_suidchk_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -104,4 +110,5 @@
     N_("[ProcessCheck]"),
     sh_prochk_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -119,4 +126,5 @@
     N_("[PortCheck]"),
     sh_portchk_table,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 #endif
@@ -134,4 +142,5 @@
     NULL,
     NULL,
+    PTHREAD_MUTEX_INITIALIZER,
   },
 };
Index: trunk/src/sh_mounts.c
===================================================================
--- trunk/src/sh_mounts.c	(revision 139)
+++ trunk/src/sh_mounts.c	(revision 140)
@@ -165,6 +165,7 @@
  * This is called once at the start of each samhain run.
  * Non-configuration setup code should be placed here. */
-int sh_mounts_init ()
-{
+int sh_mounts_init (struct mod_type * arg)
+{
+  (void) arg;
   SL_ENTER(_("sh_mounts_init"));
 
Index: trunk/src/sh_portcheck.c
===================================================================
--- trunk/src/sh_portcheck.c	(revision 139)
+++ trunk/src/sh_portcheck.c	(revision 140)
@@ -815,9 +815,10 @@
 #endif
 
-int sh_portchk_init ()
+int sh_portchk_init (struct mod_type * arg)
 {
   struct hostent * hent;
   int              i = 0;
   char errbuf[256];
+  (void) arg;
 
   if (portchk_debug)
Index: trunk/src/sh_processcheck.c
===================================================================
--- trunk/src/sh_processcheck.c	(revision 139)
+++ trunk/src/sh_processcheck.c	(revision 140)
@@ -1150,6 +1150,7 @@
 /* Initialise. 
  */
-int sh_prochk_init(void) 
-{
+int sh_prochk_init(struct mod_type * arg) 
+{
+  (void) arg;
   SL_ENTER(_("sh_prochk_init"));
 
Index: trunk/src/sh_pthread.c
===================================================================
--- trunk/src/sh_pthread.c	(revision 139)
+++ trunk/src/sh_pthread.c	(revision 140)
@@ -2,6 +2,11 @@
 
 #include "sh_pthread.h"
+#include "sh_modules.h"
 
 #ifdef HAVE_PTHREAD
+
+#include <signal.h>
+#include "sh_calls.h"
+
 SH_MUTEX_INIT(mutex_skey,   PTHREAD_MUTEX_INITIALIZER);
 SH_MUTEX_INIT(mutex_resolv, PTHREAD_MUTEX_INITIALIZER);
@@ -15,4 +20,162 @@
 }
 
+int sh_pthread_init_threadspecific()
+{
+  int rc = 0;
+#ifdef SH_STEALTH
+  extern int sh_g_thread();
+
+  rc = sh_g_thread();
+  if (rc != 0)
+    return rc;
+#endif
+
+  return rc;
+}
+
+
+/* 
+ *  ----  Utilities for modules  ----
+ */
+
+/* MODULES: init()
+ *             -- starts thread_run() function if threaded
+ *             -- fallback on internal_init if threading fails
+ *             -- and returns MODULE_INACTIVE/MODULE_ACTIVE/MODULE_THREADED
+ *
+ *                int retval = MODULE_INACTIVE;
+ *                if (0 != sh_pthread_create(thread_run, NULL))
+ *                   return internal_init();
+ *                return MODULE_THREADED;
+ *
+ *          thread_run() 
+ *             -- calls internal init, 
+ *             -- polls timer, 
+ *             -- runs module check,
+ *             -- runs sh_pthread_testcancel()
+ *             -- returns (return == exit)
+ */
+
+#define SH_NUM_THREADS 16
+static pthread_t threads[SH_NUM_THREADS];
+static int       ithread[SH_NUM_THREADS];
+static pthread_mutex_t  create_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int sh_pthread_create(void *(*start_routine)(void*), void *arg)
+{
+  int rc, nthread = 1;
+  sigset_t signal_set;
+  int retval = 0;
+
+  pthread_mutex_lock(&create_mutex);
+
+  /* block all signals 
+   */
+  sigfillset( &signal_set );
+  pthread_sigmask( SIG_BLOCK, &signal_set, NULL );
+
+  /* find a free slot in threads[]
+   */
+  while (nthread < SH_NUM_THREADS) 
+    {
+      if (ithread[nthread] == 0)
+	break;
+      ++nthread;
+      if (nthread == SH_NUM_THREADS)
+	{
+	  retval = -1;
+	  goto err_out;
+	}
+    } 
+
+  rc = pthread_create(&threads[nthread], NULL, start_routine, arg);
+  if (rc != 0)
+    {
+      retval = -1;
+      goto err_out;
+    }
+
+  ithread[nthread] = 1;
+
+ err_out:
+  pthread_sigmask( SIG_UNBLOCK, &signal_set, NULL );
+  pthread_mutex_unlock(&create_mutex);
+  return retval;
+}
+
+int sh_pthread_cancel_all()
+{
+  int i;
+  int ret = 0;
+
+  SH_MUTEX_LOCK(create_mutex);
+
+  for (i = 1; i < SH_NUM_THREADS; ++i)
+    {
+      if (ithread[i] != 0)
+	if (0 != pthread_cancel(threads[i]))
+	  ithread[i] = 0;
+    }
+
+  for (i = 1; i < SH_NUM_THREADS; ++i)
+    {
+      if (ithread[i] != 0)
+	pthread_join(threads[i], NULL);
+      ithread[i] = 0;
+    }
+
+  SH_MUTEX_UNLOCK(create_mutex);
+  return ret;
+}
+
+/* ---- Utility functions for modules ----
+ */
+void sh_threaded_module_reconf(void *arg)
+{
+  sh_mtype * this_module = (sh_mtype *) arg;
+  this_module->mod_reconf();
+  return;
+}
+
+void sh_threaded_module_run(void *arg)
+{
+  sh_mtype * this_module = (sh_mtype *) arg;
+
+  /* First we lock the module. This ensures that it cannot be
+   * run twice.
+   */
+  pthread_cleanup_push(sh_pthread_mutex_unlock, (void*) &(this_module->mod_mutex));
+  pthread_mutex_lock(&(this_module->mod_mutex));
+
+  if (0 == sh_pthread_init_threadspecific())
+    {
+
+      if (0 == this_module->mod_init(NULL))
+	{
+	  pthread_cleanup_push(sh_threaded_module_reconf, arg);
+
+	  while (1)
+	    {
+	      if (0 != this_module->mod_timer(time(NULL)))
+		{
+		  this_module->mod_check();
+		  pthread_testcancel();
+		  retry_msleep(1,0);
+		}
+	    }
+
+	  pthread_cleanup_pop(1); /* notreached,but required */
+	}
+    }
+
+  pthread_cleanup_pop(1);
+
+  return;
+}
+
+
+/*
+ *  ----  Implementation of recursive mutexes from libxml2  ----
+ */
 #if !defined(HAVE_PTHREAD_MUTEX_RECURSIVE)
 /**
@@ -21,6 +184,36 @@
  * Gary Pennington <Gary.Pennington@uk.sun.com>
  * daniel@veillard.com
- */
-
+ 
+ * Except where otherwise noted in the source code (e.g. the files hash.c,
+ * list.c and the trio files, which are covered by a similar licence but
+ * with different Copyright notices) all the files are:
+ *
+ *    Copyright (C) 1998-2003 Daniel Veillard.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is fur-
+ * nished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+ * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Daniel Veillard shall not
+ * be used in advertising or otherwise to promote the sale, use or other deal-
+ * ings in this Software without prior written authorization from him.
+ */
+
+/* Modified NewRMutex -> InitRMutex. We use a static structure, rather than 
+ * allocating one. Also dropped code for non-POSIX OSes.
+ */
 void sh_InitRMutex(struct sh_RMutex * tok)
 {
Index: trunk/src/sh_suidchk.c
===================================================================
--- trunk/src/sh_suidchk.c	(revision 139)
+++ trunk/src/sh_suidchk.c	(revision 140)
@@ -1172,6 +1172,7 @@
  *
  *************/
-int sh_suidchk_init ()
-{
+int sh_suidchk_init (struct mod_type * arg)
+{
+  (void) arg;
   if (ShSuidchkActive == S_FALSE)
     return (-1);
Index: trunk/src/sh_userfiles.c
===================================================================
--- trunk/src/sh_userfiles.c	(revision 139)
+++ trunk/src/sh_userfiles.c	(revision 140)
@@ -246,9 +246,10 @@
 /* Build the list of users, then use this to construct the filenames to
  * be checked. */
-int sh_userfiles_init(void) {
+int sh_userfiles_init(struct mod_type * arg) {
     struct passwd *cur_user;
     struct userhomeslist *end;
     struct userhomeslist *new;
     struct userhomeslist *homes;
+    (void) arg;
 
     SL_ENTER(_("sh_userfiles_init"));
Index: trunk/src/sh_utmp.c
===================================================================
--- trunk/src/sh_utmp.c	(revision 139)
+++ trunk/src/sh_utmp.c	(revision 140)
@@ -461,7 +461,8 @@
  *
  *************/
-int sh_utmp_init ()
+int sh_utmp_init (struct mod_type * arg)
 {
   static int done = 0;
+  (void) arg;
 
   SL_ENTER(_("sh_utmp_init"));
Index: trunk/test/testcompile.sh
===================================================================
--- trunk/test/testcompile.sh	(revision 139)
+++ trunk/test/testcompile.sh	(revision 140)
@@ -51,5 +51,5 @@
 	    for i in ${CDIR}/*.c.sm ; do
 	        # echo $i;
-		cat $i | ./unreached_code.pl;
+		cat $i | ./unreached_code.pl | grep -v sh_threaded_module_run;
 		cat $i | ./ampersand_missing.sh;
 		cat $i | ./eqeq.pl;
