Index: trunk/src/samhain.c
===================================================================
--- trunk/src/samhain.c	(revision 487)
+++ trunk/src/samhain.c	(revision 488)
@@ -122,4 +122,6 @@
 volatile  int      sig_termfast;           /* SIGTERM */
 volatile  int      sig_force_check;        /* SIGTTOU */
+volatile  int      sig_force_silent;       /* SIGTSTP */
+volatile  int      sh_global_check_silent;
 volatile  int      sh_load_delta_flag;
 long int           eintr__result;
@@ -343,4 +345,6 @@
   sig_termfast           = 0;           /* SIGTERM */
   sig_force_check        = 0;           /* SIGTTOU */
+  sig_force_silent       = 0;           /* SIGTSTP */
+  sh_global_check_silent = 0;
   sh_load_delta_flag     = 0;
   strcpy ( sh_sig_msg, _("None"));
@@ -1228,4 +1232,12 @@
 }
 
+static int sh_flag_silent = S_FALSE;
+
+int sh_set_silent_full (const char * str)
+{
+  int status = sh_util_flagval(str, &sh_flag_silent);
+  return status;
+}
+
 
 void do_reconf()
@@ -1378,9 +1390,14 @@
 	  }
       
-      if (sig_force_check == 1) /* SIGTTOU */
+      if (sig_force_check == 1) /* SIGTTOU / SIGTSTP */
 	{
 	  TPT((0, FIL__, __LINE__, _("msg=<Check run triggered.>\n")));
 	  *flag_check_1 = 1; *flag_check_2 = 1;
-	  sig_force_check = 0; --sig_raised; 
+	  sig_force_check = 0; --sig_raised;
+	  if (sig_force_silent)
+	    {
+	      sig_force_silent       = 0;
+	      sh_global_check_silent = (sh_flag_silent == S_FALSE) ? SH_SILENT_STD : SH_SILENT_FULL;
+	    }
 	  sh_sem_trylock();
 	}
@@ -1470,5 +1487,6 @@
   /* Need to contact the server.
    */
-  sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_2);
+  if (sh_global_check_silent < SH_SILENT_FULL)
+    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_2);
 
   if (sig_raised > 0 && sh_load_delta_flag > 0)  /* DELTA Command */
@@ -2119,5 +2137,5 @@
 	    (void) sh_files_chk ();
 
-	  if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); continue; }
+	  if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); sh_global_check_silent = 0; continue; }
 	  /*
 	   * check for files not visited
@@ -2129,5 +2147,5 @@
 	    }
 
-	  if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); continue; }
+	  if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); sh_global_check_silent = 0; continue; }
 
 	  /* reset
@@ -2136,5 +2154,5 @@
 	  sh_dirs_reset  ();
 
-	  if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); continue; }
+	  if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); sh_global_check_silent = 0; continue; }
 
 	  sh_files_reset ();
@@ -2150,5 +2168,5 @@
 	  (void) sh_prelink_run (NULL, NULL, 0, 0);
 
-	  if (sig_urgent > 0) continue;
+	  if (sig_urgent > 0) { sh_global_check_silent = 0; continue; }
 
 	  runtim = time(NULL) - sh.statistics.time_start;
@@ -2156,5 +2174,6 @@
 	
 	  if ((sh.statistics.dirs_checked == 0) && 
-	      (sh.statistics.files_checked == 0))
+	      (sh.statistics.files_checked == 0) &&
+	      (sh_global_check_silent < SH_SILENT_FULL))
 	    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_0);
 
@@ -2174,13 +2193,18 @@
 	      sh.statistics.bytes_speed = (unsigned long) st_1;
 
-	      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_1,
-			       (long) runtim, 
-			       0.001 * st_1);
+	      if (sh_global_check_silent < SH_SILENT_FULL)
+		sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_1,
+				 (long) runtim, 
+				 0.001 * st_1);
 
 	      if (sh.flag.checkSum != SH_CHECK_INIT)
 		sh_efile_report();
 	    }
-	  sh.fileCheck.alarm_last = time (NULL);
-
+	  
+	  if (0 == sh_global_check_silent)
+	    sh.fileCheck.alarm_last = time (NULL);
+
+	  sh_global_check_silent = 0;
+	  
 	  if (sig_urgent > 0) continue;
 
Index: trunk/src/sh_audit.c
===================================================================
--- trunk/src/sh_audit.c	(revision 487)
+++ trunk/src/sh_audit.c	(revision 488)
@@ -28,10 +28,13 @@
 #include <errno.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "samhain.h"
+#include "sh_error.h"
 
 #if !defined(SH_COMPILE_STATIC) && defined(__linux__) && defined(HAVE_AUPARSE_H) && defined(HAVE_AUPARSE_LIB)
 #include <auparse.h>
 
-#include "samhain.h"
-#include "sh_error.h"
 #include "sh_extern.h"
 #include "sh_utils.h"
@@ -103,9 +106,10 @@
 }
     
-static char * doAuparse (char * file, time_t time, char * result, size_t rsize)
+static char * doAuparse (const char * file, time_t time, int tol, char * result, size_t rsize, int redo_flag)
 {
   struct recordState state;
   struct recordState stateFetched;
-
+  unsigned int       found_flag = 0;
+  
   auparse_state_t * au = auparse_init(AUSOURCE_LOGS, NULL);
 
@@ -131,6 +135,6 @@
   if (time != 0)
     {
-      ausearch_add_timestamp_item(au, ">=", time-1, 0, AUSEARCH_RULE_AND);
-      ausearch_add_timestamp_item(au, "<=", time+1, 0, AUSEARCH_RULE_AND);
+      ausearch_add_timestamp_item(au, ">=", time-tol, 0, AUSEARCH_RULE_AND);
+      ausearch_add_timestamp_item(au, "<=", time+tol, 0, AUSEARCH_RULE_AND);
     }
 
@@ -152,8 +156,25 @@
 	{
 	  memcpy(&state, &stateFetched, sizeof(state));
+	  ++found_flag;
 	}
       auparse_next_event(au);
     }
 
+  if (found_flag == 0 && redo_flag == S_FALSE)
+    {
+      size_t len = strlen(file);
+      char * path = SH_ALLOC(len + 2);
+      char * altres;
+      
+      sl_strlcpy(path, file, len+2);
+      path[len] = '/'; path[len+1] = '\0';
+      auparse_destroy(au);
+      
+      altres = doAuparse(path, time, tol, result, rsize, S_TRUE);
+
+      SH_FREE(path);
+      return altres;
+    }
+  
   if (0 == strcmp(state.success, "yes"))
     {
@@ -189,5 +210,5 @@
  * The 'result' array should be sized ~256 char. 
  */
