Support live addition and removal of connection.

This commit is contained in:
Arnaud Cornet 2007-11-25 14:50:22 +01:00
parent f1a0aede23
commit cc9afd6b1e
3 changed files with 99 additions and 10 deletions

View File

@ -355,6 +355,74 @@ static int add_network(bip_t *bip, list_t *data)
return 1;
}
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)) {
adm_reply(ic, "cannot find this connection");
return;
}
l = hash_get(&user->connections, conn_name);
link_kill(bip, l);
adm_reply(ic, "deleted");
}
void adm_bip_addconn(bip_t *bip, struct link_client *ic, char *conn_name,
char *network_name)
{
struct user *user = LINK(ic)->user;
struct network *network;
/* check name uniqueness */
if (hash_get(&user->connections, conn_name)) {
adm_reply(ic, "connection name already exists for this user.");
return;
}
/* check we know about this network */
network = hash_get(&bip->networks, network_name);
if (!network) {
adm_reply(ic, "no such network name");
return;
}
struct link *l;
l = irc_link_new();
l->name = strdup(conn_name);
hash_insert(&user->connections, conn_name, l);
list_add_last(&bip->link_list, l);
l->user = user;
l->network = network;
l->log = log_new(user, conn_name);
#ifdef HAVE_LIBSSL
l->ssl_check_mode = user->ssl_check_mode;
l->untrusted_certs = sk_X509_new_null();
#endif
#define SCOPY(member) l->member = (LINK(ic)->member ? strdup(LINK(ic)->member) : NULL)
#define ICOPY(member) l->member = LINK(ic)->member
SCOPY(connect_nick);
SCOPY(username);
SCOPY(realname);
/* we don't copy server password */
SCOPY(vhost);
ICOPY(follow_nick);
ICOPY(ignore_first_nick);
SCOPY(away_nick);
SCOPY(no_client_away_msg);
/* we don't copy on_connect_send */
#ifdef HAVE_LIBSSL
ICOPY(ssl_check_mode);
#endif
#undef SCOPY
#undef ICOPY
}
static int add_connection(bip_t *bip, struct user *user, list_t *data)
{
struct tuple *t, *t2;
@ -725,6 +793,7 @@ void clear_marks(bip_t *bip)
void user_kill(bip_t *bip, struct user *user)
{
(void)bip;
if (!hash_is_empty(&user->connections))
fatal("user_kill, user still has connections");
free(user->name);
@ -1745,7 +1814,8 @@ void adm_bip_help(struct link_client *ic, int admin)
adm_reply(ic, "/BIP AWAY_NICK # clear away nick");
}
int adm_bip(struct link_client *ic, struct line *line, unsigned int privmsg)
int adm_bip(bip_t *bip, struct link_client *ic, struct line *line,
unsigned int privmsg)
{
int admin = LINK(ic)->user->admin;
@ -1850,7 +1920,8 @@ int adm_bip(struct link_client *ic, struct line *line, unsigned int privmsg)
if (line->elemc == privmsg + 2) {
adm_on_connect_send(ic, NULL);
} else if (line->elemc == privmsg + 3) {
// TODO: on connect send should not be limited to one word
// TODO: on connect send should not be limited to one
// word
adm_on_connect_send(ic, line->elemv[privmsg + 2]);
} else {
adm_reply(ic, "/BIP ON_CONNECT_SEND needs zero or one "
@ -1865,6 +1936,22 @@ int adm_bip(struct link_client *ic, struct line *line, unsigned int privmsg)
adm_reply(ic, "/BIP AWAY_NICK needs zero or one "
"argument");
}
} else if (admin &&
strcasecmp(line->elemv[privmsg + 1], "ADD_CONN") == 0) {
if (line->elemc != privmsg + 4) {
adm_reply(ic, "/BIP ADD_CONN <connection name> "
"<network name>");
} else {
adm_bip_addconn(bip, ic, line->elemv[privmsg + 2],
line->elemv[privmsg + 3]);
}
} else if (admin &&
strcasecmp(line->elemv[privmsg + 1], "DEL_CONN") == 0) {
if (line->elemc != privmsg + 3) {
adm_reply(ic, "/BIP DEL_CONN <connection name>");
} else {
adm_bip_delconn(bip, ic, line->elemv[privmsg + 2]);
}
#ifdef HAVE_LIBSSL
} else if (strcasecmp(line->elemv[privmsg + 1], "TRUST") == 0) {
/* TODO : warn the user of results */

View File

@ -17,7 +17,8 @@
#ifdef HAVE_LIBSSL
int adm_trust(struct link_client *ic, struct line *line);
#endif
int adm_bip(struct link_client *ic, struct line *line, unsigned int privmsg);
int adm_bip(bip_t *bip, struct link_client *ic, struct line *line,
unsigned int privmsg);
int ssl_check_trust(struct link_client *ic);
void adm_blreset(struct link_client *ic);

View File

@ -56,6 +56,7 @@ static void irc_copy_cli(struct link_client *src, struct link_client *dest,
struct line *line);
static void irc_cli_make_join(struct link_client *ic);
static void server_setup_reconnect_timer(struct link *link);
int irc_cli_bip(bip_t *bip, struct link_client *ic, struct line *line);
#define LAGOUT_TIME 480
#define LAGCHECK_TIME (90)
@ -605,9 +606,9 @@ void unbind_from_link(struct link_client *ic)
fatal("realloc");
}
int irc_cli_bip(struct link_client *ic, struct line *line)
int irc_cli_bip(bip_t *bip, struct link_client *ic, struct line *line)
{
return adm_bip(ic, line, 0);
return adm_bip(bip, ic, line, 0);
}
#define PASS_SEP ':'
@ -857,13 +858,14 @@ static int irc_cli_quit(struct link_client *ic, struct line *line)
return OK_CLOSE;
}
static int irc_cli_privmsg(struct link_client *ic, struct line *line)
static int irc_cli_privmsg(bip_t *bip, struct link_client *ic,
struct line *line)
{
if (line->elemc >= 3)
log_cli_privmsg(LINK(ic)->log, LINK(ic)->l_server->nick,
line->elemv[1], line->elemv[2]);
if (strcmp(line->elemv[1], "-bip") == 0)
return adm_bip(ic, line, 1);
return adm_bip(bip, ic, line, 1);
if (LINK(ic)->user->blreset_on_talk)
log_reinit_all(LINK(ic)->log);
@ -1052,7 +1054,6 @@ static int irc_dispatch_trust_client(struct link_client *ic, struct line *line)
}
#endif
int irc_cli_bip(struct link_client *ic, struct line *line);
static int irc_dispatch_client(bip_t *bip, struct link_client *ic,
struct line *line)
{
@ -1071,7 +1072,7 @@ static int irc_dispatch_client(bip_t *bip, struct link_client *ic,
"before sending commands\r\n");
r = OK_FORGET;
} else if (strcasecmp(line->elemv[0], "BIP") == 0) {
r = irc_cli_bip(ic, line);
r = irc_cli_bip(bip, ic, line);
} else if (strcmp(line->elemv[0], "JOIN") == 0) {
r = irc_cli_join(ic, line);
} else if (strcmp(line->elemv[0], "PART") == 0) {
@ -1081,7 +1082,7 @@ static int irc_dispatch_client(bip_t *bip, struct link_client *ic,
} else if (strcmp(line->elemv[0], "QUIT") == 0) {
r = irc_cli_quit(ic, line);
} else if (strcmp(line->elemv[0], "PRIVMSG") == 0) {
r = irc_cli_privmsg(ic, line);
r = irc_cli_privmsg(bip, ic, line);
} else if (strcmp(line->elemv[0], "NOTICE") == 0) {
r = irc_cli_notice(ic, line);
} else if (strcmp(line->elemv[0], "WHO") == 0) {