summaryrefslogtreecommitdiff
path: root/src/plugins/relay
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2012-12-24 17:31:33 +0100
committerSebastien Helleu <flashcode@flashtux.org>2012-12-24 17:31:33 +0100
commitcf76379aa96a4df0677f1d1485d38225a3d79c95 (patch)
treebccfa7978a2786bd337fdc0b9aaf654177837956 /src/plugins/relay
parent2e48874ce04d2adb537dec3c4725638c089404c5 (diff)
downloadweechat-cf76379aa96a4df0677f1d1485d38225a3d79c95.zip
relay: add backlog, options and server capability "server-time" for irc protocol (task #12076)
New options: - relay.irc.backlog_max_minutes - relay.irc.backlog_max_number - relay.irc.backlog_since_last_disconnect - relay.irc.backlog_tags - relay.irc.backlog_time_format
Diffstat (limited to 'src/plugins/relay')
-rw-r--r--src/plugins/relay/irc/relay-irc.c597
-rw-r--r--src/plugins/relay/irc/relay-irc.h22
-rw-r--r--src/plugins/relay/relay-client.c16
-rw-r--r--src/plugins/relay/relay-client.h1
-rw-r--r--src/plugins/relay/relay-config.c135
-rw-r--r--src/plugins/relay/relay-config.h8
-rw-r--r--src/plugins/relay/relay-server.c73
-rw-r--r--src/plugins/relay/relay-server.h3
-rw-r--r--src/plugins/relay/relay-upgrade.c38
-rw-r--r--src/plugins/relay/relay-upgrade.h1
-rw-r--r--src/plugins/relay/relay.c2
11 files changed, 865 insertions, 31 deletions
diff --git a/src/plugins/relay/irc/relay-irc.c b/src/plugins/relay/irc/relay-irc.c
index e94724ebd..ebe512801 100644
--- a/src/plugins/relay/irc/relay-irc.c
+++ b/src/plugins/relay/irc/relay-irc.c
@@ -35,10 +35,15 @@
#include "../relay-client.h"
#include "../relay-config.h"
#include "../relay-raw.h"
+#include "../relay-server.h"
char *relay_irc_relay_commands[] = { "privmsg", "notice", NULL };
-char *relay_irc_ignore_commands[] = { "pong", "quit", NULL };
+char *relay_irc_ignore_commands[] = { "cap", "pong", "quit", NULL };
+char *relay_irc_backlog_commands_tags[RELAY_IRC_NUM_CMD] =
+{ "irc_join", "irc_part", "irc_quit", "irc_nick", "irc_privmsg" };
+char *relay_irc_server_capabilities[RELAY_IRC_NUM_CAPAB] =
+{ "server-time" };
/*
@@ -94,6 +99,49 @@ relay_irc_command_ignored (const char *irc_command)
}
/*
+ * Searches for a tag of a command (in backlog).
+ *
+ * Returns index of tag in enum t_relay_irc_command, -1 if tag is not found.
+ */
+
+int
+relay_irc_search_backlog_commands_tags (const char *tag)
+{
+ int i;
+
+ for (i = 0; i < RELAY_IRC_NUM_CMD; i++)
+ {
+ if (strcmp (relay_irc_backlog_commands_tags[i], tag) == 0)
+ return i;
+ }
+
+ /* tag not found */
+ return -1;
+}
+
+/*
+ * Searches for a server capability.
+ *
+ * Returns index of server capability in enum t_relay_irc_server_capab, -1 if
+ * server capability is not found.
+ */
+
+int
+relay_irc_search_server_capability (const char *capability)
+{
+ int i;
+
+ for (i = 0; i < RELAY_IRC_NUM_CAPAB; i++)
+ {
+ if (strcmp (relay_irc_server_capabilities[i], capability) == 0)
+ return i;
+ }
+
+ /* server capability not found */
+ return -1;
+}
+
+/*
* Parses an IRC message.
*
* Returns hashtable with parsed message, NULL if error.
@@ -272,7 +320,8 @@ relay_irc_signal_irc_in2_cb (void *data, const char *signal,
}
/*
- * Gets id of client by looking for tag "relay_client_NNN" in list of tags (comma separated list).
+ * Gets id of client by looking for tag "relay_client_NNN" in list of tags
+ * (comma separated list).
*
* Returns number found (NNN), -1 if not found.
*/
@@ -397,7 +446,8 @@ relay_irc_signal_irc_outtags_cb (void *data, const char *signal,
RELAY_IRC_DATA(client, nick));
host = NULL;
- infolist_nick = weechat_infolist_get ("irc_nick", NULL, str_infolist_args);
+ infolist_nick = weechat_infolist_get ("irc_nick", NULL,
+ str_infolist_args);
if (infolist_nick && weechat_infolist_next (infolist_nick))
host = weechat_infolist_string (infolist_nick, "host");
@@ -498,6 +548,381 @@ relay_irc_hsignal_irc_redir_cb (void *data, const char *signal,
}
/*
+ * Gets info about a line in a buffer:
+ * - irc command
+ * - date
+ * - nick
+ * - nick1 and nick2 (old and new nick for irc "nick" command)
+ * - host (without colors)
+ * - message (without colors).
+ *
+ * Arguments hdata_line_data and line_data must be non NULL, the other arguments
+ * can be NULL.
+ *
+ * Note: tags, host and message (if given and filled) must be freed after use.
+ */
+
+void
+relay_irc_get_line_info (struct t_relay_client *client,
+ struct t_gui_buffer *buffer,
+ struct t_hdata *hdata_line_data, void *line_data,
+ int *irc_command, int *irc_action, time_t *date,
+ const char **nick, const char **nick1,
+ const char **nick2, char **tags, char **host,
+ char **message)
+{
+ int i, num_tags, command, action, all_tags, length;
+ char str_tag[256], *pos, *pos2, *message_no_color, str_time[256];
+ const char *ptr_tag, *ptr_message, *ptr_nick, *ptr_nick1, *ptr_nick2;
+ const char *localvar_nick, *time_format;
+ time_t msg_date;
+ struct tm *tm;
+
+ if (irc_command)
+ *irc_command = -1;
+ if (irc_action)
+ *irc_action = 0;
+ if (date)
+ *date = 0;
+ if (nick)
+ *nick = NULL;
+ if (nick1)
+ *nick1 = NULL;
+ if (nick2)
+ *nick2 = NULL;
+ if (tags)
+ *tags = NULL;
+ if (host)
+ *host = NULL;
+ if (message)
+ *message = NULL;
+
+ msg_date = weechat_hdata_time (hdata_line_data, line_data, "date");
+ tm = localtime (&msg_date);
+ num_tags = weechat_hdata_get_var_array_size (hdata_line_data, line_data,
+ "tags_array");
+ ptr_message = weechat_hdata_pointer (hdata_line_data, line_data, "message");
+
+ /* no tag found, or no message? just exit */
+ if ((num_tags <= 0) || !ptr_message)
+ return;
+
+ command = -1;
+ action = 0;
+ ptr_nick = NULL;
+ ptr_nick1 = NULL;
+ ptr_nick2 = NULL;
+ all_tags = weechat_hashtable_has_key (relay_config_hashtable_irc_backlog_tags,
+ "*");
+ for (i = 0; i < num_tags; i++)
+ {
+ snprintf (str_tag, sizeof (str_tag), "%d|tags_array", i);
+ ptr_tag = weechat_hdata_string (hdata_line_data, line_data, str_tag);
+ if (ptr_tag)
+ {
+ if (strcmp (ptr_tag, "irc_action") == 0)
+ action = 1;
+ else if (strncmp (ptr_tag, "nick_", 5) == 0)
+ ptr_nick = ptr_tag + 5;
+ else if (strncmp (ptr_tag, "irc_nick1_", 10) == 0)
+ ptr_nick1 = ptr_tag + 10;
+ else if (strncmp (ptr_tag, "irc_nick2_", 10) == 0)
+ ptr_nick2 = ptr_tag + 10;
+ else if ((command < 0)
+ && (all_tags
+ || (weechat_hashtable_has_key (relay_config_hashtable_irc_backlog_tags,
+ ptr_tag))))
+ {
+ command = relay_irc_search_backlog_commands_tags (ptr_tag);
+ }
+ }
+ }
+
+ /* not a supported IRC command? */
+ if (command < 0)
+ return;
+
+ /* ignore join/part/quit from self nick */
+ if ((command == RELAY_IRC_CMD_JOIN) || (command == RELAY_IRC_CMD_PART)
+ || (command == RELAY_IRC_CMD_QUIT))
+ {
+ localvar_nick = weechat_buffer_get_string (buffer, "localvar_nick");
+ if (localvar_nick && localvar_nick[0]
+ && (strcmp (ptr_nick, localvar_nick) == 0))
+ {
+ command = -1;
+ return;
+ }
+ }
+
+ /* fills variables with the line data */
+ if (irc_command)
+ *irc_command = command;
+ if (irc_action)
+ *irc_action = action;
+ if (date)
+ *date = msg_date;
+ if (nick)
+ *nick = ptr_nick;
+ if (nick1)
+ *nick1 = ptr_nick1;
+ if (nick2)
+ *nick2 = ptr_nick2;
+ message_no_color = (ptr_message) ?
+ weechat_string_remove_color (ptr_message, NULL) : NULL;
+ if ((command == RELAY_IRC_CMD_PRIVMSG) && message && message_no_color)
+ {
+ pos = message_no_color;
+ if (action)
+ {
+ pos = strchr (message_no_color, ' ');
+ if (pos)
+ {
+ while (pos[0] == ' ')
+ {
+ pos++;
+ }
+ }
+ else
+ pos = message_no_color;
+ }
+ /*
+ * if server capability "server-time" is NOT enabled, and if the time
+ * format is not empty, add time inside message (before message)
+ */
+ time_format = weechat_config_string (relay_config_irc_backlog_time_format);
+ if (!(RELAY_IRC_DATA(client, server_capabilities) & (1 << RELAY_IRC_CAPAB_SERVER_TIME))
+ && time_format && time_format[0])
+ {
+ strftime (str_time, sizeof (str_time), time_format, tm);
+ length = strlen (str_time) + strlen (pos) + 1;
+ *message = malloc (length);
+ if (*message)
+ snprintf (*message, length, "%s%s", str_time, pos);
+ }
+ else
+ *message = strdup (pos);
+ }
+ switch (command)
+ {
+ case RELAY_IRC_CMD_JOIN:
+ case RELAY_IRC_CMD_PART:
+ case RELAY_IRC_CMD_QUIT:
+ if (host && message && message_no_color)
+ {
+ pos = strstr (message_no_color, " (");
+ if (pos)
+ {
+ pos2 = strchr (pos, ')');
+ if (pos2)
+ *host = weechat_strndup (pos + 2, pos2 - pos - 2);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ /* if server capability "server-time" is enabled, add an irc tag with time */
+ if (tags
+ && (RELAY_IRC_DATA(client, server_capabilities) & (1 << RELAY_IRC_CAPAB_SERVER_TIME)))
+ {
+ strftime (str_time, sizeof (str_time), "%Y-%m-%dT%H:%M:%S", tm);
+ snprintf (str_tag, sizeof (str_tag), "@time=%s.000Z ", str_time);
+ *tags = strdup (str_tag);
+ }
+
+ if (message_no_color)
+ free (message_no_color);
+}
+
+/*
+ * Sends channel backlog to client.
+ */
+
+void
+relay_irc_send_channel_backlog (struct t_relay_client *client,
+ const char *channel,
+ struct t_gui_buffer *buffer)
+{
+ struct t_relay_server *ptr_server;
+ void *ptr_own_lines, *ptr_line, *ptr_line_data;
+ void *ptr_hdata_line, *ptr_hdata_line_data;
+ char *tags, *host, *message;
+ const char *ptr_nick, *ptr_nick1, *ptr_nick2;
+ int irc_command, irc_action, count, max_number, max_minutes;
+ time_t date_min, date_min2, date;
+
+ /* get pointer on "own_lines" in buffer */
+ ptr_own_lines = weechat_hdata_pointer (weechat_hdata_get ("buffer"),
+ buffer, "own_lines");
+ if (!ptr_own_lines)
+ return;
+
+ /* get pointer on "last_line" in lines */
+ ptr_line = weechat_hdata_pointer (weechat_hdata_get ("lines"),
+ ptr_own_lines, "last_line");
+ if (!ptr_line)
+ return;
+
+ /* get hdata "line" */
+ ptr_hdata_line = weechat_hdata_get ("line");
+ if (!ptr_hdata_line)
+ return;
+
+ /* get hdata "line_data" */
+ ptr_hdata_line_data = weechat_hdata_get ("line_data");
+ if (!ptr_hdata_line_data)
+ return;
+
+ max_number = weechat_config_integer (relay_config_irc_backlog_max_number);
+ max_minutes = weechat_config_integer (relay_config_irc_backlog_max_minutes);
+ date_min = (max_minutes > 0) ? time (NULL) - (max_minutes * 60) : 0;
+ if (weechat_config_boolean (relay_config_irc_backlog_since_last_disconnect))
+ {
+ ptr_server = relay_server_search (client->protocol_string);
+ if (ptr_server && (ptr_server->last_client_disconnect > 0))
+ {
+ date_min2 = ptr_server->last_client_disconnect;
+ if (date_min2 > date_min)
+ date_min = date_min2;
+ }
+ }
+
+ /*
+ * loop on lines in buffer, from last to first, and stop when we have
+ * reached max number of lines (or max minutes)
+ */
+ count = 0;
+ while (ptr_line)
+ {
+ ptr_line_data = weechat_hdata_pointer (ptr_hdata_line,
+ ptr_line, "data");
+ if (ptr_line_data)
+ {
+ relay_irc_get_line_info (client, buffer,
+ ptr_hdata_line_data, ptr_line_data,
+ &irc_command,
+ NULL, /* irc_action */
+ &date,
+ NULL, /* nick */
+ NULL, /* nick1 */
+ NULL, /* nick2 */
+ NULL, /* tags */
+ NULL, /* host */
+ NULL); /* message */
+ if (irc_command >= 0)
+ {
+ /* if we have reached max minutes, exit loop */
+ if ((date_min > 0) && (date < date_min))
+ break;
+ count++;
+ }
+ /* if we have reached max number of messages, exit loop */
+ if ((max_number > 0) && (count > max_number))
+ break;
+ }
+ ptr_line = weechat_hdata_move (ptr_hdata_line, ptr_line, -1);
+ }
+
+ if (!ptr_line)
+ {
+ /* if we have reached beginning of buffer, start from first line */
+ ptr_line = weechat_hdata_pointer (weechat_hdata_get ("lines"),
+ ptr_own_lines, "first_line");
+ }
+ else
+ {
+ /* start from line + 1 (the current line must not be sent) */
+ ptr_line = weechat_hdata_move (ptr_hdata_line, ptr_line, 1);
+ }
+
+ /*
+ * loop on lines from line pointer until last line of buffer, and for each
+ * irc message, sends it to client
+ */
+ while (ptr_line)
+ {
+ ptr_line_data = weechat_hdata_pointer (ptr_hdata_line,
+ ptr_line, "data");
+ if (ptr_line_data)
+ {
+ relay_irc_get_line_info (client, buffer,
+ ptr_hdata_line_data, ptr_line_data,
+ &irc_command,
+ &irc_action,
+ &date,
+ &ptr_nick,
+ &ptr_nick1,
+ &ptr_nick2,
+ &tags,
+ &host,
+ &message);
+ switch (irc_command)
+ {
+ case RELAY_IRC_CMD_JOIN:
+ relay_irc_sendf (client,
+ "%s:%s%s%s JOIN :%s",
+ (tags) ? tags : "",
+ ptr_nick,
+ (host) ? "!" : "",
+ (host) ? host : "",
+ channel);
+ break;
+ case RELAY_IRC_CMD_PART:
+ relay_irc_sendf (client,
+ "%s:%s%s%s PART %s",
+ (tags) ? tags : "",
+ ptr_nick,
+ (host) ? "!" : "",
+ (host) ? host : "",
+ channel);
+ case RELAY_IRC_CMD_QUIT:
+ relay_irc_sendf (client,
+ "%s:%s%s%s QUIT",
+ (tags) ? tags : "",
+ ptr_nick,
+ (host) ? "!" : "",
+ (host) ? host : "");
+ break;
+ case RELAY_IRC_CMD_NICK:
+ if (ptr_nick1 && ptr_nick2)
+ {
+ relay_irc_sendf (client,
+ "%s:%s NICK :%s",
+ (tags) ? tags : "",
+ ptr_nick1,
+ ptr_nick2);
+ }
+ break;
+ case RELAY_IRC_CMD_PRIVMSG:
+ if (ptr_nick && message)
+ {
+ relay_irc_sendf (client,
+ "%s:%s PRIVMSG %s :%s%s%s",
+ (tags) ? tags : "",
+ ptr_nick,
+ channel,
+ (irc_action) ? "\01ACTION " : "",
+ message,
+ (irc_action) ? "\01": "");
+ }
+ break;
+ case RELAY_IRC_NUM_CMD:
+ /* make C compiler happy */
+ break;
+ }
+ if (tags)
+ free (tags);
+ if (host)
+ free (host);
+ if (message)
+ free (message);
+ }
+ ptr_line = weechat_hdata_move (ptr_hdata_line, ptr_line, 1);
+ }
+}
+
+/*
* Sends IRC "JOIN" for a channel to client.
*/
@@ -510,6 +935,7 @@ relay_irc_send_join (struct t_relay_client *client,
char *host;
int length, length_nicks;
struct t_infolist *infolist_nick, *infolist_channel, *infolist_nicks;
+ struct t_gui_buffer *buffer;
length = strlen (client->protocol_args) + 1 + strlen (channel) + 1
+ strlen (RELAY_IRC_DATA(client, nick)) + 1;
@@ -533,6 +959,7 @@ relay_irc_send_join (struct t_relay_client *client,
}
weechat_infolist_free (infolist_nick);
}
+
relay_irc_sendf (client,
":%s!%s JOIN %s",
RELAY_IRC_DATA(client, nick),
@@ -543,12 +970,15 @@ relay_irc_send_join (struct t_relay_client *client,
snprintf (infolist_name, length, "%s,%s",
client->protocol_args,
channel);
+
+ buffer = NULL;
infolist_channel = weechat_infolist_get ("irc_channel", NULL,
infolist_name);
if (infolist_channel)
{
if (weechat_infolist_next (infolist_channel))
{
+ buffer = weechat_infolist_pointer (infolist_channel, "buffer");
topic = weechat_infolist_string (infolist_channel, "topic");
if (topic && topic[0])
{
@@ -613,6 +1043,10 @@ relay_irc_send_join (struct t_relay_client *client,
RELAY_IRC_DATA(client, nick),
channel);
free (infolist_name);
+
+ /* send backlog to client */
+ if (buffer)
+ relay_irc_send_channel_backlog (client, channel, buffer);
}
}
@@ -739,6 +1173,99 @@ relay_irc_hook_signals (struct t_relay_client *client)
}
/*
+ * Timer called to hooks signals and send joins for all channels to client.
+ */
+
+int
+relay_irc_timer_hooks_and_joins_cb (void *data, int remaining_calls)
+{
+ /* make C compiler happy */
+ (void) remaining_calls;
+
+ if (relay_client_valid (data))
+ {
+ /* hook signals */
+ relay_irc_hook_signals (data);
+
+ /* send JOIN for all channels on server to client */
+ relay_irc_send_join_channels (data);
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * Processes the "CAP" irc command (received from client)
+ */
+
+void
+relay_irc_recv_command_capab (struct t_relay_client *client,
+ const char *arguments)
+{
+ char str_capab[1024], **capabs;
+ const char *ptr_args;
+ int i, num_capabs, capability;
+
+ if (weechat_strcasecmp (arguments, "ls") == 0)
+ {
+ /* return the list of supported server capabilities */
+ str_capab[0] = '\0';
+ for (i = 0; i < RELAY_IRC_NUM_CAPAB; i++)
+ {
+ if (str_capab[0])
+ strcat (str_capab, " ");
+ strcat (str_capab, relay_irc_server_capabilities[i]);
+ relay_irc_sendf (client,
+ ":%s CAP %s LS :%s",
+ RELAY_IRC_DATA(client, address),
+ (RELAY_IRC_DATA(client, nick)) ? RELAY_IRC_DATA(client, nick) : "nick",
+ str_capab);
+ }
+ }
+ else if (weechat_strncasecmp (arguments, "req ", 4) == 0)
+ {
+ /* client is asking for one or more server capabilities */
+ ptr_args = arguments + 4;
+ while (ptr_args[0] == ' ')
+ {
+ ptr_args++;
+ }
+ if (ptr_args[0] == ':')
+ ptr_args++;
+ capabs = weechat_string_split (ptr_args, " ", 0, 0, &num_capabs);
+ if (capabs)
+ {
+ str_capab[0] = '\0';
+ for (i = 0; i < num_capabs; i++)
+ {
+ capability = relay_irc_search_server_capability (capabs[i]);
+ if (capability >= 0)
+ {
+ if (str_capab[0])
+ strcat (str_capab, " ");
+ strcat (str_capab,
+ relay_irc_server_capabilities[capability]);
+ RELAY_IRC_DATA(client, server_capabilities) |= 1 << capability;
+ }
+ }
+ /*
+ * if at least one supported capability was enabled, send ACK to
+ * client
+ */
+ if (str_capab[0])
+ {
+ relay_irc_sendf (client,
+ ":%s CAP %s ACK :%s",
+ RELAY_IRC_DATA(client, address),
+ (RELAY_IRC_DATA(client, nick)) ? RELAY_IRC_DATA(client, nick) : "nick",
+ str_capab);
+ }
+ weechat_string_free_split (capabs);
+ }
+ }
+}
+
+/*
* Reads one message from client.
*/
@@ -786,7 +1313,10 @@ relay_irc_recv_one_msg (struct t_relay_client *client, char *data)
if (irc_args)
irc_argv = weechat_string_split (irc_args, " ", 0, 0, &irc_argc);
- /* process the message */
+ /*
+ * first process the "nick" command (it will be processed again in this
+ * function below)
+ */
if (irc_command && (weechat_strcasecmp (irc_command, "nick") == 0))
{
if (irc_args && irc_args[0])
@@ -796,6 +1326,13 @@ relay_irc_recv_one_msg (struct t_relay_client *client, char *data)
RELAY_IRC_DATA(client, nick) = strdup (irc_args);
}
}
+ /* server capabilities */
+ if (irc_command && (weechat_strcasecmp (irc_command, "cap") == 0))
+ {
+ if (irc_args)
+ relay_irc_recv_command_capab (client, irc_args);
+ }
+ /* if client is not yet "connected" */
if (!RELAY_IRC_DATA(client, connected))
{
if (irc_command && (weechat_strcasecmp (irc_command, "pass") == 0))
@@ -942,11 +1479,17 @@ relay_irc_recv_one_msg (struct t_relay_client *client, char *data)
RELAY_IRC_DATA(client, address),
RELAY_IRC_DATA(client, nick));
- /* hook signals */
- relay_irc_hook_signals (client);
-
- /* send JOIN for all channels on server to client */
- relay_irc_send_join_channels (client);
+ /*
+ * hook a timer which will hook signals and send JOIN for all
+ * channels to client (a timer is needed because we may not have
+ * received the server capabilities yet, like server-time)
+ */
+ if (RELAY_IRC_DATA(client, hook_timer_signals_joins))
+ weechat_unhook (RELAY_IRC_DATA(client, hook_timer_signals_joins));
+ RELAY_IRC_DATA(client, hook_timer_signals_joins) =
+ weechat_hook_timer (500, 0, 1,
+ &relay_irc_timer_hooks_and_joins_cb,
+ client);
}
}
else
@@ -1173,6 +1716,12 @@ void
relay_irc_close_connection (struct t_relay_client *client)
{
RELAY_IRC_DATA(client, connected) = 0;
+
+ if (RELAY_IRC_DATA(client, hook_timer_signals_joins))
+ {
+ weechat_unhook (RELAY_IRC_DATA(client, hook_timer_signals_joins));
+ RELAY_IRC_DATA(client, hook_timer_signals_joins) = NULL;
+ }
if (RELAY_IRC_DATA(client, hook_signal_irc_in2))
{
weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_in2));
@@ -1215,6 +1764,8 @@ relay_irc_alloc (struct t_relay_client *client)
RELAY_IRC_DATA(client, nick) = NULL;
RELAY_IRC_DATA(client, user_received) = 0;
RELAY_IRC_DATA(client, connected) = 0;
+ RELAY_IRC_DATA(client, server_capabilities) = 0;
+ RELAY_IRC_DATA(client, hook_timer_signals_joins) = NULL;
RELAY_IRC_DATA(client, hook_signal_irc_in2) = NULL;
RELAY_IRC_DATA(client, hook_signal_irc_outtags) = NULL;
RELAY_IRC_DATA(client, hook_signal_irc_disc) = NULL;
@@ -1245,6 +1796,8 @@ relay_irc_alloc_with_infolist (struct t_relay_client *client,
RELAY_IRC_DATA(client, nick) = NULL;
RELAY_IRC_DATA(client, user_received) = weechat_infolist_integer (infolist, "user_received");
RELAY_IRC_DATA(client, connected) = weechat_infolist_integer (infolist, "connected");
+ RELAY_IRC_DATA(client, server_capabilities) = weechat_infolist_integer (infolist, "server_capabilities");
+ RELAY_IRC_DATA(client, hook_timer_signals_joins) = NULL;
if (RELAY_IRC_DATA(client, connected))
{
relay_irc_hook_signals (client);
@@ -1272,6 +1825,8 @@ relay_irc_free (struct t_relay_client *client)
free (RELAY_IRC_DATA(client, address));
if (RELAY_IRC_DATA(client, nick))
free (RELAY_IRC_DATA(client, nick));
+ if (RELAY_IRC_DATA(client, hook_timer_signals_joins))
+ weechat_unhook (RELAY_IRC_DATA(client, hook_timer_signals_joins));
if (RELAY_IRC_DATA(client, hook_signal_irc_in2))
weechat_unhook (RELAY_IRC_DATA(client, hook_signal_irc_in2));
if (RELAY_IRC_DATA(client, hook_signal_irc_outtags))
@@ -1312,6 +1867,10 @@ relay_irc_add_to_infolist (struct t_infolist_item *item,
return 0;
if (!weechat_infolist_new_var_integer (item, "connected", RELAY_IRC_DATA(client, connected)))
return 0;
+ if (!weechat_infolist_new_var_integer (item, "server_capabilities", RELAY_IRC_DATA(client, server_capabilities)))
+ return 0;
+ if (!weechat_infolist_new_var_pointer (item, "hook_timer_signals_joins", RELAY_IRC_DATA(client, hook_timer_signals_joins)))
+ return 0;
if (!weechat_infolist_new_var_pointer (item, "hook_signal_irc_in2", RELAY_IRC_DATA(client, hook_signal_irc_in2)))
return 0;
if (!weechat_infolist_new_var_pointer (item, "hook_signal_irc_outtags", RELAY_IRC_DATA(client, hook_signal_irc_outtags)))
@@ -1333,14 +1892,16 @@ relay_irc_print_log (struct t_relay_client *client)
{
if (client->protocol_data)
{
- weechat_log_printf (" address. . . . . . . . : '%s'", RELAY_IRC_DATA(client, address));
- weechat_log_printf (" password_ok. . . . . . : %d", RELAY_IRC_DATA(client, password_ok));
- weechat_log_printf (" nick . . . . . . . . . : '%s'", RELAY_IRC_DATA(client, nick));
- weechat_log_printf (" user_received. . . . . : %d", RELAY_IRC_DATA(client, user_received));
- weechat_log_printf (" connected. . . . . . . : %d", RELAY_IRC_DATA(client, connected));
- weechat_log_printf (" hook_signal_irc_in2. . : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_in2));
- weechat_log_printf (" hook_signal_irc_outtags: 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_outtags));
- weechat_log_printf (" hook_signal_irc_disc . : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_disc));
- weechat_log_printf (" hook_hsignal_irc_redir : 0x%lx", RELAY_IRC_DATA(client, hook_hsignal_irc_redir));
+ weechat_log_printf (" address . . . . . . . . : '%s'", RELAY_IRC_DATA(client, address));
+ weechat_log_printf (" password_ok . . . . . . : %d", RELAY_IRC_DATA(client, password_ok));
+ weechat_log_printf (" nick. . . . . . . . . . : '%s'", RELAY_IRC_DATA(client, nick));
+ weechat_log_printf (" user_received . . . . . : %d", RELAY_IRC_DATA(client, user_received));
+ weechat_log_printf (" connected . . . . . . . : %d", RELAY_IRC_DATA(client, connected));
+ weechat_log_printf (" server_capabilities . . : %d", RELAY_IRC_DATA(client, server_capabilities));
+ weechat_log_printf (" hook_timer_signals_joins: 0x%lx", RELAY_IRC_DATA(client, hook_timer_signals_joins));
+ weechat_log_printf (" hook_signal_irc_in2 . . : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_in2));
+ weechat_log_printf (" hook_signal_irc_outtags : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_outtags));
+ weechat_log_printf (" hook_signal_irc_disc. . : 0x%lx", RELAY_IRC_DATA(client, hook_signal_irc_disc));
+ weechat_log_printf (" hook_hsignal_irc_redir. : 0x%lx", RELAY_IRC_DATA(client, hook_hsignal_irc_redir));
}
}
diff --git a/src/plugins/relay/irc/relay-irc.h b/src/plugins/relay/irc/relay-irc.h
index 2235da1f1..a30e9cf1b 100644
--- a/src/plugins/relay/irc/relay-irc.h
+++ b/src/plugins/relay/irc/relay-irc.h
@@ -34,12 +34,34 @@ struct t_relay_irc_data
int user_received; /* command "USER" received */
int connected; /* 1 if client is connected as IRC */
/* client */
+ int server_capabilities; /* server capabilities enabled (one */
+ /* bit per capability) */
+ struct t_hook *hook_timer_signals_joins;/* timer to hooks signals and */
+ /* send joins to client */
struct t_hook *hook_signal_irc_in2; /* signal "irc_in2" */
struct t_hook *hook_signal_irc_outtags; /* signal "irc_outtags" */
struct t_hook *hook_signal_irc_disc; /* signal "irc_disconnected" */
struct t_hook *hook_hsignal_irc_redir; /* hsignal "irc_redirection_..."*/
};
+enum t_relay_irc_command
+{
+ RELAY_IRC_CMD_JOIN = 0,
+ RELAY_IRC_CMD_PART,
+ RELAY_IRC_CMD_QUIT,
+ RELAY_IRC_CMD_NICK,
+ RELAY_IRC_CMD_PRIVMSG,
+ /* number of relay irc commands */
+ RELAY_IRC_NUM_CMD,
+};
+
+enum t_relay_irc_server_capab
+{
+ RELAY_IRC_CAPAB_SERVER_TIME = 0,
+ /* number of server capabilities */
+ RELAY_IRC_NUM_CAPAB,
+};
+
extern void relay_irc_recv (struct t_relay_client *client,
const char *data);
extern void relay_irc_close_connection (struct t_relay_client *client);
diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c
index 7816accd1..7b2ac1605 100644
--- a/src/plugins/relay/relay-client.c
+++ b/src/plugins/relay/relay-client.c
@@ -647,6 +647,7 @@ relay_client_new (int sock, const char *address, struct t_relay_server *server)
new_client->address = strdup ((address) ? address : "?");
new_client->status = RELAY_STATUS_CONNECTED;
new_client->protocol = server->protocol;
+ new_client->protocol_string = (server->protocol_string) ? strdup (server->protocol_string) : NULL;
new_client->protocol_args = (server->protocol_args) ? strdup (server->protocol_args) : NULL;
new_client->listen_start_time = server->start_time;
new_client->start_time = time (NULL);
@@ -794,6 +795,8 @@ relay_client_new_with_infolist (struct t_infolist *infolist)
new_client->address = strdup (weechat_infolist_string (infolist, "address"));
new_client->status = weechat_infolist_integer (infolist, "status");
new_client->protocol = weechat_infolist_integer (infolist, "protocol");
+ str = weechat_infolist_string (infolist, "protocol_string");
+ new_client->protocol_string = (str) ? strdup (str) : NULL;
str = weechat_infolist_string (infolist, "protocol_args");
new_client->protocol_args = (str) ? strdup (str) : NULL;
new_client->listen_start_time = weechat_infolist_time (infolist, "listen_start_time");
@@ -859,12 +862,18 @@ void
relay_client_set_status (struct t_relay_client *client,
enum t_relay_status status)
{
+ struct t_relay_server *ptr_server;
+
client->status = status;
if (RELAY_CLIENT_HAS_ENDED(client))
{
client->end_time = time (NULL);
+ ptr_server = relay_server_search (client->protocol_string);
+ if (ptr_server)
+ ptr_server->last_client_disconnect = client->end_time;
+
relay_client_outqueue_free_all (client);
if (client->hook_fd)
@@ -951,8 +960,12 @@ relay_client_free (struct t_relay_client *client)
(client->next_client)->prev_client = client->prev_client;
/* free data */
+ if (client->desc)
+ free (client->desc);
if (client->address)
free (client->address);
+ if (client->protocol_string)
+ free (client->protocol_string);
if (client->protocol_args)
free (client->protocol_args);
#ifdef HAVE_GNUTLS
@@ -1075,6 +1088,8 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "protocol_string", relay_protocol_string[client->protocol]))
return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "protocol_string", client->protocol_string))
+ return 0;
if (!weechat_infolist_new_var_string (ptr_item, "protocol_args", client->protocol_args))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "listen_start_time", client->listen_start_time))
@@ -1138,6 +1153,7 @@ relay_client_print_log ()
weechat_log_printf (" protocol. . . . . . . : %d (%s)",
ptr_client->protocol,
relay_protocol_string[ptr_client->protocol]);
+ weechat_log_printf (" protocol_string . . . : '%s'", ptr_client->protocol_string);
weechat_log_printf (" protocol_args . . . . : '%s'", ptr_client->protocol_args);
weechat_log_printf (" listen_start_time . . : %ld", ptr_client->listen_start_time);
weechat_log_printf (" start_time. . . . . . : %ld", ptr_client->start_time);
diff --git a/src/plugins/relay/relay-client.h b/src/plugins/relay/relay-client.h
index 07a21b0b0..96b236439 100644
--- a/src/plugins/relay/relay-client.h
+++ b/src/plugins/relay/relay-client.h
@@ -70,6 +70,7 @@ struct t_relay_client
char *address; /* string with IP address */
enum t_relay_status status; /* status (connecting, active,..) */
enum t_relay_protocol protocol; /* protocol (irc,..) */
+ char *protocol_string; /* example: "ipv6.ssl.irc.freenode" */
char *protocol_args; /* arguments used for protocol */
/* example: server for irc protocol */
time_t listen_start_time; /* when listening started */
diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c
index 2f66e23b8..72790c698 100644
--- a/src/plugins/relay/relay-config.c
+++ b/src/plugins/relay/relay-config.c
@@ -58,9 +58,18 @@ struct t_config_option *relay_config_network_max_clients;
struct t_config_option *relay_config_network_password;
struct t_config_option *relay_config_network_ssl_cert_key;
+/* relay config, irc section */
+
+struct t_config_option *relay_config_irc_backlog_max_number;
+struct t_config_option *relay_config_irc_backlog_max_minutes;
+struct t_config_option *relay_config_irc_backlog_since_last_disconnect;
+struct t_config_option *relay_config_irc_backlog_tags;
+struct t_config_option *relay_config_irc_backlog_time_format;
+
/* other */
regex_t *relay_config_regex_allowed_ips = NULL;
+struct t_hashtable *relay_config_hashtable_irc_backlog_tags = NULL;
/*
@@ -179,6 +188,46 @@ relay_config_change_network_ssl_cert_key (void *data,
}
/*
+ * Callback for changes on option "relay.irc.backlog_tags".
+ */
+
+void
+relay_config_change_irc_backlog_tags (void *data,
+ struct t_config_option *option)
+{
+ char **items;
+ int num_items, i;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) option;
+
+ if (!relay_config_hashtable_irc_backlog_tags)
+ {
+ relay_config_hashtable_irc_backlog_tags = weechat_hashtable_new (8,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL,
+ NULL);
+ }
+ else
+ weechat_hashtable_remove_all (relay_config_hashtable_irc_backlog_tags);
+
+ items = weechat_string_split (weechat_config_string (relay_config_irc_backlog_tags),
+ ";", 0, 0, &num_items);
+ if (items)
+ {
+ for (i = 0; i < num_items; i++)
+ {
+ weechat_hashtable_set (relay_config_hashtable_irc_backlog_tags,
+ items[i],
+ NULL);
+ }
+ weechat_string_free_split (items);
+ }
+}
+
+/*
* Checks if a port is valid.
*
* Returns:
@@ -401,6 +450,7 @@ relay_config_init ()
if (!relay_config_file)
return 0;
+ /* section look */
ptr_section = weechat_config_new_section (relay_config_file, "look",
0, 0,
NULL, NULL, NULL, NULL,
@@ -424,6 +474,7 @@ relay_config_init ()
"closed (messages will be displayed when opening raw data buffer)"),
NULL, 0, 65535, "256", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ /* section color */
ptr_section = weechat_config_new_section (relay_config_file, "color",
0, 0,
NULL, NULL, NULL, NULL,
@@ -490,6 +541,7 @@ relay_config_init ()
NULL, 0, 0, "lightred", NULL, 0,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
+ /* section network */
ptr_section = weechat_config_new_section (relay_config_file, "network",
0, 0,
NULL, NULL, NULL, NULL,
@@ -555,6 +607,56 @@ relay_config_init ()
NULL, 0, 0, "%h/ssl/relay.pem", NULL, 0, NULL, NULL,
&relay_config_change_network_ssl_cert_key, NULL, NULL, NULL);
+ /* section irc */
+ ptr_section = weechat_config_new_section (relay_config_file, "irc",
+ 0, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL);
+ if (!ptr_section)
+ {
+ weechat_config_free (relay_config_file);
+ return 0;
+ }
+
+ relay_config_irc_backlog_max_number = weechat_config_new_option (
+ relay_config_file, ptr_section,
+ "backlog_max_number", "integer",
+ N_("maximum number of lines in backlog per IRC channel "
+ "(0 = unlimited)"),
+ NULL, 0, INT_MAX, "256", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ relay_config_irc_backlog_max_minutes = weechat_config_new_option (
+ relay_config_file, ptr_section,
+ "backlog_max_minutes", "integer",
+ N_("maximum number of minutes in backlog per IRC channel "
+ "(0 = unlimited, examples: 1440 = one day, 10080 = one week, "
+ "43200 = one month, 525600 = one year)"),
+ NULL, 0, INT_MAX, "1440", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ relay_config_irc_backlog_since_last_disconnect = weechat_config_new_option (
+ relay_config_file, ptr_section,
+ "backlog_since_last_disconnect", "boolean",
+ N_("display backlog starting from last client disconnect"),
+ NULL, 0, 0, "on", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ relay_config_irc_backlog_tags = weechat_config_new_option (
+ relay_config_file, ptr_section,
+ "backlog_tags", "string",
+ N_("tags of messages which are displayed in backlog per IRC channel "
+ "(supported tags: \"irc_join\", \"irc_part\", \"irc_quit\", "
+ "\"irc_nick\", \"irc_privmsg\"), \"*\" = all supported tags"),
+ NULL, 0, 0, "irc_privmsg", NULL, 0, NULL, NULL,
+ &relay_config_change_irc_backlog_tags, NULL, NULL, NULL);
+ relay_config_irc_backlog_time_format = weechat_config_new_option (
+ relay_config_file, ptr_section,
+ "backlog_time_format", "string",
+ N_("format for time in backlog messages (see man strftime for format) "
+ "(not used if server capability \"server-time\" was enabled by "
+ "client, because time is sent as irc tag); empty string = disable "
+ "time in backlog messages"),
+ NULL, 0, 0, "[%H:%M] ", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ /* section port */
ptr_section = weechat_config_new_section (relay_config_file, "port",
1, 1,
NULL, NULL,
@@ -580,7 +682,15 @@ relay_config_init ()
int
relay_config_read ()
{
- return weechat_config_read (relay_config_file);
+ int rc;
+
+ rc = weechat_config_read (relay_config_file);
+ if (rc == WEECHAT_CONFIG_READ_OK)
+ {
+ relay_config_change_network_allowed_ips (NULL, NULL);
+ relay_config_change_irc_backlog_tags (NULL, NULL);
+ }
+ return rc;
}
/*
@@ -592,3 +702,26 @@ relay_config_write ()
{
return weechat_config_write (relay_config_file);
}
+
+/*
+ * Frees relay configuration.
+ */
+
+void
+relay_config_free ()
+{
+ weechat_config_free (relay_config_file);
+
+ if (relay_config_regex_allowed_ips)
+ {
+ regfree (relay_config_regex_allowed_ips);
+ free (relay_config_regex_allowed_ips);
+ relay_config_regex_allowed_ips = NULL;
+ }
+
+ if (relay_config_hashtable_irc_backlog_tags)
+ {
+ weechat_hashtable_free (relay_config_hashtable_irc_backlog_tags);
+ relay_config_hashtable_irc_backlog_tags = NULL;
+ }
+}
diff --git a/src/plugins/relay/relay-config.h b/src/plugins/relay/relay-config.h
index 8a54b75e1..c4499bc0d 100644
--- a/src/plugins/relay/relay-config.h
+++ b/src/plugins/relay/relay-config.h
@@ -44,7 +44,14 @@ extern struct t_config_option *relay_config_network_max_clients;
extern struct t_config_option *relay_config_network_password;
extern struct t_config_option *relay_config_network_ssl_cert_key;
+extern struct t_config_option *relay_config_irc_backlog_max_number;
+extern struct t_config_option *relay_config_irc_backlog_max_minutes;
+extern struct t_config_option *relay_config_irc_backlog_since_last_disconnect;
+extern struct t_config_option *relay_config_irc_backlog_tags;
+extern struct t_config_option *relay_config_irc_backlog_time_format;
+
extern regex_t *relay_config_regex_allowed_ips;
+extern struct t_hashtable *relay_config_hashtable_irc_backlog_tags;
extern int relay_config_create_option_port (void *data,
struct t_config_file *config_file,
@@ -54,5 +61,6 @@ extern int relay_config_create_option_port (void *data,
extern int relay_config_init ();
extern int relay_config_read ();
extern int relay_config_write ();
+extern void relay_config_free ();
#endif /* __WEECHAT_RELAY_CONFIG_H */
diff --git a/src/plugins/relay/relay-server.c b/src/plugins/relay/relay-server.c
index 00d8f23cd..4ae749af1 100644
--- a/src/plugins/relay/relay-server.c
+++ b/src/plugins/relay/relay-server.c
@@ -501,6 +501,7 @@ relay_server_new (const char *protocol_string, enum t_relay_protocol protocol,
new_server->sock = -1;
new_server->hook_fd = NULL;
new_server->start_time = 0;
+ new_server->last_client_disconnect = 0;
if (!relay_server_create_socket (new_server))
{
@@ -596,6 +597,53 @@ relay_server_free_all ()
}
/*
+ * Adds a server in an infolist.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+relay_server_add_to_infolist (struct t_infolist *infolist,
+ struct t_relay_server *server)
+{
+ struct t_infolist_item *ptr_item;
+
+ if (!infolist || !server)
+ return 0;
+
+ ptr_item = weechat_infolist_new_item (infolist);
+ if (!ptr_item)
+ return 0;
+
+ if (!weechat_infolist_new_var_string (ptr_item, "protocol_string", server->protocol_string))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "protocol", server->protocol))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "protocol_args", server->protocol_args))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "port", server->port))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "ipv4", server->ipv4))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "ipv6", server->ipv6))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "ssl", server->ssl))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "sock", server->sock))
+ return 0;
+ if (!weechat_infolist_new_var_pointer (ptr_item, "hook_fd", server->hook_fd))
+ return 0;
+ if (!weechat_infolist_new_var_time (ptr_item, "start_time", server->start_time))
+ return 0;
+ if (!weechat_infolist_new_var_time (ptr_item, "last_client_disconnect", server->last_client_disconnect))
+ return 0;
+
+ return 1;
+}
+
+/*
* Prints servers in WeeChat log file (usually for crash dump).
*/
@@ -609,19 +657,20 @@ relay_server_print_log ()
{
weechat_log_printf ("");
weechat_log_printf ("[relay server (addr:0x%lx)]", ptr_server);
- weechat_log_printf (" protocol_string . . : '%s'", ptr_server->protocol_string);
- weechat_log_printf (" protocol. . . . . . : %d (%s)",
+ weechat_log_printf (" protocol_string . . . : '%s'", ptr_server->protocol_string);
+ weechat_log_printf (" protocol. . . . . . . : %d (%s)",
ptr_server->protocol,
relay_protocol_string[ptr_server->protocol]);
- weechat_log_printf (" protocol_args . . . : '%s'", ptr_server->protocol_args);
- weechat_log_printf (" port. . . . . . . . : %d", ptr_server->port);
- weechat_log_printf (" ipv4. . . . . . . . : %d", ptr_server->ipv4);
- weechat_log_printf (" ipv6. . . . . . . . : %d", ptr_server->ipv6);
- weechat_log_printf (" ssl . . . . . . . . : %d", ptr_server->ssl);
- weechat_log_printf (" sock. . . . . . . . : %d", ptr_server->sock);
- weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_server->hook_fd);
- weechat_log_printf (" start_time. . . . . : %ld", ptr_server->start_time);
- weechat_log_printf (" prev_server . . . . : 0x%lx", ptr_server->prev_server);
- weechat_log_printf (" next_server . . . . : 0x%lx", ptr_server->next_server);
+ weechat_log_printf (" protocol_args . . . . : '%s'", ptr_server->protocol_args);
+ weechat_log_printf (" port. . . . . . . . . : %d", ptr_server->port);
+ weechat_log_printf (" ipv4. . . . . . . . . : %d", ptr_server->ipv4);
+ weechat_log_printf (" ipv6. . . . . . . . . : %d", ptr_server->ipv6);
+ weechat_log_printf (" ssl . . . . . . . . . : %d", ptr_server->ssl);
+ weechat_log_printf (" sock. . . . . . . . . : %d", ptr_server->sock);
+ weechat_log_printf (" hook_fd . . . . . . . : 0x%lx", ptr_server->hook_fd);
+ weechat_log_printf (" start_time. . . . . . : %ld", ptr_server->start_time);
+ weechat_log_printf (" last_client_disconnect: %ld", ptr_server->last_client_disconnect);
+ weechat_log_printf (" prev_server . . . . . : 0x%lx", ptr_server->prev_server);
+ weechat_log_printf (" next_server . . . . . : 0x%lx", ptr_server->next_server);
}
}
diff --git a/src/plugins/relay/relay-server.h b/src/plugins/relay/relay-server.h
index f4af777e8..b5945bec7 100644
--- a/src/plugins/relay/relay-server.h
+++ b/src/plugins/relay/relay-server.h
@@ -37,6 +37,7 @@ struct t_relay_server
int sock; /* socket for connection */
struct t_hook *hook_fd; /* hook for socket */
time_t start_time; /* start time */
+ time_t last_client_disconnect; /* last time a client disconnected */
struct t_relay_server *prev_server;/* link to previous server */
struct t_relay_server *next_server;/* link to next server */
};
@@ -61,6 +62,8 @@ extern struct t_relay_server *relay_server_new (const char *protocol_string,
extern void relay_server_update_port (struct t_relay_server *server, int port);
extern void relay_server_free (struct t_relay_server *server);
extern void relay_server_free_all ();
+extern int relay_server_add_to_infolist (struct t_infolist *infolist,
+ struct t_relay_server *server);
extern void relay_server_print_log ();
#endif /* __WEECHAT_RELAY_SERVER_H */
diff --git a/src/plugins/relay/relay-upgrade.c b/src/plugins/relay/relay-upgrade.c
index dadbfc5ac..d60968c69 100644
--- a/src/plugins/relay/relay-upgrade.c
+++ b/src/plugins/relay/relay-upgrade.c
@@ -29,6 +29,7 @@
#include "relay-buffer.h"
#include "relay-client.h"
#include "relay-raw.h"
+#include "relay-server.h"
/*
@@ -43,10 +44,31 @@ int
relay_upgrade_save_all_data (struct t_upgrade_file *upgrade_file)
{
struct t_infolist *infolist;
+ struct t_relay_server *ptr_server;
struct t_relay_client *ptr_client;
struct t_relay_raw_message *ptr_raw_message;
int rc;
+ /* save servers */
+ for (ptr_server = relay_servers; ptr_server;
+ ptr_server = ptr_server->next_server)
+ {
+ infolist = weechat_infolist_new ();
+ if (!infolist)
+ return 0;
+ if (!relay_server_add_to_infolist (infolist, ptr_server))
+ {
+ weechat_infolist_free (infolist);
+ return 0;
+ }
+ rc = weechat_upgrade_write_object (upgrade_file,
+ RELAY_UPGRADE_TYPE_SERVER,
+ infolist);
+ weechat_infolist_free (infolist);
+ if (!rc)
+ return 0;
+ }
+
/* save clients */
for (ptr_client = last_relay_client; ptr_client;
ptr_client = ptr_client->prev_client)
@@ -162,6 +184,9 @@ relay_upgrade_read_cb (void *data,
int object_id,
struct t_infolist *infolist)
{
+ const char *str;
+ struct t_relay_server *ptr_server;
+
/* make C compiler happy */
(void) data;
(void) upgrade_file;
@@ -171,6 +196,19 @@ relay_upgrade_read_cb (void *data,
{
switch (object_id)
{
+ case RELAY_UPGRADE_TYPE_SERVER:
+ str = weechat_infolist_string (infolist, "protocol_string");
+ if (str)
+ {
+ ptr_server = relay_server_search (str);
+ if (ptr_server)
+ {
+ ptr_server->last_client_disconnect =
+ weechat_infolist_time (infolist,
+ "last_client_disconnect");
+ }
+ }
+ break;
case RELAY_UPGRADE_TYPE_CLIENT:
relay_client_new_with_infolist (infolist);
break;
diff --git a/src/plugins/relay/relay-upgrade.h b/src/plugins/relay/relay-upgrade.h
index c10726bd6..308c60f78 100644
--- a/src/plugins/relay/relay-upgrade.h
+++ b/src/plugins/relay/relay-upgrade.h
@@ -28,6 +28,7 @@ enum t_relay_upgrade_type
{
RELAY_UPGRADE_TYPE_CLIENT = 0,
RELAY_UPGRADE_TYPE_RAW_MESSAGE,
+ RELAY_UPGRADE_TYPE_SERVER,
};
extern int relay_upgrade_save ();
diff --git a/src/plugins/relay/relay.c b/src/plugins/relay/relay.c
index b5c3c4c16..3d9618e78 100644
--- a/src/plugins/relay/relay.c
+++ b/src/plugins/relay/relay.c
@@ -260,5 +260,7 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
relay_network_end ();
+ relay_config_free ();
+
return WEECHAT_RC_OK;
}