-char * sh_audit_fetch (char * file, time_t time, char * result, size_t rsize)
+char * sh_audit_fetch (char * file, time_t mtime, time_t ctime, char * result, size_t rsize)
 {
   char * res = NULL;
@@ -195,10 +216,17 @@
   if (sh_audit_checkdaemon() >= 0)
     {
-      res = doAuparse (file, time, result, rsize);
+      time_t new;
+      char buf[64];
+      
+      if (mtime >= ctime) { new = mtime; }
+      else                { new = ctime; }
+
+      res = doAuparse (file, new, 1, result, rsize, S_FALSE);
 
       if (!res)
 	{
-	  res = doAuparse (file, 0, result, rsize);
+	  res = doAuparse (file, new, 3, result, rsize, S_FALSE);
 	}
+
     }
   return res;
@@ -226,4 +254,13 @@
 }
 
+static int  sh_audit_isdir(const char * file)
+{
+  struct stat buf;
+
+  if ( (0 == lstat (file, &buf)) && S_ISDIR(buf.st_mode))
+    return S_TRUE;
+  return S_FALSE;
+}
+
 static void sh_audit_mark_int (const char * file)
 {
@@ -246,4 +283,7 @@
       char * safe;
       char   ctl[64];
+      char   a1[32];
+      char   a2[32];
+      char   a3[32];
 
       sl_snprintf(command, len, _("%s -w %s -p wa -k samhain"),
@@ -256,4 +296,5 @@
 		       safe,
 		       _("sh_audit_mark") );
+
       SH_FREE(safe);
 
@@ -261,6 +302,24 @@
       sl_strlcpy(command, file, len);
 
-      sh_ext_system(ctl, ctl, "-w", command, "-p", "wa", "-k", _("samhain"), NULL);
-
+      sl_strlcpy(a3, _("samhain"), sizeof(a3));
+      sh_ext_system(ctl, ctl, "-w", command, "-p", "wa", "-k", a3, NULL);
+
+      /* Placing a watch on a directory will not place a watch on the
+       * directory inode, so we do this explicitely. 
+       */
+      if (S_TRUE == sh_audit_isdir(file))
+	{
+	  safe = sh_util_safe_name(file);
+	  sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
+			   0, MSG_E_SUBGPATH,
+			   _("Add path watch for directory"),
+			   _("sh_audit_mark_int"), safe );
+	  SH_FREE(safe);
+	  sl_strlcpy(command, _("path="), len);
+	  sl_strlcat(command, file, len);
+	  sl_strlcpy(a1, _("always,exit"), sizeof(a1));
+	  sl_strlcpy(a2, _("perm=wa"), sizeof(a2));
+	  sh_ext_system(ctl, ctl, "-a", a1, "-F", command, "-F", a2, "-k", a3, NULL);
+	}
       SH_FREE(command);
     }
