Commit 9f2c88e0 authored by rswindell's avatar rswindell
Browse files

Parse the old pre-standard TZUTCINFO kludge line in fidomsg_to_echostat_msg()

Use the SBBSecho PID info as the TID field, by default, in export echostats
Don't include the Total* stats that are zero, in echostats (0 is assumed)
Uppercase the echotag when auto-adding a sub to the Area File.
Implemented long-awaited "bad echo" re-toss feature (use '-R' command-line
option to enable).
parent 8856cce9
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment