sbbsecho.c 149 KB
Newer Older
1
/* sbbsecho.c */
2

3
/* Synchronet FidoNet EchoMail Scanning/Tossing and NetMail Tossing Utility */
4

5
6
7
8
9
10
/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
11
 * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html		*
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *																			*
 * 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.	*
 ****************************************************************************/
37

38
/* Portions written by Allen Christiansen 1994-1996 						*/
39
40
41
42
43
44
45
46
47
48
49
50
51

#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>
52
#include <sys/stat.h>
53
54
55
56
57

#ifdef __WATCOMC__
	#include <mem.h>
#endif

58
#ifndef __unix__
59
60
61
	#include <malloc.h>
#endif

rswindell's avatar
rswindell committed
62
#include "conwrap.h"		/* getch() */
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#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;
79
BOOL twit_list;
80
81
82
83

faddr_t		sys_faddr;
config_t	cfg;
scfg_t		scfg;
84
char		revision[16];
85
char		compiler[32];
86

87
BOOL pause_on_exit=FALSE;
88
89
90
91
92
93
94
95

#ifndef __NT__
#define delfile(x) remove(x)
#else
int delfile(char *filename)
{
	int i=0;

96
97
98
	while(remove(filename) && i++<120)	/* Wait up to 60 seconds to delete file */
		delay(500); 					/* for Win95 bug fix */
	return(i);
99
100
101
}
#endif

102
#if defined(__unix__)	/* borrowed from MSVC */
rswindell's avatar
rswindell committed
103
unsigned _rotr (
104
105
106
107
        unsigned val,
        int shift
        )
{
108
109
110
111
112
113
114
115
116
117
118
    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 */
	}
119

120
    return num;
121
122
123
}
#endif

rswindell's avatar
rswindell committed
124
/****************************************************************************/
125
/* This is needed by load_cfg.c												*/
rswindell's avatar
rswindell committed
126
/****************************************************************************/
127
int lprintf(int level, char *fmat, ...)
rswindell's avatar
rswindell committed
128
129
130
131
132
133
{
	va_list argptr;
	char sbuf[256];
	int chcount;

	va_start(argptr,fmat);
134
	chcount=vsnprintf(sbuf,sizeof(sbuf),fmat,argptr);
135
	sbuf[sizeof(sbuf)-1]=0;
rswindell's avatar
rswindell committed
136
	va_end(argptr);
137
138
	truncsp(sbuf);
	printf("%s\n",sbuf);
rswindell's avatar
rswindell committed
139
140
141
	return(chcount);
}

142
143
144
145
146
147
148
149
150
151
/**********************/
/* Log print function */
/**********************/
void logprintf(char *str, ...)
{
    va_list argptr;
    char buf[256];
    time_t now;
    struct tm *gm;

152
153
154
155
156
157
158
159
	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);
160
	fprintf(fidologfile,"%02u/%02u/%02u %02u:%02u:%02u %s\n"
161
162
		,gm->tm_mon+1,gm->tm_mday,TM_YEAR(gm->tm_year),gm->tm_hour,gm->tm_min,gm->tm_sec
		,buf);
163
164
165
166
167
}

/*****************************************************************************/
/* Returns command line generated from instr with %c replacments             */
/*****************************************************************************/
168
char *mycmdstr(scfg_t* cfg, char *instr, char *fpath, char *fspec)
169
{
170
    static char cmd[MAX_PATH+1];
171
172
173
    char str[256],str2[128];
    int i,j,len;

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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
	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;
268

269
	return(cmd);
270
271
272
273
274
275
276
}

