diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c
index 3192bd7a67ec88e126f9ef4ddd203c4784d9943f..7940c5fc2f2a772a334e87f4e23c95251be0cfd7 100644
--- a/src/sbbs3/sbbsecho.c
+++ b/src/sbbs3/sbbsecho.c
@@ -75,6 +75,7 @@ bool opt_update_msgptrs		= false;
 bool opt_ignore_msgptrs		= false;
 bool opt_leave_msgptrs		= false;
 bool opt_dump_area_file		= false;
+bool opt_retoss_badmail		= false;	/* Re-toss from the badecho/unknown msg sub */
 
 /* statistics */
 ulong netmail=0;	/* imported */
@@ -109,6 +110,27 @@ int mv(const char *insrc, const char *indest, bool copy);
 time32_t fmsgtime(const char *str);
 void export_echomail(const char *sub_code, const nodecfg_t*, bool rescan);
 
+/* FTN-compliant "Program Identifier"/PID (also used as a "Tosser Identifier"/TID) */
+const char* sbbsecho_pid(void)
+{
+	static char str[256];
+	
+	sprintf(str, "SBBSecho %u.%02u-%s r%s %s %s"
+		,SBBSECHO_VERSION_MAJOR,SBBSECHO_VERSION_MINOR,PLATFORM_DESC,revision,__DATE__,compiler);
+
+	return str;
+}
+
+/* for *.bsy file contents: */
+const char* program_id(void)
+{
+	static char str[256];
+	
+	SAFEPRINTF2(str, "%u %s", getpid(), sbbsecho_pid());
+
+	return str;
+}
+
 const char default_domain[] = "fidonet";
 
 const char* zone_domain(uint16_t zone)
@@ -276,7 +298,8 @@ echostat_msg_t fidomsg_to_echostat_msg(fmsghdr_t fmsghdr, fidoaddr_t* pkt_orig,
 		SAFECOPY(msg.tid, p);
 		free(p);
 	}
-	if((p = parse_control_line(fmsgbuf, "TZUTC:")) != NULL) {
+	if((p = parse_control_line(fmsgbuf, "TZUTC:")) != NULL
+		|| (p = parse_control_line(fmsgbuf, "TZUTCINFO:")) != NULL) {
 		SAFECOPY(msg.msg_tz, p);
 		free(p);
 	}
@@ -307,6 +330,8 @@ echostat_msg_t smsg_to_echostat_msg(smbmsg_t smsg, size_t msglen, fidoaddr_t add
 		SAFECOPY(emsg.pid, p);
 	if((p = smsg.ftn_tid) != NULL)
 		SAFECOPY(emsg.tid, p);
+	else
+		SAFECOPY(emsg.tid, sbbsecho_pid());
 	emsg.length = msglen;
 	emsg.pkt_orig = addr;
 
@@ -397,7 +422,8 @@ void write_echostat_msg(FILE* fp, echostat_msg_t msg, const char* prefix)
 	fprintf(fp, "%s.msg_time = %s\n"						, prefix, iniTimeStr(msg.msg_time));
 	if(msg.msg_tz[0])	fprintf(fp, "%s.msg_tz = %s\n"		, prefix, msg.msg_tz);
 	fprintf(fp, "%s.localtime = %s\n"						, prefix, iniTimeStr(msg.localtime));
-	fprintf(fp, "%s.origaddr = %s\n"						, prefix, faddrtoa(&msg.origaddr));
+	if(msg.origaddr.zone)
+		fprintf(fp, "%s.origaddr = %s\n"					, prefix, faddrtoa(&msg.origaddr));
 	fprintf(fp, "%s.pkt_orig = %s\n"						, prefix, faddrtoa(&msg.pkt_orig));
 }
 
@@ -418,7 +444,8 @@ bool write_echostats(const char* fname, echostat_t* echostat, size_t echo_count)
 			char prefix[32];
 			sprintf(prefix, "First%s", echostat_msg_type[type])	, write_echostat_msg(fp, stat->first[type], prefix);
 			sprintf(prefix, "Last%s", echostat_msg_type[type])	, write_echostat_msg(fp, stat->last[type], prefix);
-			fprintf(fp,		"Total%s = %lu\n"					, echostat_msg_type[type], stat->total[type]);
+			if(stat->total[type] != 0)
+				fprintf(fp,	"Total%s = %lu\n"					, echostat_msg_type[type], stat->total[type]);
 		}
 		fprintf(fp, "\n");
 	}
