diff options
Diffstat (limited to 'src/irc/core/irc-servers-reconnect.c')
-rw-r--r-- | src/irc/core/irc-servers-reconnect.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c new file mode 100644 index 0000000..e18a5a9 --- /dev/null +++ b/src/irc/core/irc-servers-reconnect.c @@ -0,0 +1,128 @@ +/* + servers-reconnect.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "module.h" +#include <irssi/src/core/commands.h> +#include <irssi/src/core/network.h> +#include <irssi/src/core/signals.h> + +#include <irssi/src/irc/core/modes.h> +#include <irssi/src/irc/core/irc-servers.h> + +#include <irssi/src/core/settings.h> + +static void sig_server_connect_copy(SERVER_CONNECT_REC **dest, + IRC_SERVER_CONNECT_REC *src) +{ + IRC_SERVER_CONNECT_REC *rec; + + g_return_if_fail(dest != NULL); + if (!IS_IRC_SERVER_CONNECT(src)) + return; + + rec = g_new0(IRC_SERVER_CONNECT_REC, 1); + rec->chat_type = IRC_PROTOCOL; + rec->max_cmds_at_once = src->max_cmds_at_once; + rec->cmd_queue_speed = src->cmd_queue_speed; + rec->max_query_chans = src->max_query_chans; + rec->max_kicks = src->max_kicks; + rec->max_modes = src->max_modes; + rec->max_msgs = src->max_msgs; + rec->max_whois = src->max_whois; + rec->usermode = g_strdup(src->usermode); + rec->alternate_nick = g_strdup(src->alternate_nick); + rec->sasl_mechanism = src->sasl_mechanism; + rec->sasl_username = g_strdup(src->sasl_username); + rec->sasl_password = g_strdup(src->sasl_password); + rec->disallow_starttls = src->disallow_starttls; + rec->starttls = src->starttls; + rec->no_cap = src->no_cap; + *dest = (SERVER_CONNECT_REC *) rec; +} + +static void sig_server_reconnect_save_status(IRC_SERVER_CONNECT_REC *conn, + IRC_SERVER_REC *server) +{ + if (!IS_IRC_SERVER_CONNECT(conn) || !IS_IRC_SERVER(server) || + !server->connected) + return; + + g_free_not_null(conn->channels); + conn->channels = + irc_server_get_channels(server, settings_get_choice("rejoin_channels_on_reconnect")); + + g_free_not_null(conn->usermode); + conn->usermode = g_strdup(server->wanted_usermode); +} + +static void sig_connected(IRC_SERVER_REC *server) +{ + if (!IS_IRC_SERVER(server) || !server->connrec->reconnection) + return; + + if (server->connrec->away_reason != NULL) + irc_server_send_away(server, server->connrec->away_reason); +} + +static void event_nick_collision(IRC_SERVER_REC *server, const char *data) +{ + time_t new_connect; + + if (!IS_IRC_SERVER(server)) + return; + + /* after server kills us because of nick collision, we want to + connect back immediately. but no matter how hard they kill us, + don't connect to the server more than once in every 10 seconds. */ + + new_connect = server->connect_time+10 - + settings_get_time("server_reconnect_time")/1000; + if (server->connect_time > new_connect) + server->connect_time = new_connect; + + server->nick_collision = TRUE; +} + +static void event_kill(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + if (addr != NULL && !server->nick_collision) { + /* don't reconnect if we were killed by an oper (not server) */ + server->no_reconnect = TRUE; + } +} + +void irc_servers_reconnect_init(void) +{ + signal_add("server connect copy", (SIGNAL_FUNC) sig_server_connect_copy); + signal_add("server reconnect save status", (SIGNAL_FUNC) sig_server_reconnect_save_status); + signal_add("event connected", (SIGNAL_FUNC) sig_connected); + signal_add("event 436", (SIGNAL_FUNC) event_nick_collision); + signal_add("event kill", (SIGNAL_FUNC) event_kill); +} + +void irc_servers_reconnect_deinit(void) +{ + signal_remove("server connect copy", (SIGNAL_FUNC) sig_server_connect_copy); + signal_remove("server reconnect save status", (SIGNAL_FUNC) sig_server_reconnect_save_status); + signal_remove("event connected", (SIGNAL_FUNC) sig_connected); + signal_remove("event 436", (SIGNAL_FUNC) event_nick_collision); + signal_remove("event kill", (SIGNAL_FUNC) event_kill); +} |