Index: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in	(revision 213)
+++ trunk/Makefile.in	(revision 214)
@@ -110,5 +110,6 @@
 
 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_getopt.h sh_readconf.h sh_tiger.h sh_hash.h \
+	sh_mail.h sh_mail_int.h sh_nmail.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 \
@@ -128,5 +129,5 @@
 	$(srcsrc)/sh_tiger1.c $(srcsrc)/sh_tiger2.c \
 	$(srcsrc)/sh_tiger1_64.c $(srcsrc)/sh_tiger2_64.c \
-	$(srcsrc)/sh_hash.c $(srcsrc)/sh_mail.c \
+	$(srcsrc)/sh_hash.c $(srcsrc)/sh_mail.c $(srcsrc)/sh_nmail.c \
 	$(srcsrc)/sh_mem.c $(srcsrc)/sh_entropy.c \
 	$(srcsrc)/sh_forward.c $(srcsrc)/sh_modules.c \
@@ -163,5 +164,5 @@
 	samhain.o sh_unix.o sh_utils.o sh_error.o \
 	sh_getopt.o sh_readconf.o \
-	sh_hash.o sh_mail.o sh_mem.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 \
 	sh_suidchk.o sh_srp.o sh_fifo.o sh_tools.o sh_html.o sh_gpg.o \
@@ -1652,11 +1653,11 @@
 
 
-samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_mail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
+samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
 sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
-sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
+sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_nmail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
 sh_files.o: $(srcsrc)/sh_files.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/zAVLTree.h 
 sh_getopt.o: $(srcsrc)/sh_getopt.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_getopt.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h 
-sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_database.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_files.h $(srcinc)/sh_mail.h $(srcinc)/sh_calls.h $(srcinc)/sh_tiger.h $(srcinc)/sh_forward.h $(srcinc)/sh_modules.h $(srcinc)/sh_gpg.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_extern.h $(srcinc)/sh_tools.h $(srcinc)/sh_database.h $(srcinc)/sh_prelude.h 
+sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_database.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_files.h $(srcinc)/sh_mail.h $(srcinc)/sh_nmail.h $(srcinc)/sh_calls.h $(srcinc)/sh_tiger.h $(srcinc)/sh_forward.h $(srcinc)/sh_modules.h $(srcinc)/sh_gpg.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_extern.h $(srcinc)/sh_tools.h $(srcinc)/sh_database.h $(srcinc)/sh_prelude.h 
 sh_tiger0.o: $(srcsrc)/sh_tiger0.c Makefile config_xor.h $(srcinc)/sh_tiger.h $(srcinc)/sh_unix.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_pthread.h $(srcinc)/sh_string.h 
 sh_tiger1.o: $(srcsrc)/sh_tiger1.c Makefile config_xor.h 
@@ -1665,8 +1666,8 @@
 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_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_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 
-sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_mail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
+sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_kern.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h $(srcinc)/sh_logmon.h 
 sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h 
@@ -1674,5 +1675,5 @@
 sh_suidchk.o: $(srcsrc)/sh_suidchk.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_hash.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_schedule.h $(srcinc)/sh_calls.h 
 sh_srp.o: $(srcsrc)/sh_srp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/sh_srp.h $(srcinc)/bignum.h 
-sh_fifo.o: $(srcsrc)/sh_fifo.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_unix.h 
+sh_fifo.o: $(srcsrc)/sh_fifo.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_fifo.h 
 sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
 sh_html.o: $(srcsrc)/sh_html.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_forward.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_html.h $(srcinc)/zAVLTree.h 
@@ -1724,2 +1725,3 @@
 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 
Index: trunk/depend.dep
===================================================================
--- trunk/depend.dep	(revision 213)
+++ trunk/depend.dep	(revision 214)
@@ -1,11 +1,11 @@
 
 # DO NOT DELETE THIS LINE
-samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_mail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
+samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
 sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
-sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
+sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_nmail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
 sh_files.o: $(srcsrc)/sh_files.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_tiger.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/zAVLTree.h 
 sh_getopt.o: $(srcsrc)/sh_getopt.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_getopt.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_mail.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h 
-sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_database.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_files.h $(srcinc)/sh_mail.h $(srcinc)/sh_calls.h $(srcinc)/sh_tiger.h $(srcinc)/sh_forward.h $(srcinc)/sh_modules.h $(srcinc)/sh_gpg.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_extern.h $(srcinc)/sh_tools.h $(srcinc)/sh_database.h $(srcinc)/sh_prelude.h 
+sh_readconf.o: $(srcsrc)/sh_readconf.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_database.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_files.h $(srcinc)/sh_mail.h $(srcinc)/sh_nmail.h $(srcinc)/sh_calls.h $(srcinc)/sh_tiger.h $(srcinc)/sh_forward.h $(srcinc)/sh_modules.h $(srcinc)/sh_gpg.h $(srcinc)/sh_hash.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h $(srcinc)/sh_extern.h $(srcinc)/sh_tools.h $(srcinc)/sh_database.h $(srcinc)/sh_prelude.h 
 sh_tiger0.o: $(srcsrc)/sh_tiger0.c Makefile config_xor.h $(srcinc)/sh_tiger.h $(srcinc)/sh_unix.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_pthread.h $(srcinc)/sh_string.h 
 sh_tiger1.o: $(srcsrc)/sh_tiger1.c Makefile config_xor.h 
@@ -14,8 +14,8 @@
 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_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_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 
-sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_mail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
+sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_kern.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h $(srcinc)/sh_logmon.h 
 sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h 
@@ -23,5 +23,5 @@
 sh_suidchk.o: $(srcsrc)/sh_suidchk.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_hash.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_schedule.h $(srcinc)/sh_calls.h 
 sh_srp.o: $(srcsrc)/sh_srp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/sh_srp.h $(srcinc)/bignum.h 
-sh_fifo.o: $(srcsrc)/sh_fifo.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_unix.h 
+sh_fifo.o: $(srcsrc)/sh_fifo.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_fifo.h 
 sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
 sh_html.o: $(srcsrc)/sh_html.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_forward.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_html.h $(srcinc)/zAVLTree.h 
@@ -75,2 +75,3 @@
 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 
Index: trunk/depend.sum
===================================================================
--- trunk/depend.sum	(revision 213)
+++ trunk/depend.sum	(revision 214)
@@ -1,1 +1,1 @@
-3645502766
+1874099800
Index: trunk/docs/Changelog
===================================================================
--- trunk/docs/Changelog	(revision 213)
+++ trunk/docs/Changelog	(revision 214)
@@ -1,3 +1,5 @@
 2.5.3:
+	* rewrite mail subsystem to allow individual filtering
+	  for recipients
 	* allow shell expansion for values of config file options
 	* allow list as value for option PortCheckInterface
Index: trunk/include/sh_fifo.h
===================================================================
--- trunk/include/sh_fifo.h	(revision 213)
+++ trunk/include/sh_fifo.h	(revision 214)
@@ -10,5 +10,5 @@
  *****************************************************/
 
-#define SH_FIFO_MAX 128
+#define SH_FIFO_MAX 16384
 
 /*****************************************************
@@ -21,4 +21,7 @@
   struct dlist * next;
   char         * data;
+  char         * s_xtra;
+  int            i_xtra;
+  int            transact;
   struct dlist * prev;
 };
@@ -47,5 +50,5 @@
  * Returns: -1 if the list is full, 0 on success 
  */
-int push_list (SH_FIFO * fifo, char * indat);
+int push_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str);
 
 /* Push an item on the tail of the list.
@@ -53,5 +56,5 @@
  * Returns: -1 if the list is full, 0 on success 
  */
-int push_tail_list (SH_FIFO * fifo, char * indat);
+int push_tail_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str);
 
 /* pop an item from the tail of the list
@@ -62,3 +65,12 @@
 char * pop_list (SH_FIFO * fifo);
 
+
+sh_string * tag_list (SH_FIFO * fifo, char * tag,
+		      int(*check)(int, const char*, const char*, const void*),
+		      const void * info);
+void rollback_list (SH_FIFO * fifo);
+void mark_list (SH_FIFO * fifo);
+void reset_list (SH_FIFO * fifo);
+int commit_list (SH_FIFO * fifo);
+
 #endif
Index: trunk/include/sh_mail.h
===================================================================
--- trunk/include/sh_mail.h	(revision 213)
+++ trunk/include/sh_mail.h	(revision 214)
@@ -52,9 +52,5 @@
 /* call if not urgent
  */
