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.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/* scfglib2.c */

/* Synchronet configuration library routines */

/* $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 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 37 38 39 40 41
 *																			*
 * 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.	*
 ****************************************************************************/

#include "sbbs.h"
#include "scfglib.h"

/****************************************************************************/
rswindell's avatar
rswindell committed
42
/* Reads in FILE.CNF and initializes the associated variables				*/
43
/****************************************************************************/
44
BOOL read_file_cfg(scfg_t* cfg, char* error)
45
{
46
	char	str[MAX_PATH+1],fname[13],c,cmd[LEN_CMD+1];
deuce's avatar
64-bit  
deuce committed
47 48 49 50
	short	i,j;
	int16_t	n;
	long	offset=0;
	int32_t	t;
51 52
	FILE	*instream;

53
	strcpy(fname,"file.cnf");
54
	sprintf(str,"%s%s",cfg->ctrl_dir,fname);
55
	if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
56
		sprintf(error,"%d (%s) opening %s",errno,STRERROR(errno),str);
57 58
		return(FALSE); 
	}
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

	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);
74
	get_int(cfg->file_misc,instream);
75

76
	for(i=0;i<30;i++)
77 78 79 80 81 82 83 84 85
		get_int(n,instream);

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

	get_int(cfg->total_fextrs,instream);

	if(cfg->total_fextrs) {
deuce's avatar
deuce committed
86
		if((cfg->fextr=(fextr_t **)malloc(sizeof(fextr_t *)*cfg->total_fextrs))==NULL)
87
			return allocerr(instream,error,offset,fname,sizeof(fextr_t*)*cfg->total_fextrs); 
88
	} else
89 90 91 92 93
		cfg->fextr=NULL;

	for(i=0; i<cfg->total_fextrs; i++) {
		if(feof(instream))
			break;
deuce's avatar
deuce committed
94
		if((cfg->fextr[i]=(fextr_t *)malloc(sizeof(fextr_t)))==NULL)
95
			return allocerr(instream,error,offset,fname,sizeof(fextr_t));
96 97
		memset(cfg->fextr[i],0,sizeof(fextr_t));
		get_str(cfg->fextr[i]->ext,instream);
98 99
		get_str(cfg->fextr[i]->cmd,instream);
		get_str(cfg->fextr[i]->arstr,instream);
100
		cfg->fextr[i]->ar=ARSTR(cfg->fextr[i]->arstr,cfg);
101

102 103
		for(j=0;j<8;j++)
			get_int(n,instream);
104
	}
105 106 107 108 109 110 111 112 113
	cfg->total_fextrs=i;

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

	get_int(cfg->total_fcomps,instream);

	if(cfg->total_fcomps) {
deuce's avatar
deuce committed
114
		if((cfg->fcomp=(fcomp_t **)malloc(sizeof(fcomp_t *)*cfg->total_fcomps))==NULL)
115
			return allocerr(instream,error,offset,fname,sizeof(fcomp_t*)*cfg->total_fcomps); 
116
	} else
117 118 119 120 121
		cfg->fcomp=NULL;

	for(i=0; i<cfg->total_fcomps; i++) {
		if(feof(instream))
			break;
deuce's avatar
deuce committed
122
		if((cfg->fcomp[i]=(fcomp_t *)malloc(sizeof(fcomp_t)))==NULL)
123
			return allocerr(instream,error,offset,fname,sizeof(fcomp_t));
124 125
		memset(cfg->fcomp[i],0,sizeof(fcomp_t));
		get_str(cfg->fcomp[i]->ext,instream);
126 127
		get_str(cfg->fcomp[i]->cmd,instream);
		get_str(cfg->fcomp[i]->arstr,instream);
128
		cfg->fcomp[i]->ar=ARSTR(cfg->fcomp[i]->arstr,cfg);
129

130 131
		for(j=0;j<8;j++)
			get_int(n,instream);
132
	}
133 134 135 136 137 138 139 140 141
	cfg->total_fcomps=i;

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

	get_int(cfg->total_fviews,instream);

	if(cfg->total_fviews) {
deuce's avatar
deuce committed
142
		if((cfg->fview=(fview_t **)malloc(sizeof(fview_t *)*cfg->total_fviews))==NULL)
143
			return allocerr(instream,error,offset,fname,sizeof(fview_t*)*cfg->total_fviews); 
144
	} else
