Index: trunk/include/sh_modules.h
===================================================================
--- trunk/include/sh_modules.h	(revision 252)
+++ trunk/include/sh_modules.h	(revision 253)
@@ -26,4 +26,5 @@
 
   /* The check function. Return 0 on success.                  */
+  /* Return nonzero on fatal error or if module is disabled.   */
   int (* mod_check)   (void); 
 
Index: trunk/src/sh_portcheck.c
===================================================================
--- trunk/src/sh_portcheck.c	(revision 252)
+++ trunk/src/sh_portcheck.c	(revision 253)
@@ -1618,4 +1618,14 @@
   if (sh_portchk_active != S_FALSE)
     {
+#ifdef SL_DEBUG
+      sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Checking for open ports"),
+		      _("sh_portchk_check"));
+#else
+      sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+		      _("Checking for open ports"),
+		      _("sh_portchk_check"));
+#endif
+
       sh_portchk_reset_lists();
       if (0 != geteuid())
@@ -1627,5 +1637,6 @@
 	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-			  _("not scanning ports below 1024"), _("sh_portchk_check"));
+			  _("not scanning ports below 1024"), 
+			  _("sh_portchk_check"));
 	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 #endif
Index: trunk/src/sh_processcheck.c
===================================================================
--- trunk/src/sh_processcheck.c	(revision 252)
+++ trunk/src/sh_processcheck.c	(revision 253)
@@ -1360,7 +1360,13 @@
     {
       SH_MUTEX_LOCK(mutex_thread_nolog);
+#ifdef SL_DEBUG
+      sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0, MSG_PCK_CHECK, 
+		      (unsigned long) sh_prochk_minpid, 
+		      (unsigned long) (sh_prochk_maxpid-1));
+#else
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_PCK_CHECK, 
 		      (unsigned long) sh_prochk_minpid, 
 		      (unsigned long) (sh_prochk_maxpid-1));
+#endif
       SH_MUTEX_UNLOCK(mutex_thread_nolog);
 
Index: trunk/src/sh_suidchk.c
===================================================================
--- trunk/src/sh_suidchk.c	(revision 252)
+++ trunk/src/sh_suidchk.c	(revision 253)
@@ -163,4 +163,6 @@
 #endif
 
+SH_MUTEX_STATIC(mutex_suid_check, PTHREAD_MUTEX_INITIALIZER);
+
 extern unsigned long sh_files_maskof (int class);
 
@@ -202,7 +204,9 @@
   if (depth > 99)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 		       MSG_SUID_ERROR,
 		       _("do_truncate: max depth 99 exceeded"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       return -1;
     }
@@ -210,7 +214,9 @@
   if (path[0] != '/')
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 		       MSG_SUID_ERROR,
 		       _("do_truncate: not an absolute path"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       return -1;
     }
@@ -222,7 +228,9 @@
       if (0 != retry_lstat(FIL__, __LINE__, path, &one))
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno,
 			   MSG_SUID_ERROR,
 			   sh_error_message(errno, errbuf, sizeof(errbuf)));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  *q = '/'; 
 	  return -1; 
@@ -231,7 +239,9 @@
 	
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 			   MSG_SUID_ERROR,
 			   _("Possible race: not a directory"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  *q = '/'; 
 	  return -1; 
@@ -241,7 +251,9 @@
       if (0 != chdir(path))
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno,
 			   MSG_SUID_ERROR,
 			   sh_error_message(errno, errbuf, sizeof(errbuf)));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  *q = '/';
 	  return -1;
@@ -259,7 +271,9 @@
 	  (!S_ISDIR(two.st_mode))/*@+usedef@*/)
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 			   MSG_SUID_ERROR,
 			   _("Possible race: lstat(dir) != lstat(.)"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  return -1;
 	}
@@ -276,7 +290,9 @@
       if (0 != retry_lstat(FIL__, __LINE__, path, &one))
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno,
 			   MSG_SUID_ERROR,
 			   sh_error_message(errno, errbuf, sizeof(errbuf)));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  return -1;
 	} 
@@ -284,14 +300,18 @@
       if (-1 == fd)
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno,
 			   MSG_SUID_ERROR,
 			   sh_error_message(errno, errbuf, sizeof(errbuf)));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  return -1;
 	} 
       if (0 != retry_fstat(FIL__, __LINE__, fd, &two))
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno,
 			   MSG_SUID_ERROR,
 			   sh_error_message(errno, errbuf, sizeof(errbuf)));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  (void) sl_close_fd(FIL__, __LINE__, fd);
 	  return -1; 
