Skip to content
Snippets Groups Projects
rechocfg.c 17.9 KiB
Newer Older
/* rechocfg.C */

/* 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)		*
 *																			*
rswindell's avatar
rswindell committed
 * 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>
rswindell's avatar
rswindell committed
#include <sys/stat.h>
rswindell's avatar
rswindell committed
#include "sbbs.h"
#include "sbbsecho.h"
#include "filewrap.h"	/* O_DENYNONE */

#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;

	for(i=0;instr[i];i++)
		if((uchar)instr[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;
rswindell's avatar
rswindell committed
		return(addr); 
	}
	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
rswindell's avatar
rswindell committed
			addr.net=atoi(p);
	}
	else {
	#ifdef SCFG
		if(total_faddrs)
			addr.zone=faddr[0].zone;
	#endif
			addr.zone=1;
rswindell's avatar
rswindell committed
		addr.net=atoi(str);
	}
	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
rswindell's avatar
rswindell committed
			addr.node=atoi(p);
	}
		if(!addr.net) {
	#ifdef SCFG
			if(total_faddrs)
				addr.net=faddr[0].net;
			else
	#endif
rswindell's avatar
rswindell committed
				addr.net=1;
		}
		addr.node=atoi(str);
	}
	if((p=strchr(str,'.'))!=NULL) {
		p++;
		if(!strnicmp(p,"ALL",3))
			addr.point=0xffff;
		else
rswindell's avatar
rswindell committed
			addr.point=atoi(p);
	}
	return(addr);
/******************************************************************************
 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)
rswindell's avatar
rswindell committed
			return(i);
	}

	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++
void read_echo_cfg()
{
	char *str = NULL;
	size_t str_size;
	char tmp[512],*p,*tp;
	int i,j,file;
	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);
rswindell's avatar
rswindell committed
		bail(1);
	}
	cfg.maxpktsize=DFLT_PKT_SIZE;
	cfg.maxbdlsize=DFLT_BDL_SIZE;
	cfg.badecho=-1;
	cfg.log=LOG_DEFAULTS;
	cfg.fwd_circular=TRUE;
	cfg.zone_blind_threshold=0xffff;
	while(1) {
		if(getdelim(&str,&str_size,'\n',stream)==-1)
			break;
		truncsp(str);
		p=str;
		if(*p==';')
			continue;
		sprintf(tmp,"%-.25s",p);
		tp=strchr(tmp,' ');
		if(tp)
			*tp=0;                              /* Chop off at space */
		strupr(tmp);                            /* Convert code to uppercase */
		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) {
deuce's avatar
deuce committed
				printf("\nError allocating %" XP_PRIsize_t "u bytes of memory for arcdef #%u.\n"
					,sizeof(arcdef_t)*(cfg.arcdefs+1),cfg.arcdefs+1);
rswindell's avatar
rswindell committed
				bail(1);
			}
			SAFECOPY(cfg.arcdef[cfg.arcdefs].name,p);
			tp=cfg.arcdef[cfg.arcdefs].name;
			while(*tp && *tp>' ') tp++;
			cfg.arcdef[cfg.arcdefs].byteloc=atoi(p);
			SAFECOPY(cfg.arcdef[cfg.arcdefs].hexid,p);
			tp=cfg.arcdef[cfg.arcdefs].hexid;
			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);
rswindell's avatar
rswindell committed
					continue;
				}
				if(!strnicmp(p,"UNPACK ",7)) {
					p+=7;
					SAFECOPY(cfg.arcdef[cfg.arcdefs].unpack,p);
rswindell's avatar
rswindell committed
					truncsp(cfg.arcdef[cfg.arcdefs].unpack);
				}
			}
			++cfg.arcdefs;
rswindell's avatar
rswindell committed
			continue;
		}
			continue;
		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);
			cfg.notify=atoi(cleanstr(p));
rswindell's avatar
rswindell committed
			continue;
		}
			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's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"LOG_LEVEL")) {
			cfg.log_level=atoi(cleanstr(p));
rswindell's avatar
rswindell committed
			continue;
		}
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"SECURE_ECHOMAIL")) {
			misc|=SECURE;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"STRIP_LF")) {
			misc|=STRIP_LF;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"CONVERT_TEAR")) {
			misc|=CONVERT_TEAR;
			continue;
		}

		if(!stricmp(tmp,"STORE_SEENBY")) {
			misc|=STORE_SEENBY;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"STORE_PATH")) {
			misc|=STORE_PATH;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"STORE_KLUDGE")) {
			misc|=STORE_KLUDGE;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"FUZZY_ZONE")) {
			misc|=FUZZY_ZONE;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"TRUNC_BUNDLES")) {
			misc|=TRUNC_BUNDLES;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"FLO_MAILER")) {
			misc|=FLO_MAILER;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"ELIST_ONLY")) {
			misc|=ELIST_ONLY;
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"KILL_EMPTY")) {
			misc|=KILL_EMPTY_MAIL;
rswindell's avatar
rswindell committed
			continue;
		}
			SAFECOPY(cfg.areafile,cleanstr(p));
