home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_ra
/
msgq160s.arj
/
CONFIG.C
< prev
next >
Wrap
Text File
|
1991-07-28
|
46KB
|
1,816 lines
/*
* CONFIG.C - Config file
*
* Msged/Q message editor for QuickBBS Copyright 1990 by P.J. Muller
*
*/
#define TEXTLEN 200
#define BUFSIZE 4096 /* buffer size for config files */
#define TOSSCAN /* last-minute addition, Local for TosScan */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <ctype.h>
#include <fcntl.h>
#include <mem.h>
#if defined(__TURBOC__) || defined(__JPIC__)
#include <dir.h>
#endif
#ifdef __MSC__
#include <sys/types.h>
#endif
#include <sys/stat.h>
#include "msged.h"
#include "screen.h"
#include "editmail.h"
#include "maincmds.h"
#include "p2c.h"
#include "shell.h"
#include "ra.h"
enum {A_LOCAL=1, A_NETM, A_ECHO}; /* area types */
enum {F_PRIV=1, F_CRASH=2, F_KILL=4, F_SOFT=8}; /* flag bits */
enum {INFO,WARN,ERR,FATAL}; /* log types */
static int insertarea; /* position for inserting next area */
/* if -1, insert at end */
static int initerrors; /* number of errors */
static int initwarnings; /* number of warnings */
#ifdef TOSSCAN
static BOOLEAN tosscan = FALSE;
#endif
static void checkareas(char *cpath);
static void set_colors(char *keyword,char *value);
static void init(void);
static void parsemail(char *keyword, char *value);
static void parseconfig(FILE *fp);
static unsigned int *parse_macro(char *macro);
static void addarea(char *tag, char *desc, BYTE board, BYTE areatype,
BYTE flag, BYTE aka, char *orig);
static void readconfigbbs(void);
static void createconfigbbs(void);
static void readraconfigs(void);
void checkorig(void);
/* Not for tc++ static int numlookup(struct _nentry *tab, char *val); */
static void log(BYTE type, char *msg, char *param);
static void verifyorigin(char *origin, ADDRESS addr);
#ifdef DBRIDGE
static void readdbridgeprm(void);
static void readdbridgeconfigs(void);
static void readdbridgeprm(void);
#endif
/*
* Config keyword dispatcher jump table
*/
struct _centry {
char *label;
void (*action)(char *keyword, char *value);
};
struct _nentry {
char *label;
int value;
};
struct _ientry {
char *label;
int *value;
};
static unsigned int *parse_macro(char *macro)
{
unsigned int *m;
unsigned int *t;
char tmp[5];
t = m = (unsigned int *) calloc(strlen(macro), sizeof(int));
if ((t == NULL) || (macro == NULL))
return(NULL);
while (*macro) {
if (*macro == '^') {
if (*(macro + 1) == '^')
*t++ = (unsigned int) '^';
else
*t++ = (unsigned int) (toupper(*(macro + 1)) - 64);
macro += 2;
}
else if (*macro == '\\') {
if (*(macro + 1) != '0') { /* escape */
*t++ = (unsigned int) *(++macro);
++macro;
} /* must be of form '\0xhh' */
else {
memset(tmp,0,sizeof tmp);
strncpy(tmp,macro+1,4);
*t++ = (unsigned int) strtol(tmp,NULL,0) << 8;
macro += 5;
}
}
else
*t++ = (unsigned int) *macro++;
}
*t = 0;
return(m);
} /* parse_macro */
static void log(BYTE type, char *msg, char *param)
{
char ch;
switch (type) {
case INFO:
if (!configdebug) return;
ch = ' ';
break;
case WARN:
if (!configdebug) return;
++initwarnings;
ch = '-';
break;
case ERR:
++initerrors;
ch = '!';
break;
case FATAL:
++initerrors;
ch = '?';
break;
default:
ch = '#';
break;
} /* switch */
printf("%c ",ch);
printf(msg,param);
printf("\n");
if (type == FATAL) {
printf(" A fatal error occurred, I cannot continue.\n");
halt(255);
} /* if */
} /* log */
void opening(char *cfgfile, char *areafile, char *uname)
{
int y, c;
FILE *fp = NULL;
char fname[TEXTLEN];
initerrors = initwarnings = 0;
init(); /* set defaults */
insertarea = -1; /* insert areas at end */
if (createconfig)
log(INFO,"Will create new CONFIG.BBS with netmailpath '%s'",newnetpath);
if (quicksysop) { /* first read CONFIG.BBS if needed */
log(INFO, "Reading QuickBBS configs", NULL);
readconfigbbs();
}
if (rastruct) { /* read RA messages file if needed */
log(INFO, "Reading RemoteAccess configs", NULL);
readraconfigs();
}
#ifdef DBRIDGE
if (dbridgestruct) { /* read D'Bridge messages file if needed */
log(INFO, "Reading D'Bridge configs", NULL);
readdbridgeconfigs();
}
#endif
/*- Moved here 22/01/90 -*/
checkareas(areafile); /* read areas.bbs */
/* start looking for the ascii config file... */
fname[0] = EOS;
if (cfgfile != NULL) { /* first try the specified file */
strcpy(fname,cfgfile);
fp = fopen(fname,"rt");
} /* if */
if (fp == NULL) { /* now try $BINKLEY\binkley.cfg */
char *env = getenv("BINKLEY");
fname[0] = EOS;
if (env != NULL) {
strcpy(fname,env);
if (strchr("/\\",fname[strlen(fname)-1]) == NULL)
strcat(fname,"\\");
} /* if */
strcat(fname,"binkley.cfg");
fp = fopen(fname,"rt");
} /* if */
if (fp == NULL) { /* now try msged.cfg */
strcpy(fname,"msged.cfg");
fp = fopen(fname,"rt");
} /* if */
if (fp == NULL) { /* now try msgedq.cfg */
strcpy(fname,"msgedq.cfg");
fp = fopen(fname,"rt");
} /* if */
if (fp != NULL) { /* we found a file */
char *buf = malloc(BUFSIZE);
log(INFO,"Reading '%s'", fname);
if (buf != NULL)
setvbuf(fp,buf,_IOFBF,BUFSIZE);
insertarea = 0; /* insert at front */
parseconfig(fp);
if (fp != NULL)
fclose(fp);
if (buf != NULL)
ptrfree(buf);
} /* if */
video_init();
if (co_quote == 0)
co_quote = co_normal;
if (rm > maxx)
rm = maxx - 1;
if (quoteright > rm-15)
quoteright = rm-15;
else if (quoteright < 20)
quoteright = 20;
if (uname != NULL) { /* override */
if (username != NULL) ptrfree(username);
username = strdup(uname);
log(INFO,"Command line username override '%s'", username);
}
if ((username == NULL) || (addresses == 0))
log(FATAL,"I could not find a username or address",NULL);
if (areas == 0)
log(FATAL,"I hate to mention the obvious, but you defined no areas!",NULL);
#ifdef TOSSCAN
if (tosscan) {
int c;
for (c=0; c < areas; c++)
arealist[c].msgbits.is_local = 1; /* all messages local */
} /* if */
#endif
if (createconfig)
if (quicksysop)
log(ERR,"I won't create CONFIG.BBS for you, a QuickBBS sysop should use QCONFIG",NULL);
else
createconfigbbs();
if (useusersbbs) {
if ((usernum = searchuser(username, TRUE)) == -1) {
log(ERR,"Could not find user '%s', defaulting to UserNumber 0\n",username);
usernum = 0;
} /* if */
} else usernum = 0; /* if USERS.BBS not searched */
checkorig(); /* Check for origin overrides */
if (createconfig) {
log(INFO, "Exit after rebuilding CONFIG.BBS",NULL);
halt(200);
} /* if */
if (configdebug || (initerrors != 0) || (initwarnings != 0)) {
if (initerrors != 0) {
log(ERR,"Pardon me, I think I spotted something wrong.",NULL);
if (!configdebug)
printf("Try the -d command line switch to debug your config file.\n");
} else if (initwarnings != 0) {
log(WARN,"I saw some warnings above...",NULL);
} /* else */
printf("Press <Return> to continue please:");
while (getkey() != 0x0d)
/* loop */;
} /* if */
set_color(co_normal);
cls();
gotoxy(1, maxy); video_update();
gotoxy(1, y=1);
set_color(co_hilite);
bputs("------------------------------------------------------------------------------");
set_color(co_normal);
gotoxy(10, y+=2);
bputs("Msged/Q " VERSION " - QuickBBS/RemoteAccess Compatible Mail Editor");
set_color(co_normal);
gotoxy(10, y+=2);
bputs("Copyright 1991 by Pieter Muller, 5:7102/11"
#ifdef __DATE__
" (" __DATE__ ")"
#endif
);
gotoxy(10, y+=2);
bputs("Based on msged 1.99 by Jim Nutt");
gotoxy(1, y+=2);
set_color(co_hilite);
bputs("---- SETUP -------------------------------------------------------------------");
set_color(co_info);
gotoxy(1, y+=2);
bprintf(" Sysop: %s", username);
for (c=0; c < addresses; ++c) {
char pointstr[80];
if ((thisnode[c].point) && (pointnet != 0))
sprintf(pointstr, "(private net %d/%d)", pointnet, thisnode[c].point);
else
pointstr[0] = EOS;
gotoxy(1, ++y);
bprintf("%9s: %s %s", c==0 ? "Address" : "AKA",
formaddr(thisnode[c], Z_A|N_A|P_O|D_O),
pointstr);
}
{ char buffer[200];
formatorigin(buffer, origin, thisnode[0]);
gotoxy(1, ++y);
bputs(buffer);
}
gotoxy(1, ++y);
bprintf("Msg Areas: %d found", areas);
gotoxy(1, ++y);
bprintf(" Video: %d by %d ", maxx, maxy);
switch (videomethod) {
case DIRECT:
bputs("direct"); break;
case BIOS:
bputs("bios"); break;
case FOSSIL:
bputs("fossil"); break;
case NOSNOW:
bputs("no-snow"); break;
} /* switch */
set_color(co_normal);
gotoxy(1,y+2);
} /* opening */
ADDRESS parsenode(char *t)
{
ADDRESS tmp;
char *s = NULL, *str = NULL;
memset(&tmp, 0, sizeof tmp);
if ((s = strrchr(t,'@')) != NULL) {
size_t len;
tmp.domain = strdup(s + 1);
len = strcspn(tmp.domain, " \t\n\r;");
tmp.domain[len] = EOS;
} else
tmp.domain = NULL;
str = s = strdup(t);
if (strchr(t, ':')) {
tmp.zone = (int) strtol(strtok(s, ":"),NULL,0);
if (strchr(t, '/')) {
tmp.net = (int) strtol(s = strtok(NULL, "/"),NULL,0);
if (strchr(t, '.')) {
tmp.node = (int) strtol(s = strtok(NULL, "."),NULL,0);
tmp.point = (int) strtol(strtok(NULL, "\0"),NULL,0);
}
else {
tmp.point = 0;
tmp.node = (int) strtol(strtok(NULL, "\0"),NULL,0);
}
}
else {
tmp.net = thisnode[0].net;
if (strchr(t, '.')) {
tmp.node = (int) strtol(strtok(s, "."),NULL,0);
tmp.point = (int) strtol(strtok(NULL, "\0"),NULL,0);
}
else {
tmp.point = 0;
tmp.node = (int) strtol(s,NULL,0);
}
}
}
else {
tmp.zone = thisnode[0].zone;
if (strchr(t, '/')) {
tmp.net = (int) strtol(strtok(s, "/"),NULL,0);
if (strchr(t, '.')) {
tmp.node = (int) strtol(strtok(NULL, "."),NULL,0);
tmp.point = (int) strtol(strtok(NULL, "\0"),NULL,0);
}
else {
tmp.point = 0;
tmp.node = (int)strtol(strtok(NULL, "\0"),NULL,0);
}
}
else {
tmp.net = thisnode[0].net;
if (strchr(t, '.')) {
tmp.node = (int) strtol(s = strtok(s, "."),NULL,0);
tmp.point = (int) strtol(s = strtok(NULL, "\0"),NULL,0);
}
else {
tmp.point = 0;
tmp.node = (int) strtol(s,NULL,0);
}
}
}
ptrfree(str);
return (tmp);
}
static void checkareas(char *areafile)
{
char buffer[TEXTLEN];
char path[PATHLEN];
char *fname;
char *s = NULL;
int flag = 1;
FILE *fp;
strcpy(path,bbspath);
strcat(path,"areas.bbs");
fp = NULL;
if (areafile != NULL)
fp = fopen(fname = areafile,"rt");
if (fp == NULL)
fp = fopen(fname = path,"rt");
if (fp == NULL)
fp = fopen(fname = "areas.bbs","rt");
if (fp == NULL)
return;
log(INFO,"Reading '%s'",fname);
if (fp != NULL) {
while (fgets(buffer, TEXTLEN, fp) != NULL) {
char *tag = NULL;
BYTE board;
if ((*buffer == '\r') || (*buffer == '\n'))
continue;
s = buffer;
while (isspace(*s))
s++;
if ((*s == ';') || (*s == '-'))
continue;
if ((strchr(buffer,'!')) && flag) {
char *p = strrchr(buffer,'!');
if (p != NULL) {
*p = '\0';
if (origin != NULL)
ptrfree(origin);
origin = strdup(buffer);
verifyorigin(origin,thisnode[0]);
}
flag = 0;
continue;
}
board = atoi(strtok(s," \t"));
tag = strtok(NULL," \t\n");
flag = 0;
addarea(tag, NULL, board, A_ECHO, 0, 0, NULL);
} /* while */
} /* if */
if (fp != NULL)
fclose(fp);
} /* checkareas */
/*
* Add or modify an area
* One of tag or desc may be NULL
*/
static void addarea(char *tag, char *desc, BYTE board, BYTE areatype,
BYTE flag, BYTE aka, char *orig)
{
int i;
if (board == 0) return; /* Passthrough area... */
#ifdef DEBUGAREAS
printf("\nAdding %d %s %s\n", board, tag, desc);
for (i = 0; i < areas; i++)
printf("%d %s %s\n", arealist[i].board, arealist[i].tag,
arealist[i].description);
#endif
for (i = 0; i < areas; i++) /* look for the board */
if (arealist[i].board == board)
break; /* found? */
if (i == areas) { /* new area... */
areas++;
area = areas - 1;
if (arealist == NULL) {
arealist = malloc(areas * sizeof(AREA));
checkmem(arealist);
} else {
arealist = realloc(arealist, areas * sizeof(AREA));
checkmem(arealist);
} /* else */
if (insertarea >= 0) {
if (areas-1-insertarea > 0)
movmem(&arealist[insertarea],&arealist[insertarea+1],
(areas-1-insertarea)*sizeof(arealist[0])); /* move up */
area = insertarea++;
} /* if */
memset(&arealist[area],0,sizeof(AREA)); /* this also clears msgbits */
switch (areatype) {
case A_LOCAL: arealist[area].local = 1;
if (tag == NULL)
tag = "Local";
break;
case A_NETM: arealist[area].netmail = 1;
if (tag == NULL)
tag = "Netmail";
break;
case A_ECHO: arealist[area].echomail = 1;
if (tag == NULL)
tag = "Echomail";
break;
} /* switch */
arealist[area].tag = strdup(tag);
if (desc == NULL)
desc = arealist[area].tag;
arealist[area].description = strdup(desc);
arealist[area].board = board;
} else { /* old area... */
AREA temp = arealist[i]; /* save old */
if (areas-i-1 > 0)
movmem(&arealist[i+1],&arealist[i],(areas-i-1)*sizeof(arealist[0]));
/* move down to close gap */
if (insertarea >= 0) {
if (areas-1-insertarea > 0)
movmem(&arealist[insertarea],&arealist[insertarea+1],
(areas-1-insertarea)*sizeof(arealist[0])); /* move up */
area = insertarea++;
} else {
area = areas-1;
} /* else */
arealist[area] = temp; /* restore old */
if ((tag != NULL) && (*tag != EOS)) { /* modify old tag */
if (arealist[area].tag != NULL)
ptrfree(arealist[area].tag);
arealist[area].tag = strdup(tag);
} /* if */
if ((desc != NULL) && (*desc != EOS)) { /* modify old desc */
if (arealist[area].description != NULL)
ptrfree(arealist[area].description);
arealist[area].description = strdup(desc);
} /* if */
} /* else */
if (flag & F_PRIV)
arealist[area].msgbits.is_priv = 1;
if (flag & F_CRASH)
arealist[area].msgbits.is_crash = 1;
if (flag & F_KILL)
arealist[area].msgbits.is_kill = 1;
if (flag & F_SOFT)
arealist[area].softcr = 1;
arealist[area].aka = aka;
if (orig != NULL) {
arealist[area].areaorig = strdup(orig);
verifyorigin(orig, thisnode[0]);
}
} /* addarea */
static void init()
{
memset(macros,0,sizeof(macros));
shownotes = NO;
memset(&thisnode,0,sizeof(thisnode));
addresses = 0;
username = NULL;
outfile = strdup("prn");
domains = 0;
domain_list = NULL;
tabsize = 8;
pointnet = 0;
override = FALSE;
#ifdef SEENBY
seenbys = NO;
#endif
#ifdef GATE
gate = 7;
#endif
#ifdef TEARLINE
tearline = YES;
#endif
quotestr = strdup(">");
attribline = strdup("In a message of <$d>, $f ($a) writes:");
areas = 0;
fidolist = NULL;
userlist = NULL;
origin = NULL;
confirmations = YES;
videomethod = DIRECT;
vbase = 0;
maxx = maxy = 0;
co_normal = 0x07;
co_quote = 0;
co_warn = 0x0f;
co_block = 0x0f;
co_info = 0x07;
co_hilite = 0x70;
quoteright = rm = 300; /* an unreasonable value */
checkmem(bbspath = malloc(PATHLEN));
if (getcwd(bbspath, PATHLEN) == NULL)
strcpy(bbspath,".");
if (bbspath[strlen(bbspath)-1] != '\\')
strcat(bbspath,"\\");
checkmem(bbspath = realloc(bbspath,strlen(bbspath)+1));
beepson = YES;
msgids = ON;
#ifdef EIDS
eids = ON;
#endif
strip = ON;
globsrch = ON;
techie = OFF;
} /* init */
/*
* Handle local, mail and echo statements from the config file
*/
static void parsemail(char *keyword, char *value)
{
char *key;
char desc[PATHLEN];
char tag[PATHLEN];
char *s = NULL, *d, ch;
BYTE type = A_LOCAL;
BYTE bits;
BYTE board, aka = 0;
key = keyword;
keyword = strtok(value," \t");
value = strtok(NULL,";\n\r");
if (stricmp("local", keyword) == 0)
type = A_LOCAL;
else if (stricmp("mail", keyword) == 0)
type = A_NETM;
else if (stricmp("echo", keyword) == 0)
type = A_ECHO;
else return;
bits = 0;
d = value;
while ((*d != EOS) && (*d != '"'))
switch (tolower(ch = *d++)) {
case 'p':
bits |= F_PRIV; break;
case 'c':
bits |= F_CRASH; break;
case 'k':
bits |= F_KILL; break;
case 's':
bits |= F_SOFT; break;
case '1':
case '2':
case '3':
case '4':
case '5': /* MAXAKA */
aka = (ch-'0'); break;
} /* switch */
if (*d == EOS)
goto error;
s = ++d;
d = desc;
while ((*s != EOS) && (*s != '"'))
*d++ = *s++;
*d = EOS;
s++; /* skip delimiter */
d = tag;
while ((*s != EOS) && isspace(*s)) s++; /* skip spaces */
if (*s == EOS) {
goto error;
} else {
while ((*s != EOS) && !isspace(*s)) /* get next keyword */
*d++ = *s++;
*d = EOS;
board = atoi(tag);
if (type == A_ECHO) { /* look for tag */
while ((*s != EOS) && isspace(*s)) s++; /* skip spaces again */
if (*s != NULL) { /* More! */
d = tag;
while ((*s != EOS) && !isspace(*s))
*d++ = *s++;
*d = '\0';
} /* if */
d = tag; /* tag for echomail */
} else {
d = NULL; /* don't modify tag of Net/Local */
} /* else */
addarea(d, desc, board, type, bits, aka, NULL);
} /* else */
return;
error:
log(ERR,"Syntax error in '%s' statement", key);
} /* parsemail */
/*
* Parse a string with possible quotes (" or ') and return
* malloc'ed string
*/
char *parse_string(char *s)
{
char *t, *orgt;
char delimit = ';';
orgt = t = malloc(strlen(s)+1);
if ((s == NULL) || (t == NULL)) return(NULL);
while (isspace(*s)) s++; /* skip whitespace */
if ((*s == '\'') || (*s == '"'))
delimit = *s++;
while ((*s != delimit) && (*s != EOS))
*t++ = *s++;
*t = EOS;
return(realloc(orgt,strlen(orgt)+1));
} /* parse_string */
#ifdef __TURBOC__
#pragma warn -par /* avoid stupid warnings about jmptable funcs */
#endif
#ifdef __JPIC__
#pragma warn(wpnu => off)
#endif
static void getusername(char *k, char *v);
static void includeconfig(char *k, char *v);
static void getoutfile(char *k, char *v);
static void getnode(char *k, char *v);
static void getvideo(char *k, char *v);
static void getdomains(char *k, char *v);
static void getorigin(char *k, char *v);
static void getflags(char *k, char *v);
static void getcolour(char *k, char *v);
static void getuserlist(char *k, char *v);
static void getfunction(char *k, char *v);
static void getquote(char *k, char *v);
static void getattrib(char *k, char *v);
static void getquickbbs(char *k, char *v);
static void getcols(char *k, char *v);
static void getedit(char *k, char *v);
static void getread(char *k, char *v);
#ifdef GATE
static void getgate(char *k, char *v);
#endif
static struct _centry configtable[] = {
{"sysop", getusername}, /* binkley */
{"name", getusername}, /* msged */
{"include", includeconfig}, /* binkley */
{"outfile", getoutfile}, /* msged */
{"address", getnode}, /* binkley */
{"video", getvideo}, /* msged */
{"domain", getdomains}, /* msged */
{"origin", getorigin}, /* msged */
{"enable", getflags}, /* msged/q */
{"disable", getflags}, /* msged/q */
{"no", getflags}, /* msged 2.00 */
{"colors", getcolour}, /* binkley */
{"colours", getcolour}, /* msged */
{"userlist", getuserlist}, /* msged */
{"function", getfunction}, /* msged */
{"quote", getquote}, /* msged */
{"attrib", getattrib}, /* msged/q */
{"quick", parsemail}, /* msged 2.00 */
{"bbsfiles", getquickbbs}, /* msged/q */
{"quickbbs", getquickbbs}, /* msged 2.00 */
{"color", getcols}, /* msged */
{"colour", getcols}, /* msged */
{"editkey", getedit}, /* msged */
{"readkey", getread}, /* msged */
#ifdef GATE
{"gate", getgate}, /* msged */
#endif
{NULL, NULL}
};
static struct _ientry oneinttable[] = {
{"videoseg", (int *)&vbase}, /* msged */
{"maxx", &maxx}, /* msged */
{"maxy", &maxy}, /* msged */
{"tabsize", &tabsize}, /* msged */
{"right", &rm}, /* msged */
{"quoteright", "eright}, /* msged/q */
{"privatenet", &pointnet}, /* binkley */
{NULL, NULL}
};
/*
* Display debugging info
*/
static void logit(BOOLEAN ok, char *k, char *v)
{
char buf[TEXTLEN];
sprintf(buf,"%s\t%s",k,v);
log(ok ? INFO : WARN, buf, NULL);
} /* logit */
/*
* Look up in NULL terminated number table and return value
* Return the value paired with NULL if not found
* Lowercases the second argument
*/
static int numlookup(struct _nentry *tab, char *val)
{
strlwr(val);
while (tab->label != NULL) {
size_t len = strlen(tab->label);
if (strncmp(tab->label, val, len) == 0)
return tab->value;
tab++;
} /* while */
log(WARN,"Unknown word '%s'", val);
return tab->value; /* return argument of NULL in table */
} /* numlookup */
static void getusername(char *k, char *v)
{
username = strdup(v);
} /* getusername */
static void includeconfig(char *k, char *v)
{
FILE *ifp;
if ((ifp = fopen(v,"rt")) != NULL) {
char *buf = malloc(BUFSIZE);
log(INFO,"Including '%s'",v);
if (buf != NULL)
setvbuf(ifp,buf,_IOFBF,BUFSIZE);
parseconfig(ifp);
fclose(ifp);
if (buf != NULL)
ptrfree(buf);
} /* if */
} /* includeconfig */
static void getoutfile(char *k, char *v)
{
ptrfree(outfile);
outfile = strdup(v);
} /* getoutfile */
static void getnode(char *k, char *v)
{
if (addresses >= MAXAKA) {
log(WARN, "Too many addresses defined", NULL);
return;
}
thisnode[addresses++] = parsenode(v);
} /* getnode */
static void getvideo(char *k, char *v)
{
static struct _nentry vmt[] = {
{"direct", DIRECT},
{"nosnow", NOSNOW},
{"bios", BIOS},
{"fossil", FOSSIL},
{NULL, -1}
};
int i;
if ((i = numlookup(vmt,v)) != -1)
videomethod = i;
} /* getvideo */
static void getdomains(char *k, char *v)
{
char *s;
ADDRESS tdom;
s = strdup(strtok(v," \t"));
tdom = parsenode(strtok(NULL,"\n"));
tdom.domain = s;
checkmem(domain_list = (ADDRESS *) realloc(domain_list,++domains * sizeof(ADDRESS)));
domain_list[domains - 1] = tdom;
} /* getdomains */
static void getorigin(char *k, char *v)
{
if (origin != NULL)
ptrfree(origin);
origin = strdup(v);
verifyorigin(origin,thisnode[0]);
} /* getorigin */
/*
* Handle "disable xxx", "enable xxx" and "no xxx"
*/
static void getflags(char *k, char *v)
{
enum {UNKNOWN,SEENBYS,TEARLINE,SHOWNOTES,CONFIRM,MSGIDS,STRIP,
EIDSS,BEEPS,GLOBSRCH,TOSSSSSS,SWAPPING};
static struct _nentry vmt[] = {
{"shownotes", SHOWNOTES},
{"confirm", CONFIRM},
{"msgids", MSGIDS},
{"strip", STRIP},
{"beeps", BEEPS},
{"globalsearch",GLOBSRCH},
{"swapping", SWAPPING},
#ifdef SEENBY
{"seen-bys", SEENBYS},
#endif
#ifdef TEARLINE
{"tearline", TEARLINE},
#endif
#ifdef EIDS
{"eids", EIDSS},
#endif
#ifdef TOSSCAN
{"tosscan", TOSSSSSS},
#endif
{NULL, UNKNOWN}
};
BOOLEAN on;
on = (stricmp(k,"enable") == 0);
switch (numlookup(vmt,v)) {
#ifdef SEENBY
case SEENBYS: seenbys = on; break;
#endif
#ifdef TEARLINE
case TEARLINE: tearline = on; break;
#endif
case SHOWNOTES: shownotes = on; break;
case CONFIRM: confirmations = on; break;
case MSGIDS: msgids = on; break;
#ifdef EIDS
case EIDSS: eids = on; break;
#endif
case STRIP: strip = on; break;
case BEEPS: beepson = on; break;
case GLOBSRCH: globsrch = on; break;
case SWAPPING: swapping_enabled = on; break;
#ifdef TOSSCAN
case TOSSSSSS: tosscan = on; break;
#endif
} /* switch */
} /* getflags */
static void getcolour(char *k, char *v)
{
co_quote = (int) strtol(strtok(v," \t"),NULL,0);
co_warn = (int) strtol(strtok(NULL," \t"),NULL,0);
co_block = (int) strtol(strtok(NULL," \t"),NULL,0);
co_info = (int) strtol(strtok(NULL," \t"),NULL,0);
co_normal = (int) strtol(strtok(NULL," \t"),NULL,0);
co_hilite = (int) strtol(strtok(NULL," \t\n\r"),NULL,0);
} /* getcolour */
static void getuserlist(char *k, char *v)
{
fidolist = strdup(strtok(v," ,\n"));
if ((userlist = strtok(NULL," ,\n")) != NULL)
userlist = strdup(userlist);
} /* getuserlist */
static void getfunction(char *k, char *v)
{
int i;
char *s;
i = (int) strtol(v,&s,0) - 1;
while (isspace(*s))
s++;
if ((i >= 0) && (i < 40))
macros[i] = parse_macro(s);
} /* getfunction */
static void getquote(char *k, char *v)
{
ptrfree(quotestr);
quotestr = parse_string(v);
} /* getquote */
static void getattrib(char *k, char *v)
{
ptrfree(attribline);
attribline = parse_string(v);
} /* getattrib */
static void getquickbbs(char *k, char *v)
{
if (v != NULL) {
checkmem(bbspath = realloc(bbspath,strlen(v)+2));
strcpy(bbspath,v);
if (bbspath[strlen(bbspath)-1] != '\\')
strcat(bbspath,"\\");
} /* if */
} /* getquickbbs */
static void getcols(char *k, char *v)
{
k = strtok(v," \t");
v = strtok(NULL," \t");
set_colors(k,v);
} /* getcols */
static void getedit(char *k, char *v)
{
int scancode;
int i = 0;
strlwr(v);
scancode = (int) strtol(v,&v,0);
while (*v && isspace(*v)) v++;
while (editcmds[i].label != NULL) {
if (strncmp(editcmds[i].label,v,strlen(editcmds[i].label)) == 0) {
if (scancode & 0xff)
editckeys[scancode & 0xff] = editcmds[i].action;
else
editakeys[scancode >> 8] = editcmds[i].action;
break;
} /* if */
i++;
} /* while */
} /* getedit */
static void getread(char *k, char *v)
{
int scancode;
int i = 0;
strlwr(v);
scancode = (int) strtol(v,&v,0);
while (*v && isspace(*v)) v++;
while (maincmds[i].label != NULL) {
if (strncmp(maincmds[i].label,v,strlen(maincmds[i].label)) == 0) {
if (scancode & 0xff)
mainckeys[scancode & 0xff] = maincmds[i].action;
else
mainakeys[scancode >> 8] = maincmds[i].action;
break;
} /* if */
i++;
} /* while */
} /* getread */
#ifdef GATE
**** untested code, should work... ****
static void getgate(char *k, char *v)
{
if (gate == 7)
gate = 0;
strlwr(v);
if (strncmp(v,"zones",5) == 0)
gate |= GZONES;
else if (strncmp(v,"domains",7) == 0)
gate |= GDOMAINS;
else if (strncmp(v,"both",4) == 0)
gate = GDOMAINS | GZONES;
else if (strncmp(v,"none",4) == 0)
gate = 0;
} /* getgate */
#endif
static void set_colors(char *keyword,char *value)
{
static struct _nentry ctab[] = {
{"bla", 0},
{"blu", 1},
{"gre", 2},
{"cya", 3},
{"red", 4},
{"mag", 5},
{"yel", 6},
{"bro", 6},
{"whi", 7},
{"gra", 7},
{NULL, 0}
};
enum {F_UNKNOWN,F_NORMAL,F_QUOTE,F_WARN,F_BLOCK,F_INFO,F_HILITE};
static struct _nentry ftab[] = {
{"normal", F_NORMAL},
{"quote", F_QUOTE},
{"warn", F_WARN},
{"block", F_BLOCK},
{"info", F_INFO},
{"hilite", F_HILITE},
{"highlight", F_HILITE},
{NULL, F_UNKNOWN}
};
int color, temp;
char *s, *f, *b;
f = strtok(value,"/");
b = strtok(NULL," \t");
s = strlwr(strtok(f, " \t+"));
color = numlookup(ctab,s);
s = strlwr(strtok(NULL, " \t"));
while ((s != NULL) && isspace(*s))
s++;
if ((s != NULL) && (strncmp(s, "int", 3) == 0)) /* intense */
color |= 8;
temp = numlookup(ctab,b);
color |= (temp << 4);
switch (numlookup(ftab,keyword)) {
case F_NORMAL: co_normal = color; break;
case F_QUOTE: co_quote = color; break;
case F_WARN: co_warn = color; break;
case F_BLOCK: co_block = color; break;
case F_INFO: co_info = color; break;
case F_HILITE: co_hilite = color; break;
} /* switch */
} /* set_colors */
/*
* Check if an origin line is ok and log a warning if it is too long
*/
static void verifyorigin(char *origin, ADDRESS addr)
{
char buffer[200];
formatorigin(buffer, origin, addr);
if (strlen(buffer) > 80) {
strcpy(&buffer[50],"..."); /* truncate the origin line with ... */
log(WARN,"Origin line too long: '%s'",buffer);
} /* if */
} /* verifyorigin */
static void parseconfig(FILE *fp)
{
char buffer[TEXTLEN];
char *keyword = NULL;
char *value = NULL;
BOOLEAN stripped, skipline;
struct _centry *look;
struct _ientry *ilook;
while (!feof(fp)) {
memset(buffer, 0, TEXTLEN);
if (fgets(buffer, TEXTLEN, fp) == NULL)
return; /* error reading */
do {
stripped = FALSE;
skipline = TRUE;
keyword = strlwr(strtok(buffer, " \t"));
if ((*keyword) == ';') /* comment, go skip line */
break;
if ((value = strtok(NULL, ";\n\r")) == NULL)
break; /* get rest of line up to end or comment */
while (isspace(*value) && !((*value == '\n') || (*value == ';') || (*value == '\r')))
value++; /* skip spaces in front */
if (stricmp("application",keyword) == 0) {
char *s = strlwr(strtok(value," \t"));
if ((stricmp("msged",s) == 0) || (stricmp("msgq",s) == 0)) {
strcpy(buffer,strtok(NULL,"\n\r"));
stripped = TRUE;
} /* if */
} /* if */
skipline = FALSE;
} while (stripped);
if (skipline) continue; /* continue the continue */
for (look = configtable; look->label != NULL; look++)
if (stricmp(look->label,keyword) == 0) {
logit(TRUE,keyword,value);
(look->action)(keyword,value);
skipline = TRUE;
break;
} /* if */
if (skipline) continue;
for (ilook = oneinttable; ilook->label != NULL; ilook++)
if (stricmp(ilook->label,keyword) == 0) {
logit(TRUE,keyword,value);
*ilook->value = (int) strtol(value,NULL,0);
skipline = TRUE;
break;
} /* if */
if (skipline) continue;
logit(FALSE,keyword,value);
} /* while */
} /* parseconfig */
/*
* Create CONFIG.BBS
*/
static void createconfigbbs(void)
{
char name[PATHLEN];
CONFIGRECORD *config = NULL;
BYTE b, e;
int conf = -1;
BYTE netmailboard = 0;
if ((config = calloc(sizeof(CONFIGRECORD),1)) == NULL) {
log(ERR,"No memory to create CONFIG.BBS",NULL);
goto leave;
} /* if */
strcpy(name,bbspath);
strcat(name,"config.bbs");
log(INFO,"Creating '%s'", name);
if ((conf = creat(name,S_IREAD|S_IWRITE)) == -1) {
log(ERR,"Could not create '%s'", name);
goto leave;
} /* if */
strncpy(config->netpath,newnetpath,66);
c2p_str(config->netpath);
strncpy(config->originline,origin,60);
c2p_str(config->originline);
strncpy(config->sysopname,username,35);
c2p_str(config->sysopname);
config->uselastread = YES;
config->matrixzone = thisnode[0].zone;
if (thisnode[0].point) {
config->matrixnet = pointnet;
config->matrixnode = thisnode[0].point;
} else {
config->matrixnet = thisnode[0].net;
config->matrixnode = thisnode[0].node;
} /* else */
/* config->usezonegates = 1; */
e = addresses > 5 ? 5 : addresses; /* copy over aka's */
for (b=1; b < e; b++) {
config->akazone[b-1] = thisnode[b].zone;
config->akanode[b-1] = thisnode[b].node;
config->akanet[b-1] = thisnode[b].net;
config->akapoint[b-1] = thisnode[b].point;
}
for (b = 0; b < areas; b++) {
BYTE board = arealist[b].board-1; /* index of board */
strncpy(config->boardrec[board].name,arealist[b].description,16);
c2p_str(config->boardrec[board].name);
config->boardrec[board].combined = YES;
config->boardrec[board].readseclvl = 5;
config->boardrec[board].writeseclvl = 10;
config->boardrec[board].sysopseclvl = 100;
if (arealist[b].echomail)
config->boardrec[board].typ = 3;
else if (arealist[b].netmail) {
config->boardrec[board].typ = 1;
netmailboard = board+1;
} /* else */
if (arealist[b].msgbits.is_priv)
config->boardrec[board].kinds = 1; /* Private */
/* default is 0, which is "both" */
} /* for */
config->netmailboard = netmailboard;
config->deffgcolor = 7;
if (write(conf,(char *)config,sizeof(CONFIGRECORD)) != sizeof(CONFIGRECORD))
log(ERR,"Error writing to '%s'", name);
leave:
if (config != NULL)
ptrfree(config);
if (conf != -1)
if (close(conf) == -1)
log(ERR,"Error closing '%s'", name);
} /* createconfigbbs */
/*
* Read CONFIG.BBS
*/
static void readconfigbbs(void)
{
char name[PATHLEN];
CONFIGRECORD *config = NULL;
BYTE b;
int conf = -1;
if ((config = calloc(sizeof(CONFIGRECORD),1)) == NULL) {
log(ERR,"No memory to load CONFIG.BBS",NULL);
goto leave;
} /* if */
strcpy(name,bbspath);
strcat(name,"config.bbs");
if ((conf = open(name,O_RDWR|O_BINARY,S_IREAD|S_IWRITE)) == -1) {
log(ERR,"Could not open '%s'", name);
goto leave;
} /* if */
log(INFO,"Reading '%s'", name);
if (read(conf,(char *)config,sizeof(CONFIGRECORD)) != sizeof(CONFIGRECORD)) {
log(ERR,"Error reading '%s'", name);
goto leave;
} /* if */
for (b = 0; b < BLIM; b++) {
p2c_strn(config->boardrec[b].name,16);
if (*config->boardrec[b].name != EOS) {
BYTE type, bits = 0;
switch (config->boardrec[b].typ) {
case 1: type = A_NETM; break; /* Netmail */
case 3: type = A_ECHO; break; /* Echomail */
default:type = A_LOCAL; break; /* Standard or Email */
} /* switch */
if (config->boardrec[b].kinds == 1) /* Private? */
bits |= F_PRIV;
addarea(NULL, config->boardrec[b].name, b+1, type, bits, config->useaka[b], NULL);
} /* if */
} /* for */
if (*config->sysopname != EOS) {
if (username != NULL) ptrfree(username);
p2c_strn(config->sysopname,35);
username = strdup(config->sysopname);
} /* if */
if (*config->originline != EOS) {
if (origin != NULL) ptrfree(origin);
p2c_strn(config->originline,60);
origin = strdup(config->originline);
} /* if */
thisnode[0].zone = config->matrixzone;
thisnode[0].net = config->matrixnet;
thisnode[0].node = config->matrixnode;
thisnode[0].point = config->matrixpoint; /* from 2.61 */
if (thisnode[0].net != 0)
addresses = 1;
for (b=0; b < 5; b++) /* from 2.61 */
if ((config->akanet[b] != 0) && (addresses <= MAXAKA)) {
thisnode[addresses].zone = config->akazone[b];
thisnode[addresses].net = config->akanet[b];
thisnode[addresses].node = config->akanode[b];
thisnode[addresses].point = config->akapoint[b];
++addresses;
}
co_normal = config->deffgcolor | (config->defbgcolor << 4);
if (*config->quotestr != EOS) {
char *pos;
if (quotestr != NULL) ptrfree(quotestr);
p2c_strn(config->quotestr,3);
quotestr = strdup(config->quotestr);
if ((pos = strchr(quotestr,'\01')) != NULL)
*pos = '&'; /* all initials */
} /* if */
leave:
if (config != NULL)
ptrfree(config);
if (conf != -1)
close(conf);
} /* readconfigbbs */
/*
* Read MESSAGES.RA
*/
static void readmessagesra(void)
{
char name[PATHLEN];
RA_BOARDRECORD board;
BYTE b;
int conf = -1;
strcpy(name,bbspath);
strcat(name,"messages.ra");
if ((conf = open(name,O_RDWR|O_BINARY,S_IREAD|S_IWRITE)) == -1) {
log(ERR,"Could not open '%s'", name);
goto leave;
} /* if */
log(INFO,"Reading '%s'", name);
b = 0;
while (!eof(conf)) {
++b;
(void)read(conf, &board, sizeof(board));
p2c_strn(board.name,40);
if (*board.name != EOS) {
BYTE type, bits = 0;
switch (board.type) {
case RA_NetMail: type = A_NETM; break;
case RA_EchoMail: type = A_ECHO; break;
default: type = A_LOCAL; break;
} /* switch */
if (board.kinds == RA_Private) /* Private? */
bits |= F_PRIV;
addarea(NULL, board.name, b, type, bits, board.aka, NULL);
} /* if */
} /* while */
leave:
if (conf != -1)
close(conf);
} /* readmessagesra */
/*
* Read CONFIG.RA
*/
static void readconfigra(void)
{
char name[PATHLEN];
RA_CONFIG *config = NULL;
int conf = -1;
int c;
if ((config = calloc(sizeof(RA_CONFIG),1)) == NULL) {
log(ERR,"No memory to load CONFIG.RA",NULL);
goto leave;
} /* if */
strcpy(name,bbspath);
strcat(name,"config.ra");
if ((conf = open(name,O_RDWR|O_BINARY,S_IREAD|S_IWRITE)) == -1) {
log(ERR,"Could not open '%s'", name);
goto leave;
} /* if */
log(INFO,"Reading '%s'", name);
if (read(conf,(char *)config,sizeof(RA_CONFIG)) != sizeof(RA_CONFIG)) {
log(ERR,"Error reading '%s'", name);
goto leave;
} /* if */
if (*config->sysop != EOS) {
if (username != NULL) ptrfree(username);
p2c_strn(config->sysop,35);
username = strdup(config->sysop);
} /* if */
if (*config->origin_line != EOS) {
if (origin != NULL) ptrfree(origin);
p2c_strn(config->origin_line,60);
origin = strdup(config->origin_line);
} /* if */
for (c=0; c < 10; c++)
if ((config->address[c].net != 0) && (addresses <= MAXAKA)) {
thisnode[addresses].zone = config->address[c].zone;
thisnode[addresses].net = config->address[c].net;
thisnode[addresses].node = config->address[c].node;
thisnode[addresses].point = config->address[c].point;
++addresses;
}
co_normal = config->norm_fore | (config->norm_back << 4);
co_warn = config->hi_fore | (config->hi_back << 4);
co_block = config->stat_fore | (config->stat_back << 4);
co_info = config->wind_fore | (config->wind_back << 4);
co_quote = config->bar_fore | (config->bar_back << 4);
co_hilite = config->border_fore | (config->border_back << 4);
if (*config->quote_string != EOS) {
char *pos;
if (quotestr != NULL) ptrfree(quotestr);
p2c_strn(config->quote_string,15);
quotestr = strdup(config->quote_string);
if ((pos = strchr(quotestr,'\01')) != NULL)
*pos = '&'; /* all initials */
} /* if */
leave:
if (config != NULL)
ptrfree(config);
if (conf != -1)
close(conf);
} /* readconfigra */
/*
* Read RA configs
*/
static void readraconfigs(void)
{
readconfigra();
readmessagesra();
} /* readraconfigs */
/*
* Look for the file ECHOORIG.CTL
* All areas must have been defined when this is called
*/
void checkorig(void)
{
char buf[TEXTLEN];
char *s;
FILE *orig;
BYTE board;
int c;
strcpy(buf,bbspath);
strcat(buf,"echoorig.ctl");
if ((orig = fopen(buf,"rt")) == NULL)
return; /* not found */
log(INFO,"Reading '%s'",buf);
while (fgets(buf, TEXTLEN, orig) != NULL) {
c = strlen(buf)-1;
if (buf[c] == '\n') /* strip the newline */
buf[c] = EOS;
s = buf;
while (isspace(*s)) s++; /* skip spaces */
if ((board = atoi(s)) == 0) /* get number */
continue;
while (isdigit(*s)) s++; /* skip number */
while (isspace(*s)) s++; /* skip spaces */
for (c = 0; c < areas; c++)
if (board == arealist[c].board) {
arealist[c].areaorig = strdup(s); /* override default origin */
verifyorigin(s,thisnode[0]);
break;
} /* if */
} /* while */
fclose(orig);
} /* checkorig */
/*
* D'Bridge code courtesy of Fredrik Chabot (2:281/5.10)
*/
#ifdef DBRIDGE
typedef struct {
char allocated;
char tag[17];
char ECHOmail_tag[57];
} _aa1;
typedef struct {
char description[41];
int group;
char storage;
char directory_path[49];
char kind;
int quick_area;
char default_private;
char tiny_seenbys;
char origin_line[57];
char depault_priority;
int alias_zone,
alias_net,
alias_node,
alias_point;
int area_purge,
area_preserve,
area_security;
char area_archive[57];
char forward_to[5][57];
} _aa2;
/*
* Read D'Bridge config
*/
static void readdbridgeprm()
{
/*
Field Line/Column Description
-------------------------------------------------------------------------
PARAMETER FILE VERSION 1/1 Current software version
NETWORK MAIL STORAGE 2/1 NETmail storage method: F, T or Q
DBMAILER OVERLAY EMS? 2/2 Copy DBMAILER.OVR to EMS? 1 or 0
DBEDIT OVERLAY EMS? 2/3 Copy DBEDIT.OVR to EMS? 1 or 0
DBMAILER PROGRAM SIZE 2/4 Total memory (in K)
DBMAILER WORKRAM SIZE 2/11 WorkRAM (in K)
NETWORK MAIL DIRECTORY 3/1 Fido-style NETmail directory path
INBOUND FILES DIRECTORY 4/1 Inbound files directory path
PACKET DIRECTORY 5/1 Temporary packet directory path
QUEUE DIRECTORY 6/1 Disk-based queue directory path
SCRIPT DIRECTORY 7/1 Script file directory path
BADECHO DIRECTORY 8/1 BADECHO directory path (Fido-style)
NEWECHO DIRECTORY 9/1 New ECHOmail base directory path
QUICKBBS DIRECTORY 10/1 QuickBBS directory path
SJF DIRECTORY 11/1 SJF directory path
DOWNLOAD DIRECTORY 12/1 Terminal download directory path
OUTBOUND MAIL ARCHIVE 13/1 Outbound NETmail archive filename
NETWORK MAIL ARCHIVE 14/1 NETmail archive filename
SYSTEM NAME 15/1 Primary system name
OPERATOR NAME 16/1 Primary operator name
ZONE 17/1 Zone address
NET 17/8 Net address
NODE 17/15 Node address
POINT 17/22 Point address
--------------------------------------------------------------------
QBBSNETMAIL 17/85 **NIET GEDOCUMENTEERD**
*/
FILE *fd, *fopen();
char buffer[512], *line,
netmailst;
int qbbsnetmail;
if((fd=fopen("dbridge.prm","rt"))==NULL){
log(ERR,"Could not open dbridge.prm",NULL);
}
line=fgets(buffer,512,fd); /* 1 */
/* dbridge=strdup(line); */
line=fgets(buffer,512,fd); /* 2 */
netmailst=line[0];
line=fgets(buffer,512,fd); /* 3 */
/* netmaildir=strdup(line); */
line=fgets(buffer,512,fd); /* 4 */
line=fgets(buffer,512,fd); /* 5 */
line=fgets(buffer,512,fd); /* 6 */
line=fgets(buffer,512,fd); /* 7 */
line=fgets(buffer,512,fd); /* 8 */
/* badechodir=strdup(line); */
line=fgets(buffer,512,fd); /* 9 */
line=fgets(buffer,512,fd); line[strlen(line)-1]=0; /* 10 */
bbspath=strdup(line);
line=fgets(buffer,512,fd); /* 11 */
line=fgets(buffer,512,fd); /* 12 */
line=fgets(buffer,512,fd); /* 13 */
line=fgets(buffer,512,fd); /* 14 */
line=fgets(buffer,512,fd); /* 15 */
/* sysname=strdup(line); */
line=fgets(buffer,512,fd); line[strlen(line)-1]=0;/* 16 */
username=strdup(line);
line=fgets(buffer,512,fd); /* 17 */
thisnode[0].zone=atoi(line);
thisnode[0].net=atoi(line+7);
thisnode[0].node=atoi(line+14);
thisnode[0].point=atoi(line+21);
if (thisnode[0].net != 0)
addresses = 1;
qbbsnetmail=atoi(line+84);
if(netmailst=='Q'){
insertarea = 0; /* insert at front */
addarea("Net-Mail", NULL, qbbsnetmail, A_NETM, 0, 0, NULL);
}
fclose(fd);
} /* readdbridgeprm */
/*
* Read D'Bridge areas
*/
static void readdbridgeareas(void)
{
_aa1 aa1;
_aa2 aa2;
int fdaa1, fdaa2;
if((fdaa1=_open("Dbridge.aa1",O_BINARY | O_RDONLY))==-1)
log(ERR,"Could not open dbridge.aa1",NULL);
if((fdaa2=_open("Dbridge.aa2",O_BINARY | O_RDONLY))==-1)
log(ERR,"Could not open dbridge.aa2",NULL);
while( _read(fdaa1,&aa1,sizeof(aa1))==sizeof(aa1) ){
_read(fdaa2,&aa2,sizeof(aa2));
p2c_str(aa1.tag);
p2c_str(aa1.ECHOmail_tag);
/* printf("'%s' - ",aa1.tag); */
p2c_str(aa2.description);
p2c_str(aa2.directory_path);
p2c_str(aa2.origin_line);
/* printf("%d - '%s' - '%s'\n",aa2.quick_area,aa2.description,aa2.origin_line); */
addarea(aa1.tag, aa2.description, aa2.quick_area, A_ECHO, 0, 0, aa2.origin_line);
}
_close(fdaa1);
_close(fdaa2);
} /* readdbridgeareas */
static void readdbridgeconfigs(void)
{
readdbridgeareas();
readdbridgeprm();
} /* readdbridgeconfigs */
#endif /* DBRIDGE */