@@ -300,7 +320,9 @@
 	  (one.st_ino != two.st_ino)/*@+usedef@*/)
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 			   MSG_SUID_ERROR,
 			   _("Possible race: lstat != fstat"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  (void) sl_close_fd(FIL__, __LINE__, fd); 
 	  return -1;
@@ -308,7 +330,9 @@
       if (!S_ISREG(two.st_mode))
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 			   MSG_SUID_ERROR,
 			   _("Possible race: not a regular file"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  (void) sl_close_fd(FIL__, __LINE__, fd); 
 	  return -1;
@@ -316,7 +340,9 @@
       if ((0 == (two.st_mode & S_ISUID)) && (0 == (two.st_mode & S_ISGID)))
 	{ 
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 			   MSG_SUID_ERROR,
 			   _("Possible race: not a suid/sgid file"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  (void) sl_close_fd(FIL__, __LINE__, fd); 
 	  return -1;
@@ -331,14 +357,18 @@
 	  if (-1 == /*@-unrecog@*/fchmod(fd, two.st_mode)/*@+unrecog@*/)
 	    {
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle ((-1), FIL__, __LINE__, errno,
 			       MSG_SUID_ERROR,
 			       sh_error_message(errno, errbuf, sizeof(errbuf)));
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      (void) sl_close_fd(FIL__, __LINE__, fd); 
 	      return -1;
 	    }
 #else
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno,
 			   MSG_SUID_ERROR,
 			   _("The fchmod() function is not available"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  (void) sl_close_fd(FIL__, __LINE__, fd); 
 	  return -1;
@@ -346,7 +376,9 @@
 	  if (two.st_nlink > 1)
 	    {
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle ((-1), FIL__, __LINE__, 0,
 			       MSG_SUID_ERROR,
 			       _("Not truncated because hardlink count gt 1"));
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      (void) sl_close_fd(FIL__, __LINE__, fd); 
 	      return -1;
@@ -356,7 +388,9 @@
 	  if (-1 == /*@-unrecog@*/ftruncate(fd, 0)/*@+unrecog@*/)
 	    {
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle ((-1), FIL__, __LINE__, errno,
 			       MSG_SUID_ERROR,
 			       sh_error_message(errno, errbuf, sizeof(errbuf)));
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      (void) sl_close_fd(FIL__, __LINE__, fd); 
 	      return -1;
@@ -367,7 +401,9 @@
 	  if (-1 == retry_aud_unlink(FIL__, __LINE__, path))
 	    {
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle ((-1), FIL__, __LINE__, errno,
 			       MSG_SUID_ERROR,
 			       sh_error_message(errno, errbuf, sizeof(errbuf)));
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      (void) sl_close_fd(FIL__, __LINE__, fd); 
 	      return -1;
@@ -381,5 +417,5 @@
 static int do_truncate (const char * path_in)
 {
-  int    caperr;
+  volatile int    caperr;
   int    result;
   char * path;
@@ -388,14 +424,18 @@
   if (0 != chdir("/"))
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, errno,
 		       MSG_SUID_ERROR,
 		       sh_error_message(errno, errbuf, sizeof(errbuf)));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
     }
 
   if (0 != (caperr = sl_get_cap_qdel()))
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, caperr, MSG_E_SUBGEN,
 		      sh_error_message (caperr, errbuf, sizeof(errbuf)), 
 		      _("sl_get_cap_qdel"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
     }
 
@@ -406,17 +446,28 @@
   if (0 != (caperr = sl_drop_cap_qdel()))
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, caperr, MSG_E_SUBGEN,
 		      sh_error_message (caperr, errbuf, sizeof(errbuf)), 
 		      _("sl_drop_cap_qdel"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
     }
 
   if (0 != chdir("/"))
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, errno,
 		       MSG_SUID_ERROR,
 		       sh_error_message(errno, errbuf, sizeof(errbuf)));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
     }
   return result;
 }
+
+/* This variable is not used anywhere. It only exists
+ * to assign &dirlist to it, which keeps gcc from
+ * putting it into a register, and avoids the 'clobbered
+ * by longjmp' warning. And no, 'volatile' proved insufficient.
+ */
+static void * sh_dummy_tmp = NULL;
 
 static void sh_q_delete(const char * fullpath)
@@ -426,4 +477,9 @@
   char * tmp;
 
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_tmp = (void*) &tmp;
+
   if (do_truncate (fullpath) == -1)
     {
@@ -435,4 +491,5 @@
 			 _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), 
 			 status);
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle (ShSuidchkSeverity,
 		       FIL__, __LINE__, 
@@ -440,4 +497,5 @@
 		       MSG_SUID_QREPORT, msg,
 		       tmp );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SH_FREE(tmp);
       SH_FREE(msg);
@@ -446,4 +504,5 @@
     {
       tmp    = sh_util_safe_name(fullpath);
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle (ShSuidchkSeverity,
 		       FIL__, __LINE__, 0,
@@ -451,8 +510,17 @@
 		       _("Quarantine method applied"),
 		       tmp );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SH_FREE(tmp);
     }
   return;
 }
+
+/* This variable is not used anywhere. It only exists
+ * to assign &dirlist to it, which keeps gcc from
+ * putting it into a register, and avoids the 'clobbered
+ * by longjmp' warning. And no, 'volatile' proved insufficient.
+ */
+static void * sh_dummy_mtmp = NULL;
+static void * sh_dummy_mmsg = NULL;
 
 static void sh_q_move(const char * fullpath, file_type * theFile, 
@@ -460,7 +528,7 @@
 		      const char * timestrm)
 {
-  int           status;
+  volatile int  status;
   int           readFile  = -1;
-  int           writeFile = -1;
+  volatile int  writeFile = -1;
   struct stat   fileInfo;
   ssize_t       count;
@@ -474,4 +542,10 @@
   FILE *        filePtr = NULL;
 
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_mtmp = (void*) &tmp;
+  sh_dummy_mmsg = (void*) &msg;
+
   (void) sl_strlcpy (dir, DEFAULT_QDIR, PATH_MAX+1);
 
@@ -487,4 +561,5 @@
 			 _("Problem quarantining file.  File NOT quarantined.  errno = %ld (stat)"), 
 			 status);
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle (ShSuidchkSeverity,
 		       FIL__, __LINE__, 
@@ -492,4 +567,5 @@
 		       MSG_SUID_QREPORT, msg,
 		       tmp );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SH_FREE(tmp);
       SH_FREE(msg);
@@ -505,4 +581,5 @@
 
 	  (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld(stat)"), status);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -510,4 +587,5 @@
 			   MSG_SUID_QREPORT,
 			   msg, tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	  SH_FREE(msg);
@@ -535,8 +613,10 @@
 
 	      (void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld (open)"), status);
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle (ShSuidchkSeverity,
 			       FIL__, __LINE__, status,
 			       MSG_SUID_QREPORT,
 			       msg, tmp );
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      SH_FREE(tmp);
 	      SH_FREE(msg);
@@ -556,4 +636,5 @@
 		      (void) sl_snprintf(msg, SH_BUFSIZE, 
 					 _("I/O error.  errno = %ld (write)"), status);
+		      SH_MUTEX_LOCK(mutex_thread_nolog);
 		      sh_error_handle (ShSuidchkSeverity,
 				       FIL__,
@@ -562,4 +643,5 @@
 				       MSG_SUID_QREPORT,
 				       msg, tmp );
+		      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		      SH_FREE(tmp);
 		      SH_FREE(msg);
@@ -581,8 +663,10 @@
 				 _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), 
 				 status);
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle (ShSuidchkSeverity,
 			       FIL__, __LINE__, status,
 			       MSG_SUID_QREPORT,
 			       msg, tmp );
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      SH_FREE(tmp);
 	      SH_FREE(msg);
@@ -619,4 +703,5 @@
 	      
 	      tmp    = sh_util_safe_name(fullpath);
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle (ShSuidchkSeverity,
 			       FIL__,__LINE__,
@@ -624,4 +709,5 @@
 			       _("Quarantine method applied"),
 			       tmp );
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      SH_FREE(tmp);
 	    }
@@ -633,8 +719,16 @@
 }
 
