Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 77)
+++ /trunk/configure.ac	(revision 78)
@@ -202,5 +202,5 @@
 	elf.h linux/elf.h \
 	paths.h arpa/nameser.h arpa/nameser_compat.h \
-	rpc/rpcent.h,
+	rpc/rpcent.h sys/statvfs.h,
 	[],
 	[],
@@ -267,5 +267,5 @@
 	initgroups getpagesize \
 	ttyname fchmod \
-	getsid getpriority getpgid
+	getsid getpriority getpgid statvfs
 )
 AC_CHECK_FUNC(statfs, AC_DEFINE(HAVE_STATFS) statfs="yes",  statfs="no")
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 77)
+++ /trunk/docs/Changelog	(revision 78)
@@ -1,3 +1,10 @@
 2.3.1:
+	* sh_portcheck.c: make connect errors more descriptive
+	* sh_portcheck.c: fix ignored setting of PortCheckActive
+	* sh_processcheck.c: add statvfs, and wrap for EINTR
+	* sh_portcheck.c: add wrappers for EINTR
+	* report user and executable for hidden processes
+	* fix update failure if reportonlyonce = false (reported
+	  by D. Strine)
 	* fix compile error in sh_portcheck.c (problem on cygwin
 	  reported by J. D. Fiori)
@@ -8,5 +15,5 @@
 	* CL option -v|--version for info on version and compiled-in options
 	
-2.3.0a:
+2.3.0a (01-11-2006):
 	* fix compile failure with portcheck + stealth (reported by lucas)
 
Index: /trunk/include/sh_cat.h
===================================================================
--- /trunk/include/sh_cat.h	(revision 77)
+++ /trunk/include/sh_cat.h	(revision 78)
@@ -135,4 +135,5 @@
  MSG_PCK_CHECK,  
  MSG_PCK_OK,     
+ MSG_PCK_P_HIDDEN, 
  MSG_PCK_HIDDEN, 
  MSG_PCK_FAKE,   
Index: /trunk/include/sh_unix.h
===================================================================
--- /trunk/include/sh_unix.h	(revision 77)
+++ /trunk/include/sh_unix.h	(revision 78)
@@ -259,9 +259,9 @@
 /* Test whether file exists
  */
-int sh_unix_file_stat(char * path);
+int sh_unix_file_exists(char * path);
 
 /* test whether file exists with proper attributes
  */
