Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 130)
+++ /trunk/configure.ac	(revision 131)
@@ -273,5 +273,7 @@
 	initgroups getpagesize \
 	ttyname fchmod \
-	getsid getpriority getpgid statvfs
+	getsid getpriority getpgid statvfs \
+	fpathconf dirfd \
+	getgrgid_r getpwnam_r getpwuid_r gmtime_r localtime_r rand_r readdir_r strtok_r
 )
 AC_CHECK_FUNC(statfs, AC_DEFINE(HAVE_STATFS) statfs="yes",  statfs="no")
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 130)
+++ /trunk/docs/Changelog	(revision 131)
@@ -1,2 +1,8 @@
+2.4.0:
+	* eliminate alarm() for I/O timeout (replaced by select)
+	* use getgrgid_r, getpwnam_r, getpwuid_r, gmtime_r, localtime_r, 
+	  rand_r, strtok_r if available
+	* protect readdir() with mutex (readdir_r considered harmful)
+
 2.3.8:
 	* new option PortCheckIgnore = interface:portlist
Index: /trunk/docs/TODO
===================================================================
--- /trunk/docs/TODO	(revision 130)
+++ /trunk/docs/TODO	(revision 131)
@@ -1,1 +1,12 @@
 
+sh_unix_time: not thread_safe (static buffer)
+sh_error_message: not thread_safe (static buffer)
+
+check thread_safe sh_entropy
+
+lock NEED_LOCK
+
+globber
+
+sh_alloc/sh_free
+
Index: /trunk/include/samhain.h
===================================================================
--- /trunk/include/samhain.h	(revision 130)
+++ /trunk/include/samhain.h	(revision 131)
@@ -42,4 +42,7 @@
 #define SH_MAXBUF      4096
 #define SH_PATHBUF      256
+
+#define SH_GRBUF_SIZE  4096
+#define SH_PWBUF_SIZE  4096
 
 /* Sizes for arrays (user, group, timestamp).
Index: /trunk/include/sh_files.h
===================================================================
--- /trunk/include/sh_files.h	(revision 130)
+++ /trunk/include/sh_files.h	(revision 131)
@@ -21,4 +21,17 @@
 #define SH_FILES_H
 
+struct sh_dirent {
+  char             * sh_d_name;
+  struct sh_dirent * next;
+};
+
+/* free a directory listing
+ */
+void kill_sh_dirlist (struct sh_dirent * dirlist);
+
+/* add an entry to a directory listing
+ */
+struct sh_dirent * addto_sh_dirlist (struct dirent * thisEntry, 
+				     struct sh_dirent * dirlist);
 /* register exceptions to hardlink check
  */
Index: /trunk/include/sh_static.h
===================================================================
--- /trunk/include/sh_static.h	(revision 130)
+++ /trunk/include/sh_static.h	(revision 131)
@@ -15,7 +15,17 @@
 void  sh_setpwent(void);
 struct group * sh_getgrnam(const char *name);
+
 struct passwd * sh_getpwnam(const char *name);
+int getpwnam_r(const char *name, struct passwd *pwbuf,
+               char *buf, size_t buflen, struct passwd **pwbufp);
+
 struct group * sh_getgrgid(gid_t gid);
+int getgrgid_r(gid_t gid, struct group *gbuf,
+	       char *buf, size_t buflen, struct group **gbufp);
+
 struct passwd * sh_getpwuid(uid_t uid);
+int getpwuid_r(uid_t uid, struct passwd *pwbuf,
+               char *buf, size_t buflen, struct passwd **pwbufp);
+
 #endif
 
@@ -29,7 +39,10 @@
 #define sh_initgroups initgroups
 #define sh_getgrgid   getgrgid
+#define sh_getgrgid_r getgrgid_r
+#define sh_getpwnam   getpwnam
+#define sh_getpwnam_r getpwnam_r
+#define sh_getpwuid   getpwuid
+#define sh_getpwuid_r getpwuid_r
 #define sh_getpwent   getpwent
-#define sh_getpwnam   getpwnam
-#define sh_getpwuid   getpwuid
 #define sh_endpwent   endpwent
 #define sh_setpwent   setpwent
Index: /trunk/include/slib.h
===================================================================
--- /trunk/include/slib.h	(revision 130)
+++ /trunk/include/slib.h	(revision 131)
@@ -353,6 +353,9 @@
   int sl_read_timeout_prep (SL_TICKET ticket);
 
+  int sl_read_timeout_fd (int fd, void * buf, 
+			  size_t count, int timeout, int is_nonblocking);
+
   int sl_read_timeout (SL_TICKET ticket, void * buf, 
-		       size_t count, int timeout);
+		       size_t count, int timeout, int is_nonblocking);
 
   int sl_read_fast (SL_TICKET ticket, void * buf_in, size_t count);
Index: /trunk/src/samhain.c
===================================================================
--- /trunk/src/samhain.c	(revision 130)
+++ /trunk/src/samhain.c	(revision 131)
@@ -63,4 +63,5 @@
 
 #include "samhain.h"
+#include "sh_pthread.h"
 #include "sh_files.h"
 #include "sh_utils.h"
@@ -450,4 +451,15 @@
   if (0 == strcmp (DEFAULT_MAILADDRESS, _("NULL")))
     {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      char * saveptr;
+      (void) sl_strncpy(q, DEFAULT_MAILADDRESS, SH_PATHBUF);
+      p = strtok_r (q, ", \t", &saveptr);
+      if (p)
+	{
+	  (void) sh_mail_setaddress_int (p);
+	  while (NULL != (p = strtok_r (NULL, ", \t", &saveptr)))
+	    (void) sh_mail_setaddress_int (p);
+	}
+#else
       (void) sl_strncpy(q, DEFAULT_MAILADDRESS, SH_PATHBUF);
       p = strtok (q, ", \t");
@@ -458,4 +470,5 @@
 	    (void) sh_mail_setaddress_int (p);
 	}
+#endif
     }
 #endif
@@ -747,4 +760,7 @@
       return NULL;
     }
+
+  SH_MUTEX_LOCK(readdir_lock);
+
   while (NULL != (d = readdir(dp)) && i < 65535)
     {
@@ -767,4 +783,7 @@
 	}
     }
+
+  SH_MUTEX_UNLOCK(readdir_lock);
+
   closedir(dp);
   return pidlist;