145 146 147 148
		cfg->fview=NULL;

	for(i=0; i<cfg->total_fviews; i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
149
		if((cfg->fview[i]=(fview_t *)malloc(sizeof(fview_t)))==NULL)
150
			return allocerr(instream,error,offset,fname,sizeof(fview_t));
151 152
		memset(cfg->fview[i],0,sizeof(fview_t));
		get_str(cfg->fview[i]->ext,instream);
153 154
		get_str(cfg->fview[i]->cmd,instream);
		get_str(cfg->fview[i]->arstr,instream);
155
		cfg->fview[i]->ar=ARSTR(cfg->fview[i]->arstr,cfg);
156

157 158
		for(j=0;j<8;j++)
			get_int(n,instream);
159
	}
160 161 162 163 164 165 166 167 168
	cfg->total_fviews=i;

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

	get_int(cfg->total_ftests,instream);

	if(cfg->total_ftests) {
deuce's avatar
deuce committed
169
		if((cfg->ftest=(ftest_t **)malloc(sizeof(ftest_t *)*cfg->total_ftests))==NULL)
170
			return allocerr(instream,error,offset,fname,sizeof(ftest_t*)*cfg->total_ftests); 
171
	} else
172 173 174 175
		cfg->ftest=NULL;

	for(i=0; i<cfg->total_ftests; i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
176
		if((cfg->ftest[i]=(ftest_t *)malloc(sizeof(ftest_t)))==NULL)
177
			return allocerr(instream,error,offset,fname,sizeof(ftest_t));
178 179
		memset(cfg->ftest[i],0,sizeof(ftest_t));
		get_str(cfg->ftest[i]->ext,instream);
180 181 182
		get_str(cfg->ftest[i]->cmd,instream);
		get_str(cfg->ftest[i]->workstr,instream);
		get_str(cfg->ftest[i]->arstr,instream);
183
		cfg->ftest[i]->ar=ARSTR(cfg->ftest[i]->arstr,cfg);
184

185 186
		for(j=0;j<8;j++)
			get_int(n,instream);
187
	}
188 189 190 191 192 193 194 195 196
	cfg->total_ftests=i;

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

	get_int(cfg->total_dlevents,instream);

	if(cfg->total_dlevents) {
deuce's avatar
deuce committed
197
		if((cfg->dlevent=(dlevent_t **)malloc(sizeof(dlevent_t *)*cfg->total_dlevents))
198
			==NULL)
199
			return allocerr(instream,error,offset,fname,sizeof(dlevent_t*)*cfg->total_dlevents); 
200
	} else
201 202 203 204
		cfg->dlevent=NULL;

	for(i=0; i<cfg->total_dlevents; i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
205
		if((cfg->dlevent[i]=(dlevent_t *)malloc(sizeof(dlevent_t)))==NULL)
206
			return allocerr(instream,error,offset,fname,sizeof(dlevent_t));
207 208
		memset(cfg->dlevent[i],0,sizeof(dlevent_t));
		get_str(cfg->dlevent[i]->ext,instream);
209 210 211
		get_str(cfg->dlevent[i]->cmd,instream);
		get_str(cfg->dlevent[i]->workstr,instream);
		get_str(cfg->dlevent[i]->arstr,instream);
212
		cfg->dlevent[i]->ar=ARSTR(cfg->dlevent[i]->arstr,cfg);
213

214 215
		for(j=0;j<8;j++)
			get_int(n,instream);
216
	}
217 218 219 220 221 222 223 224 225 226
	cfg->total_dlevents=i;


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

	get_int(cfg->total_prots,instream);

	if(cfg->total_prots) {
deuce's avatar
deuce committed
227
		if((cfg->prot=(prot_t **)malloc(sizeof(prot_t *)*cfg->total_prots))==NULL)
228
			return allocerr(instream,error,offset,fname,sizeof(prot_t*)*cfg->total_prots); 
229
	} else
230 231 232 233
		cfg->prot=NULL;

	for(i=0;i<cfg->total_prots;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
234
		if((cfg->prot[i]=(prot_t *)malloc(sizeof(prot_t)))==NULL)
235
			return allocerr(instream,error,offset,fname,sizeof(prot_t));
236 237 238
		memset(cfg->prot[i],0,sizeof(prot_t));

		get_int(cfg->prot[i]->mnemonic,instream);
239 240 241 242 243 244 245
		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);
