The open() is done without mode_t mode.
#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" },
{ 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" },
{ 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;
}