Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

scfglib2.c 31.3 KB
Newer Older
1 2 3 4 5 6
/* Synchronet configuration library routines */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *																			*
 * 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										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "scfglib.h"
23 24
#include "nopen.h"
#include "ars_defs.h"
25 26

/****************************************************************************/
rswindell's avatar
rswindell committed
27
/* Reads in FILE.CNF and initializes the associated variables				*/
28
/****************************************************************************/
29
BOOL read_file_cfg(scfg_t* cfg, char* error, size_t maxerrlen)
30
{
31
	char	str[MAX_PATH+1],c,cmd[LEN_CMD+1];
deuce's avatar
64-bit  
deuce committed
32 33 34 35
	short	i,j;
	int16_t	n;
	long	offset=0;
	int32_t	t;
36 37
	FILE	*instream;

38 39
	const char* fname = "file.cnf";
	SAFEPRINTF2(str,"%s%s",cfg->ctrl_dir,fname);
40
	if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
41
		safe_snprintf(error, maxerrlen,"%d (%s) opening %s",errno,STRERROR(errno),str);
42 43
		return(FALSE); 
	}
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

	get_int(cfg->min_dspace,instream);
	get_int(cfg->max_batup,instream);

	get_int(cfg->max_batdn,instream);

	get_int(cfg->max_userxfer,instream);

	get_int(t,instream);	/* unused - was cdt_byte_value */
	get_int(cfg->cdt_up_pct,instream);
	get_int(cfg->cdt_dn_pct,instream);
	get_int(t,instream);	/* unused - was temp_ext */
	get_str(cmd,instream);	/* unused - was temp_cmd */
	get_int(cfg->leech_pct,instream);
	get_int(cfg->leech_sec,instream);
59
	get_int(cfg->file_misc,instream);
60

61
	for(i=0;i<30;i++)
62 63 64 65 66 67 68 69 70
		get_int(n,instream);

	/**************************/
	/* Extractable File Types */
	/**************************/

	get_int(cfg->total_fextrs,instream);

	if(cfg->total_fextrs) {
deuce's avatar
deuce committed
71
		if((cfg->fextr=(fextr_t **)malloc(sizeof(fextr_t *)*cfg->total_fextrs))==NULL)
72
			return allocerr(instream, error, maxerrlen, offset, fname, sizeof(fextr_t*)*cfg->total_fextrs); 
73
	} else
74 75 76 77 78
		cfg->fextr=NULL;

	for(i=0; i<cfg->total_fextrs; i++) {
		if(feof(instream))
			break;
deuce's avatar
deuce committed
79
		if((cfg->fextr[i]=(fextr_t *)malloc(sizeof(fextr_t)))==NULL)
80
			return allocerr(instream, error, maxerrlen, offset, fname, sizeof(fextr_t));
81 82
		memset(cfg->fextr[i],0,sizeof(fextr_t));
		get_str(cfg->fextr[i]->ext,instream);
83 84
		get_str(cfg->fextr[i]->cmd,instream);
		get_str(cfg->fextr[i]->arstr,instream);
85
		arstr(NULL, cfg->fextr[i]->arstr, cfg, cfg->fextr[i]->ar);
86

87 88
		for(j=0;j<8;j++)
			get_int(n,instream);
89
	}
90 91 92 93 94 95 96 97 98
	cfg->total_fextrs=i;

	/***************************/
	/* Compressable File Types */
	/***************************/

	get_int(cfg->total_fcomps,instream);

	if(cfg->total_fcomps) {
deuce's avatar
deuce committed
99
		if((cfg->fcomp=(fcomp_t **)malloc(sizeof(fcomp_t *)*cfg->total_fcomps))==NULL)
100
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(fcomp_t*)*cfg->total_fcomps); 
101
	} else
102 103 104 105 106
		cfg->fcomp=NULL;

	for(i=0; i<cfg->total_fcomps; i++) {
		if(feof(instream))
			break;
deuce's avatar
deuce committed
107
		if((cfg->fcomp[i]=(fcomp_t *)malloc(sizeof(fcomp_t)))==NULL)
108
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(fcomp_t));
109 110
		memset(cfg->fcomp[i],0,sizeof(fcomp_t));
		get_str(cfg->fcomp[i]->ext,instream);
111 112
		get_str(cfg->fcomp[i]->cmd,instream);
		get_str(cfg->fcomp[i]->arstr,instream);