246
		get_int(cfg->prot[i]->misc,instream);
247
		get_str(cfg->prot[i]->arstr,instream);
248
		cfg->prot[i]->ar=ARSTR(cfg->prot[i]->arstr,cfg);
249

250 251
		for(j=0;j<8;j++)
			get_int(n,instream);
252
	}
253
	cfg->total_prots=i;
254 255 256 257 258 259 260 261

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

	get_int(cfg->altpaths,instream);

	if(cfg->altpaths) {
deuce's avatar
deuce committed
262
		if((cfg->altpath=(char **)malloc(sizeof(char *)*cfg->altpaths))==NULL)
263
			return allocerr(instream,error,offset,fname,sizeof(char *)*cfg->altpaths); 
264
	} else
265 266 267 268 269
		cfg->altpath=NULL;

	for(i=0;i<cfg->altpaths;i++) {
		if(feof(instream)) break;
		fread(str,LEN_DIR+1,1,instream);
270
		str[LEN_DIR] = 0;
271 272 273
		offset+=LEN_DIR+1;
		backslash(str);
		j=LEN_DIR+1;
deuce's avatar
deuce committed
274
		if((cfg->altpath[i]=(char *)malloc(j))==NULL)
275
			return allocerr(instream,error,offset,fname,j);
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
		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
291
		if((cfg->lib=(lib_t **)malloc(sizeof(lib_t *)*cfg->total_libs))==NULL)
292
			return allocerr(instream,error,offset,fname,sizeof(lib_t *)*cfg->total_libs);
293
	} else
294 295 296 297
		cfg->lib=NULL;

	for(i=0;i<cfg->total_libs;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
298
		if((cfg->lib[i]=(lib_t *)malloc(sizeof(lib_t)))==NULL)
299
			return allocerr(instream,error,offset,fname,sizeof(lib_t));
300 301 302
		memset(cfg->lib[i],0,sizeof(lib_t));
		cfg->lib[i]->offline_dir=INVALID_DIR;

303 304 305 306
		get_str(cfg->lib[i]->lname,instream);
		get_str(cfg->lib[i]->sname,instream);

		get_str(cfg->lib[i]->arstr,instream);
307
		cfg->lib[i]->ar=ARSTR(cfg->lib[i]->arstr,cfg);
308

309 310
		get_str(cfg->lib[i]->parent_path,instream);

311 312 313
		get_str(cfg->lib[i]->code_prefix,instream);

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

316 317 318
		get_int(cfg->lib[i]->misc, instream);
		
		for(j=0;j<1;j++)
319
			get_int(n,instream);	/* 0x0000 */
320 321 322

		for(j=0;j<16;j++)
			get_int(n,instream);	/* 0xffff */
323
	}
324 325 326 327 328 329 330 331 332 333
	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
334
		if((cfg->dir=(dir_t **)malloc(sizeof(dir_t *)*(cfg->total_dirs+1)))==NULL)
335
			return allocerr(instream,error,offset,fname,sizeof(dir_t *)*(cfg->total_dirs+1));
336
	} else
337 338 339 340
		cfg->dir=NULL;

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

345 346
		cfg->dir[i]->dirnum = i;

347
		get_int(cfg->dir[i]->lib,instream);
348 349
		get_str(cfg->dir[i]->lname,instream);
		get_str(cfg->dir[i]->sname,instream);
350

351
		if(!stricmp(cfg->dir[i]->sname,"SYSOP"))			/* Sysop upload directory */
352
			cfg->sysop_dir=i;
353
		else if(!stricmp(cfg->dir[i]->sname,"USER"))		/* User to User xfer dir */
354
			cfg->user_dir=i;
355
		else if(!stricmp(cfg->dir[i]->sname,"UPLOADS"))  /* Upload directory */
356
			cfg->upload_dir=i;
357
		else if(!stricmp(cfg->dir[i]->sname,"OFFLINE"))	/* Offline files dir */
358 359
			cfg->lib[cfg->dir[i]->lib]->offline_dir=i;

360
		get_str(cfg->dir[i]->code_suffix,instream);
361 362

		get_str(cfg->dir[i]->data_dir,instream);
363 364 365 366 367 368

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