/****************************************************************************/
/* Runs an external program directly using spawnvp							*/
/****************************************************************************/
int execute(char *cmdline)
{
rswindell's avatar
rswindell committed
277
#if 1
278
	return system(cmdline);
rswindell's avatar
rswindell committed
279
#else
280
281
282
283
284
285
286
	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 */
287
		if(str[c]==' ') {
288
289
290
291
292
293
			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);
rswindell's avatar
rswindell committed
294
#endif
295
}
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/******************************************************************************
 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)
{
324
325
326
327
328
	char fname[MAX_PATH+1];
	char outbound[MAX_PATH+1];
	char str[MAX_PATH+1];
	char ch;
	char searchstr[MAX_PATH+1];
329
330
331
332
333
334
335
336
	ushort attr=0;
	int i,file;
	FILE *stream;

	i=matchnode(dest,0);
	if(i<(int)cfg.nodecfgs)
		attr=cfg.nodecfg[i].attr;

rswindell's avatar
rswindell committed
337
338
339
340
	if(attr&ATTR_CRASH) ch='c';
	else if(attr&ATTR_HOLD) ch='h';
	else if(attr&ATTR_DIRECT) ch='d';
	else ch='f';
341
342
	if(dest.zone==scfg.faddr[0].zone)		/* Default zone, use default outbound */
		strcpy(outbound,cfg.outbound);
343
344
	else {								/* Inter-zone outbound is OUTBOUND.XXX */
		sprintf(outbound,"%.*s.%03x"
rswindell's avatar
rswindell committed
345
			,(int)strlen(cfg.outbound)-1,cfg.outbound,dest.zone);
346
347
348
		MKDIR(outbound);
		backslash(outbound);
	}
349
	if(dest.point) {					/* Point destination is OUTBOUND\*.PNT */
rswindell's avatar
rswindell committed
350
		sprintf(str,"%04x%04x.pnt"
351
352
			,dest.net,dest.node);
		strcat(outbound,str); }
rswindell's avatar
rswindell committed
353
354
	if(outbound[strlen(outbound)-1]=='\\'
		|| outbound[strlen(outbound)-1]=='/')
355
		outbound[strlen(outbound)-1]=0;
rswindell's avatar
rswindell committed
356
	MKDIR(outbound);
357
	backslash(outbound);
358
	if(dest.point)
rswindell's avatar
rswindell committed
359
		sprintf(fname,"%s%08x.%clo",outbound,dest.point,ch);
360
	else
rswindell's avatar
rswindell committed
361
		sprintf(fname,"%s%04x%04x.%clo",outbound,dest.net,dest.node,ch);
362
363
364
	sprintf(searchstr,"^%s",attachment);
	if(findstr(searchstr,fname))	/* file already in FLO file */
		return(0);
365
	if((stream=fopen(fname,"a"))==NULL) {
366
367
		printf("\7ERROR line %d opening %s %s\n",__LINE__,fname,strerror(errno));
		logprintf("ERROR line %d opening %s %s",__LINE__,fname,strerror(errno));
368
369
		return(-1); 
	}
370
	fprintf(stream,"^%s\n",attachment);
371
372
373
374
	fclose(stream);
	return(0);
}

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
/* 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);
}

398
399
400
401
402
/******************************************************************************
 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.
******************************************************************************/
403
int create_netmail(char *to, char *subject, char *body, faddr_t dest, BOOL file_attached)
404
405
{
	FILE *fstream;
406
	char str[256],fname[MAX_PATH+1];
407
408
409
410
411
412
413
414
415
	ushort attr=0;
	int fmsg;
	uint i;
	static uint startmsg;
	time_t t;
	faddr_t	faddr;
	fmsghdr_t hdr;
	struct tm *tm;

416
417
418
419
420
421
422
423
424
425
426
	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++) {
427
			sprintf(fname,"%s%u.msg",scfg.netmail_dir,i);
428
429
430
			if(!fexistcase(fname))
				break; 
		}
431
432
433
434
435
436
		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) {
437
438
			printf("\7ERROR line %d opening %s %s\n",__LINE__,fname,strerror(errno));
			logprintf("ERROR line %d opening %s %s",__LINE__,fname,strerror(errno));
439
			return(-1); }
440

441
442
443
444
445
446
447
448
449
450
451
452
		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);
453
		if(file_attached)
454
			hdr.attr|=FIDO_FILE;
455

