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 2003 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 */
#ifdef _WIN32
#include <windows.h>
#endif
#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>
#endif
#ifndef __unix__

rswindell
committed
#include <malloc.h>
#endif
#include "sbbs.h" /* load_cfg() */
#include "sbbsdefs.h"
#include "smblib.h"
#include "scfglib.h"
#include "lzh.h"
#include "sbbsecho.h"
smb_t *smb,*email;
long misc=(IMPORT_PACKETS|IMPORT_NETMAIL|IMPORT_ECHOMAIL|EXPORT_ECHOMAIL
|DELETE_NETMAIL|DELETE_PACKETS);
ulong netmail=0;
char tmp[256],pkt_type=0;
int secure,cur_smb=0;
FILE *fidologfile=NULL;
two_two_t two_two;
two_plus_t two_plus;
faddr_t sys_faddr;
config_t cfg;
scfg_t scfg;
char revision[16];
BOOL pause_on_exit=FALSE;
#ifdef __WATCOMC__
/******************************************************************************
A DOS to Unix function - because WATCOM doesn't have one
******************************************************************************/
time_t dostounix(struct date *d,struct time *t)
{
struct tm tm;
tm.tm_sec=t->ti_sec;
tm.tm_min=t->ti_min;
tm.tm_hour=t->ti_hour;
tm.tm_mday=d->da_day;
tm.tm_mon=(d->da_mon-1);
tm.tm_year=d->da_year-1900;
tm.tm_isdst=0;
return(mktime(&tm));
}
#endif
#ifndef __NT__
#define delfile(x) remove(x)
#else
int delfile(char *filename)
{
int i=0;
while(remove(filename) && i++<120) /* Wait up to 60 seconds to delete file */
delay(500); /* for Win95 bug fix */
return(i);
#if defined(__unix__) /* borrowed from MSVC */
unsigned val,
int shift
)
{
register unsigned lobit; /* non-zero means lo bit set */
register unsigned num = val; /* number to rotate */
shift &= 0x1f; /* modulo 32 -- this will also make
negative shifts work */
while (shift--) {
lobit = num & 1; /* get high bit */
num >>= 1; /* shift right one bit */
if (lobit)
num |= 0x80000000; /* set hi bit if lo bit was set */
}
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/******************************************************************************
Displays characters locally
******************************************************************************/
long lputs(char *str)
{
char tmp[256];
int i,j,k;
j=strlen(str);
for(i=k=0;i<j;i++) /* remove CRs */
if(str[i]==CR && str[i+1]==LF)
continue;
else
tmp[k++]=str[i];
tmp[k]=0;
return(fputs(tmp,stdout));
}
/****************************************************************************/
/* Performs printf() through local assembly routines */
/* Called from everywhere */
/****************************************************************************/
int lprintf(char *fmat, ...)
{
va_list argptr;
char sbuf[256];
int chcount;
va_start(argptr,fmat);
chcount=vsnprintf(sbuf,sizeof(sbuf),fmat,argptr);
sbuf[sizeof(sbuf)-1]=0;
va_end(argptr);
lputs(sbuf);
return(chcount);
}
/**********************/
/* Log print function */
/**********************/
void logprintf(char *str, ...)
{
va_list argptr;
char buf[256];
time_t now;
struct tm *gm;
if(!(misc&LOGFILE) || fidologfile==NULL)
return;
va_start(argptr,str);
vsnprintf(buf,sizeof(buf),str,argptr);
buf[sizeof(buf)-1]=0;
va_end(argptr);
now=time(NULL);
gm=localtime(&now);
fseek(fidologfile,0L,SEEK_END);
fprintf(fidologfile,"%02u/%02u/%02u %02u:%02u:%02u %s\r\n"
,gm->tm_mon+1,gm->tm_mday,TM_YEAR(gm->tm_year),gm->tm_hour,gm->tm_min,gm->tm_sec
,buf);
fflush(fidologfile);
}
/*****************************************************************************/
/* Returns command line generated from instr with %c replacments */
/*****************************************************************************/
char *cmdstr(scfg_t* cfg, char *instr, char *fpath, char *fspec)
{
static char cmd[128];
char str[256],str2[128];
int i,j,len;
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
len=strlen(instr);
for(i=j=0;i<len && j<128;i++) {
if(instr[i]=='%') {
i++;
cmd[j]=0;
switch(toupper(instr[i])) {
case 'F': /* File path */
strcat(cmd,fpath);
break;
case 'G': /* Temp directory */
if(cfg->temp_dir[0]!='\\'
&& cfg->temp_dir[0]!='/'
&& cfg->temp_dir[1]!=':') {
strcpy(str,cfg->node_dir);
strcat(str,cfg->temp_dir);
if(FULLPATH(str2,str,40))
strcpy(str,str2);
backslash(str);
strcat(cmd,str);}
else
strcat(cmd,cfg->temp_dir);
break;
case 'J':
if(cfg->data_dir[0]!='\\'
&& cfg->data_dir[0]!='/'
&& cfg->data_dir[1]!=':') {
strcpy(str,cfg->node_dir);
strcat(str,cfg->data_dir);
if(FULLPATH(str2,str,40))
strcpy(str,str2);
backslash(str);
strcat(cmd,str); }
else
strcat(cmd,cfg->data_dir);
break;
case 'K':
if(cfg->ctrl_dir[0]!='\\'
&& cfg->ctrl_dir[0]!='/'
&& cfg->ctrl_dir[1]!=':') {
strcpy(str,cfg->node_dir);
strcat(str,cfg->ctrl_dir);
if(FULLPATH(str2,str,40))
strcpy(str,str2);
backslash(str);
strcat(cmd,str); }
else
strcat(cmd,cfg->ctrl_dir);
break;
case 'N': /* Node Directory (same as SBBSNODE environment var) */
strcat(cmd,cfg->node_dir);
break;
case 'O': /* SysOp */
strcat(cmd,cfg->sys_op);
break;
case 'Q': /* QWK ID */
strcat(cmd,cfg->sys_id);
break;
case 'S': /* File Spec */
strcat(cmd,fspec);
break;
case '!': /* EXEC Directory */
if(cfg->exec_dir[0]!='\\'
&& cfg->exec_dir[0]!='/'
&& cfg->exec_dir[1]!=':') {
strcpy(str,cfg->node_dir);
strcat(str,cfg->exec_dir);
if(FULLPATH(str2,str,40))
strcpy(str,str2);
backslash(str);
strcat(cmd,str); }
else
strcat(cmd,cfg->exec_dir);
break;
case '#': /* Node number (same as SBBSNNUM environment var) */
sprintf(str,"%d",cfg->node_num);
strcat(cmd,str);
break;
case '*':
sprintf(str,"%03d",cfg->node_num);
strcat(cmd,str);
break;
case '%': /* %% for percent sign */
strcat(cmd,"%");
break;
default: /* unknown specification */
printf("ERROR Checking Command Line '%s'\n",instr);
logprintf("ERROR line %d Checking Command Line '%s'",__LINE__
,instr);
bail(1);
break; }
j=strlen(cmd); }
else
cmd[j++]=instr[i]; }
cmd[j]=0;
}
/****************************************************************************/
/* Runs an external program directly using spawnvp */
/****************************************************************************/
int execute(char *cmdline)
{
return system(cmdline);
char c,d,e,cmdlen,*arg[30],str[256];
int i;
strcpy(str,cmdline);
arg[0]=str; /* point to the beginning of the string */
cmdlen=strlen(str);
for(c=0,d=1,e=0;c<cmdlen;c++,e++) /* Break up command line */
if(str[c]==SP) {
str[c]=0; /* insert nulls */
arg[d++]=str+c+1; /* point to the beginning of the next arg */
e=0; }
arg[d]=0;
i=spawnvp(P_WAIT,arg[0],arg);
return(i);
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/******************************************************************************
Returns the system address with the same zone as the address passed
******************************************************************************/
faddr_t getsysfaddr(short zone)
{
int i;
faddr_t sysfaddr;
sysfaddr.zone=sysfaddr.net=sysfaddr.node=1;
sysfaddr.point=0;
if(!scfg.total_faddrs)
return(sys_faddr);
sysfaddr=scfg.faddr[0];
if(scfg.total_faddrs==1)
return(sysfaddr);
for(i=0;i<scfg.total_faddrs;i++)
if(scfg.faddr[i].zone==zone)
return(scfg.faddr[i]);
return(sysfaddr);
}
/******************************************************************************
This function creates or appends on existing Binkley compatible .?LO file
attach file.
Returns 0 on success.
******************************************************************************/
int write_flofile(char *attachment, faddr_t dest)
{
char fname[MAX_PATH+1];
char outbound[MAX_PATH+1];
char str[MAX_PATH+1];
char ch;
char searchstr[MAX_PATH+1];
ushort attr=0;
int i,file;
FILE *stream;
i=matchnode(dest,0);
if(i<(int)cfg.nodecfgs)
attr=cfg.nodecfg[i].attr;
if(attr&ATTR_CRASH) ch='c';
else if(attr&ATTR_HOLD) ch='h';
else if(attr&ATTR_DIRECT) ch='d';
else ch='f';
if(dest.zone==scfg.faddr[0].zone) /* Default zone, use default outbound */
strcpy(outbound,cfg.outbound);
else { /* Inter-zone outbound is OUTBOUND.XXX */
sprintf(outbound,"%.*s.%03x"
,(int)strlen(cfg.outbound)-1,cfg.outbound,dest.zone);
MKDIR(outbound);
backslash(outbound);
}
if(dest.point) { /* Point destination is OUTBOUND\*.PNT */
,dest.net,dest.node);
strcat(outbound,str); }
if(outbound[strlen(outbound)-1]=='\\'
|| outbound[strlen(outbound)-1]=='/')
sprintf(fname,"%s%04x%04x.%clo",outbound,dest.net,dest.node,ch);
sprintf(searchstr,"^%s",attachment);
if(findstr(searchstr,fname)) /* file already in FLO file */
return(0);
if((stream=fnopen(&file,fname,O_WRONLY|O_APPEND|O_CREAT))==NULL) {
printf("\7ERROR line %d opening %s %s\n",__LINE__,fname,strerror(errno));
logprintf("ERROR line %d opening %s %s",__LINE__,fname,strerror(errno));
return(-1);
}
fprintf(stream,"^%s\r\n",attachment);
fclose(stream);
return(0);
}
/* Writes text buffer to file, expanding sole LFs to CRLFs */
size_t fwrite_crlf(char* buf, size_t len, FILE* fp)
{
char ch,last_ch=0;
size_t i;
size_t wr=0; /* total chars written (may be > len) */
for(i=0;i<len;i++) {
ch=*buf++;
if(ch=='\n' && last_ch!='\r') {
if(fputc('\r',fp)==EOF)
return(wr);
wr++;
}
if(fputc(ch,fp)==EOF)
return(wr);
wr++;
last_ch=ch;
}
return(wr);
}
/******************************************************************************
This function will create a netmail message (.MSG format).
If file is non-zero, will set file attachment bit (for bundles).
Returns 0 on success.
******************************************************************************/
int create_netmail(char *to, char *subject, char *body, faddr_t dest, BOOL file_attached)
{
FILE *fstream;
char str[256],fname[256];
ushort attr=0;
int fmsg;
uint i;
static uint startmsg;
time_t t;
faddr_t faddr;
fmsghdr_t hdr;
struct tm *tm;
if(!startmsg) startmsg=1;
i=matchnode(dest,0);
if(i<cfg.nodecfgs) {
attr=cfg.nodecfg[i].attr;
if(!attr) {
i=matchnode(dest,2);
if(i<cfg.nodecfgs)
attr=cfg.nodecfg[i].attr; } }
do {
for(i=startmsg;i;i++) {
sprintf(fname,"%s%u.msg",scfg.netmail_dir,i);
if(!fexistcase(fname))
break;
}
if(!i) {
printf("\7%s directory full!\n",scfg.netmail_dir);
logprintf("Directory full: %s",scfg.netmail_dir);
return(-1); }
startmsg=i+1;
if((fstream=fnopen(&fmsg,fname,O_RDWR|O_CREAT))==NULL) {
printf("\7ERROR line %d opening %s %s\n",__LINE__,fname,strerror(errno));
logprintf("ERROR line %d opening %s %s",__LINE__,fname,strerror(errno));
faddr=getsysfaddr(dest.zone);
memset(&hdr,0,sizeof(fmsghdr_t));
hdr.origzone=faddr.zone;
hdr.orignet=faddr.net;
hdr.orignode=faddr.node;
hdr.origpoint=faddr.point;
hdr.destzone=dest.zone;
hdr.destnet=dest.net;
hdr.destnode=dest.node;
hdr.destpoint=dest.point;
hdr.attr=(FIDO_PRIVATE|FIDO_KILLSENT|FIDO_LOCAL);
if(attr&ATTR_HOLD)
hdr.attr|=FIDO_HOLD;
if(attr&ATTR_CRASH)
hdr.attr|=FIDO_CRASH;
sprintf(hdr.from,"SBBSecho");
t=time(NULL);
tm=localtime(&t);
sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u"
,tm->tm_mday,mon[tm->tm_mon],TM_YEAR(tm->tm_year)
,tm->tm_hour,tm->tm_min,tm->tm_sec);
if(to)
sprintf(hdr.to,"%s",to);
sprintf(hdr.to,"SYSOP");
sprintf(hdr.subj,"%.71s",subject);
fwrite(&hdr,sizeof(fmsghdr_t),1,fstream);
sprintf(str,"\1INTL %hu:%hu/%hu %hu:%hu/%hu\r"
,hdr.destzone,hdr.destnet,hdr.destnode
,hdr.origzone,hdr.orignet,hdr.orignode);
fwrite(str,strlen(str),1,fstream);
/* Add FSC-53 FLAGS kludge */
fprintf(fstream,"\1FLAGS");
if(attr&ATTR_DIRECT)
fprintf(fstream," DIR");
if(file_attached) {
if(misc&TRUNC_BUNDLES)
fprintf(fstream," TFS");
fprintf(fstream," KFS");
}
fprintf(fstream,"\r");
if(hdr.destpoint) {
sprintf(str,"\1TOPT %hu\r",hdr.destpoint);
fwrite(str,strlen(str),1,fstream); }
if(hdr.origpoint) {
sprintf(str,"\1FMPT %hu\r",hdr.origpoint);
fwrite(str,strlen(str),1,fstream); }
if(!file_attached || (!(attr&ATTR_DIRECT) && file_attached))
fwrite_crlf(body,strlen(body)+1,fstream); /* Write additional NULL */
else
fwrite("\0",1,1,fstream); /* Write NULL */
fclose(fstream);
} while(!fexistcase(fname));
}
/******************************************************************************
This function takes the contents of 'infile' and puts it into a netmail
message bound for addr.
******************************************************************************/
void file_to_netmail(FILE *infile,char *title,faddr_t addr,char *to)
{
char *buf,*p;
long l,m,len;
l=len=ftell(infile);
if(len>8192L)
len=8192L;
rewind(infile);
if((buf=(char *)MALLOC(len+1))==NULL) {
printf("ERROR allocating %lu bytes for file to netmail buffer.\n",len);
logprintf("ERROR line %d allocating %lu for file to netmail buf",__LINE__
,len);
return; }
while((m=fread(buf,1,(len>8064L) ? 8064L:len,infile))>0) {
buf[m]=0;
if(l>8064L && (p=strrchr(buf,'\n'))!=NULL) {
fseek(infile,-1L,SEEK_CUR);
while(*p) { /* Seek back to end of last line */
p++;
fseek(infile,-1L,SEEK_CUR); } } }
if(ftell(infile)<l)
strcat(buf,"\r\nContinued in next message...\r\n");
create_netmail(to,title,buf,addr,FALSE);
}
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
}
/******************************************************************************
This function sends a notify list to applicable nodes, this list includes the
settings configured for the node, as well as a list of areas the node is
connected to.
******************************************************************************/
void notify_list(void)
{
FILE * tmpf;
char str[256];
uint i,j,k;
for(k=0;k<cfg.nodecfgs;k++) {
if(!(cfg.nodecfg[k].attr&SEND_NOTIFY))
continue;
if((tmpf=tmpfile())==NULL) {
printf("\7ERROR couldn't open tmpfile.\n");
logprintf("ERROR line %d couldn't open tmpfile",__LINE__);
return; }
fprintf(tmpf,"Following are the options set for your system and a list "
"of areas\r\nyou are connected to. Please make sure everything "
"is correct.\r\n\r\n");
fprintf(tmpf,"Packet Type %s\r\n"
,cfg.nodecfg[k].pkt_type==PKT_TWO ? "2"
:cfg.nodecfg[k].pkt_type==PKT_TWO_TWO ? "2.2":"2+");
fprintf(tmpf,"Archive Type %s\r\n"
,(cfg.nodecfg[k].arctype>cfg.arcdefs) ?
"None":cfg.arcdef[cfg.nodecfg[k].arctype].name);
fprintf(tmpf,"Mail Status %s\r\n"
,cfg.nodecfg[k].attr&ATTR_CRASH ? "Crash"
:cfg.nodecfg[k].attr&ATTR_HOLD ? "Hold" : "None");
fprintf(tmpf,"Direct %s\r\n"
,cfg.nodecfg[k].attr&ATTR_DIRECT ? "Yes":"No");
fprintf(tmpf,"Passive %s\r\n"
,cfg.nodecfg[k].attr&ATTR_PASSIVE ? "Yes":"No");
fprintf(tmpf,"Remote AreaMgr %s\r\n\r\n"
,cfg.nodecfg[k].password[0] ? "Yes" : "No");
fprintf(tmpf,"Connected Areas\r\n---------------\r\n");
for(i=0;i<cfg.areas;i++) {
sprintf(str,"%s\r\n",cfg.area[i].name);
if(str[0]=='*')
continue;
for(j=0;j<cfg.area[i].uplinks;j++)
if(!memcmp(&cfg.nodecfg[k].faddr,&cfg.area[i].uplink[j]
,sizeof(faddr_t)))
break;
if(j<cfg.area[i].uplinks)
fprintf(tmpf,"%s",str); }
if(ftell(tmpf))
file_to_netmail(tmpf,"SBBSecho Notify List",cfg.nodecfg[k].faddr,0);
fclose(tmpf); }
}
/******************************************************************************
This function creates a netmail to addr showing a list of available areas (0),
a list of connected areas (1), or a list of removed areas (2).
******************************************************************************/
void netmail_arealist(char type,faddr_t addr)
{
FILE *stream,*tmpf;
char str[256],temp[256],title[81],match,*p;
int file,i,j,k,x,y;
if(!type)
strcpy(title,"List of Available Areas");
else if(type==1)
strcpy(title,"List of Connected Areas");
else
strcpy(title,"List of Unlinked Areas");
if((tmpf=tmpfile())==NULL) {
printf("\7ERROR couldn't open tmpfile.\n");
logprintf("ERROR line %d couldn't open tmpfile",__LINE__);
return; }
if(type==1 || (type!=1 && !(misc&ELIST_ONLY))) {
for(i=0;i<cfg.areas;i++) {
sprintf(str,"%s\r\n",cfg.area[i].name);
if(type) {
for(j=0;j<cfg.area[i].uplinks;j++)
if(!memcmp(&addr,&cfg.area[i].uplink[j],sizeof(faddr_t)))
break;
if((type==1 && j<cfg.area[i].uplinks) ||
(type==2 && j==cfg.area[i].uplinks))
fprintf(tmpf,"%s",str); }
else
fprintf(tmpf,"%s",str); } }
if(!type) {
i=matchnode(addr,0);
if(i<cfg.nodecfgs) {
for(j=0;j<cfg.listcfgs;j++) {
match=0;
for(k=0;k<cfg.listcfg[j].numflags;k++) {
if(match) break;
for(x=0;x<cfg.nodecfg[i].numflags;x++)
if(!stricmp(cfg.listcfg[j].flag[k].flag
,cfg.nodecfg[i].flag[x].flag)) {
if((stream=fnopen(&file
,cfg.listcfg[j].listpath,O_RDONLY))==NULL) {
printf("\7ERROR couldn't open %s.\n"
,cfg.listcfg[j].listpath);
logprintf("ERROR line %d couldn't open %s %s"
,__LINE__,cfg.listcfg[j].listpath
,strerror(errno));
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
match=1;
break; }
while(!feof(stream)) {
if(!fgets(str,255,stream))
break;
truncsp(str);
strcat(str,"\r\n");
p=str;
while(*p && *p<=SP) p++;
if(*p==';') /* Ignore Comment Lines */
continue;
strcpy(temp,p);
p=temp;
while(*p && *p>SP) p++;
*p=0;
if(!(misc&ELIST_ONLY)) {
for(y=0;y<cfg.areas;y++)
if(!stricmp(cfg.area[y].name,temp))
break;
if(y==cfg.areas)
fprintf(tmpf,"%s",str); }
else
fprintf(tmpf,"%s",str); }
fclose(stream);
match=1;
break; } } } } }
if(!ftell(tmpf))
create_netmail(NULL,title,"None.",addr,FALSE);
else
file_to_netmail(tmpf,title,addr,0);
fclose(tmpf);
}
/******************************************************************************
Imitation of Borland's tempnam function because Watcom doesn't have it
******************************************************************************/
char *tempname(char *dir, char *prefix)
{
char str[256],*p;
int i;
for(i=0;i<1000;i++) {
sprintf(str,"%s%s%03u.$$$",dir,prefix,i);
if(!fexist(str))
break; }
if(i>=1000) {
logprintf("tempnam: too many files");
return(NULL); }
p=malloc(strlen(str)+1);
if(!p) {
logprintf("tempnam: couldn't malloc %u",strlen(str)+1);
return(NULL); }
strcpy(p,str);
return(p);
char str[1025],quit=0,*p;
int i,j,k,x,file,match=0;
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
i=matchnode(addr,0);
if(i<cfg.nodecfgs) {
for(j=0;j<cfg.listcfgs;j++) {
quit=0;
for(k=0;k<cfg.listcfg[j].numflags;k++) {
if(quit) break;
for(x=0;x<cfg.nodecfg[i].numflags;x++)
if(!stricmp(cfg.listcfg[j].flag[k].flag
,cfg.nodecfg[i].flag[x].flag)) {
if((stream=fnopen(&file
,cfg.listcfg[j].listpath,O_RDONLY))==NULL) {
printf("\7ERROR couldn't open %s.\n"
,cfg.listcfg[j].listpath);
logprintf("ERROR line %d opening %s"
,__LINE__,cfg.listcfg[j].listpath);
quit=1;
break; }
while(!feof(stream)) {
if(!fgets(str,255,stream))
break;
truncsp(str);
strcat(str,"\r\n");
p=str;
while(*p && *p<=SP) p++;
if(*p==';') /* Ignore Comment Lines */
continue;
strcpy(str,p);
p=str;
while(*p && *p>SP) p++;
*p=0;
if(!stricmp(areatag,str)) {
match=1;
break; } }
fclose(stream);
if(match)
return(match);
break; } } } }
return(match);
}
/******************************************************************************
Used by AREAFIX to add/remove/change areas in the areas file
******************************************************************************/
void alter_areas(area_t add_area,area_t del_area,faddr_t addr)
{
FILE *nmfile,*afilein,*afileout,*fwdfile;
char str[1025],fields[1025],field1[81],field2[81],field3[81]
,drive[3],dir[MAX_PATH+1],name[MAX_PATH+1],ext[MAX_PATH+1],outpath[128]
,*outname,*p,*tp,nomatch=0,match=0;
int i,j,k,x,y,file;
ulong tagcrc;
_splitpath(cfg.areafile,drive,dir,name,ext);
sprintf(outpath,"%s%s",drive,dir);
if((outname=tempname(outpath,"AREAS"))==NULL) {
printf("\7ERROR creating temp file name for %s.\n",outpath);
logprintf("ERROR tempnam(%s,AREAS)",outpath);
return; }
if((nmfile=tmpfile())==NULL) {
printf("\7ERROR couldn't open NetMail temp file.\n");
logprintf("ERROR in tmpfile()");
free(outname);
return; }
if((afileout=fopen(outname,"w+b"))==NULL) {
printf("\7ERROR couldn't open %s.\n",outname);
logprintf("ERROR line %d opening %s %s",__LINE__,outname
,strerror(errno));
fclose(nmfile);
free(outname);
return; }
if((afilein=fnopen(&file,cfg.areafile,O_RDONLY))==NULL) {
printf("\7ERROR couldn't open %s.\n",cfg.areafile);
logprintf("ERROR line %d opening %s %s",__LINE__,cfg.areafile
,strerror(errno));
fclose(afileout);
fclose(nmfile);
free(outname);
return; }
while(!feof(afilein)) {
if(!fgets(fields,1024,afilein))
break;
truncsp(fields);
strcat(fields,"\r\n");
p=fields;
while(*p && *p<=SP) p++;
if(*p==';') { /* Skip Comment Lines */
fprintf(afileout,"%s",fields);
continue; }
sprintf(field1,"%-.81s",p); /* Internal Code Field */
tp=field1;
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
*tp=0;
while(*p && *p>SP) p++;
while(*p && *p<=SP) p++;
sprintf(field2,"%-.81s",p); /* Areatag Field */
tp=field2;
while(*tp && *tp>SP) tp++;
*tp=0;
while(*p && *p>SP) p++;
while(*p && *p<=SP) p++;
if((tp=strchr(p,';'))!=NULL) {
sprintf(field3,"%-.81s",p); /* Comment Field (if any) */
while(*tp && *tp>SP) tp++;
*tp=0; }
else
field3[0]=0;
if(del_area.tags) { /* Check for areas to remove */
for(i=0;i<del_area.tags;i++) {
if(!stricmp(del_area.tag[i],field2) ||
!stricmp(del_area.tag[0],"-ALL")) /* Match Found */
break; }
if(i<del_area.tags) {
for(i=0;i<cfg.areas;i++) {
if(!stricmp(field2,cfg.area[i].name)) {
for(j=0;j<cfg.area[i].uplinks;j++)
if(!memcmp(&cfg.area[i].uplink[j],&addr
,sizeof(faddr_t)))
break;
if(j==cfg.area[i].uplinks &&
stricmp(del_area.tag[0],"-ALL")) {
fprintf(afileout,"%s",fields);
fprintf(nmfile,"%s not connected.\r\n",field2);
break; }
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
/* Added 12/4/95 to remove uplink from connected uplinks */
for(k=j;k<cfg.area[i].uplinks-1;k++)
memcpy(&cfg.area[i].uplink[k],&cfg.area[i].uplink[k+1]
,sizeof(faddr_t));
--cfg.area[i].uplinks;
if((cfg.area[i].uplink=(faddr_t *)
REALLOC(cfg.area[i].uplink,sizeof(faddr_t)
*(cfg.area[i].uplinks)))==NULL) {
printf("ERROR allocating memory for area #%u "
"uplinks.\n",i+1);
logprintf("ERROR line %d allocating memory for area "
"#%u uplinks.\n",__LINE__,i+1);
bail(1); }
fprintf(afileout,"%-16s%-23s ",field1,field2);
for(j=0;j<cfg.area[i].uplinks;j++) {
if(!memcmp(&cfg.area[i].uplink[j],&addr
,sizeof(faddr_t)))
continue;
fprintf(afileout,"%s "
,faddrtoa(&cfg.area[i].uplink[j],NULL)); }
if(field3[0])
fprintf(afileout,"%s",field3);
fprintf(afileout,"\r\n");
fprintf(nmfile,"%s removed.\r\n",field2);
break; } }
if(i==cfg.areas) /* Something screwy going on */
fprintf(afileout,"%s",fields);
continue; } } /* Area match so continue on */
if(add_area.tags) { /* Check for areas to add */
for(i=0;i<add_area.tags;i++)
if(!stricmp(add_area.tag[i],field2) ||
!stricmp(add_area.tag[0],"+ALL")) /* Match Found */
break;
if(i<add_area.tags) {
if(stricmp(add_area.tag[i],"+ALL"))
add_area.tag[i][0]=0; /* So we can check other lists */
for(i=0;i<cfg.areas;i++) {
if(!stricmp(field2,cfg.area[i].name)) {
for(j=0;j<cfg.area[i].uplinks;j++)
if(!memcmp(&cfg.area[i].uplink[j],&addr
,sizeof(faddr_t)))
break;
if(j<cfg.area[i].uplinks) {
fprintf(afileout,"%s",fields);
fprintf(nmfile,"%s already connected.\r\n",field2);
if(misc&ELIST_ONLY && !check_elists(field2,addr)) {
fprintf(afileout,"%s",fields);
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
/* Added 12/4/95 to add uplink to connected uplinks */
++cfg.area[i].uplinks;
if((cfg.area[i].uplink=(faddr_t *)
REALLOC(cfg.area[i].uplink,sizeof(faddr_t)
*(cfg.area[i].uplinks)))==NULL) {
printf("ERROR allocating memory for area #%u "
"uplinks.\n",i+1);
logprintf("ERROR line %d allocating memory for area "
"#%u uplinks.\n",__LINE__,i+1);
bail(1); }
memcpy(&cfg.area[i].uplink[j],&addr,sizeof(faddr_t));
fprintf(afileout,"%-16s%-23s ",field1,field2);
for(j=0;j<cfg.area[i].uplinks;j++)
fprintf(afileout,"%s "
,faddrtoa(&cfg.area[i].uplink[j],NULL));
if(field3[0])
fprintf(afileout,"%s",field3);
fprintf(afileout,"\r\n");
fprintf(nmfile,"%s added.\r\n",field2);
break; } }
if(i==cfg.areas) /* Something screwy going on */
fprintf(afileout,"%s",fields);
continue; } /* Area match so continue on */
nomatch=1; } /* This area wasn't in there */
fprintf(afileout,"%s",fields); } /* No match so write back line */
fclose(afilein);
if(nomatch || (add_area.tags && !stricmp(add_area.tag[0],"+ALL"))) {
i=matchnode(addr,0);
if(i<cfg.nodecfgs) {
for(j=0;j<cfg.listcfgs;j++) {
match=0;
for(k=0;k<cfg.listcfg[j].numflags;k++) {
if(match) break;
for(x=0;x<cfg.nodecfg[i].numflags;x++)
if(!stricmp(cfg.listcfg[j].flag[k].flag
,cfg.nodecfg[i].flag[x].flag)) {
if((fwdfile=tmpfile())==NULL) {
printf("\7ERROR couldn't open forwarding temp "
"file.\n");
logprintf("ERROR line %d opening forward temp "
"file",__LINE__);
match=1;
break; }
if((afilein=fnopen(&file
,cfg.listcfg[j].listpath,O_RDONLY))==NULL) {
printf("\7ERROR couldn't open %s.\n"
,cfg.listcfg[j].listpath);
logprintf("ERROR line %d opening %s"
,__LINE__,cfg.listcfg[j].listpath);
fclose(fwdfile);
match=1;
break; }
while(!feof(afilein)) {
if(!fgets(str,255,afilein))
truncsp(str);
strcat(str,"\r\n");
p=str;
while(*p && *p<=SP) p++;
if(*p==';') /* Ignore Comment Lines */
continue;
strcpy(str,p);
p=str;
while(*p && *p>SP) p++;
*p=0;
if(!stricmp(add_area.tag[0],"+ALL")) {
sprintf(fields,"%.1024s",str);
tagcrc=crc32(strupr(fields),0);