Index: /trunk/Makefile.in
===================================================================
--- /trunk/Makefile.in	(revision 274)
+++ /trunk/Makefile.in	(revision 275)
@@ -160,5 +160,5 @@
 	$(srcsrc)/sh_pthread.c $(srcsrc)/sh_string.c \
 	$(srcsrc)/sh_log_parse_syslog.c $(srcsrc)/sh_log_parse_pacct.c \
-	$(srcsrc)/sh_log_parse_samba.c \
+	$(srcsrc)/sh_log_parse_samba.c $(srcsrc)/sh_log_parse_generic.c \
 	$(srcsrc)/sh_log_parse_apache.c $(srcsrc)/sh_log_evalrule.c \
 	$(srcsrc)/sh_log_correlate.c $(srcsrc)/sh_log_mark.c \
@@ -181,4 +181,5 @@
 	sh_log_parse_syslog.o sh_log_parse_pacct.o sh_log_parse_apache.o \
 	sh_log_parse_samba.o sh_log_evalrule.o sh_log_check.o \
+	sh_log_parse_generic.o \
 	sh_log_correlate.o sh_log_mark.o sh_log_repeat.o \
 	sh_pthread.o sh_string.o sh_inotify.o dnmalloc.o
@@ -1733,5 +1734,5 @@
 sh_log_parse_apache.o: $(srcsrc)/sh_log_parse_apache.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
 sh_log_evalrule.o: $(srcsrc)/sh_log_evalrule.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/zAVLTree.h 
-sh_log_check.o: $(srcsrc)/sh_log_check.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/sh_modules.h 
+sh_log_check.o: $(srcsrc)/sh_log_check.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h 
 sh_log_parse_samba.o: $(srcsrc)/sh_log_parse_samba.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
 sh_nmail.o: $(srcsrc)/sh_nmail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_mail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_string.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/zAVLTree.h 
@@ -1741,2 +1742,3 @@
 sh_log_mark.o: $(srcsrc)/sh_log_mark.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_string.h $(srcinc)/sh_error_min.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/zAVLTree.h 
 sh_log_repeat.o: $(srcsrc)/sh_log_repeat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h 
+sh_log_parse_generic.o: $(srcsrc)/sh_log_parse_generic.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 274)
+++ /trunk/configure.ac	(revision 275)
@@ -12,5 +12,5 @@
 dnl start
 dnl
-AM_INIT_AUTOMAKE(samhain, 2.6.2)
+AM_INIT_AUTOMAKE(samhain, 2.6.3)
 AC_DEFINE([SAMHAIN], 1, [Application is samhain])
 AC_CANONICAL_HOST
Index: /trunk/depend.dep
===================================================================
--- /trunk/depend.dep	(revision 274)
+++ /trunk/depend.dep	(revision 275)
@@ -73,5 +73,5 @@
 sh_log_parse_apache.o: $(srcsrc)/sh_log_parse_apache.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
 sh_log_evalrule.o: $(srcsrc)/sh_log_evalrule.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/zAVLTree.h 
-sh_log_check.o: $(srcsrc)/sh_log_check.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/sh_modules.h 
+sh_log_check.o: $(srcsrc)/sh_log_check.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/sh_log_correlate.h $(srcinc)/sh_log_mark.h $(srcinc)/sh_log_repeat.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h 
 sh_log_parse_samba.o: $(srcsrc)/sh_log_parse_samba.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
 sh_nmail.o: $(srcsrc)/sh_nmail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_mail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_string.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/zAVLTree.h 
@@ -81,2 +81,3 @@
 sh_log_mark.o: $(srcsrc)/sh_log_mark.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mem.h $(srcinc)/sh_string.h $(srcinc)/sh_error_min.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h $(srcinc)/zAVLTree.h 
 sh_log_repeat.o: $(srcsrc)/sh_log_repeat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h 
+sh_log_parse_generic.o: $(srcsrc)/sh_log_parse_generic.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
Index: /trunk/depend.sum
===================================================================
--- /trunk/depend.sum	(revision 274)
+++ /trunk/depend.sum	(revision 275)
@@ -1,1 +1,1 @@
-2302754398
+315325077
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 274)
+++ /trunk/docs/Changelog	(revision 275)
@@ -1,2 +1,7 @@
+2.6.3:
+	* Fix bug in mail module, recipients incorrectly flagged
+	  as aliases, which breaks immediate mail for 'alert'
+	  (reported by Jesse)
+	
 2.6.2:
 	* Makefile.in: fix problem in deploy system caused
Index: /trunk/include/sh_extern.h
===================================================================
--- /trunk/include/sh_extern.h	(revision 274)
+++ /trunk/include/sh_extern.h	(revision 275)
@@ -35,4 +35,10 @@
  */
 int sh_ext_popen (sh_tas_t * task);