456
457
458
459
		if(attr&ATTR_HOLD)
			hdr.attr|=FIDO_HOLD;
		if(attr&ATTR_CRASH)
			hdr.attr|=FIDO_CRASH;
460

461
462
463
464
465
466
467
468
469
		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)
470
			SAFECOPY(hdr.to,to);
471
		else
472
			SAFECOPY(hdr.to,"SYSOP");
473

474
		SAFECOPY(hdr.subj,subject);
475
476
477
478
479
480

		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);
481
482
483
484
485
486
487
488

		/* 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");
489
			else
490
491
492
493
				fprintf(fstream," KFS");
		}
		fprintf(fstream,"\r");

494
495
496
497
498
499
		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); }
500
		if(!file_attached || (!(attr&ATTR_DIRECT) && file_attached))
501
			fwrite_crlf(body,strlen(body)+1,fstream);	/* Write additional NULL */
502
503
504
		else
			fwrite("\0",1,1,fstream);               /* Write NULL */
		fclose(fstream);
505
	} while(!fexistcase(fname));
506
	return(0);
507
508
509
510
511
512
513
514
515
516
517
}

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

518
519
520
521
522
523
524
525
526
527
528
529
	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) {
530
			p++;
531
532
			if(*p) {
				*p=0;
533
				p++;
534
535
536
537
538
539
				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");
540
541
		create_netmail(to,title,buf,addr,FALSE); 
	}
542
	FREE(buf);
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
}
/******************************************************************************
 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).
******************************************************************************/
604
void netmail_arealist(int type, faddr_t addr)
605
606
{
	FILE *stream,*tmpf;
607
	char str[256],temp[256],title[128],match,*p,*tp;
608
609
610
611
612
613
614
615
616
617
618
619
620
621
	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; }

622
	if(type==1 || !(misc&ELIST_ONLY)) {
623
624
625
626
627
628
629
		for(i=0;i<cfg.areas;i++) {
			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))
630
						fprintf(tmpf,"%s\r\n",cfg.area[i].name); }
631
			else
632
				fprintf(tmpf,"%s\r\n",cfg.area[i].name); } }
633
634
635
636
637
638
639
640
641
642
643

	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)) {
644
							if((stream=fopen(cfg.listcfg[j].listpath,"r"))==NULL) {
645
646
647
648
								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
649
									,strerror(errno));
650
651
652
								match=1;
								break; }
							while(!feof(stream)) {
653
								if(!fgets(str,sizeof(str),stream))
654
655
									break;
								p=str;
656
								SKIP_WHITESPACE(p);
657
658
								if(*p==';')     /* Ignore Comment Lines */
									continue;
659
660
661
								tp=p;
								FIND_WHITESPACE(tp);
								*tp=0;
662
663
								if(!(misc&ELIST_ONLY)) {
									for(y=0;y<cfg.areas;y++)
664
										if(!stricmp(cfg.area[y].name,p))
665
666
											break;
									if(y==cfg.areas)
667
										fprintf(tmpf,"%s\r\n",p); }
668
								else
669
									fprintf(tmpf,"%s\r\n",p); }
670
671
672
673
674
							fclose(stream);
							match=1;
							break; } } } } }

	if(!ftell(tmpf))
675
		create_netmail(NULL,title,"None.",addr,FALSE);
676
677
678
679
680
681
682
683
684
	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)
{
685
	char str[MAX_PATH+1],*p;
686
687
	int i;

688
689
690
691
692
693
694
695
696
697
698
699
700
	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);
701
702
}

