diff options
author | Timo Sirainen <cras@irssi.org> | 2001-02-19 02:15:15 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2001-02-19 02:15:15 +0000 |
commit | b8375d471fe245f454b1cdf15f5379fe17a1c928 (patch) | |
tree | 336e8df6842147615f666a7dc3f24be97bec11cf /src/core | |
parent | fa1715b5155c88749af8ecedfeffc97a4502fd9c (diff) | |
download | irssi-b8375d471fe245f454b1cdf15f5379fe17a1c928.zip |
Connection updates: moved /SERVER and /CONNECT to core from irc.
Several other related multiprotocol updates.
Removed /SILCSERVER from SILC, /CONNECT and /SERVER should work
properly now. Rejoining channels after reconnection works.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1245 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/chat-commands.c | 221 | ||||
-rw-r--r-- | src/core/chat-protocols.c | 3 | ||||
-rw-r--r-- | src/core/server-connect-rec.h | 1 | ||||
-rw-r--r-- | src/core/servers-reconnect.c | 29 | ||||
-rw-r--r-- | src/core/servers-reconnect.h | 1 | ||||
-rw-r--r-- | src/core/servers-setup.c | 7 | ||||
-rw-r--r-- | src/core/servers.c | 63 | ||||
-rw-r--r-- | src/core/servers.h | 2 |
8 files changed, 247 insertions, 80 deletions
diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 22dc9e4f..a22e24d2 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -19,14 +19,223 @@ */ #include "module.h" +#include "network.h" #include "signals.h" #include "commands.h" #include "special-vars.h" +#include "settings.h" -#include "servers.h" #include "chat-protocols.h" +#include "servers.h" +#include "servers-setup.h" +#include "servers-reconnect.h" #include "window-item-def.h" +static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr) +{ + CHAT_PROTOCOL_REC *proto; + SERVER_CONNECT_REC *conn; + GHashTable *optlist; + char *addr, *portstr, *password, *nick, *chatnet, *host; + void *free_arg; + + g_return_val_if_fail(data != NULL, NULL); + + if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_OPTIONS, + "connect", &optlist, &addr, &portstr, + &password, &nick)) + return NULL; + if (plus_addr != NULL) *plus_addr = *addr == '+'; + if (*addr == '+') addr++; + if (*addr == '\0') { + signal_emit("error command", 1, + GINT_TO_POINTER(CMDERR_NOT_ENOUGH_PARAMS)); + cmd_params_free(free_arg); + return NULL; + } + + if (strcmp(password, "-") == 0) + *password = '\0'; + + /* check if -<chatnet> option is used to specify chat protocol */ + proto = chat_protocol_find_net(optlist); + + /* connect to server */ + conn = server_create_conn(proto != NULL ? proto->id : -1, + addr, atoi(portstr), password, nick); + if (proto == NULL) + proto = chat_protocol_find_id(conn->chat_type); + + if (g_hash_table_lookup(optlist, "6") != NULL) + conn->family = AF_INET6; + else if (g_hash_table_lookup(optlist, "4") != NULL) + conn->family = AF_INET; + + chatnet = g_hash_table_lookup(optlist, proto->chatnet); + if (chatnet != NULL) { + g_free_not_null(conn->chatnet); + conn->chatnet = g_strdup(chatnet); + } + + host = g_hash_table_lookup(optlist, "host"); + if (host != NULL && *host != '\0') { + IPADDR ip; + + if (net_gethostbyname(host, &ip, conn->family) == 0) { + if (conn->own_ip == NULL) + conn->own_ip = g_new(IPADDR, 1); + memcpy(conn->own_ip, &ip, sizeof(IPADDR)); + } + } + + cmd_params_free(free_arg); + return conn; +} + +/* SYNTAX: CONNECT [-4 | -6] [-ircnet <ircnet>] [-host <hostname>] + <address>|<chatnet> [<port> [<password> [<nick>]]] */ +static void cmd_connect(const char *data) +{ + SERVER_CONNECT_REC *conn; + + conn = get_server_connect(data, NULL); + if (conn != NULL) + CHAT_PROTOCOL(conn)->server_connect(conn); +} + +static RECONNECT_REC *find_reconnect_server(int chat_type, + const char *addr, int port) +{ + RECONNECT_REC *match, *last_proto_match; + GSList *tmp; + int count; + + g_return_val_if_fail(addr != NULL, NULL); + + /* check if there's a reconnection to the same host and maybe even + the same port */ + match = last_proto_match = NULL; count = 0; + for (tmp = reconnects; tmp != NULL; tmp = tmp->next) { + RECONNECT_REC *rec = tmp->data; + + if (rec->conn->chat_type == chat_type) { + count++; last_proto_match = rec; + if (g_strcasecmp(rec->conn->address, addr) == 0) { + if (rec->conn->port == port) + return rec; + match = rec; + } + } + } + + if (count == 1) { + /* only one reconnection with wanted protocol, + we probably want to use it */ + return last_proto_match; + } + + return match; +} + +static void update_reconnection(SERVER_CONNECT_REC *conn, SERVER_REC *server) +{ + SERVER_CONNECT_REC *oldconn; + RECONNECT_REC *recon; + + conn->reconnection = TRUE; + + if (server != NULL) { + oldconn = server->connrec; + 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_reconnect_destroy(recon, FALSE); + + conn->away_reason = g_strdup(oldconn->away_reason); + conn->channels = g_strdup(oldconn->channels); + } + + if (conn->chatnet == NULL && oldconn->chatnet != NULL) + conn->chatnet = g_strdup(oldconn->chatnet); + + if (server != NULL) { + signal_emit("command disconnect", 2, + "* Changing server", server); + } else { + server_connect_free(oldconn); + } +} + +/* SYNTAX: SERVER [-4 | -6] [-ircnet <ircnet>] [-host <hostname>] + [+]<address>|<chatnet> [<port> [<password> [<nick>]]] */ +static void cmd_server(const char *data, SERVER_REC *server) +{ + SERVER_CONNECT_REC *conn; + int plus_addr; + + g_return_if_fail(data != NULL); + + /* create connection record */ + conn = get_server_connect(data, &plus_addr); + if (conn != NULL) { + if (!plus_addr) + update_reconnection(conn, server); + CHAT_PROTOCOL(conn)->server_connect(conn); + } +} + +/* SYNTAX: DISCONNECT *|<tag> [<message>] */ +static void cmd_disconnect(const char *data, SERVER_REC *server) +{ + char *tag, *msg; + void *free_arg; + + g_return_if_fail(data != NULL); + + 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) cmd_param_error(CMDERR_NOT_CONNECTED); + + if (*msg == '\0') msg = (char *) settings_get_str("quit_message"); + signal_emit("server quit", 2, server, msg); + + cmd_params_free(free_arg); + server_disconnect(server); +} + +/* SYNTAX: QUIT [<message>] */ +static void cmd_quit(const char *data) +{ + GSList *tmp, *next; + const char *quitmsg; + char *str; + + g_return_if_fail(data != NULL); + + quitmsg = *data != '\0' ? data : + settings_get_str("quit_message"); + + /* disconnect from every server */ + for (tmp = servers; tmp != NULL; tmp = next) { + next = tmp->next; + + str = g_strdup_printf("* %s", quitmsg); + cmd_disconnect(str, tmp->data); + g_free(str); + } + + signal_emit("gui exit", 0); +} + /* SYNTAX: JOIN [-invite] [-<server tag>] <channels> [<keys>] */ static void cmd_join(const char *data, SERVER_REC *server) { @@ -101,13 +310,23 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) void chat_commands_init(void) { + command_bind("server", NULL, (SIGNAL_FUNC) cmd_server); + command_bind("connect", NULL, (SIGNAL_FUNC) cmd_connect); + command_bind("disconnect", NULL, (SIGNAL_FUNC) cmd_disconnect); + command_bind("quit", NULL, (SIGNAL_FUNC) cmd_quit); command_bind("join", NULL, (SIGNAL_FUNC) cmd_join); command_bind("msg", NULL, (SIGNAL_FUNC) cmd_msg); + + command_set_options("connect", "4 6 +host"); command_set_options("join", "invite"); } void chat_commands_deinit(void) { + command_unbind("server", (SIGNAL_FUNC) cmd_server); + command_unbind("connect", (SIGNAL_FUNC) cmd_connect); + command_unbind("disconnect", (SIGNAL_FUNC) cmd_disconnect); + command_unbind("quit", (SIGNAL_FUNC) cmd_quit); command_unbind("join", (SIGNAL_FUNC) cmd_join); command_unbind("msg", (SIGNAL_FUNC) cmd_msg); } diff --git a/src/core/chat-protocols.c b/src/core/chat-protocols.c index bb53829a..88199656 100644 --- a/src/core/chat-protocols.c +++ b/src/core/chat-protocols.c @@ -91,7 +91,8 @@ CHAT_PROTOCOL_REC *chat_protocol_find_net(GHashTable *optlist) for (tmp = chat_protocols; tmp != NULL; tmp = tmp->next) { CHAT_PROTOCOL_REC *rec = tmp->data; - if (g_hash_table_lookup(optlist, rec->chatnet) != NULL) + if (rec->chatnet != NULL && + g_hash_table_lookup(optlist, rec->chatnet) != NULL) return rec; } diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h index 6378fd83..90b2ed7c 100644 --- a/src/core/server-connect-rec.h +++ b/src/core/server-connect-rec.h @@ -24,4 +24,3 @@ char *realname; unsigned int reconnection:1; /* we're trying to reconnect */ char *channels; char *away_reason; -char *usermode; diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 808dd803..756a14a6 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -23,6 +23,7 @@ #include "network.h" #include "signals.h" +#include "chat-protocols.h" #include "servers.h" #include "servers-setup.h" #include "servers-reconnect.h" @@ -34,6 +35,15 @@ static int last_reconnect_tag; static int reconnect_timeout_tag; static int reconnect_time; +void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server) +{ + 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); +} + static void server_reconnect_add(SERVER_CONNECT_REC *conn, time_t next_connect) { @@ -83,7 +93,7 @@ static int server_reconnect_timeout(void) if (rec->next_connect <= now) { conn = rec->conn; server_reconnect_destroy(rec, FALSE); - server_connect(conn); + CHAT_PROTOCOL(conn)->server_connect(conn); } } @@ -102,7 +112,7 @@ static void sserver_connect(SERVER_SETUP_REC *rec, SERVER_CONNECT_REC *conn) server_reconnect_add(conn, rec->last_connect+reconnect_time); } else { /* connect to server.. */ - server_connect(conn); + CHAT_PROTOCOL(conn)->server_connect(conn); } } @@ -161,11 +171,7 @@ static void sig_reconnect(SERVER_REC *server) 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); + reconnect_save_status(conn, server); } sserver = server_setup_find(server->connrec->address, @@ -190,7 +196,7 @@ static void sig_reconnect(SERVER_REC *server) time(NULL)-server->connect_time > reconnect_time) { /* there's been enough time since last connection, reconnect back immediately */ - server_connect(conn); + CHAT_PROTOCOL(conn)->server_connect(conn); } else { /* reconnect later.. */ server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) : @@ -282,7 +288,6 @@ static RECONNECT_REC *reconnect_find_tag(int tag) return NULL; } -/* Try to reconnect immediately */ /* SYNTAX: RECONNECT <tag> */ static void cmd_reconnect(const char *data, SERVER_REC *server) { @@ -294,7 +299,9 @@ static void cmd_reconnect(const char *data, SERVER_REC *server) if (*data == '\0' && server != NULL) { /* reconnect back to same server */ str = g_strdup_printf("%s %d %s %s", server->connrec->address, - server->connrec->port, server->connrec->password, + server->connrec->port, + server->connrec->password == NULL ? "-" : + server->connrec->password, server->connrec->nick); signal_emit("command server", 2, str, server); g_free(str); @@ -321,7 +328,7 @@ static void cmd_reconnect(const char *data, SERVER_REC *server) conn = rec->conn; server_reconnect_destroy(rec, FALSE); - server_connect(conn); + CHAT_PROTOCOL(conn)->server_connect(conn); } static void cmd_disconnect(const char *data, SERVER_REC *server) diff --git a/src/core/servers-reconnect.h b/src/core/servers-reconnect.h index 50bcfc06..b51486f6 100644 --- a/src/core/servers-reconnect.h +++ b/src/core/servers-reconnect.h @@ -14,6 +14,7 @@ typedef struct { extern GSList *reconnects; +void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server); void server_reconnect_destroy(RECONNECT_REC *rec, int free_conn); void servers_reconnect_init(void); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 90fb3c51..cc0e83ba 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -176,7 +176,12 @@ create_addr_conn(int chat_type, const char *address, int port, g_return_val_if_fail(address != NULL, NULL); sserver = server_setup_find(address, port); - if (sserver != NULL) chat_type = sserver->chat_type; + 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(); diff --git a/src/core/servers.c b/src/core/servers.c index a4e0966d..4b190267 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -26,9 +26,7 @@ #include "net-sendbuffer.h" #include "misc.h" #include "rawlog.h" -#include "settings.h" -#include "chat-protocols.h" #include "servers.h" #include "servers-reconnect.h" #include "servers-redirect.h" @@ -278,14 +276,6 @@ int server_start_connect(SERVER_REC *server) return TRUE; } -/* Connect to server */ -SERVER_REC *server_connect(SERVER_CONNECT_REC *conn) -{ - g_return_val_if_fail(IS_SERVER_CONNECT(conn), NULL); - - return CHAT_PROTOCOL(conn)->server_connect(conn); -} - static int server_remove_channels(SERVER_REC *server) { GSList *tmp; @@ -421,7 +411,6 @@ void server_connect_free(SERVER_CONNECT_REC *conn) g_free_not_null(conn->channels); g_free_not_null(conn->away_reason); - g_free_not_null(conn->usermode); g_free(conn); } @@ -465,52 +454,6 @@ SERVER_REC *cmd_options_get_server(const char *cmd, return server; } -/* SYNTAX: DISCONNECT *|<tag> [<message>] */ -static void cmd_disconnect(const char *data, SERVER_REC *server) -{ - char *tag, *msg; - void *free_arg; - - g_return_if_fail(data != NULL); - - 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) cmd_param_error(CMDERR_NOT_CONNECTED); - - if (*msg == '\0') msg = (char *) settings_get_str("quit_message"); - signal_emit("server quit", 2, server, msg); - - cmd_params_free(free_arg); - server_disconnect(server); -} - -/* SYNTAX: QUIT [<message>] */ -static void cmd_quit(const char *data) -{ - GSList *tmp, *next; - const char *quitmsg; - char *str; - - g_return_if_fail(data != NULL); - - quitmsg = *data != '\0' ? data : - settings_get_str("quit_message"); - - /* disconnect from every server */ - for (tmp = servers; tmp != NULL; tmp = next) { - next = tmp->next; - - str = g_strdup_printf("* %s", quitmsg); - cmd_disconnect(str, tmp->data); - g_free(str); - } - - signal_emit("gui exit", 0); -} - void servers_init(void) { lookup_servers = servers = NULL; @@ -518,16 +461,10 @@ void servers_init(void) servers_reconnect_init(); servers_redirect_init(); servers_setup_init(); - - command_bind("disconnect", NULL, (SIGNAL_FUNC) cmd_disconnect); - command_bind("quit", NULL, (SIGNAL_FUNC) cmd_quit); } void servers_deinit(void) { - command_unbind("disconnect", (SIGNAL_FUNC) cmd_disconnect); - command_unbind("quit", (SIGNAL_FUNC) cmd_quit); - while (servers != NULL) server_disconnect(servers->data); while (lookup_servers != NULL) diff --git a/src/core/servers.h b/src/core/servers.h index 4ed9a34b..7a88af2c 100644 --- a/src/core/servers.h +++ b/src/core/servers.h @@ -33,8 +33,6 @@ extern GSList *servers, *lookup_servers; void servers_init(void); void servers_deinit(void); -/* Connect to server */ -SERVER_REC *server_connect(SERVER_CONNECT_REC *conn); /* Disconnect from server */ void server_disconnect(SERVER_REC *server); |