From 8f998c97b6413a2982af0b7a4e4bf08a8f993d59 Mon Sep 17 00:00:00 2001 From: Arnaud Cornet Date: Fri, 14 Dec 2007 23:07:18 +0100 Subject: [PATCH] Be verbose when conf_die is called. Try to inform calling client. --- src/bip.c | 102 +++++++++++++++++++++++++++++++++-------------------- src/conf.y | 8 ----- src/irc.c | 11 +++++- src/irc.h | 2 ++ src/lex.l | 20 ++++++++--- 5 files changed, 91 insertions(+), 52 deletions(-) diff --git a/src/bip.c b/src/bip.c index 81022e1..1f54e35 100644 --- a/src/bip.c +++ b/src/bip.c @@ -50,7 +50,7 @@ int conf_log_system = DEFAULT_LOG_SYSTEM; int conf_log_sync_interval = DEFAULT_LOG_SYNC_INTERVAL; 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 int adm_trust(struct link_client *ic, struct line *line); #endif @@ -87,7 +87,7 @@ static void hash_binary(char *hex, unsigned char **password, unsigned int *seed) *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; @@ -110,7 +110,7 @@ static int add_server(struct server *s, list_t *data) } if (!s->host) { free(s); - conf_die("Server conf: host not set"); + conf_die(bip, "Server conf: host not set"); return 0; } return 1; @@ -121,15 +121,32 @@ static int add_server(struct server *s, list_t *data) extern list_t *root_list; int yyparse(); -static void conf_die(char *fmt, ...) +void conf_die(bip_t *bip, char *fmt, ...) { 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); _mylog(LOG_ERROR, fmt, ap); va_end(ap); } - FILE *conf_global_log_file; static pid_t daemonize(void) @@ -255,20 +272,20 @@ static void version() "Distributed under the GNU Public License Version 2\n", BIP_VERSION); } +bip_t *_bip; + void reload_config(int i) { (void)i; sighup = 1; + _bip->reloading_client = NULL; } -bip_t *_bip; - void rlimit_cpu_reached(int i) { (void)i; mylog(LOG_WARN, "This process has reached the CPU time usage limit. " "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) @@ -277,7 +294,6 @@ void rlimit_bigfile_reached(int i) mylog(LOG_WARN, "A file has reached the max size this process is " "allowed to create. The file will not be written correctly, " "an error message should follow. This is not fatal."); -#warning CODEME warn all users via bip_notify ? } 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); if (name == NULL) { - conf_die("Network with no name"); + conf_die(bip, "Network with no name"); return 0; } n = hash_get(&bip->networks, name); @@ -337,7 +353,8 @@ static int add_network(bip_t *bip, list_t *data) n->serverc++; memset(&n->serverv[n->serverc - 1], 0, 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) { n->serverc--; return 0; @@ -346,7 +363,7 @@ static int add_network(bip_t *bip, list_t *data) t->pdata = NULL; break; default: - conf_die("unknown keyword in network statement"); + conf_die(bip, "unknown keyword in network statement"); return 0; 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 link *l; - if (!hash_get(&user->connections, conn_name)) { + if (!(l = hash_get(&user->connections, conn_name))) { bip_notify(ic, "cannot find this connection"); return; } - l = hash_get(&user->connections, conn_name); + bip_notify(ic, "deleting"); link_kill(bip, l); - bip_notify(ic, "deleted"); } 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); if (name == NULL) { - conf_die("Connection with no name"); + conf_die(bip, "Connection with no name"); return 0; } 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: l->network = hash_get(&bip->networks, t->pdata); if (!l->network) { - conf_die("Undefined network %s.\n", + conf_die(bip, "Undefined network %s.\n", t->pdata); return 0; } break; case LEX_NICK: 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); break; case LEX_USER: @@ -486,7 +502,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data) case LEX_CHANNEL: name = get_tuple_pvalue(t->pdata, LEX_NAME); if (name == NULL) { - conf_die("Channel with no name"); + conf_die(bip, "Channel with no name"); return 0; } @@ -542,7 +558,8 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data) break; #endif default: - conf_die("unknown keyword in connection statement"); + conf_die(bip, "Unknown keyword in connection " + "statement"); return 0; } 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 */ if (!l->network) - conf_die("Missing network in connection block"); + conf_die(bip, "Missing network in connection block"); if (!l->connect_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); } if (!l->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); } if (!l->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); } @@ -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); if (name == NULL) { - conf_die("User with no name"); + conf_die(bip, "User with no name"); return 0; } 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; #endif default: - conf_die("Uknown keyword in user statement"); + conf_die(bip, "Uknown keyword in user statement"); return 0; } 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); } if (!u->password) { - conf_die("Missing password in user block"); + conf_die(bip, "Missing password in user block"); return 0; } @@ -757,10 +776,10 @@ static int validate_config(bip_t *bip) #ifdef HAVE_LIBSSL if (link->network->ssl && !link->ssl_check_mode) - conf_die("user %s, connection %s: you " - "should define a " - "ssl_check_mode.", user->name, - link->name); + conf_die(bip, "user %s, " + "connection %s: you should " + "define a ssl_check_mode.", + user->name, link->name); #endif r = 0; @@ -769,7 +788,8 @@ static int validate_config(bip_t *bip) (ci = hash_it_item(&cit)); hash_it_next(&cit)) { if (!ci->name) - conf_die("user %s, connection " + conf_die(bip, "user %s, " + "connection " "%s: channel must have" "a name.", user->name, link->name); @@ -778,7 +798,8 @@ static int validate_config(bip_t *bip) } 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" "backlog = true. Faulty user is %s", user->name); @@ -853,8 +874,11 @@ int fireup(bip_t *bip, FILE *conf) struct tuple *t; int err = 0; struct historical_directives hds; + char *l; clear_marks(bip); + while ((l = list_remove_first(&bip->errors))) + free(l); parse_conf(conf, &err); if (err) { free_conf(root_list); @@ -940,7 +964,8 @@ int fireup(bip_t *bip, FILE *conf) goto out_conf_error; break; 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; } if (t->tuple_type == TUPLE_STR && t->pdata) @@ -1134,7 +1159,8 @@ int main(int argc, char **argv) if (!conf_biphome) { char *home = getenv("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; } conf_biphome = malloc(strlen(home) + strlen("/.bip") + 1); @@ -1731,7 +1757,6 @@ void bip_notify(struct link_client *ic, char *fmt, ...) va_end(ap); } -extern struct link_client *reloading_client; void adm_blreset(struct link_client *ic) { 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"); return OK_FORGET; } - bip_notify(ic, "-- Bip has been set to reload shortly"); - reloading_client = ic; + bip_notify(ic, "-- Reloading bip..."); + bip->reloading_client = ic; sighup = 1; } else if (strcasecmp(line->elemv[privmsg + 1], "LIST") == 0) { 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)) { switch (t->tuple_type) { case TUPLE_STR: - printf("freeconf: %s\n", (char *)t->pdata); free(t->pdata); break; case TUPLE_INT: diff --git a/src/conf.y b/src/conf.y index eedc86a..63111c8 100644 --- a/src/conf.y +++ b/src/conf.y @@ -19,20 +19,12 @@ extern int yylex (void); extern char *yytext; extern int linec; -int conf_error; int yywrap() { 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; list_t *root_list; diff --git a/src/irc.c b/src/irc.c index 417ad6c..7a474fe 100644 --- a/src/irc.c +++ b/src/irc.c @@ -2414,7 +2414,6 @@ prot_err: } } -struct link_client *reloading_client; /* * The main loop * 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; + 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, * 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); while (link->l_clientc) { struct link_client *lc = link->l_clientv[0]; + if (lc == bip->reloading_client) + bip->reloading_client = NULL; list_remove(&bip->conn_list, CONN(lc)); unbind_from_link(lc); irc_client_free(lc); diff --git a/src/irc.h b/src/irc.h index 1fdc9ab..f034d2d 100644 --- a/src/irc.h +++ b/src/irc.h @@ -244,6 +244,8 @@ typedef struct bip { hash_t networks; hash_t users; + list_t errors; + struct link_client *reloading_client; } bip_t; void bip_init(bip_t *bip); diff --git a/src/lex.l b/src/lex.l index 643ba7d..af9a6b5 100644 --- a/src/lex.l +++ b/src/lex.l @@ -13,13 +13,15 @@ */ #include "conf.h" -int linec = 0; +int linec; #define YY_NO_UNPUT #include "util.h" extern list_t *root_list; void yyparse(void); void free_conf(list_t*); -extern int conf_error; +int conf_error; +typedef struct bip bip_t; +extern bip_t *_bip; #if 0 /* SPANK ME WITH A SHOVEL */ @@ -29,12 +31,22 @@ void dummy_lex_FFS(void) yyunput(0, NULL); } #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) { + conf_error = 0; + linec = 0; + YY_BUFFER_STATE in = yy_create_buffer(file, YY_BUF_SIZE); yy_switch_to_buffer(in); - conf_error = 0; yyparse(); yy_delete_buffer(in); *err = conf_error; @@ -112,6 +124,6 @@ list_t *parse_conf(FILE *file, int *err) "{" { return LEX_LBRA; } "}" { return LEX_RBRA; } ";" { 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; } %%