369 370 371 372
		cfg->dir[i]->ar=ARSTR(cfg->dir[i]->arstr,cfg);
		cfg->dir[i]->ul_ar=ARSTR(cfg->dir[i]->ul_arstr,cfg);
		cfg->dir[i]->dl_ar=ARSTR(cfg->dir[i]->dl_arstr,cfg);
		cfg->dir[i]->op_ar=ARSTR(cfg->dir[i]->op_arstr,cfg);
373 374 375 376 377

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

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

378 379 380
		get_int(cfg->dir[i]->maxfiles,instream);
		if(cfg->dir[i]->maxfiles>MAX_FILES)
			cfg->dir[i]->maxfiles=MAX_FILES;
381
		get_str(cfg->dir[i]->exts,instream);
382 383 384
		get_int(cfg->dir[i]->misc,instream);
		get_int(cfg->dir[i]->seqdev,instream);
		get_int(cfg->dir[i]->sort,instream);
385
		get_str(cfg->dir[i]->ex_arstr,instream);
386
		cfg->dir[i]->ex_ar=ARSTR(cfg->dir[i]->ex_arstr,cfg);
387

388 389 390 391 392
		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++)
393 394
			get_int(n,instream); 
	}
395 396 397 398 399 400 401 402 403 404 405

	cfg->total_dirs=i;

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

	get_int(cfg->total_txtsecs,instream);


	if(cfg->total_txtsecs) {
deuce's avatar
deuce committed
406
		if((cfg->txtsec=(txtsec_t **)malloc(sizeof(txtsec_t *)*cfg->total_txtsecs))==NULL)
407
			return allocerr(instream,error,offset,fname,sizeof(txtsec_t *)*cfg->total_txtsecs); 
408
	} else
409 410 411 412
		cfg->txtsec=NULL;

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

417
		get_str(cfg->txtsec[i]->name,instream);
418
		get_str(cfg->txtsec[i]->code,instream);
419
		get_str(cfg->txtsec[i]->arstr,instream);
420
		cfg->txtsec[i]->ar=ARSTR(cfg->txtsec[i]->arstr,cfg);
421

422 423
		for(j=0;j<8;j++)
			get_int(n,instream);
424
	}
425 426 427
	cfg->total_txtsecs=i;

	fclose(instream);
428
	return(TRUE);
429 430 431 432 433
}

/****************************************************************************/
/* Reads in XTRN.CNF and initializes the associated variables				*/
/****************************************************************************/
434
BOOL read_xtrn_cfg(scfg_t* cfg, char* error)
435
{
436
	char	str[MAX_PATH+1],fname[13],c;
deuce's avatar
64-bit  
deuce committed
437 438
	short	i,j;
	int16_t	n;
439 440 441
	long	offset=0;
	FILE	*instream;

442
	strcpy(fname,"xtrn.cnf");
443
	sprintf(str,"%s%s",cfg->ctrl_dir,fname);
444
	if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
445
		sprintf(error,"%d (%s) opening %s",errno,STRERROR(errno),str);
446 447
		return(FALSE); 
	}
448 449 450 451 452 453 454 455

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

	get_int(cfg->total_swaps,instream);

	if(cfg->total_swaps) {
deuce's avatar
deuce committed
456
		if((cfg->swap=(swap_t **)malloc(sizeof(swap_t *)*cfg->total_swaps))==NULL)
457
			return allocerr(instream,error,offset,fname,sizeof(swap_t *)*cfg->total_swaps); 
458
	} else
459 460 461 462
		cfg->swap=NULL;

	for(i=0;i<cfg->total_swaps;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
463
		if((cfg->swap[i]=(swap_t *)malloc(sizeof(swap_t)))==NULL)
464
			return allocerr(instream,error,offset,fname,sizeof(swap_t));
465 466
		get_str(cfg->swap[i]->cmd,instream); 
	}
467 468 469 470 471 472 473 474 475
	cfg->total_swaps=i;

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

	get_int(cfg->total_xedits,instream);

	if(cfg->total_xedits) {
deuce's avatar
deuce committed
476
		if((cfg->xedit=(xedit_t **)malloc(sizeof(xedit_t *)*cfg->total_xedits))==NULL)
477
			return allocerr(instream,error,offset,fname,sizeof(xedit_t *)*cfg->total_xedits); 
478
	} else
479 480 481 482
		cfg->xedit=NULL;

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

487
		get_str(cfg->xedit[i]->name,instream);