113
		arstr(NULL, cfg->fcomp[i]->arstr, cfg, cfg->fcomp[i]->ar);
114

115 116
		for(j=0;j<8;j++)
			get_int(n,instream);
117
	}
118 119 120 121 122 123 124 125 126
	cfg->total_fcomps=i;

	/***********************/
	/* Viewable File Types */
	/***********************/

	get_int(cfg->total_fviews,instream);

	if(cfg->total_fviews) {
deuce's avatar
deuce committed
127
		if((cfg->fview=(fview_t **)malloc(sizeof(fview_t *)*cfg->total_fviews))==NULL)
128
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(fview_t*)*cfg->total_fviews); 
129
	} else
130 131 132 133
		cfg->fview=NULL;

	for(i=0; i<cfg->total_fviews; i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
134
		if((cfg->fview[i]=(fview_t *)malloc(sizeof(fview_t)))==NULL)
135
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(fview_t));
136 137
		memset(cfg->fview[i],0,sizeof(fview_t));
		get_str(cfg->fview[i]->ext,instream);
138 139
		get_str(cfg->fview[i]->cmd,instream);
		get_str(cfg->fview[i]->arstr,instream);
140
		arstr(NULL, cfg->fview[i]->arstr, cfg, cfg->fview[i]->ar);
141

142 143
		for(j=0;j<8;j++)
			get_int(n,instream);
144
	}
145 146 147 148 149 150 151 152 153
	cfg->total_fviews=i;

	/***********************/
	/* Testable File Types */
	/***********************/

	get_int(cfg->total_ftests,instream);

	if(cfg->total_ftests) {
deuce's avatar
deuce committed
154
		if((cfg->ftest=(ftest_t **)malloc(sizeof(ftest_t *)*cfg->total_ftests))==NULL)
155
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(ftest_t*)*cfg->total_ftests); 
156
	} else
157 158 159 160
		cfg->ftest=NULL;

	for(i=0; i<cfg->total_ftests; i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
161
		if((cfg->ftest[i]=(ftest_t *)malloc(sizeof(ftest_t)))==NULL)
162
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(ftest_t));
163 164
		memset(cfg->ftest[i],0,sizeof(ftest_t));
		get_str(cfg->ftest[i]->ext,instream);
165 166 167
		get_str(cfg->ftest[i]->cmd,instream);
		get_str(cfg->ftest[i]->workstr,instream);
		get_str(cfg->ftest[i]->arstr,instream);
168
		arstr(NULL, cfg->ftest[i]->arstr, cfg, cfg->ftest[i]->ar);
169

170 171
		for(j=0;j<8;j++)
			get_int(n,instream);
172
	}
173 174 175 176 177 178 179 180 181
	cfg->total_ftests=i;

	/*******************/
	/* Download events */
	/*******************/

	get_int(cfg->total_dlevents,instream);

	if(cfg->total_dlevents) {
deuce's avatar
deuce committed
182
		if((cfg->dlevent=(dlevent_t **)malloc(sizeof(dlevent_t *)*cfg->total_dlevents))
183
			==NULL)
184
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(dlevent_t*)*cfg->total_dlevents); 
185
	} else
186 187 188 189
		cfg->dlevent=NULL;

	for(i=0; i<cfg->total_dlevents; i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
190
		if((cfg->dlevent[i]=(dlevent_t *)malloc(sizeof(dlevent_t)))==NULL)
191
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(dlevent_t));
192 193
		memset(cfg->dlevent[i],0,sizeof(dlevent_t));
		get_str(cfg->dlevent[i]->ext,instream);
194 195 196
		get_str(cfg->dlevent[i]->cmd,instream);
		get_str(cfg->dlevent[i]->workstr,instream);
		get_str(cfg->dlevent[i]->arstr,instream);
197
		arstr(NULL, cfg->dlevent[i]->arstr, cfg, cfg->dlevent[i]->ar);
198

199 200
		for(j=0;j<8;j++)
			get_int(n,instream);
201
	}
202 203 204 205 206 207 208 209 210 211
	cfg->total_dlevents=i;


	/***************************/
	/* File Transfer Protocols */
	/***************************/

	get_int(cfg->total_prots,instream);

	if(cfg->total_prots) {
deuce's avatar
deuce committed
212
		if((cfg->prot=(prot_t **)malloc(sizeof(prot_t *)*cfg->total_prots))==NULL)
213
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(prot_t*)*cfg->total_prots); 
214
	} else