-int sh_unix_file_exists(int fd);
+int sh_unix_device_readable(int fd);
 
 /* local host
Index: /trunk/src/sh_cat.c
===================================================================
--- /trunk/src/sh_cat.c	(revision 77)
+++ /trunk/src/sh_cat.c	(revision 78)
@@ -127,4 +127,5 @@
   { MSG_PCK_CHECK,   SH_ERR_NOTICE,  RUN,   N_("msg=\"Checking processes in pid interval [%ld,%ld]\"")},
   { MSG_PCK_OK,      SH_ERR_ALL,     RUN,   N_("msg=\"PID %ld found with tests %s\"")},
+  { MSG_PCK_P_HIDDEN,SH_ERR_SEVERE,  EVENT, N_("msg=\"POLICY [Process] Hidden pid: %ld tests: %s\" path=\"%s\" userid=\"%s\"")},
   { MSG_PCK_HIDDEN,  SH_ERR_SEVERE,  EVENT, N_("msg=\"POLICY [Process] Hidden pid: %ld tests: %s\"")},
   { MSG_PCK_FAKE,    SH_ERR_SEVERE,  EVENT, N_("msg=\"POLICY [Process] Fake pid: %ld tests: %s\"")},
@@ -441,4 +442,5 @@
   { MSG_PCK_CHECK,   SH_ERR_NOTICE,  RUN,   N_("msg=<Checking processes in pid interval [%ld,%ld]>")},
   { MSG_PCK_OK,      SH_ERR_ALL,     RUN,   N_("msg=<PID %ld found with tests %s>")},
+  { MSG_PCK_P_HIDDEN,SH_ERR_SEVERE,  EVENT, N_("msg=<POLICY [Process] Hidden pid: %ld tests: %s> path=<%s> userid=<%s>")},
   { MSG_PCK_HIDDEN,  SH_ERR_SEVERE,  EVENT, N_("msg=<POLICY [Process] Hidden pid: %ld tests: %s>")},
   { MSG_PCK_FAKE,    SH_ERR_SEVERE,  EVENT, N_("msg=<POLICY [Process] Fake pid: %ld tests: %s>")},
Index: /trunk/src/sh_entropy.c
===================================================================
--- /trunk/src/sh_entropy.c	(revision 77)
+++ /trunk/src/sh_entropy.c	(revision 78)
@@ -310,7 +310,7 @@
     {
       /* Test whether file is a character device, and is 
-       * not world writeable.
-       */
-      if (0 == sh_unix_file_exists(fd2)) 
+       * readable.
+       */
+      if (0 == sh_unix_device_readable(fd2)) 
 	{
 
Index: /trunk/src/sh_files.c
===================================================================
--- /trunk/src/sh_files.c	(revision 77)
+++ /trunk/src/sh_files.c	(revision 78)
@@ -2077,5 +2077,5 @@
       if (sl_strlen(testpath) == (17 + sl_strlen(fullpath)))
 	{
-	  if (0 != sh_unix_file_stat (testpath))
+	  if (S_TRUE == sh_unix_file_exists (testpath))
 	    {
 	      sh_files_filecheck (class, fullpath, rsrc, &dummy, 1);
Index: /trunk/src/sh_portcheck.c
===================================================================
--- /trunk/src/sh_portcheck.c	(revision 77)
+++ /trunk/src/sh_portcheck.c	(revision 78)
@@ -593,5 +593,8 @@
   char             * p;
   char               buf[8];
-
+#ifndef TEST_ONLY
+  char               errmsg[256];
+  int                nerr;
+#endif
 
   /* inet_aton(interface, &haddr); */
@@ -601,5 +604,8 @@
   sinr.sin_addr   = haddr;
 
-  retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
+  do {
+    retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
+  } while (retval < 0 && errno == EINTR);
+
   if (retval == -1)
     {
@@ -608,11 +614,16 @@
 	perror(_("connect"));
 #else
-      sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 
-		      sh_error_message(errno), _("connect"));
+      nerr = errno;
+      sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/udp on %15s: %s"),
+		  port, inet_ntoa(haddr), sh_error_message(errno));
+      sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN, 
+		      errmsg, _("connect"));
 #endif
     }
   else
     {
-      retval = send (fd, buf, 0, 0);
+      do {
+	retval = send (fd, buf, 0, 0);
+      } while (retval < 0 && errno == EINTR);
 
       if (retval == -1 && errno == ECONNREFUSED)
@@ -624,5 +635,10 @@
       else 
 	{
-	  retval = send (fd, buf, 0, 0);
+	  /* Only the second send() may catch the error 
+	   */
+	  do {
+	    retval = send (fd, buf, 0, 0);
+	  } while (retval < 0 && errno == EINTR);
+
 	  if (retval == -1 && errno == ECONNREFUSED)
 	    {
@@ -661,4 +677,8 @@
   int                retval;
   char             * p;
+#ifndef TEST_ONLY
+  char               errmsg[256];
+  int                nerr;
+#endif
 
 
@@ -669,5 +689,8 @@
   sinr.sin_addr   = haddr;
 
-  retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
+  do {
+    retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
+  } while (retval < 0 && errno == EINTR);
+
   if (retval == -1 && errno == ECONNREFUSED)
     {
@@ -682,6 +705,9 @@
 	perror(_("connect"));
 #else
-      sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 
-		      sh_error_message(errno), _("connect"));
+      nerr = errno;
+      sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/tcp on %15s: %s"),
+		  port, inet_ntoa(haddr), sh_error_message(errno));
+      sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN, 
+		      errmsg, _("connect"));
 #endif
     }