+/* This variable is not used anywhere. It only exists
+ * to assign &dirlist to it, which keeps gcc from
+ * putting it into a register, and avoids the 'clobbered
+ * by longjmp' warning. And no, 'volatile' proved insufficient.
+ */
+static void * sh_dummy_ctmp = NULL;
+static void * sh_dummy_cmsg = NULL;
+
 static void sh_q_changeperm(const char * fullpath)
 {
-  int             caperr;
-  int             status;
+  volatile int    caperr;
+  volatile int    status;
   char          * msg;
   char          * tmp;
@@ -642,6 +736,12 @@
   struct stat     fileInfo_F;
   int             cperm_status = 0;
-  int             file_d       = -1;
+  volatile int    file_d       = -1;
   char errbuf[SH_ERRBUF_SIZE];
+
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_ctmp = (void*) &tmp;
+  sh_dummy_cmsg = (void*) &msg;
 
   if (retry_lstat(FIL__, __LINE__, fullpath, &fileInfo) == -1)
@@ -652,4 +752,5 @@
 
       (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld"), status);
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle (ShSuidchkSeverity,
 		       FIL__, __LINE__, 
@@ -657,4 +758,5 @@
 		       MSG_SUID_QREPORT, msg,
 		       tmp );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SH_FREE(tmp);
       SH_FREE(msg);
@@ -666,8 +768,10 @@
       if (0 != (caperr = sl_get_cap_qdel()))
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle((-1), FIL__, __LINE__, 
 			  caperr, MSG_E_SUBGEN,
 			  sh_error_message (caperr, errbuf, sizeof(errbuf)), 
 			  _("sl_get_cap_qdel"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  cperm_status = -1;
 	}
@@ -685,4 +789,5 @@
 
 	  (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld"), status);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -690,4 +795,5 @@
 			   MSG_SUID_QREPORT, msg,
 			   tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	  SH_FREE(msg);
@@ -706,4 +812,5 @@
 	  (void) sl_snprintf(msg, SH_BUFSIZE, 
 			     _("I/O error.  errno = %ld"), status);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -711,4 +818,5 @@
 			   MSG_SUID_QREPORT, msg,
 			   tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	  SH_FREE(msg);
@@ -729,4 +837,5 @@
 	  (void) sl_snprintf(msg, SH_BUFSIZE, 
 			     _("Race detected.  errno = %ld"), status);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -734,4 +843,5 @@
 			   MSG_SUID_QREPORT, msg,
 			   tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	  SH_FREE(msg);
@@ -756,4 +866,5 @@
 			     _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), 
 			     status);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -761,4 +872,5 @@
 			   MSG_SUID_QREPORT,
 			   msg, tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	  SH_FREE(msg);
@@ -767,4 +879,5 @@
 	{
 	  tmp    = sh_util_safe_name(fullpath);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -773,4 +886,5 @@
 			   _("Quarantine method applied"),
 			   tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	}
@@ -779,8 +893,10 @@
   if (0 != (caperr = sl_drop_cap_qdel()))
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, 
 		      caperr, MSG_E_SUBGEN,
 		      sh_error_message (caperr, errbuf, sizeof(errbuf)), 
 		      _("sl_drop_cap_qdel"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
     }
   
@@ -799,4 +915,5 @@
 	  (void) sl_snprintf(msg, SH_BUFSIZE, 
 			     _("I/O error.  errno = %ld"), status);
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle (ShSuidchkSeverity,
 			   FIL__, __LINE__, 
@@ -804,4 +921,5 @@
 			   MSG_SUID_QREPORT, msg,
 			   tmp );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  SH_FREE(tmp);
 	  SH_FREE(msg);
@@ -836,12 +954,23 @@
   /*@+usedef@*/
   
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__, 
 		   0, MSG_SUID_POLICY,
 		   _("suid/sgid file not in database"),
 		   tmp, msg );
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
   SH_FREE(tmp);
   SH_FREE(msg);
   return;
 }