@@ -442,27 +469,6 @@ echostat_t* get_echostat(const char* tag)
 	return &echostat[echostat_count++];
 }
 
-/* FTN-compliant "Program Identifier"/PID (also used as a "Tosser Identifier"/TID) */
-const char* sbbsecho_pid(void)
-{
-	static char str[256];
-	
-	sprintf(str, "SBBSecho %u.%02u-%s r%s %s %s"
-		,SBBSECHO_VERSION_MAJOR,SBBSECHO_VERSION_MINOR,PLATFORM_DESC,revision,__DATE__,compiler);
-
-	return str;
-}
-
-/* for *.bsy file contents: */
-const char* program_id(void)
-{
-	static char str[256];
-	
-	SAFEPRINTF2(str, "%u %s", getpid(), sbbsecho_pid());
-
-	return str;
-}
-
 /**********************/
 /* Log print function */
 /**********************/
@@ -1745,6 +1751,7 @@ bool add_sub_to_areafile(sub_t* sub, fidoaddr_t uplink)
 	SAFECOPY(echotag, sub->sname);
 	char* p;
 	REPLACE_CHARS(echotag, ' ', '_', p);
+	strupr(echotag);
 	fprintf(fp, "%-*s %-*s %s\n"
 		,LEN_EXTCODE, sub->code, FIDO_AREATAG_LEN, echotag, smb_faddrtoa(&uplink, NULL));
 	fclose(fp);
@@ -2655,37 +2662,37 @@ long getlastmsg(uint subnum, uint32_t *ptr, /* unused: */time_t *t)
 }
 
 
-ulong loadmsgs(post_t** post, ulong ptr)
+ulong loadmsgs(smb_t* smb, post_t** post, ulong ptr)
 {
 	int i;
 	long l,total;
 	idxrec_t idx;
 
 
-	if((i=smb_locksmbhdr(&smb[cur_smb]))!=SMB_SUCCESS) {
-		lprintf(LOG_ERR,"ERROR %d (%s) line %d locking %s",i,smb[cur_smb].last_error,__LINE__,smb[cur_smb].file);
+	if((i=smb_locksmbhdr(smb))!=SMB_SUCCESS) {
+		lprintf(LOG_ERR,"ERROR %d (%s) line %d locking %s",i,smb->last_error,__LINE__,smb->file);
 		return(0); 
 	}
 
 	/* total msgs in sub */
-	total=filelength(fileno(smb[cur_smb].sid_fp))/sizeof(idxrec_t);
+	total=filelength(fileno(smb->sid_fp))/sizeof(idxrec_t);
 
 	if(!total) {			/* empty */
-		smb_unlocksmbhdr(&smb[cur_smb]);
+		smb_unlocksmbhdr(smb);
 		return(0); 
 	}
 
 	if(((*post)=(post_t*)malloc(sizeof(post_t)*total))    /* alloc for max */
 		==NULL) {
-		smb_unlocksmbhdr(&smb[cur_smb]);
+		smb_unlocksmbhdr(smb);
 		lprintf(LOG_ERR,"ERROR line %d allocating %lu bytes for %s",__LINE__
-			,sizeof(post_t *)*total,smb[cur_smb].file);
+			,sizeof(post_t *)*total,smb->file);
 		return(0); 
 	}
 
-	fseek(smb[cur_smb].sid_fp,0L,SEEK_SET);
-	for(l=0;l<total && !feof(smb[cur_smb].sid_fp); ) {
-		if(smb_fread(&smb[cur_smb], &idx,sizeof(idx),smb[cur_smb].sid_fp) != sizeof(idx))
+	fseek(smb->sid_fp,0L,SEEK_SET);
+	for(l=0;l<total && !feof(smb->sid_fp); ) {
+		if(smb_fread(smb, &idx,sizeof(idx),smb->sid_fp) != sizeof(idx))
 			break;
 
 		if(idx.number==0)	/* invalid message number, ignore */
@@ -2702,7 +2709,7 @@ ulong loadmsgs(post_t** post, ulong ptr)
 
 		(*post)[l++].idx=idx;
 	}
-	smb_unlocksmbhdr(&smb[cur_smb]);
+	smb_unlocksmbhdr(smb);
 	if(!l)
 		FREE_AND_NULL(*post);
 	return(l);
@@ -4401,17 +4408,17 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 			continue; 
 		}
 
-		sprintf(smb[cur_smb].file,"%s%s"
+		sprintf(smb->file,"%s%s"
 			,scfg.sub[i]->data_dir,scfg.sub[i]->code);
-		smb[cur_smb].retry_time=scfg.smb_retry_time;
+		smb->retry_time=scfg.smb_retry_time;
 		if((j=smb_open(&smb[cur_smb]))!=SMB_SUCCESS) {
-			lprintf(LOG_ERR,"ERROR %d (%s) line %d opening %s",j,smb[cur_smb].last_error,__LINE__
-				,smb[cur_smb].file);
+			lprintf(LOG_ERR,"ERROR %d (%s) line %d opening %s",j,smb->last_error,__LINE__
+				,smb->file);
 			continue; 
 		}
 
 		post=NULL;
-		posts=loadmsgs(&post,ptr);
+		posts=loadmsgs(&smb[cur_smb], &post, ptr);
 
 		if(!posts)	{ /* no new messages */
 			smb_close(&smb[cur_smb]);
@@ -4424,6 +4431,7 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 			lprintf(LOG_CRIT, "Failed to allocated memory for echostats!");
 			break;
 		}
+		stat->known = true;
 
 		for(m=exp=0;m<posts && !terminated;m++) {
 			printf("\r%*s %5lu of %-5"PRIu32"  "
@@ -4475,8 +4483,11 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 				continue; 
 			}
 
-			if(msg.hdr.type != SMB_MSG_TYPE_NORMAL)
+			if(msg.hdr.type != SMB_MSG_TYPE_NORMAL) {
+				smb_unlockmsghdr(&smb[cur_smb],&msg);
+				smb_freemsgmem(&msg);
 				continue;
+			}
 
 			memset(&hdr,0,sizeof(fmsghdr_t));	 /* Zero the header */
 			hdr.origzone=scfg.sub[i]->faddr.zone;
@@ -4515,6 +4526,7 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 					,__LINE__,fmsgbuflen);
 				smb_unlockmsghdr(&smb[cur_smb],&msg);
 				smb_freemsgmem(&msg);
+				free(buf);
 				continue; 
 			}
 			fmsgbuflen-=1024;	/* give us a bit of a guard band here */
@@ -4666,6 +4678,165 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 	exported_echomail += exported;
 }
 