@@ -1294,4 +1313,7 @@
       if ( 0 == strcmp(argv[1], NOCL_CODE) )
 	{
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+	  char * saveptr;
+#endif
 	  my_argv[0] = argv[0]; ++my_argc;  
 	  command_line[0] = '\0';
@@ -1299,6 +1321,11 @@
 	  command_line[sizeof(command_line)-1] = '\0';
 	  do {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
 	    my_argv[my_argc] = 
-	      strtok( (my_argc == 1) ? command_line : NULL, " \n"); 
+	      strtok_r( (my_argc == 1) ? command_line : NULL, " \n", &saveptr);
+#else
+	    my_argv[my_argc] = 
+	      strtok( (my_argc == 1) ? command_line : NULL, " \n");
+#endif 
 	    if (my_argv[my_argc] != NULL) {
 	      ++my_argc;
Index: /trunk/src/sh_entropy.c
===================================================================
--- /trunk/src/sh_entropy.c	(revision 130)
+++ /trunk/src/sh_entropy.c	(revision 131)
@@ -276,32 +276,8 @@
 #if defined (HAVE_URANDOM)
 
-#include <setjmp.h>
-
-static jmp_buf          entropy_timeout;
-
-static void sh_entropy_alarmhandle (int mysignal)
-{
-  (void) mysignal; /* avoid compiler warning */
-  longjmp (entropy_timeout, 1);
-}
-
-
 int read_mbytes(int timeout_val, char * path, char * nbuf, int nbytes)
 {
-  int count, m_count;
+  int m_count;
   int fd2;
-
-  struct  sigaction  new_act;
-  sigset_t           unblock;
-
-  struct sigaction      old_act;
-  volatile unsigned int old_alarm = 0;
-
-  new_act.sa_handler = sh_entropy_alarmhandle;
-  sigemptyset( &new_act.sa_mask );       /* set an empty mask       */
-  new_act.sa_flags = 0;                  /* init sa_flags           */
-
-  sigemptyset(&unblock);
-  sigaddset  (&unblock, SIGALRM);
 
   SL_ENTER(_("read_mbytes"));
@@ -314,55 +290,8 @@
       if (0 == sh_unix_device_readable(fd2)) 
 	{
-
-	  /* alarm was triggered
-	   */
-	  if (setjmp(entropy_timeout) != 0)
-	    {
-	      alarm(0);
-	      sigaction (SIGALRM, &old_act, NULL);
-	      alarm(old_alarm);
-	      sigprocmask(SIG_UNBLOCK, &unblock, NULL);
-	      TPT((0,FIL__,__LINE__, _("msg=<read_mbytes: timeout>\n"))); 
-	      close (fd2);
-	      SL_RETURN(0, _("read_mbytes"));
-	    }
-
-	  /* timeout after 30 seconds
-	   */
-	  old_alarm = alarm(0);
-	  sigaction (SIGALRM, &new_act, &old_act);
-	  alarm(timeout_val);
-
-	  m_count = 0;
-
-	  while (m_count < nbytes) 
-	    {
-	      errno = 0; /* paranoia */
-	      count = read (fd2, &nbuf[m_count], nbytes-m_count);
-
-	      switch (count)
-		{
-		case -1:
-#ifdef EWOULDBLOCK
-                  if (errno == EINTR || errno == EAGAIN ||
-                      errno == EWOULDBLOCK)
-#else
-                  if (errno == EINTR || errno == EAGAIN)
-#endif
-                    continue;
-
-                  /* if errno == -1 && no continue: fallthrough to this */
-                case 0:
-                  break;
-                default:
-                  m_count += count;
-                }
-	    }
-	  close (fd2);
-
-	  alarm(0);
-	  sigaction (SIGALRM, &old_act, NULL);
-	  alarm(old_alarm);
-	  sigprocmask(SIG_UNBLOCK, &unblock, NULL);
+	  m_count = sl_read_timeout_fd(fd2, &nbuf, nbytes, 
+				       timeout_val, SL_FALSE);
+	  if (m_count < 0)
+	    m_count = 0;
 	}
       else
@@ -371,4 +300,6 @@
   else
     m_count = 0;
+
+  close(fd2);
 
   TPT((0, FIL__, __LINE__, _("msg=<read_mbytes: OK>\n"))); 
@@ -568,5 +499,4 @@
   int pipedes[2];
   FILE *outf = NULL;
-  struct passwd * tempres;
   char * arg[4];
   char * envp[2];
@@ -645,20 +575,29 @@
        */
       i = 0; 
-      if (0 == geteuid()) {  
-	tempres = sh_getpwnam(DEFAULT_IDENT);
-	if (NULL != tempres) {
-	  i = aud_setgid(FIL__, __LINE__, tempres->pw_gid); 
-	  if (i == 0)
-	    i = sh_unix_initgroups(DEFAULT_IDENT ,tempres->pw_gid);
-	  if (i == 0) 
-	    i = aud_setuid(FIL__, __LINE__, tempres->pw_uid);
-	  /* make sure we cannot get root again
-	   */
-	  if ((tempres->pw_uid != 0) && (aud_setuid(FIL__, __LINE__, 0) >= 0))
+      if (0 == geteuid()) 
+	{
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+	  struct passwd    pwd;
+	  char             buffer[SH_PWBUF_SIZE];
+	  struct passwd *  tempres;
+	  sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, sizeof(buffer), &tempres);
+#else
+	  struct passwd * tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
+  
+	  if (NULL != tempres) {
+	    i = aud_setgid(FIL__, __LINE__, tempres->pw_gid); 
+	    if (i == 0)
+	      i = sh_unix_initgroups(DEFAULT_IDENT ,tempres->pw_gid);
+	    if (i == 0) 
+	      i = aud_setuid(FIL__, __LINE__, tempres->pw_uid);
+	    /* make sure we cannot get root again
+	     */
+	    if ((tempres->pw_uid != 0) && (aud_setuid(FIL__, __LINE__, 0) >= 0))
+	      i = -1;
+	  } else {
 	    i = -1;
-	} else {
-	  i = -1;
+	  }
 	}
-      }
       
       /* some problem ...
Index: /trunk/src/sh_error.c
===================================================================
--- /trunk/src/sh_error.c	(revision 130)
+++ /trunk/src/sh_error.c	(revision 131)
@@ -257,11 +257,20 @@
 
   do {
-    if (num == 0)
-      {
-	p = strtok (c, " ,\t");
-	++num;
-      }
-    else
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+    char * saveptr;
+    if (num == 0) {
+      p = strtok_r (c, " ,\t", &saveptr);
+      ++num;
+    } else {
+      p = strtok_r (NULL, " ,\t", &saveptr);
+    }
+#else
+    if (num == 0) {
+      p = strtok (c, " ,\t");
+      ++num;
+    } else {
       p = strtok (NULL, " ,\t");
+    }
+#endif
 
     if (p == NULL)
Index: /trunk/src/sh_extern.c
===================================================================
--- /trunk/src/sh_extern.c	(revision 130)
+++ /trunk/src/sh_extern.c	(revision 131)
@@ -914,5 +914,9 @@
 int sh_ext_uid (const char * user, /*@out@*/uid_t * uid, /*@out@*/gid_t * gid)
 {
-  struct passwd * tempres;
+  struct passwd *  tempres;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+  struct passwd    pwd;
+  char             buffer[SH_PWBUF_SIZE];
+#endif
 
   SL_ENTER(_("sh_ext_uid"));
@@ -924,5 +928,10 @@
       SL_RETURN (-1, _("sh_ext_uid"));
     }
+
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+  sh_getpwnam_r(user, &pwd, buffer, sizeof(buffer), &tempres);
+#else
   tempres = sh_getpwnam(user);
+#endif
 
   if (NULL != tempres) 
@@ -959,8 +968,17 @@
   do
     {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      char * saveptr;
+      if (i == 0)
+	p = strtok_r (new, ", \t", &saveptr);
+      else
+	p = strtok_r (NULL, ", \t", &saveptr);
+#else
       if (i == 0)
 	p = strtok (new, ", \t");
       else
 	p = strtok (NULL, ", \t");
+#endif
+
       if (p == NULL)
 	break;
Index: /trunk/src/sh_files.c
===================================================================
--- /trunk/src/sh_files.c	(revision 130)
+++ /trunk/src/sh_files.c	(revision 131)
@@ -60,4 +60,5 @@
 #if (defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)) 
 
+#include "sh_pthread.h"
 #include "sh_error.h"
 #include "sh_utils.h"
@@ -191,5 +192,4 @@
   SL_RETURN((0), _("sh_files_setrecursion"));
 }
-
 
 unsigned long sh_files_chk ()
@@ -1340,11 +1340,12 @@
 }
 
+/**
 struct sh_dirent {
-  /* char               sh_d_name[NAME_MAX + 2]; */
   char             * sh_d_name;
   struct sh_dirent * next;
 };
-
-static void kill_sh_dirlist (struct sh_dirent * dirlist)
+**/
+
+void kill_sh_dirlist (struct sh_dirent * dirlist)
 {
   struct sh_dirent * this;
@@ -1362,6 +1363,6 @@
 /* -- add an entry to a directory listing
  */
-static struct sh_dirent * addto_sh_dirlist (struct dirent * thisEntry, 
-					    struct sh_dirent * dirlist)
+struct sh_dirent * addto_sh_dirlist (struct dirent * thisEntry, 
+				     struct sh_dirent * dirlist)
 {
   struct sh_dirent * this;
@@ -1485,5 +1486,5 @@
   dir_type        theDir;
   ShFileType      checkit;
-
+  static unsigned int state = 1;
 
   file_type       theFile;
@@ -1633,4 +1634,6 @@
   /* ---- read ----
    */
+  SH_MUTEX_LOCK(readdir_lock);
+
   do {
       thisEntry = readdir (thisDir);
@@ -1652,4 +1655,6 @@
   } while (thisEntry != NULL);
 
+  SH_MUTEX_UNLOCK(readdir_lock);
+
   closedir (thisDir);
 
@@ -1672,6 +1677,10 @@
 
     BREAKEXIT(sh_derr);
-    if (0 == (rand() % 5))
-      (void) sh_derr();
+
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_RAND_R)
+    if (0 == (rand_r(&state) % 5)) (void) sh_derr();
+#else
+    if (0 == state * (rand() % 5)) (void) sh_derr();
+#endif
     
     /* ---- Check the file. ---- 
@@ -1929,10 +1938,15 @@
   char          * fileName;
   struct utimbuf  utime_buf;
+  static unsigned int state = 1;
 
   SL_ENTER(_("sh_files_filecheck"));
 
   BREAKEXIT(sh_derr);
-  if (0 == (rand() % 2))
-    (void) sh_derr();
+
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_RAND_R)
+  if (0 == (rand_r(&state) % 2)) (void) sh_derr();
+#else
+  if (0 == state * (rand() % 2)) (void) sh_derr();
+#endif
 
   if (dirName && infileName && (dirName[0] == '/') && (dirName[1] == '\0')
Index: /trunk/src/sh_gpg.c
===================================================================
--- /trunk/src/sh_gpg.c	(revision 130)
+++ /trunk/src/sh_gpg.c	(revision 131)
@@ -292,5 +292,12 @@
       struct stat lbuf;
       int         status_stat = 0;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      struct passwd    pwd;
+      char             buffer[SH_PWBUF_SIZE];
+      struct passwd *  tempres;
+      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, sizeof(buffer), &tempres);
+#else
       struct passwd * tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
 
       if (!tempres)
@@ -844,4 +851,7 @@
   while (NULL != fgets(line, sizeof(line), source.pipe))
     {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      char * saveptr = NULL;
+#endif
       if (line[strlen(line)-1] == '\n')
 	line[strlen(line)-1] = ' ';
@@ -852,15 +862,31 @@
       if (sl_strlen(line) < 18) 
 	continue;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      ptr = strtok_r (line, " ", &saveptr);
+#else
       ptr = strtok (line, " ");
+#endif
       while (ptr)
 	{
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+	  ptr = strtok_r (NULL, " ", &saveptr);
+#else
 	  ptr = strtok (NULL, " ");
+#endif
 	  if (ptr && 0 == sl_strncmp (ptr, _("fingerprint"), 11))
 	    {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+	      ptr = strtok_r (NULL, " ", &saveptr); /* to '=' */
+#else
 	      ptr = strtok (NULL, " "); /* to '=' */
+#endif
 	      sign_fp[0] = '\0';
 	      while (ptr)
 		{
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+		  ptr = strtok_r (NULL, " ", &saveptr); /* part of fingerprint */
+#else
 		  ptr = strtok (NULL, " "); /* part of fingerprint */
+#endif
 		  sl_strlcat (sign_fp, ptr, SH_MINIBUF+1);
 		}
@@ -923,5 +949,10 @@
 #if defined(SH_WITH_SERVER)
   struct passwd * tempres;
-#endif
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+  struct passwd    pwd;
+  char             buffer[SH_PWBUF_SIZE];
+#endif
+#endif
+
 #ifdef USE_FINGERPRINT
 #include "sh_gpg_fp.h"
@@ -952,5 +983,9 @@
       TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD1 = %d>\n"), fd1));
 #if defined(SH_WITH_SERVER)
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, sizeof(buffer), &tempres);
+#else
       tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
 
       if ((tempres != NULL) && (0 == sl_ret_euid()))
@@ -969,5 +1004,9 @@
       TPT(((0), FIL__, __LINE__, _("msg=<GPG_CHECK: FD2 = %d>\n"), fd2));
 #if defined(SH_WITH_SERVER)
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, sizeof(buffer), &tempres);
+#else
       tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
 
       if ((tempres != NULL) && (0 == sl_ret_euid()))