215 216 217 218
		cfg->prot=NULL;

	for(i=0;i<cfg->total_prots;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
219
		if((cfg->prot[i]=(prot_t *)malloc(sizeof(prot_t)))==NULL)
220
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(prot_t));
221 222 223
		memset(cfg->prot[i],0,sizeof(prot_t));

		get_int(cfg->prot[i]->mnemonic,instream);
224 225 226 227 228 229 230
		get_str(cfg->prot[i]->name,instream);
		get_str(cfg->prot[i]->ulcmd,instream);
		get_str(cfg->prot[i]->dlcmd,instream);
		get_str(cfg->prot[i]->batulcmd,instream);
		get_str(cfg->prot[i]->batdlcmd,instream);
		get_str(cfg->prot[i]->blindcmd,instream);
		get_str(cfg->prot[i]->bicmd,instream);
231
		get_int(cfg->prot[i]->misc,instream);
232
		get_str(cfg->prot[i]->arstr,instream);
233
		arstr(NULL, cfg->prot[i]->arstr, cfg, cfg->prot[i]->ar);
234

235 236
		for(j=0;j<8;j++)
			get_int(n,instream);
237
	}
238
	cfg->total_prots=i;
239 240 241 242 243 244 245 246

	/************************/
	/* Alternate File Paths */
	/************************/

	get_int(cfg->altpaths,instream);

	if(cfg->altpaths) {
deuce's avatar
deuce committed
247
		if((cfg->altpath=(char **)malloc(sizeof(char *)*cfg->altpaths))==NULL)
248
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(char *)*cfg->altpaths); 
249
	} else
250 251 252 253 254
		cfg->altpath=NULL;

	for(i=0;i<cfg->altpaths;i++) {
		if(feof(instream)) break;
		fread(str,LEN_DIR+1,1,instream);
255
		str[LEN_DIR] = 0;
256 257 258
		offset+=LEN_DIR+1;
		backslash(str);
		j=LEN_DIR+1;
deuce's avatar
deuce committed
259
		if((cfg->altpath[i]=(char *)malloc(j))==NULL)
260
			return allocerr(instream, error, maxerrlen,offset,fname,j);
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
		memset(cfg->altpath[i],0,j);
		strcpy(cfg->altpath[i],str);
		for(j=0;j<8;j++)
			get_int(n,instream);
		}

	cfg->altpaths=i;

	/******************/
	/* File Libraries */
	/******************/

	get_int(cfg->total_libs,instream);

	if(cfg->total_libs) {
deuce's avatar
deuce committed
276
		if((cfg->lib=(lib_t **)malloc(sizeof(lib_t *)*cfg->total_libs))==NULL)
277
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(lib_t *)*cfg->total_libs);
278
	} else
279 280 281 282
		cfg->lib=NULL;

	for(i=0;i<cfg->total_libs;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
283
		if((cfg->lib[i]=(lib_t *)malloc(sizeof(lib_t)))==NULL)
284
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(lib_t));
285 286 287
		memset(cfg->lib[i],0,sizeof(lib_t));
		cfg->lib[i]->offline_dir=INVALID_DIR;

288 289 290 291
		get_str(cfg->lib[i]->lname,instream);
		get_str(cfg->lib[i]->sname,instream);

		get_str(cfg->lib[i]->arstr,instream);
292
		arstr(NULL, cfg->lib[i]->arstr, cfg, cfg->lib[i]->ar);
293

294 295
		get_str(cfg->lib[i]->parent_path,instream);

296 297 298
		get_str(cfg->lib[i]->code_prefix,instream);

		get_int(c,instream);
299
		cfg->lib[i]->sort = c;
300

301 302 303
		get_int(cfg->lib[i]->misc, instream);
		
		for(j=0;j<1;j++)
304
			get_int(n,instream);	/* 0x0000 */
305 306 307

		for(j=0;j<16;j++)
			get_int(n,instream);	/* 0xffff */
308
	}
309 310 311 312 313 314 315 316 317 318
	cfg->total_libs=i;

	/********************/
	/* File Directories */
	/********************/

	cfg->sysop_dir=cfg->user_dir=cfg->upload_dir=INVALID_DIR;
	get_int(cfg->total_dirs,instream);

	if(cfg->total_dirs) {
deuce's avatar
deuce committed
319
		if((cfg->dir=(dir_t **)malloc(sizeof(dir_t *)*(cfg->total_dirs+1)))==NULL)
320
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(dir_t *)*(cfg->total_dirs+1));
321
	} else
