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); } } }
static int server_reconnect_timeout(void) { SERVER_CONNECT_REC *conn; GSList *list, *tmp; time_t now; /* If 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 = list; tmp != NULL; tmp = tmp->next) { RECONNECT_REC *rec = tmp->data; if (g_slist_find(reconnects, rec) == NULL) continue; if (rec->next_connect <= now) { conn = rec->conn; server_reconnect_destroy(rec, FALSE); server_connect(conn); } } g_slist_free(list); return 1; }
static void reconnect_all(void) { GSList *list; SERVER_CONNECT_REC *conn; RECONNECT_REC *rec; /* first move reconnects to another list so if server_connect() fails and goes to reconnection list again, we won't get stuck here forever */ list = NULL; while (reconnects != NULL) { rec = reconnects->data; list = g_slist_append(list, rec->conn); server_connect_ref(rec->conn); server_reconnect_destroy(rec); } while (list != NULL) { conn = list->data; server_connect(conn); server_connect_unref(conn); list = g_slist_remove(list, conn); } }
static void update_reconnection(SERVER_CONNECT_REC *conn, SERVER_REC *server) { SERVER_CONNECT_REC *oldconn; RECONNECT_REC *recon; if (server != NULL) { oldconn = server->connrec; server_connect_ref(oldconn); reconnect_save_status(conn, server); } else { /* maybe we can reconnect some server from reconnection queue */ recon = find_reconnect_server(conn->chat_type, conn->address, conn->port); if (recon == NULL) return; oldconn = recon->conn; server_connect_ref(oldconn); server_reconnect_destroy(recon); conn->away_reason = g_strdup(oldconn->away_reason); conn->channels = g_strdup(oldconn->channels); } conn->reconnection = TRUE; if (conn->chatnet == NULL && oldconn->chatnet != NULL) conn->chatnet = g_strdup(oldconn->chatnet); server_connect_unref(oldconn); if (server != NULL) { signal_emit("command disconnect", 2, "* Changing server", server); } }
/* Try to reconnect immediately */ static void cmd_reconnect(const char *data, IRC_SERVER_REC *server) { IRC_SERVER_CONNECT_REC *conn; RECONNECT_REC *rec; char *str; int tag; if (*data == '\0') { /* reconnect back to same server */ if (server == NULL) cmd_return_error(CMDERR_NOT_CONNECTED); str = g_strdup_printf("%s %d %s %s", server->connrec->address, server->connrec->port, server->connrec->password, server->connrec->nick); signal_emit("command server", 2, str, server); g_free(str); return; } if (g_strncasecmp(data, "RECON-", 6) == 0) data += 6; tag = atoi(data); rec = tag <= 0 ? NULL : reconnect_find_tag(tag); if (rec == NULL) signal_emit("server reconnect not found", 1, data); else { conn = rec->conn; server_reconnect_destroy(rec, FALSE); irc_server_connect(conn); } }
static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto) { GSList *tmp, *next; for (tmp = reconnects; tmp != NULL; tmp = next) { RECONNECT_REC *rec = tmp->data; next = tmp->next; if (rec->conn->chat_type == proto->id) server_reconnect_destroy(rec); } }
void servers_reconnect_deinit(void) { g_source_remove(reconnect_timeout_tag); while (reconnects != NULL) server_reconnect_destroy(reconnects->data, TRUE); 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); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_unbind("rmreconns", (SIGNAL_FUNC) cmd_rmreconns); command_unbind("reconnect", (SIGNAL_FUNC) cmd_reconnect); command_unbind("disconnect", (SIGNAL_FUNC) cmd_disconnect); }
static void cmd_disconnect(const char *data, SERVER_REC *server) { RECONNECT_REC *rec; if (g_ascii_strncasecmp(data, "RECON-", 6) != 0) return; /* handle only reconnection removing */ rec = reconnect_find_tag(atoi(data+6)); if (rec == NULL) signal_emit("server reconnect not found", 1, data); else server_reconnect_destroy(rec); signal_stop(); }
static void cmd_disconnect(const char *data, SERVER_REC *server) { RECONNECT_REC *rec; int tag; if (g_strncasecmp(data, "RECON-", 6) != 0) return; /* handle only reconnection removing */ rec = sscanf(data+6, "%d", &tag) == 1 && tag > 0 ? reconnect_find_tag(tag) : NULL; if (rec == NULL) signal_emit("server reconnect not found", 1, data); else server_reconnect_destroy(rec, TRUE); }
static int server_reconnect_timeout(void) { SERVER_CONNECT_REC *conn; GSList *list, *tmp, *next; time_t now; now = time(NULL); /* timeout any connections that haven't gotten to connected-stage */ for (tmp = servers; tmp != NULL; tmp = next) { SERVER_REC *server = tmp->data; next = tmp->next; if (!server->connected && server->connect_time + connect_timeout < now && connect_timeout > 0) { server->connection_lost = TRUE; server_disconnect(server); } } /* If 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); for (tmp = list; tmp != NULL; tmp = tmp->next) { RECONNECT_REC *rec = tmp->data; if (g_slist_find(reconnects, rec) == NULL) continue; if (rec->next_connect <= now) { conn = rec->conn; server_connect_ref(conn); server_reconnect_destroy(rec); server_connect(conn); server_connect_unref(conn); } } g_slist_free(list); return 1; }
static int server_reconnect_timeout(void) { IRC_SERVER_CONNECT_REC *conn; GSList *tmp, *next; time_t now; now = time(NULL); for (tmp = reconnects; tmp != NULL; tmp = next) { RECONNECT_REC *rec = tmp->data; next = tmp->next; if (rec->next_connect <= now) { conn = rec->conn; server_reconnect_destroy(rec, FALSE); irc_server_connect(conn); } } return 1; }
/* SYNTAX: RMRECONNS */ static void cmd_rmreconns(void) { while (reconnects != NULL) server_reconnect_destroy(reconnects->data, TRUE); }
/* SYNTAX: RECONNECT <tag> [<quit message>] */ static void cmd_reconnect(const char *data, SERVER_REC *server) { SERVER_CONNECT_REC *conn; RECONNECT_REC *rec; char *tag, *msg; void *free_arg; int tagnum; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &tag, &msg)) return; if (*tag != '\0' && strcmp(tag, "*") != 0) server = server_find_tag(tag); if (server != NULL) { /* reconnect connected server */ conn = server_connect_copy_skeleton(server->connrec, TRUE); if (server->connected) reconnect_save_status(conn, server); msg = g_strconcat("* ", *msg == '\0' ? "Reconnecting" : msg, NULL); signal_emit("command disconnect", 2, msg, server); g_free(msg); conn->reconnection = TRUE; server_connect(conn); server_connect_unref(conn); cmd_params_free(free_arg); return; } if (g_ascii_strcasecmp(tag, "all") == 0) { /* reconnect all servers in reconnect queue */ reconnect_all(); cmd_params_free(free_arg); return; } if (*data == '\0') { /* reconnect to first server in reconnection list */ if (reconnects == NULL) cmd_param_error(CMDERR_NOT_CONNECTED); rec = reconnects->data; } else { if (g_ascii_strncasecmp(data, "RECON-", 6) == 0) data += 6; tagnum = atoi(tag); rec = tagnum <= 0 ? NULL : reconnect_find_tag(tagnum); } if (rec == NULL) { signal_emit("server reconnect not found", 1, data); } else { conn = rec->conn; server_connect_ref(conn); server_reconnect_destroy(rec); server_connect(conn); server_connect_unref(conn); } cmd_params_free(free_arg); }
/* SYNTAX: SERVER [-ircnet <ircnet>] [-host <hostname>] [+]<address>|<ircnet> [<port> [<password> [<nick>]]] */ static void cmd_server(const char *data, IRC_SERVER_REC *server, void *item) { GHashTable *optlist; IRC_SERVER_CONNECT_REC *conn; char *addr, *port, *channels, *away_reason, *usermode, *ircnet; void *free_arg; int no_old_server; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS, "connect", &optlist, &addr, &port)) return; if (*addr == '\0' || strcmp(addr, "+") == 0) cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); conn = server == NULL ? NULL : server->connrec; if (*addr != '+' && conn == NULL) { /* check if there's a server waiting for removal in reconnection queue.. */ RECONNECT_REC *rec; rec = find_reconnect_server(addr, atoi(port)); if (rec != NULL) { /* remove the reconnection.. */ conn = (IRC_SERVER_CONNECT_REC *) rec->conn; server_reconnect_destroy(rec, FALSE); } } no_old_server = server == NULL; ircnet = conn == NULL ? NULL : g_strdup(conn->chatnet); if (*addr == '+' || conn == NULL) { channels = away_reason = usermode = NULL; } else if (server != NULL) { channels = irc_server_get_channels((IRC_SERVER_REC *) server); if (*channels == '\0') g_free_and_null(channels); away_reason = !server->usermode_away ? NULL : g_strdup(server->away_reason); usermode = g_strdup(server->usermode); signal_emit("command disconnect", 3, "* Changing server", server, item); } else { channels = g_strdup(conn->channels); away_reason = g_strdup(conn->away_reason); usermode = g_strdup(conn->usermode); } server = IRC_SERVER(irc_connect_server(data)); if (*addr == '+' || server == NULL || (ircnet != NULL && server->connrec->chatnet != NULL && g_strcasecmp(ircnet, server->connrec->chatnet) != 0)) { g_free_not_null(channels); g_free_not_null(usermode); g_free_not_null(away_reason); } else if (server != NULL && conn != NULL) { server->connrec->reconnection = TRUE; server->connrec->channels = channels; server->connrec->usermode = usermode; server->connrec->away_reason = away_reason; if (no_old_server) server_connect_free(SERVER_CONNECT(conn)); } g_free_not_null(ircnet); cmd_params_free(free_arg); }