/* SYNTAX: SERVER REMOVE <address> [<port>] [<network>] */ static void cmd_server_remove(const char *data) { SERVER_SETUP_REC *rec; char *addr, *port, *chatnet; void *free_arg; if (!cmd_get_params(data, &free_arg, 3, &addr, &port, &chatnet)) return; if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*port == '\0') { if (*chatnet == '\0') rec = server_setup_find(addr, -1, NULL); else rec = server_setup_find(addr, -1, chatnet); } else { if (*chatnet == '\0') rec = server_setup_find(addr, atoi(port), NULL); else rec = server_setup_find(addr, atoi(port), chatnet); } if (rec == NULL) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_NOT_FOUND, addr, port); else { server_setup_remove(rec); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_REMOVED, addr, port); } cmd_params_free(free_arg); }
/* Find matching server from setup. Ports must match or NULL is returned. */ SERVER_SETUP_REC *server_setup_find_port(const char *address, int port) { SERVER_SETUP_REC *rec; rec = server_setup_find(address, port, NULL); return rec == NULL || rec->port != port ? NULL : rec; }
static SETUP_SERVER_REC *setupserver_add_node(CONFIG_NODE *node) { SETUP_SERVER_REC *rec; char *server; int port; g_return_val_if_fail(node != NULL, NULL); server = config_node_get_str(node, "address", NULL); if (server == NULL) return NULL; port = config_node_get_int(node, "port", 6667); if (server_setup_find(server, port) != NULL) { /* already exists - don't let it get there twice or server reconnects will screw up! */ return NULL; } rec = g_new0(SETUP_SERVER_REC, 1); rec->ircnet = g_strdup(config_node_get_str(node, "ircnet", NULL)); rec->address = g_strdup(server); rec->password = g_strdup(config_node_get_str(node, "password", NULL)); rec->port = port; rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE); rec->max_cmds_at_once = config_node_get_int(node, "cmds_max_at_once", 0); rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0); rec->own_host = g_strdup(config_node_get_str(node, "own_host", 0)); setupservers = g_slist_append(setupservers, rec); return rec; }
static SERVER_CONNECT_REC * create_addr_conn(int chat_type, const char *address, int port, const char *chatnet, const char *password, const char *nick) { CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; SERVER_SETUP_REC *sserver; CHATNET_REC *chatnetrec; g_return_val_if_fail(address != NULL, NULL); sserver = server_setup_find(address, port, chatnet); if (sserver != NULL) { if (chat_type < 0) chat_type = sserver->chat_type; else if (chat_type != sserver->chat_type) sserver = NULL; } proto = chat_type >= 0 ? chat_protocol_find_id(chat_type) : chat_protocol_get_default(); conn = proto->create_server_connect(); server_connect_ref(conn); conn->chat_type = proto->id; if (chatnet != NULL && *chatnet != '\0') conn->chatnet = g_strdup(chatnet); /* fill in the defaults */ server_setup_fill(conn, address, port); /* fill the rest from chat network settings */ chatnetrec = chatnet != NULL ? chatnet_find(chatnet) : (sserver == NULL || sserver->chatnet == NULL ? NULL : chatnet_find(sserver->chatnet)); if (chatnetrec != NULL) server_setup_fill_chatnet(conn, chatnetrec); /* fill the information from setup */ if (sserver != NULL) server_setup_fill_server(conn, sserver); /* nick / password given in command line overrides all settings */ if (password && *password) { g_free_not_null(conn->password); conn->password = g_strdup(password); } if (nick && *nick) { g_free_not_null(conn->nick); conn->nick = g_strdup(nick); } return conn; }
static void sig_reconnect(SERVER_REC *server) { SERVER_CONNECT_REC *conn; SERVER_SETUP_REC *sserver; GSList *tmp; int found, through; time_t now; g_return_if_fail(IS_SERVER(server)); if (reconnect_time == -1 || !server_should_reconnect(server)) return; conn = server_connect_copy_skeleton(server->connrec); g_return_if_fail(conn != NULL); /* save the server status */ if (server->connected) { conn->reconnection = TRUE; g_free_not_null(conn->away_reason); conn->away_reason = !server->usermode_away ? NULL : g_strdup(server->away_reason); signal_emit("server reconnect save status", 2, conn, server); } sserver = server_setup_find(server->connrec->address, server->connrec->port); if (sserver != NULL) { /* save the last connection time/status */ sserver->last_connect = server->connect_time == 0 ? time(NULL) : server->connect_time; sserver->last_failed = !server->connected; if (server->banned) sserver->banned = TRUE; } if (sserver == NULL || conn->chatnet == NULL) { /* not in any chatnet, just reconnect back to same server */ conn->address = g_strdup(server->connrec->address); conn->port = server->connrec->port; conn->password = server->connrec->password == NULL ? NULL : g_strdup(server->connrec->password); if (server->connect_time != 0 && time(NULL)-server->connect_time > reconnect_time) { /* there's been enough time since last connection, reconnect back immediately */ server_connect(conn); } else { /* reconnect later.. */ server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) : server->connect_time) + reconnect_time); } return; } /* always try to first connect to the first on the list where we haven't got unsuccessful connection attempts for the last half an hour. */ now = time(NULL); for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { SERVER_SETUP_REC *rec = tmp->data; if (rec->chatnet != NULL && g_strcasecmp(conn->chatnet, rec->chatnet) == 0 && !rec->banned && (!rec->last_connect || !rec->last_failed || rec->last_connect < now-FAILED_RECONNECT_WAIT)) { if (rec == sserver) conn->port = server->connrec->port; sserver_connect(rec, conn); return; } } /* just try the next server in list */ found = through = FALSE; for (tmp = setupservers; tmp != NULL; ) { SERVER_SETUP_REC *rec = tmp->data; if (!found && g_strcasecmp(rec->address, server->connrec->address) == 0 && server->connrec->port == rec->port) found = TRUE; else if (found && !rec->banned && rec->chatnet != NULL && g_strcasecmp(conn->chatnet, rec->chatnet) == 0) { if (rec == sserver) conn->port = server->connrec->port; sserver_connect(rec, conn); break; } if (tmp->next != NULL) { tmp = tmp->next; continue; } if (through) { /* shouldn't happen unless there's no servers in this chatnet in setup.. */ server_connect_free(conn); break; } tmp = setupservers; found = through = TRUE; } }
static void sig_reconnect(SERVER_REC *server) { SERVER_CONNECT_REC *conn; SERVER_SETUP_REC *sserver; GSList *tmp; int use_next, through; time_t now; g_return_if_fail(IS_SERVER(server)); if (reconnect_time == -1 || !server_should_reconnect(server)) return; conn = server_connect_copy_skeleton(server->connrec, FALSE); g_return_if_fail(conn != NULL); /* save the server status */ if (server->connected) { conn->reconnection = TRUE; reconnect_save_status(conn, server); } sserver = server_setup_find(server->connrec->address, server->connrec->port, server->connrec->chatnet); if (sserver != NULL) { /* save the last connection time/status */ sserver->last_connect = server->connect_time == 0 ? time(NULL) : server->connect_time; sserver->last_failed = !server->connected; sserver->banned = server->banned; sserver->dns_error = server->dns_error; } if (sserver == NULL || conn->chatnet == NULL) { /* not in any chatnet, just reconnect back to same server */ conn->family = server->connrec->family; conn->address = g_strdup(server->connrec->address); conn->port = server->connrec->port; conn->password = g_strdup(server->connrec->password); server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) : server->connect_time) + reconnect_time); server_connect_unref(conn); return; } /* always try to first connect to the first on the list where we haven't got unsuccessful connection attempts for the past half an hour. */ now = time(NULL); for (tmp = setupservers; tmp != NULL; tmp = tmp->next) { SERVER_SETUP_REC *rec = tmp->data; if (sserver_connect_ok(rec, conn->chatnet) && (!rec->last_connect || !rec->last_failed || rec->last_connect < now-FAILED_RECONNECT_WAIT)) { if (rec == sserver) conn->port = server->connrec->port; sserver_connect(rec, conn); return; } } /* just try the next server in list */ use_next = through = FALSE; for (tmp = setupservers; tmp != NULL; ) { SERVER_SETUP_REC *rec = tmp->data; if (!use_next && server->connrec->port == rec->port && g_strcasecmp(rec->address, server->connrec->address) == 0) use_next = TRUE; else if (use_next && sserver_connect_ok(rec, conn->chatnet)) { if (rec == sserver) conn->port = server->connrec->port; sserver_connect(rec, conn); break; } if (tmp->next != NULL) { tmp = tmp->next; continue; } if (through) { /* shouldn't happen unless there's no servers in this chatnet in setup.. */ server_connect_unref(conn); break; } tmp = setupservers; use_next = through = TRUE; } }
static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) { SERVER_SETUP_REC *rec; CHATNET_REC *chatnetrec; char *server, *chatnet, *family; int port; g_return_val_if_fail(node != NULL, NULL); server = config_node_get_str(node, "address", NULL); if (server == NULL) return NULL; port = config_node_get_int(node, "port", 0); chatnet = config_node_get_str(node, "chatnet", NULL); if (server_setup_find(server, port, chatnet) != NULL) { return NULL; } rec = NULL; chatnetrec = chatnet == NULL ? NULL : chatnet_find(chatnet); if (chatnetrec == NULL && chatnet != NULL) { /* chat network not found, create it. */ chatnetrec = chat_protocol_get_default()->create_chatnet(); chatnetrec->chat_type = chat_protocol_get_default()->id; chatnetrec->name = g_strdup(chatnet); chatnet_create(chatnetrec); } family = config_node_get_str(node, "family", ""); rec = CHAT_PROTOCOL(chatnetrec)->create_server_setup(); rec->type = module_get_uniq_id("SERVER SETUP", 0); rec->chat_type = CHAT_PROTOCOL(chatnetrec)->id; rec->chatnet = chatnetrec == NULL ? NULL : g_strdup(chatnetrec->name); rec->family = g_ascii_strcasecmp(family, "inet6") == 0 ? AF_INET6 : (g_ascii_strcasecmp(family, "inet") == 0 ? AF_INET : 0); rec->address = g_strdup(server); rec->password = g_strdup(config_node_get_str(node, "password", NULL)); rec->use_ssl = config_node_get_bool(node, "use_ssl", FALSE); rec->ssl_cert = g_strdup(config_node_get_str(node, "ssl_cert", NULL)); rec->ssl_pkey = g_strdup(config_node_get_str(node, "ssl_pkey", NULL)); rec->ssl_verify = config_node_get_bool(node, "ssl_verify", FALSE); rec->ssl_cafile = g_strdup(config_node_get_str(node, "ssl_cafile", NULL)); rec->ssl_capath = g_strdup(config_node_get_str(node, "ssl_capath", NULL)); if (rec->ssl_cafile || rec->ssl_capath) rec->ssl_verify = TRUE; if (rec->ssl_cert != NULL || rec->ssl_verify) rec->use_ssl = TRUE; rec->port = port; rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE); rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE); rec->own_host = g_strdup(config_node_get_str(node, "own_host", NULL)); signal_emit("server setup read", 2, rec, node); setupservers = g_slist_append(setupservers, rec); return rec; }
static void cmd_server_add(const char *data) { GHashTable *optlist; SERVER_SETUP_REC *rec; char *addr, *portstr, *password, *value, *chatnet; void *free_arg; int port; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS, "server add", &optlist, &addr, &portstr, &password)) return; if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); port = *portstr == '\0' ? DEFAULT_SERVER_ADD_PORT : atoi(portstr); chatnet = g_hash_table_lookup(optlist, "network"); rec = server_setup_find(addr, port, chatnet); if (rec == NULL) { rec = create_server_setup(optlist); if (rec == NULL) { cmd_params_free(free_arg); return; } rec->address = g_strdup(addr); rec->port = port; } else { value = g_hash_table_lookup(optlist, "port"); if (value != NULL && *value != '\0') rec->port = atoi(value); if (*password != '\0') g_free_and_null(rec->password); if (g_hash_table_lookup(optlist, "host")) { g_free_and_null(rec->own_host); rec->own_ip4 = rec->own_ip6 = NULL; } } if (g_hash_table_lookup(optlist, "6")) rec->family = AF_INET6; else if (g_hash_table_lookup(optlist, "4")) rec->family = AF_INET; if (g_hash_table_lookup(optlist, "ssl")) rec->use_ssl = TRUE; value = g_hash_table_lookup(optlist, "ssl_cert"); if (value != NULL && *value != '\0') rec->ssl_cert = g_strdup(value); value = g_hash_table_lookup(optlist, "ssl_pkey"); if (value != NULL && *value != '\0') rec->ssl_pkey = g_strdup(value); if (g_hash_table_lookup(optlist, "ssl_verify")) rec->ssl_verify = TRUE; value = g_hash_table_lookup(optlist, "ssl_cafile"); if (value != NULL && *value != '\0') rec->ssl_cafile = g_strdup(value); value = g_hash_table_lookup(optlist, "ssl_capath"); if (value != NULL && *value != '\0') rec->ssl_capath = g_strdup(value); if ((rec->ssl_cafile != NULL && rec->ssl_cafile[0] != '\0') || (rec->ssl_capath != NULL && rec->ssl_capath[0] != '\0')) rec->ssl_verify = TRUE; if ((rec->ssl_cert != NULL && rec->ssl_cert[0] != '\0') || rec->ssl_verify == TRUE) rec->use_ssl = TRUE; if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE; if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE; if (g_hash_table_lookup(optlist, "noproxy")) rec->no_proxy = TRUE; if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password); value = g_hash_table_lookup(optlist, "host"); if (value != NULL && *value != '\0') { rec->own_host = g_strdup(value); rec->own_ip4 = rec->own_ip6 = NULL; } signal_emit("server add fill", 2, rec, optlist); server_setup_add(rec); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_ADDED, addr, port); cmd_params_free(free_arg); }
/* Create server connection record. `address' is required, rest can be NULL */ static IRC_SERVER_CONNECT_REC * create_addr_conn(const char *address, int port, const char *password, const char *nick) { IRC_SERVER_CONNECT_REC *conn; SETUP_SERVER_REC *sserver; IRCNET_REC *ircnet; g_return_val_if_fail(address != NULL, NULL); conn = g_new0(IRC_SERVER_CONNECT_REC, 1); conn->address = g_strdup(address); conn->port = port > 0 ? port : 6667; if (password && *password) conn->password = g_strdup(password); if (nick && *nick) conn->nick = g_strdup(nick); if (!conn->nick) conn->nick = g_strdup(settings_get_str("default_nick")); conn->alternate_nick = g_strdup(settings_get_str("alternate_nick")); conn->username = g_strdup(settings_get_str("user_name")); conn->realname = g_strdup(settings_get_str("real_name")); /* proxy settings */ if (settings_get_bool("use_ircproxy")) { conn->proxy = g_strdup(settings_get_str("proxy_address")); conn->proxy_port = settings_get_int("proxy_port"); conn->proxy_string = g_strdup(settings_get_str("proxy_string")); } /* source IP */ get_source_host_ip(); if (source_host_ok) { conn->own_ip = g_new(IPADDR, 1); memcpy(conn->own_ip, source_host_ip, sizeof(IPADDR)); } /* fill the information from setup */ sserver = server_setup_find(address, -1); if (sserver == NULL) return conn; server_setup_fill_conn(conn, sserver); /* fill the rest from IRC network settings */ ircnet = sserver->ircnet == NULL ? NULL : ircnet_find(sserver->ircnet); if (ircnet == NULL) return conn; if (ircnet->nick && !(nick && *nick)) { g_free(conn->nick); conn->nick = g_strdup(ircnet->nick);; } if (ircnet->username) { g_free(conn->username); conn->username = g_strdup(ircnet->username);; } if (ircnet->realname) { g_free(conn->realname); conn->realname = g_strdup(ircnet->realname);; } if (ircnet->max_kicks > 0) conn->max_kicks = ircnet->max_kicks; if (ircnet->max_msgs > 0) conn->max_msgs = ircnet->max_msgs; if (ircnet->max_modes > 0) conn->max_modes = ircnet->max_modes; if (ircnet->max_whois > 0) conn->max_whois = ircnet->max_whois; if (ircnet->max_cmds_at_once > 0 && sserver->max_cmds_at_once <= 0) conn->max_cmds_at_once = ircnet->max_cmds_at_once; if (ircnet->cmd_queue_speed > 0 && sserver->cmd_queue_speed <= 0) conn->cmd_queue_speed = ircnet->cmd_queue_speed; if (sserver->own_host == NULL && ircnet->own_host != NULL) conn_set_ip(conn, &ircnet->own_ip, ircnet->own_host); return conn; }