322 323 324 325
		cfg->dir=NULL;

	for(i=0;i<cfg->total_dirs;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
326
		if((cfg->dir[i]=(dir_t *)malloc(sizeof(dir_t)))==NULL)
327
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(dir_t));
328 329
		memset(cfg->dir[i],0,sizeof(dir_t));

330 331
		cfg->dir[i]->dirnum = i;

332
		get_int(cfg->dir[i]->lib,instream);
333 334
		get_str(cfg->dir[i]->lname,instream);
		get_str(cfg->dir[i]->sname,instream);
335

336
		if(!stricmp(cfg->dir[i]->sname,"SYSOP"))			/* Sysop upload directory */
337
			cfg->sysop_dir=i;
338
		else if(!stricmp(cfg->dir[i]->sname,"USER"))		/* User to User xfer dir */
339
			cfg->user_dir=i;
340
		else if(!stricmp(cfg->dir[i]->sname,"UPLOADS"))  /* Upload directory */
341
			cfg->upload_dir=i;
342
		else if(!stricmp(cfg->dir[i]->sname,"OFFLINE"))	/* Offline files dir */
343 344
			cfg->lib[cfg->dir[i]->lib]->offline_dir=i;

345
		get_str(cfg->dir[i]->code_suffix,instream);
346 347

		get_str(cfg->dir[i]->data_dir,instream);
348 349 350 351 352 353

		get_str(cfg->dir[i]->arstr,instream);
		get_str(cfg->dir[i]->ul_arstr,instream);
		get_str(cfg->dir[i]->dl_arstr,instream);
		get_str(cfg->dir[i]->op_arstr,instream);

354 355 356 357
		arstr(NULL, cfg->dir[i]->arstr ,cfg, cfg->dir[i]->ar);
		arstr(NULL, cfg->dir[i]->ul_arstr, cfg, cfg->dir[i]->ul_ar);
		arstr(NULL, cfg->dir[i]->dl_arstr, cfg, cfg->dir[i]->dl_ar);
		arstr(NULL, cfg->dir[i]->op_arstr, cfg, cfg->dir[i]->op_ar);
358 359 360 361 362

		get_str(cfg->dir[i]->path,instream);

		get_str(cfg->dir[i]->upload_sem,instream);

363 364 365
		get_int(cfg->dir[i]->maxfiles,instream);
		if(cfg->dir[i]->maxfiles>MAX_FILES)
			cfg->dir[i]->maxfiles=MAX_FILES;
366
		get_str(cfg->dir[i]->exts,instream);
367 368 369
		get_int(cfg->dir[i]->misc,instream);
		get_int(cfg->dir[i]->seqdev,instream);
		get_int(cfg->dir[i]->sort,instream);
370
		get_str(cfg->dir[i]->ex_arstr,instream);
371
		arstr(NULL, cfg->dir[i]->ex_arstr, cfg, cfg->dir[i]->ex_ar);
372

373 374 375 376 377
		get_int(cfg->dir[i]->maxage,instream);
		get_int(cfg->dir[i]->up_pct,instream);
		get_int(cfg->dir[i]->dn_pct,instream);
		get_int(c,instream);
		for(j=0;j<24;j++)
378 379
			get_int(n,instream); 
	}
380 381 382 383 384 385 386 387 388 389 390

	cfg->total_dirs=i;

	/**********************/
	/* Text File Sections */
	/**********************/

	get_int(cfg->total_txtsecs,instream);


	if(cfg->total_txtsecs) {
deuce's avatar
deuce committed
391
		if((cfg->txtsec=(txtsec_t **)malloc(sizeof(txtsec_t *)*cfg->total_txtsecs))==NULL)
392
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(txtsec_t *)*cfg->total_txtsecs); 
393
	} else
394 395 396 397
		cfg->txtsec=NULL;

	for(i=0;i<cfg->total_txtsecs;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
398
		if((cfg->txtsec[i]=(txtsec_t *)malloc(sizeof(txtsec_t)))==NULL)
399
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(txtsec_t));
400 401
		memset(cfg->txtsec[i],0,sizeof(txtsec_t));

402
		get_str(cfg->txtsec[i]->name,instream);
403
		get_str(cfg->txtsec[i]->code,instream);
404
		get_str(cfg->txtsec[i]->arstr,instream);
