diff --git a/src/sbbs3/bulkmail.cpp b/src/sbbs3/bulkmail.cpp
index e768ed5e950f1f05f8b5c88061eb4b88fcd39907..0461c6709a9aec21b460ee3eb6f5f7973f29d862 100644
--- a/src/sbbs3/bulkmail.cpp
+++ b/src/sbbs3/bulkmail.cpp
@@ -205,7 +205,7 @@ int sbbs_t::bulkmailhdr(smb_t* smb, smbmsg_t* msg, uint usernum)
 		smb_hfield_str(&newmsg,RECIPIENTEXT,str);
 	}
 
-	j=smb_addmsghdr(smb,&newmsg,SMB_SELFPACK);
+	j=smb_addmsghdr(smb,&newmsg,smb_storage_mode(&cfg, smb));
 	smb_freemsgmem(&newmsg);
 	if(j!=SMB_SUCCESS)
 		return(j);
diff --git a/src/sbbs3/email.cpp b/src/sbbs3/email.cpp
index 5e638715db267d623d7dc9351f8b541518c555f7..2d6e73c68fe1f8ebace94d0d23f6e9bc66827093 100644
--- a/src/sbbs3/email.cpp
+++ b/src/sbbs3/email.cpp
@@ -49,6 +49,7 @@ bool sbbs_t::email(int usernumber, const char *top, const char *subj, long mode)
 				,buf[SDT_BLOCK_LEN];
 	char 		tmp[512];
 	char		pid[128];
+	char		msg_id[128];
 	char*		editor=NULL;
 	uint16_t	msgattr=0;
 	uint16_t	xlat=XLAT_NONE;
@@ -316,12 +317,14 @@ bool sbbs_t::email(int usernumber, const char *top, const char *subj, long mode)
 	/* Generate FidoNet Program Identifier */
 	smb_hfield_str(&msg,FIDOPID,msg_program_id(pid));
 
+ 	smb_hfield_str(&msg, RFC822MSGID, get_msgid(&cfg, INVALID_SUB, &msg, msg_id, sizeof(msg_id)));
+
 	if(editor!=NULL)
 		smb_hfield_str(&msg,SMB_EDITOR,editor);
 
 	smb_dfield(&msg,TEXT_BODY,length);
 
-	i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() 
+	i=smb_addmsghdr(&smb,&msg,smb_storage_mode(&cfg, &smb)); // calls smb_unlocksmbhdr() 
 	smb_close(&smb);
 	smb_stack(&smb,SMB_STACK_POP);
 
diff --git a/src/sbbs3/js_msgbase.c b/src/sbbs3/js_msgbase.c
index 2f3042a9673e7e9f1280145e2387b8d9885b0ecd..32dcdf0b40b7cfa97264012e741311ab6c72890e 100644
--- a/src/sbbs3/js_msgbase.c
+++ b/src/sbbs3/js_msgbase.c
@@ -2304,7 +2304,7 @@ js_save_msg(JSContext *cx, uintN argc, jsval *arglist)
 						break;
 
 					rc=JS_SUSPENDREQUEST(cx);
