Be verbose when conf_die is called. Try to inform calling client.

This commit is contained in:
Arnaud Cornet 2007-12-14 23:07:18 +01:00
parent cbcd4c18a3
commit 8f998c97b6
5 changed files with 91 additions and 52 deletions

102
src/bip.c
View File

@ -50,7 +50,7 @@ int conf_log_system = DEFAULT_LOG_SYSTEM;
int conf_log_sync_interval = DEFAULT_LOG_SYNC_INTERVAL; int conf_log_sync_interval = DEFAULT_LOG_SYNC_INTERVAL;
list_t *parse_conf(FILE *file, int *err); list_t *parse_conf(FILE *file, int *err);
static void conf_die(char *fmt, ...); void conf_die(bip_t *bip, char *fmt, ...);
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
int adm_trust(struct link_client *ic, struct line *line); int adm_trust(struct link_client *ic, struct line *line);
#endif #endif
@ -87,7 +87,7 @@ static void hash_binary(char *hex, unsigned char **password, unsigned int *seed)
*password = md5; *password = md5;
} }
static int add_server(struct server *s, list_t *data) static int add_server(bip_t *bip, struct server *s, list_t *data)
{ {
struct tuple *t; struct tuple *t;
@ -110,7 +110,7 @@ static int add_server(struct server *s, list_t *data)
} }
if (!s->host) { if (!s->host) {
free(s); free(s);
conf_die("Server conf: host not set"); conf_die(bip, "Server conf: host not set");
return 0; return 0;
} }
return 1; return 1;
@ -121,15 +121,32 @@ static int add_server(struct server *s, list_t *data)
extern list_t *root_list; extern list_t *root_list;
int yyparse(); int yyparse();
static void conf_die(char *fmt, ...) void conf_die(bip_t *bip, char *fmt, ...)
{ {
va_list ap; va_list ap;
int size = ERRBUFSZ;
int n;
char *error = malloc(size);
for (;;) {
va_start(ap, fmt);
n = vsnprintf(error, size, fmt, ap);
va_end(ap);
if (n > -1 && n < size) {
list_add_last(&bip->errors, error);
break;
}
if (n > -1)
size = n + 1;
else
size *= 2;
error = realloc(error, size);
}
va_start(ap, fmt); va_start(ap, fmt);
_mylog(LOG_ERROR, fmt, ap); _mylog(LOG_ERROR, fmt, ap);
va_end(ap); va_end(ap);
} }
FILE *conf_global_log_file; FILE *conf_global_log_file;
static pid_t daemonize(void) static pid_t daemonize(void)
@ -255,20 +272,20 @@ static void version()
"Distributed under the GNU Public License Version 2\n", BIP_VERSION); "Distributed under the GNU Public License Version 2\n", BIP_VERSION);
} }
bip_t *_bip;
void reload_config(int i) void reload_config(int i)
{ {
(void)i; (void)i;
sighup = 1; sighup = 1;
_bip->reloading_client = NULL;
} }
bip_t *_bip;
void rlimit_cpu_reached(int i) void rlimit_cpu_reached(int i)
{ {
(void)i; (void)i;
mylog(LOG_WARN, "This process has reached the CPU time usage limit. " mylog(LOG_WARN, "This process has reached the CPU time usage limit. "
"It means bip will be killed by the Operating System soon."); "It means bip will be killed by the Operating System soon.");
#warning CODEME warn all users via bip_notify
} }
void rlimit_bigfile_reached(int i) void rlimit_bigfile_reached(int i)
@ -277,7 +294,6 @@ void rlimit_bigfile_reached(int i)
mylog(LOG_WARN, "A file has reached the max size this process is " mylog(LOG_WARN, "A file has reached the max size this process is "
"allowed to create. The file will not be written correctly, " "allowed to create. The file will not be written correctly, "
"an error message should follow. This is not fatal."); "an error message should follow. This is not fatal.");
#warning CODEME warn all users via bip_notify ?
} }
void bad_quit(int i) void bad_quit(int i)
@ -306,7 +322,7 @@ static int add_network(bip_t *bip, list_t *data)
char *name = get_tuple_pvalue(data, LEX_NAME); char *name = get_tuple_pvalue(data, LEX_NAME);
if (name == NULL) { if (name == NULL) {
conf_die("Network with no name"); conf_die(bip, "Network with no name");
return 0; return 0;
} }
n = hash_get(&bip->networks, name); n = hash_get(&bip->networks, name);
@ -337,7 +353,8 @@ static int add_network(bip_t *bip, list_t *data)
n->serverc++; n->serverc++;
memset(&n->serverv[n->serverc - 1], 0, memset(&n->serverv[n->serverc - 1], 0,
sizeof(struct server)); sizeof(struct server));
r = add_server(&n->serverv[n->serverc - 1], t->pdata); r = add_server(bip, &n->serverv[n->serverc - 1],
t->pdata);
if (!r) { if (!r) {
n->serverc--; n->serverc--;
return 0; return 0;
@ -346,7 +363,7 @@ static int add_network(bip_t *bip, list_t *data)
t->pdata = NULL; t->pdata = NULL;
break; break;
default: default:
conf_die("unknown keyword in network statement"); conf_die(bip, "unknown keyword in network statement");
return 0; return 0;
break; break;
} }
@ -362,14 +379,13 @@ void adm_bip_delconn(bip_t *bip, struct link_client *ic, char *conn_name)
struct user *user = LINK(ic)->user; struct user *user = LINK(ic)->user;
struct link *l; struct link *l;
if (!hash_get(&user->connections, conn_name)) { if (!(l = hash_get(&user->connections, conn_name))) {
bip_notify(ic, "cannot find this connection"); bip_notify(ic, "cannot find this connection");
return; return;
} }
l = hash_get(&user->connections, conn_name); bip_notify(ic, "deleting");
link_kill(bip, l); link_kill(bip, l);
bip_notify(ic, "deleted");
} }
void adm_bip_addconn(bip_t *bip, struct link_client *ic, char *conn_name, void adm_bip_addconn(bip_t *bip, struct link_client *ic, char *conn_name,
@ -434,7 +450,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
char *name = get_tuple_pvalue(data, LEX_NAME); char *name = get_tuple_pvalue(data, LEX_NAME);
if (name == NULL) { if (name == NULL) {
conf_die("Connection with no name"); conf_die(bip, "Connection with no name");
return 0; return 0;
} }
l = hash_get(&user->connections, name); l = hash_get(&user->connections, name);
@ -461,14 +477,14 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
case LEX_NETWORK: case LEX_NETWORK:
l->network = hash_get(&bip->networks, t->pdata); l->network = hash_get(&bip->networks, t->pdata);
if (!l->network) { if (!l->network) {
conf_die("Undefined network %s.\n", conf_die(bip, "Undefined network %s.\n",
t->pdata); t->pdata);
return 0; return 0;
} }
break; break;
case LEX_NICK: case LEX_NICK:
if (!is_valid_nick(t->pdata)) if (!is_valid_nick(t->pdata))
conf_die("Invalid nickname %s.", t->pdata); conf_die(bip, "Invalid nickname %s.", t->pdata);
MOVE_STRING(l->connect_nick, t->pdata); MOVE_STRING(l->connect_nick, t->pdata);
break; break;
case LEX_USER: case LEX_USER:
@ -486,7 +502,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
case LEX_CHANNEL: case LEX_CHANNEL:
name = get_tuple_pvalue(t->pdata, LEX_NAME); name = get_tuple_pvalue(t->pdata, LEX_NAME);
if (name == NULL) { if (name == NULL) {
conf_die("Channel with no name"); conf_die(bip, "Channel with no name");
return 0; return 0;
} }
@ -542,7 +558,8 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
break; break;
#endif #endif
default: default:
conf_die("unknown keyword in connection statement"); conf_die(bip, "Unknown keyword in connection "
"statement");
return 0; return 0;
} }
if (t->tuple_type == TUPLE_STR && t->pdata) if (t->tuple_type == TUPLE_STR && t->pdata)
@ -551,20 +568,22 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
} }
/* checks that can only be here, or must */ /* checks that can only be here, or must */
if (!l->network) if (!l->network)
conf_die("Missing network in connection block"); conf_die(bip, "Missing network in connection block");
if (!l->connect_nick) { if (!l->connect_nick) {
if (!user->default_nick) if (!user->default_nick)
conf_die("No nick set and no default nick."); conf_die(bip, "No nick set and no default nick.");
l->connect_nick = strdup(user->default_nick); l->connect_nick = strdup(user->default_nick);
} }
if (!l->username) { if (!l->username) {
if (!user->default_username) if (!user->default_username)
conf_die("No username set and no default username."); conf_die(bip, "No username set and no default "
"username.");
l->username = strdup(user->default_username); l->username = strdup(user->default_username);
} }
if (!l->realname) { if (!l->realname) {
if (!user->default_realname) if (!user->default_realname)
conf_die("No realname set and no default realname."); conf_die(bip, "No realname set and no default "
"realname.");
l->realname = strdup(user->default_realname); l->realname = strdup(user->default_realname);
} }
@ -616,7 +635,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
char *name = get_tuple_pvalue(data, LEX_NAME); char *name = get_tuple_pvalue(data, LEX_NAME);
if (name == NULL) { if (name == NULL) {
conf_die("User with no name"); conf_die(bip, "User with no name");
return 0; return 0;
} }
u = hash_get(&bip->users, name); u = hash_get(&bip->users, name);
@ -714,7 +733,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
break; break;
#endif #endif
default: default:
conf_die("Uknown keyword in user statement"); conf_die(bip, "Uknown keyword in user statement");
return 0; return 0;
} }
if (t->tuple_type == TUPLE_STR && t->pdata) if (t->tuple_type == TUPLE_STR && t->pdata)
@ -722,7 +741,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
free(t); free(t);
} }
if (!u->password) { if (!u->password) {
conf_die("Missing password in user block"); conf_die(bip, "Missing password in user block");
return 0; return 0;
} }
@ -757,10 +776,10 @@ static int validate_config(bip_t *bip)
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
if (link->network->ssl && if (link->network->ssl &&
!link->ssl_check_mode) !link->ssl_check_mode)
conf_die("user %s, connection %s: you " conf_die(bip, "user %s, "
"should define a " "connection %s: you should "
"ssl_check_mode.", user->name, "define a ssl_check_mode.",
link->name); user->name, link->name);
#endif #endif
r = 0; r = 0;
@ -769,7 +788,8 @@ static int validate_config(bip_t *bip)
(ci = hash_it_item(&cit)); (ci = hash_it_item(&cit));
hash_it_next(&cit)) { hash_it_next(&cit)) {
if (!ci->name) if (!ci->name)
conf_die("user %s, connection " conf_die(bip, "user %s, "
"connection "
"%s: channel must have" "%s: channel must have"
"a name.", user->name, "a name.", user->name,
link->name); link->name);
@ -778,7 +798,8 @@ static int validate_config(bip_t *bip)
} }
if (user->backlog && !conf_log && user->backlog_lines == 0) { if (user->backlog && !conf_log && user->backlog_lines == 0) {
conf_die("If conf_log = false, you must set backlog_" conf_die(bip, "If conf_log = false, you must set "
"backlog_"
"lines to a non-nul value for each user with" "lines to a non-nul value for each user with"
"backlog = true. Faulty user is %s", "backlog = true. Faulty user is %s",
user->name); user->name);
@ -853,8 +874,11 @@ int fireup(bip_t *bip, FILE *conf)
struct tuple *t; struct tuple *t;
int err = 0; int err = 0;
struct historical_directives hds; struct historical_directives hds;
char *l;
clear_marks(bip); clear_marks(bip);
while ((l = list_remove_first(&bip->errors)))
free(l);
parse_conf(conf, &err); parse_conf(conf, &err);
if (err) { if (err) {
free_conf(root_list); free_conf(root_list);
@ -940,7 +964,8 @@ int fireup(bip_t *bip, FILE *conf)
goto out_conf_error; goto out_conf_error;
break; break;
default: default:
conf_die("Config error in base config (%d)", t->type); conf_die(bip, "Config error in base config (%d)",
t->type);
goto out_conf_error; goto out_conf_error;
} }
if (t->tuple_type == TUPLE_STR && t->pdata) if (t->tuple_type == TUPLE_STR && t->pdata)
@ -1134,7 +1159,8 @@ int main(int argc, char **argv)
if (!conf_biphome) { if (!conf_biphome) {
char *home = getenv("HOME"); char *home = getenv("HOME");
if (!home) { if (!home) {
conf_die("no $HOME !, do you live in a trailer ?"); conf_die(&bip,
"no $HOME !, do you live in a trailer ?");
return 0; return 0;
} }
conf_biphome = malloc(strlen(home) + strlen("/.bip") + 1); conf_biphome = malloc(strlen(home) + strlen("/.bip") + 1);
@ -1731,7 +1757,6 @@ void bip_notify(struct link_client *ic, char *fmt, ...)
va_end(ap); va_end(ap);
} }
extern struct link_client *reloading_client;
void adm_blreset(struct link_client *ic) void adm_blreset(struct link_client *ic)
{ {
log_reinit_all(LINK(ic)->log); log_reinit_all(LINK(ic)->log);
@ -1876,8 +1901,8 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line,
bip_notify(ic, "-- You're not allowed to reload bip"); bip_notify(ic, "-- You're not allowed to reload bip");
return OK_FORGET; return OK_FORGET;
} }
bip_notify(ic, "-- Bip has been set to reload shortly"); bip_notify(ic, "-- Reloading bip...");
reloading_client = ic; bip->reloading_client = ic;
sighup = 1; sighup = 1;
} else if (strcasecmp(line->elemv[privmsg + 1], "LIST") == 0) { } else if (strcasecmp(line->elemv[privmsg + 1], "LIST") == 0) {
if (line->elemc != privmsg + 3) { if (line->elemc != privmsg + 3) {
@ -2013,7 +2038,6 @@ void free_conf(list_t *l)
for (list_it_init(l, &li); (t = list_it_item(&li)); list_it_next(&li)) { for (list_it_init(l, &li); (t = list_it_item(&li)); list_it_next(&li)) {
switch (t->tuple_type) { switch (t->tuple_type) {
case TUPLE_STR: case TUPLE_STR:
printf("freeconf: %s\n", (char *)t->pdata);
free(t->pdata); free(t->pdata);
break; break;
case TUPLE_INT: case TUPLE_INT:

View File

@ -19,20 +19,12 @@
extern int yylex (void); extern int yylex (void);
extern char *yytext; extern char *yytext;
extern int linec; extern int linec;
int conf_error;
int yywrap() int yywrap()
{ {
return 1; return 1;
} }
int yyerror()
{
mylog(LOG_ERROR, "Parse error near %s, line %d\n", yytext, linec + 1);
conf_error = 1;
return 1;
}
int yydebug = 1; int yydebug = 1;
list_t *root_list; list_t *root_list;

View File

@ -2414,7 +2414,6 @@ prot_err:
} }
} }
struct link_client *reloading_client;
/* /*
* The main loop * The main loop
* inc is the incoming connection, clientl list a list of client struct that * inc is the incoming connection, clientl list a list of client struct that
@ -2424,6 +2423,14 @@ void irc_main(bip_t *bip)
{ {
int timeleft = 1000; int timeleft = 1000;
if (bip->reloading_client) {
char *l;
while ((l = list_remove_first(&bip->errors)))
bip_notify(bip->reloading_client, l);
bip->reloading_client = NULL;
}
/* /*
* If the list is empty, we are starting. Otherwise we are reloading, * If the list is empty, we are starting. Otherwise we are reloading,
* and conn_list is kept accross reloads. * and conn_list is kept accross reloads.
@ -2491,6 +2498,8 @@ void link_kill(bip_t *bip, struct link *link)
irc_server_free(link->l_server); irc_server_free(link->l_server);
while (link->l_clientc) { while (link->l_clientc) {
struct link_client *lc = link->l_clientv[0]; struct link_client *lc = link->l_clientv[0];
if (lc == bip->reloading_client)
bip->reloading_client = NULL;
list_remove(&bip->conn_list, CONN(lc)); list_remove(&bip->conn_list, CONN(lc));
unbind_from_link(lc); unbind_from_link(lc);
irc_client_free(lc); irc_client_free(lc);

View File

@ -244,6 +244,8 @@ typedef struct bip {
hash_t networks; hash_t networks;
hash_t users; hash_t users;
list_t errors;
struct link_client *reloading_client;
} bip_t; } bip_t;
void bip_init(bip_t *bip); void bip_init(bip_t *bip);

View File

@ -13,13 +13,15 @@
*/ */
#include "conf.h" #include "conf.h"
int linec = 0; int linec;
#define YY_NO_UNPUT #define YY_NO_UNPUT
#include "util.h" #include "util.h"
extern list_t *root_list; extern list_t *root_list;
void yyparse(void); void yyparse(void);
void free_conf(list_t*); void free_conf(list_t*);
extern int conf_error; int conf_error;
typedef struct bip bip_t;
extern bip_t *_bip;
#if 0 #if 0
/* SPANK ME WITH A SHOVEL */ /* SPANK ME WITH A SHOVEL */
@ -29,12 +31,22 @@ void dummy_lex_FFS(void)
yyunput(0, NULL); yyunput(0, NULL);
} }
#endif #endif
void conf_die(bip_t *, char *, ...);
int yyerror(void)
{
conf_die(_bip, "Parse error near %s, line %d", yytext, linec + 1);
conf_error = 1;
return 1;
}
list_t *parse_conf(FILE *file, int *err) list_t *parse_conf(FILE *file, int *err)
{ {
conf_error = 0;
linec = 0;
YY_BUFFER_STATE in = yy_create_buffer(file, YY_BUF_SIZE); YY_BUFFER_STATE in = yy_create_buffer(file, YY_BUF_SIZE);
yy_switch_to_buffer(in); yy_switch_to_buffer(in);
conf_error = 0;
yyparse(); yyparse();
yy_delete_buffer(in); yy_delete_buffer(in);
*err = conf_error; *err = conf_error;
@ -112,6 +124,6 @@ list_t *parse_conf(FILE *file, int *err)
"{" { return LEX_LBRA; } "{" { return LEX_LBRA; }
"}" { return LEX_RBRA; } "}" { return LEX_RBRA; }
";" { return LEX_SEMICOLON; } ";" { return LEX_SEMICOLON; }
. { mylog(LOG_ERROR, "Parse error in config file line %d, unknown character '%s'\n", linec + 1, yytext); . { conf_die(_bip, "Parse error in config file line %d, unknown character '%s'", linec + 1, yytext); conf_error = 1;
return LEX_BUNCH; } return LEX_BUNCH; }
%% %%