rswindell's avatar
rswindell committed
			continue;
		}
			SAFECOPY(cfg.logfile,cleanstr(p));
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"INBOUND")) {            /* Inbound directory */
			SAFECOPY(cfg.inbound,cleanstr(p));
			backslash(cfg.inbound);
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"SECURE_INBOUND")) {     /* Secure Inbound directory */
			SAFECOPY(cfg.secure,cleanstr(p));
			backslash(cfg.secure);
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"OUTBOUND")) {           /* Outbound directory */
			SAFECOPY(cfg.outbound,cleanstr(p));
			backslash(cfg.outbound);
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"ARCSIZE")) {            /* Maximum bundle size */
			cfg.maxbdlsize=atol(p);
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"PKTSIZE")) {            /* Maximum packet size */
			cfg.maxpktsize=atol(p);
rswindell's avatar
rswindell committed
			continue;
		}
		if(!stricmp(tmp,"USEPACKER")) {          /* Which packer to use */
				continue;
			if(!*p)
				continue;
			*p=0;
			p++;
			for(u=0;u<cfg.arcdefs;u++)
rswindell's avatar
rswindell committed
				if(!stricmp(cfg.arcdef[u].name,str))
			if(u==cfg.arcdefs)				/* i = number of arcdef til done */
				u=0xffff;					/* Uncompressed type if not found */
			while(*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);
rswindell's avatar
rswindell committed
						bail(1);
					}
					memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
					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);
rswindell's avatar
rswindell committed
					bail(1);
				}
				memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
				cfg.nodecfg[j].faddr=addr;
			}
			SAFECOPY(cfg.nodecfg[j].pktpwd,p);
		}
		if(!stricmp(tmp,"PKTTYPE")) {            /* Packet Type to Use */
			if(!*p)
				continue;
			*p=0;
			p++;
			while(*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);
rswindell's avatar
rswindell committed
						bail(1);
					}
					memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
					cfg.nodecfg[j].faddr=addr;
				}
				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"))
rswindell's avatar
rswindell committed
					cfg.nodecfg[j].pkt_type=PKT_TWO;
			}
		}
		if(!stricmp(tmp,"SEND_NOTIFY")) {    /* Nodes to send notify lists to */
			while(*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);
rswindell's avatar
rswindell committed
						bail(1);
					}
					memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
					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"))
				attr=ATTR_PASSIVE;
				attr=ATTR_CRASH;
				attr=ATTR_HOLD;
			else if(!stricmp(tmp,"DIRECT"))
				attr=ATTR_DIRECT;
			while(*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);
rswindell's avatar
rswindell committed
						bail(1);
					}
					memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
					cfg.nodecfg[j].faddr=addr;
				}
				cfg.nodecfg[j].attr|=attr;
			}
		}
			if(*p) {
				route_addr=atofaddr(p);
rswindell's avatar
rswindell committed
				SKIPCODE(p);
			}
			while(*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);
rswindell's avatar
rswindell committed
						bail(1);
					}
					memset(&cfg.nodecfg[j],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
					cfg.nodecfg[j].faddr=addr;
				}
				cfg.nodecfg[j].route=route_addr;
			}
		}
		if(!stricmp(tmp,"AREAFIX")) {            /* Areafix stuff here */
				continue;
			addr=atofaddr(p);
			i=matchnode(addr,1);
			if(i==cfg.nodecfgs) {
				cfg.nodecfgs++;
				if((cfg.nodecfg=(nodecfg_t *)realloc(cfg.nodecfg
					,sizeof(nodecfg_t)*(i+1)))==NULL) {
					printf("\nError allocating memory for nodecfg #%u.\n"
rswindell's avatar
rswindell committed
					bail(1);
				}
				memset(&cfg.nodecfg[i],0,sizeof(nodecfg_t));
rswindell's avatar
rswindell committed
				cfg.nodecfg[i].faddr=addr;
			}
			cfg.nodecfg[i].flag=NULL;
			SKIPCODE(p); 		/* Get to the end of the address */
			SKIPCTRLSP(p);		/* Skip over whitespace chars */
			SKIPCODE(p); 		/* Find end of password 	*/
			*p=0;							/* and terminate the string */
			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 */
				*p=0;						/* and terminate it 	 */
				for(j=0;j<cfg.nodecfg[i].numflags;j++)
rswindell's avatar
rswindell committed
					if(!stricmp(cfg.nodecfg[i].flag[j].flag,tp))
						break;
				if(j==cfg.nodecfg[i].numflags) {
					if((cfg.nodecfg[i].flag=
						(flag_t *)realloc(cfg.nodecfg[i].flag
						,sizeof(flag_t)*(j+1)))==NULL) {
						printf("\nError allocating memory for nodecfg #%u "
							"flag #%u.\n",cfg.nodecfgs,j+1);
rswindell's avatar
rswindell committed
						bail(1);
					}
					cfg.nodecfg[i].numflags++;
rswindell's avatar
rswindell committed
					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);
rswindell's avatar
rswindell committed
				bail(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;
				if(*p)
					cfg.listcfg[cfg.listcfgs-1].forward=atofaddr(p);
				if(*p && !(cfg.listcfg[cfg.listcfgs-1].misc&NOFWD)) {
					tp=p;
rswindell's avatar
rswindell committed
					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 */
			while(*p) {
				tp=p;
				SKIPCODE(p); 	/* Find end of this flag */
				*p=0;						/* and terminate it 	 */
				++p;
				for(u=0;u<cfg.listcfg[cfg.listcfgs-1].numflags;u++)
rswindell's avatar
rswindell committed
					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);
rswindell's avatar
rswindell committed
						bail(1);
					}
					cfg.listcfg[cfg.listcfgs-1].numflags++;
rswindell's avatar
rswindell committed
					SAFECOPY(cfg.listcfg[cfg.listcfgs-1].flag[u].flag,tp);
				}
				SKIPCTRLSP(p); 
			} 
		}
		/* Message disabled why?  ToDo */
		/* printf("Unrecognized line in SBBSECHO.CFG file.\n"); */
	}
	fclose(stream);

	/* 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;

	printf("\n");