@@ -278,5 +337,10 @@
 {
   struct aud_list * this = SH_ALLOC(sizeof(struct aud_list));
+  size_t len = strlen(file);
+
   this->file = sh_util_strdup(file);
+  if ((len > 1) && (file[len-1] == '/'))
+    this->file[len-1] = '\0';
+  
   this->next = mark_these;
   mark_these = this;
@@ -284,4 +348,6 @@
 }
 
+/* Check whether it is already covered by a higher directory
+ */
 static int test_exchange (struct aud_list * this, char * file)
 {
@@ -312,6 +378,9 @@
 	   if (0 == strncmp(s0, s1, len1 + 1))
 	     {
+	       size_t len = strlen(file);
 	       SH_FREE(this->file);
 	       this->file = sh_util_strdup(file);
+	       if ((len > 1) && (file[len-1] == '/'))
+		 this->file[len-1] = '\0';
 	       ret = 0;
 	     }
@@ -324,4 +393,6 @@
 }
 
+/* Place a path on the list of of paths to be watched
+ */
 void sh_audit_mark (char * file)
 {
@@ -335,4 +406,7 @@
   while (this)
     {
+      /* Check whether it is already covered by a higher
+       * directory 
+       */
       if (0 == test_exchange(this, file))
 	return;
@@ -464,8 +538,9 @@
 /* HAVE_AUPARSE_H */
 #else
-char * sh_audit_fetch (char * file, time_t time, char * result, size_t rsize)
+char * sh_audit_fetch (char * file, time_t mtime, time_t ctime, char * result, size_t rsize)
 {
   (void) file;
-  (void) time;
+  (void) mtime;
+  (void) ctime;
   (void) result;
   (void) rsize;
@@ -476,4 +551,7 @@
 {
   (void) file;
+  sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN,
+		  _("Setting audit watch not supported"),
+		  _("sh_audit_mark"));
   return;
 }
Index: trunk/src/sh_error.c
===================================================================
--- trunk/src/sh_error.c	(revision 487)
+++ trunk/src/sh_error.c	(revision 488)
@@ -1106,5 +1106,12 @@
       goto exit_here;
     }
-
+  
+#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
+  if ((sh_global_check_silent > SH_SILENT_STD) &&
+      (((1 << FIL) & (1 << class)) != 0))
+    {
+      goto exit_here;
+    }
+#endif
 
   /* Allocate space for the message.
Index: trunk/src/sh_fInotify.c
===================================================================
--- trunk/src/sh_fInotify.c	(revision 487)
+++ trunk/src/sh_fInotify.c	(revision 488)
@@ -511,5 +511,6 @@
 
   SH_MUTEX_LOCK(mutex_thread_nolog);
-  sh_error_handle (level, FIL__, __LINE__, 0, MSG_FI_MISS, tmp);
+  if (!sh_global_check_silent)
+    sh_error_handle (level, FIL__, __LINE__, 0, MSG_FI_MISS, tmp);
   SH_MUTEX_UNLOCK(mutex_thread_nolog);
   ++sh.statistics.files_report;
Index: trunk/src/sh_files.c
===================================================================
--- trunk/src/sh_files.c	(revision 487)
+++ trunk/src/sh_files.c	(revision 488)
@@ -393,9 +393,10 @@
 		if (tmp == NULL) 
 		  tmp = sh_util_safe_name (ptr->name);
-		sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 
-				 ShDFLevel[ptr->class] : 
-				 ShDFLevel[SH_ERR_T_FILE],
-				 FIL__, __LINE__, 0, MSG_FI_MISS,
-				 tmp);
+		if (!sh_global_check_silent)
+		  sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 
+				   ShDFLevel[ptr->class] : 
+				   ShDFLevel[SH_ERR_T_FILE],
+				   FIL__, __LINE__, 0, MSG_FI_MISS,
+				   tmp);
 		++sh.statistics.files_report;
 	      }
@@ -447,9 +448,10 @@
 		    if (tmp == NULL) 
 		      tmp = sh_util_safe_name (ptr->name);
-		    sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE)? 
-				     ShDFLevel[ptr->class] : 
-				     ShDFLevel[SH_ERR_T_FILE],
-				     FIL__, __LINE__, 0, MSG_FI_MISS,
-				     tmp);
+		    if (!sh_global_check_silent)
+		      sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE)? 
+				       ShDFLevel[ptr->class] : 
+				       ShDFLevel[SH_ERR_T_FILE],
+				       FIL__, __LINE__, 0, MSG_FI_MISS,
+				       tmp);
 		    ++sh.statistics.files_report;
 		  }
@@ -953,5 +955,5 @@
 	else if (0 == strcmp(myword, _("TXT")))
 	  sh_files_set_mask (mask, MODI_TXT, act);
-/* get content */
+/* get audit report */
 	else if (0 == strcmp(myword, _("AUDIT")))
 	  sh_files_set_mask (mask, MODI_AUDIT, act);
@@ -1157,4 +1159,7 @@
       if (MODI_AUDIT_ENABLED(check_flags))
 	{
+	  sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGPATH,
+			  _("Setting audit watch"),
+			  _("sh_files_push_file_int"), str_s);
 	  sh_audit_mark(str_s);
 	}