@@ -738,5 +764,9 @@
   if (portchk_debug)
     fprintf(stderr, _("checking ports on: %s\n"), portchk_hostname ? portchk_hostname : _("NULL"));
+
   if (!portchk_hostname)
+    return -1;
+
+  if (sh_portchk_active == S_FALSE)
     return -1;
 
@@ -767,5 +797,8 @@
 int sh_portchk_reconf ()
 {
-  iface_initialized   = 0;
+  iface_initialized    = 0;
+
+  sh_portchk_active    = 1;
+  sh_portchk_check_upd = 1;
 
   portlist_udp = sh_portchk_kill_list (portlist_udp);
@@ -1139,21 +1172,24 @@
   int min_port = 0;
 
-  sh_portchk_reset_lists();
-  if (0 != geteuid())
-    {
-      min_port = 1024;
-#ifdef TEST_ONLY
-      fprintf(stderr, "** WARNING not scanning ports < 1024\n");
-#else
-      sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
-		      _("not scanning ports below 1024"), _("sh_portchk_check"));
-#endif
-    }
-  if (sh_portchk_check_udp == 1)
-    sh_portchk_scan_ports_udp(min_port, -1);
-  sh_portchk_scan_ports_tcp(min_port, -1);
-  sh_portchk_check_list (&portlist_tcp, "tcp", SH_PORT_REPORT);
-  if (sh_portchk_check_udp == 1)
-    sh_portchk_check_list (&portlist_udp, "udp", SH_PORT_REPORT);
+  if (sh_portchk_active != S_FALSE)
+    {
+      sh_portchk_reset_lists();
+      if (0 != geteuid())
+	{
+	  min_port = 1024;
+#ifdef TEST_ONLY
+	  fprintf(stderr, "** WARNING not scanning ports < 1024\n");
+#else
+	  sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
+			  _("not scanning ports below 1024"), _("sh_portchk_check"));
+#endif
+	}
+      if (sh_portchk_check_udp == 1)
+	sh_portchk_scan_ports_udp(min_port, -1);
+      sh_portchk_scan_ports_tcp(min_port, -1);
+      sh_portchk_check_list (&portlist_tcp, "tcp", SH_PORT_REPORT);
+      if (sh_portchk_check_udp == 1)
+	sh_portchk_check_list (&portlist_udp, "udp", SH_PORT_REPORT);
+    }
   return 0;
 }
Index: /trunk/src/sh_processcheck.c
===================================================================
--- /trunk/src/sh_processcheck.c	(revision 77)
+++ /trunk/src/sh_processcheck.c	(revision 78)
@@ -48,4 +48,9 @@
 #endif
 
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+
+
 #ifdef HAVE_REGEX_H
 #include <regex.h>
@@ -58,4 +63,5 @@
 #include "sh_error.h"
 #include "sh_extern.h"
+#include "sh_calls.h"
 
 #ifdef SH_USE_PROCESSCHECK
@@ -157,9 +163,10 @@
 
 static const short SH_PR_PRIORITY = 0x0100;
-
-static const short SH_PR_PS2      = 0x0200;
-static const short SH_PR_PS_ANY   = 0x0400;
-static const short SH_PR_ALL      = 0x0800;
-static const short SH_PR_ANY      = 0x1000;
+static const short SH_PR_STATVSF  = 0x0200;
+
+static const short SH_PR_PS2      = 0x1000;
+static const short SH_PR_PS_ANY   = 0x2000;
+static const short SH_PR_ALL      = 0x4000;
+static const short SH_PR_ANY      = 0x8000;
 
 /* /proc: 
@@ -168,4 +175,63 @@
  *        solaris10: /proc/pid/path/a.out
  */