+
+/*
+ * -- generic simple safe popen; returns 0 on success, -1 otherwise,
+ *    executes shell command
+ */
+int sh_ext_popen_init (sh_tas_t * task, char * command);
 
 /*
Index: /trunk/include/sh_log_check.h
===================================================================
--- /trunk/include/sh_log_check.h	(revision 274)
+++ /trunk/include/sh_log_check.h	(revision 275)
@@ -26,4 +26,5 @@
 #define SH_LOGFILE_REWIND (1<<1)
 #define SH_LOGFILE_PIPE   (1<<2)
+#define SH_LOGFILE_NOFILE (1<<3)
 
 struct sh_logfile 
@@ -52,4 +53,13 @@
 };
 
+/* Generic callback function to parse fileinfo. 
+ */
+void * sh_eval_fileinfo_generic(char * str);
+
+/* Generic parser info. 
+ */
+struct sh_logrecord * sh_parse_generic (sh_string * logline, void * fileinfo);
+
+
 /****************************************************************
  **
@@ -59,4 +69,11 @@
 /* Open file, position at stored offset. */
 int sh_open_for_reader (struct sh_logfile * logfile);
+
+/* Simple line reader for executed shell command   */ 
+sh_string * sh_command_reader (sh_string * record, 
+			       struct sh_logfile * logfile);
+
+/* Wrapper for sh_command_reader */
+sh_string * sh_read_shell (sh_string * record, struct sh_logfile * logfile);
 
 /* Simple line reader.   */ 
Index: /trunk/src/sh_extern.c
===================================================================
--- /trunk/src/sh_extern.c	(revision 274)
+++ /trunk/src/sh_extern.c	(revision 275)
@@ -809,4 +809,34 @@
 }
 