-int sh_mail_pushstack (/*@null@*/char * msg);
-
-/* call if mail immediate
- */
-int sh_mail_msg (/*@null@*/char * message);
+int sh_mail_pushstack (int severity, const char * msg, const char * alias);
 
 /* set sender of mail
Index: trunk/include/sh_pthread.h
===================================================================
--- trunk/include/sh_pthread.h	(revision 213)
+++ trunk/include/sh_pthread.h	(revision 214)
@@ -30,4 +30,5 @@
 
 #define SH_MUTEX_LOCK_UNSAFE(M) pthread_mutex_lock(&(M))
+#define SH_MUTEX_TRYLOCK_UNSAFE(M) pthread_mutex_trylock(&(M))
 #define SH_MUTEX_UNLOCK_UNSAFE(M) pthread_mutex_unlock(&(M))
 
@@ -140,4 +141,5 @@
 #define SH_MUTEX_UNLOCK(M)			((void)0)
 #define SH_MUTEX_LOCK_UNSAFE(M)			((void)0)
+#define SH_MUTEX_TRYLOCK_UNSAFE(M)		(0)
 #define SH_MUTEX_UNLOCK_UNSAFE(M)		((void)0)
 
Index: trunk/include/sh_utils.h
===================================================================
--- trunk/include/sh_utils.h	(revision 213)
+++ trunk/include/sh_utils.h	(revision 214)
@@ -40,5 +40,5 @@
   unsigned long   data_ulong;
   long            data_long;
-  /*@null@*/char *data_str;
+  char           *data_str;
 } st_format;
 
@@ -131,5 +131,5 @@
 /* a simple compressor
  */
-long sh_util_compress (char * dest, char * src, size_t dest_size);
+size_t sh_util_compress (char * dest, char * src, size_t dest_size);
 
 /* an even simpler en-/decoder 
Index: trunk/include/slib.h
===================================================================
--- trunk/include/slib.h	(revision 213)
+++ trunk/include/slib.h	(revision 214)
@@ -203,5 +203,5 @@
    * strstr
    */
-  const char * sl_strstr (const char * haystack, const char * needle); 
+  char * sl_strstr (const char * haystack, const char * needle); 
 
   /*
Index: trunk/src/samhain.c
===================================================================
--- trunk/src/samhain.c	(revision 213)
+++ trunk/src/samhain.c	(revision 214)
@@ -72,5 +72,5 @@
 #include "sh_hash.h"
 
-#include "sh_mail.h"
+#include "sh_nmail.h"
 
 #include "sh_tiger.h"
@@ -521,5 +521,5 @@
    */
 #if defined(SH_WITH_MAIL)
-  if (0 == strcmp (DEFAULT_MAILADDRESS, _("NULL")))
+  if (0 != strcmp (DEFAULT_MAILADDRESS, _("NULL")))
     {
 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
@@ -529,7 +529,7 @@
       if (p)
 	{
-	  (void) sh_mail_setaddress_int (p);
+	  (void) sh_nmail_add_compiled_recipient (p);
 	  while (NULL != (p = strtok_r (NULL, ", \t", &saveptr)))
-	    (void) sh_mail_setaddress_int (p);
+	    (void) sh_nmail_add_compiled_recipient (p);
 	}
 #else
@@ -538,7 +538,7 @@
       if (p)
 	{
-	  (void) sh_mail_setaddress_int (p);
+	  (void) sh_nmail_add_compiled_recipient (p);
 	  while (NULL != (p = strtok (NULL, ", \t")))
-	    (void) sh_mail_setaddress_int (p);
+	    (void) sh_nmail_add_compiled_recipient (p);
 	}
 #endif
@@ -725,5 +725,5 @@
   if (sh.mailNum.alarm_last > 0) 
     {
-      (void) sh_mail_msg (NULL);
+      (void) sh_nmail_flush ();
     }
 #endif
@@ -1777,7 +1777,4 @@
 #endif
 
-#if defined(SH_WITH_MAIL)
-	      reset_count_dev_mail();
-#endif
 	      reset_count_dev_console();
 	      reset_count_dev_time();
@@ -2057,5 +2054,5 @@
 #if defined(SH_WITH_MAIL)
 	  TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
-	  (void) sh_mail_msg (NULL);
+	  (void) sh_nmail_flush ();
 #endif
 	}
@@ -2108,5 +2105,5 @@
 	{
 	  TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
-	  (void) sh_mail_msg (NULL);
+	  (void) sh_nmail_flush ();
 	  sh.mailTime.alarm_last = time (NULL);
 	}
@@ -2157,5 +2154,5 @@
 #if defined(SH_WITH_MAIL)
   if (sh.mailNum.alarm_last > 0) 
-    (void)sh_mail_msg (NULL);
+    (void)sh_nmail_flush ();
 #endif
 
Index: trunk/src/sh_error.c
===================================================================
--- trunk/src/sh_error.c	(revision 213)
+++ trunk/src/sh_error.c	(revision 214)
@@ -58,5 +58,5 @@
 #include "sh_unix.h"
 #include "sh_tiger.h"
-#include "sh_mail.h"
+#include "sh_nmail.h"
 #include "sh_forward.h"
 #include "sh_prelude.h"
@@ -1227,9 +1227,9 @@
 	      mail_block = 1;
 
-	      BREAKEXIT(sh_mail_msg);
+	      BREAKEXIT(sh_nmail_msg);
 	      if ( (severity & SH_ERR_FATAL) == 0) 
-		retval = sh_mail_pushstack (lmsg->msg);
+		retval = sh_nmail_pushstack (severity, lmsg->msg, NULL);
 	      else 
-		retval = sh_mail_msg (lmsg->msg);
+		retval = sh_nmail_msg (severity, lmsg->msg, NULL);
 
 	      mail_block = 0;
Index: trunk/src/sh_extern.c
===================================================================
--- trunk/src/sh_extern.c	(revision 213)
+++ trunk/src/sh_extern.c	(revision 214)
@@ -1380,10 +1380,9 @@
 
       for (i = 0; i < task->fand_c; ++i)