+
+/* This variable is not used anywhere. It only exists
+ * to assign &dirlist to it, which keeps gcc from
+ * putting it into a register, and avoids the 'clobbered
+ * by longjmp' warning. And no, 'volatile' proved insufficient.
+ */
+static void * sh_dummy_dirlist = NULL;
+static void * sh_dummy_itmp    = NULL;
+
 
 static
@@ -856,8 +985,8 @@
   char            timestrm[32];
   struct stat     buf;
-  int             status;
+  volatile int    status;
   int             fflags;
   char          * fs;
-  long            sl_status;
+  volatile long   sl_status;
   file_type     * theFile = NULL;
   char            fileHash[2*(KEY_LEN + 1)];
@@ -869,4 +998,10 @@
   SL_ENTER(_("sh_suidchk_check_internal"));
 
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_dirlist = (void*) &dirlist;
+  sh_dummy_itmp    = (void*) &tmp;
+
   if (iname == NULL)
     {
@@ -885,7 +1020,9 @@
       status = errno;
       tmp = sh_util_safe_name(iname);
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, status, 
 		       MSG_E_OPENDIR,
 		       sh_error_message (status, errbuf, sizeof(errbuf)), tmp);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       SH_FREE(tmp);
       SL_RETURN( (-1), _("sh_suidchk_check_internal"));
@@ -954,8 +1091,10 @@
       {
 	tmp = sh_util_safe_name(tmpcat);
+	SH_MUTEX_LOCK(mutex_thread_nolog);
 	sh_error_handle ((-1), FIL__, __LINE__, (int) sl_status, 
 			 MSG_E_SUBGPATH,
 			 _("path too long"),
 			 _("sh_suidchk_check_internal"), tmp );
+	SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	SH_FREE(tmp);
 	SH_FREE(tmpcat);
@@ -985,5 +1124,5 @@
     if (status != 0)
       {
-	int elevel = SH_ERR_ERR;
+	volatile int elevel = SH_ERR_ERR;
 	size_t tlen;
 
@@ -993,7 +1132,9 @@
 	if (tlen >= 6 && 0 == strcmp(&tmp[tlen-6], _("/.gvfs")))
 	  elevel = SH_ERR_NOTICE;
+	SH_MUTEX_LOCK(mutex_thread_nolog);
 	sh_error_handle (elevel, FIL__, __LINE__, status, MSG_ERR_LSTAT,
 			 sh_error_message(status, errbuf, sizeof(errbuf)),
 			 tmp );
+	SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	SH_FREE(tmp);
       }
@@ -1058,4 +1199,5 @@
 	    if (status != 0)
 	      {
+		SH_MUTEX_LOCK(mutex_thread_nolog);
 		sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__, 
 				 0, MSG_E_SUBGPATH,
@@ -1063,4 +1205,5 @@
 				 _("sh_suidchk_check_internal"),
 				 tmp);
+		SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      }
 	    else
@@ -1071,4 +1214,6 @@
 		      sh.flag.checkSum == SH_CHECK_CHECK))
 		  {
+		    int compret;
+
 		    /* Updating database. Report new files that
 		     * are not in database already. Then compare
@@ -1077,22 +1222,30 @@
 		    if (-1 == sh_hash_have_it (tmpcat))
 		      {
+			SH_MUTEX_LOCK(mutex_thread_nolog);
 			sh_error_handle ((-1), FIL__, __LINE__, 
 					 0, MSG_SUID_FOUND, tmp );
+			SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		      }
 		    else
 		      {
+			SH_MUTEX_LOCK(mutex_thread_nolog);
 			sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
 					 0, MSG_SUID_FOUND, tmp );
+			SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		      }
 		    
-		    if (0 == sh_hash_compdata (SH_LEVEL_READONLY, 
-					       theFile, fileHash,
-					       _("[SuidCheck]"), 
-					       ShSuidchkSeverity))
+		    SH_MUTEX_LOCK(mutex_thread_nolog);
+		    compret = sh_hash_compdata (SH_LEVEL_READONLY, 
+						theFile, fileHash,
+						_("[SuidCheck]"), 
+						ShSuidchkSeverity);
+		    SH_MUTEX_UNLOCK(mutex_thread_nolog);
+
+		    if (compret == 0)
 		      {
-			sh_hash_pushdata_memory (theFile, fileHash);
+			sh_hash_pushdata_memory (theFile, fileHash); /* no call to sh_error_handle */
 		      }
 		    
-		    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
+		    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK); /* no call to sh_error_handle */
 		    
 		  }
@@ -1103,7 +1256,9 @@
 		    /* Running init. Report on files detected.
 		     */