-					if((p->status=smb_addmsghdr(&(p->smb), &rcpt_msg, SMB_SELFPACK))!=SMB_SUCCESS) {
+					if((p->status=smb_addmsghdr(&(p->smb), &rcpt_msg, smb_storage_mode(scfg, &(p->smb))))!=SMB_SUCCESS) {
 						JS_RESUMEREQUEST(cx, rc);
 						break;
 					}
diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c
index 43fcd568129ea0ea2e36e4ab87fd6c53930c16e2..1472f2aa65335b7214684677f3909bcd071465d7 100644
--- a/src/sbbs3/mailsrvr.c
+++ b/src/sbbs3/mailsrvr.c
@@ -3099,8 +3099,10 @@ static void smtp_thread(void* arg)
 				if(dnsbl_recvhdr)			/* DNSBL-listed IP found in Received header? */
 					dnsbl_result.s_addr=0;	/* Reset DNSBL look-up result between messages */
 				
-				if((startup->options&MAIL_OPT_KILL_READ_SPAM) && (msg.hdr.attr&MSG_SPAM))
+				if((scfg.sys_misc&SM_DELREADM)
+					|| ((startup->options&MAIL_OPT_KILL_READ_SPAM) && (msg.hdr.attr&MSG_SPAM)))
 					msg.hdr.attr |= MSG_KILLREAD;
+
 				if(sender[0]==0) {
 					lprintf(LOG_WARNING,"%04d !SMTP MISSING mail header 'FROM' field (%u total)"
 						,socket, ++stats.msgs_refused);
@@ -3340,7 +3342,7 @@ static void smtp_thread(void* arg)
 					if(agent!=newmsg.to_agent)
 						smb_hfield(&newmsg, RECIPIENTAGENT, sizeof(agent), &agent);
 
-					i=smb_addmsghdr(&smb,&newmsg,SMB_SELFPACK);
+					i=smb_addmsghdr(&smb,&newmsg,smb_storage_mode(&scfg, &smb));
 					smb_freemsgmem(&newmsg);
 					if(i!=SMB_SUCCESS) {
 						lprintf(LOG_ERR,"%04d !SMTP ERROR %d (%s) adding message header"
@@ -4429,6 +4431,10 @@ BOOL bounce(SOCKET sock, smb_t* smb, smbmsg_t* msg, char* err, BOOL immediate)
 		smb_hfield(&newmsg, RECIPIENTAGENT, sizeof(msg->from_agent), &msg->from_agent);
 	}
 	newmsg.hdr.attr|=MSG_NOREPLY;
+	newmsg.hdr.attr&=~MSG_READ;
+	if(scfg.sys_misc&SM_DELREADM)
+		newmsg.hdr.attr |= MSG_KILLREAD;
+
 	strcpy(str,"Mail Delivery Subsystem");
 	smb_hfield_str(&newmsg, SENDER, str);
 	smb_hfield(&newmsg, SENDERAGENT, sizeof(agent), &agent);
@@ -4451,7 +4457,7 @@ BOOL bounce(SOCKET sock, smb_t* smb, smbmsg_t* msg, char* err, BOOL immediate)
 	smb_hfield_str(&newmsg, SMB_COMMENT, err);
 	smb_hfield_str(&newmsg, SMB_COMMENT, "\r\nOriginal message text follows:");
 
-	if((i=smb_addmsghdr(smb,&newmsg,SMB_SELFPACK))!=SMB_SUCCESS)
+	if((i=smb_addmsghdr(smb,&newmsg,smb_storage_mode(&scfg, smb)))!=SMB_SUCCESS)
 		lprintf(LOG_ERR,"%04d !BOUNCE ERROR %d (%s) adding message header"
 			,sock,i,smb->last_error);
 	else {
diff --git a/src/sbbs3/netmail.cpp b/src/sbbs3/netmail.cpp
index eb8420625c3a68d1321cd3c8c8e3086553e7b502..c754c8166428f0d1e1cf359cbc374efb4e2ca2c3 100644
--- a/src/sbbs3/netmail.cpp
+++ b/src/sbbs3/netmail.cpp
@@ -267,7 +267,7 @@ bool sbbs_t::inetmail(const char *into, const char *subj, long mode)
 
 	smb_dfield(&msg,TEXT_BODY,length);
 
-	i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK);	// calls smb_unlocksmbhdr() 
+	i=smb_addmsghdr(&smb,&msg,smb_storage_mode(&cfg, &smb));	// calls smb_unlocksmbhdr() 
 	smb_close(&smb);
 	smb_stack(&smb,SMB_STACK_POP);
 
@@ -474,7 +474,7 @@ bool sbbs_t::qnetmail(const char *into, const char *subj, long mode)
 
 	smb_dfield(&msg,TEXT_BODY,length);
 
-	i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() 
+	i=smb_addmsghdr(&smb,&msg,smb_storage_mode(&cfg, &smb)); // calls smb_unlocksmbhdr() 
 	smb_close(&smb);
 	smb_stack(&smb,SMB_STACK_POP);
 
diff --git a/src/sbbs3/postmsg.cpp b/src/sbbs3/postmsg.cpp
index ee037fff39e7c22069f559b8eb29c0ebfa0c5416..f05258a04716a79bc773f439e994c9bb1fe011ea 100644
--- a/src/sbbs3/postmsg.cpp
+++ b/src/sbbs3/postmsg.cpp
@@ -59,7 +59,6 @@ int msgbase_open(scfg_t* cfg, smb_t* smb, int* storage, long* dupechk_hashes, ui
 {
 	int i;
 
-	*storage=SMB_SELFPACK;
 	*dupechk_hashes=SMB_HASH_SOURCE_DUPE;
 	*xlat=XLAT_NONE;
 
@@ -70,8 +69,6 @@ int msgbase_open(scfg_t* cfg, smb_t* smb, int* storage, long* dupechk_hashes, ui
 		smb->status.max_age=cfg->mail_maxage;
 		smb->status.max_msgs=0;	/* unlimited */
 		smb->status.attr=SMB_EMAIL;
-		if(cfg->sys_misc&SM_FASTMAIL)
-			*storage = SMB_FASTALLOC;
 		/* duplicate message-IDs must be allowed in mail database */
 		*dupechk_hashes&=~(1<<SMB_HASH_SOURCE_MSG_ID);
 	} else {
@@ -80,11 +77,6 @@ int msgbase_open(scfg_t* cfg, smb_t* smb, int* storage, long* dupechk_hashes, ui
 		smb->status.max_msgs=cfg->sub[smb->subnum]->maxmsgs;
 		smb->status.max_age=cfg->sub[smb->subnum]->maxage;
 		smb->status.attr=0;
-		if(cfg->sub[smb->subnum]->misc&SUB_HYPER)
-			*storage = smb->status.attr = SMB_HYPERALLOC;
-		else if(cfg->sub[smb->subnum]->misc&SUB_FAST)
-			*storage = SMB_FASTALLOC;
-
 		if(cfg->sub[smb->subnum]->misc&SUB_LZH)
 			*xlat=XLAT_LZH;
 	}
@@ -97,6 +89,8 @@ int msgbase_open(scfg_t* cfg, smb_t* smb, int* storage, long* dupechk_hashes, ui
 	if(filelength(fileno(smb->shd_fp)) < 1) /* MsgBase doesn't exist yet, create it */
 		i=smb_create(smb);
 
+	*storage=smb_storage_mode(cfg, smb);
+
 	return i;
 }
 
@@ -420,13 +414,13 @@ extern "C" int DLLCALL msg_client_hfields(smbmsg_t* msg, client_t* client)
 	return smb_hfield_str(msg,SENDERPORT,port);
 }
 
+/* Note: support MSG_BODY only, no tails or other data fields (dfields) */
 extern "C" int DLLCALL savemsg(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, client_t* client, const char* server, char* msgbuf)
 {
 	char	pid[128];
 	char	msg_id[256];
 	ushort	xlat=XLAT_NONE;
 	int 	i;
-	int		storage=SMB_SELFPACK;
 	long	dupechk_hashes=SMB_HASH_SOURCE_DUPE;
 
 	if(msg==NULL)
@@ -454,29 +448,11 @@ extern "C" int DLLCALL savemsg(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, client_t*
 
 	if(smb->subnum==INVALID_SUB) {	/* e-mail */
 
-		/* exception here during recycle:
-
-	sbbs.dll!savemsg(scfg_t * cfg, smb_t * smb, smbmsg_t * msg, client_t * client, char * msgbuf)  Line 473 + 0xf bytes	C++
- 	sbbs.dll!js_save_msg(JSContext * cx, JSObject * obj, unsigned int argc, long * argv, long * rval)  Line 1519 + 0x25 bytes	C
- 	js32.dll!js_Invoke(JSContext * cx, unsigned int argc, unsigned int flags)  Line 1375 + 0x17 bytes	C
- 	js32.dll!js_Interpret(JSContext * cx, unsigned char * pc, long * result)  Line 3944 + 0xf bytes	C
- 	js32.dll!js_Execute(JSContext * cx, JSObject * chain, JSObject * script, JSStackFrame * down, unsigned int flags, long * result)  Line 1633 + 0x13 bytes	C
- 	js32.dll!JS_ExecuteScript(JSContext * cx, JSObject * obj, JSObject * script, long * rval)  Line 4188 + 0x19 bytes	C
- 	sbbs.dll!sbbs_t::js_execfile(const char * cmd, const char * startup_dir)  Line 686 + 0x27 bytes	C++
- 	sbbs.dll!sbbs_t::external(const char * cmdline, long mode, const char * startup_dir)  Line 413 + 0x1e bytes	C++
- 	sbbs.dll!event_thread(void * arg)  Line 2745 + 0x71 bytes	C++
-
-	apparently the event_thread is sharing an scfg_t* with another thread! */
-
-
 		smb->status.max_crcs=cfg->mail_maxcrcs;
 		smb->status.max_age=cfg->mail_maxage;
 		smb->status.max_msgs=0;	/* unlimited */
 		smb->status.attr=SMB_EMAIL;
 
-		if(cfg->sys_misc&SM_FASTMAIL)
-			storage=SMB_FASTALLOC;
-
 		/* duplicate message-IDs must be allowed in mail database */
 		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_MSG_ID);
 
@@ -487,11 +463,6 @@ extern "C" int DLLCALL savemsg(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, client_t*
 		smb->status.max_age=cfg->sub[smb->subnum]->maxage;
 		smb->status.attr=0;
 
-		if(cfg->sub[smb->subnum]->misc&SUB_HYPER)
-			storage = smb->status.attr = SMB_HYPERALLOC;
-		else if(cfg->sub[smb->subnum]->misc&SUB_FAST)
-			storage = SMB_FASTALLOC;
-
 		if(cfg->sub[smb->subnum]->misc&SUB_LZH)
 			xlat=XLAT_LZH;
 
@@ -536,7 +507,7 @@ extern "C" int DLLCALL savemsg(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, client_t*
  	if(msg->ftn_pid==NULL) 	
  		smb_hfield_str(msg,FIDOPID,msg_program_id(pid));
 
-	if((i=smb_addmsg(smb,msg,storage,dupechk_hashes,xlat,(uchar*)msgbuf,NULL))==SMB_SUCCESS
+	if((i=smb_addmsg(smb,msg,smb_storage_mode(cfg, smb),dupechk_hashes,xlat,(uchar*)msgbuf, /* tail: */NULL))==SMB_SUCCESS
 		&& msg->to!=NULL	/* no recipient means no header created at this stage */) {
 		if(smb->subnum == INVALID_SUB) {
 			if(msg->to_net.type == NET_FIDO)
diff --git a/src/sbbs3/qwktomsg.cpp b/src/sbbs3/qwktomsg.cpp
index cfe068514554675bfc9c38a79b8ea18130c5e081..dc1b5b1566c2a6ad3a87ea42a550650918709e8b 100644
--- a/src/sbbs3/qwktomsg.cpp
+++ b/src/sbbs3/qwktomsg.cpp
@@ -222,7 +222,6 @@ bool sbbs_t::qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks
 	bool		success=false;
 	uint16_t	net_type;
 	ushort		xlat=XLAT_NONE;
-	int			storage=SMB_SELFPACK;
 	long		dupechk_hashes=SMB_HASH_SOURCE_DUPE;
 	str_list_t	kludges;
 
@@ -255,8 +254,6 @@ bool sbbs_t::qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks
 		msg->hdr.thread_back=atol((char *)hdrblk+108);
 
 	if(subnum==INVALID_SUB) { 		/* E-mail */
-		if(cfg.sys_misc&SM_FASTMAIL)
-			storage=SMB_FASTALLOC;
 
 		/* duplicate message-IDs must be allowed in mail database */
 		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_MSG_ID);
@@ -264,10 +261,6 @@ bool sbbs_t::qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks
 		sprintf(str,"%u",touser);
 		smb_hfield_str(msg,RECIPIENTEXT,str); 
 	} else {
-		if(cfg.sub[subnum]->misc&SUB_HYPER)
-			storage = SMB_HYPERALLOC;
-		else if(cfg.sub[subnum]->misc&SUB_FAST)
-			storage = SMB_FASTALLOC;
 
 		if(cfg.sub[subnum]->misc&SUB_LZH)
 			xlat=XLAT_LZH;
@@ -462,7 +455,7 @@ bool sbbs_t::qwk_import_msg(FILE *qwk_fp, char *hdrblk, ulong blocks
 	if(smb.status.max_crcs==0)	/* no CRC checking means no body text dupe checking */
 		dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY);
 
-	if((i=smb_addmsg(&smb,msg,storage,dupechk_hashes,xlat,(uchar*)body,(uchar*)tail))==SMB_SUCCESS)
+	if((i=smb_addmsg(&smb,msg,smb_storage_mode(&cfg, &smb),dupechk_hashes,xlat,(uchar*)body,(uchar*)tail))==SMB_SUCCESS)
 		success=true;
 	else if(i==SMB_DUPE_MSG) {
 		bprintf("\r\n!%s\r\n",smb.last_error);
diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index 16429136019ba9b9ec91afa30bdf023d57bd946e..a764c405b1612ce4775090f3d71ee797a56f1b4a 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -1207,7 +1207,7 @@ void sbbs_t::forwardmail(smbmsg_t *msg, int usernumber)
 	smb_close_da(&smb);
 
 
-	if((i=smb_addmsghdr(&smb,msg,SMB_SELFPACK))!=SMB_SUCCESS) {
+	if((i=smb_addmsghdr(&smb,msg,smb_storage_mode(&cfg, &smb)))!=SMB_SUCCESS) {
 		errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
 		smb_freemsg_dfields(&smb,msg,1);
 		return;