Index: /trunk/Makefile.in
===================================================================
--- /trunk/Makefile.in	(revision 214)
+++ /trunk/Makefile.in	(revision 215)
@@ -111,5 +111,5 @@
 HEADERS = samhain.h sh_unix.h sh_utils.h sh_error.h sh_error_min.h sh_files.h \
 	sh_getopt.h sh_readconf.h sh_tiger.h sh_hash.h \
-	sh_mail.h sh_mail_int.h sh_nmail.h \
+	sh_mail.h sh_mail_int.h sh_nmail.h sh_filter.h \
 	sh_mem.h sh_entropy.h sh_forward.h sh_modules.h sh_utmp.h \
 	sh_kern.h sh_suidchk.h sh_srp.h sh_fifo.h sh_html.h sh_tools.h \
@@ -153,5 +153,5 @@
 	$(srcsrc)/sh_prelink.c $(srcsrc)/sh_static.c \
 	$(srcsrc)/sh_portcheck.c $(srcsrc)/sh_port2proc.c\
-	$(srcsrc)/sh_processcheck.c \
+	$(srcsrc)/sh_processcheck.c $(srcsrc)/sh_filter.c \
 	$(srcsrc)/sh_pthread.c $(srcsrc)/sh_string.c \
 	$(srcsrc)/sh_log_parse_syslog.c $(srcsrc)/sh_log_parse_pacct.c \
@@ -163,5 +163,5 @@
 OBJECTS = sh_files.o sh_tiger0.o sh_tiger2.o sh_tiger2_64.o \
 	samhain.o sh_unix.o sh_utils.o sh_error.o \
-	sh_getopt.o sh_readconf.o \
+	sh_getopt.o sh_readconf.o sh_filter.o \
 	sh_hash.o sh_mail.o sh_nmail.o sh_mem.o \
 	sh_entropy.o sh_forward.o sh_modules.o sh_utmp.o sh_kern.o \
@@ -1666,5 +1666,5 @@
 sh_tiger2_64.o: $(srcsrc)/sh_tiger2_64.c Makefile config_xor.h 
 sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/sh_hash.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h 
-sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
+sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
 sh_mem.o: $(srcsrc)/sh_mem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_pthread.h 
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
@@ -1681,5 +1681,5 @@
 sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h 
 sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h 
-sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_static.h 
+sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_filter.h $(srcinc)/sh_static.h 
 sh_database.o: $(srcsrc)/sh_database.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h 
 sh_err_log.o: $(srcsrc)/sh_err_log.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h 
@@ -1725,3 +1725,4 @@
 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_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.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_mail_int.h $(srcinc)/zAVLTree.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 
+sh_filter.o: $(srcsrc)/sh_filter.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_filter.h 
Index: /trunk/depend.dep
===================================================================
--- /trunk/depend.dep	(revision 214)
+++ /trunk/depend.dep	(revision 215)
@@ -14,5 +14,5 @@
 sh_tiger2_64.o: $(srcsrc)/sh_tiger2_64.c Makefile config_xor.h 
 sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/sh_hash.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h 
-sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
+sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
 sh_mem.o: $(srcsrc)/sh_mem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_pthread.h 
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
@@ -29,5 +29,5 @@
 sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h 
 sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h 
-sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_static.h 
+sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_filter.h $(srcinc)/sh_static.h 
 sh_database.o: $(srcsrc)/sh_database.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h 
 sh_err_log.o: $(srcsrc)/sh_err_log.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h 
@@ -75,3 +75,4 @@
 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_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.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_mail_int.h $(srcinc)/zAVLTree.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 
+sh_filter.o: $(srcsrc)/sh_filter.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_filter.h 
Index: /trunk/depend.sum
===================================================================
--- /trunk/depend.sum	(revision 214)
+++ /trunk/depend.sum	(revision 215)
@@ -1,1 +1,1 @@
-1874099800
+3041707433
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 214)
+++ /trunk/docs/Changelog	(revision 215)
@@ -1,3 +1,5 @@
 2.5.3:
+	* allow POSIX regexes for filters
+	* consolidate filtering code from sh_extern.c, sh_(n)mail.c
 	* rewrite mail subsystem to allow individual filtering
 	  for recipients
Index: /trunk/include/sh_string.h
===================================================================
--- /trunk/include/sh_string.h	(revision 214)
+++ /trunk/include/sh_string.h	(revision 215)
@@ -80,4 +80,8 @@
 char ** split_array_ws(char *line, unsigned int * nfields, size_t * lengths);
 
+/* Same as above, but split on [space, tab, comma]
+ */ 
+char ** split_array_list(char *line, unsigned int * nfields, size_t * lengths);
+
 /* Replaces fields in s with 'replacement'. Fields are given
  * in the ordered array ovector, comprising ovecnum pairs 
Index: /trunk/src/samhain.c
===================================================================
--- /trunk/src/samhain.c	(revision 214)
+++ /trunk/src/samhain.c	(revision 215)
@@ -746,4 +746,7 @@
 #if defined(SH_WITH_SERVER)
   sh_forward_free_all ();
+#endif
+#if defined(SH_WITH_MAIL)
+  sh_nmail_free();
 #endif
   delete_cache();
@@ -1749,4 +1752,8 @@
 	      (void) sh_ext_cleanup();
 #endif
+#if defined(SH_WITH_MAIL)
+	      sh_nmail_free();
+#endif
+
 	      /* delete the file list, make all database
 	       * entries visible (allignore = FALSE)
Index: /trunk/src/sh_extern.c
===================================================================
--- /trunk/src/sh_extern.c	(revision 214)
+++ /trunk/src/sh_extern.c	(revision 215)
@@ -92,4 +92,5 @@
 #include "sh_extern.h"
 #include "sh_calls.h"
+#include "sh_filter.h"
 #define SH_NEED_PWD_GRP 1
 #include "sh_static.h"
@@ -867,10 +868,6 @@
   char     type[4];
 
-  int      for_c;
-  char   * for_v[32];
-  int      fand_c;
-  char   * fand_v[32];
-  int      fnot_c;
-  char   * fnot_v[32];
+  sh_filter_type * filter;
+
   time_t   deadtime;
   time_t   last_run;
@@ -900,5 +897,4 @@
 sh_com_t * command_init(void)
 {
-  int         i;
   uid_t       ff_euid;
   sh_com_t  * ext_com = NULL;
@@ -924,16 +920,8 @@
 
   set3(ext_com->type, 'l', 'o', 'g');
-  ext_com->for_c        = 0;
-  ext_com->fand_c       = 0;
-  ext_com->fnot_c       = 0;
+  ext_com->filter       = NULL;
   ext_com->deadtime     = 0;
   ext_com->last_run     = 0;
 
-  for (i = 0; i < 32; ++i)
-    {
-      ext_com->for_v[i]         = NULL;
-      ext_com->fand_v[i]        = NULL;
-      ext_com->fnot_v[i]        = NULL;
-    }
   ext_com->next             = NULL;
 
@@ -1128,5 +1116,4 @@
 int sh_ext_cleanup(void)
 {
-  int i;
   sh_com_t * retval;
 
@@ -1140,10 +1127,6 @@
       sh_ext_tas_free (&(retval->tas));
 
-      for (i = 0; i < 32; ++i)
-	{
-	  if (NULL != retval->for_v[i])  SH_FREE(retval->for_v[i]);
-	  if (NULL != retval->fand_v[i]) SH_FREE(retval->fand_v[i]);
-	  if (NULL != retval->fnot_v[i]) SH_FREE(retval->fnot_v[i]);
-	}
+      if (retval->filter)
+	sh_filter_free (retval->filter);
 
       SH_FREE(retval);
@@ -1173,5 +1156,7 @@
   if (ext_coms == NULL || ext_failed == (-1))
     return (-1);
-  return (sh_ext_add (str, &(ext_coms->for_c), ext_coms->for_v));
+  if (ext_coms->filter == NULL)
+    ext_coms->filter = sh_filter_alloc();
+  return (sh_filter_add(str, ext_coms->filter, SH_FILT_OR));
 }
 
@@ -1183,5 +1168,7 @@
   if (ext_coms == NULL || ext_failed == (-1))
     return (-1);
-  return (sh_ext_add (str, &(ext_coms->fand_c), ext_coms->fand_v));
+  if (ext_coms->filter == NULL)
+    ext_coms->filter = sh_filter_alloc();
+  return (sh_filter_add(str, ext_coms->filter, SH_FILT_AND));
 }
 
@@ -1193,5 +1180,7 @@
   if (ext_coms == NULL || ext_failed == (-1))
     return (-1);
-  return (sh_ext_add (str, &(ext_coms->fnot_c), ext_coms->fnot_v));
+  if (ext_coms->filter == NULL)
+    ext_coms->filter = sh_filter_alloc();
+  return (sh_filter_add(str, ext_coms->filter, SH_FILT_NOT));
 }
 
@@ -1354,55 +1343,19 @@
 static int sh_ext_filter (char * message, sh_com_t * task)
 {
-  int i;
-  int j = 0;
   time_t now_time;
 
   SL_ENTER(_("sh_ext_filter"));
 
-  /* Presence of any of these keywords prevents execution.
-   */
-  if (task->fnot_c > 0)
-    {
-      for (i = 0; i < task->fnot_c; ++i)
+  if (task->filter)
+    {
+      if (0 != sh_filter_filter (message, task->filter))
 	{
-	  if (NULL != sl_strstr(message, task->fnot_v[i]))
-	    {
-	      SL_RETURN ((-1), _("sh_ext_filter"));
-	    }
+	  SL_RETURN ((-1), _("sh_ext_filter"));
 	}
     }
 
-  /* Presence of all of these keywords is required for execution.
-   */
-  if (task->fand_c > 0)
-    {
-      j = 0;
-
-      for (i = 0; i < task->fand_c; ++i)
-	{
-	  if (NULL == sl_strstr(message, task->fand_v[i]))
-	    {
-	      SL_RETURN ((-1), _("sh_ext_filter"));
-	    }
-	}
-
-    }
-
-  /* Presence of at least one of these keywords is required for execution.
-   */
-  if (task->for_c > 0)
-    {
-      for (i = 0; i < task->for_c; ++i)
-	{
-	  if (NULL != sl_strstr(message, task->for_v[i]))
-	    {
-	      goto checkdeadtime;
-	    }
-	}
-      SL_RETURN ((-1), _("sh_ext_filter"));
-    }
-
- checkdeadtime:
-  if (task->deadtime != (time_t) 0)   /* deadtime */
+  /* Filter passed, check deadtime */
+
+  if (task->deadtime != (time_t) 0)
     {
       now_time = time (NULL);
Index: /trunk/src/sh_forward.c
===================================================================
--- /trunk/src/sh_forward.c	(revision 214)
+++ /trunk/src/sh_forward.c	(revision 215)
@@ -5056,4 +5056,7 @@
 	    (void) sh_ext_cleanup();
 #endif
+#if defined(SH_WITH_MAIL)
+	      sh_nmail_free();
+#endif
 	    /* - mark all clients dead
 	     * - read configuration file
Index: /trunk/src/sh_mail.c
===================================================================
--- /trunk/src/sh_mail.c	(revision 214)
+++ /trunk/src/sh_mail.c	(revision 215)
@@ -59,4 +59,5 @@
 #include "sh_tools.h"
 #include "sh_pthread.h"
+#include "sh_filter.h"
 #include "sh_mail_int.h"
 #include "sh_nmail.h"
@@ -245,186 +246,4 @@
 
   /*@notreached@*/
-}
-
-void sh_filter_filterfree (sh_filter_type * filter)
-{
-  int i;
-
-  if (filter)
-    {
-      for (i = 0; i < filter->for_c; ++i) {
-	if (filter->for_v[i])
-	  SH_FREE(filter->for_v[i]);
-	filter->for_v[i] = NULL; 
-      }
-      filter->for_c = 0;
-      for (i = 0; i < filter->fand_c; ++i) {
-	if (filter->fand_v[i])
-	  SH_FREE(filter->fand_v[i]);
-	filter->fand_v[i] = NULL; 
-      }
-      filter->fand_c = 0;
-      for (i = 0; i < filter->fnot_c; ++i) {
-	if (filter->fnot_v[i])
-	  SH_FREE(filter->fnot_v[i]);
-	filter->fnot_v[i] = NULL; 
-      }
-      filter->fnot_c = 0;
-    }
-}
-
-int sh_filter_filteradd (const char * argstring, 
-			 sh_filter_type * filter, int ftype)
-{
-  int     i = 0;
-  int     flag = 0;
-  size_t  s;
-
-  char  * dupp;
-  char  * p;
-  char  * end;
-  int   * ntok;
-  char ** stok;
-
-  SL_ENTER(_("sh_filter_filteradd"));
-
-  if (NULL == argstring)
-    {
-      SL_RETURN((-1), _("sh_filter_filteradd")); 
-    }
-
-  if (ftype == SH_FILT_OR) {
-    ntok = &(filter->for_c);
-    stok = filter->for_v;
-  }
-  else if (ftype == SH_FILT_AND) {
-    ntok = &(filter->fand_c);
-    stok = filter->fand_v;
-  }
-  else if (ftype == SH_FILT_NOT) {
-    ntok = &(filter->fnot_c);
-    stok = filter->fnot_v;
-  }
-  else {
-    SL_RETURN((-1), _("sh_filter_filteradd")); 
-  }
-
-  *ntok = 0;
-
-  dupp = sh_util_strdup(argstring);
-  p   = dupp;
-
-  do
-    {
-      while (*p == ',' || *p == ' ' || *p == '\t')
-	++p;
-      if (*p == '\0')
-	break;
-
-      end = p; ++end;
-      if (*end == '\0')
-	break;
-
-      if (*p == '\'')
-	{
-	  ++p; end = p; ++end;
-	  if (*p == '\0' || *end == '\0')
-	    break;
-	  while (*end != '\0' && *end != '\'')
-	    ++end;
-	}
-      else if (*p == '"')
-	{
-	  ++p; end = p; ++end;
-	  if (*p == '\0' || *end == '\0')
-	    break;
-	  while (*end != '\0' && *end != '"')
-	    ++end;
-	}
-      else
-	{
-	  while (*end != '\0' && *end != ',' && *end != ' ' && *end != '\t')
-	    ++end;
-	}
-      if (*end == '\0')
-	flag = 1;
-      else
-	*end = '\0';
-
-      s = strlen(p) + 1;
-      if (stok[i] != NULL)
-	SH_FREE(stok[i]);
-      stok[i] = SH_ALLOC(s);
-      (void) sl_strlcpy(stok[i], p, s);
-
-      p = end; ++p;
-
-      ++i;
-      if (i == SH_FILT_NUM)
-	break;
-    }
-  while (p != NULL && *p != '\0' && flag == 0);
-
-  *ntok = i;
-  SH_FREE(dupp);
-
-  SL_RETURN (0, _("sh_filter_filteradd"));
-}
-
-/*
- * -- Check filters. Returns 0 if message passes.
- */ 
-int sh_filter_filter (const char * message, sh_filter_type * filter)
-{
-  int i;
-
-  SL_ENTER(_("sh_filter_filter"));
-
-  if (filter)
-    {
-
-      /* Presence of any of these keywords prevents execution.
-       */
-      if (filter->fnot_c > 0)
-	{
-	  for (i = 0; i < filter->fnot_c; ++i)
-	    {
-	      if (NULL != sl_strstr(message, filter->fnot_v[i]))
-		{
-		  SL_RETURN ((-1), _("sh_filter_filter"));
-		}
-	    }
-	}
-      
-      /* Presence of all of these keywords is required for execution.
-       */
-      if (filter->fand_c > 0)
-	{
-	  for (i = 0; i < filter->fand_c; ++i)
-	    {
-	      if (NULL == sl_strstr(message, filter->fand_v[i]))
-		{
-		  SL_RETURN ((-1), _("sh_filter_filter"));
-		}
-	    }
-	}
-      
-      /* Presence of at least one of these keywords is required for execution.
-       */
-      if (filter->for_c > 0)
-	{
-	  for (i = 0; i < filter->for_c; ++i)
-	    {
-	      if (NULL != sl_strstr(message, filter->for_v[i]))
-		{
-		  goto isok;
-		}
-	    }
-	  SL_RETURN ((-1), _("sh_filter_filter"));
-	}
-    }
-
- isok:
-  SL_RETURN ((0), _("sh_filter_filter"));
 }
 
Index: /trunk/src/sh_readconf.c
===================================================================
--- /trunk/src/sh_readconf.c	(revision 214)
+++ /trunk/src/sh_readconf.c	(revision 215)
@@ -1107,4 +1107,6 @@
   { N_("setmailsender"),     SH_SECTION_MAIL,  SH_SECTION_MISC, 
     sh_mail_set_sender },
+  { N_("setmailalias"),       SH_SECTION_MAIL,  SH_SECTION_MISC, 
+    sh_nmail_add_alias },
   { N_("setmailaddress"),    SH_SECTION_MAIL,  SH_SECTION_MISC, 
     sh_nmail_add_recipient },
Index: /trunk/src/sh_string.c
===================================================================
--- /trunk/src/sh_string.c	(revision 214)
+++ /trunk/src/sh_string.c	(revision 215)
@@ -127,5 +127,11 @@
  * If nfields < actual fields, last string will be remainder.
  */
-char ** split_array_ws(char *line, unsigned int * nfields, size_t * lengths)
+
+#define SH_SPLIT_LIST 0
+#define SH_SPLIT_WS   1
+
+char ** split_array_ws_int (char *line, 
+			    unsigned int * nfields, size_t * lengths,
+			    int isList)
 {
   char *a, *e, *s;
@@ -144,10 +150,22 @@
       /* skip leading WS 
        */
-      if ( *s && isspace((int)*s) )
-        {
-          do {
-            ++s;
-          } while ( *s && isspace((int)*s) );
-        }
+      if (isList == SH_SPLIT_WS)
+	{
+	  if ( *s && isspace((int)*s) )
+	    {
+	      do {
+		++s;
+	      } while ( *s && isspace((int)*s) );
+	    }
+	}
+      else
+	{
+	  if ( *s && (*s == ' ' || *s == '\t' || *s == ','))
+	    {
+	      do {
+		++s;
+	      } while ( *s && (*s == ' ' || *s == '\t' || *s == ','));
+	    }
+	}
 
       if (*s)
@@ -157,7 +175,16 @@
            */
           a = s;
-          do {
-            a++;
-          } while ( *a && (!isspace((int)*a)) );
+	  if (isList == SH_SPLIT_WS)
+	    {
+	      do {
+		a++;
+	      } while ( *a && (!isspace((int)*a)) );
+	    }
+	  else
+	    {
+	      do {
+		a++;
+	      } while ( *a && (*a != ' ' && *a != '\t' && *a != ','));
+	    }
 
           /* next token, *a is either ws or '\0' 
@@ -201,4 +228,15 @@
 }
 
+char ** split_array_ws (char *line, 
+			unsigned int * nfields, size_t * lengths)
+{
+  return split_array_ws_int (line, nfields, lengths, SH_SPLIT_WS);
+}
+
+char ** split_array_list (char *line, 
+			  unsigned int * nfields, size_t * lengths)
+{
+  return split_array_ws_int (line, nfields, lengths, SH_SPLIT_LIST);
+}
 
 #define SH_STRING_PARCEL 120
