Config load fixes.

- Leaks
- Better logging
- Handle historical configs
This commit is contained in:
Arnaud Cornet 2007-10-21 12:31:07 +02:00
parent 32e47b900c
commit 0abd8a386d
6 changed files with 125 additions and 103 deletions

195
src/bip.c
View File

@ -48,14 +48,15 @@ int conf_log = DEFAULT_LOG;
int conf_log_system = DEFAULT_LOG_SYSTEM;
int conf_log_sync_interval = DEFAULT_LOG_SYNC_INTERVAL;
list_t *parse_conf(FILE *file);
list_t *parse_conf(FILE *file, int *err);
static void conf_die(char *fmt, ...);
#ifdef HAVE_LIBSSL
int adm_trust(struct link_client *ic, struct line *line);
#endif
static char *get_tuple_value(list_t *tuple_l, int lex);
static char *get_tuple_pvalue(list_t *tuple_l, int lex);
void adm_reply(struct link_client *ic, char *str);
void adm_list_connections(struct link_client *ic, struct user *bu);
void free_conf(list_t *l);
static void hash_binary(char *hex, unsigned char **password, unsigned int *seed)
{
@ -94,7 +95,7 @@ static int add_server(struct server *s, list_t *data)
while ((t = list_remove_first(data))) {
switch (t->type) {
case LEX_HOST:
s->host = t->pdata;
MOVE_STRING(s->host, t->pdata);
break;
case LEX_PORT:
s->port = t->ndata;
@ -102,6 +103,9 @@ static int add_server(struct server *s, list_t *data)
default:
fatal("Config error in server block (%d)", t->type);
}
if (t->tuple_type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
if (!s->host) {
free(s);
@ -115,23 +119,12 @@ static int add_server(struct server *s, list_t *data)
extern list_t *root_list;
int yyparse();
int conf_error;
char conf_errstr[ERRBUFSZ];
static void conf_start(void)
{
conf_error = 0;
}
static void conf_die(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(conf_errstr, ERRBUFSZ, fmt, ap);
conf_errstr[ERRBUFSZ - 1] = 0;
conf_error = 1;
_mylog(LOG_ERROR, fmt, ap);
va_end(ap);
}
@ -305,8 +298,9 @@ static int add_network(bip_t *bip, list_t *data)
struct tuple *t;
struct network *n;
int i;
int r;
char *name = get_tuple_value(data, LEX_NAME);
char *name = get_tuple_pvalue(data, LEX_NAME);
if (name == NULL) {
conf_die("Network with no name");
@ -338,17 +332,22 @@ static int add_network(bip_t *bip, list_t *data)
n->serverv = realloc(n->serverv, (n->serverc + 1)
* sizeof(struct server));
n->serverc++;
add_server(&n->serverv[n->serverc - 1], t->pdata);
memset(&n->serverv[n->serverc - 1], 0,
sizeof(struct server));
r = add_server(&n->serverv[n->serverc - 1], t->pdata);
if (!r) {
n->serverc--;
return 0;
}
free(t->pdata);
t->pdata = NULL;
break;
default:
conf_die("unknown keyword in network statement");
if (t->type == TUPLE_STR)
free(t->pdata);
return 0;
break;
}
if (t->type == TUPLE_STR && t->pdata)
if (t->tuple_type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
@ -360,7 +359,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
struct tuple *t, *t2;
struct link *l;
struct chan_info *ci;
char *name = get_tuple_value(data, LEX_NAME);
char *name = get_tuple_pvalue(data, LEX_NAME);
if (name == NULL) {
conf_die("Connection with no name");
@ -414,7 +413,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
MOVE_STRING(l->vhost, t->pdata);
break;
case LEX_CHANNEL:
name = get_tuple_value(t->pdata, LEX_NAME);
name = get_tuple_pvalue(t->pdata, LEX_NAME);
if (name == NULL) {
conf_die("Channel with no name");
return 0;
@ -441,6 +440,9 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
ci->backlog = t2->ndata;
break;
}
if (t2->tuple_type == TUPLE_STR && t2->pdata)
free(t2->pdata);
free(t2);
}
list_free(t->pdata);
break;
@ -458,6 +460,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
break;
case LEX_ON_CONNECT_SEND:
list_add_last(&l->on_connect_send, t->pdata);
t->pdata = NULL;
break;
#ifdef HAVE_LIBSSL
case LEX_SSL_CHECK_MODE:
@ -470,10 +473,9 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
#endif
default:
conf_die("unknown keyword in connection statement");
if (t->type == TUPLE_STR)
free(t->pdata);
return 0;
}
if (t->type == TUPLE_STR && t->pdata)
if (t->tuple_type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
@ -498,7 +500,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
return 1;
}
static char *get_tuple_value(list_t *tuple_l, int lex)
static char *get_tuple_pvalue(list_t *tuple_l, int lex)
{
struct tuple *t;
list_iterator_t it;
@ -511,13 +513,35 @@ static char *get_tuple_value(list_t *tuple_l, int lex)
return NULL;
}
static int add_user(bip_t *bip, list_t *data)
static int get_tuple_nvalue(list_t *tuple_l, int lex)
{
struct tuple *t;
list_iterator_t it;
for (list_it_init(tuple_l, &it); (t = list_it_item(&it));
list_it_next(&it)) {
if (t->type == lex)
return t->ndata;
}
return -1;
}
struct historical_directives {
int always_backlog;
int backlog;
int bl_msg_only;
int backlog_lines;
int backlog_no_timestamp;
int blreset_on_talk;
};
static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
{
int r;
struct tuple *t;
struct user *u;
char *name = get_tuple_value(data, LEX_NAME);
char *name = get_tuple_pvalue(data, LEX_NAME);
if (name == NULL) {
conf_die("User with no name");
@ -529,12 +553,6 @@ static int add_user(bip_t *bip, list_t *data)
hash_insert(&bip->users, name, u);
hash_init(&u->connections, HASH_NOCASE);
u->admin = 0;
u->backlog = DEFAULT_BACKLOG;
u->always_backlog = DEFAULT_ALWAYS_BACKLOG;
u->bl_msg_only = DEFAULT_BL_MSG_ONLY;
u->backlog_lines = DEFAULT_BACKLOG_LINES;
u->backlog_no_timestamp = DEFAULT_BACKLOG_NO_TIMESTAMP;
u->blreset_on_talk = DEFAULT_BLRESET_ON_TALK;
} else {
FREE(u->name);
FREE(u->password);
@ -546,6 +564,13 @@ static int add_user(bip_t *bip, list_t *data)
#endif
}
u->backlog = hds->backlog;
u->always_backlog = hds->always_backlog;
u->bl_msg_only = hds->bl_msg_only;
u->backlog_lines = hds->backlog_lines;
u->backlog_no_timestamp = hds->backlog_no_timestamp;
u->blreset_on_talk = hds->blreset_on_talk;
while ((t = list_remove_first(data))) {
switch (t->type) {
case LEX_NAME:
@ -557,6 +582,7 @@ static int add_user(bip_t *bip, list_t *data)
case LEX_PASSWORD:
hash_binary(t->pdata, &u->password, &u->seed);
free(t->pdata);
t->pdata = NULL;
break;
case LEX_DEFAULT_NICK:
MOVE_STRING(u->default_nick, t->pdata);
@ -585,10 +611,10 @@ static int add_user(bip_t *bip, list_t *data)
case LEX_BLRESET_ON_TALK:
u->blreset_on_talk = t->ndata;
break;
case LEX_CONNECTION:
r = add_connection(bip, u, t->pdata);
free(t->pdata);
t->pdata = NULL;
if (!r)
return 0;
break;
@ -599,16 +625,17 @@ static int add_user(bip_t *bip, list_t *data)
if (!strncmp(t->pdata, "ca", 2))
u->ssl_check_mode = SSL_CHECK_CA;
free(t->pdata);
t->pdata = NULL;
break;
case LEX_SSL_CHECK_STORE:
u->ssl_check_store = t->pdata;
MOVE_STRING(u->ssl_check_store, t->pdata);
break;
#endif
default:
conf_die("Uknown keyword in user statement");
break;
return 0;
}
if (t->type == TUPLE_STR && t->pdata)
if (t->tuple_type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
@ -653,7 +680,6 @@ static int validate_config(bip_t *bip)
link->name);
#endif
//conf_die("user: ... net: ... can i has nick/user/rael");
r = 0;
for (hash_it_init(&link->chan_infos, &cit);
@ -681,16 +707,34 @@ static int validate_config(bip_t *bip)
int fireup(bip_t *bip, FILE *conf)
{
int r;
struct tuple *t;
list_t *l;
int err = 0;
struct historical_directives hds;
conf_start();
l = parse_conf(conf);
if (conf_error)
parse_conf(conf, &err);
if (err) {
free_conf(root_list);
root_list = NULL;
return 0;
}
while ((t = list_remove_first(l))) {
#define SET_HV(d, n) do {\
int __gtv = get_tuple_nvalue(root_list, LEX_##n);\
if (__gtv != -1) \
d = __gtv;\
else\
d = DEFAULT_##n;\
} while(0);
SET_HV(hds.always_backlog, ALWAYS_BACKLOG);
SET_HV(hds.backlog, BACKLOG);
SET_HV(hds.bl_msg_only, BL_MSG_ONLY);
SET_HV(hds.backlog_lines, BACKLOG_LINES);
SET_HV(hds.backlog_no_timestamp, BACKLOG_NO_TIMESTAMP);
SET_HV(hds.blreset_on_talk, BLRESET_ON_TALK);
#undef SET_HV
while ((t = list_remove_first(root_list))) {
switch (t->type) {
case LEX_LOG_SYNC_INTERVAL:
conf_log_sync_interval = t->ndata;
@ -723,43 +767,22 @@ int fireup(bip_t *bip, FILE *conf)
MOVE_STRING(conf_pid_file, t->pdata);
break;
case LEX_NETWORK:
add_network(bip, t->pdata);
r = add_network(bip, t->pdata);
list_free(t->pdata);
if (!r)
goto out_conf_error;
break;
case LEX_USER:
add_user(bip, t->pdata);
r = add_user(bip, t->pdata, &hds);
list_free(t->pdata);
if (!r)
goto out_conf_error;
break;
#warning deprecated but we still need to support these
#if 0
case LEX_ALWAYS_BACKLOG:
conf_always_backlog = t->ndata;
break;
case LEX_BACKLOG:
conf_backlog = t->ndata;
break;
case LEX_BL_MSG_ONLY:
conf_bl_msg_only = t->ndata;
break;
case LEX_BACKLOG_LINES:
conf_backlog_lines = t->ndata;
break;
case LEX_BACKLOG_NO_TIMESTAMP:
conf_backlog_no_timestamp = t->ndata;
break;
case LEX_BLRESET_ON_TALK:
conf_blreset_on_talk = t->ndata;
break;
/* end of deprectated */
#endif
default:
conf_die("Config error in base config (%d)", t->type);
goto out_conf_error;
}
if (t->type == TUPLE_STR && t->pdata)
if (t->tuple_type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
@ -768,6 +791,11 @@ int fireup(bip_t *bip, FILE *conf)
validate_config(bip);
return 1;
out_conf_error:
free_conf(root_list);
root_list = NULL;
return 0;
}
static void log_file_setup(void)
@ -937,13 +965,10 @@ int main(int argc, char **argv)
fatal("%s config file not found", confpath);
}
r = fireup(&bip, conf);
fclose(conf);
if (!r) {
fatal("%s", conf_errstr);
exit(28);
}
if (!r)
fatal("Not starting: error in config file.");
if (!conf_biphome) {
char *home = getenv("HOME");
@ -1005,9 +1030,6 @@ int main(int argc, char **argv)
fatal("Could not create listening socket");
for (;;) {
if (conf_error)
mylog(LOG_ERROR, "conf error: %s", conf_errstr);
irc_main(&bip);
sighup = 0;
@ -1773,12 +1795,14 @@ void free_conf(list_t *l)
{
struct tuple *t;
list_iterator_t li;
for (list_it_init(l, &li); (t = list_it_item(&li)); list_it_next(&li)) {
switch (t->tuple_type) {
case TUPLE_STR:
free(t->pdata); /* no break, for the style */
printf("freeconf: %s\n", (char *)t->pdata);
free(t->pdata);
break;
case TUPLE_INT:
free(t);
break;
case TUPLE_LIST:
free_conf(t->pdata);
@ -1787,5 +1811,8 @@ void free_conf(list_t *l)
fatal("internal error free_conf");
break;
}
free(t);
}
free(l);
}

View File

@ -19,9 +19,7 @@
extern int yylex (void);
extern char *yytext;
extern int linec;
extern int conf_error;
#define ERRBUFSZ 80
extern char conf_errstr[ERRBUFSZ];
int conf_error;
int yywrap()
{
@ -30,9 +28,7 @@ int yywrap()
int yyerror()
{
snprintf(conf_errstr, ERRBUFSZ, "Parse error near %s, line %d\n",
yytext, linec + 1);
conf_errstr[ERRBUFSZ - 1] = 0;
mylog(LOG_ERROR, "Parse error near %s, line %d\n", yytext, linec + 1);
conf_error = 1;
return 1;
}

View File

@ -49,8 +49,6 @@ void oidentd_dump(list_t *connl);
void irc_client_free(struct link_client *cli);
extern int conf_log_sync_interval;
extern int conf_error;
extern char conf_errstr[];
void write_user_list(connection_t *c, char *dest);
@ -1556,7 +1554,7 @@ static int irc_mode(struct link_server *server, struct line *line)
log_mode(LINK(server)->log, line->origin, line->elemv[1],
line->elemv[2], line->elemv + 3, line->elemc - 3);
/*
/*
* MODE -a+b.. #channel args
* ^ ^
* mode cur_arg

View File

@ -16,10 +16,10 @@
int linec = 0;
#define YY_NO_UNPUT
#include "util.h"
extern int conf_error;
extern list_t *root_list;
void yyparse(void);
void free_conf(list_t*);
extern int conf_error;
#if 0
/* SPANK ME WITH A SHOVEL */
@ -30,15 +30,14 @@ void dummy_lex_FFS(void)
}
#endif
list_t *parse_conf(FILE *file)
list_t *parse_conf(FILE *file, int *err)
{
YY_BUFFER_STATE in = yy_create_buffer(file, YY_BUF_SIZE);
yy_switch_to_buffer(in);
conf_error = 0;
yyparse();
if (conf_error) {
free_conf(root_list);
return NULL;
}
yy_delete_buffer(in);
*err = conf_error;
return root_list;
}
%}
@ -112,6 +111,6 @@ list_t *parse_conf(FILE *file)
"{" { return LEX_LBRA; }
"}" { return LEX_RBRA; }
";" { return LEX_SEMICOLON; }
. { printf("Parse error line %d, unknown character '%s'\n", linec + 1, yytext);
. { mylog(LOG_ERROR, "Parse error in config file line %d, unknown character '%s'\n", linec + 1, yytext);
return LEX_BUNCH; }
%%

View File

@ -118,6 +118,9 @@ void _mylog(int level, char *fmt, va_list ap)
{
char *prefix;
if (!conf_log_system)
return;
if (level > conf_log_level)
return;
@ -157,9 +160,6 @@ void mylog(int level, char *fmt, ...)
{
va_list ap;
if (!conf_log_system)
return;
va_start(ap, fmt);
_mylog(level, fmt, ap);
va_end(ap);

View File

@ -15,6 +15,7 @@
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdarg.h>
/* Warning: must be in order, 0 = less output */
#define LOG_STD -1
@ -30,6 +31,7 @@
#define HASH_DEFAULT 0
void mylog(int level, char *fmt, ...);
void _mylog(int level, char *fmt, va_list ap);
void fatal(char *fmt, ...);
char *timestamp(void);
struct list_item;