488
		get_str(cfg->xedit[i]->code,instream);
489 490
		get_str(cfg->xedit[i]->lcmd,instream);
		get_str(cfg->xedit[i]->rcmd,instream);
491 492

		get_int(cfg->xedit[i]->misc,instream);
493
		get_str(cfg->xedit[i]->arstr,instream);
494
		cfg->xedit[i]->ar=ARSTR(cfg->xedit[i]->arstr,cfg);
495

496 497
		get_int(cfg->xedit[i]->type,instream);
		get_int(c,instream);
498 499 500
		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;
501 502
		get_int(cfg->xedit[i]->quotewrap_cols, instream);
		for(j=0;j<6;j++)
503
			get_int(n,instream);
504
	}
505 506 507 508 509 510 511 512 513 514
	cfg->total_xedits=i;


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

	get_int(cfg->total_xtrnsecs,instream);

	if(cfg->total_xtrnsecs) {
deuce's avatar
deuce committed
515
		if((cfg->xtrnsec=(xtrnsec_t **)malloc(sizeof(xtrnsec_t *)*cfg->total_xtrnsecs))
516
			==NULL)
517
			return allocerr(instream,error,offset,fname,sizeof(xtrnsec_t *)*cfg->total_xtrnsecs);
518
	} else
519 520 521 522
		cfg->xtrnsec=NULL;

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

527
		get_str(cfg->xtrnsec[i]->name,instream);
528
		get_str(cfg->xtrnsec[i]->code,instream);
529
		get_str(cfg->xtrnsec[i]->arstr,instream);
530
		cfg->xtrnsec[i]->ar=ARSTR(cfg->xtrnsec[i]->arstr,cfg);
531

532 533
		for(j=0;j<8;j++)
			get_int(n,instream);
534
	}
535 536 537 538 539 540 541 542 543 544
	cfg->total_xtrnsecs=i;


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

	get_int(cfg->total_xtrns,instream);

	if(cfg->total_xtrns) {
deuce's avatar
deuce committed
545
		if((cfg->xtrn=(xtrn_t **)malloc(sizeof(xtrn_t *)*cfg->total_xtrns))==NULL)
546
			return allocerr(instream,error,offset,fname,sizeof(xtrn_t *)*cfg->total_xtrns);
547
	} else
548 549 550 551
		cfg->xtrn=NULL;

	for(i=0;i<cfg->total_xtrns;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
552
		if((cfg->xtrn[i]=(xtrn_t *)malloc(sizeof(xtrn_t)))==NULL)
553
			return allocerr(instream,error,offset,fname,sizeof(xtrn_t));
554 555 556
		memset(cfg->xtrn[i],0,sizeof(xtrn_t));

		get_int(cfg->xtrn[i]->sec,instream);
557
		get_str(cfg->xtrn[i]->name,instream);
558
		get_str(cfg->xtrn[i]->code,instream);
559 560
		get_str(cfg->xtrn[i]->arstr,instream);
		get_str(cfg->xtrn[i]->run_arstr,instream);
561 562
		cfg->xtrn[i]->ar=ARSTR(cfg->xtrn[i]->arstr,cfg);
		cfg->xtrn[i]->run_ar=ARSTR(cfg->xtrn[i]->run_arstr,cfg);
563

564 565 566 567
		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);
568 569 570
		get_str(cfg->xtrn[i]->cmd,instream);
		get_str(cfg->xtrn[i]->clean,instream);
		get_str(cfg->xtrn[i]->path,instream);
571 572 573 574
		get_int(cfg->xtrn[i]->textra,instream);
		get_int(cfg->xtrn[i]->maxtime,instream);
		for(j=0;j<7;j++)
			get_int(n,instream);
575
	}
576 577 578 579 580 581 582 583 584 585
	cfg->total_xtrns=i;


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

	get_int(cfg->total_events,instream);

	if(cfg->total_events) {
deuce's avatar
deuce committed
586
		if((cfg->event=(event_t **)malloc(sizeof(event_t *)*cfg->total_events))==NULL)
587
			return allocerr(instream,error,offset,fname,sizeof(event_t *)*cfg->total_events);
588
	} else