-	if (NULL != sl_strstr(message, task->fand_v[i]))
-	  ++j;
-
-      if (j != task->fand_c)
-	{
-	  SL_RETURN ((-1), _("sh_ext_filter"));
+	{
+	  if (NULL == sl_strstr(message, task->fand_v[i]))
+	    {
+	      SL_RETURN ((-1), _("sh_ext_filter"));
+	    }
 	}
 
Index: trunk/src/sh_fifo.c
===================================================================
--- trunk/src/sh_fifo.c	(revision 213)
+++ trunk/src/sh_fifo.c	(revision 214)
@@ -32,4 +32,7 @@
 #include "sh_mem.h"
 #include "sh_unix.h"
+#include "sh_utils.h"
+#include "sh_string.h"
+#include "sh_fifo.h"
 
 #if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
@@ -37,23 +40,156 @@
 #endif
 
-#define SH_FIFO_MAX 128
-
-struct dlist {
-  /*@null@*//*@dependent@*/ struct dlist * next;
-  char         * data;
-  /*@null@*//*@dependent@*/ struct dlist * prev;
-};
-
-typedef struct fifo_str {
-  /*@null@*//*@dependent@*/ struct dlist * head_ptr;
-  /*@null@*//*@dependent@*/ struct dlist * tail_ptr;
-  int            fifo_cts;
-} SH_FIFO;
-
-
+#define SH_FIFO_TAGGED 1
+#define SH_FIFO_M_FAIL 2
+#define SH_FIFO_MARKED 4
+
+/* Prepare an email message and return it.
+ */
+sh_string * tag_list (SH_FIFO * fifo, char * tag,
+		      int(*valid)(int, const char*, const char*, const void*),
+		      const void * info)
+{
+  struct dlist * item;
+  sh_string * result = NULL;
+
+  if (fifo && fifo->fifo_cts > 0)
+    {
+      item = fifo->head_ptr;
+
+      while (item)
+	{
+	  if ( (tag && item->s_xtra && 0 == strcmp(item->s_xtra, tag)) ||
+	       !(item->s_xtra) )
+	    {
+	      if (valid == NULL)
+		{
+		  item->transact |= SH_FIFO_TAGGED;
+		}
+	      else
+		{
+		  if (!valid(item->i_xtra, item->data, tag, info))
+		    goto skipped;
+		  item->transact |= SH_FIFO_TAGGED;
+		}
+	      if (!result)
+		{
+		  result = sh_string_new_from_lchar(item->data, strlen(item->data));
+		}
+	      else
+		{
+		  result = sh_string_cat_lchar(result, "\r\n", 2);
+		  result = sh_string_add_from_char(result, item->data);
+		}
+	    }
+	skipped:
+	  item = item->next;
+	}
+    }
+  return result;
+}
+
+void rollback_list (SH_FIFO * fifo)
+{
+  struct dlist * item;
+
+  if (fifo && fifo->fifo_cts > 0)
+    {
+      item = fifo->head_ptr;
+
+      while (item && 0 != (item->transact & SH_FIFO_TAGGED))
+	{
+	  item->transact |= SH_FIFO_M_FAIL;
+	  item = item->next;
+	}
+    }
+}
+
+void mark_list (SH_FIFO * fifo)
+{
+  struct dlist * item;
+
+  if (fifo && fifo->fifo_cts > 0)
+    {
+      item = fifo->head_ptr;
+
+      while (item && 0 != (item->transact & SH_FIFO_TAGGED))
+	{
+	  item->transact |= SH_FIFO_MARKED;
+	  item = item->next;
+	}
+    }
+}
+
+void reset_list (SH_FIFO * fifo)
+{
+  struct dlist * item;
+
+  if (fifo && fifo->fifo_cts > 0)
+    {
+      item = fifo->head_ptr;
+
+      while (item)
+	{
+	  item->transact = 0;
+	  item = item->next;
+	}
+    }
+}
+
+int commit_list (SH_FIFO * fifo)
+{
+  struct dlist * item;
+  struct dlist * getit;
+  int    retval = 0;
+
+  if (fifo && fifo->fifo_cts > 0)
+    {
+      item = fifo->head_ptr;
+
+      while (item)
+	{
+	  getit = NULL;
+
+	  if ( 0 != (item->transact & SH_FIFO_MARKED) && /* sent              */
+	       0 == (item->transact & SH_FIFO_M_FAIL) )  /* no recipient fail */
+	    {
+	      if (item == fifo->head_ptr)
+		fifo->head_ptr   = item->next;
+	      if (item == fifo->tail_ptr)
+		fifo->tail_ptr   = item->prev;
+	      if (item->prev)
+		item->prev->next = item->next;
+	      if (item->next)
+		item->next->prev = item->prev;
+	      --(fifo->fifo_cts);
+	      getit = item;
+	    }
+	  item  = item->next;
+
+	  /* Delete it
+	   */
+	  if (getit)
+	    {
+	      size_t len = sl_strlen(getit->data);
+	      memset(getit->data, 0, len);
+	      if (NULL != sl_strstr (getit->data, _("LOGKEY")))
+		{
+		  MUNLOCK(getit->data, (len+1));
+		  ;
+		}
+	      if (getit->s_xtra)
+		SH_FREE(getit->s_xtra);
+	      SH_FREE(getit->data);
+	      SH_FREE(getit);
+	      ++retval;
+	    }
+	}
+    }
+  return retval;
+}
 
 /* push an item on the head of the list
  */
-int push_list (SH_FIFO * fifo, char * indat)
+int push_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str)
 {
   struct dlist * item;
@@ -79,5 +215,5 @@
     }
   item            = SH_ALLOC(sizeof(struct dlist));
-  /*@i@*/ item->data      = SH_ALLOC(len+1);
+  item->data      = SH_ALLOC(len+1);
   
   if (NULL != sl_strstr (indat, _("LOGKEY")))
@@ -90,4 +226,11 @@
   item->data[len] = '\0';
 
+  item->i_xtra = in_i;
+  if (in_str)
+    item->s_xtra = sh_util_strdup(in_str);
+  else
+    item->s_xtra = NULL;
+  item->transact = 0;
+
   if (fifo->tail_ptr == NULL)
     {
@@ -97,5 +240,5 @@
   else
     {
-      /*@i@*/ fifo->head_ptr->prev = item;
+      fifo->head_ptr->prev = item;
       item->prev           = NULL;
     }
@@ -111,5 +254,5 @@
 /* push an item on the tail of the list
  */
-int push_tail_list (SH_FIFO * fifo, char * indat)
+int push_tail_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str)
 {
   struct dlist * item;
@@ -135,5 +278,5 @@
 
   item            = SH_ALLOC(sizeof(struct dlist));
-  /*@i@*/item->data      = SH_ALLOC(len+1);
+  item->data      = SH_ALLOC(len+1);
 
   if (NULL != sl_strstr (indat, _("LOGKEY")))
@@ -145,4 +288,11 @@
   sl_strlcpy (item->data, indat, len+1);
   item->data[len] = '\0';
+
+  item->i_xtra = in_i;
+  if (in_str)
+    item->s_xtra = sh_util_strdup(in_str);
+  else
+    item->s_xtra = NULL;
+  item->transact = 0;
 
   if (fifo->head_ptr == NULL)
@@ -205,4 +355,6 @@
     }
 
+  if (getit->s_xtra)
+    SH_FREE(getit->s_xtra);
   SH_FREE(getit->data);
   SH_FREE(getit);
Index: trunk/src/sh_forward.c
===================================================================
--- trunk/src/sh_forward.c	(revision 213)
+++ trunk/src/sh_forward.c	(revision 214)
@@ -131,5 +131,5 @@
 #include "sh_entropy.h"
 #include "sh_html.h"
-#include "sh_mail.h"
+#include "sh_nmail.h"
 #include "sh_socket.h"
 #define SH_NEED_GETHOSTBYXXX