@@ -1577,8 +1582,9 @@
 					      ShDFLevel[SH_ERR_T_DIR])) {
 		    tmp = sh_util_safe_name (ptr->name);
-		    sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 
-				     ShDFLevel[ptr->class] : 
-				     ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__,
-				     0, MSG_FI_MISS, tmp);
+		    if (!sh_global_check_silent)
+		      sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 
+				       ShDFLevel[ptr->class] : 
+				       ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__,
+				       0, MSG_FI_MISS, tmp);
 		    ++sh.statistics.files_report;
 		    SH_FREE(tmp);
@@ -1601,9 +1607,10 @@
 		   */
 		  tmp = sh_util_safe_name (ptr->name);
-		  sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 
-				   ShDFLevel[ptr->class] : 
-				   ShDFLevel[SH_ERR_T_DIR],
-				   FIL__, __LINE__, 0, MSG_FI_ADD,
-				   tmp);
+		  if (!sh_global_check_silent)
+		    sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 
+				     ShDFLevel[ptr->class] : 
+				     ShDFLevel[SH_ERR_T_DIR],
+				     FIL__, __LINE__, 0, MSG_FI_ADD,
+				     tmp);
 		  ++sh.statistics.files_report;
 		  SH_FREE(tmp);
@@ -1778,4 +1785,7 @@
       if (MODI_AUDIT_ENABLED(check_flags))
 	{
+	  sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGPATH,
+			  _("Setting audit watch"),
+			  _("sh_files_push_file_int"), tail);
 	  sh_audit_mark(tail);
 	}
@@ -2156,7 +2166,8 @@
   if (theFile->c_mode[0] != 'd') 
     { 
-      sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
-		       MSG_FI_NODIR,
-		       tmpname);
+      if (!sh_global_check_silent)
+	sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
+			 MSG_FI_NODIR,
+			 tmpname);
       ++sh.statistics.files_nodir;
       if (theFile->attr_string) SH_FREE(theFile->attr_string);
Index: trunk/src/sh_hash.c
===================================================================
--- trunk/src/sh_hash.c	(revision 487)
+++ trunk/src/sh_hash.c	(revision 488)
@@ -248,6 +248,7 @@
 
   SH_MUTEX_LOCK(mutex_thread_nolog);
-  sh_error_handle (level, FIL__, __LINE__, 0, 
-		   MSG_FI_MISS2, tmp, str);
+  if (!sh_global_check_silent)
+    sh_error_handle (level, FIL__, __LINE__, 0, 
+		     MSG_FI_MISS2, tmp, str);
   SH_MUTEX_UNLOCK(mutex_thread_nolog);
   ++sh.statistics.files_report;
@@ -363,6 +364,7 @@
 		  theFile = sh_hash_create_ft (p, fileHash);
 		  str = all_items(theFile, fileHash, 0);
-		  sh_error_handle (level, FIL__, __LINE__, 0, 
-				   MSG_FI_MISS2, tmp, str);
+		  if (!sh_global_check_silent)
+		    sh_error_handle (level, FIL__, __LINE__, 0, 
+				     MSG_FI_MISS2, tmp, str);
 		  ++sh.statistics.files_report;
 		  SH_FREE(str);
@@ -405,6 +407,7 @@
 	  theFile = sh_hash_create_ft (p, fileHash);
 	  str = all_items(theFile, fileHash, 0);