@@ -1077,5 +1116,12 @@
 
 #if defined(SH_WITH_SERVER)
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      struct passwd    e_pwd;
+      char             e_buffer[SH_PWBUF_SIZE];
+      struct passwd *  e_tempres;
+      sh_getpwnam_r(DEFAULT_IDENT, &e_pwd, e_buffer, sizeof(e_buffer), &e_tempres);
+#else
       struct passwd * e_tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
 
       if ((e_tempres != NULL) && (0 == sl_ret_euid()))   
Index: /trunk/src/sh_hash.c
===================================================================
--- /trunk/src/sh_hash.c	(revision 130)
+++ /trunk/src/sh_hash.c	(revision 131)
@@ -3665,8 +3665,23 @@
   time_t then = (time_t) p->theFile.mtime;
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GMTIME_R)
+  struct tm   * time_ptr;
+  struct tm     time_tm;
+
+  time_ptr = gmtime_r(&then, &time_tm);
+  strftime(thetime, 127, _("%b %d  %Y"), time_ptr);
+  time_ptr = gmtime_r(&now,  &time_tm);
+  strftime(nowtime, 127, _("%b %d  %Y"), time_ptr);
+  if (0 == strncmp(&nowtime[7], &thetime[7], 4))
+    {
+      time_ptr = gmtime_r(&then, &time_tm);
+      strftime(thetime, 127, _("%b %d %H:%M"), time_ptr);
+    }
+#else
   strftime(thetime, 127, _("%b %d  %Y"), gmtime(&then));
   strftime(nowtime, 127, _("%b %d  %Y"), gmtime(&now));
   if (0 == strncmp(&nowtime[7], &thetime[7], 4))
     strftime(thetime, 127, _("%b %d %H:%M"), gmtime(&then));
+#endif
 
   tmp = sh_util_safe_name(p->fullpath);
Index: /trunk/src/sh_html.c
===================================================================
--- /trunk/src/sh_html.c	(revision 130)
+++ /trunk/src/sh_html.c	(revision 131)
@@ -34,4 +34,5 @@
 #endif
 #endif
+#include <unistd.h>
 
 
@@ -90,4 +91,7 @@
   time_t    now;
   struct tm   * time_ptr;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  struct tm    time_tm;
+#endif
 
   char    * formatted;
