Newer
Older
/* Synchronet FidoNet EchoMail Scanning/Tossing and NetMail Tossing Utility */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
/* Portions written by Allen Christiansen 1994-1996 */
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#ifdef __WATCOMC__
#include <mem.h>
#define O_DENYNONE SH_DENYNO
#endif
extern long misc;
extern config_t cfg;
/******************************************************************************
Here we take a string and put a terminator in place of the first TAB or SPACE
******************************************************************************/
char *cleanstr(char *instr)
{
int i;
break;
instr[i]=0;
return(instr);
/****************************************************************************/
/* Returns the FidoNet address kept in str as ASCII. */
/****************************************************************************/
faddr_t atofaddr(char *instr)
{
char *p,str[51];
faddr_t addr;
sprintf(str,"%.50s",instr);
cleanstr(str);
if(!stricmp(str,"ALL")) {
addr.zone=addr.net=addr.node=addr.point=0xffff;
addr.zone=addr.net=addr.node=addr.point=0;
if((p=strchr(str,':'))!=NULL) {
if(!strnicmp(str,"ALL:",4))
addr.zone=0xffff;
else
addr.zone=atoi(str);
p++;
if(!strnicmp(p,"ALL",3))
addr.net=0xffff;
else
if(!addr.zone) /* no such thing as zone 0 */
addr.zone=1;
if((p=strchr(str,'/'))!=NULL) {
p++;
if(!strnicmp(p,"ALL",3))
addr.node=0xffff;
else
if(!addr.net) {
#ifdef SCFG
if(total_faddrs)
addr.net=faddr[0].net;
else
#endif
if((p=strchr(str,'.'))!=NULL) {
p++;
if(!strnicmp(p,"ALL",3))
addr.point=0xffff;
else
/******************************************************************************
This function returns the number of the node in the SBBSECHO.CFG file which
matches the address passed to it (or cfg.nodecfgs if no match).
******************************************************************************/
int matchnode(faddr_t addr, int exact)
{
if(exact!=2) {
for(i=0;i<cfg.nodecfgs;i++) /* Look for exact match */
if(!memcmp(&cfg.nodecfg[i].faddr,&addr,sizeof(faddr_t)))
break;
if(exact || i<cfg.nodecfgs)
for(i=0;i<cfg.nodecfgs;i++) /* Look for point match */
if(cfg.nodecfg[i].faddr.point==0xffff
&& addr.zone==cfg.nodecfg[i].faddr.zone
&& addr.net==cfg.nodecfg[i].faddr.net
&& addr.node==cfg.nodecfg[i].faddr.node)
if(i<cfg.nodecfgs)
return(i);
for(i=0;i<cfg.nodecfgs;i++) /* Look for node match */
if(cfg.nodecfg[i].faddr.node==0xffff
&& addr.zone==cfg.nodecfg[i].faddr.zone
&& addr.net==cfg.nodecfg[i].faddr.net)
break;
if(i<cfg.nodecfgs)
return(i);
for(i=0;i<cfg.nodecfgs;i++) /* Look for net match */
if(cfg.nodecfg[i].faddr.net==0xffff
&& addr.zone==cfg.nodecfg[i].faddr.zone)
break;
if(i<cfg.nodecfgs)
return(i);
for(i=0;i<cfg.nodecfgs;i++) /* Look for total wild */
if(cfg.nodecfg[i].faddr.zone==0xffff)
break;
return(i);
#define SKIPCTRLSP(p) while(*p>0 && *p<=' ') p++
#define SKIPCODE(p) while(*p<0 || *p>' ') p++
char *str = NULL;
size_t str_size;
char tmp[512],*p,*tp;
FILE *stream;
faddr_t addr,route_addr;
/****** READ IN SBBSECHO.CFG FILE *******/
printf("\nReading %s\n",cfg.cfgfile);
if((stream=fnopen(&file,cfg.cfgfile,O_RDONLY))==NULL) {
printf("Unable to open %s for read.\n",cfg.cfgfile);
cfg.maxpktsize=DFLT_PKT_SIZE;
cfg.maxbdlsize=DFLT_BDL_SIZE;
cfg.badecho=-1;
cfg.log=LOG_DEFAULTS;

rswindell
committed
cfg.log_level=LOG_INFO;
cfg.check_path=TRUE;
cfg.fwd_circular=TRUE;
cfg.zone_blind=FALSE;
cfg.zone_blind_threshold=0xffff;
SAFECOPY(cfg.sysop_alias,"SYSOP");
if(getdelim(&str,&str_size,'\n',stream)==-1)
if(*p==';')
continue;
sprintf(tmp,"%-.25s",p);
if(tp)
*tp=0; /* Chop off at space */
#if 0
strupr(tmp); /* Convert code to uppercase */
#endif
SKIPCODE(p); /* Skip code */
SKIPCTRLSP(p); /* Skip white space */
if(!stricmp(tmp,"SYSOP_ALIAS")) {
SAFECOPY(cfg.sysop_alias, p);
continue;
}
if(!stricmp(tmp,"PACKER")) { /* Archive Definition */
if((cfg.arcdef=(arcdef_t *)realloc(cfg.arcdef
,sizeof(arcdef_t)*(cfg.arcdefs+1)))==NULL) {
printf("\nError allocating %" XP_PRIsize_t "u bytes of memory for arcdef #%u.\n"
,sizeof(arcdef_t)*(cfg.arcdefs+1),cfg.arcdefs+1);
SAFECOPY(cfg.arcdef[cfg.arcdefs].name,p);
while(*tp && *tp>' ') tp++;
SKIPCODE(p);
SKIPCTRLSP(p);
cfg.arcdef[cfg.arcdefs].byteloc=atoi(p);
SKIPCODE(p);
SKIPCTRLSP(p);
SAFECOPY(cfg.arcdef[cfg.arcdefs].hexid,p);
while((getdelim(&str,&str_size,'\n',stream) != -1) && strnicmp(str,"END",3)) {
if(!strnicmp(p,"PACK ",5)) {
p+=5;
SAFECOPY(cfg.arcdef[cfg.arcdefs].pack,p);
truncsp(cfg.arcdef[cfg.arcdefs].pack);
if(!strnicmp(p,"UNPACK ",7)) {
p+=7;
SAFECOPY(cfg.arcdef[cfg.arcdefs].unpack,p);
truncsp(cfg.arcdef[cfg.arcdefs].unpack);
}
}
if(!stricmp(tmp,"REGNUM"))
if(!stricmp(tmp,"NOPATHCHECK")) {
cfg.check_path=FALSE;
continue;
}
if(!stricmp(tmp,"NOCIRCULARFWD")) {
cfg.fwd_circular=FALSE;
continue;
}
if(!stricmp(tmp,"ZONE_BLIND")) {
cfg.zone_blind=TRUE;
if(*p && isdigit(*p)) /* threshold specified (zones > this threshold will be treated normally/separately) */
cfg.zone_blind_threshold=atoi(p);
continue;
}
if(!stricmp(tmp,"NOTIFY")) {
if(!stricmp(tmp,"LOG")) {
cleanstr(p);
if(!stricmp(p,"ALL"))
cfg.log=0xffffffffUL;
else if(!stricmp(p,"DEFAULT"))
cfg.log=LOG_DEFAULTS;
else if(!stricmp(p,"NONE"))
cfg.log=0L;
else
cfg.log=strtol(cleanstr(p),0,16);

rswindell
committed
if(!stricmp(tmp,"LOG_LEVEL")) {
cfg.log_level=atoi(cleanstr(p));

rswindell
committed
if(!stricmp(tmp,"NOSWAP")) {
if(!stricmp(tmp,"SECURE_ECHOMAIL")) {
if(!stricmp(tmp,"STRIP_LF")) {
misc|=STRIP_LF;
if(!stricmp(tmp,"CONVERT_TEAR")) {
misc|=CONVERT_TEAR;
continue;
}
if(!stricmp(tmp,"STORE_SEENBY")) {
if(!stricmp(tmp,"STORE_PATH")) {
if(!stricmp(tmp,"STORE_KLUDGE")) {
if(!stricmp(tmp,"FUZZY_ZONE")) {
if(!stricmp(tmp,"TRUNC_BUNDLES")) {
misc|=TRUNC_BUNDLES;
if(!stricmp(tmp,"FLO_MAILER")) {
if(!stricmp(tmp,"ELIST_ONLY")) {
if(!stricmp(tmp,"KILL_EMPTY")) {
if(!stricmp(tmp,"AREAFILE")) {
SAFECOPY(cfg.areafile,cleanstr(p));
if(!stricmp(tmp,"LOGFILE")) {
SAFECOPY(cfg.logfile,cleanstr(p));
if(!stricmp(tmp,"INBOUND")) { /* Inbound directory */
SAFECOPY(cfg.inbound,cleanstr(p));
if(!stricmp(tmp,"SECURE_INBOUND")) { /* Secure Inbound directory */
if(!stricmp(tmp,"OUTBOUND")) { /* Outbound directory */
SAFECOPY(cfg.outbound,cleanstr(p));
if(!stricmp(tmp,"ARCSIZE")) { /* Maximum bundle size */
if(!stricmp(tmp,"PKTSIZE")) { /* Maximum packet size */
if(!stricmp(tmp,"USEPACKER")) { /* Which packer to use */
strcpy(str,p);
if(!*p)
continue;
*p=0;
p++;
for(u=0;u<cfg.arcdefs;u++)
if(u==cfg.arcdefs) /* i = number of arcdef til done */
u=0xffff; /* Uncompressed type if not found */
if(!*p)
break;
addr=atofaddr(p);
j=matchnode(addr,1);
if(j==cfg.nodecfgs) {
cfg.nodecfgs++;
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
,sizeof(nodecfg_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u.\n"
,j+1);
memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
cfg.nodecfg[j].faddr=addr;
}
cfg.nodecfg[j].arctype=u;
}
}
if(!stricmp(tmp,"PKTPWD")) { /* Packet Password */
if(!*p)
continue;
addr=atofaddr(p);
SKIPCODE(p); /* Skip address */
SKIPCTRLSP(p); /* Find beginning of password */
j=matchnode(addr,1);
if(j==cfg.nodecfgs) {
cfg.nodecfgs++;
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
,sizeof(nodecfg_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u.\n"
,j+1);
memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
cfg.nodecfg[j].faddr=addr;
}
SAFECOPY(cfg.nodecfg[j].pktpwd,p);
}
if(!stricmp(tmp,"PKTTYPE")) { /* Packet Type to Use */
strcpy(str,p);
if(!*p)
break;
addr=atofaddr(p);
j=matchnode(addr,1);
if(j==cfg.nodecfgs) {
cfg.nodecfgs++;
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
,sizeof(nodecfg_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u.\n"
,j+1);
memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
if(!strcmp(str,"2+"))
cfg.nodecfg[j].pkt_type=PKT_TWO_PLUS;
else if(!strcmp(str,"2.2"))
cfg.nodecfg[j].pkt_type=PKT_TWO_TWO;
else if(!strcmp(str,"2"))
if(!stricmp(tmp,"SEND_NOTIFY")) { /* Nodes to send notify lists to */
if(!*p)
break;
addr=atofaddr(p);
j=matchnode(addr,1);
if(j==cfg.nodecfgs) {
cfg.nodecfgs++;
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
,sizeof(nodecfg_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u.\n"
,j+1);
memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
cfg.nodecfg[j].faddr=addr;
}
cfg.nodecfg[j].attr|=SEND_NOTIFY;
}
}
if(!stricmp(tmp,"PASSIVE")
|| !stricmp(tmp,"HOLD")
|| !stricmp(tmp,"CRASH")
|| !stricmp(tmp,"DIRECT")) { /* Set node attributes */
if(!stricmp(tmp,"PASSIVE"))
else if(!stricmp(tmp,"CRASH"))
else if(!stricmp(tmp,"HOLD"))
else if(!stricmp(tmp,"DIRECT"))
if(!*p)
break;
addr=atofaddr(p);
j=matchnode(addr,1);
if(j==cfg.nodecfgs) {
cfg.nodecfgs++;
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
,sizeof(nodecfg_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u.\n"
,j+1);
memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
cfg.nodecfg[j].faddr=addr;
}
cfg.nodecfg[j].attr|=attr;
}
}
if(!stricmp(tmp,"ROUTE_TO")) {
if(!*p)
break;
addr=atofaddr(p);
j=matchnode(addr,1);
if(j==cfg.nodecfgs) {
cfg.nodecfgs++;
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
,sizeof(nodecfg_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u.\n"
,j+1);
memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
cfg.nodecfg[j].faddr=addr;
}
cfg.nodecfg[j].route=route_addr;
}
}
if(!stricmp(tmp,"AREAFIX")) { /* Areafix stuff here */
i=matchnode(addr,1);
if(i==cfg.nodecfgs) {
if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
printf("\nError allocating memory for nodecfg #%u.\n"
memset(&cfg.nodecfg[i],0,sizeof(nodecfg_t));
SKIPCODE(p); /* Get to the end of the address */
SKIPCTRLSP(p); /* Skip over whitespace chars */
SKIPCODE(p); /* Find end of password */
SAFECOPY(cfg.nodecfg[i].password,tp);
SKIPCTRLSP(p); /* Search for more chars */
if(!*p) /* Nothing else there */
continue;
while(*p) {
SKIPCODE(p); /* Find end of this flag */
for(j=0;j<cfg.nodecfg[i].numflags;j++)
break;
if(j==cfg.nodecfg[i].numflags) {
if((cfg.nodecfg[i].flag=
,sizeof(flag_t)*(j+1)))==NULL) {
printf("\nError allocating memory for nodecfg #%u "
"flag #%u.\n",cfg.nodecfgs,j+1);
SAFECOPY(cfg.nodecfg[i].flag[j].flag,tp);
}
SKIPCTRLSP(p);
}
}
if(!stricmp(tmp,"ECHOLIST")) { /* Echolists go here */
if((cfg.listcfg=(echolist_t *)realloc(cfg.listcfg
,sizeof(echolist_t)*(cfg.listcfgs+1)))==NULL) {
printf("\nError allocating memory for echolist cfg #%u.\n"
,cfg.listcfgs+1);
memset(&cfg.listcfg[cfg.listcfgs],0,sizeof(echolist_t));
++cfg.listcfgs;
/* Need to forward requests? */
if(!strnicmp(p,"FORWARD ",8) || !strnicmp(p,"HUB ",4)) {
if(!strnicmp(p,"HUB ",4))
cfg.listcfg[cfg.listcfgs-1].misc|=NOFWD;
SKIPCODE(p);
SKIPCTRLSP(p);
if(*p)
cfg.listcfg[cfg.listcfgs-1].forward=atofaddr(p);
SKIPCODE(p);
SKIPCTRLSP(p);
if(*p && !(cfg.listcfg[cfg.listcfgs-1].misc&NOFWD)) {
tp=p;
SAFECOPY(cfg.listcfg[cfg.listcfgs-1].password,tp);
}
}
else
cfg.listcfg[cfg.listcfgs-1].misc|=NOFWD;
if(!*p)
continue;
SAFECOPY(cfg.listcfg[cfg.listcfgs-1].listpath,tp);
cfg.listcfg[cfg.listcfgs-1].numflags=0;
cfg.listcfg[cfg.listcfgs-1].flag=NULL;
SKIPCTRLSP(p); /* Skip over whitespace chars */
SKIPCODE(p); /* Find end of this flag */
*p=0; /* and terminate it */
++p;
for(u=0;u<cfg.listcfg[cfg.listcfgs-1].numflags;u++)
if(!stricmp(cfg.listcfg[cfg.listcfgs-1].flag[u].flag,tp))
if(u==cfg.listcfg[cfg.listcfgs-1].numflags) {
if((cfg.listcfg[cfg.listcfgs-1].flag=
(flag_t *)realloc(cfg.listcfg[cfg.listcfgs-1].flag
,sizeof(flag_t)*(u+1)))==NULL) {
printf("\nError allocating memory for listcfg #%u "
"flag #%u.\n",cfg.listcfgs,u+1);
cfg.listcfg[cfg.listcfgs-1].numflags++;
SAFECOPY(cfg.listcfg[cfg.listcfgs-1].flag[u].flag,tp);
}
SKIPCTRLSP(p);
}
}
/* Message disabled why? ToDo */
/* printf("Unrecognized line in SBBSECHO.CFG file.\n"); */
/* make sure we have some sane "maximum" size values here: */
if(cfg.maxpktsize<1024)
cfg.maxpktsize=DFLT_PKT_SIZE;
if(cfg.maxbdlsize<1024)
cfg.maxbdlsize=DFLT_BDL_SIZE;
if(str)
free(str);