+bool retoss_bad_echomail(void)
+{
+	area_t* badarea;
+
+	if(cfg.badecho < 0 || (uint)cfg.badecho >= cfg.areas)
+		return false;
+
+	badarea = &cfg.area[cfg.badecho];
+
+	int badsub = badarea->sub;
+	if(badsub < 0 || badsub >= scfg.total_subs)
+		return false;
+
+	printf("\nRe-tossing Bad EchoMail from %s...\n", scfg.sub[badsub]->code);
+
+	smb_t badsmb;
+	int retval = smb_open_sub(&scfg, &badsmb, badsub);
+	if(retval != SMB_SUCCESS) {
+		lprintf(LOG_ERR,"ERROR %d (%s) line %d opening %s", retval, badsmb.last_error,__LINE__
+			,badsmb.file);
+		return false; 
+	}
+
+	post_t *post = NULL;
+	ulong posts	= loadmsgs(&badsmb, &post, /* ptr: */0);
+
+	if(posts < 1) { /* no messages */
+		smb_close(&badsmb);
+		FREE_AND_NULL(post);
+		return false; 
+	}
+		
+	for(ulong m=0; m<posts && !terminated; m++) {
+		printf("\r%*s %5lu of %-5"PRIu32"  "
+			,LEN_EXTCODE,scfg.sub[badsub]->code,m+1,posts);
+		smbmsg_t badmsg;
+		memset(&badmsg, 0, sizeof(badmsg));
+		badmsg.idx = post[m].idx;
+		if((retval=smb_lockmsghdr(&badsmb, &badmsg))!=SMB_SUCCESS) {
+			lprintf(LOG_ERR,"ERROR %d (%s) line %d locking %s msghdr"
+				,retval,badsmb.last_error,__LINE__,badsmb.file);
+			continue; 
+		}
+		retval = smb_getmsghdr(&badsmb, &badmsg);
+		if(retval || badmsg.hdr.number != post[m].idx.number) {
+			smb_unlockmsghdr(&badsmb,&badmsg);
+			smb_freemsgmem(&badmsg);
+
+			badmsg.hdr.number=post[m].idx.number;
+			if((retval=smb_getmsgidx(&badsmb, &badmsg))!=SMB_SUCCESS) {
+				lprintf(LOG_ERR,"ERROR %d line %d reading %s index",retval,__LINE__
+					,badsmb.file);
+				continue; 
+			}
+			if((retval=smb_lockmsghdr(&badsmb,&badmsg))!=SMB_SUCCESS) {
+				lprintf(LOG_ERR,"ERROR %d line %d locking %s msghdr",retval,__LINE__
+					,badsmb.file);
+				continue; 
+			}
+			if((retval=smb_getmsghdr(&badsmb,&badmsg))!=SMB_SUCCESS) {
+				smb_unlockmsghdr(&badsmb,&badmsg);
+				lprintf(LOG_ERR,"ERROR %d line %d reading %s msghdr",retval,__LINE__
+					,badsmb.file);
+				continue; 
+			} 
+		}
+
+		if(badmsg.from_net.type != NET_FIDO 
+			|| badmsg.ftn_area == NULL
+			|| badmsg.hdr.type != SMB_MSG_TYPE_NORMAL) {
+			smb_unlockmsghdr(&badsmb,&badmsg);
+			smb_freemsgmem(&badmsg);
+			continue; 
+		}
+
+		uint areanum = find_area(badmsg.ftn_area);
+		if(!area_is_valid(areanum) || cfg.area[areanum].sub >= scfg.total_subs) {
+			smb_unlockmsghdr(&badsmb,&badmsg);
+			smb_freemsgmem(&badmsg);
+			continue; 
+		}
+		int subnum = cfg.area[areanum].sub;
+		printf("-> %s\n", scfg.sub[subnum]->code);
+		lprintf(LOG_DEBUG,"Moving %s message #%u to sub-board %s"
+			,scfg.sub[badsub]->code, badmsg.hdr.number, scfg.sub[subnum]->code);
+
+		smbmsg_t newmsg;
+		if((retval = smb_copymsgmem(NULL, &newmsg, &badmsg)) != SMB_SUCCESS) {
+			smb_unlockmsghdr(&badsmb,&badmsg);
+			smb_freemsgmem(&badmsg);
+			continue; 
+		}
+
+		char* body = smb_getmsgtxt(&badsmb, &badmsg, GETMSGTXT_BODY_ONLY);
+		if(body == NULL) {
+			smb_unlockmsghdr(&badsmb,&badmsg);
+			smb_freemsgmem(&badmsg);
+			smb_freemsgmem(&newmsg);
+			continue;
+		}
+		truncsp(body);
+		char* tail = smb_getmsgtxt(&badsmb, &badmsg, GETMSGTXT_TAIL_ONLY);
+		if(tail != NULL)
+			truncsp(tail);
+
+		/* Target sub-board: */
+		{
+			smb_t smb;
+			retval = smb_open_sub(&scfg, &smb, subnum);
+			if(retval != SMB_SUCCESS) {
+				lprintf(LOG_ERR,"ERROR %d (%s) line %d opening %s", retval, smb.last_error,__LINE__
+					,smb.file);
+				smb_unlockmsghdr(&badsmb,&badmsg);
+				smb_freemsgmem(&badmsg);
+				smb_freemsgmem(&newmsg);
+				FREE_AND_NULL(body);
+				FREE_AND_NULL(tail);
+				continue;
+			}
+
+			long	dupechk_hashes=SMB_HASH_SOURCE_DUPE;
+			if(smb.status.max_crcs == 0)
+				dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY);
+			char* body_start = body;
+			if(strncmp(body_start, "AREA:", 5) == 0) {
+				FIND_CHAR(body_start, '\r');
+				SKIP_CHARSET(body_start, "\r\n");
+			}
+			retval = smb_addmsg(&smb, &newmsg, smb.status.attr&SMB_HYPERALLOC, dupechk_hashes, XLAT_NONE
+				,body_start, tail);
+			FREE_AND_NULL(body);
+			FREE_AND_NULL(tail);
+
+			if(retval != SMB_SUCCESS) {
+				lprintf(LOG_ERR,"ERROR smb_addmsg(%s) returned %d: %s"
+					,scfg.sub[subnum]->code, retval, smb.last_error);
+			} else {
+				badmsg.hdr.attr |= MSG_DELETE;
+				if((retval = smb_updatemsg(&badsmb, &badmsg)) != SMB_SUCCESS)
+					lprintf(LOG_ERR,"!ERROR %d (%s) deleting msg #%u in bad echo sub"
+						,retval, badsmb.last_error, badmsg.hdr.number);
+				if(badmsg.hdr.auxattr&MSG_FILEATTACH)
+					delfattach(&scfg,&badmsg);
+			}
+			smb_close(&smb);
+		}
+		smb_unlockmsghdr(&badsmb,&badmsg);
+		smb_freemsgmem(&badmsg);
+		smb_freemsgmem(&newmsg);
+	}
+
+	smb_close(&badsmb);
+	FREE_AND_NULL(post);
+
+	printf("\r%*s\r", 70, "");
+	return true;
+}
+
+
 /* New Feature (as of Nov-22-2015):
    Export NetMail from SMB (data/mail) to .msg format
 */