@@ -148,9 +152,17 @@
       if (!SL_ISERROR(status))
 	{
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+	  time_ptr   = localtime_r (&(server_status.start), &time_tm);
+#else
 	  time_ptr   = localtime (&(server_status.start));
+#endif
 	  if (time_ptr != NULL) 
 	    status = strftime (ts1, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
 	  now = time(NULL);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+	  time_ptr   = localtime_r (&now, &time_tm);
+#else
 	  time_ptr   = localtime (&now);
+#endif
 	  if (time_ptr != NULL) 
 	    status = strftime (ts2, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
@@ -174,5 +186,9 @@
 	  if (server_status.last > (time_t) 0)
 	    {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+	      time_ptr   = localtime_r (&(server_status.last), &time_tm);
+#else
 	      time_ptr   = localtime (&(server_status.last));
+#endif
 	      if (time_ptr != NULL) 
 		status = strftime (ts1, 80, _("%d-%m-%Y %H:%M:%S"), time_ptr);
Index: /trunk/src/sh_kern.c
===================================================================
--- /trunk/src/sh_kern.c	(revision 130)
+++ /trunk/src/sh_kern.c	(revision 131)
@@ -58,4 +58,5 @@
 
 #include "samhain.h"
+#include "sh_pthread.h"
 #include "sh_utils.h"
 #include "sh_error.h"
@@ -966,4 +967,6 @@
   if (df)
     {
+      SH_MUTEX_LOCK(readdir_lock);
+
       while (NULL != (entry = readdir(df)))
 	{
@@ -977,4 +980,7 @@
 	  SH_FREE(pcipath);
 	}
+
+      SH_MUTEX_UNLOCK(readdir_lock);
+
       closedir(df);
     }
Index: /trunk/src/sh_mail.c
===================================================================
--- /trunk/src/sh_mail.c	(revision 130)
+++ /trunk/src/sh_mail.c	(revision 131)
@@ -654,6 +654,6 @@
 /* The mailer.
  */
-static int sh_mail_end_conn (FILE * connfile);
-static FILE * sh_mail_start_conn (int aFlag);
+static int sh_mail_end_conn (FILE * connfile, int fd);
+static FILE * sh_mail_start_conn (int aFlag, int * fd);
 
 static
@@ -797,4 +797,6 @@
 
     static  int ma_block = 0;
+
+    int       ma_socket = -1;
 
     SH_FIFO * fifo_temp = NULL;
@@ -1065,5 +1067,5 @@
 	while (address_list[i] != NULL && i < address_num)
 	  {
-	    connfile = sh_mail_start_conn (i);
+	    connfile = sh_mail_start_conn (i, &ma_socket);
 	    
 	    if (NULL != connfile)
@@ -1073,5 +1075,5 @@
 		wrlen -= sl_strlen(mailMsg);
 		if (wrlen == 0) 
-		  status = sh_mail_end_conn (connfile);
+		  status = sh_mail_end_conn (connfile, ma_socket);
 		else
 		  status = -1;
@@ -1101,5 +1103,5 @@
     else
       {
-	connfile = sh_mail_start_conn ( -9 );
+	connfile = sh_mail_start_conn ( -9 , &ma_socket);
 	
 	if (NULL != connfile)
@@ -1108,5 +1110,5 @@
 	    wrlen -= sl_strlen(mailMsg);
 	    if (wrlen == 0)
-	      status = sh_mail_end_conn (connfile);
+	      status = sh_mail_end_conn (connfile, ma_socket);
 	    else
 	      status = -1;
@@ -1287,5 +1289,5 @@
 static time_t time_wait = 300;
 
-static FILE * sh_mail_start_conn (int aFlag)
+static FILE * sh_mail_start_conn (int aFlag, int * ma_socket)
 {
   char       * address;
@@ -1302,4 +1304,7 @@
   FILE       * connFile = NULL;
   struct tm  * my_tm;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  struct tm    time_tm;
+#endif
   time_t       my_time;
   char         my_tbuf[128];
@@ -1312,5 +1317,6 @@
   SL_ENTER(_("sh_mail_start_conn"));
 
-  time_wait = 300;
+  *ma_socket = -1;
+  time_wait  = 300;
 
   if (aFlag >= 0)
@@ -1416,5 +1422,5 @@
   /* say HELO to the other socket
    */
-  if (0 == sh_mail_wait (220, connFile)) 
+  if (0 == sh_mail_wait (220, fd)) 
     {
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
@@ -1446,5 +1452,5 @@
   (void) fflush(connFile);
 
-  if (0 == sh_mail_wait(250, connFile)) 
+  if (0 == sh_mail_wait(250, fd)) 
     {
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
@@ -1479,5 +1485,5 @@
   (void) fflush(connFile);
 
-  if (0 == sh_mail_wait(250, connFile)) 
+  if (0 == sh_mail_wait(250, fd)) 
     {
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
@@ -1500,5 +1506,5 @@
       (void) fflush(connFile);
 
-      if (0 == sh_mail_wait(250, connFile)) 
+      if (0 == sh_mail_wait(250, fd)) 
 	{
 	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
@@ -1524,5 +1530,5 @@
 	  (void) fflush(connFile);
 	  
-	  if (0 == sh_mail_wait(250, connFile)) 
+	  if (0 == sh_mail_wait(250, fd)) 
 	    {
 	      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
@@ -1549,5 +1555,5 @@
   (void) fflush(connFile);
 
-  if (0 == sh_mail_wait(354, connFile)) 
+  if (0 == sh_mail_wait(354, fd)) 
     {
       sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
@@ -1561,5 +1567,9 @@
 
   my_time = time(NULL);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  my_tm   = localtime_r(&my_time, &time_tm);
+#else
   my_tm   = localtime(&my_time);
+#endif
   (void)    strftime(my_tbuf, 127, _("%a, %d %b %Y %H:%M:%S %Z"), my_tm);
 
@@ -1576,4 +1586,5 @@
 	  my_tbuf, 13, 10);
 
+  *ma_socket = fd;
   SL_RETURN( connFile, _("sh_mail_start_conn"));
 }
@@ -1585,5 +1596,5 @@
  */
 
-static int sh_mail_end_conn (FILE * connFile)
+static int sh_mail_end_conn (FILE * connFile, int fd)
 {
   SL_ENTER(_("sh_mail_end_conn"));
@@ -1597,5 +1608,5 @@
   TPT(( 0, FIL__, __LINE__, _("msg=<message end written>\n")));
 
-  if (0 != sh_mail_wait(250, connFile))
+  if (0 != sh_mail_wait(250, fd))
     {  
       (void) fflush(connFile);
@@ -1625,18 +1636,9 @@
  */
 
-static jmp_buf wait_timeout;
-
-static void sh_mail_alarmhandle (int mysignal)
-{
-  /*@-noeffect@*/
-  (void) mysignal; /* avoid compiler warning */
-  /*@+noeffect@*/
-
-  longjmp(wait_timeout, 1);
-}
-
-static int sh_mail_wait(int code, FILE * ma_socket)
+static int sh_mail_wait(int code, int ma_socket)
 {
   int rcode, g;
+
+  char c;
 
   char errmsg[128];
@@ -1651,50 +1653,20 @@
   time_t waited_time;
 
-  struct   sigaction          old_act;
-  volatile unsigned int       old_alarm = 0;
-
-  struct  sigaction  new_act;
-  sigset_t           unblock;
-
-  (void) sigemptyset(&unblock);
-  (void) sigaddset  (&unblock, SIGALRM);
-
-  new_act.sa_handler = sh_mail_alarmhandle;
-  (void) sigemptyset( &new_act.sa_mask );       /* set an empty mask       */
-  new_act.sa_flags = 0;                         /* init sa_flags           */
-
   SL_ENTER(_("mail_wait"));
   
-  /* alarm was triggered
-   */
-  if (setjmp(wait_timeout) != 0)
-    {
-      (void) alarm(0);
-      (void) sigaction (SIGALRM, &old_act, NULL);
-      (void) alarm(old_alarm);
-      (void) sigprocmask(SIG_UNBLOCK, &unblock, NULL);
-      TPT((0, FIL__, __LINE__, _("msg=<mail_wait: timeout>\n"))); 
-      SL_RETURN( 0, _("mail_wait"));
-    }
-
   waited_time = time(NULL);
 
   /* timeout after 5 minutes
    */
-  old_alarm = alarm(0);
-  (void) sigaction (SIGALRM, &new_act, &old_act);
-  (void) alarm((unsigned int) time_wait);
 
   rcode = 0;
   state = WAIT_CODE_START;
 
-  while (0 == feof(ma_socket) && 0 == ferror(ma_socket)) {
+  while (sl_read_timeout_fd (ma_socket, &c, 1, time_wait, SL_FALSE) > 0) {
+
+    g = (int) c;
 
     if ( (g=fgetc(ma_socket)) == EOF)
       {
-	(void) alarm(0);
-	(void) sigaction (SIGALRM, &old_act, NULL); 
-	(void) alarm(old_alarm);
-	(void) sigprocmask(SIG_UNBLOCK, &unblock, NULL);
 	TPT((0, FIL__, __LINE__, _("msg=<mail_wait: EOF>\n"))); 
 	SL_RETURN( 0, _("mail_wait")); 
@@ -1733,8 +1705,4 @@
 	break;
       /*@-charintliteral@*/
-      (void) alarm(0);
-      (void) sigaction (SIGALRM, &old_act, NULL); 
-      (void) alarm(old_alarm);
-      (void) sigprocmask(SIG_UNBLOCK, &unblock, NULL);
 
       TPT((0, FIL__, __LINE__, 
@@ -1769,8 +1737,4 @@
       
     default:
-      (void) alarm(0);
-      (void) sigaction (SIGALRM, &old_act, NULL); 
-      (void) alarm(old_alarm);
-      (void) sigprocmask(SIG_UNBLOCK, &unblock, NULL);
 
       TPT((0, FIL__, __LINE__, _("msg=<mail_wait: bad>\n"))); 
@@ -1779,9 +1743,4 @@
     }
   }
-
-  (void) alarm(0);                            /* Disable alarm       */
-  (void) sigaction (SIGALRM, &old_act, NULL); 
-  (void) alarm(old_alarm);
-  (void) sigprocmask(SIG_UNBLOCK, &unblock, NULL);
 
   TPT((0, FIL__, __LINE__, _("msg=<mail_wait: failed>\n"))); 
Index: /trunk/src/sh_portcheck.c
===================================================================
--- /trunk/src/sh_portcheck.c	(revision 130)
+++ /trunk/src/sh_portcheck.c	(revision 131)
@@ -1145,4 +1145,7 @@
   char * list;
   char * p;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+  char * saveptr;
+#endif
 
   if (!str)
@@ -1187,5 +1190,9 @@
 
   list = sh_util_strdup(&str[ll]);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+  p    = strtok_r (list, " ,\t", &saveptr);
+#else
   p    = strtok (list, " ,\t");
+#endif
   if (!p)
     {
@@ -1202,5 +1209,9 @@
 	  return -1;
 	}
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      p    = strtok_r (NULL, " ,\t", &saveptr);
+#else
       p    = strtok (NULL, " ,\t");
+#endif
     }
   SH_FREE(interface);
Index: /trunk/src/sh_prelink.c
===================================================================
--- /trunk/src/sh_prelink.c	(revision 130)
+++ /trunk/src/sh_prelink.c	(revision 131)
@@ -84,5 +84,5 @@
     return S_FALSE;
 
-  status = sl_read_timeout (fd, magic, 4, alert_timeout);
+  status = sl_read_timeout (fd, magic, 4, alert_timeout, SL_FALSE);
   (void) sl_rewind(fd);
   if (status == 4)
Index: /trunk/src/sh_prelude.c
===================================================================
--- /trunk/src/sh_prelude.c	(revision 130)
+++ /trunk/src/sh_prelude.c	(revision 131)
@@ -83,4 +83,6 @@
 #include "sh_error_min.h"
 #include "sh_prelude.h"
+#define SH_NEED_PWD_GRP 1
+#include "sh_static.h"
 
 /*
@@ -138,9 +140,16 @@
         char * p;
 	char * dup = strdup (str);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+	char * saveptr;
+#endif
 
 	if (!dup) 
 	        return -1;
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+	p = strtok_r (dup, ", \t", &saveptr);
+#else
 	p = strtok (dup, ", \t");
+#endif
         if (p) {
                 do {
@@ -165,5 +174,9 @@
 	                        return -1;
 			}
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+                        p = strtok_r (NULL, ", \t", &saveptr);
+#else
                         p = strtok (NULL, ", \t");
+#endif
                 } while (p);
         }
@@ -679,4 +692,8 @@
         idmef_node_t *node;
         struct passwd *pw;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+	struct passwd pwd;
+	char buffer[SH_PWBUF_SIZE];
+#endif
         prelude_string_t *str;
         idmef_user_id_t *user_id;
@@ -763,5 +780,9 @@
                 idmef_user_id_set_type(user_id, IDMEF_USER_ID_TYPE_TARGET_USER);
                 
-                pw = getpwnam(ptr);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+		sh_getpwnam_r(ptr, &pwd, buffer, sizeof(buffer), &pw);
+#else
+		pw = sh_getpwnam(ptr);
+#endif
                 if ( pw )
                         idmef_user_id_set_number(user_id, pw->pw_uid);
Index: /trunk/src/sh_schedule.c
===================================================================
--- /trunk/src/sh_schedule.c	(revision 130)
+++ /trunk/src/sh_schedule.c	(revision 131)
@@ -130,4 +130,7 @@
   struct tm * tval;
   int count, i, nval;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  struct tm     time_tm;
+#endif
 
   if (!isched)
@@ -135,6 +138,9 @@
 
   now  = time(NULL);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  tval = localtime_r(&now, &time_tm);
+#else
   tval = localtime(&now);
-
+#endif
   count = 0;
   for (i = 0; i < 5; ++i)
@@ -320,4 +326,7 @@
   int    i = 0;
   size_t len;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+  char * saveptr;
+#endif
 
   if (!ssched || !isched)
@@ -332,5 +341,10 @@
   sl_strlcpy(copy, ssched, len);
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+  p = strtok_r(copy, " \t", &saveptr); /* parse crontab-style schedule */
+#else
   p = strtok(copy, " \t"); /* parse crontab-style schedule */
+#endif
+
   if (!p)
     goto err; 
@@ -340,5 +354,9 @@
   for (i = 1; i < 5; ++i)
     {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      p = strtok_r(NULL, " \t", &saveptr); /* parse crontab-style schedule */
+#else
       p = strtok(NULL, " \t"); /* parse crontab-style schedule */
+#endif
       if (!p)
 	goto err; 
@@ -420,5 +438,5 @@
     {
       if (test_sched(&isched))
-	printf("EXECUTE  at: %s", ctime(&(isched.last_exec)));
+	printf("EXECUTE  at: %s", ctime(&(isched.last_exec))); /* TESTONLY */
       sleep (1); /* TESTONLY */
     }
Index: /trunk/src/sh_suidchk.c
===================================================================
--- /trunk/src/sh_suidchk.c	(revision 130)
+++ /trunk/src/sh_suidchk.c	(revision 131)
@@ -71,4 +71,5 @@
 
 #include "samhain.h"
+#include "sh_pthread.h"
 #include "sh_utils.h"
 #include "sh_error.h"
@@ -842,4 +843,6 @@
   char            fileHash[2*(KEY_LEN + 1)];
 
+  struct sh_dirent * dirlist = NULL;
+  struct sh_dirent * dirlist_orig = NULL;
 
   SL_ENTER(_("sh_suidchk_check_internal"));
@@ -870,4 +873,6 @@
   /* Loop over directory entries
    */
+  SH_MUTEX_LOCK(readdir_lock);
+
   do {
 
@@ -886,236 +891,255 @@
 	continue;
 
-      tmpcat = SH_ALLOC(PATH_MAX);
-      (void) sl_strlcpy(tmpcat, iname, PATH_MAX);
-
-      if ((sl_strlen(tmpcat) != sl_strlen(iname)) || (tmpcat[0] == '\0'))
-	{
-	  sl_status = SL_ETRUNC;
-	}
-      else
-	{
-	  if (tmpcat[1] != '\0') 
-	    sl_status = sl_strlcat(tmpcat, "/",                 PATH_MAX);
-	}
-
-      if (! SL_ISERROR(sl_status))
-	sl_status = sl_strlcat(tmpcat, thisEntry->d_name,   PATH_MAX);
-
-      if (SL_ISERROR(sl_status))
-	{
-	  tmp = sh_util_safe_name(tmpcat);
-	  sh_error_handle ((-1), FIL__, __LINE__, (int) sl_status, 
-			   MSG_E_SUBGPATH,
-			   _("path too long"),
-			   _("sh_suidchk_check_internal"), tmp );
-	  SH_FREE(tmp);
-	  continue;
-	}
-
-      ++FileLimNum;
-      ++FileLimTotal;
-
-      /* Rate limit (Fps == Files per second)
-       */
-      if ((ShSuidchkFps > 0 && FileLimNum > ShSuidchkFps && FileLimTotal > 0)&&
-	  (ShSuidchkYield == S_FALSE))
-	{
-	  FileLimNum  = 0;
-	  FileLimNow  = time(NULL);
- 
-	  if ( (FileLimNow  - FileLimStart) > 0 && 
-	       FileLimTotal/(FileLimNow  - FileLimStart) > ShSuidchkFps )
-	    (void) retry_msleep((int)((FileLimTotal/(FileLimNow-FileLimStart))/
-		   ShSuidchkFps) , 0);
-	}
+      dirlist = addto_sh_dirlist (thisEntry, dirlist);
+    }
+
+  } while (thisEntry != NULL);
+
+  SH_MUTEX_UNLOCK(readdir_lock);
+
+  closedir(thisDir);
+
+  dirlist_orig = dirlist;
+
+  do {
+
+    /* If the directory is empty, dirlist = NULL
+     */
+    if (!dirlist)
+      break;
+
+    tmpcat = SH_ALLOC(PATH_MAX);
+    (void) sl_strlcpy(tmpcat, iname, PATH_MAX);
+    
+    if ((sl_strlen(tmpcat) != sl_strlen(iname)) || (tmpcat[0] == '\0'))
+      {
+	sl_status = SL_ETRUNC;
+      }
+    else
+      {
+	if (tmpcat[1] != '\0') 
+	  sl_status = sl_strlcat(tmpcat, "/",                 PATH_MAX);
+      }
+
+    if (! SL_ISERROR(sl_status))
+      sl_status = sl_strlcat(tmpcat, dirlist->sh_d_name,   PATH_MAX);
+
+    if (SL_ISERROR(sl_status))
+      {
+	tmp = sh_util_safe_name(tmpcat);
+	sh_error_handle ((-1), FIL__, __LINE__, (int) sl_status, 
+			 MSG_E_SUBGPATH,
+			 _("path too long"),
+			 _("sh_suidchk_check_internal"), tmp );
+	SH_FREE(tmp);
+	dirlist = dirlist->next;
+	continue;
+      }
+
+    ++FileLimNum;
+    ++FileLimTotal;
+
+    /* Rate limit (Fps == Files per second)
+     */
+    if ((ShSuidchkFps > 0 && FileLimNum > ShSuidchkFps && FileLimTotal > 0)&&
+	(ShSuidchkYield == S_FALSE))
+      {
+	FileLimNum  = 0;
+	FileLimNow  = time(NULL);
+	
+	if ( (FileLimNow  - FileLimStart) > 0 && 
+	     FileLimTotal/(FileLimNow  - FileLimStart) > ShSuidchkFps )
+	  (void) retry_msleep((int)((FileLimTotal/(FileLimNow-FileLimStart))/
+				    ShSuidchkFps) , 0);
+      }
 	      
-      status = (int) retry_lstat(FIL__, __LINE__, tmpcat, &buf);
-
-      if (status != 0)
-	{
-	  status = errno;
-	  tmp = sh_util_safe_name(tmpcat);
-	  sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
-			   sh_error_message(status),
-			   tmpcat );
-	  SH_FREE(tmp);
-	}
-      else
-	{
-	  if (/*@-usedef@*/S_ISDIR(buf.st_mode)/*@+usedef@*/ &&
-	      (ShSuidchkExclude == NULL || 
-	       0 != strcmp(tmpcat, ShSuidchkExclude)))
-	    {
-	      /* fs is a STATIC string or NULL
-	       */
-	      fs = filesystem_type (tmpcat, tmpcat, &buf);
-	      if (fs != NULL 
+    status = (int) retry_lstat(FIL__, __LINE__, tmpcat, &buf);
+
+    if (status != 0)
+      {
+	status = errno;
+	tmp = sh_util_safe_name(tmpcat);
+	sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, status, MSG_ERR_LSTAT,
+			 sh_error_message(status),
+			 tmpcat );
+	SH_FREE(tmp);
+      }
+    else
+      {
+	if (/*@-usedef@*/S_ISDIR(buf.st_mode)/*@+usedef@*/ &&
+	    (ShSuidchkExclude == NULL || 
+	     0 != strcmp(tmpcat, ShSuidchkExclude)))
+	  {
+	    /* fs is a STATIC string or NULL
+	     */
+	    fs = filesystem_type (tmpcat, tmpcat, &buf);
+	    if (fs != NULL 
 #ifndef SH_SUIDTESTDIR
-		  && 
-		  0 != strncmp (_("afs"),     fs, 3) && 
-		  0 != strncmp (_("devfs"),   fs, 5) &&
-		  0 != strncmp (_("iso9660"), fs, 7) &&
-		  0 != strncmp (_("lustre"),  fs, 6) &&
-		  0 != strncmp (_("mmfs"),    fs, 4) && 
-		  0 != strncmp (_("msdos"),   fs, 5) &&
-		  0 != strncmp (_("nfs"),     fs, 3) &&
-		  0 != strncmp (_("proc"),    fs, 4) &&
-		  0 != strncmp (_("vfat"),    fs, 4)
+		&& 
+		0 != strncmp (_("afs"),     fs, 3) && 
+		0 != strncmp (_("devfs"),   fs, 5) &&
+		0 != strncmp (_("iso9660"), fs, 7) &&
+		0 != strncmp (_("lustre"),  fs, 6) &&
+		0 != strncmp (_("mmfs"),    fs, 4) && 
+		0 != strncmp (_("msdos"),   fs, 5) &&
+		0 != strncmp (_("nfs"),     fs, 3) &&
+		0 != strncmp (_("proc"),    fs, 4) &&
+		0 != strncmp (_("vfat"),    fs, 4)
 #endif 
+		)
+	      {
+		if ((ShSuidchkNosuid == S_TRUE) || 
+		    (0 != strncmp (_("nosuid"),  fs, 6)))
+		  /* fprintf(stderr, "%s: %s\n", fs, tmpcat); */
+		  (void) sh_suidchk_check_internal(tmpcat);
+	      }
+	  }
+	else if (S_ISREG(buf.st_mode) &&
+		 (0 !=(S_ISUID & buf.st_mode) ||
+#if defined(HOST_IS_LINUX)
+		  (0 !=(S_ISGID & buf.st_mode) && 
+		   0 !=(S_IXGRP & buf.st_mode)) 
+#else  
+		  0 !=(S_ISGID & buf.st_mode)
+#endif
 		  )
-		{
-		  if ((ShSuidchkNosuid == S_TRUE) || 
-		      (0 != strncmp (_("nosuid"),  fs, 6)))
-		    /* fprintf(stderr, "%s: %s\n", fs, tmpcat); */
-		    (void) sh_suidchk_check_internal(tmpcat);
-		}
-	    }
-	  else if (S_ISREG(buf.st_mode) &&
-		   (0 !=(S_ISUID & buf.st_mode) ||
-#if defined(HOST_IS_LINUX)
-		    (0 !=(S_ISGID & buf.st_mode) && 
-		     0 !=(S_IXGRP & buf.st_mode)) 
-#else  
-		    0 !=(S_ISGID & buf.st_mode)
-#endif
-		    )
-		   )
-	    {
-	      
-	      (void) sl_strlcpy (theFile.fullpath, tmpcat, PATH_MAX);
-	      theFile.check_mask  = sh_files_maskof(SH_LEVEL_READONLY);
-	      CLEAR_SH_FFLAG_REPORTED(theFile.file_reported);
-	      theFile.attr_string = NULL;
-
-	      status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_RO], 
-					thisEntry->d_name,
-					&theFile, fileHash, 0);
-
-	      tmp = sh_util_safe_name(tmpcat);
-
-	      if (status != 0)
-		{
-		  sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__, 
-				   0, MSG_E_SUBGPATH,
-				   _("Could not check suid/sgid file"),
-				   _("sh_suidchk_check_internal"),
-				   tmp);
-		}
-	      else
-		{
-
-		  if ( sh.flag.update   == S_TRUE && 
-		      (sh.flag.checkSum == SH_CHECK_INIT  || 
-		       sh.flag.checkSum == SH_CHECK_CHECK))
-		    {
-		      /* Updating database. Report new files that
-		       * are not in database already. Then compare
-		       * to database and report changes.
-		       */
-		      if (-1 == sh_hash_have_it (tmpcat))
-			{
-			  sh_error_handle ((-1), FIL__, __LINE__, 
-					   0, MSG_SUID_FOUND, tmp );
-			}
-		      else
-			{
-			  sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
-					   0, MSG_SUID_FOUND, tmp );
-			}
-
-		      if (0 == sh_hash_compdata (SH_LEVEL_READONLY, 
+		 )
+	  {
+	    
+	    (void) sl_strlcpy (theFile.fullpath, tmpcat, PATH_MAX);
+	    theFile.check_mask  = sh_files_maskof(SH_LEVEL_READONLY);
+	    CLEAR_SH_FFLAG_REPORTED(theFile.file_reported);
+	    theFile.attr_string = NULL;
+	    
+	    status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_RO], 
+				      thisEntry->d_name,
+				      &theFile, fileHash, 0);
+	    
+	    tmp = sh_util_safe_name(tmpcat);
+	    
+	    if (status != 0)
+	      {
+		sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__, 
+				 0, MSG_E_SUBGPATH,
+				 _("Could not check suid/sgid file"),
+				 _("sh_suidchk_check_internal"),
+				 tmp);
+	      }
+	    else
+	      {
+		
+		if ( sh.flag.update   == S_TRUE && 
+		     (sh.flag.checkSum == SH_CHECK_INIT  || 
+		      sh.flag.checkSum == SH_CHECK_CHECK))
+		  {
+		    /* Updating database. Report new files that
+		     * are not in database already. Then compare
+		     * to database and report changes.
+		     */
+		    if (-1 == sh_hash_have_it (tmpcat))
+		      {
+			sh_error_handle ((-1), FIL__, __LINE__, 
+					 0, MSG_SUID_FOUND, tmp );
+		      }
+		    else
+		      {
+			sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
+					 0, MSG_SUID_FOUND, tmp );
+		      }
+		    
+		    if (0 == sh_hash_compdata (SH_LEVEL_READONLY, 
+					       &theFile, fileHash,
+					       _("[SuidCheck]"), 
+					       ShSuidchkSeverity))
+		      {
+			sh_hash_pushdata_memory (&theFile, fileHash);
+		      }
+		    
+		    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
+		    
+		  }
+		
+		else if (sh.flag.checkSum == SH_CHECK_INIT  && 
+			 sh.flag.update == S_FALSE )
+		  {
+		    /* Running init. Report on files detected.
+		     */
+		    sh_hash_pushdata (&theFile, fileHash);
+		    sh_error_handle ((-1), FIL__, __LINE__, 
+				     0, MSG_SUID_FOUND, tmp );
+		  }
+		
+		else if (sh.flag.checkSum == SH_CHECK_CHECK )
+		  {
+		    /* Running file check. Report on new files
+		     * detected, and quarantine them.
+		     */
+		    sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
+				     0, MSG_SUID_FOUND, tmp );
+		    
+		    fflags = sh_hash_getflags(tmpcat);
+		    
+		    if ( (-1 == fflags) || (!SH_FFLAG_SUIDCHK_SET(fflags)))
+		      {
+			if (-1 == fflags)
+			  report_file(tmpcat, &theFile, timestrc, timestra, timestrm);
+			
+			/* Quarantine file according to configured method
+			 */
+			if (ShSuidchkQEnable == S_TRUE)
+			  {
+			    switch (ShSuidchkQMethod)
+			      {
+			      case SH_Q_DELETE:
+				sh_q_delete(theFile.fullpath);
+				break;
+			      case SH_Q_CHANGEPERM:
+				sh_q_changeperm(theFile.fullpath);
+				break;
+			      case SH_Q_MOVE:
+				sh_q_move(theFile.fullpath, &theFile, timestrc, timestra, timestrm);
+				break;
+			      default:
+				sh_error_handle (ShSuidchkSeverity, FIL__,
+						 __LINE__, 0, MSG_SUID_QREPORT,
+						 _("Bad quarantine method"), tmp);
+				break;
+			      }
+			  }
+			else
+			  {
+			    /* 1.8.1 push file to in-memory database
+			     */
+			    (void) sh_hash_compdata (SH_LEVEL_READONLY,
+						     &theFile, fileHash,
+						     _("[SuidCheck]"),
+						     ShSuidchkSeverity);
+			    
+			    sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
+			    
+			  }
+		      }
+		    else
+		      {
+			/* File exists. Check for modifications.
+			 */
+			(void) sh_hash_compdata (SH_LEVEL_READONLY, 
 						 &theFile, fileHash,
-						 _("[SuidCheck]"), 
-						 ShSuidchkSeverity))
-			{
-			  sh_hash_pushdata_memory (&theFile, fileHash);
-			}
-		      
-		      sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
-		      
-		    }
-
-		  else if (sh.flag.checkSum == SH_CHECK_INIT  && 
-			   sh.flag.update == S_FALSE )
-		    {
-		      /* Running init. Report on files detected.
-		       */
-		      sh_hash_pushdata (&theFile, fileHash);
-		      sh_error_handle ((-1), FIL__, __LINE__, 
-				       0, MSG_SUID_FOUND, tmp );
-		    }
-
-		  else if (sh.flag.checkSum == SH_CHECK_CHECK )
-		    {
-		      /* Running file check. Report on new files
-		       * detected, and quarantine them.
-		       */
-		      sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
-				       0, MSG_SUID_FOUND, tmp );
-
-		      fflags = sh_hash_getflags(tmpcat);
-
-		      if ( (-1 == fflags) || (!SH_FFLAG_SUIDCHK_SET(fflags)))
-			{
-			  if (-1 == fflags)
-			    report_file(tmpcat, &theFile, timestrc, timestra, timestrm);
-
-			  /* Quarantine file according to configured method
-                          */
-			  if (ShSuidchkQEnable == S_TRUE)
-			    {
-			      switch (ShSuidchkQMethod)
-				{
-				  case SH_Q_DELETE:
-				    sh_q_delete(theFile.fullpath);
-				    break;
-				  case SH_Q_CHANGEPERM:
-				    sh_q_changeperm(theFile.fullpath);
-				    break;
-				  case SH_Q_MOVE:
-				    sh_q_move(theFile.fullpath, &theFile, timestrc, timestra, timestrm);
-				    break;
-				  default:
-				    sh_error_handle (ShSuidchkSeverity, FIL__,
-						     __LINE__, 0, MSG_SUID_QREPORT,
-						     _("Bad quarantine method"), tmp);
-				    break;
-				}
-			    }
-			  else
-			    {
-			      /* 1.8.1 push file to in-memory database
-			       */
-			      (void) sh_hash_compdata (SH_LEVEL_READONLY,
-						       &theFile, fileHash,
-						       _("[SuidCheck]"),
-						       ShSuidchkSeverity);
-
-			      sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
-
-			    }
-			}
-		      else
-			{
-			  /* File exists. Check for modifications.
-			   */
-			  (void) sh_hash_compdata (SH_LEVEL_READONLY, 
-						   &theFile, fileHash,
-						   _("[SuidCheck]"),
-						   ShSuidchkSeverity);
-			  
-			  sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
-
-			}
-		    }
-		}
-	      SH_FREE(tmp);
-	      if (theFile.attr_string)
-		SH_FREE(theFile.attr_string);
-	    }
-	}
-      SH_FREE(tmpcat);
-    }
-
+						 _("[SuidCheck]"),
+						 ShSuidchkSeverity);
+			
+			sh_hash_addflag(tmpcat, SH_FFLAG_SUIDCHK);
+			
+		      }
+		  }
+	      }
+	    SH_FREE(tmp);
+	    if (theFile.attr_string)
+	      SH_FREE(theFile.attr_string);
+	  }
+      }
+    SH_FREE(tmpcat);
+
+  
 #ifdef HAVE_SCHED_YIELD
     if (ShSuidchkYield == S_TRUE)
@@ -1125,13 +1149,17 @@
 	    status = errno;
 	    sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
-		             _("Failed to release time slice"),
+			     _("Failed to release time slice"),
 			     _("sh_suidchk_check_internal") );
 	  }
       }
 #endif
-
-  }  while (thisEntry != NULL);
-
-  (void) closedir (thisDir);
+  
+    dirlist = dirlist->next;
+
+  }  while (dirlist != NULL);
+
+
+  kill_sh_dirlist (dirlist_orig);
+
   SL_RETURN( (0), _("sh_suidchk_check_internal"));
 }