-		    sh_hash_pushdata (theFile, fileHash);
+		    sh_hash_pushdata (theFile, fileHash); /* no call to sh_error_handle */
+		    SH_MUTEX_LOCK(mutex_thread_nolog);
 		    sh_error_handle ((-1), FIL__, __LINE__, 
 				     0, MSG_SUID_FOUND, tmp );
+		    SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		  }
 		
@@ -1113,8 +1268,10 @@
 		     * detected, and quarantine them.
 		     */
+		    SH_MUTEX_LOCK(mutex_thread_nolog);
 		    sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
 				     0, MSG_SUID_FOUND, tmp );
+		    SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		    
-		    fflags = sh_hash_getflags(tmpcat);
+		    fflags = sh_hash_getflags(tmpcat); /* no call to sh_error_handle */
 		    
 		    if ( (-1 == fflags) || (!SH_FFLAG_SUIDCHK_SET(fflags)))
@@ -1144,7 +1301,9 @@
 				break;
 			      default:
+				SH_MUTEX_LOCK(mutex_thread_nolog);
 				sh_error_handle (ShSuidchkSeverity, FIL__,
 						 __LINE__, 0, MSG_SUID_QREPORT,
 						 _("Bad quarantine method"), tmp);
+				SH_MUTEX_UNLOCK(mutex_thread_nolog);
 				break;
 			      }
@@ -1154,10 +1313,12 @@
 			    /* 1.8.1 push file to in-memory database
 			     */
+			    SH_MUTEX_LOCK(mutex_thread_nolog);
 			    (void) sh_hash_compdata (SH_LEVEL_READONLY,
 						     theFile, fileHash,
 						     _("[SuidCheck]"),
 						     ShSuidchkSeverity);
+			    SH_MUTEX_UNLOCK(mutex_thread_nolog);
 			    
-			    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
+			    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK); /* no call to sh_error_handle */
 			    
 			  }
@@ -1167,10 +1328,11 @@
 			/* File exists. Check for modifications.
 			 */
+			SH_MUTEX_LOCK(mutex_thread_nolog);
 			(void) sh_hash_compdata (SH_LEVEL_READONLY, 
 						 theFile, fileHash,
 						 _("[SuidCheck]"),
 						 ShSuidchkSeverity);
-			
-			sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
+			SH_MUTEX_UNLOCK(mutex_thread_nolog);	
+			sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK); /* no call to sh_error_handle */
 			
 		      }
@@ -1192,7 +1354,9 @@
 	  {
 	    status = errno;
+	    SH_MUTEX_LOCK(mutex_thread_nolog);
 	    sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
 			     _("Failed to release time slice"),
 			     _("sh_suidchk_check_internal") );
+	    SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  }
       }
@@ -1216,7 +1380,21 @@
 int sh_suidchk_init (struct mod_type * arg)
 {
+#ifndef HAVE_PTHREAD
   (void) arg;
+#endif
+
   if (ShSuidchkActive == S_FALSE)
-    return (-1);
+    return SH_MOD_FAILED;
+
+#ifdef HAVE_PTHREAD
+  if (arg != NULL && arg->initval < 0 &&
+      (sh.flag.isdaemon == S_TRUE || sh.flag.loop == S_TRUE))
+    {
+      if (0 == sh_pthread_create(sh_threaded_module_run, (void *)arg))
+	return SH_MOD_THREAD;
+      else
+	return SH_MOD_FAILED;
+    }
+#endif
 
   return (0);
@@ -1270,11 +1448,16 @@
 int sh_suidchk_check ()
 {
-  int status;
+  volatile int status;
 
   SL_ENTER(_("sh_suidchk_check"));
 
+  if (ShSuidchkActive == S_FALSE)
+    SL_RETURN(-1, _("sh_suidchk_check"));
+
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   sh_error_handle (SH_ERR_NOTICE, FIL__, __LINE__, EINVAL, MSG_E_SUBGEN,
 		   _("Checking for SUID programs"),
 		   _("suidchk_check") );
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 
   FileLimNow        = time(NULL);
@@ -1289,7 +1472,9 @@
 #endif
 
+  SH_MUTEX_LOCK(mutex_thread_nolog);
   sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_SUID_SUMMARY,
 		   FileLimTotal,
 		   (long) (time(NULL) - FileLimStart) );
+  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 
   SL_RETURN(status, _("sh_suidchk_check"));
@@ -1346,5 +1531,5 @@
 int sh_suidchk_set_timer (const char * c)
 {
-  long val;
+  volatile long val;
 
   SL_ENTER(_("sh_suidchk_set_timer"));
@@ -1352,7 +1537,10 @@
   val = strtol (c, (char **)NULL, 10);
   if (val <= 0)
-    sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
-                      _("suidchk timer"), c);
-
+    {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
+      sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
+		       _("suidchk timer"), c);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
+    }
   val = (val <= 0 ? 7200 : val);
 
