/*
  config reader, partially from ifmail package
*/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "config.h"

node_t whoami;
char *inbound;
/* removed -- char *outbound; */
char *domains_file;
char *users_file;
char *areas_file;
/* char *default_desc; */
char *log_file;
char *lock_file;
char *desc_dir;
char *bad_dir;
char *help_file;
long wait_file;
int file_mode;
int log_file_mode;
int bad_dir_mode;
char *announce_exec;
char *newarea_exec;
char *response_exec;
int toss_badtic;
char *msg_from;
int make_hardlinks;
char *default_newfile;
int add_point_seenby;
int outbound_mode;
char *newarea_group;
char *areagroups_config;
char *basepath;
char *msg_to;
char *pub_path;
char *pub_url;

char *v,*k;
static int linecnt=0;

static void getstr(dest)
char **dest;
{
        *dest=xstrcpy(v);
}

static void getaddr(dest)
char **dest;
{
	int i;
	if ((i = ftntonode(((node_t*)dest),v,NULL)) != 0)
	{
		e_printf("(%d): \"%s\" is bad address [error %d]",linecnt,v,i);
		abort2();
	}
}

static void getlong(dest)
char **dest;
{
        *((long*)dest)=atol(v);
}

static void getoct(dest)
char **dest;
{
	sscanf(v,"%o",(int*)dest);
}

static void getyesno(dest)
char **dest;
{
/* ??? from ifmail        *dest=xstrcpy(v); */
        if( !strcasecmp( v, "yes" )) *((int*)dest) = 1;
        else if( !strcasecmp( v, "no" )) *((int*)dest) = 0;
        else
                e_printf("(%d): %s %s - bad value in config",
                        linecnt,k,v);
}

static struct _keytab {
	char *key;
        void (*prc)(char**);
        char** dest;
	int need; /* 0 - can be default, 1 - need value, after read from config 			set to 2 */
	char *_default;
} keytab[] = {

{"address",     getaddr,        (char**)&whoami,1,""},

{"inbound",     getstr,         &inbound,	1,""},
/* {"outbound",	getstr,		&outbound,	1,""}, */
{"domains_file",	getstr,		&domains_file,	1,""},
{"users_file",	getstr,		&users_file,	1,""},
{"areas_file",	getstr,		&areas_file,	1,""},
/* {"default_desc",getstr,		&default_desc,	0,"description missing"}, */
{"log_file",	getstr,		&log_file,	0,"/dev/null"},
{"lock_file",	getstr,		&lock_file,	0,"/tmp/gtic.lck"},
{"desc_dir",	getstr,		&desc_dir,	0,"."},
{"bad_dir",	getstr,		&bad_dir,	0,"/tmp/badtic"},
{"help_file",	getstr,		&help_file,	0,NULL},

{"wait_file",	getlong,	(char**)&wait_file,	0,"168"}, /* one week */

{"file_mode",	getoct,		(char**)&file_mode,	0,"644"},
{"log_file_mode",getoct,	(char**)&log_file_mode,	0,"600"},
{"bad_dir_mode",getoct,		(char**)&bad_dir_mode,	0,"755"},
{"outbound_mode",getoct,	(char**)&outbound_mode,	0,"644"},

{"newarea_exec",getstr,		&newarea_exec,		0,""},
{"announce_exec",getstr,	&announce_exec,		0,""},
{"response_exec",getstr,	&response_exec,		0,NULL},
{"toss_badtic",	getyesno,	(char**)&toss_badtic,	0,"yes"},
{"msg_from",	getstr,		&msg_from,		0,"root"},
{"make_hardlinks",getyesno,	(char**)&make_hardlinks,1,"yes"},
{"default_newfile",getstr,	&default_newfile,	0,"/dev/null"},
{"add_point_seenby",getyesno,	(char**)&add_point_seenby,0,"no"},
{"newarea_group",getstr,	&newarea_group,		0,""},
{"areagroups_config",getstr,	&areagroups_config,	0,NULL},
{"msg_to",	getstr,	&msg_to,	0,"root"},
{"basepath",getstr,	&basepath,	0,"/tmp"},
{"pub_url",	getstr,	&pub_url,	0,	NULL},
{"pub_path",	getstr,	&pub_path,	0,	NULL},

{NULL,		NULL,		NULL,			0,NULL}

};

void readconfig(char *configname)
{
	int i;
	FILE *fp;
	char buf[BUFSIZ],*p;

	if ((fp=fopen(configname,"r")) == NULL)
	{
		e_printf("readconfig: cannot open file \"%s\" ",
			configname);
		perror("");
		exit(1);
	}
	while (fgets(buf,sizeof(buf)-1,fp))
	{
		linecnt++;
		if (*(p=buf+strlen(buf)-1) != '\n')
		{
			e_printf("%s(%d): %s - line too long",
				configname,linecnt,buf);
			while (fgets(buf,sizeof(buf)-1,fp) &&
				(*(p=buf+strlen(buf)-1) != '\n'));
			continue;
		}

		*p--='\0';
		while ((p >= buf) && isspace(*p)) *p--='\0';
		k=buf;
		while (*k && isspace(*k)) k++;
		p=k;
		while (*p && !isspace(*p)) p++;
		*p++='\0';
		v=p;
		while (*v && isspace(*v)) v++;

		if ((*k == '\0') || (*k == '#'))
			continue;

		for (i=0;keytab[i].key;i++)
			if (strcasecmp(k,keytab[i].key) == 0) break;
		if (keytab[i].key == NULL)
		{
			e_printf("%s(%d): %s %s - unknown keyword",
				configname,linecnt,k,v);
		}
		else 
		{
			if(v)
				setenv(keytab[i].key,v,0);
		        keytab[i].prc(keytab[i].dest);
			keytab[i].need=2;
		}
	}
	fclose(fp);
	for(i=0;keytab[i].key;i++)
	{
		if(keytab[i].need==0)
		{
			v=keytab[i]._default;
			if(v)
				setenv(keytab[i].key,v,0);
		        keytab[i].prc(keytab[i].dest);
			keytab[i].need=2;
		}
	}
	for(i=0;keytab[i].key;i++)
	{
		if(keytab[i].need==1)
		{
			e_printf("%s: need keyword \"%s\"",
				configname,keytab[i].key);
			abort2();
		}
	}
	
}


syntax highlighted by Code2HTML, v. 0.9.1