+static char * get_user_and_path (pid_t pid, char * user, size_t usrlen)
+{
+  extern char *  sh_unix_getUIDname (int level, uid_t uid);
+
+  char        path[128];
+  char *      buf;
+  struct stat sbuf;
+  int         len;
+  char *      tmp;
+
+  sl_snprintf (path, sizeof(path), "/proc/%ld/exe", (unsigned long) pid);
+
+  if (0 == retry_lstat(FIL__, __LINE__, path, &sbuf) && S_ISLNK(sbuf.st_mode))
+    {
+      goto linkread;
+    }
+
+  sl_snprintf (path, sizeof(path), "/proc/%ld/file", (unsigned long) pid);
+
+  if (0 == retry_lstat(FIL__, __LINE__, path, &sbuf) && S_ISLNK(sbuf.st_mode))
+    {
+      goto linkread;
+    }
+
+  sl_snprintf (path, sizeof(path), "/proc/%ld/path/a.out", (unsigned long) pid);
+
+  if (0 == retry_lstat(FIL__, __LINE__, path, &sbuf) && S_ISLNK(sbuf.st_mode))
+    {
+      goto linkread;
+    }
+
+  return NULL;
+
+ linkread:
+
+  buf = SH_ALLOC(PATH_MAX);
+  len = readlink(path, buf, PATH_MAX);   /* flawfinder: ignore */
+  len = (len >= PATH_MAX) ? (PATH_MAX-1) : len;
+
+  if (len > 0)
+    { 
+      buf[len] = '\0';
+    }
+  else
+    {
+      SH_FREE(buf);
+      return NULL;
+    }
+
+  tmp = sh_unix_getUIDname (SH_ERR_ALL, sbuf.st_uid);
+
+  if (tmp)
+    sl_strlcpy(user, tmp, usrlen);
+  else
+    sl_snprintf (user, usrlen, "%ld", (unsigned long) sbuf.st_uid);
+
+  return buf;
+}
+
 
 struct watchlist {
@@ -483,12 +549,11 @@
   size_t  value;
   char * foo;
-  int    retval = 0;
+  int    retval = -1;
 
   SL_ENTER(_("sh_prochk_set_maxpid"));
 
   value = (size_t) strtoul(str, &foo, 0);
-  if (*foo != '\0') {
-    retval = -1;
-  } else {
+
+  if (*foo == '\0' && SL_TRUE == sl_ok_adds(value, 1)) {
     sh_prochk_maxpid = value + 1;
     userdef_maxpid   = 1;
@@ -593,12 +658,13 @@
   if (res & SH_PR_GETPGID)  sl_strlcat(list, _(" getpgid"), len);
   if (res & SH_PR_KILL)     sl_strlcat(list, _(" kill"), len);
+  if (res & SH_PR_STATVSF)  sl_strlcat(list, _(" statvfs"), len);
   if (res & SH_PR_PS2)      sl_strlcat(list, _(" ps(final)"), len);
   return;
 }
 
-/* FIXME: add open, statvfs, sched_getaffinity
- */
+
 static short sh_processes_check (pid_t pid, short res)
 {
+  int  retval;
   int  have_checks = 0;
   int  need_checks = 0;
@@ -608,4 +674,7 @@
   DIR * dir;
 #endif
+#ifdef HAVE_STATVFS
+  struct statvfs vfsbuf;
+#endif
 
 #if !defined(sun) && !defined(__sun) && !defined(__sun__)
@@ -624,4 +693,5 @@
       ++need_checks;
     }
+
 
 #ifdef HAVE_GETPGID
@@ -666,5 +736,5 @@
   sl_snprintf (path, sizeof(path), "/proc/%ld", (unsigned long) pid);
 
-  if (0 == lstat (path, &buf))
+  if (0 == retry_lstat (FIL__, __LINE__, path, &buf))
     { 
       res |= SH_PR_LSTAT;   res |= SH_PR_ANY; ++have_checks;
@@ -678,4 +748,16 @@
     }
   ++need_checks;
+
+#ifdef HAVE_STATVFS
+  do {
+    retval = statvfs (path, &vfsbuf);
+  } while (retval < 0 && errno == EINTR);
+
+  if (0 == retval)
+    { 
+      res |= SH_PR_STATVSF;   res |= SH_PR_ANY; ++have_checks;
+    }
+  ++need_checks;
+#endif
 
 #if !defined(SH_PROFILE)
@@ -972,7 +1054,24 @@
 		  if (S_FALSE == is_in_list(&list_hidden, NULL, i))
 		    {
-		      sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
-				      MSG_PCK_HIDDEN,
-				      (unsigned long) i, tests);
+		      char   user[16];
+		      char * aout;
+		      char * safe;
+
+		      aout = get_user_and_path ((pid_t) i, user, sizeof(user));
+
+		      if (aout)
+			{
+			  safe = sh_util_safe_name (aout);
+			  sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
+					  MSG_PCK_P_HIDDEN,
+					  (unsigned long) i, tests, safe, user);
+			  SH_FREE(safe);
+			  SH_FREE(aout);
+			}
+		      else
+			sh_error_handle(sh_prochk_severity, FIL__, __LINE__, 0, 
+					MSG_PCK_HIDDEN,
+					(unsigned long) i, tests);
+			
 		    }
 		}