rswindell's avatar
rswindell committed
703
int check_elists(char *areatag,faddr_t addr)
704
705
{
	FILE *stream;
706
	char str[1025],quit=0,*p,*tp;
rswindell's avatar
rswindell committed
707
	int i,j,k,x,file,match=0;
708

rswindell's avatar
rswindell committed
709
710
711
712
713
714
715
716
717
	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)) {
718
						if((stream=fopen(cfg.listcfg[j].listpath,"r"))==NULL) {
rswindell's avatar
rswindell committed
719
720
721
722
723
724
725
							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)) {
726
							if(!fgets(str,sizeof(str),stream))
rswindell's avatar
rswindell committed
727
728
								break;
							p=str;
729
							SKIP_WHITESPACE(p);
rswindell's avatar
rswindell committed
730
731
							if(*p==';')     /* Ignore Comment Lines */
								continue;
732
733
734
735
							tp=p;
							FIND_WHITESPACE(tp);
							*tp=0;
							if(!stricmp(areatag,p)) {
rswindell's avatar
rswindell committed
736
737
738
								match=1;
								break; } }
						fclose(stream);
739
						quit=1;
rswindell's avatar
rswindell committed
740
741
742
743
						if(match)
							return(match);
						break; } } } }
	return(match);
744
745
746
747
}
/******************************************************************************
 Used by AREAFIX to add/remove/change areas in the areas file
******************************************************************************/
748
void alter_areas(area_t* add_area,area_t* del_area,faddr_t addr)
749
750
{
	FILE *nmfile,*afilein,*afileout,*fwdfile;
751
752
	char str[1024],fields[1024],field1[256],field2[256],field3[256]
		,outpath[MAX_PATH+1]
753
		,*outname,*p,*tp,nomatch=0,match=0;
754
	int i,j,k,x,y;
755
756
	ulong tagcrc;

757
758
	SAFECOPY(outpath,cfg.areafile);
	*getfname(outpath)=0;
759
760
761
762
763
764
765
766
767
	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; }
768
	if((afileout=fopen(outname,"w+"))==NULL) {
769
770
		printf("\7ERROR couldn't open %s.\n",outname);
		logprintf("ERROR line %d opening %s %s",__LINE__,outname
771
			,strerror(errno));
772
773
774
		fclose(nmfile);
		free(outname);
		return; }
775
	if((afilein=fopen(cfg.areafile,"r"))==NULL) {
776
777
		printf("\7ERROR couldn't open %s.\n",cfg.areafile);
		logprintf("ERROR line %d opening %s %s",__LINE__,cfg.areafile
778
			,strerror(errno));
779
780
781
782
783
		fclose(afileout);
		fclose(nmfile);
		free(outname);
		return; }
	while(!feof(afilein)) {
784
		if(!fgets(fields,sizeof(fields),afilein))
785
786
787
			break;
		truncsp(fields);
		p=fields;
788
		SKIP_WHITESPACE(p);
789
		if(*p==';') {    /* Skip Comment Lines */
790
			fprintf(afileout,"%s\n",fields);
791
			continue; }
792
		SAFECOPY(field1,p);         /* Internal Code Field */
793
		truncstr(field1," \t\r\n");
794
795
796
		FIND_WHITESPACE(p);
		SKIP_WHITESPACE(p);
		SAFECOPY(field2,p);         /* Areatag Field */
797
		truncstr(field2," \t\r\n");
798
799
		FIND_WHITESPACE(p);
		SKIP_WHITESPACE(p);
800
		if((tp=strchr(p,';'))!=NULL) {
801
802
			SAFECOPY(field3,p);     /* Comment Field (if any) */
			FIND_WHITESPACE(tp);
803
804
805
			*tp=0; }
		else
			field3[0]=0;
806
807
808
809
		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 */
810
					break; }
811
			if(i<del_area->tags) {
812
813
814
815
816
817
				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;
818
819
820
821
822
823
824
						if(j==cfg.area[i].uplinks) {
							fprintf(afileout,"%s\n",fields);
							/* bugfix here Mar-25-2004 (wasn't breaking for "-ALL") */
							if(stricmp(del_area->tag[0],"-ALL"))
								fprintf(nmfile,"%s not connected.\r\n",field2);
							break; 
						}
825

826
827
828
829
830
831
						/* 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;
832
833
834
835
836
837
838
839
840
841
842
843
						if(cfg.area[i].uplinks==0) {
							FREE_AND_NULL(cfg.area[i].uplink);
						} else
							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); 
							}
844
845
846
847
848
849
850
851
852
853

						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);
854
						fprintf(afileout,"\n");
855
						fprintf(nmfile,"%s removed.\r\n",field2);
856
857
858
						break; 
					} 
				}
859
				if(i==cfg.areas)			/* Something screwy going on */
860
					fprintf(afileout,"%s\n",fields);
861
				continue; } }				/* Area match so continue on */