Index: /trunk/src/sh_tiger0.c
===================================================================
--- /trunk/src/sh_tiger0.c	(revision 130)
+++ /trunk/src/sh_tiger0.c	(revision 131)
@@ -206,5 +206,5 @@
       {
 	if (timeout > 0)
-	  count = sl_read_timeout (fd, buffer, PRIV_MAX, timeout);
+	  count = sl_read_timeout (fd, buffer, PRIV_MAX, timeout, SL_TRUE);
 	else
 	  count = sl_read         (fd, buffer, PRIV_MAX);
Index: /trunk/src/sh_unix.c
===================================================================
--- /trunk/src/sh_unix.c	(revision 130)
+++ /trunk/src/sh_unix.c	(revision 131)
@@ -598,4 +598,5 @@
   strncpy (sh_sig_msg, sh_unix_siglist(mysignal), 40);
 #endif
+  sh_sig_msg[63] = '\0';
 
   sl_stack_print();
@@ -648,5 +649,5 @@
   if (mysignal == SIGQUIT)
     {
-      sig_terminate         = 1;
+      sig_terminate       = 1;
       ++sig_urgent;
     }
@@ -770,5 +771,5 @@
 #endif
 #ifdef SIGTERM
-  retry_sigaction(FIL__, __LINE__, SIGTERM,     &act,  &oldact);
+  retry_sigaction(FIL__, __LINE__, SIGTERM,    &act,  &oldact);
 #endif
 
@@ -951,9 +952,20 @@
   uid_t                     pwid  = (uid_t)-1;
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+  struct passwd    pwd;
+  char             buffer[SH_PWBUF_SIZE];
+#endif
+  
   SL_ENTER(_("tf_add_trusted_user_int"));
 
   /* First check for a user name.
    */
-  if ((w = sh_getpwnam(c)) != NULL && ((pwid = w->pw_uid) > 0))
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+  status = sh_getpwnam_r(c, &pwd, buffer, sizeof(buffer), &w);
+#else
+  w = sh_getpwnam(c);
+#endif
+
+  if ((w != NULL) && ((pwid = w->pw_uid) > 0))
     goto succe;
 	
@@ -978,8 +990,15 @@
   char * q;
   char * p = sh_util_strdup (c);
-  
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+  char * saveptr;
+#endif
+
   SL_ENTER(_("tf_add_trusted_user"));
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+  q = strtok_r(p, ", \t", &saveptr);
+#else
   q = strtok(p, ", \t");
+#endif
   if (!q)
     {
@@ -995,5 +1014,9 @@
 	  SL_RETURN((i), _("tf_add_trusted_user"));
 	}
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
+      q = strtok_r(NULL, ", \t", &saveptr);
+#else
       q = strtok(NULL, ", \t");
+#endif
     }
   SH_FREE(p);