405
		arstr(NULL, cfg->txtsec[i]->arstr, cfg, cfg->txtsec[i]->ar);
406

407 408
		for(j=0;j<8;j++)
			get_int(n,instream);
409
	}
410 411 412
	cfg->total_txtsecs=i;

	fclose(instream);
413
	return(TRUE);
414 415 416 417 418
}

/****************************************************************************/
/* Reads in XTRN.CNF and initializes the associated variables				*/
/****************************************************************************/
419
BOOL read_xtrn_cfg(scfg_t* cfg, char* error, size_t maxerrlen)
420
{
421
	char	str[MAX_PATH+1],c;
deuce's avatar
64-bit  
deuce committed
422 423
	short	i,j;
	int16_t	n;
424 425 426
	long	offset=0;
	FILE	*instream;

427 428
	const char* fname = "xtrn.cnf";
	SAFEPRINTF2(str,"%s%s",cfg->ctrl_dir,fname);
429
	if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
430
		safe_snprintf(error, maxerrlen,"%d (%s) opening %s",errno,STRERROR(errno),str);
431 432
		return(FALSE); 
	}
433 434 435 436 437 438 439 440

	/*************/
	/* Swap list */
	/*************/

	get_int(cfg->total_swaps,instream);

	if(cfg->total_swaps) {
deuce's avatar
deuce committed
441
		if((cfg->swap=(swap_t **)malloc(sizeof(swap_t *)*cfg->total_swaps))==NULL)
442
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(swap_t *)*cfg->total_swaps); 
443
	} else
444 445 446 447
		cfg->swap=NULL;

	for(i=0;i<cfg->total_swaps;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
448
		if((cfg->swap[i]=(swap_t *)malloc(sizeof(swap_t)))==NULL)
449
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(swap_t));
450 451
		get_str(cfg->swap[i]->cmd,instream); 
	}
452 453 454 455 456 457 458 459 460
	cfg->total_swaps=i;

	/********************/
	/* External Editors */
	/********************/

	get_int(cfg->total_xedits,instream);

	if(cfg->total_xedits) {
deuce's avatar
deuce committed
461
		if((cfg->xedit=(xedit_t **)malloc(sizeof(xedit_t *)*cfg->total_xedits))==NULL)
462
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(xedit_t *)*cfg->total_xedits); 
463
	} else
464 465 466 467
		cfg->xedit=NULL;

	for(i=0;i<cfg->total_xedits;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
468
		if((cfg->xedit[i]=(xedit_t *)malloc(sizeof(xedit_t)))==NULL)
469
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(xedit_t));
470 471
		memset(cfg->xedit[i],0,sizeof(xedit_t));

472
		get_str(cfg->xedit[i]->name,instream);
473
		get_str(cfg->xedit[i]->code,instream);
474 475
		get_str(cfg->xedit[i]->lcmd,instream);
		get_str(cfg->xedit[i]->rcmd,instream);
476 477

		get_int(cfg->xedit[i]->misc,instream);
478
		get_str(cfg->xedit[i]->arstr,instream);
479
		arstr(NULL, cfg->xedit[i]->arstr, cfg, cfg->xedit[i]->ar);
480

481 482
		get_int(cfg->xedit[i]->type,instream);
		get_int(c,instream);
483 484 485
		if(c == XEDIT_SOFT_CR_UNDEFINED)
			c = (cfg->xedit[i]->misc&QUICKBBS) ? XEDIT_SOFT_CR_EXPAND : XEDIT_SOFT_CR_RETAIN;
		cfg->xedit[i]->soft_cr = c;
486 487
		get_int(cfg->xedit[i]->quotewrap_cols, instream);
		for(j=0;j<6;j++)
488
			get_int(n,instream);
489
	}
490 491 492 493 494 495 496 497 498 499
	cfg->total_xedits=i;


	/*****************************/
	/* External Program Sections */
	/*****************************/

	get_int(cfg->total_xtrnsecs,instream);

	if(cfg->total_xtrnsecs) {
deuce's avatar
deuce committed
500
		if((cfg->xtrnsec=(xtrnsec_t **)malloc(sizeof(xtrnsec_t *)*cfg->total_xtrnsecs))
501
			==NULL)
502
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(xtrnsec_t *)*cfg->total_xtrnsecs);
503
	} else