862
863
864
865
		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 */
866
					break;
867
868
869
			if(i<add_area->tags) {
				if(stricmp(add_area->tag[i],"+ALL"))
					add_area->tag[i][0]=0;  /* So we can check other lists */
870
871
872
873
874
875
876
				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) {
877
							fprintf(afileout,"%s\n",fields);
878
							fprintf(nmfile,"%s already connected.\r\n",field2);
879
							break; }
880
						if(misc&ELIST_ONLY && !check_elists(field2,addr)) {
881
							fprintf(afileout,"%s\n",fields);
882
							break; }
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

						/* 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);
903
						fprintf(afileout,"\n");
904
905
906
						fprintf(nmfile,"%s added.\r\n",field2);
						break; } }
				if(i==cfg.areas)			/* Something screwy going on */
907
					fprintf(afileout,"%s\n",fields);
908
909
				continue; } 				/* Area match so continue on */
			nomatch=1; }					/* This area wasn't in there */
910
		fprintf(afileout,"%s\n",fields); }  /* No match so write back line */
911
	fclose(afilein);
912
	if(nomatch || (add_area->tags && !stricmp(add_area->tag[0],"+ALL"))) {
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
		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; }
929
							if((afilein=fopen(cfg.listcfg[j].listpath,"r"))==NULL) {
930
931
932
933
934
935
936
937
								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)) {
938
								if(!fgets(str,sizeof(str),afilein))
939
									break;
940
								p=str;
941
								SKIP_WHITESPACE(p);
942
943
								if(*p==';')     /* Ignore Comment Lines */
									continue;
944
945
946
947
948
949
								tp=p;
								FIND_WHITESPACE(tp);
								*tp=0;
								if(!stricmp(add_area->tag[0],"+ALL")) {
									SAFECOPY(tmp,p);
									tagcrc=crc32(strupr(tmp),0);
950
951
952
953
954
									for(y=0;y<cfg.areas;y++)
										if(tagcrc==cfg.area[y].tag)
											break;
									if(y<cfg.areas)
										continue; }
955
956
957
958
								for(y=0;y<add_area->tags;y++)
									if((!stricmp(add_area->tag[y],str) &&
										add_area->tag[y][0]) ||
										!stricmp(add_area->tag[0],"+ALL"))
959
										break;
960
								if(y<add_area->tags) {
961
962
963
964
									fprintf(afileout,"%-16s%-23s","P",str);
									if(cfg.listcfg[j].forward.zone)
										fprintf(afileout," %s"
											,faddrtoa(&cfg.listcfg[j].forward,NULL));
965
									fprintf(afileout," %s\n",faddrtoa(&addr,NULL));
966
									fprintf(nmfile,"%s added.\r\n",str);
967
968
									if(stricmp(add_area->tag[0],"+ALL"))
										add_area->tag[y][0]=0;
969
970
971
972
973
974
975
976
977
978
									if(!(cfg.listcfg[j].misc&NOFWD)
										&& cfg.listcfg[j].forward.zone)
										fprintf(fwdfile,"%s\r\n",str); } }
							fclose(afilein);
							if(!(cfg.listcfg[j].misc&NOFWD) && ftell(fwdfile)>0)
								file_to_netmail(fwdfile,cfg.listcfg[j].password
									,cfg.listcfg[j].forward,"Areafix");
							fclose(fwdfile);
							match=1;
							break; } } } } }