@@ -1379,6 +1567,8 @@
 int sh_suidchk_reconf ()
 {
+  SH_MUTEX_LOCK(mutex_suid_check);
   sh_suidchk_free_schedule();
   set_defaults();
+  SH_MUTEX_UNLOCK(mutex_suid_check);
   return 0;
 }
@@ -1424,5 +1614,5 @@
 int sh_suidchk_set_fps (const char * c)
 {
-  long val;
+  volatile long val;
 
   SL_ENTER(_("sh_suidchk_set_fps"));
@@ -1430,7 +1620,10 @@
   val = strtol (c, (char **)NULL, 10);
   if (val < 0)
-    sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
-                      _("suidchk fps"), c);
-
+    {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
+      sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
+		       _("suidchk fps"), c);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
+    }
   val = (val < 0 ? 0 : val);
 
@@ -1486,6 +1679,6 @@
 int sh_suidchk_set_qmethod (const char * c)
 {
-  long val;
-  int  ret = 0;
+  volatile long val;
+  volatile int  ret = 0;
   struct stat buf;
 
@@ -1495,6 +1688,8 @@
   if (val < 0)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
 		       _("suidchk qmethod"), c);
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       ret = -1;
     }
@@ -1514,7 +1709,9 @@
 	      if (mkdir (DEFAULT_QDIR, 0750) == -1)
 		{
+		  SH_MUTEX_LOCK(mutex_thread_nolog);
 		  sh_error_handle ((-1), FIL__, __LINE__, EINVAL,
 				   MSG_SUID_ERROR,
 				   _("Unable to create quarantine directory"));
+		  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 		}
 	    }
@@ -1522,6 +1719,8 @@
           break;
         default:
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
 			   _("suidchk qmethod"), c);
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
           ShSuidchkQMethod = -1;
 	  ret = -1;
@@ -1972,4 +2171,12 @@
 }
 
+/* This variable is not used anywhere. It only exists
+ * to assign &dirlist to it, which keeps gcc from
+ * putting it into a register, and avoids the 'clobbered
+ * by longjmp' warning. And no, 'volatile' proved insufficient.
+ */
+static void * sh_dummy_type = NULL;
+
+
 /* Return a newly allocated string naming the type of filesystem that the
    file PATH, described by STATP, is on.
@@ -1999,9 +2206,16 @@
   if (mfp == NULL)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
 		       _("setmntent() failed"),
 		       _("filesystem_type_uncached") );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
       return NULL;
     }
+
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_type = (void*) &type;
 
   /* Find the entry with the same device number as STATP, and return
@@ -2041,5 +2255,5 @@
 	    {
 	      char errmsg[256];
-	      int  elevel = SH_ERR_ERR;
+	      volatile int  elevel = SH_ERR_ERR;
 	      size_t tlen = strlen(mnt->mnt_dir);
 	      if (tlen >= 6 && 0 == strcmp(&((mnt->mnt_dir)[tlen-6]), _("/.gvfs")))
@@ -2047,7 +2261,9 @@
 	      sl_snprintf(errmsg, sizeof(errmsg), _("stat(%s) failed"),
 			  mnt->mnt_dir);
+	      SH_MUTEX_LOCK(mutex_thread_nolog);
 	      sh_error_handle (elevel, FIL__, __LINE__, 0, MSG_E_SUBGEN,
 			       errmsg,
 			       _("filesystem_type_uncached") );
+	      SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	      return NULL;
 	    }
@@ -2072,7 +2288,9 @@
   if (endmntent (mfp) == 0)
     {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
 		       _("endmntent() failed"),
 		       _("filesystem_type_uncached") );
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
     }
 #endif
@@ -2085,4 +2303,9 @@
     return NULL;
 
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_type = (void*) &type;
+
   while (type == NULL
 	 && getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 0) > 0)
@@ -2100,4 +2323,9 @@
     return NULL;
 
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_type = (void*) &type;
+
   if (statfs (relpath, &fss, sizeof (struct statfs), 0) == -1)
     {
@@ -2105,7 +2333,9 @@
       if (errno != ENOENT)
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
 			   _("statfs() failed"),
 			   _("filesystem_type_uncached") );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  return NULL;
 	}
@@ -2120,4 +2350,9 @@
   if (path == NULL || relpath == NULL)
     return NULL;
+
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_type = (void*) &type;
 
   if (statvfs (relpath, &fss) == -1)
@@ -2126,7 +2361,9 @@
       if (errno != ENOENT)
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
 			   _("statvfs() failed"),
 			   _("filesystem_type_uncached") );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  return NULL;
 	}
@@ -2155,4 +2392,9 @@
     return NULL;
 
+  /* Take the address to keep gcc from putting it into a register. 
+   * Avoids the 'clobbered by longjmp' warning. 
+   */
+  sh_dummy_type = (void*) &type;
+
   if (S_ISLNK (statp->st_mode))
     p = sh_dirname (relpath);