@@ -1031,5 +1054,12 @@
   if (0 == sl_ret_euid())   /* privileges not dropped yet */
     {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      struct passwd    pwd;
+      char             buffer[SH_PWBUF_SIZE];
+      struct passwd *  tempres;
+      sh_getpwnam_r(DEFAULT_IDENT, &pwd, buffer, sizeof(buffer), &tempres);
+#else
       struct passwd * tempres = sh_getpwnam(DEFAULT_IDENT);
+#endif
 
       if (!tempres)
@@ -1964,9 +1994,17 @@
   SL_ENTER(_("t_zone"));
 
-
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GMTIME_R)
+  cc = gmtime_r (xx, &aa);
+#else
   cc = gmtime (xx);
   memcpy (&aa, cc, sizeof(struct tm));
+#endif
+
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  cc = localtime_r (xx, &bb);
+#else
   cc = localtime (xx);
   memcpy (&bb, cc, sizeof(struct tm));
+#endif
 
   /* Check for datum wrap-around.
@@ -2064,4 +2102,7 @@
   time_t        time_now;
   struct tm   * time_ptr;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+  struct tm     time_tm;
+#endif
   static char   AsciiTime[81];                       /* local time   */
   static char   RetTime[81];                         /* local time   */
@@ -2164,6 +2205,11 @@
     SL_RETURN( _(deftime), _("sh_unix_time"));
   else