Index: /trunk/src/sh_unix.c
===================================================================
--- /trunk/src/sh_unix.c	(revision 77)
+++ /trunk/src/sh_unix.c	(revision 78)
@@ -3833,38 +3833,32 @@
 /* Test whether file exists
  */
-int sh_unix_file_stat(char * path)
+int sh_unix_file_exists(char * path)
 {
   struct stat buf;
 
-  SL_ENTER(_("sh_unix_file_stat"));
+  SL_ENTER(_("sh_unix_file_exists"));
 
   if (-1 == retry_stat(FIL__, __LINE__, path, &buf))
-    SL_RETURN(  (0), _("sh_unix_file_stat"));
+    SL_RETURN( S_FALSE, _("sh_unix_file_exists"));
   else 
-    SL_RETURN( (-1), _("sh_unix_file_stat"));
-}
-
-
-/* Test whether file exists, is a character device, allows read
- * access, and is not world writeable.
+    SL_RETURN( S_TRUE,  _("sh_unix_file_exists"));
+}
+
+
+/* Test whether file exists, is a character device, and allows read
+ * access.
  */
-int sh_unix_file_exists(int fd)
+int sh_unix_device_readable(int fd)
 {
   struct stat buf;
 
-  SL_ENTER(_("sh_unix_file_exists"));
+  SL_ENTER(_("sh_unix_device_readable"));
 
   if (retry_fstat(FIL__, __LINE__, fd, &buf) == -1)
-    SL_RETURN( (-1), _("sh_unix_file_exists"));
-  else if ( S_ISCHR(buf.st_mode) &&  0 != (S_IROTH & buf.st_mode)
-	    /*
-	     * #if !defined(__CYGWIN32__) && !defined(__CYGWIN__) 
-	     * && 0 == (S_IWOTH & buf.st_mode)
-	     * #endif
-	     */
-	    ) 
-    SL_RETURN( (0), _("sh_unix_file_exists"));
+    SL_RETURN( (-1), _("sh_unix_device_readable"));
+  else if ( S_ISCHR(buf.st_mode) &&  0 != (S_IROTH & buf.st_mode) ) 
+    SL_RETURN( (0), _("sh_unix_device_readable"));
   else 
-    SL_RETURN( (-1), _("sh_unix_file_exists"));
+    SL_RETURN( (-1), _("sh_unix_device_readable"));
 }
 
