diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c
index 232bee97cdd90a2ada83d10d72f3748673fc5a37..570b25881e65b589462c3ff33981d7b2177fc1b9 100644
--- a/src/sbbs3/sbbsecho.c
+++ b/src/sbbs3/sbbsecho.c
@@ -106,6 +106,7 @@ bool terminated=false;
 str_list_t	locked_bso_nodes;
 
 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);
 
 const char default_domain[] = "fidonet";
@@ -138,6 +139,287 @@ const char* zone_root_outbound(uint16_t zone)
 	return cfg.outbound;
 }
 
+/* Allocates the buffer and returns the data (or NULL) */
+char* parse_control_line(const char* fmsgbuf, const char* kludge)
+{
+	char*	p;
+	char	str[128];
+
+	if(fmsgbuf == NULL)
+		return NULL;
+	sprintf(str, "\1%s", kludge);
+	p = strstr(fmsgbuf, str);
+	if(p == NULL)
+		return NULL;
+	if(p != fmsgbuf && *(p-1) != '\r' && *(p-1) != '\n')	/* Kludge must start new-line */
+		return NULL;
+	SAFECOPY(str, p);
+
+	/* Terminate at the CR */
+	p = strchr(str, '\r');
+	if(p == NULL)
+		return NULL;
+	*p = 0;
+
+	/* Only return the data portion */
+	p = str + strlen(kludge) + 1;
+	SKIP_WHITESPACE(p);
+	return strdup(p);
+}
+
+typedef struct echostat_msg {
+	char msg_id[128];
+	char reply_id[128];
+	char pid[128];
+	char tid[128];
+	char to[FIDO_NAME_LEN];
+	char from[FIDO_NAME_LEN];
+	char subj[FIDO_SUBJ_LEN];
+	time_t msgtime;
+	time_t localtime;
+	size_t length;
+	fidoaddr_t origaddr;
+	fidoaddr_t pkt_orig;
+} echostat_msg_t;
+
+enum echostat_msg_type {
+	ECHOSTAT_MSG_RECEIVED,
+	ECHOSTAT_MSG_IMPORTED,
+	ECHOSTAT_MSG_EXPORTED,
+	ECHOSTAT_MSG_DUPLICATE,
+	ECHOSTAT_MSG_CIRCULAR,
+	ECHOSTAT_MSG_TYPES
+};
+
+const char* echostat_msg_type[ECHOSTAT_MSG_TYPES] = {
+	"Received",
+	"Imported",
+	"Exported",
+	"Duplicate",
+	"Circular",
+};
+
+typedef struct echostat {
+	char tag[FIDO_AREATAG_LEN + 1];
+	echostat_msg_t last[ECHOSTAT_MSG_TYPES];
+	echostat_msg_t first[ECHOSTAT_MSG_TYPES];
+	ulong total[ECHOSTAT_MSG_TYPES];
+} echostat_t;
+
+echostat_t* echostat;
+size_t echostat_count;
+
+echostat_msg_t parse_echostat_msg(str_list_t ini, const char* section, const char* prefix)
+{
+	char str[128];
+	char key[128];
+	echostat_msg_t msg = {0};
+
+	sprintf(key, "%s.to", prefix),			iniGetString(ini, section, key, NULL, msg.to);
+	sprintf(key, "%s.from", prefix),		iniGetString(ini, section, key, NULL, msg.from);
+	sprintf(key, "%s.subj", prefix),		iniGetString(ini, section, key, NULL, msg.subj);
+	sprintf(key, "%s.msg_id", prefix),		iniGetString(ini, section, key, NULL, msg.msg_id);
+	sprintf(key, "%s.reply_id", prefix),	iniGetString(ini, section, key, NULL, msg.reply_id);
+	sprintf(key, "%s.pid", prefix),			iniGetString(ini, section, key, NULL, msg.pid);
+	sprintf(key, "%s.tid", prefix),			iniGetString(ini, section, key, NULL, msg.tid);
+	sprintf(key, "%s.msgtime", prefix),		msg.msgtime = iniGetDateTime(ini, section, key, 0);
+	sprintf(key, "%s.localtime", prefix),	msg.localtime = iniGetDateTime(ini, section, key, 0);
+	sprintf(key, "%s.length", prefix),		msg.length = (size_t)iniGetBytes(ini, section, key, 1, 0);
+	sprintf(key, "%s.origaddr", prefix),	iniGetString(ini, section, key, NULL, str);
+	if(str[0])	 msg.origaddr = atofaddr(str);
+	sprintf(key, "%s.pkt_orig", prefix),	iniGetString(ini, section, key, NULL, str);
+	if(str[0])	 msg.pkt_orig = atofaddr(str);
+
+	return msg;
+}
+
+echostat_msg_t fidomsg_to_echostat_msg(fmsghdr_t fmsghdr, fidoaddr_t* pkt_orig, const char* fmsgbuf)
+{
+	char* p;
+	echostat_msg_t msg = {0};
+
+	SAFECOPY(msg.to		, fmsghdr.to);
+	SAFECOPY(msg.from	, fmsghdr.from);
+	SAFECOPY(msg.subj	, fmsghdr.subj);
+	msg.msgtime			= fmsgtime(fmsghdr.time);
+	msg.localtime		= time(NULL);
+	msg.origaddr.zone	= fmsghdr.origzone;
+	msg.origaddr.net	= fmsghdr.orignet;
+	msg.origaddr.node	= fmsghdr.orignode;
+	msg.origaddr.point	= fmsghdr.origpoint;
+	if(pkt_orig != NULL)
+		msg.pkt_orig	= *pkt_orig;
+	if((p = parse_control_line(fmsgbuf, "MSGID:")) != NULL) {
+		SAFECOPY(msg.msg_id, p);
+		free(p);
+	}
+	if((p = parse_control_line(fmsgbuf, "REPLY:")) != NULL) {
+		SAFECOPY(msg.reply_id, p);
+		free(p);
+	}
+	if((p = parse_control_line(fmsgbuf, "PID:")) != NULL) {
+		SAFECOPY(msg.pid, p);
+		free(p);
+	}
+	if((p = parse_control_line(fmsgbuf, "TID:")) != NULL) {
+		SAFECOPY(msg.tid, p);
+		free(p);
+	}
+	if(fmsgbuf != NULL)
+		msg.length = strlen(fmsgbuf);
+
+	return msg;
+}
+
+echostat_msg_t smsg_to_echostat_msg(smbmsg_t smsg, size_t msglen)
+{
+	char* p;
+	echostat_msg_t emsg = {0};
+
+	SAFECOPY(emsg.to	, smsg.to);
+	SAFECOPY(emsg.from	, smsg.from);
+	SAFECOPY(emsg.subj	, smsg.subj);
+	emsg.msgtime		= smsg.hdr.when_written.time;
+	emsg.localtime		= time(NULL);
+	if(smsg.from_net.type == NET_FIDO && smsg.from_net.addr != NULL)
+		emsg.origaddr	= atofaddr(smsg.from_net.addr);
+	if((p = smsg.ftn_msgid) != NULL)
+		SAFECOPY(emsg.msg_id, p);
+	if((p = smsg.ftn_reply) != NULL)
+		SAFECOPY(emsg.reply_id, p);
+	if((p = smsg.ftn_pid) != NULL)
+		SAFECOPY(emsg.pid, p);
+	if((p = smsg.ftn_tid) != NULL)
+		SAFECOPY(emsg.tid, p);
+	emsg.length = msglen;
+
+	return emsg;
+}
+
+void new_echostat_msg(echostat_t* stat, enum echostat_msg_type type, echostat_msg_t msg)
+{
+	stat->last[type] = msg;
+	if(stat->first[type].localtime == 0)
+		stat->first[type] = msg;
+	stat->total[type]++;
+}
+
+size_t read_echostats(const char* fname, echostat_t **echostat)
+{
+	str_list_t ini;
+	FILE* fp = iniOpenFile(fname, FALSE);
+	if(fp == NULL)
+		return 0;
+
+	ini = iniReadFile(fp);
+	iniCloseFile(fp);
+
+	str_list_t echoes = iniGetSectionList(ini, NULL);
+	if(echoes == NULL) {
+		iniFreeStringList(ini);
+		return 0;
+	}
+
+	size_t echo_count = strListCount(echoes);
+	*echostat = malloc(sizeof(echostat_t) * echo_count);
+	if(*echostat == NULL) {
+		iniFreeStringList(echoes);
+		iniFreeStringList(ini);
+		return 0;
+	}
+	for(unsigned i = 0; i < echo_count; i++) {
+		echostat_t* stat = &(*echostat)[i];
+		SAFECOPY(stat->tag, echoes[i]);
+		for(int type = 0; type < ECHOSTAT_MSG_TYPES; type++) {
+			char prefix[32];
+			sprintf(prefix, "First%s", echostat_msg_type[type])
+				,stat->first[type]	= parse_echostat_msg(ini, stat->tag, prefix);
+			sprintf(prefix, "Last%s", echostat_msg_type[type])
+				,stat->last[type]	= parse_echostat_msg(ini, stat->tag, prefix);
+			sprintf(prefix, "Total%s", echostat_msg_type[type])
+				,stat->total[type] = iniGetLongInt(ini, stat->tag, prefix, 0);
+		}
+	}
+	iniFreeStringList(echoes);
+	iniFreeStringList(ini);
+
+	return echo_count;
+}
+
+/* Mimic iniSetDateTime() */
+const char* iniTimeStr(time_t t)
+{
+	static char	tstr[32];
+	char	tmp[32];
+	char*	p;
+
+	if(t == 0)
+		return "Never";
+	if((p = ctime_r(&t, tmp)) == NULL)
+		sprintf(tstr, "0x%lx", t);
+	else
+		sprintf(tstr, "%.3s %.2s %.4s %.8s", p+4, p+8, p+20, p+11);
+	
+	return tstr;
+}
+
+void write_echostat_msg(FILE* fp, echostat_msg_t msg, const char* prefix)
+{
+	echostat_msg_t zero = {0};
+	if(memcmp(&msg, &zero, sizeof(msg)) == 0)
+		return;
+	if(msg.to[0])		fprintf(fp, "%s.to = %s\n"			, prefix, msg.to);
+	if(msg.from[0])		fprintf(fp, "%s.from = %s\n"		, prefix, msg.from);
+	if(msg.subj[0])		fprintf(fp, "%s.subj = %s\n"		, prefix, msg.subj);
+	if(msg.msg_id[0])	fprintf(fp, "%s.msg_id = %s\n"		, prefix, msg.msg_id);
+	if(msg.reply_id[0])	fprintf(fp, "%s.reply_id = %s\n"	, prefix, msg.reply_id);
+	if(msg.pid[0])		fprintf(fp, "%s.pid = %s\n"			, prefix, msg.pid);
+	if(msg.tid[0])		fprintf(fp, "%s.tid = %s\n"			, prefix, msg.tid);
+	fprintf(fp, "%s.length = %lu\n"							, prefix, msg.length);
+	fprintf(fp, "%s.msgtime = %s\n"							, prefix, iniTimeStr(msg.msgtime));
+	fprintf(fp, "%s.localtime = %s\n"						, prefix, iniTimeStr(msg.localtime));
+	fprintf(fp, "%s.origaddr = %s\n"						, prefix, faddrtoa(&msg.origaddr));
+	fprintf(fp, "%s.pkt_orig = %s\n"						, prefix, faddrtoa(&msg.pkt_orig));
+}
+
+bool write_echostats(const char* fname, echostat_t* echostat, size_t echo_count)
+{
+	FILE* fp;
+
+	if((fp=fopen(fname, "w"))==NULL)
+		return false;
+
+	for(unsigned i = 0; i < echo_count; i++) {
+		echostat_t* stat = &echostat[i];
+		fprintf(fp, "[%s]\n"						, stat->tag);
+		for(int type = 0; type < ECHOSTAT_MSG_TYPES; type++) {
+			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]);
+		}
+		fprintf(fp, "\n");
+	}
+	fclose(fp);
+	return true;
+}
+
+echostat_t* get_echostat(const char* tag)
+{
+	for(unsigned int i = 0; i < echostat_count; i++) {
+		if(stricmp(echostat[i].tag, tag) == 0)
+			return &echostat[i];
+	}
+	echostat_t* new_echostat = realloc(echostat, sizeof(echostat_t) * (echostat_count + 1));
+	if(new_echostat == NULL)
+		return NULL;
+	echostat = new_echostat;
+	memset(&echostat[echostat_count], 0, sizeof(echostat_t));
+	SAFECOPY(echostat[echostat_count].tag, tag);
+
+	return &echostat[echostat_count++];
+}
+
 /* FTN-compliant "Program Identifier"/PID (also used as a "Tosser Identifier"/TID) */
 const char* sbbsecho_pid(void)
 {
@@ -2346,7 +2628,7 @@ const char* area_desc(const char* areatag)
 	char tag[FIDO_AREATAG_LEN+1];
 	static char desc[128];
 
-	for(int i=0; i<cfg.listcfgs; i++) {
+	for(uint i=0; i<cfg.listcfgs; i++) {
 		FILE* fp = fopen(cfg.listcfg[i].listpath, "r");
 		if(fp == NULL) {
 			lprintf(LOG_ERR, "ERROR %d (%s) opening %s", errno, strerror(errno), cfg.listcfg[i].listpath);
@@ -4065,6 +4347,12 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 			FREE_AND_NULL(post);
 			continue; 
 		}
+		
+		echostat_t* stat = get_echostat(tag);
+		if(stat == NULL) {
+			lprintf(LOG_CRIT, "Failed to allocated memory for echostats!");
+			break;
+		}
 
 		for(m=exp=0;m<posts && !terminated;m++) {
 			printf("\r%*s %5lu of %-5"PRIu32"  "
@@ -4269,17 +4557,18 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 				strcat((char *)fmsgbuf,str); 
 			}
 
-			for(k=0;k<cfg.areas;k++)
-				if(cfg.area[k].sub==i) {
-					cfg.area[k].exported++;
-					pkt_to_pkt(fmsgbuf,cfg.area[k]
-						,nodecfg ? &nodecfg->addr : NULL,hdr,msg_seen
-						,msg_path);
+			for(uint u=0; u < cfg.areas; u++) {
+				if(cfg.area[u].sub == i) {
+					cfg.area[u].exported++;
+					pkt_to_pkt(fmsgbuf, cfg.area[u]
+						,nodecfg ? &nodecfg->addr : NULL, hdr, msg_seen, msg_path);
 					break; 
 				}
-			FREE_AND_NULL(fmsgbuf);
+			}
 			exported++;
 			exp++;
+			new_echostat_msg(stat, ECHOSTAT_MSG_EXPORTED, smsg_to_echostat_msg(msg, strlen(fmsgbuf)));
+			FREE_AND_NULL(fmsgbuf);
 			printf("Exp: %lu ",exp);
 			smb_unlockmsghdr(&smb[cur_smb],&msg);
 			smb_freemsgmem(&msg); 
@@ -4294,11 +4583,11 @@ void export_echomail(const char* sub_code, const nodecfg_t* nodecfg, bool rescan
 
 	printf("\r%*s\r", 70, "");
 
-	for(i=0;i<cfg.areas;i++)
-		if(cfg.area[i].exported)
+	for(unsigned u=0; u<cfg.areas; u++)
+		if(cfg.area[u].exported)
 			lprintf(LOG_INFO,"Exported: %5u msgs %*s -> %s"
-				,cfg.area[i].exported,LEN_EXTCODE,scfg.sub[cfg.area[i].sub]->code
-				,cfg.area[i].name);
+				,cfg.area[u].exported,LEN_EXTCODE,scfg.sub[cfg.area[u].sub]->code
+				,cfg.area[u].name);
 
 	if(exported)
 		lprintf(LOG_INFO,"Exported: %5lu msgs total", exported);
@@ -4881,6 +5170,18 @@ void import_packets(const char* inbound, nodecfg_t* inbox, bool secure)
 				continue; 
 			}
 
+			p+=5;								/* Skip "AREA:" */
+			SKIP_WHITESPACE(p);					/* Skip any white space */
+			printf("%21s: ",p);                 /* Show areaname: */
+			SAFECOPY(areatag,p);
+
+			echostat_t* stat = get_echostat(areatag);
+			if(stat == NULL) {
+				lprintf(LOG_CRIT, "Failed to allocate memory for echostats!");
+				break;
+			}
+			new_echostat_msg(stat, ECHOSTAT_MSG_RECEIVED, fidomsg_to_echostat_msg(hdr, &pkt_orig, NULL));
+
 			if(!opt_import_echomail) {
 				printf("EchoMail Ignored");
 				seektonull(fidomsg);
@@ -4888,11 +5189,6 @@ void import_packets(const char* inbound, nodecfg_t* inbox, bool secure)
 				continue; 
 			}
 
-			p+=5;								/* Skip "AREA:" */
-			SKIP_WHITESPACE(p);					/* Skip any white space */
-			printf("%21s: ",p);                 /* Show areaname: */
-			SAFECOPY(areatag,p);
-
 			if(!secure && (nodecfg == NULL || nodecfg->pktpwd[0] == 0)) {
 				lprintf(LOG_WARNING, "Unauthenticated %s EchoMail from %s ignored"
 					,areatag, smb_faddrtoa(&pkt_orig, NULL));
@@ -4932,7 +5228,6 @@ void import_packets(const char* inbound, nodecfg_t* inbox, bool secure)
 			if(!parse_origin(fmsgbuf, &hdr))
 				lprintf(LOG_WARNING, "%s: Failed to parse Origin Line in message from %s (%s) in packet from %s: %s"
 					,areatag, hdr.from, fmsghdr_srcaddr_str(&hdr), smb_faddrtoa(&pkt_orig,NULL), packet);
-
 			if(cfg.secure_echomail && cfg.area[i].sub!=INVALID_SUB) {
 				if(!area_is_linked(i,&pkt_orig)) {
 					lprintf(LOG_WARNING, "%s: Security violation - %s not in AREAS.BBS"
@@ -4967,6 +5262,8 @@ void import_packets(const char* inbound, nodecfg_t* inbox, bool secure)
 					lprintf(LOG_NOTICE, "%s: Circular path detected for %s in message from %s (%s)"
 						,areatag,smb_faddrtoa(&scfg.faddr[j],NULL), hdr.from, fmsghdr_srcaddr_str(&hdr));
 					printf("\n");
+					new_echostat_msg(stat, ECHOSTAT_MSG_CIRCULAR
+						,fidomsg_to_echostat_msg(hdr, &pkt_orig, fmsgbuf));
 					continue; 
 				}
 			}
@@ -5039,6 +5336,8 @@ void import_packets(const char* inbound, nodecfg_t* inbox, bool secure)
 				lprintf(LOG_NOTICE, "%s Duplicate message from %s (%s) to %s, subject: %s"
 					,areatag, hdr.from, fmsghdr_srcaddr_str(&hdr), hdr.to, hdr.subj);
 				cfg.area[i].dupes++; 
+				new_echostat_msg(stat, ECHOSTAT_MSG_DUPLICATE
+					,fidomsg_to_echostat_msg(hdr, &pkt_orig, fmsgbuf));
 			}
 			else if(result==IMPORT_SUCCESS || (result==IMPORT_FILTERED_AGE && cfg.relay_filtered_msgs)) {	   /* Not a dupe */
 				strip_psb(fmsgbuf);
@@ -5060,10 +5359,13 @@ void import_packets(const char* inbound, nodecfg_t* inbox, bool secure)
 				} 
 				echomail++;
 				cfg.area[i].imported++;
+				new_echostat_msg(stat, ECHOSTAT_MSG_IMPORTED
+					,fidomsg_to_echostat_msg(hdr, &pkt_orig, fmsgbuf));
 			}
 			printf("\n");
 		}
 		fclose(fidomsg);
+		FREE_AND_NULL(fmsgbuf);
 
 		if(bad_packet)
 			rename_bad_packet(packet);
@@ -5336,9 +5638,9 @@ int main(int argc, char **argv)
 		SAFECOPY(cfg.outbound, outbound);
 		free(outbound);
 	}
-	for(i=0; i<cfg.nodecfgs; i++) {
-		if(cfg.nodecfg[i].inbox[0])
-			backslash(cfg.nodecfg[i].inbox);
+	for(uint u=0; u<cfg.nodecfgs; u++) {
+		if(cfg.nodecfg[u].inbox[0])
+			backslash(cfg.nodecfg[u].inbox);
 	}
 	
 	truncsp(cmdline);
@@ -5501,6 +5803,8 @@ int main(int argc, char **argv)
 		gen_notify_list(); 
 	}
 
+	echostat_count = read_echostats("../data/echostats.ini", &echostat);
+
 	find_stray_packets();
 
 	if(opt_import_packets) {
@@ -5511,13 +5815,13 @@ int main(int argc, char **argv)
 		/* to take care of any packets that may already be hanging around for some	 */
 		/* reason or another (thus the do/while loop) */
 
-		for(i=0; i<cfg.nodecfgs && !terminated; i++) {
-			if(cfg.nodecfg[i].inbox[0] == 0)
+		for(uint u=0; u<cfg.nodecfgs && !terminated; u++) {
+			if(cfg.nodecfg[u].inbox[0] == 0)
 				continue;
-			printf("Scanning %s inbox: %s\n", faddrtoa(&cfg.nodecfg[i].addr), cfg.nodecfg[i].inbox);
+			printf("Scanning %s inbox: %s\n", faddrtoa(&cfg.nodecfg[u].addr), cfg.nodecfg[u].inbox);
 			do {
-				import_packets(cfg.nodecfg[i].inbox, &cfg.nodecfg[i], /* secure: */true);
-			} while(unpack_bundle(cfg.nodecfg[i].inbox));
+				import_packets(cfg.nodecfg[u].inbox, &cfg.nodecfg[u], /* secure: */true);
+			} while(unpack_bundle(cfg.nodecfg[u].inbox));
 		}
 		if(cfg.secure_inbound[0] && !terminated) {
 			printf("Scanning secure inbound: %s\n", cfg.secure_inbound);
@@ -5538,21 +5842,21 @@ int main(int argc, char **argv)
 
 		/******* END OF IMPORT PKT ROUTINE *******/
 
-		for(i=0;i<cfg.areas;i++) {
-			if(cfg.area[i].imported)
+		for(uint u=0; u<cfg.areas; u++) {
+			if(cfg.area[u].imported)
 				lprintf(LOG_INFO,"Imported: %5u msgs %*s <- %s"
-					,cfg.area[i].imported,LEN_EXTCODE,scfg.sub[cfg.area[i].sub]->code
-					,cfg.area[i].name); 
+					,cfg.area[u].imported,LEN_EXTCODE,scfg.sub[cfg.area[u].sub]->code
+					,cfg.area[u].name); 
 		}
-		for(i=0;i<cfg.areas;i++) {
-			if(cfg.area[i].circular)
+		for(uint u=0; u<cfg.areas; u++) {
+			if(cfg.area[u].circular)
 				lprintf(LOG_INFO,"Circular: %5u detected in %s"
-					,cfg.area[i].circular,cfg.area[i].name); 
+					,cfg.area[u].circular, cfg.area[u].name); 
 		}
-		for(i=0;i<cfg.areas;i++) {
-			if(cfg.area[i].dupes)
+		for(uint u=0; u<cfg.areas; u++) {
+			if(cfg.area[u].dupes)
 				lprintf(LOG_INFO,"Duplicate: %4u detected in %s"
-					,cfg.area[i].dupes,cfg.area[i].name); 
+					,cfg.area[u].dupes, cfg.area[u].name); 
 		} 
 
 		if(echomail)
@@ -5625,17 +5929,17 @@ int main(int argc, char **argv)
 
 		lprintf(LOG_DEBUG,"Updating Message Pointers to Last Posted Message...");
 
-		for(j=0; j<cfg.areas; j++) {
+		for(uint u=0; u<cfg.areas; u++) {
 			uint32_t lastmsg;
-			if(j==cfg.badecho)	/* Don't scan the bad-echo area */
+			if(u==cfg.badecho)	/* Don't scan the bad-echo area */
 				continue;
-			i=cfg.area[j].sub;
+			i=cfg.area[u].sub;
 			if(i<0 || i>=scfg.total_subs)	/* Don't scan pass-through areas */
 				continue;
 			lprintf(LOG_DEBUG,"\n%-*.*s -> %s"
-				,LEN_EXTCODE, LEN_EXTCODE, scfg.sub[i]->code, cfg.area[j].name);
+				,LEN_EXTCODE, LEN_EXTCODE, scfg.sub[i]->code, cfg.area[u].name);
 			if(getlastmsg(i,&lastmsg,0) >= 0)
-				write_export_ptr(i, lastmsg, cfg.area[j].name);
+				write_export_ptr(i, lastmsg, cfg.area[u].name);
 		}
 	}
 
@@ -5643,6 +5947,8 @@ int main(int argc, char **argv)
 	if(nodecfg != NULL)
 		attachment(NULL,nodecfg->addr,ATTACHMENT_NETMAIL);
 
+	write_echostats("../data/echostats.ini", echostat, echostat_count);
+
 	if(email->shd_fp)
 		smb_close(email);