979
980
981
982
	if(add_area->tags && stricmp(add_area->tag[0],"+ALL")) {
		for(i=0;i<add_area->tags;i++)
			if(add_area->tag[i][0])
				fprintf(nmfile,"%s not found.\r\n",add_area->tag[i]); }
983
	if(!ftell(nmfile))
984
		create_netmail(NULL,"Area Change Request","No changes made.",addr,FALSE);
985
986
987
988
989
990
	else
		file_to_netmail(nmfile,"Area Change Request",addr,0);
	fclose(nmfile);
	fclose(afileout);
	if(delfile(cfg.areafile))					/* Delete AREAS.BBS */
		logprintf("ERROR line %d removing %s %s",__LINE__,cfg.areafile
991
			,strerror(errno));
992
993
994
	if(rename(outname,cfg.areafile))		   /* Rename new AREAS.BBS file */
		logprintf("ERROR line %d renaming %s to %s",__LINE__,outname,cfg.areafile);
	free(outname);
995
996
997
998
999
1000
1001
1002
1003
}
/******************************************************************************
 Used by AREAFIX to add/remove/change uplink info in the configuration file
 old = the old setting for this option, new = what the setting is changing to
 option = 0 for compression type change
		  1 for areafix password change
		  2 to set this node to passive
		  3 to set this node to active (remove passive)
******************************************************************************/
1004
void alter_config(faddr_t addr, char *old, char *new, int option)
1005
1006
{
	FILE *outfile,*cfgfile;
1007
1008
	char str[257],outpath[MAX_PATH+1],tmp[257],tmp2[257],*outname,*p,*tp
		,match=0;
1009
1010
1011
	int i,j,k,file;
	faddr_t taddr;

rswindell's avatar
rswindell committed
1012
	i=matchnode(addr,0);				  /* i = config number from here on */
1013
1014
	SAFECOPY(outpath,cfg.cfgfile);
	*getfname(outpath)=0;
rswindell's avatar
rswindell committed
1015
1016
1017
1018
	if((outname=tempname(outpath,"CFG"))==NULL) {
		printf("\7ERROR creating temporary file name for %s.\n",outpath);
		logprintf("ERROR tempnam(%s,CFG)",outpath);
		return; }
1019
	if((outfile=fopen(outname,"w+"))==NULL) {
rswindell's avatar
rswindell committed
1020
1021
		printf("\7ERROR couldn't open %s.\n",outname);
		logprintf("ERROR line %d opening %s %s",__LINE__,outname
1022
			,strerror(errno));
rswindell's avatar
rswindell committed
1023
1024
		free(outname);
		return; }
1025
	if((cfgfile=fopen(cfg.cfgfile,"r"))==NULL) {
rswindell's avatar
rswindell committed
1026
1027
		printf("\7ERROR couldn't open %s.\n",cfg.cfgfile);
		logprintf("ERROR line %d opening %s",__LINE__,cfg.cfgfile
1028
			,strerror(errno));
rswindell's avatar
rswindell committed
1029
1030
1031
		fclose(outfile);
		free(outname);
		return; }
1032

rswindell's avatar
rswindell committed
1033
	while(!feof(cfgfile)) {
1034
		if(!fgets(str,sizeof(str),cfgfile))
rswindell's avatar
rswindell committed
1035
1036
1037
			break;
		truncsp(str);
		p=str;
1038
		SKIP_WHITESPACE(p);
rswindell's avatar
rswindell committed
1039
		if(*p==';') {
1040
			fprintf(outfile,"%s\n",str);
1041
			continue; }
rswindell's avatar
rswindell committed
1042
		sprintf(tmp,"%-.25s",p);
1043
		tp=strchr(tmp,' ');
rswindell's avatar
rswindell committed
1044
1045
1046
		if(tp)
			*tp=0;								/* Chop off at space */
		strupr(tmp);							/* Convert code to uppercase */
1047
1048
		FIND_WHITESPACE(p);						/* Skip code */
		SKIP_WHITESPACE(p);						/* Skip white space */
rswindell's avatar
rswindell committed
1049
1050
1051
1052
1053
1054

		if(option==0 && !strcmp(tmp,"USEPACKER")) {     /* Change Compression */
			if(!*p)
				continue;
			strcpy(tmp2,p);
			p=tmp2;
1055
			FIND_WHITESPACE(p);
rswindell's avatar
rswindell committed
1056
1057
1058
			*p=0;
			p++;
			if(!stricmp(new,tmp2)) {   /* Add to new definition */
1059
				fprintf(outfile,"%-10s %s %s %s\n",tmp,tmp2
rswindell's avatar
rswindell committed
1060
1061
1062
					,faddrtoa(&cfg.nodecfg[i].faddr,NULL)
					,(*p) ? p : "");
				match=1;
1063
				continue; }
rswindell's avatar
rswindell committed
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
			else if(!stricmp(old,tmp2)) {	/* Remove from old def */
				for(j=k=0;j<cfg.nodecfgs;j++) {
					if(j==i)
						continue;
					if(!stricmp(cfg.arcdef[cfg.nodecfg[j].arctype].name,tmp2)) {
						if(!k) {
							fprintf(outfile,"%-10s %s",tmp,tmp2);
							k++; }
						fprintf(outfile," %s"
							,faddrtoa(&cfg.nodecfg[j].faddr,NULL)); } }
1074
				fprintf(outfile,"\n");
rswindell's avatar
rswindell committed
1075
1076
1077
1078
				continue; } }

		if(option==1 && !strcmp(tmp,"AREAFIX")) {       /* Change Password */
			if(!*p)
1079
				continue;
rswindell's avatar
rswindell committed
1080
1081
			taddr=atofaddr(p);
			if(!memcmp(&cfg.nodecfg[i].faddr,&taddr,sizeof(faddr_t))) {
1082
1083
1084
1085
				FIND_WHITESPACE(p); 	/* Skip over address */
				SKIP_WHITESPACE(p);	/* Skip over whitespace */
				FIND_WHITESPACE(p); 	/* Skip over password */
				SKIP_WHITESPACE(p);	/* Skip over whitespace */
1086
				fprintf(outfile,"%-10s %s %s %s\n",tmp
rswindell's avatar
rswindell committed
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
					,faddrtoa(&cfg.nodecfg[i].faddr,NULL),new,p);
				continue; } }

		if(option>1 && !strcmp(tmp,"PASSIVE")) {        /* Toggle Passive Areas */
			match=1;
			for(j=k=0;j<cfg.nodecfgs;j++) {
				if(option==2 && j==i) {
					if(!k) fprintf(outfile,"%-10s",tmp);
					fprintf(outfile," %s",faddrtoa(&cfg.nodecfg[j].faddr,NULL));
					k++;
					continue; }
				if(option==3 && j==i)
					continue;
				if(cfg.nodecfg[j].attr&ATTR_PASSIVE) {
					if(!k) fprintf(outfile,"%-10s",tmp);
					fprintf(outfile," %s",faddrtoa(&cfg.nodecfg[j].faddr,NULL));
					k++; } }
1104
			if(k) fprintf(outfile,"\n");
rswindell's avatar
rswindell committed
1105
			continue; }
1106
		fprintf(outfile,"%s\n",str); }
rswindell's avatar
rswindell committed
1107
1108
1109

	if(!match) {
		if(option==0)
1110
			fprintf(outfile,"%-10s %s %s\n","USEPACKER",new
rswindell's avatar
rswindell committed
1111
1112
				,faddrtoa(&cfg.nodecfg[i].faddr,NULL));
		if(option==2)
1113
			fprintf(outfile,"%-10s %s\n","PASSIVE"
rswindell's avatar
rswindell committed
1114
1115
1116
1117
1118
1119
				,faddrtoa(&cfg.nodecfg[i].faddr,NULL)); }

	fclose(cfgfile);
	fclose(outfile);
	if(delfile(cfg.cfgfile))
		logprintf("ERROR line %d removing %s %s",__LINE__,cfg.cfgfile
1120
			,strerror(errno));
rswindell's avatar
rswindell committed
1121
1122
1123
	if(rename(outname,cfg.cfgfile))
		logprintf("ERROR line %d renaming %s to %s",__LINE__,outname,cfg.cfgfile);
	free(outname);
1124
1125
1126
1127
1128
1129
1130
}
/******************************************************************************
 Used by AREAFIX to process any '%' commands that come in via netmail
******************************************************************************/
void command(char *instr,faddr_t addr)
{
	FILE *stream,*tmpf;
1131
	char str[MAX_PATH+1],temp[256],*buf,*p;
1132
1133
1134
1135
1136
	int  file,i,node;
	long l;
	area_t add_area,del_area;

	node=matchnode(addr,0);
1137
	if(node>=cfg.nodecfgs)
1138
1139
1140
1141
1142
		return;
	memset(&add_area,0,sizeof(area_t));
	memset(&del_area,0,sizeof(area_t));
	strupr(instr);
	if((p=strstr(instr,"HELP"))!=NULL) {
rswindell's avatar
rswindell committed
1143
		sprintf(str,"%sAREAMGR.HLP",scfg.exec_dir);
1144
		if(!fexistcase(str))
1145
1146
1147
1148
			return;
		if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
			printf("\7ERROR couldn't open %s.\n",str);
			logprintf("ERROR line %d opening %s %s",__LINE__,str
1149
				,strerror(errno));
1150
1151
			return; 
		}
1152
		l=filelength(file);
1153
		if((buf=(char *)malloc(l+1L))==NULL) {
1154
			printf("ERROR line %d allocating %lu bytes for %s\n",__LINE__,l,str);
1155
1156
			return; 
		}
1157
1158
1159
		fread(buf,l,1,stream);
		fclose(stream);
		buf[l]=0;
1160
		create_netmail(NULL,"Area Manager Help",buf,addr,FALSE);
1161
		free(buf);
1162
1163
		return; 
	}