-	  sh_error_handle (level, FIL__, __LINE__, 0, 
-			   MSG_FI_MISS2, tmp, str);
+	  if (!sh_global_check_silent)
+	    sh_error_handle (level, FIL__, __LINE__, 0, 
+			     MSG_FI_MISS2, tmp, str);
 	  ++sh.statistics.files_report;
 	  SH_FREE(str);
@@ -1812,7 +1815,8 @@
       str = all_items (theFile, fileHash, 1);
       
-      sh_error_handle (log_severity, FIL__, __LINE__, 0, 
-		       MSG_FI_ADD2, 
-		       tmp, str);
+      if (!sh_global_check_silent)
+	sh_error_handle (log_severity, FIL__, __LINE__, 0, 
+			 MSG_FI_ADD2, 
+			 tmp, str);
       ++sh.statistics.files_report;
       SH_FREE(str);
@@ -2540,6 +2544,11 @@
 	{
 	  char result[256];
-
-	  if (NULL != sh_audit_fetch (theFile->fullpath, theFile->mtime, result, sizeof(result)))
+	  
+	  sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 
+			   0, MSG_E_SUBGPATH,
+			   _("Fetching audit record"),
+			   _("sh_hash"),  theFile->fullpath );
+
+	  if (NULL != sh_audit_fetch (theFile->fullpath, theFile->mtime, theFile->ctime, result, sizeof(result)))
 	    {
 #ifdef SH_USE_XML
@@ -2565,8 +2574,9 @@
        ****************************************************/
       tmp_path = sh_util_safe_name(theFile->fullpath);
-      sh_error_handle(log_severity, FIL__, __LINE__, 
-		      (long) modi_mask, MSG_FI_CHAN,
-		      (policy_override == NULL) ? _(policy[class]):log_policy,
-		      change_code, tmp_path, msg);
+      if (!sh_global_check_silent)
+	sh_error_handle(log_severity, FIL__, __LINE__, 
+			(long) modi_mask, MSG_FI_CHAN,
+			(policy_override == NULL) ? _(policy[class]):log_policy,
+			change_code, tmp_path, msg);
       ++sh.statistics.files_report;
 
Index: trunk/src/sh_readconf.c
===================================================================
--- trunk/src/sh_readconf.c	(revision 487)
+++ trunk/src/sh_readconf.c	(revision 488)
@@ -871,4 +871,5 @@
 extern int sh_set_schedule_one(const char * str);
 extern int sh_set_schedule_two(const char * str);
+extern int sh_set_silent_full (const char * str);
 #endif
 #if defined (SH_WITH_SERVER)
@@ -1101,4 +1102,7 @@
   { N_("setprelinkchecksum"),   SH_SECTION_MISC,   SH_SECTION_NONE, 
     sh_prelink_set_hash },
+
+  { N_("setfullsilent"),        SH_SECTION_MISC,   SH_SECTION_NONE, 
+    sh_set_silent_full },
 
   /* client or standalone
Index: trunk/src/sh_unix.c
===================================================================
--- trunk/src/sh_unix.c	(revision 487)
+++ trunk/src/sh_unix.c	(revision 488)
@@ -666,4 +666,8 @@
     sig_force_check = 1; sh_sem_trylock(); }
 #endif
+#ifdef SIGTSTP
+  if (mysignal == SIGTSTP) {
+    sig_force_check = 1; sig_force_silent = 1; sh_sem_trylock(); }
+#endif
 #ifdef SIGTTIN
   if (mysignal == SIGTTIN)
@@ -841,7 +845,4 @@
   retry_sigaction(FIL__, __LINE__, SIGALRM,   &ignact, &oldact);
 #endif
-#ifdef SIGTSTP
-  retry_sigaction(FIL__, __LINE__, SIGTSTP,   &ignact, &oldact);
-#endif
 
 #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
@@ -852,4 +853,10 @@
     retry_sigaction(FIL__, __LINE__, SIGTTOU,   &ignact, &oldact);
 #endif
+#ifdef SIGTSTP
+  if (goDaemon == 1)
+    retry_sigaction(FIL__, __LINE__, SIGTSTP,     &act2, &oldact);
+  else
+    retry_sigaction(FIL__, __LINE__, SIGTSTP,   &ignact, &oldact);
+#endif
 #ifdef SIGTTIN
   if (goDaemon == 1)
@@ -859,4 +866,7 @@
 #endif
 #else
+#ifdef SIGTSTP
+  retry_sigaction(FIL__, __LINE__, SIGTSTP,   &ignact, &oldact);
+#endif
 #ifdef SIGTTOU
   retry_sigaction(FIL__, __LINE__, SIGTTOU,   &ignact, &oldact);