-    time_ptr   = localtime (&time_now);
-
+    {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+      time_ptr   = localtime_r (&time_now, &time_tm);
+#else
+      time_ptr   = localtime (&time_now);
+#endif
+    }
   if (time_ptr != NULL) 
     {
@@ -2208,4 +2254,7 @@
 
   struct tm   * time_ptr;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS)
+  struct tm     time_tm;
+#endif
   static char   AsciiTime[81];                       /* GMT time   */
 #ifdef SH_USE_XML
@@ -2218,8 +2267,19 @@
 
   if (sh_unix_use_localtime == S_FALSE)
-    time_ptr   = gmtime (&thetime);
+    {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GMTIME_R)
+      time_ptr   = gmtime_r (&thetime, &time_tm);
+#else
+      time_ptr   = gmtime (&thetime);
+#endif
+    }
   else
-    time_ptr   = localtime (&thetime);
-
+    {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_LOCALTIME_R)
+      time_ptr   = localtime_r (&thetime, &time_tm);
+#else
+      time_ptr   = localtime (&thetime);
+#endif
+    }
   if (time_ptr != NULL) 
     {
@@ -2249,10 +2309,18 @@
   struct passwd * tempres;
   int    status = 0;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
+  struct passwd pwd;
+  char   buffer[SH_PWBUF_SIZE];
+#endif
 
   SL_ENTER(_("sh_unix_getUIDdir"));
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
+  sh_getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &tempres);
+#else
   errno = 0;
   tempres = sh_getpwuid(uid);
   status = errno;
+#endif
 
   if (tempres == NULL) {
@@ -2276,4 +2344,8 @@
 {
   struct passwd * tempres;
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
+  struct passwd pwd;
+  char   buffer[SH_PWBUF_SIZE];
+#endif
   int             status = 0;
   static uid_t    old_uid;
@@ -2286,7 +2358,11 @@
   }
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
+  sh_getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &tempres);
+#else
   errno = 0;
   tempres = sh_getpwuid(uid);
   status = errno;
