1 /*
2 servers-reconnect.c : irssi
3
4 Copyright (C) 1999-2000 Timo Sirainen
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "module.h"
22 #include "commands.h"
23 #include "network.h"
24 #include "signals.h"
25
26 #include "modes.h"
27 #include "irc-servers.h"
28
29 #include "settings.h"
30
sig_server_connect_copy(SERVER_CONNECT_REC ** dest,IRC_SERVER_CONNECT_REC * src)31 static void sig_server_connect_copy(SERVER_CONNECT_REC **dest,
32 IRC_SERVER_CONNECT_REC *src)
33 {
34 IRC_SERVER_CONNECT_REC *rec;
35
36 g_return_if_fail(dest != NULL);
37 if (!IS_IRC_SERVER_CONNECT(src))
38 return;
39
40 rec = g_new0(IRC_SERVER_CONNECT_REC, 1);
41 rec->chat_type = IRC_PROTOCOL;
42 rec->max_cmds_at_once = src->max_cmds_at_once;
43 rec->cmd_queue_speed = src->cmd_queue_speed;
44 rec->max_query_chans = src->max_query_chans;
45 rec->max_kicks = src->max_kicks;
46 rec->max_modes = src->max_modes;
47 rec->max_msgs = src->max_msgs;
48 rec->max_whois = src->max_whois;
49 rec->usermode = g_strdup(src->usermode);
50 rec->alternate_nick = g_strdup(src->alternate_nick);
51 rec->sasl_mechanism = src->sasl_mechanism;
52 rec->sasl_username = g_strdup(src->sasl_username);
53 rec->sasl_password = g_strdup(src->sasl_password);
54 *dest = (SERVER_CONNECT_REC *) rec;
55 }
56
sig_server_reconnect_save_status(IRC_SERVER_CONNECT_REC * conn,IRC_SERVER_REC * server)57 static void sig_server_reconnect_save_status(IRC_SERVER_CONNECT_REC *conn,
58 IRC_SERVER_REC *server)
59 {
60 if (!IS_IRC_SERVER_CONNECT(conn) || !IS_IRC_SERVER(server) ||
61 !server->connected)
62 return;
63
64 g_free_not_null(conn->channels);
65 conn->channels = irc_server_get_channels(server);
66
67 g_free_not_null(conn->usermode);
68 conn->usermode = g_strdup(server->wanted_usermode);
69 }
70
sig_connected(IRC_SERVER_REC * server)71 static void sig_connected(IRC_SERVER_REC *server)
72 {
73 if (!IS_IRC_SERVER(server) || !server->connrec->reconnection)
74 return;
75
76 if (server->connrec->away_reason != NULL)
77 irc_server_send_away(server, server->connrec->away_reason);
78 }
79
event_nick_collision(IRC_SERVER_REC * server,const char * data)80 static void event_nick_collision(IRC_SERVER_REC *server, const char *data)
81 {
82 time_t new_connect;
83
84 if (!IS_IRC_SERVER(server))
85 return;
86
87 /* after server kills us because of nick collision, we want to
88 connect back immediately. but no matter how hard they kill us,
89 don't connect to the server more than once in every 10 seconds. */
90
91 new_connect = server->connect_time+10 -
92 settings_get_time("server_reconnect_time")/1000;
93 if (server->connect_time > new_connect)
94 server->connect_time = new_connect;
95
96 server->nick_collision = TRUE;
97 }
98
event_kill(IRC_SERVER_REC * server,const char * data,const char * nick,const char * addr)99 static void event_kill(IRC_SERVER_REC *server, const char *data,
100 const char *nick, const char *addr)
101 {
102 if (addr != NULL && !server->nick_collision) {
103 /* don't reconnect if we were killed by an oper (not server) */
104 server->no_reconnect = TRUE;
105 }
106 }
107
irc_servers_reconnect_init(void)108 void irc_servers_reconnect_init(void)
109 {
110 signal_add("server connect copy", (SIGNAL_FUNC) sig_server_connect_copy);
111 signal_add("server reconnect save status", (SIGNAL_FUNC) sig_server_reconnect_save_status);
112 signal_add("event connected", (SIGNAL_FUNC) sig_connected);
113 signal_add("event 436", (SIGNAL_FUNC) event_nick_collision);
114 signal_add("event kill", (SIGNAL_FUNC) event_kill);
115 }
116
irc_servers_reconnect_deinit(void)117 void irc_servers_reconnect_deinit(void)
118 {
119 signal_remove("server connect copy", (SIGNAL_FUNC) sig_server_connect_copy);
120 signal_remove("server reconnect save status", (SIGNAL_FUNC) sig_server_reconnect_save_status);
121 signal_remove("event connected", (SIGNAL_FUNC) sig_connected);
122 signal_remove("event 436", (SIGNAL_FUNC) event_nick_collision);
123 signal_remove("event kill", (SIGNAL_FUNC) event_kill);
124 }
125