1164
1165
1166

	if((p=strstr(instr,"LIST"))!=NULL) {
		netmail_arealist(0,addr);
1167
1168
		return; 
	}
1169
1170
1171

	if((p=strstr(instr,"QUERY"))!=NULL) {
		netmail_arealist(1,addr);
1172
1173
		return; 
	}
1174
1175
1176

	if((p=strstr(instr,"UNLINKED"))!=NULL) {
		netmail_arealist(2,addr);
1177
1178
		return; 
	}
1179
1180

	if((p=strstr(instr,"COMPRESSION"))!=NULL) {
1181
1182
		FIND_WHITESPACE(p);
		SKIP_WHITESPACE(p);
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
		for(i=0;i<cfg.arcdefs;i++)
			if(!stricmp(p,cfg.arcdef[i].name))
				break;
		if(!stricmp(p,"NONE"))
			i=0xffff;
		if(i==cfg.arcdefs) {
			if((tmpf=tmpfile())==NULL) {
				printf("\7ERROR couldn't open tmpfile.\n");
				logprintf("ERROR line %d opening tmpfile()",__LINE__);
				return; }
			fprintf(tmpf,"Compression type unavailable.\r\n\r\n"
				"Available types are:\r\n");
			for(i=0;i<cfg.arcdefs;i++)
				fprintf(tmpf,"                     %s\r\n",cfg.arcdef[i].name);
			file_to_netmail(tmpf,"Compression Type Change",addr,0);
			fclose(tmpf);
1199
1200
			return; 
		}
1201
1202
1203
1204
		alter_config(addr,cfg.arcdef[cfg.nodecfg[node].arctype].name
			,cfg.arcdef[i].name,0);
		cfg.nodecfg[node].arctype=i;
		sprintf(str,"Compression type changed to %s.",cfg.arcdef[i].name);
1205
		create_netmail(NULL,"Compression Type Change",str,addr,FALSE);
1206
1207
		return; 
	}
1208
1209

	if((p=strstr(instr,"PASSWORD"))!=NULL) {
1210
1211