+#endif
  
   if (tempres == NULL) {
@@ -2299,6 +2375,8 @@
 
   if (tempres->pw_name != NULL) {
+    /* NEED_LOCK */
     sl_strlcpy(name, tempres->pw_name, sizeof(name));
     old_uid = uid;
+    /* END_LOCK  */
     SL_RETURN( name, _("sh_unix_getUIDname"));
   } else {
@@ -2316,4 +2394,9 @@
   static gid_t    old_gid;
   static char     name[32] = { '\0' };
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
+  struct group    grp;
+  char            buffer[SH_GRBUF_SIZE];
+#endif
+  
 
   SL_ENTER(_("sh_unix_getGIDname"));
@@ -2323,7 +2406,11 @@
   }
   
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
+  status = sh_getgrgid_r(gid, &grp, buffer, sizeof(buffer), &tempres);
+#else
   errno = 0;
   tempres = sh_getgrgid(gid);
   status = errno;
+#endif
 
   if (tempres == NULL) {
@@ -2336,6 +2423,8 @@
 
   if (tempres->gr_name != NULL) {
+    /* NEED_LOCK */
     sl_strlcpy(name, tempres->gr_name, sizeof(name));
     old_gid = gid;
+    /* END_LOCK  */
     SL_RETURN( name, _("sh_unix_getGIDname"));
   } else {
Index: /trunk/src/slib.c
===================================================================
--- /trunk/src/slib.c	(revision 130)
+++ /trunk/src/slib.c	(revision 131)
@@ -1425,6 +1425,4 @@
 int sl_policy_get_real(char * user)
 {
-  struct passwd * tempres;
-
   SL_ENTER(_("sl_policy_get_real"));
   SL_REQUIRE(uids_are_stored == SL_FALSE, _("uids_are_stored == SL_FALSE"));
@@ -1433,5 +1431,12 @@
   if (euid == 0 || ruid == 0)
     {
-      tempres = sh_getpwnam(user);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      struct passwd    pwd;
+      char             buffer[SH_PWBUF_SIZE];
+      struct passwd *  tempres;
+      sh_getpwnam_r(user, &pwd, buffer, sizeof(buffer), &tempres);
+#else
+      struct passwd * tempres = sh_getpwnam(user);
+#endif
 
       SL_REQUIRE (NULL != tempres, _("tempres != NULL"));
@@ -1471,14 +1476,15 @@
   if (euid != ruid || egid != rgid)
     {
-      tempres = sh_getpwnam(user);
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      struct passwd    pwd;
+      char             buffer[SH_PWBUF_SIZE];
+      struct passwd *  tempres;
+      sh_getpwnam_r(user, &pwd, buffer, sizeof(buffer), &tempres);
+#else
+      struct passwd * tempres = sh_getpwnam(user);
+#endif
 
       SL_REQUIRE (NULL != tempres, _("tempres != NULL"));
 
-#if 0
-      rgid = tempres->pw_gid;
-      ruid = tempres->pw_uid;
-      SL_REQUIRE(sl_unset_suid() == SL_ENONE, 
-		 _("sl_unset_suid() == SL_ENONE"));
-#endif
       SL_REQUIRE (sl_drop_privileges() == SL_ENONE,
 		  _("sl_drop_privileges() == SL_ENONE"));
@@ -2115,9 +2121,10 @@
   SL_IRETURN(SL_ENONE, _("sl_read_timeout_prep"));
 }
-  
-
-int sl_read_timeout (SL_TICKET ticket, void * buf_in, size_t count, 
-		     int timeout)
-{
+
+
+int sl_read_timeout_fd (int fd, void * buf_in, size_t count, 
+			int timeout, int is_nonblocking)
+{
+  int sflags;
   fd_set readfds;
   struct timeval tv;
@@ -2135,16 +2142,10 @@
   extern volatile int sig_termfast;
  
-  if (buf_in == NULL || SL_ISERROR(fd = get_the_fd(ticket)))
-    {
-      if (buf_in == NULL)
-	{
-	  TPT(( 0, FIL__, __LINE__, _("msg=<null buffer>")));
-	  return (SL_ENULL);
-	}
-      if (SL_ISERROR(fd = get_the_fd(ticket)))
-	{
-	  TPT(( 0, FIL__, __LINE__, _("msg=<ticket error> errno=<%d>"), fd));
-	  return (fd);
-	}
+  if (is_nonblocking == SL_FALSE)
+    {
+      /* set to non-blocking mode 
+       */
+      sflags = retry_fcntl(FIL__, __LINE__, fd, F_GETFL, 0);
+      retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags | O_NONBLOCK);
     }
 
@@ -2190,4 +2191,6 @@
 	      else
 		{
+		  if (is_nonblocking == SL_FALSE)
+		      retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags);
 		  return (SL_EREAD);
 		}
@@ -2203,8 +2206,12 @@
       else if (retval == 0)
 	{
+	  if (is_nonblocking == SL_FALSE)
+	      retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags);
 	  return (SL_TIMEOUT);
 	}
       else
 	{
+	  if (is_nonblocking == SL_FALSE)
+	      retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags);
 	  return (SL_EREAD);
 	}
@@ -2212,4 +2219,6 @@
       if (sig_termfast == 1) 
 	{
+	  if (is_nonblocking == SL_FALSE)
+	      retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags);
 	  return (SL_EREAD);
 	}
@@ -2220,9 +2229,35 @@
       if (tdiff > timeout)
 	{
+	  if (is_nonblocking == SL_FALSE)
+	      retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags);
 	  return (SL_TIMEOUT);
 	}
     }
 
+  if (is_nonblocking == SL_FALSE)
+    retry_fcntl(FIL__, __LINE__, fd, F_SETFL, sflags);
   return ((int) bytes);
+}
+
+int sl_read_timeout (SL_TICKET ticket, void * buf_in, size_t count, 
+		     int timeout, int is_nonblocking)
+{
+  int    fd;
+ 
+  if (buf_in == NULL || SL_ISERROR(fd = get_the_fd(ticket)))
+    {
+      if (buf_in == NULL)
+	{
+	  TPT(( 0, FIL__, __LINE__, _("msg=<null buffer>")));
+	  return (SL_ENULL);
+	}
+      if (SL_ISERROR(fd = get_the_fd(ticket)))
+	{
+	  TPT(( 0, FIL__, __LINE__, _("msg=<ticket error> errno=<%d>"), fd));
+	  return (fd);
+	}
+    }
+
+  return sl_read_timeout_fd (fd, buf_in, count, timeout, is_nonblocking);
 }
 
Index: /trunk/src/trustfile.c
===================================================================
--- /trunk/src/trustfile.c	(revision 130)
+++ /trunk/src/trustfile.c	(revision 131)
@@ -99,14 +99,20 @@
 
 #ifndef TRUST_MAIN
+
 #include "slib.h"
 #define SH_NEED_PWD_GRP 1
 #include "sh_static.h"
+#define SH_GRBUF_SIZE 4096
+#define SH_PWBUF_SIZE 4096
 
 #else
 
 #define sh_getgrgid   getgrgid
+#define sh_getgrgid_r getgrgid_r
+#define sh_getpwnam   getpwnam
+#define sh_getpwnam_r getpwnam_r
+#define sh_getpwuid   getpwuid
+#define sh_getpwuid_r getpwuid_r
 #define sh_getpwent   getpwent
-#define sh_getpwnam   getpwnam
-#define sh_getpwuid   getpwuid
 #define sh_endpwent   endpwent
 
@@ -410,7 +416,20 @@
   register struct group *g;	/* pointer to group information */
   
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
+  struct group    gr;
+  char            buffer[SH_GRBUF_SIZE];
+  struct passwd   pwd;
+  char            pbuffer[SH_PWBUF_SIZE];
+#endif
+
   SL_ENTER(_("isingrp"));
 
-  if ((g = sh_getgrgid(grp)) == NULL)
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
+  sh_getgrgid_r(grp, &gr, buffer, sizeof(buffer), &g);
+#else
+  g = sh_getgrgid(grp);
+#endif
+
+  if (g == NULL)
     {
       SL_IRETURN(SL_FALSE, _("isingrp") );
@@ -428,9 +447,15 @@
 	{
 	  /* map user name to UID and compare */
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+	  sh_getpwnam_r(*p, &pwd, pbuffer, sizeof(pbuffer), &w);
+#else
+	  w = sh_getpwnam(*p);
+#endif
+
 #ifdef TRUST_MAIN
-	  if ((w = sh_getpwnam(*p)) != NULL && *u == (uid_t)(w->pw_uid) )
+	  if (w != NULL && *u == (uid_t)(w->pw_uid) )
 	    SL_IRETURN(SL_TRUE, _("isingrp"));
 #else
-	  if ((w = sh_getpwnam(*p)) != NULL && *u == (uid_t)(w->pw_uid) )
+	  if (w != NULL && *u == (uid_t)(w->pw_uid) )
 	    {
 	      SL_IRETURN(SL_TRUE, _("isingrp"));
@@ -444,9 +469,14 @@
   for(u = ulist; *u != tf_uid_neg; u++)
     {
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
+      sh_getpwuid_r(*u, &pwd, pbuffer, sizeof(pbuffer), &w);
+#else
+      w = sh_getpwuid(*u);
+#endif
 #ifdef TRUST_MAIN
-      if ((w = sh_getpwuid(*u)) != NULL && grp == (gid_t)(w->pw_gid) )
+      if (w != NULL && grp == (gid_t)(w->pw_gid) )
 	SL_IRETURN(SL_TRUE, _("isingrp"));
 #else
-      if ((w = sh_getpwuid(*u)) != NULL && grp == (gid_t)(w->pw_gid) )
+      if (w != NULL && grp == (gid_t)(w->pw_gid) )
 	{
 	  SL_IRETURN(SL_TRUE, _("isingrp"));
@@ -470,4 +500,11 @@
   register int flag = -1;       /* group member found */
 
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
+  struct group    gr;
+  char            buffer[SH_GRBUF_SIZE];
+  struct group    pw;
+  char            pbuffer[SH_PWBUF_SIZE];
+#endif
+
   SL_ENTER(_("onlytrustedingrp"));
 
@@ -477,5 +514,11 @@
 #endif
 
-  if ((g = sh_getgrgid(grp)) == NULL)
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
+  sh_getgrgid_r(grp, &gr, buffer, sizeof(buffer), &g);
+#else
+  g = sh_getgrgid(grp);
+#endif
+
+  if (g == NULL)
     {
 #ifdef TRUST_DEBUG
@@ -503,9 +546,10 @@
       /* map user name to UID and compare 
        */
+#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
+      sh_getpwnam_r(*p, &pw, pbuffer, sizeof(pbuffer), &w);
+#else
       w = sh_getpwnam(*p);
-#ifndef TRUST_MAIN
-      if (!w)
-	w = sh_getpwnam(*p);
-#endif
+#endif
+
       if (w == NULL)    /* not a valid user, ignore    */
 	{
@@ -961,5 +1005,5 @@
   tf_path[0] = '\0';
 #if defined(SH_WITH_SERVER)
-  pass = sh_getpwnam(SH_IDENT);
+  pass = sh_getpwnam(SH_IDENT);  /* TESTONLY */
   if (pass != NULL)
     tf_euid = pass->pw_uid;