+int sh_ext_popen_init (sh_tas_t * task, char * command)
+{
+  int status;
+
+  sh_ext_tas_init(task);
+
+  (void) sh_ext_tas_add_envv (task, _("SHELL"), 
+			      _("/bin/sh")); 
+  (void) sh_ext_tas_add_envv (task, _("PATH"),  
+			      _("/sbin:/bin:/usr/sbin:/usr/bin:/usr/ucb")); 
+  (void) sh_ext_tas_add_envv (task, _("IFS"), " \n\t"); 
+  if (sh.timezone != NULL)
+    {
+      (void) sh_ext_tas_add_envv(task,  "TZ", sh.timezone);
+    }
+  
+  sh_ext_tas_command(task,  _("/bin/sh"));
+
+  (void) sh_ext_tas_add_argv(task,  _("/bin/sh"));
+  (void) sh_ext_tas_add_argv(task,  _("-c"));
+  (void) sh_ext_tas_add_argv(task,  command);
+  
+  task->rw = 'r';
+  task->fork_twice = S_FALSE;
+
+  status = sh_ext_popen(task);
+
+  return status;
+}
+
 /* Execute command, return first line of output
  * ifconfig | grep -1 lo | tail -n 1 | sed s/.*inet addr:\([0-9.]*\)\(.*\)/\1/
@@ -822,39 +852,18 @@
   SL_ENTER(_("sh_ext_popen_str"));
 
-  sh_ext_tas_init(&task);
-
-  (void) sh_ext_tas_add_envv (&task, _("SHELL"), 
-			      _("/bin/sh")); 
-  (void) sh_ext_tas_add_envv (&task, _("PATH"),  
-			      _("/sbin:/bin:/usr/sbin:/usr/bin:/usr/ucb")); 
-  (void) sh_ext_tas_add_envv (&task, _("IFS"), " \n\t"); 
-  if (sh.timezone != NULL)
-    {
-      (void) sh_ext_tas_add_envv(&task,  "TZ", sh.timezone);
-    }
-  
-  sh_ext_tas_command(&task,  _("/bin/sh"));
-
-  (void) sh_ext_tas_add_argv(&task,  _("/bin/sh"));
-  (void) sh_ext_tas_add_argv(&task,  _("-c"));
-  (void) sh_ext_tas_add_argv(&task,  command);
-  
-  task.rw = 'r';
-  task.fork_twice = S_FALSE;
-
-  status = sh_ext_popen(&task);
+  status = sh_ext_popen_init (&task, command);
 
   if (status != 0)
     {
       sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 
-		      _("Could not open pipe"), _("sh_ext_popen_str"));
+                      _("Could not open pipe"), _("sh_ext_popen_str"));
       SL_RETURN ((NULL), _("sh_ext_popen_str"));
     }
 
-  /* ignore SIGPIPE (instead get EPIPE if connection is closed)
-   */
-  new_act.sa_handler = SIG_IGN;
-  (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
-
+   /* ignore SIGPIPE (instead get EPIPE if connection is closed)
+    */
+   new_act.sa_handler = SIG_IGN;
+   (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
+   
   /* read from the open pipe
    */
Index: /trunk/src/sh_log_check.c
===================================================================
--- /trunk/src/sh_log_check.c	(revision 274)
+++ /trunk/src/sh_log_check.c	(revision 275)
@@ -39,4 +39,5 @@
 #include "sh_log_mark.h"
 #include "sh_log_repeat.h"
+#include "sh_extern.h"
 
 /* List of supported logfile types, format is
@@ -57,4 +58,5 @@
     {  "PACCT",  sh_read_pacct,   sh_parse_pacct,  NULL },
 #endif
+    {  "SHELL",  sh_read_shell,   sh_parse_generic,  sh_eval_fileinfo_generic },
 };
 
@@ -237,5 +239,5 @@
     }
 
-  if (splits[1][0] != '/')
+  if (splits[1][0] != '/' && 0 != strcmp(splits[0], _("SHELL")))
     {
       sh_string * msg =  sh_string_new(0);
@@ -258,5 +260,8 @@
 
   thisfile->filename     = filename;
-  thisfile->flags        = SH_LOGFILE_REWIND;
+  if (strcmp(splits[0], _("SHELL")))
+    thisfile->flags        = SH_LOGFILE_NOFILE;
+  else
+    thisfile->flags        = SH_LOGFILE_REWIND;
   thisfile->inode        = 0;
   thisfile->device_id    = 0;
@@ -323,44 +328,47 @@
   /* Try reading saved offset. On success clear rewind flag.
    */
-  if (0 == stat(thisfile->filename, &buf))
-    {
-      if (S_ISREG(buf.st_mode)
+  if ((thisfile->flags & SH_LOGFILE_NOFILE) == 0)
+    {
+      if (0 == stat(thisfile->filename, &buf))
+	{
+	  if (S_ISREG(buf.st_mode)
 #ifdef S_ISLNK
-	  || S_ISLNK(buf.st_mode)
+	      || S_ISLNK(buf.st_mode)
 #endif 
-	  )
-	{
-	  thisfile->inode     = buf.st_ino;
-	  thisfile->device_id = buf.st_dev;
+	      )
+	    {
+	      thisfile->inode     = buf.st_ino;
+	      thisfile->device_id = buf.st_dev;
+	      
+	      if (0 != read_pos(thisfile))
+		{
+		  thisfile->flags &= ~SH_LOGFILE_REWIND;
+		}
+	    }
+	  else if (S_ISFIFO(buf.st_mode))
+	    {
+	      thisfile->inode      = buf.st_ino;
+	      thisfile->device_id  = buf.st_dev;
+	      thisfile->flags     |= SH_LOGFILE_PIPE;
+	    }
+	}
+      else
+	{
+	  sh_string * msg =  sh_string_new(0);
+	  sh_string_add_from_char(msg, _("Logfile is not a regular file, link, or named pipe: "));
+	  sh_string_add_from_char(msg, splits[1]);
 	  
-	  if (0 != read_pos(thisfile))
-	    {
-	      thisfile->flags &= ~SH_LOGFILE_REWIND;
-	    }
-	}
-      else if (S_ISFIFO(buf.st_mode))
-	{
-	  thisfile->inode      = buf.st_ino;
-	  thisfile->device_id  = buf.st_dev;
-	  thisfile->flags     |= SH_LOGFILE_PIPE;
-	}
-    }
-  else
-    {
-      sh_string * msg =  sh_string_new(0);
-      sh_string_add_from_char(msg, _("Logfile is not a regular file, link, or named pipe: "));
-      sh_string_add_from_char(msg, splits[1]);
-      
-      SH_MUTEX_LOCK(mutex_thread_nolog);
-      sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
-		      sh_string_str(msg),
-		      _("sh_add_watch"));
-      SH_MUTEX_UNLOCK(mutex_thread_nolog);
-      sh_string_destroy(&msg);
-      
-      SH_FREE(filename);
-      SH_FREE(thisfile);
-      SH_FREE(new);
-      return -1;
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
+	  sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
+			  sh_string_str(msg),
+			  _("sh_add_watch"));
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
+	  sh_string_destroy(&msg);
+	  
+	  SH_FREE(filename);
+	  SH_FREE(thisfile);
+	  SH_FREE(new);
+	  return -1;
+	}
     }
 
@@ -380,11 +388,16 @@
       sh_watched_logs = thisfile->next;
 
-      if ((thisfile->flags & SH_LOGFILE_PIPE) == 0)
+      if ((thisfile->flags & SH_LOGFILE_NOFILE) == 0 &&
+	  (thisfile->flags & SH_LOGFILE_PIPE) == 0)
 	{
 	  save_pos(thisfile);
 	}
 
-      if (thisfile->fp)
-	sl_fclose(FIL__, __LINE__, thisfile->fp);
+      if ((thisfile->flags & SH_LOGFILE_NOFILE) == 0)
+	{
+	  if (thisfile->fp)
+	    sl_fclose(FIL__, __LINE__, thisfile->fp);
+	}
+
       if (thisfile->filename)
 	SH_FREE(thisfile->filename);
@@ -677,5 +690,5 @@
 sh_string * sh_default_reader (sh_string * s, struct sh_logfile * logfile)
 {
-  int         status;
+  volatile int         status;
   char * tmp;
 
@@ -712,4 +725,70 @@
   if (0 != sh_open_for_reader(logfile))
     goto start_read;
+
+  return NULL;
+}
+
+sh_string * sh_command_reader (sh_string * s, struct sh_logfile * logfile)
+{
+  sh_tas_t task;
+  struct  sigaction  new_act;
+  struct  sigaction  old_act;
+
+  volatile int         status;
+  char * tmp;
+
+ start_read:
+
+  if (logfile->fp)
+    {
+      /* ignore SIGPIPE (instead get EPIPE if connection is closed)
+       */
+      new_act.sa_handler = SIG_IGN;
+      (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
+
+      /* Result cannot be larger than 8192, thus cast is ok
+       */
+      status = (int) sh_string_read(s, logfile->fp, 8192);
+
+      /* restore old signal handler
+       */
+      (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &old_act, NULL);
+
+      if (status <= 0)
+	{
+	  sh_ext_pclose (&task);
+	  logfile->fp = NULL;
+	  sh_string_destroy(&s);
+
+	  if (status == 0)
+	    {
+	      return NULL;
+	    }
+
+	  SH_MUTEX_LOCK(mutex_thread_nolog);
+	  tmp = sh_util_safe_name (logfile->filename);
+	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_LOGMON_EREAD,
+			  tmp);
+	  SH_FREE(tmp);
+	  SH_MUTEX_UNLOCK(mutex_thread_nolog);
+
+	  return NULL;
+	}
+      return s;
+    }
+
+  status = sh_ext_popen_init (&task, logfile->filename);
+  if (0 == status)
+    {
+      logfile->fp = task.pipe;
+      goto start_read;
+    }
+  else
+    {
+      SH_MUTEX_LOCK(mutex_thread_nolog);
+      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 
+                      _("Could not open pipe"), _("sh_command reader"));
+      SH_MUTEX_UNLOCK(mutex_thread_nolog);
+    }
 
   return NULL;
Index: /trunk/src/sh_mail.c
===================================================================
--- /trunk/src/sh_mail.c	(revision 274)
+++ /trunk/src/sh_mail.c	(revision 275)
@@ -581,5 +581,5 @@
 	    ++failcount;
 	    
-	    SL_RETURN((-1), _("sh_mail_msg"));
+	    SL_RETURN((-2), _("sh_mail_msg"));
 	  }
 	else