589 590 591 592
		cfg->event=NULL;

	for(i=0;i<cfg->total_events;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
593
		if((cfg->event[i]=(event_t *)malloc(sizeof(event_t)))==NULL)
594
			return allocerr(instream,error,offset,fname,sizeof(event_t));
595 596 597
		memset(cfg->event[i],0,sizeof(event_t));

		get_str(cfg->event[i]->code,instream);
598
		get_str(cfg->event[i]->cmd,instream);
599 600 601 602
		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);
603
		get_str(cfg->event[i]->dir,instream);
604
		get_int(cfg->event[i]->freq,instream);
605
		get_int(cfg->event[i]->mdays,instream);
606
		get_int(cfg->event[i]->months,instream);
607

608
		for(j=0;j<4;j++)
609
			get_int(n,instream);
610
	}
611 612 613 614 615 616 617 618 619
	cfg->total_events=i;

	/********************************/
	/* Native (32-bit) Program list */
	/********************************/

	get_int(cfg->total_natvpgms,instream);

	if(cfg->total_natvpgms) {
deuce's avatar
deuce committed
620
		if((cfg->natvpgm=(natvpgm_t **)malloc(sizeof(natvpgm_t *)*cfg->total_natvpgms))==NULL)
621
			return allocerr(instream,error,offset,fname,sizeof(natvpgm_t *)*cfg->total_natvpgms);
622
	} else
623 624 625 626
		cfg->natvpgm=NULL;

	for(i=0;i<cfg->total_natvpgms;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
627
		if((cfg->natvpgm[i]=(natvpgm_t *)malloc(sizeof(natvpgm_t)))==NULL)
628
			return allocerr(instream,error,offset,fname,sizeof(natvpgm_t));
629
		get_str(cfg->natvpgm[i]->name,instream);
630 631
		cfg->natvpgm[i]->misc=0; 
	}
632 633 634
	cfg->total_natvpgms=i;
	for(i=0;i<cfg->total_natvpgms;i++) {
		if(feof(instream)) break;
635 636
		get_int(cfg->natvpgm[i]->misc,instream);
	}
637

638 639 640 641 642 643 644
	/*******************/
	/* Global Hot Keys */
	/*******************/

	get_int(cfg->total_hotkeys,instream);

	if(cfg->total_hotkeys) {
deuce's avatar
deuce committed
645
		if((cfg->hotkey=(hotkey_t **)malloc(sizeof(hotkey_t *)*cfg->total_hotkeys))==NULL)
646
			return allocerr(instream,error,offset,fname,sizeof(hotkey_t *)*cfg->total_hotkeys);
647
	} else
648 649 650 651
		cfg->hotkey=NULL;

	for(i=0;i<cfg->total_hotkeys;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
652
		if((cfg->hotkey[i]=(hotkey_t *)malloc(sizeof(hotkey_t)))==NULL)
653
			return allocerr(instream,error,offset,fname,sizeof(hotkey_t));
654 655 656 657 658 659 660
		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);
661
	}
662
	cfg->total_hotkeys=i;
663

664 665 666 667 668
	/************************************/
	/* External Program-related Toggles */
	/************************************/
	get_int(cfg->xtrn_misc,instream);

669 670 671 672 673 674 675
	fclose(instream);
	return(TRUE);
}

/****************************************************************************/
/* Reads in CHAT.CNF and initializes the associated variables				*/
/****************************************************************************/
676
BOOL read_chat_cfg(scfg_t* cfg, char* error)
677
{
678
	char	str[MAX_PATH+1],fname[13];
deuce's avatar
64-bit  
deuce committed
679 680
	short	i,j;
	int16_t	n;
681 682 683
	long	offset=0;
	FILE	*instream;

684
	strcpy(fname,"chat.cnf");
685
	sprintf(str,"%s%s",cfg->ctrl_dir,fname);
686
	if((instream=fnopen(NULL,str,O_RDONLY))==NULL) {
687
		sprintf(error,"%d (%s) opening %s",errno,STRERROR(errno),str);
688 689
		return(FALSE);
	}
690 691 692 693 694 695 696 697

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

	get_int(cfg->total_gurus,instream);

	if(cfg->total_gurus) {
deuce's avatar
deuce committed
698
		if((cfg->guru=(guru_t **)malloc(sizeof(guru_t *)*cfg->total_gurus))==NULL)
699
			return allocerr(instream,error,offset,fname,sizeof(guru_t *)*cfg->total_gurus);
700
	} else
701 702 703 704
		cfg->guru=NULL;

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

709
		get_str(cfg->guru[i]->name,instream);
710
		get_str(cfg->guru[i]->code,instream);
711 712

		get_str(cfg->guru[i]->arstr,instream);
713
		cfg->guru[i]->ar=ARSTR(cfg->guru[i]->arstr,cfg);
714

715 716
		for(j=0;j<8;j++)
			get_int(n,instream);
717
	}