504 505 506 507
		cfg->xtrnsec=NULL;

	for(i=0;i<cfg->total_xtrnsecs;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
508
		if((cfg->xtrnsec[i]=(xtrnsec_t *)malloc(sizeof(xtrnsec_t)))==NULL)
509
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(xtrnsec_t));
510 511
		memset(cfg->xtrnsec[i],0,sizeof(xtrnsec_t));

512
		get_str(cfg->xtrnsec[i]->name,instream);
513
		get_str(cfg->xtrnsec[i]->code,instream);
514
		get_str(cfg->xtrnsec[i]->arstr,instream);
515
		arstr(NULL, cfg->xtrnsec[i]->arstr, cfg, cfg->xtrnsec[i]->ar);
516

517 518
		for(j=0;j<8;j++)
			get_int(n,instream);
519
	}
520 521 522 523 524 525 526 527 528 529
	cfg->total_xtrnsecs=i;


	/*********************/
	/* External Programs */
	/*********************/

	get_int(cfg->total_xtrns,instream);

	if(cfg->total_xtrns) {
deuce's avatar
deuce committed
530
		if((cfg->xtrn=(xtrn_t **)malloc(sizeof(xtrn_t *)*cfg->total_xtrns))==NULL)
531
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(xtrn_t *)*cfg->total_xtrns);
532
	} else
533 534 535 536
		cfg->xtrn=NULL;

	for(i=0;i<cfg->total_xtrns;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
537
		if((cfg->xtrn[i]=(xtrn_t *)malloc(sizeof(xtrn_t)))==NULL)
538
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(xtrn_t));
539 540 541
		memset(cfg->xtrn[i],0,sizeof(xtrn_t));

		get_int(cfg->xtrn[i]->sec,instream);
542
		get_str(cfg->xtrn[i]->name,instream);
543
		get_str(cfg->xtrn[i]->code,instream);
544 545
		get_str(cfg->xtrn[i]->arstr,instream);
		get_str(cfg->xtrn[i]->run_arstr,instream);
546 547
		arstr(NULL, cfg->xtrn[i]->arstr, cfg, cfg->xtrn[i]->ar);
		arstr(NULL, cfg->xtrn[i]->run_arstr, cfg, cfg->xtrn[i]->run_ar);
548

549 550 551 552
		get_int(cfg->xtrn[i]->type,instream);
		get_int(cfg->xtrn[i]->misc,instream);
		get_int(cfg->xtrn[i]->event,instream);
		get_int(cfg->xtrn[i]->cost,instream);
553 554 555
		get_str(cfg->xtrn[i]->cmd,instream);
		get_str(cfg->xtrn[i]->clean,instream);
		get_str(cfg->xtrn[i]->path,instream);
556 557 558 559
		get_int(cfg->xtrn[i]->textra,instream);
		get_int(cfg->xtrn[i]->maxtime,instream);
		for(j=0;j<7;j++)
			get_int(n,instream);
560
	}
561 562 563 564 565 566 567 568 569 570
	cfg->total_xtrns=i;


	/****************/
	/* Timed Events */
	/****************/

	get_int(cfg->total_events,instream);

	if(cfg->total_events) {
deuce's avatar
deuce committed
571
		if((cfg->event=(event_t **)malloc(sizeof(event_t *)*cfg->total_events))==NULL)
572
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(event_t *)*cfg->total_events);
573
	} else
574 575 576 577
		cfg->event=NULL;

	for(i=0;i<cfg->total_events;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
578
		if((cfg->event[i]=(event_t *)malloc(sizeof(event_t)))==NULL)
579
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(event_t));
580 581 582
		memset(cfg->event[i],0,sizeof(event_t));

		get_str(cfg->event[i]->code,instream);
583
		get_str(cfg->event[i]->cmd,instream);
584 585 586 587
		get_int(cfg->event[i]->days,instream);
		get_int(cfg->event[i]->time,instream);
		get_int(cfg->event[i]->node,instream);
		get_int(cfg->event[i]->misc,instream);
588
		get_str(cfg->event[i]->dir,instream);
589
		get_int(cfg->event[i]->freq,instream);
590
		get_int(cfg->event[i]->mdays,instream);
591
		get_int(cfg->event[i]->months,instream);
592 593 594
		get_int(cfg->event[i]->errlevel,instream);
		get_int(c,instream);
		for(j=0;j<3;j++)
595
			get_int(n,instream);
rswindell's avatar
rswindell committed
596 597 598 599

		// You can't require exclusion *and* not specify which node/instance will execute the event
		if(cfg->event[i]->node == NODE_ANY)
			cfg->event[i]->misc &= ~EVENT_EXCL;