@@ -791,7 +791,7 @@
       if (status != 0)
 	{
-	  (void) push_tail_list (fifo, popmsg); 
+	  (void) push_tail_list (fifo, popmsg, 0, NULL); 
 	  SH_FREE(popmsg);
-	  if (SH_FIFO_MAX == push_list (fifo, errmsg))
+	  if (SH_FIFO_MAX == push_list (fifo, errmsg, 0,NULL))
 	    {
 	      SL_RETURN (-2, _("sh_forward"));
@@ -812,5 +812,5 @@
 			 sh.srvexport.name);
       failed = BAD;
-      if (SH_FIFO_MAX == push_list (fifo, errmsg))    /* push message on stack */
+      if (SH_FIFO_MAX == push_list (fifo, errmsg, 0, NULL))/* push on stack */
 	{
 	  SL_RETURN (-2, _("sh_forward"));
@@ -5062,7 +5062,4 @@
 	    sh_forward_mark_dead ();
 
-#if defined(SH_WITH_MAIL)
-	    reset_count_dev_mail();
-#endif
 	    reset_count_dev_console();
 	    reset_count_dev_time();
@@ -5284,5 +5281,5 @@
 	{
 	  TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
-	  (void) sh_mail_msg (NULL);
+	  (void) sh_nmail_flush ();
 	  sh.mailTime.alarm_last = tcurrent;
 	}
Index: trunk/src/sh_mail.c
===================================================================
--- trunk/src/sh_mail.c	(revision 213)
+++ trunk/src/sh_mail.c	(revision 214)
@@ -59,4 +59,6 @@
 #include "sh_tools.h"
 #include "sh_pthread.h"
+#include "sh_mail_int.h"
+#include "sh_nmail.h"
 
 #undef  FIL__
@@ -67,17 +69,4 @@
 static int failedMail = SL_FALSE;
 
-/* MX Resolver Struct
- */
-typedef struct mx_ {
-  int    pref;
-  char * address;
-} mx;
-
-typedef struct dnsrep_ {
-  int    count;
-  mx   * reply;
-} dnsrep;
-
-static int free_mx (dnsrep * answers);
 static dnsrep * return_mx (char *domain);
 
@@ -258,22 +247,31 @@
 }
 
-#define SH_FILT_NUM 32
-#define SH_FILT_OR  0
-#define SH_FILT_AND 1
-#define SH_FILT_NOT 2
-#define SH_FILT_INIT { 0, { NULL }, 0, { NULL }, 0, { NULL }}
-
-typedef struct _sh_filter_type
-{
-  int      for_c;
-  char   * for_v[SH_FILT_NUM];
-  int      fand_c;
-  char   * fand_v[SH_FILT_NUM];
-  int      fnot_c;
-  char   * fnot_v[SH_FILT_NUM];
-
-} sh_filter_type;
-
-static
+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)
@@ -375,166 +373,58 @@
 
 /*
- * -- check filters
- */
-static 
+ * -- Check filters. Returns 0 if message passes.
+ */ 
 int sh_filter_filter (const char * message, sh_filter_type * filter)
 {
   int i;
-  int j = 0;
-
-  SL_ENTER(_("sh_mail_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_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)
 	    {
-	      SL_RETURN ((-1), _("sh_filter_filter"));
+	      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)
-    {
-      j = 0;
-
-      for (i = 0; i < filter->fand_c; ++i)
-	if (NULL != sl_strstr(message, filter->fand_v[i]))
-	  ++j;
-
-      if (j != filter->fand_c)
-	{
+      
+      /* 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"));
 	}
-    }
-
-  /* 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"));
-}
-
-
-static sh_filter_type mail_filter = SH_FILT_INIT;
-
-/*
- * -- add keywords to the OR filter
- */
-int sh_mail_add_or (const char * str)
-{
-  return (sh_filter_filteradd (str, &(mail_filter), SH_FILT_OR));
-}
-
-/*
- * -- add keywords to the AND filter
- */
-int sh_mail_add_and (const char * str)
-{
-  return (sh_filter_filteradd (str, &(mail_filter), SH_FILT_AND));
-}
-
-/*
- * -- add keywords to the NOT filter
- */
-int sh_mail_add_not (const char * str)
-{
-  return (sh_filter_filteradd (str, &(mail_filter), SH_FILT_NOT));
-}
-
-
-static char * address_list[8] = { 
-  NULL, NULL, NULL, NULL, 
-  NULL, NULL, NULL, NULL 
-};
-
-static   int   address_num = 0;
-static   int   address_num_compiled = 0;
-static   int   setaddress_compiled = S_FALSE;
-
-void reset_count_dev_mail(void)
-{
-  /* if not, then we still have the compiled-in address (if any), so we
-   * don' touch them
-   */
-  if (address_num_compiled == -99)
-    address_num = 0;
-  return;
-}
-
-int sh_mail_setaddress (const char * address)
-{
-  char     *     p;
-
-  SL_ENTER(_("sh_mail_setaddress"));
-  
-  if (0 == strcmp(address, _("NULL")))
-    SL_RETURN ( (0), _("sh_mail_setaddress"));
-    
-  if (address != NULL && address_num < (2 * SH_PATHBUF / 64 )) 
-    {
-      if (address_num < (SH_PATHBUF / 64 ))
-	p = &sh.srvmail.name[address_num*64];
-      else
-	p = &sh.srvmail.alt[address_num*64];
-
-      (void) sl_strlcpy (p, address, 64);
-      
-      if ((p == NULL) || ( sl_strlen(address) != sl_strlen(p)))
-	{
-	  memset(p, (int)'\0', 64);
-	  SL_RETURN ( (-1), _("sh_mail_setaddress"));
-	}
-      address_list[address_num] = p;
-#if 0
-      if (!sl_is_suid())
-	{
-	  TPT(( 0, FIL__, __LINE__, _("msg=<address_list[%d] = %s>\n"), 
-		address_num, address_list[address_num]));
-	}
-#endif
-      if (setaddress_compiled == S_TRUE)
-	{
-	  ++address_num;
-	  ++address_num_compiled;
-	}
-      else
-	{
-	  if (address_num == address_num_compiled)
-	    {
-	      address_num = 0;
-	      address_num_compiled = -99;
-	    }
-	  ++address_num;
-	}
-      SL_RETURN ( (0), _("sh_mail_setaddress"));
-    }
-  SL_RETURN ( (-1), _("sh_mail_setaddress"));
-}
-
-int sh_mail_setaddress_int (const char * address)
-{
-  int i;
-  SL_ENTER(_("sh_mail_setaddress_int"));
-  setaddress_compiled = S_TRUE;
-  i = sh_mail_setaddress(address);
-  setaddress_compiled = S_FALSE;
-  SL_RETURN(i, _("sh_mail_setaddress_int"));
 }
 
@@ -553,5 +443,5 @@
 
 
-static int all_in_one = S_FALSE;
+int sh_mail_all_in_one = S_FALSE;
 
 int sh_mail_setFlag (const char * str)
@@ -559,5 +449,5 @@
   int i;
   SL_ENTER(_("sh_mail_setFlag"));
-  i = sh_util_flagval(str, &all_in_one);
+  i = sh_util_flagval(str, &sh_mail_all_in_one);
   SL_RETURN(i, _("sh_mail_setFlag"));
 }
@@ -584,6 +474,7 @@
 }
 
-
-static SH_FIFO * fifo_mail = NULL;
+SH_MUTEX_INIT(mutex_fifo_mail, PTHREAD_MUTEX_INITIALIZER);
+
+SH_FIFO * fifo_mail = NULL;
 
 static
@@ -598,4 +489,5 @@
     SL_RET0(_("sh_mail_emptystack"));
 
+  SH_MUTEX_LOCK(mutex_fifo_mail);
   while (NULL != (msg = pop_list(fifo_mail)))
     {
@@ -604,4 +496,5 @@
       SH_FREE(msg);
     }
+  SH_MUTEX_UNLOCK(mutex_fifo_mail);
 
   SL_RET0(_("sh_mail_emptystack"));
@@ -610,26 +503,25 @@
 /* insert "\r\n" after each 998 char
  */
-static char * split_string(char * str);
-
-int sh_mail_pushstack (/*@null@*/char * msg)
+static char * split_string(const char * str);
+
+/* fixes warning: variable âpâ might be clobbered by âlongjmpâ or âvforkâ*/
+static char ** p_dummy;
+
+int sh_mail_pushstack (int severity, const char * msg, const char * alias)
 {
   char * p;
-  int    retval = 0;
+  volatile int    retval = 0;
   int    status;
 
   SL_ENTER(_("sh_mail_pushstack"));
 
-  if (msg == NULL || failedMail == SL_TRUE || sh.srvmail.name[0] == '\0') 
+  if (msg == NULL || failedMail == SL_TRUE /* || sh.srvmail.name[0] == '\0' */) 
     SL_RETURN((0), (_("sh_mail_pushstack")));
 
-  if (0 != sh_filter_filter(msg, &mail_filter))
-    SL_RETURN((0), (_("sh_mail_pushstack")));
-
-#if 0
-  if (msg != NULL && sl_strlen(msg) > 998)  /* RFC 2822 */
-    msg[998] = '\0';
-#endif
-
   p = split_string(msg);
+  /* fixes "variable âpâ might be clobbered by âlongjmpâ or âvforkâ" */
+  p_dummy = &p;
+
+  SH_MUTEX_LOCK(mutex_fifo_mail);
 
   if (fifo_mail == NULL)
@@ -638,6 +530,7 @@
       fifo_init(fifo_mail);
     }
-
-  status = push_list (fifo_mail, p);
+  status = push_list (fifo_mail, p, severity, alias);
+  SH_MUTEX_UNLOCK(mutex_fifo_mail);
+
   if (status >= 0)
     ++sh.mailNum.alarm_last;
@@ -647,6 +540,6 @@
   if (sh.mailNum.alarm_last >= sh.mailNum.alarm_interval)
     {
-      BREAKEXIT(sh_mail_msg);
-      retval = sh_mail_msg (NULL);
+      BREAKEXIT(sh_nmail_flush);
+      retval = sh_nmail_flush ();
     }
 
@@ -660,8 +553,8 @@
  */
 static int sh_mail_end_conn (FILE * connfile, int fd);
-static FILE * sh_mail_start_conn (int aFlag, int * fd);
+static FILE * sh_mail_start_conn (struct alias * address, int * fd, int * anum);
 
 static
-void sh_mail_get_subject(char * message,
+void sh_mail_get_subject(const char * message,
 			 char * mheader, size_t len)
 {
@@ -677,4 +570,5 @@
   char * mptr;
   char   sev[8];
+  char * msg;
 
   SL_ENTER(_("sh_mail_get_subject"));
@@ -693,5 +587,7 @@
   /* fast forward to the important part
    */
-  mptr = (char*)sl_strstr(message, _("msg="));
+  msg  = sh_util_strdup(message);
+
+  mptr = sl_strstr(msg, _("msg="));
   if (mptr)
     {
@@ -700,7 +596,7 @@
     }
   else
-    rep_serv_tab[2].data_str   = message;
-
-  mptr = (char*)sl_strstr(message, _("sev="));
+    rep_serv_tab[2].data_str   = msg;
+
+  mptr = sl_strstr(msg, _("sev="));
   if (mptr)
     {
@@ -714,5 +610,5 @@
   else
     {
-      mptr = message;
+      mptr = msg;
       sev[0] = *mptr; ++mptr;
       sev[1] = *mptr; ++mptr;
@@ -737,59 +633,80 @@
   (void) sl_strlcat(mheader, p, len);
   SH_FREE(p);
+  SH_FREE(msg);
   SL_RET0(_("sh_mail_get_subject"));
 }
 
-
-#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
-#include <sys/mman.h>
-#endif
-
-static char * sh_mail_realloc (char * inbuf, size_t * insize, size_t increase)
-{
-  size_t newsize;
-  char * outbuf = inbuf;
-
-  SL_ENTER(_("sh_mail_realloc"));
-
-  if (sl_ok_adds((*insize), 1))
-    {
-      newsize = (*insize) + 1;
-
-      if (sl_ok_adds(newsize, increase))
-	{
-	  newsize += increase;
-
-	  outbuf = SH_ALLOC(newsize);
-	  MLOCK(outbuf, newsize);
-	  (void) sl_strlcpy(outbuf, inbuf, newsize);
-
-	  memset (inbuf, 0, (*insize));
-	  MUNLOCK(inbuf, (*insize));
-	  SH_FREE(inbuf);
-
-	  *insize = newsize;
-	}
-    }
-
-  SL_RETURN( (outbuf), _("sh_mail_realloc"));
-}
-
-int sh_mail_msg (/*@null@*/char * message)
+void sh_mail_signature_block (sh_string  * sigMsg, char * recipient,
+			      char * bufcompress)
+{
+  time_t         id_audit;
+  char         * theSig;
+  char ibuf[80];
+  unsigned int count;
+
+  /* ------ signature block ------------------------------------ */
+  
+  sigMsg = sh_string_add_from_char(sigMsg, 
+				   _("-----BEGIN SIGNATURE-----\r\n"));
+  
+  count  = sh_nmail_get_mailkey (recipient, skey->mailkey_new, KEY_LEN+1,
+				 &id_audit);
+  
+  if (count != 0)
+    {
+      char sigbuf[KEYBUF_SIZE];
+      
+      /* Sign the message with the signature key.
+       */
+      theSig = sh_util_siggen (skey->mailkey_new, 
+			       bufcompress, sl_strlen(bufcompress),
+			       sigbuf, sizeof(sigbuf));
+      sigMsg = sh_string_add_from_char(sigMsg, theSig);
+    }
+  else
+    {
+       /* reveal first signature key
+       */
+      /* flawfinder: ignore */
+      (void) sl_strlcpy(skey->crypt, skey->mailkey_new, KEY_LEN+1); 
+      
+      BREAKEXIT(sh_util_encode);
+      /* flawfinder: ignore */
+      sh_util_encode(skey->crypt, bufcompress, 0, 'A');
+      
+      /* flawfinder: ignore */
+      sigMsg     = sh_string_add_from_char(sigMsg, skey->crypt);
+      
+      /* flawfinder: ignore */
+      memset (skey->crypt, 0, KEY_LEN);
+    }
+
+    sigMsg     = sh_string_add_from_char(sigMsg, "\r\n");
+
+    sl_snprintf(ibuf, sizeof(ibuf), _("%06u %010lu::%s\r\n"),
+		count, (unsigned long) id_audit, sh.host.name);
+
+    sigMsg     = sh_string_add_from_char(sigMsg, ibuf);
+    sigMsg     = sh_string_add_from_char(sigMsg, _("-----END MESSAGE-----"));
+
+    return;
+}
+
+int sh_mail_msg (const char * message)
 {
     char         subject[32+32+SH_MINIBUF+2+3+SH_PATHBUF];
     char         mheader[32+32+SH_MINIBUF+2+3];
 
-    char       * mailMsg;
-    char       * popMsg;
-    int          status = 0, errcount;
+    sh_string  * mailMsg;
+    sh_string  * compMsg;
+    int          status = 0;
+    volatile int errcount;
     size_t       wrlen;
-    int          i;
-    int          num_popped = 0;
-    int          retval = -1;  
+    volatile int retval = -1;  
 
     char       * bufcompress;
+    size_t       compressed;
+
     static int   failcount = 0;
-    static int   isfirst   = 1;
-    static int   mailcount = 0;
     FILE       * connfile  = NULL;
 
@@ -797,50 +714,34 @@
     struct  sigaction  new_act;
 
-    static  time_t id_audit  = 0;
     static  time_t fail_time = 0;
     static  time_t success_time = 0;
 
-    static  int ma_block = 0;
-
     int       ma_socket = -1;
 
-    SH_FIFO * fifo_temp = NULL;
-
-    char    * theSig;
-    char    * theMsg = NULL;
+    int            address_num = 0;
+    sh_string    * theMsg = NULL;
 
     /* #define SH_MAILBUF (256)    */
-#define SH_MAILBUF (8*4096) 
-
-    size_t    msgbufsize = SH_MAILBUF;
-    size_t    combufsize = SH_MAILBUF;
+#define SH_MAILBUF 4096 
+
     char      timebuf[81];
-    char hashbuf[KEYBUF_SIZE];
 
     SL_ENTER(_("sh_mail_msg"));
 
-    if (ma_block == 1)
-      SL_RETURN( (0), _("sh_mail_msg"));
-
-    /* Return if we cannot mail.
+    /* 
+     * Return if we cannot mail.
      */
     if (failedMail == SL_TRUE) 
       SL_RETURN((-1), _("sh_mail_msg"));
 
-    if (failedMail == SL_FALSE && address_list[0] == NULL)
-      {
-	TPT((0, FIL__, __LINE__, 
-	     _("msg=<Mail error: no recipient address.>\n")));
-	failedMail = SL_TRUE;
-	SL_RETURN((-1), _("sh_mail_msg"));
-      }
-
+    /*
+     * Final failure, can't mail for SH_MAX_FAIL hours.
+     */
     if ( (success_time > 0) && (fail_time > 0) &&
 	 (time(NULL) - success_time) > 3600*SH_MAX_FAIL)
       {
-	ma_block = 1;
 	sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
-			 _("mail"), address_list[0]);
-	ma_block = 0;
+			 _("mail"), 
+			 sh_string_str(all_recipients->recipient));
 	sh_mail_emptystack();
 	sh.mailNum.alarm_last = 0;
@@ -849,5 +750,6 @@
       }
 
-    /* Try at most each hour.
+    /*
+     * Try at most every three seconds to mail if there was a failure.
      */
     if ((fail_time > 0) && (time(NULL) - fail_time) < 3/*600*/)
@@ -855,7 +757,7 @@
 	if (failcount > 3)
 	  {
-	    /* -- Save for later. -- 
+	    /* -- Save for later. Changed: done by caller. -- 
+	     *	    sh_nmail_pushstack (severity, message, alias);
 	     */
-	    sh_mail_pushstack (message);
 	    ++failcount;
 	    
@@ -873,19 +775,11 @@
     fail_time = 0;
 
-    /* -- Polling, empty queue. --
-     */
-    if (message == NULL && sh.mailNum.alarm_last == 0)
-      SL_RETURN((-1), _("sh_mail_msg"));
-
-    /* -- Filtered. --
-     */
-    if (message != NULL && 0 != sh_filter_filter(message, &mail_filter))
-      SL_RETURN((-1), (_("sh_mail_msg")));
-
-
 
     /* ---------  Build complete message. ------------------------ */
 
-    theMsg = split_string(message);
+    /* Don't flush the queue here, because tag_list doesn't know
+     * how to filter messages. */
+
+    theMsg = sh_string_new_from_lchar(message, strlen(message));
 
     /* ---------- Header  ---------------------------------------- */
@@ -894,5 +788,6 @@
       {
 	(void) sl_strlcpy(mheader, _("Subject: "),       sizeof(mheader)-5);
-	(void) sl_strlcat(mheader, sh_unix_time (0, timebuf, sizeof(timebuf)),
+	(void) sl_strlcat(mheader, 
+			  sh_unix_time (0, timebuf, sizeof(timebuf)),
 			  sizeof(mheader)-5);
 	(void) sl_strlcat(mheader, " ",                  sizeof(mheader)-5);
@@ -901,12 +796,4 @@
     else
       {
-	
-	if (message == NULL)
-	  {
-	    theMsg  = pop_list(fifo_mail);
-	    message = theMsg;
-	    if (message)
-	      --sh.mailNum.alarm_last;
-	  }
 	
 	if (message)
@@ -917,5 +804,6 @@
 	  {
 	    (void) sl_strlcpy(mheader, _("Subject: "),     sizeof(mheader)-5);
-	    (void) sl_strlcat(mheader, sh_unix_time (0, timebuf, sizeof(timebuf)),
+	    (void) sl_strlcat(mheader, 
+			      sh_unix_time (0, timebuf, sizeof(timebuf)),
 			      sizeof(mheader)-5);
 	    (void) sl_strlcat(mheader, " ",                sizeof(mheader)-5);
@@ -937,132 +825,29 @@
 
 
-    mailMsg     = (char *) SH_ALLOC (msgbufsize);
-    bufcompress = (char *) SH_ALLOC (combufsize);
-
-    MLOCK(mailMsg     , msgbufsize);
-    MLOCK(bufcompress , combufsize);
-
-    (void) sl_strlcpy(mailMsg, mheader, msgbufsize);
+    mailMsg     = sh_string_new (SH_MAILBUF);
+    compMsg     = sh_string_new (SH_MAILBUF);
+
+    mailMsg     = sh_string_add_from_char(mailMsg, mheader);
+    mailMsg     = sh_string_add_from_char(mailMsg, 
+					  _("-----BEGIN MESSAGE-----\r\n"));
+
+    mailMsg     = sh_string_add_from_char(mailMsg, subject);
+    mailMsg     = sh_string_add          (mailMsg, theMsg);
+    mailMsg     = sh_string_add_from_char(mailMsg, "\r\n");
+
+    /* ---------- Compressed Message  ---------------------------- */
+
+    compMsg     = sh_string_add_from_char(compMsg, subject);
+    compMsg     = sh_string_add          (compMsg, theMsg);
+    compMsg     = sh_string_add_from_char(compMsg, "\r\n");
+
+    bufcompress = SH_ALLOC(sh_string_len(compMsg) + KEY_LEN + 1);
     bufcompress[0] = '\0';
 
-    (void) sl_strlcat(mailMsg, _("-----BEGIN MESSAGE-----\r\n"), msgbufsize);
-    (void) sl_strlcat(mailMsg, subject, msgbufsize);
-    (void) sh_util_compress (bufcompress, subject, 
-			     (combufsize - KEY_LEN - 1));
-    if (message != NULL)
-      {
-	if ((sl_strlen(theMsg) + sl_strlen(mailMsg) + 1) > 
-	    (msgbufsize-(4*KEY_LEN)))
-	  {
-	    mailMsg     = sh_mail_realloc(mailMsg,     
-					  &msgbufsize, sl_strlen(theMsg)+2);
-	    bufcompress = sh_mail_realloc(bufcompress, 
-					  &combufsize, sl_strlen(theMsg));
-	  }
-	(void) sl_strlcat(mailMsg,  theMsg, msgbufsize-(4*KEY_LEN));
-	(void) sl_strlcat(mailMsg,  "\r\n", msgbufsize-(4*KEY_LEN));
-
-	(void) sh_util_compress (bufcompress,  theMsg, combufsize-KEY_LEN-1);
-      }
-
-    if (sh.mailNum.alarm_last > 0)
-      {
-	fifo_temp = SH_ALLOC (sizeof(SH_FIFO));
-	fifo_init (fifo_temp);
-
-	while ( NULL != (popMsg = pop_list(fifo_mail)) )
-	  {
-	    (void) push_list (fifo_temp, popMsg);
-
-	    if ((sl_strlen(popMsg) + sl_strlen(mailMsg) + 1) > 
-		(msgbufsize-(4*KEY_LEN)))
-	      {
-		mailMsg     = sh_mail_realloc(mailMsg,     
-					      &msgbufsize, 
-					      sl_strlen(popMsg)+2);
-		bufcompress = sh_mail_realloc(bufcompress, 
-					      &combufsize, 
-					      sl_strlen(popMsg));
-	      }
-
-	    (void) sl_strlcat(mailMsg, popMsg, msgbufsize-(4*KEY_LEN));
-	    (void) sl_strlcat(mailMsg, "\r\n", msgbufsize-(4*KEY_LEN));
-	    (void) sh_util_compress(bufcompress, popMsg, combufsize-KEY_LEN-1);
-	    SH_FREE(popMsg);
-	    --sh.mailNum.alarm_last;
-	    ++num_popped;
-	  }
-      }
-
-    /* ------ signature block ------------------------------------ */
-    
-    (void) sl_strlcat(mailMsg, _("-----BEGIN SIGNATURE-----\r\n"), msgbufsize);
-
-    /* Generate new signature key.
-     */
-    if (isfirst == 1)
-      {
-	BREAKEXIT(sh_util_keyinit);
-	(void) sh_util_keyinit (skey->mailkey_old, KEY_LEN+1);
-      }
-
-    /* iterate the key
-     */
-    (void) sl_strlcpy(skey->mailkey_new,
-		      sh_tiger_hash (skey->mailkey_old, TIGER_DATA, KEY_LEN,
-				     hashbuf, sizeof(hashbuf)),
-		      KEY_LEN+1);
-
-    if (isfirst == 0)
-      {
-	char sigbuf[KEYBUF_SIZE];
-
-        /* Sign the message with the signature key.
-         */
-	theSig = sh_util_siggen (skey->mailkey_new, 
-				 bufcompress, sl_strlen(bufcompress),
-				 sigbuf, sizeof(sigbuf));
-	(void) sl_strlcat (mailMsg, 
-			   theSig,
-			   msgbufsize);
-      }
-    else
-      {
-        id_audit = time (NULL);
-
-        /* reveal first signature key
-         */
-	/* flawfinder: ignore */
-        (void) sl_strlcpy(skey->crypt, skey->mailkey_new, KEY_LEN+1); 
-
-	BREAKEXIT(sh_util_encode);
-	/* flawfinder: ignore */
-        sh_util_encode(skey->crypt, bufcompress, 0, 'A');
-
-	/* flawfinder: ignore */
-        (void) sl_strlcat (mailMsg, skey->crypt, msgbufsize);
-	/* flawfinder: ignore */
-        memset (skey->crypt, 0, KEY_LEN);
-        isfirst = 0;
-      }
-    (void) sl_strlcat (mailMsg, "\r\n", msgbufsize);
-
-    /* X(n) -> X(n-1)
-     */
-    (void) sl_strlcpy (skey->mailkey_old, skey->mailkey_new, KEY_LEN+1);
-
-    sl_snprintf(subject, sizeof(subject), _("%06d %010ld::%s\r\n"),
-		mailcount, (long) id_audit, sh.host.name);
-
-    (void) sl_strlcat (mailMsg, subject, msgbufsize);
-    ++mailcount;
-
-    (void) sl_strlcat (mailMsg, _("-----END MESSAGE-----"), msgbufsize);
-
-
+    compressed = sh_util_compress (bufcompress, 
+				   sh_string_str(compMsg), 
+				   sh_string_len(compMsg) + 1);
 
     /* ---------- Connect ---------------------------------------- */
-
-
 
     /* -- Catch (ignore) 'broken pipe'.
@@ -1074,53 +859,92 @@
     (void) sigaction (SIGPIPE, &new_act, &old_act);
 
-    i        = 0;
     errcount = 0;
 
-    if (all_in_one == S_FALSE)
+    if (sh_mail_all_in_one == S_FALSE)
       {
-	while (address_list[i] != NULL && i < address_num)
+	struct alias * address_list;
+
+	address_list = all_recipients;
+
+	while (address_list)
 	  {
-	    connfile = sh_mail_start_conn (i, &ma_socket);
+	    if (address_list->send_mail == 1)
+	      {
+		connfile = sh_mail_start_conn (address_list, 
+					       &ma_socket, &address_num);
 	    
-	    if (NULL != connfile)
-	      {
-		wrlen = fwrite (mailMsg, 1, sl_strlen(mailMsg), 
-				 connfile);
-		wrlen -= sl_strlen(mailMsg);
-		if (wrlen == 0) 
-		  status = sh_mail_end_conn (connfile, ma_socket);
+		if (NULL != connfile)
+		  {
+		    wrlen = fwrite (sh_string_str(mailMsg), 1, 
+				    sh_string_len(mailMsg), connfile);
+		    wrlen -= sh_string_len(mailMsg);
+
+		    if (wrlen == 0)
+		      {
+			sh_string  * sigMsg  = sh_string_new (0);
+
+			sh_mail_signature_block (sigMsg, 
+						 sh_string_str(address_list->recipient),
+						 bufcompress);
+
+			wrlen = fwrite (sh_string_str(sigMsg), 1, 
+					sh_string_len(sigMsg), connfile);
+			wrlen -= sh_string_len(sigMsg);
+
+			sh_string_destroy(&sigMsg);
+		      }
+
+		    if (wrlen == 0) 
+		      status = sh_mail_end_conn (connfile, ma_socket);
+		    else
+		      status = -1;
+		  }
+		if (NULL == connfile ||  status != 0)
+		  {
+		    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
+				     _("mail"), 
+				     sh_string_str(address_list->recipient));
+		    ++errcount;
+		    ++sh.statistics.mail_failed;
+		  }
 		else
-		  status = -1;
+		  {
+		    ++sh.statistics.mail_success;
+		  }
+		
+		if (connfile != NULL)
+		  {
+		    (void) fclose (connfile);
+		    connfile = NULL;
+		  }
 	      }
-	    if (NULL == connfile ||  status != 0)
-	      {
-		ma_block = 1;
-		sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
-				 _("mail"), address_list[i]);
-		ma_block = 0;
-		++errcount;
-		++sh.statistics.mail_failed;
-	      }
-	    else
-	      {
-		++sh.statistics.mail_success;
-	      }
-
-	    if (connfile != NULL)
-	      {
-		(void) fclose (connfile);
-		connfile = NULL;
-	      }
-	    ++i;
+	    address_list = address_list->all_next;
 	  }
       }
     else
       {
-	connfile = sh_mail_start_conn ( -9 , &ma_socket);
-	
+	connfile = sh_mail_start_conn (NULL, &ma_socket, &address_num);
+
 	if (NULL != connfile)
 	  {
-	    wrlen = fwrite (mailMsg, 1, sl_strlen(mailMsg), connfile);
-	    wrlen -= sl_strlen(mailMsg);
+	    wrlen = fwrite (sh_string_str(mailMsg), 1, 
+			    sh_string_len(mailMsg), connfile);
+	    wrlen -= sh_string_len(mailMsg);
+
+	    if (wrlen == 0)
+	      {
+		sh_string  * sigMsg  = sh_string_new (0);
+		
+		sh_mail_signature_block (sigMsg, 
+					 NULL,
+					 bufcompress);
+		
+		wrlen = fwrite (sh_string_str(sigMsg), 1, 
+				sh_string_len(sigMsg), connfile);
+		wrlen -= sh_string_len(sigMsg);
+		
+		sh_string_destroy(&sigMsg);
+	      }
+
 	    if (wrlen == 0)
 	      status = sh_mail_end_conn (connfile, ma_socket);
@@ -1128,10 +952,18 @@
 	      status = -1;
 	  }
-	if (NULL == connfile ||  status != 0)
+
+	if (NULL == connfile || status != 0)
 	  {
-	    ma_block = 1;
+	    struct alias* ma_address = all_recipients;
+
+	    while (ma_address)
+	      {
+		if (ma_address->send_mail == 1)
+		  break;
+		ma_address = ma_address->all_next;
+	      }
+
 	    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
-			     _("mail"), address_list[0]);
-	    ma_block = 0;
+			     _("mail"), sh_string_str(ma_address->recipient));
 	    errcount = address_num;
 	    ++sh.statistics.mail_failed;
@@ -1148,57 +980,27 @@
 	  }
       }
-
     
-    memset (bufcompress, 0, combufsize);
-    MUNLOCK(bufcompress , combufsize);
+    memset (bufcompress, 0, compressed);
     SH_FREE(bufcompress);
 
-    memset (mailMsg, 0, msgbufsize);
-    MUNLOCK(mailMsg , msgbufsize);
-    SH_FREE(mailMsg);
+    memset (sh_string_str(mailMsg), 0, sh_string_len(mailMsg));
+    memset (sh_string_str(compMsg), 0, sh_string_len(compMsg));
+    memset (sh_string_str(theMsg),  0, sh_string_len(theMsg));
+
+    sh_string_destroy(&mailMsg);
+    sh_string_destroy(&compMsg);
+    sh_string_destroy(&theMsg);
 
     /* --- Stay responsible for delivery in case of failure --- */
 
-    if (errcount == address_num && fifo_temp != NULL)
+    if (errcount == address_num)
       {
-        while ( (NULL != (popMsg = pop_list(fifo_temp))) )
-          {
-            if (push_list (fifo_mail, popMsg) >= 0)
-	      ++sh.mailNum.alarm_last;
-            SH_FREE(popMsg);
-          }
-	if (message != NULL)
-	  {
-	    if (fifo_mail == NULL)
-	      {
-		fifo_mail = SH_ALLOC(sizeof(SH_FIFO));
-		fifo_init(fifo_mail);
-	      }
-	    retval = push_list (fifo_mail,  theMsg);
-	    if (retval >= 0) 
-	      ++sh.mailNum.alarm_last;
-	    if (retval == SH_FIFO_MAX)
-	      retval = -2;
-	    else
-	      retval = -1;
-	  }
+	rollback_list(fifo_mail);
+	retval = -1;
       }
-    else if (fifo_temp != NULL)
+    else
       {
-        while ( (NULL != (popMsg = pop_list(fifo_temp))) )
-          {
-            SH_FREE(popMsg);
-          }
+	mark_list(fifo_mail);
       }
-    if (fifo_temp != NULL)
-      SH_FREE(fifo_temp);
-
-    /*
-    if (connfile != NULL) 
-      fclose (connfile);
-    */
-
-    if (theMsg != NULL)
-      SH_FREE(theMsg);
 
     /* --- Reset signal. ---
@@ -1211,4 +1013,5 @@
 	SL_RETURN((retval), _("sh_mail_msg"));
       }
+
     success_time = time(NULL);
     failcount = 0;
@@ -1298,12 +1101,17 @@
  *
  * start connection
- * for details on SMTP, see RFC 821 
+ * for details on SMTP, see RFC 821
+ *
+ * If ma_address == NULL, will send to all marked with
+ * send_mail=1 in recipient list, else to ma_address.   
  */
 
 static time_t time_wait = 300;
 
-static FILE * sh_mail_start_conn (int aFlag, int * ma_socket)
+static FILE * sh_mail_start_conn (struct alias * ma_address, 
+				  int * ma_socket, int * anum)
 {
   char       * address;
+  int          aFlag = 0;
 
   int          ecount;
@@ -1334,19 +1142,29 @@
   time_wait  = 300;
 
-  if (aFlag >= 0)
-    address = address_list[aFlag];
-  else
-    address = address_list[0];
-
-  TPT(( 0, FIL__, __LINE__, _("msg=<aFlag %d address %s>\n"), 
-	aFlag, address)); 
-
-  /* -------   split adress ------------------  */
-
-  if (0 == strcmp(address, _("NULL")))
+  if (ma_address == NULL)
+    {
+      aFlag = 1;
+      ma_address = all_recipients;
+
+      while (ma_address)
+	{
+	  if (ma_address->send_mail == 1)
+	    break;
+	  ma_address = ma_address->all_next;
+	}
+    }
+
+  if (!ma_address)
     {
       SL_RETURN( NULL, _("sh_mail_start_conn"));
     } 
-    
+
+  address = sh_string_str(ma_address->recipient);
+
+  TPT(( 0, FIL__, __LINE__, _("msg=<address %s>\n"), 
+	address)); 
+
+  /* -------   split adress ------------------  */
+
   if (strchr (address, '@') == NULL) {
     (void) sl_strlcpy(ma_user,    address,     256);
@@ -1358,5 +1176,5 @@
       ++i;
     }
-
+    
     /* adress[i] = '@' 
      */
@@ -1385,5 +1203,11 @@
   else
     {
-      answers = return_mx (ma_machine);
+      answers = ma_address->mx_list;
+      if (!answers)
+	{
+	  answers = return_mx (ma_machine);
+	  ma_address->mx_list = answers;
+	}
+
       if (answers)
 	{
@@ -1402,5 +1226,4 @@
 		break;
 	    }
-	  (void) free_mx(answers);
 	}
       else
@@ -1511,5 +1334,5 @@
   /* tell them who to send mail to
    */
-  if (aFlag >= 0)
+  if (aFlag == 0)
     {
       TPT(( 0, FIL__, __LINE__,  _("msg=<RCPT TO:<%s>>%c%c"), 
@@ -1529,17 +1352,29 @@
 	  SL_RETURN( NULL, _("sh_mail_start_conn"));
 	}
+      *anum = 1;
     }
   else
     {
-      ecount = 0;
-      for (i = 0; i < address_num; ++i)
-	{
-	  if (address_list[i] == NULL)  /* paranoia */
-	    break;
+      int address_num = 0;
+      ecount      = 0;
+
+      ma_address = all_recipients;
+
+      while (ma_address)
+	{
+	  if (ma_address->send_mail != 1)
+	    {
+	      ma_address = ma_address->next;
+	      continue;
+	    }
+
+	  ++address_num;
+
 	  TPT(( 0, FIL__, __LINE__,  _("msg=<RCPT TO:<%s>>%c%c"), 
-		address_list[i], 13, 10)); 
+		sh_string_str(ma_address->recipient), 13, 10)); 
 	  
 	  (void) fflush(connFile);
-	  fprintf(connFile, _("RCPT TO:<%s>%c%c"), address_list[i], 13, 10); 
+	  fprintf(connFile, _("RCPT TO:<%s>%c%c"), 
+		  sh_string_str(ma_address->recipient), 13, 10); 
 	  (void) fflush(connFile);
 	  
@@ -1548,10 +1383,14 @@
 	      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 
 			      _("RCPT TO failed"), _("sh_mail_start_conn"), 
-			      _("mail"), address_list[i]);
+			      _("mail"), sh_string_str(ma_address->recipient));
 
 	      TPT(( 0, FIL__, __LINE__, _("msg=<Timeout.>\n")));
 	      ++ecount;
 	    }
-	}
+	  ma_address = ma_address->next;
+	}
+
+      *anum += address_num;
+
       if (ecount == address_num)
 	{
@@ -1771,5 +1610,5 @@
 #define SPLIT_AT 998
 
-static char * split_string(char * str)
+static char * split_string(const char * str)
 {
   size_t size;
@@ -1778,5 +1617,5 @@
 
   char * p, * p0;
-  char * q;
+  const char * q;
 
   if (!str)
@@ -2205,5 +2044,5 @@
 }
 
-static int free_mx (dnsrep * answers)
+int free_mx (dnsrep * answers)
 {
   mx     * result;
Index: trunk/src/sh_readconf.c
===================================================================
--- trunk/src/sh_readconf.c	(revision 213)
+++ trunk/src/sh_readconf.c	(revision 214)
@@ -34,4 +34,5 @@
 #include "sh_files.h"
 #include "sh_mail.h"
+#include "sh_nmail.h"
 #include "sh_calls.h"
 #include "sh_tiger.h"
@@ -1098,6 +1099,4 @@
   { N_("setmailnum"),        SH_SECTION_MAIL,  SH_SECTION_MISC, 
     sh_mail_setNum },
-  { N_("setmailaddress"),    SH_SECTION_MAIL,  SH_SECTION_MISC, 
-    sh_mail_setaddress },
   { N_("setmailrelay"),      SH_SECTION_MAIL,  SH_SECTION_MISC, 
     sh_mail_set_relay },
@@ -1108,10 +1107,16 @@
   { N_("setmailsender"),     SH_SECTION_MAIL,  SH_SECTION_MISC, 
     sh_mail_set_sender },
+  { N_("setmailaddress"),    SH_SECTION_MAIL,  SH_SECTION_MISC, 
+    sh_nmail_add_recipient },
+  { N_("closeaddress"),      SH_SECTION_MAIL,  SH_SECTION_MISC, 
+    sh_nmail_close_recipient },
+  { N_("setaddrseverity"),   SH_SECTION_MAIL,  SH_SECTION_MISC,
+    sh_nmail_set_severity },
   { N_("setmailfilternot"),  SH_SECTION_MAIL,  SH_SECTION_MISC,
-    sh_mail_add_not },
+    sh_nmail_add_not },
   { N_("setmailfilterand"),  SH_SECTION_MAIL,  SH_SECTION_MISC,
-    sh_mail_add_and },
+    sh_nmail_add_and },
   { N_("setmailfilteror"),   SH_SECTION_MAIL,  SH_SECTION_MISC,
-    sh_mail_add_or },
+    sh_nmail_add_or },
 #endif
   { N_("setbindaddress"),    SH_SECTION_MISC,  SH_SECTION_NONE,
@@ -1214,4 +1219,5 @@
   static const char  *closing[] = {
     N_("closecommand"),
+    N_("closeaddress"),
     N_("logmonendgroup"),
     N_("logmonendhost"),
Index: trunk/src/sh_utils.c
===================================================================
--- trunk/src/sh_utils.c	(revision 213)
+++ trunk/src/sh_utils.c	(revision 214)
@@ -816,5 +816,5 @@
 /* a simple compressor
  */
-long sh_util_compress (char * dest, char * src, size_t dest_size)
+size_t sh_util_compress (char * dest, char * src, size_t dest_size)
 {
   char * add;
@@ -857,5 +857,5 @@
 
   dest[dest_size-1] = '\0'; /* paranoia       */
-  SL_RETURN(((long)count), _("sh_util_compress")); /* no of chars copied */    
+  SL_RETURN((count), _("sh_util_compress")); /* no of chars copied */    
 }
 
Index: trunk/src/slib.c
===================================================================
--- trunk/src/slib.c	(revision 213)
+++ trunk/src/slib.c	(revision 214)
@@ -1091,5 +1091,5 @@
  */
 
-const char * sl_strstr (const char * haystack, const char * needle) 
+char * sl_strstr (const char * haystack, const char * needle) 
 {
 #ifndef HAVE_STRSTR
@@ -2694,5 +2694,5 @@
     {
     case SL_EBOGUS: 
-      return _("Bogus file. Modified during access");
+      return _("Bogus file, modified during access");
     case SL_EWRITE: 
       return _("Write error");