718 719 720 721 722 723 724 725 726 727
	cfg->total_chans=i;


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

	get_int(cfg->total_actsets,instream);

	if(cfg->total_actsets) {
deuce's avatar
deuce committed
728
		if((cfg->actset=(actset_t **)malloc(sizeof(actset_t *)*cfg->total_actsets))==NULL)
729
			return allocerr(instream,error,offset,fname,sizeof(actset_t *)*cfg->total_actsets);
730
	} else
731 732 733 734
		cfg->actset=NULL;

	for(i=0;i<cfg->total_actsets;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
735
		if((cfg->actset[i]=(actset_t *)malloc(sizeof(actset_t)))==NULL)
736
			return allocerr(instream,error,offset,fname,sizeof(actset_t));
737
		get_str(cfg->actset[i]->name,instream);
738
	}
739 740 741 742 743 744 745 746 747 748
	cfg->total_actsets=i;


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

	get_int(cfg->total_chatacts,instream);

	if(cfg->total_chatacts) {
deuce's avatar
deuce committed
749
		if((cfg->chatact=(chatact_t **)malloc(sizeof(chatact_t *)*cfg->total_chatacts))
750
			==NULL)
751
			return allocerr(instream,error,offset,fname,sizeof(chatact_t *)*cfg->total_chatacts);
752
	} else
753 754 755 756
		cfg->chatact=NULL;

	for(i=0;i<cfg->total_chatacts;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
757
		if((cfg->chatact[i]=(chatact_t *)malloc(sizeof(chatact_t)))==NULL)
758
			return allocerr(instream,error,offset,fname,sizeof(chatact_t));
759 760 761
		memset(cfg->chatact[i],0,sizeof(chatact_t));

		get_int(cfg->chatact[i]->actset,instream);
762 763
		get_str(cfg->chatact[i]->cmd,instream);
		get_str(cfg->chatact[i]->out,instream);
764 765
		for(j=0;j<8;j++)
			get_int(n,instream);
766
	}
767 768 769 770 771 772 773 774 775 776 777

	cfg->total_chatacts=i;


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

	get_int(cfg->total_chans,instream);

	if(cfg->total_chans) {
deuce's avatar
deuce committed
778
		if((cfg->chan=(chan_t **)malloc(sizeof(chan_t *)*cfg->total_chans))==NULL)
779
			return allocerr(instream,error,offset,fname,sizeof(chan_t *)*cfg->total_chans);
780
	} else
781 782 783 784
		cfg->chan=NULL;

	for(i=0;i<cfg->total_chans;i++) {
		if(feof(instream)) break;
deuce's avatar
deuce committed
785
		if((cfg->chan[i]=(chan_t *)malloc(sizeof(chan_t)))==NULL)
786
			return allocerr(instream,error,offset,fname,sizeof(chan_t));
787 788 789
		memset(cfg->chan[i],0,sizeof(chan_t));

		get_int(cfg->chan[i]->actset,instream);
790
		get_str(cfg->chan[i]->name,instream);
791 792 793

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

794
		get_str(cfg->chan[i]->arstr,instream);
795
		cfg->chan[i]->ar=ARSTR(cfg->chan[i]->arstr,cfg);
796

797 798 799 800
		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++)
801 802
			get_int(n,instream);
	}
803 804 805 806 807 808 809 810 811 812
	cfg->total_chans=i;


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

	get_int(cfg->total_pages,instream);

	if(cfg->total_pages) {
deuce's avatar
deuce committed
813
		if((cfg->page=(page_t **)malloc(sizeof(page_t *)*cfg->total_pages))==NULL)
814
			return allocerr(instream,error,offset,fname,sizeof(page_t *)*cfg->total_pages);
815
	} else
816 817 818 819
		cfg->page=NULL;

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

824 825 826
		get_str(cfg->page[i]->cmd,instream);

		get_str(cfg->page[i]->arstr,instream);
827
		cfg->page[i]->ar=ARSTR(cfg->page[i]->arstr,cfg);
828