600 601
		if(cfg->event[i]->errlevel == 0)
			cfg->event[i]->errlevel = LOG_ERR;
602
	}
603 604
	cfg->total_events=i;

605 606 607
	/************************************/
	/* Native (not MS-DOS) Program list */
	/************************************/
608 609 610 611

	get_int(cfg->total_natvpgms,instream);

	if(cfg->total_natvpgms) {
deuce's avatar
deuce committed
612
		if((cfg->natvpgm=(natvpgm_t **)malloc(sizeof(natvpgm_t *)*cfg->total_natvpgms))==NULL)
613
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(natvpgm_t *)*cfg->total_natvpgms);
614
	} else
615 616 617 618
		cfg->natvpgm=NULL;

	for(i=0;i<cfg->total_natvpgms;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
619
		if((cfg->natvpgm[i]=(natvpgm_t *)malloc(sizeof(natvpgm_t)))==NULL)
620
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(natvpgm_t));
621
		get_str(cfg->natvpgm[i]->name,instream);
622 623
		cfg->natvpgm[i]->misc=0; 
	}
624 625 626
	cfg->total_natvpgms=i;
	for(i=0;i<cfg->total_natvpgms;i++) {
		if(feof(instream)) break;
627 628
		get_int(cfg->natvpgm[i]->misc,instream);
	}
629

630 631 632 633 634 635 636
	/*******************/
	/* Global Hot Keys */
	/*******************/

	get_int(cfg->total_hotkeys,instream);

	if(cfg->total_hotkeys) {
deuce's avatar
deuce committed
637
		if((cfg->hotkey=(hotkey_t **)malloc(sizeof(hotkey_t *)*cfg->total_hotkeys))==NULL)
638
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(hotkey_t *)*cfg->total_hotkeys);
639
	} else
640 641 642 643
		cfg->hotkey=NULL;

	for(i=0;i<cfg->total_hotkeys;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
644
		if((cfg->hotkey[i]=(hotkey_t *)malloc(sizeof(hotkey_t)))==NULL)
645
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(hotkey_t));
646 647 648 649 650 651 652
		memset(cfg->hotkey[i],0,sizeof(hotkey_t));

		get_int(cfg->hotkey[i]->key,instream);
		get_str(cfg->hotkey[i]->cmd,instream);

		for(j=0;j<8;j++)
			get_int(n,instream);
653
	}
654
	cfg->total_hotkeys=i;
655

656 657 658 659 660
	/************************************/
	/* External Program-related Toggles */
	/************************************/
	get_int(cfg->xtrn_misc,instream);

661 662 663 664 665 666 667
	fclose(instream);
	return(TRUE);
}

/****************************************************************************/
/* Reads in CHAT.CNF and initializes the associated variables				*/
/****************************************************************************/
668
BOOL read_chat_cfg(scfg_t* cfg, char* error, size_t maxerrlen)
669
{
670
	char	str[MAX_PATH+1];
deuce's avatar
64-bit  
deuce committed
671 672
	short	i,j;
	int16_t	n;
673 674 675
	long	offset=0;
	FILE	*instream;

676 677
	const char* fname = "chat.cnf";
	SAFEPRINTF2(str,"%s%s",cfg->ctrl_dir,fname);
678
	if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
679
		safe_snprintf(error, maxerrlen,"%d (%s) opening %s",errno,STRERROR(errno),str);
680 681
		return(FALSE);
	}
682 683 684 685 686 687 688 689

	/*********/
	/* Gurus */
	/*********/

	get_int(cfg->total_gurus,instream);

	if(cfg->total_gurus) {
deuce's avatar
deuce committed
690
		if((cfg->guru=(guru_t **)malloc(sizeof(guru_t *)*cfg->total_gurus))==NULL)
691
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(guru_t *)*cfg->total_gurus);
692
	} else
693 694 695 696
		cfg->guru=NULL;

	for(i=0;i<cfg->total_gurus;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
697
		if((cfg->guru[i]=(guru_t *)malloc(sizeof(guru_t)))==NULL)
698
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(guru_t));
699 700
		memset(cfg->guru[i],0,sizeof(guru_t));

701
		get_str(cfg->guru[i]->name,instream);
702
		get_str(cfg->guru[i]->code,instream);
703 704

		get_str(cfg->guru[i]->arstr,instream);