@@ -2166,7 +2408,9 @@
       if (errno != ENOENT)
 	{
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle ((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
 			   _("statfs() failed"),
 			   _("filesystem_type_uncached") );
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	  return NULL;
 	}
Index: trunk/src/sh_unix.c
===================================================================
--- trunk/src/sh_unix.c	(revision 252)
+++ trunk/src/sh_unix.c	(revision 253)
@@ -4598,5 +4598,5 @@
   int         status = 0;
   int         pagesize;
-  sh_page_l * page_list = sh_page_locked;
+  sh_page_l * page_list;
   unsigned long addr;
 #ifdef TEST_MLOCK
@@ -4609,4 +4609,6 @@
    */
   SH_MUTEX_LOCK_UNSAFE(mutex_mlock);
+
+  page_list = sh_page_locked;
 
   if (0 != page_locking)
@@ -4703,8 +4705,8 @@
 {
   int         num_pages;
-  int         unlocked = 0;
-  int         status   = 0;
+  int         unlocked;
+  int         status;
   int         pagesize;
-  sh_page_l * page_list = sh_page_locked;
+  sh_page_l * page_list;
   sh_page_l * page_last;
   unsigned long addr;
@@ -4723,4 +4725,8 @@
    */
   SH_MUTEX_LOCK_UNSAFE(mutex_mlock);
+
+  unlocked  = 0;
+  status    = 0;
+  page_list = sh_page_locked;
 
   if (0 != page_locking)
@@ -4848,22 +4854,43 @@
 {
   int i = 0;
-  char str[128];
-  sh_page_l * page_list = sh_page_locked;
+  char str[32][64];
+  sh_page_l * page_list;
 
   SL_ENTER(_("sh_unix_count_mlock"));
+
+  /* There's no cancellation point here, except if tracing is on
+   */
+  SH_MUTEX_LOCK_UNSAFE(mutex_mlock);
+
+  page_list = sh_page_locked;
+
   while (page_list != NULL)
     {
 #ifdef WITH_TPT
-      sl_snprintf(str, sizeof(str), _("file: %s line: %d page: %d"), 
-		  page_list->file, page_list->line, i+1);
-      sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, i, MSG_E_SUBGEN,
-		  str, _("sh_unix_count_mlock"));
+      if (i < 32)
+	sl_snprintf(str[i], 64, _("file: %s line: %d page: %d"), 
+		    page_list->file, page_list->line, i+1);
 #endif
       page_list = page_list->next;
       ++i;
     }
-  sl_snprintf(str, sizeof(str), _("%d pages locked"), i);
+
+  SH_MUTEX_UNLOCK_UNSAFE(mutex_mlock);
+
+#ifdef WITH_TPT
+  {
+    int j = 0;
+    while (j < i && j < 32)
+      {
+	sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, j, MSG_E_SUBGEN,
+			str[j], _("sh_unix_count_mlock"));
+	++j;
+      }
+  }
+#endif
+
+  sl_snprintf(str[0], 64, _("%d pages locked"), i);
   sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, i, MSG_E_SUBGEN,
-		  str, _("sh_unix_count_mlock"));
+		  str[0], _("sh_unix_count_mlock"));
   SL_RETURN((i), _("sh_unix_count_mlock"));
 }
