config.c
author viric@llimona
Fri, 16 Jun 2006 18:45:24 +0200
changeset 62 39bf7ecd7b21
parent 57 de776a4548da
permissions -rw-r--r--
IPV6_V6ONLY setsockopt added for the udp server.

#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>

#include "syslog.h"

#define CONFIG_FILE "syslog.conf"

/* Data structures */

static struct
{
	int n; /* Number of config elements */
	struct config_element el[ETYPE_END];
} main_config;

/* Aquesta variable ha de reflexar l'ordre de la enum etype_config de syslog.h*/
const static struct config_element default_config[ETYPE_END+1] = {
	{ FROM_UNIX, "unixlog" },
	{ FROM_NPIPE, "disabled" },
	{ FROM_UDP, "disabled" },
	{ TO_UDP_HOST, "localhost" },
	{ TO_UDP_PORT, "1235" },
	{ TCP_MANAGER, "1234" },
	{ LOG_FILE, "file.log" },
	{ PID_FILE, "syslog.pid" },
	{ ETYPE_END, "" }};

/* Aquesta variable ha de reflexar l'ordre de la enum etype_config de syslog.h*/
const static struct {
	enum etype_config type;
	char string[MAX_STRING];
} etype_string[ETYPE_END+1] = {
	{ FROM_UNIX, "from_unix" },
	{ FROM_NPIPE, "from_npipe" },
	{ FROM_UDP, "from_udp" },
	{ TO_UDP_HOST, "to_udp_host" },
	{ TO_UDP_PORT, "to_udp_port" },
	{ TCP_MANAGER, "tcp_manager" },
	{ LOG_FILE, "log_file" },
	{ PID_FILE, "pid_file" },
	{ ETYPE_END, "" }};

/* Prototypes */
static int add_config_element(const char * restrict p, const char * restrict v,
		const int max);
static void read_config(char * restrict fname);

/* Functions' code */

void init_config()
{
	main_config.n = 0;
	read_config(CONFIG_FILE);
}

static void read_config(char * restrict fname)
{
	int file;
	char rchar;
	int res;
	char parameter[MAX_STRING];
	int nparameter;
	char value[MAX_STRING];
	int nvalue;
	enum {
		READ_PARAMETER,
		READ_VALUE
	} state;

	file = open(fname, O_RDONLY);
	if (file == -1)
	{
		fprintf(stderr,"The config file cannot be opened.\n");
		return;
	}

	nparameter=0;
	state=READ_PARAMETER;
	while ((res = read(file, &rchar, 1)) == 1)
	{
		switch (rchar)
		{
		case '=':
			assert(nparameter <= MAX_STRING);
			parameter[nparameter]='\0';
			nvalue=0;
			state=READ_VALUE;
			break;
		case '\n':
			if (state == READ_VALUE)
			{
				value[nvalue]='\0';
				assert( add_config_element(parameter,
							value, MAX_STRING)>=0);
			}
			nparameter=0;
			nvalue=0;
			state=READ_PARAMETER;
			break;
		default:
			switch(state)
			{
			case READ_PARAMETER:
				assert(nparameter <= MAX_STRING);
				parameter[nparameter++]=rchar;
				break;
			case READ_VALUE:
				assert(nvalue <= MAX_STRING);
				value[nvalue++]=rchar;
				break;
			}
		}
	}

	if (res == -1)
	{
		fprintf(stderr, "Error reading config file: %s\n",
				strerror(errno));
	}

	close(file);
}

/* Retorna el tipus si ha pogut afegir l'element, -1 si hi ha hagut error */
static int add_config_element(const char * restrict p, const char * restrict v,
		const int max)
{
	enum etype_config i, type;
	int j, pos;
	int my_max;

	my_max = max;
	if (my_max > MAX_STRING)
		my_max = MAX_STRING;

	/* busquem de quin paràmetre es tracta */
	for(i=0; i<ETYPE_END; i++)
	{
		/* a etype_string corresponen índex amb tipus */
		
		if (strncmp(p,etype_string[i].string, my_max) == 0)
		{
			type=i;
			break;
		}
	}
	if (i==ETYPE_END)
	{
		/* Si el paràmetre no és conegut... */
		return -1;
	}

	/* Busquem si el paràmetre ja està a la configuració main_config */
	for (j=0; j<main_config.n; j++)
	{
		if(main_config.el[j].type == type)
		{
			pos = j;
			break;
		}
	}
	if(j == main_config.n)
	{
		pos = j;
		main_config.n++;
		/* At maximum, there should be ETYPE_END elements) */
		assert(main_config.n <= ETYPE_END);
	}

	main_config.el[pos].type = type;
	strncpy(main_config.el[pos].value, v, MAX_STRING);

	return type;
}

/* Returns 2 on configured type, 1 on default value, 0 on disabled,
 * -1 on error */
int get_config(const enum etype_config type, char * restrict v, const int max)
{
	int j;
	enum {
		DISABLED=0,
		DEFAULT=1,
		CONFIGURED=2,
		ERROR=-1
	} ret;

	if (type < 0 || type >= ETYPE_END)
		return ERROR;

	for (j=0; j<main_config.n; j++)
	{
		if(main_config.el[j].type == type)
		{
			strncpy(v, main_config.el[j].value, max);
			ret = CONFIGURED;
			break;
		}
	}

	if(j == main_config.n)
	{
		strncpy(v, default_config[type].value, max);
		ret = DEFAULT;
	}

	if(strncmp(v, "disabled", max) == 0)
		return DISABLED;
	else
		return ret;
}