summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-02-19 02:15:15 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-02-19 02:15:15 +0000
commitb8375d471fe245f454b1cdf15f5379fe17a1c928 (patch)
tree336e8df6842147615f666a7dc3f24be97bec11cf /src/core
parentfa1715b5155c88749af8ecedfeffc97a4502fd9c (diff)
downloadirssi-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.c221
-rw-r--r--src/core/chat-protocols.c3
-rw-r--r--src/core/server-connect-rec.h1
-rw-r--r--src/core/servers-reconnect.c29
-rw-r--r--src/core/servers-reconnect.h1
-rw-r--r--src/core/servers-setup.c7
-rw-r--r--src/core/servers.c63
-rw-r--r--src/core/servers.h2
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);