diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index cf85c103..3094c5bd 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -96,7 +96,7 @@ static void cmd_server_add(const char *data) if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); port = *portstr == '\0' ? 6667 : atoi(portstr); - rec = server_setup_find(addr, port); + rec = server_setup_find_port(addr, port); if (rec == NULL) { rec = g_new0(SETUP_SERVER_REC, 1); rec->address = g_strdup(addr); @@ -148,7 +148,7 @@ static void cmd_server_remove(const char *data) if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); port = *portstr == '\0' ? -1 : atoi(portstr); - rec = server_setup_find(addr, port); + rec = server_setup_find_port(addr, port); if (rec == NULL) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_NOT_FOUND, addr, port); else { diff --git a/src/irc/core/irc-core.c b/src/irc/core/irc-core.c index c028787c..d54db954 100644 --- a/src/irc/core/irc-core.c +++ b/src/irc/core/irc-core.c @@ -69,11 +69,11 @@ void irc_core_deinit(void) ignore_deinit(); netsplit_deinit(); lag_deinit(); - irc_irc_deinit(); irc_commands_deinit(); ctcp_deinit(); query_deinit(); channels_deinit(); + irc_irc_deinit(); irc_servers_deinit(); } diff --git a/src/irc/core/irc-server.c b/src/irc/core/irc-server.c index a0b4b046..6c8efd98 100644 --- a/src/irc/core/irc-server.c +++ b/src/irc/core/irc-server.c @@ -495,4 +495,6 @@ void irc_servers_deinit(void) ircnets_setup_deinit(); servers_idle_deinit(); servers_reconnect_deinit(); + + module_uniq_destroy("IRC SERVER"); } diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 692f5346..681510e4 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -408,5 +408,4 @@ void irc_irc_deinit(void) signal_remove("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line); module_uniq_destroy("IRC"); - module_uniq_destroy("IRC SERVER"); } diff --git a/src/irc/core/server-reconnect.c b/src/irc/core/server-reconnect.c index 137e4224..a6ae23cb 100644 --- a/src/irc/core/server-reconnect.c +++ b/src/irc/core/server-reconnect.c @@ -64,14 +64,20 @@ static void server_reconnect_destroy(RECONNECT_REC *rec, int free_conn) static int server_reconnect_timeout(void) { IRC_SERVER_CONNECT_REC *conn; - GSList *tmp, *next; + GSList *list, *tmp; time_t now; + /* If irc_server_connect() removes the next reconnection in queue, + we're screwed. I don't think this should happen anymore, but just + to be sure we don't crash, do this safely. */ + list = g_slist_copy(reconnects); now = time(NULL); - for (tmp = reconnects; tmp != NULL; tmp = next) { + for (tmp = list; tmp != NULL; tmp = tmp->next) { RECONNECT_REC *rec = tmp->data; - next = tmp->next; + if (g_slist_find(reconnects, rec) == NULL) + continue; + if (rec->next_connect <= now) { conn = rec->conn; server_reconnect_destroy(rec, FALSE); @@ -79,6 +85,7 @@ static int server_reconnect_timeout(void) } } + g_slist_free(list); return 1; } @@ -152,11 +159,8 @@ static void sig_reconnect(IRC_SERVER_REC *server) conn->usermode = g_strdup(server->usermode); } - sserver = server_setup_find(server->connrec->address, server->connrec->port); - if (sserver == NULL) { - /* port specific record not found, try without port.. */ - sserver = server_setup_find(server->connrec->address, -1); - } + sserver = server_setup_find(server->connrec->address, + server->connrec->port); if (sserver != NULL) { /* save the last connection time/status */ @@ -233,33 +237,6 @@ static void sig_reconnect(IRC_SERVER_REC *server) } } -static void sig_server_looking(IRC_SERVER_REC *server) -{ - IRC_SERVER_CONNECT_REC *conn; - GSList *tmp, *next; - - g_return_if_fail(server != NULL); - if (!irc_server_check(server)) - return; - - /* trying to connect somewhere, check if there's anything in reconnect - queue waiting to connect to same ircnet or same server+port.. */ - conn = server->connrec; - for (tmp = reconnects; tmp != NULL; tmp = next) { - RECONNECT_REC *rec = tmp->data; - - next = tmp->next; - if (g_strcasecmp(conn->address, rec->conn->address) == 0 && - conn->port == rec->conn->port) { - server_reconnect_destroy(rec, TRUE); - } - else if (conn->ircnet != NULL && rec->conn->ircnet != NULL && - g_strcasecmp(conn->ircnet, rec->conn->ircnet) == 0) { - server_reconnect_destroy(rec, TRUE); - } - } -} - /* Remove all servers from reconnect list */ /* SYNTAX: RMRECONNS */ static void cmd_rmreconns(void) @@ -388,7 +365,6 @@ void servers_reconnect_init(void) reconnect_timeout_tag = g_timeout_add(1000, (GSourceFunc) server_reconnect_timeout, NULL); read_settings(); - signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server connect failed", (SIGNAL_FUNC) sig_reconnect); signal_add("server disconnected", (SIGNAL_FUNC) sig_reconnect); signal_add("event connected", (SIGNAL_FUNC) sig_connected); @@ -405,7 +381,6 @@ void servers_reconnect_deinit(void) while (reconnects != NULL) server_reconnect_destroy(reconnects->data, TRUE); - signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking); signal_remove("server connect failed", (SIGNAL_FUNC) sig_reconnect); signal_remove("server disconnected", (SIGNAL_FUNC) sig_reconnect); signal_remove("event connected", (SIGNAL_FUNC) sig_connected); diff --git a/src/irc/core/server-setup.c b/src/irc/core/server-setup.c index 7b52540d..299e703e 100644 --- a/src/irc/core/server-setup.c +++ b/src/irc/core/server-setup.c @@ -130,7 +130,7 @@ create_addr_conn(const char *address, int port, const } /* fill the information from setup */ - sserver = server_setup_find(address, -1); + sserver = server_setup_find(conn->address, conn->port); if (sserver == NULL) return conn; if (sserver->port > 0) conn->port = sserver->port; @@ -223,21 +223,36 @@ irc_server_create_conn(const char *dest, int port, return create_addr_conn(dest, port, password, nick); } -/* Find matching server from setup. Set port to -1 if you don't care about it */ +/* Find matching server from setup. Try to find record with a same port, + but fallback to any server with the same address. */ SETUP_SERVER_REC *server_setup_find(const char *address, int port) { + SETUP_SERVER_REC *server; GSList *tmp; g_return_val_if_fail(address != NULL, NULL); + server = NULL; for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { SETUP_SERVER_REC *rec = tmp->data; - if (g_strcasecmp(rec->address, address) == 0 && - (port == -1 || rec->port == port)) return rec; + if (g_strcasecmp(rec->address, address) == 0) { + server = rec; + if (rec->port == port) + break; + } } - return NULL; + return server; +} + +/* Find matching server from setup. Ports must match or NULL is returned. */ +SETUP_SERVER_REC *server_setup_find_port(const char *address, int port) +{ + SETUP_SERVER_REC *rec; + + rec = server_setup_find(address, port); + return rec == NULL || rec->port != port ? NULL : rec; } static void init_userinfo(void) @@ -367,7 +382,7 @@ static SETUP_SERVER_REC *setupserver_add_node(CONFIG_NODE *node) if (server == NULL) return NULL; port = config_node_get_int(node, "port", 6667); - if (server_setup_find(server, port) != NULL) { + if (server_setup_find_port(server, port) != NULL) { /* already exists - don't let it get there twice or server reconnects will screw up! */ return NULL; diff --git a/src/irc/core/server-setup.h b/src/irc/core/server-setup.h index 5bd1587f..8803669c 100644 --- a/src/irc/core/server-setup.h +++ b/src/irc/core/server-setup.h @@ -38,8 +38,11 @@ void server_setup_fill_conn(IRC_SERVER_CONNECT_REC *conn, SETUP_SERVER_REC *sser void server_setup_add(SETUP_SERVER_REC *rec); void server_setup_remove(SETUP_SERVER_REC *rec); -/* Find matching server from setup. Set port to -1 if you don't care about it */ +/* Find matching server from setup. Try to find record with a same port, + but fallback to any server with the same address. */ SETUP_SERVER_REC *server_setup_find(const char *address, int port); +/* Find matching server from setup. Ports must match or NULL is returned. */ +SETUP_SERVER_REC *server_setup_find_port(const char *address, int port); void servers_setup_init(void); void servers_setup_deinit(void);