705
		arstr(NULL, cfg->guru[i]->arstr, cfg, cfg->guru[i]->ar);
706

707 708
		for(j=0;j<8;j++)
			get_int(n,instream);
709
	}
710 711 712 713 714 715 716 717 718 719
	cfg->total_chans=i;


	/********************/
	/* Chat Action Sets */
	/********************/

	get_int(cfg->total_actsets,instream);

	if(cfg->total_actsets) {
deuce's avatar
deuce committed
720
		if((cfg->actset=(actset_t **)malloc(sizeof(actset_t *)*cfg->total_actsets))==NULL)
721
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(actset_t *)*cfg->total_actsets);
722
	} else
723 724 725 726
		cfg->actset=NULL;

	for(i=0;i<cfg->total_actsets;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
727
		if((cfg->actset[i]=(actset_t *)malloc(sizeof(actset_t)))==NULL)
728
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(actset_t));
729
		get_str(cfg->actset[i]->name,instream);
730
	}
731 732 733 734 735 736 737 738 739 740
	cfg->total_actsets=i;


	/****************/
	/* Chat Actions */
	/****************/

	get_int(cfg->total_chatacts,instream);

	if(cfg->total_chatacts) {
deuce's avatar
deuce committed
741
		if((cfg->chatact=(chatact_t **)malloc(sizeof(chatact_t *)*cfg->total_chatacts))
742
			==NULL)
743
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(chatact_t *)*cfg->total_chatacts);
744
	} else
745 746 747 748
		cfg->chatact=NULL;

	for(i=0;i<cfg->total_chatacts;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
749
		if((cfg->chatact[i]=(chatact_t *)malloc(sizeof(chatact_t)))==NULL)
750
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(chatact_t));
751 752 753
		memset(cfg->chatact[i],0,sizeof(chatact_t));

		get_int(cfg->chatact[i]->actset,instream);
754 755
		get_str(cfg->chatact[i]->cmd,instream);
		get_str(cfg->chatact[i]->out,instream);
756 757
		for(j=0;j<8;j++)
			get_int(n,instream);
758
	}
759 760 761 762 763 764 765 766 767 768 769

	cfg->total_chatacts=i;


	/***************************/
	/* Multinode Chat Channels */
	/***************************/

	get_int(cfg->total_chans,instream);

	if(cfg->total_chans) {
deuce's avatar
deuce committed
770
		if((cfg->chan=(chan_t **)malloc(sizeof(chan_t *)*cfg->total_chans))==NULL)
771
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(chan_t *)*cfg->total_chans);
772
	} else
773 774 775 776
		cfg->chan=NULL;

	for(i=0;i<cfg->total_chans;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
777
		if((cfg->chan[i]=(chan_t *)malloc(sizeof(chan_t)))==NULL)
778
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(chan_t));
779 780 781
		memset(cfg->chan[i],0,sizeof(chan_t));

		get_int(cfg->chan[i]->actset,instream);
782
		get_str(cfg->chan[i]->name,instream);
783 784 785

		get_str(cfg->chan[i]->code,instream);

786
		get_str(cfg->chan[i]->arstr,instream);
787
		arstr(NULL, cfg->chan[i]->arstr, cfg, cfg->chan[i]->ar);
788

789 790 791 792
		get_int(cfg->chan[i]->cost,instream);
		get_int(cfg->chan[i]->guru,instream);
		get_int(cfg->chan[i]->misc,instream);
		for(j=0;j<8;j++)
793 794
			get_int(n,instream);
	}
795 796 797 798 799 800 801 802 803 804
	cfg->total_chans=i;


	/**************/
	/* Chat Pages */
	/**************/

	get_int(cfg->total_pages,instream);

	if(cfg->total_pages) {
deuce's avatar
deuce committed
805
		if((cfg->page=(page_t **)malloc(sizeof(page_t *)*cfg->total_pages))==NULL)
806
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(page_t *)*cfg->total_pages);
807
	} else
808 809 810 811
		cfg->page=NULL;

	for(i=0;i<cfg->total_pages;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
812
		if((cfg->page[i]=(page_t *)malloc(sizeof(page_t)))==NULL)
813
			return allocerr(instream, error, maxerrlen,offset,fname,sizeof(page_t));
814 815
		memset(cfg->page[i],0,sizeof(page_t));

816 817 818
		get_str(cfg->page[i]->cmd,instream);

		get_str(cfg->page[i]->arstr,instream);
rswindell's avatar