@@ -4727,9 +4898,9 @@ int export_netmail(void)
 		if(cfg.delete_netmail || (msg.hdr.netattr&MSG_KILLSENT)) {
 			/* Delete exported netmail */
 			msg.hdr.attr |= MSG_DELETE;
-			if(smb_updatemsg(email, &msg) != SMB_SUCCESS)
-				lprintf(LOG_ERR,"!ERROR %d deleting mail msg #%u"
-					,email->last_error, msg.hdr.number);
+			if((i = smb_updatemsg(email, &msg)) != SMB_SUCCESS)
+				lprintf(LOG_ERR,"!ERROR %d (%s) deleting mail msg #%u"
+					,i, email->last_error, msg.hdr.number);
 			if(msg.hdr.auxattr&MSG_FILEATTACH)
 				delfattach(&scfg,&msg);
 			fseek(email->sid_fp, (msg.offset+1)*sizeof(msg.idx), SEEK_SET);
@@ -5469,9 +5640,10 @@ int main(int argc, char **argv)
 	"sbbsecho, by default, will NOT:\n\n"
 	" * Export echomail previously imported from FTN (-h to enable)\n"
 	" * Update echomail export pointers without exporting messages (-u to enable)\n"
+	" * Import echomail (re-toss) from the 'bad echo' sub-board (-r to enable)\n"
 	" * Generate AreaFix netmail reports/notifications for links (-g to enable)\n"
 	" * Display the parsed area file (e.g. AREAS.BBS) for debugging (-a to enable)\n"
-	" * Prompt for key-press upon normal exit (-@ to enable)\n"
+	" * Prompt for key-press upon exit (-@ to enable)\n"
 	" * Prompt for key-press upon abnormal exit (-w to enable)\n"
 	;
 
@@ -5559,6 +5731,9 @@ int main(int argc, char **argv)
 					case 'A':
 						opt_dump_area_file=true;
 						break;
+					case 'R':
+						opt_retoss_badmail=true;
+						break;
 					default:
 						fprintf(stderr, "Unsupported option: %c\n", argv[i][j]);
 					case '?':
@@ -5569,7 +5744,6 @@ int main(int argc, char **argv)
 					case 'J':
 					case 'L':
 					case 'O':
-					case 'R':
 					case 'S':
 					case 'X':
 					case 'Y':
@@ -5856,6 +6030,7 @@ int main(int argc, char **argv)
 		lprintf(LOG_DEBUG, "Read %u areas from %s", before, cfg.badareafile);
 		if(fp!=NULL)
 			fclose(fp);
+		lprintf(LOG_DEBUG, "Checking bad areas for areas we now carry - begin");
 		strListTruncateStrings(bad_areas, " \t\r\n");
 		for(i=0; bad_areas[i] != NULL; i++) {
 			if(area_is_valid(find_area(bad_areas[i]))) {			/* Do we carry this area? */
@@ -5864,6 +6039,7 @@ int main(int argc, char **argv)
 				i--;
 			}
 		}
+		lprintf(LOG_DEBUG, "Checking bad areas for areas we now carry - end");
 		after = strListCount(bad_areas);
 		if(before != after)
 			lprintf(LOG_NOTICE, "Removed %d areas from bad area file: %s", before-after, cfg.badareafile);
@@ -5877,6 +6053,9 @@ int main(int argc, char **argv)
 	if(cfg.echostats[0])
 		echostat_count = read_echostats(cfg.echostats, &echostat);
 
+	if(opt_retoss_badmail)
+		retoss_bad_echomail();
+
 	find_stray_packets();
 
 	if(opt_import_packets) {