@@ -816,5 +816,5 @@
       {
 	rollback_list(fifo_mail);
-	retval = -1;
+	retval = -3;
       }
     else
Index: /trunk/src/sh_nmail.c
===================================================================
--- /trunk/src/sh_nmail.c	(revision 274)
+++ /trunk/src/sh_nmail.c	(revision 275)
@@ -108,5 +108,5 @@
 
       SH_MUTEX_LOCK_UNSAFE(mutex_listall);
-      if (0 == check_double(str, all_recipients, S_TRUE))
+      if (0 != check_double(str, all_recipients, S_TRUE))
 	{
 	  new->isAlias    = 1;
@@ -207,5 +207,5 @@
 	      for (i = 0; i < nfields; ++i) {
 		if (0 == check_double(array[i],  all_recipients, S_TRUE))
-		  nflag = 1;
+		  nflag = 1; /* not in all_recipients --> bad */
 	      }
 
@@ -406,5 +406,7 @@
 	       */
 	      if (flagit && list->isAlias == 0)
-		list->send_mail = 1;
+		{
+		  list->send_mail = 1;
+		}
 	      list = list->all_next;
 	    }
@@ -518,4 +520,8 @@
 	  if (retval != 0)
 	    {
+	      sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
+			       retval, MSG_E_SUBGEN,
+			       _("could not mail immediately"),
+			       _("sh_nmail_msg") );
 	      sh_mail_pushstack(level, message, alias);
 	    }
