summaryrefslogtreecommitdiff
path: root/src/plugins/irc
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/irc')
-rw-r--r--src/plugins/irc/CMakeLists.txt3
-rw-r--r--src/plugins/irc/Makefile.am4
-rw-r--r--src/plugins/irc/irc-bar-item.c4
-rw-r--r--src/plugins/irc/irc-bar-item.h8
-rw-r--r--src/plugins/irc/irc-buffer.c2
-rw-r--r--src/plugins/irc/irc-buffer.h8
-rw-r--r--src/plugins/irc/irc-channel.c49
-rw-r--r--src/plugins/irc/irc-channel.h13
-rw-r--r--src/plugins/irc/irc-color.c2
-rw-r--r--src/plugins/irc/irc-color.h8
-rw-r--r--src/plugins/irc/irc-command.c272
-rw-r--r--src/plugins/irc/irc-command.h8
-rw-r--r--src/plugins/irc/irc-completion.c97
-rw-r--r--src/plugins/irc/irc-completion.h8
-rw-r--r--src/plugins/irc/irc-config.c175
-rw-r--r--src/plugins/irc/irc-config.h8
-rw-r--r--src/plugins/irc/irc-ctcp.c38
-rw-r--r--src/plugins/irc/irc-ctcp.h8
-rw-r--r--src/plugins/irc/irc-debug.c2
-rw-r--r--src/plugins/irc/irc-debug.h8
-rw-r--r--src/plugins/irc/irc-ignore.c2
-rw-r--r--src/plugins/irc/irc-ignore.h8
-rw-r--r--src/plugins/irc/irc-info.c228
-rw-r--r--src/plugins/irc/irc-info.h8
-rw-r--r--src/plugins/irc/irc-input.c5
-rw-r--r--src/plugins/irc/irc-input.h8
-rw-r--r--src/plugins/irc/irc-message.c98
-rw-r--r--src/plugins/irc/irc-message.h8
-rw-r--r--src/plugins/irc/irc-mode.c28
-rw-r--r--src/plugins/irc/irc-mode.h9
-rw-r--r--src/plugins/irc/irc-modelist.c505
-rw-r--r--src/plugins/irc/irc-modelist.h94
-rw-r--r--src/plugins/irc/irc-msgbuffer.c2
-rw-r--r--src/plugins/irc/irc-msgbuffer.h8
-rw-r--r--src/plugins/irc/irc-nick.c42
-rw-r--r--src/plugins/irc/irc-nick.h12
-rw-r--r--src/plugins/irc/irc-notify.c2
-rw-r--r--src/plugins/irc/irc-notify.h8
-rw-r--r--src/plugins/irc/irc-protocol.c326
-rw-r--r--src/plugins/irc/irc-protocol.h9
-rw-r--r--src/plugins/irc/irc-raw.c2
-rw-r--r--src/plugins/irc/irc-raw.h8
-rw-r--r--src/plugins/irc/irc-redirect.c6
-rw-r--r--src/plugins/irc/irc-redirect.h8
-rw-r--r--src/plugins/irc/irc-sasl.c10
-rw-r--r--src/plugins/irc/irc-sasl.h8
-rw-r--r--src/plugins/irc/irc-server.c252
-rw-r--r--src/plugins/irc/irc-server.h11
-rw-r--r--src/plugins/irc/irc-upgrade.c74
-rw-r--r--src/plugins/irc/irc-upgrade.h10
-rw-r--r--src/plugins/irc/irc.c4
-rw-r--r--src/plugins/irc/irc.h8
52 files changed, 2010 insertions, 526 deletions
diff --git a/src/plugins/irc/CMakeLists.txt b/src/plugins/irc/CMakeLists.txt
index a5703afef..f205adbc5 100644
--- a/src/plugins/irc/CMakeLists.txt
+++ b/src/plugins/irc/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+# Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of WeeChat, the extensible chat client.
#
@@ -33,6 +33,7 @@ irc-info.c irc-info.h
irc-input.c irc-input.h
irc-message.c irc-message.h
irc-mode.c irc-mode.h
+irc-modelist.c irc-modelist.h
irc-msgbuffer.c irc-msgbuffer.h
irc-nick.c irc-nick.h
irc-notify.c irc-notify.h
diff --git a/src/plugins/irc/Makefile.am b/src/plugins/irc/Makefile.am
index 208ce118f..966dc6813 100644
--- a/src/plugins/irc/Makefile.am
+++ b/src/plugins/irc/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+# Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
#
# This file is part of WeeChat, the extensible chat client.
#
@@ -53,6 +53,8 @@ irc_la_SOURCES = irc.c \
irc-message.h \
irc-mode.c \
irc-mode.h \
+ irc-modelist.c \
+ irc-modelist.h \
irc-msgbuffer.c \
irc-msgbuffer.h \
irc-nick.c \
diff --git a/src/plugins/irc/irc-bar-item.c b/src/plugins/irc/irc-bar-item.c
index e4494bb0b..02428b9a8 100644
--- a/src/plugins/irc/irc-bar-item.c
+++ b/src/plugins/irc/irc-bar-item.c
@@ -1,7 +1,7 @@
/*
* irc-bar-item.c - bar items for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -280,7 +280,7 @@ irc_bar_item_buffer_modes (const void *pointer, void *data,
modes_without_args = NULL;
if (!irc_config_display_channel_modes_arguments (channel->modes))
{
- pos_space = strchr(channel->modes, ' ');
+ pos_space = strchr (channel->modes, ' ');
if (pos_space)
{
modes_without_args = weechat_strndup (
diff --git a/src/plugins/irc/irc-bar-item.h b/src/plugins/irc/irc-bar-item.h
index 5889ea599..1173f9e72 100644
--- a/src/plugins/irc/irc-bar-item.h
+++ b/src/plugins/irc/irc-bar-item.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,10 +17,10 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_BAR_ITEM_H
-#define WEECHAT_IRC_BAR_ITEM_H 1
+#ifndef WEECHAT_PLUGIN_IRC_BAR_ITEM_H
+#define WEECHAT_PLUGIN_IRC_BAR_ITEM_H
extern void irc_bar_item_update_channel ();
extern void irc_bar_item_init ();
-#endif /* WEECHAT_IRC_BAR_ITEM_H */
+#endif /* WEECHAT_PLUGIN_IRC_BAR_ITEM_H */
diff --git a/src/plugins/irc/irc-buffer.c b/src/plugins/irc/irc-buffer.c
index b0a1e5ccd..7928c65ee 100644
--- a/src/plugins/irc/irc-buffer.c
+++ b/src/plugins/irc/irc-buffer.c
@@ -1,7 +1,7 @@
/*
* irc-buffer.c - buffer functions for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-buffer.h b/src/plugins/irc/irc-buffer.h
index cd0d828ce..034398e40 100644
--- a/src/plugins/irc/irc-buffer.h
+++ b/src/plugins/irc/irc-buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_BUFFER_H
-#define WEECHAT_IRC_BUFFER_H 1
+#ifndef WEECHAT_PLUGIN_IRC_BUFFER_H
+#define WEECHAT_PLUGIN_IRC_BUFFER_H
#define IRC_BUFFER_GET_SERVER(__buffer) \
struct t_weechat_plugin *buffer_plugin = NULL; \
@@ -56,4 +56,4 @@ extern int irc_buffer_nickcmp_cb (const void *pointer, void *data,
extern struct t_gui_buffer *irc_buffer_search_server_lowest_number ();
extern struct t_gui_buffer *irc_buffer_search_private_lowest_number (struct t_irc_server *server);
-#endif /* WEECHAT_IRC_BUFFER_H */
+#endif /* WEECHAT_PLUGIN_IRC_BUFFER_H */
diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c
index b184a5330..ab24038a0 100644
--- a/src/plugins/irc/irc-channel.c
+++ b/src/plugins/irc/irc-channel.c
@@ -1,7 +1,7 @@
/*
* irc-channel.c - channel and private chat management for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -33,6 +33,7 @@
#include "irc-color.h"
#include "irc-command.h"
#include "irc-config.h"
+#include "irc-modelist.h"
#include "irc-nick.h"
#include "irc-server.h"
#include "irc-input.h"
@@ -356,7 +357,7 @@ irc_channel_create_buffer (struct t_irc_server *server,
}
/* set highlights settings on channel buffer */
- weechat_buffer_set(
+ weechat_buffer_set (
ptr_buffer,
"highlight_words_add",
(channel_type == IRC_CHANNEL_TYPE_CHANNEL) ?
@@ -426,6 +427,7 @@ irc_channel_new (struct t_irc_server *server, int channel_type,
{
struct t_irc_channel *new_channel;
struct t_gui_buffer *ptr_buffer;
+ const char *ptr_chanmode;
/* create buffer for channel (or use existing one) */
ptr_buffer = irc_channel_create_buffer (server, channel_type,
@@ -479,6 +481,14 @@ irc_channel_new (struct t_irc_server *server, int channel_type,
new_channel->nicks_speaking[1] = NULL;
new_channel->nicks_speaking_time = NULL;
new_channel->last_nick_speaking_time = NULL;
+ new_channel->modelists = NULL;
+ new_channel->last_modelist = NULL;
+ for (ptr_chanmode = irc_server_get_chanmodes (server); ptr_chanmode[0];
+ ptr_chanmode++)
+ {
+ if (ptr_chanmode[0] != ',')
+ irc_modelist_new (new_channel, ptr_chanmode[0]);
+ }
new_channel->join_smart_filtered = NULL;
new_channel->buffer = ptr_buffer;
new_channel->buffer_as_string = NULL;
@@ -711,8 +721,8 @@ irc_channel_check_whox (struct t_irc_server *server,
}
else
{
- irc_channel_remove_account(server, channel);
- irc_channel_remove_away(server, channel);
+ irc_channel_remove_account (server, channel);
+ irc_channel_remove_away (server, channel);
}
}
}
@@ -1360,6 +1370,22 @@ irc_channel_display_nick_back_in_pv (struct t_irc_server *server,
}
/*
+ * Sets state for modelists in a channel.
+ */
+
+void
+irc_channel_modelist_set_state (struct t_irc_channel *channel, int state)
+{
+ struct t_irc_modelist *ptr_modelist;
+
+ for (ptr_modelist = channel->modelists; ptr_modelist;
+ ptr_modelist = ptr_modelist->next_modelist)
+ {
+ ptr_modelist->state = state;
+ }
+}
+
+/*
* Frees a channel and remove it from channels list.
*/
@@ -1387,6 +1413,7 @@ irc_channel_free (struct t_irc_server *server, struct t_irc_channel *channel)
/* free linked lists */
irc_nick_free_all (server, channel);
+ irc_modelist_free_all (channel);
/* free channel data */
if (channel->name)
@@ -1472,6 +1499,8 @@ irc_channel_hdata_channel_cb (const void *pointer, void *data,
WEECHAT_HDATA_VAR(struct t_irc_channel, nicks_speaking, POINTER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_channel, nicks_speaking_time, POINTER, 0, NULL, "irc_channel_speaking");
WEECHAT_HDATA_VAR(struct t_irc_channel, last_nick_speaking_time, POINTER, 0, NULL, "irc_channel_speaking");
+ WEECHAT_HDATA_VAR(struct t_irc_channel, modelists, POINTER, 0, NULL, "irc_modelist");
+ WEECHAT_HDATA_VAR(struct t_irc_channel, last_modelist, POINTER, 0, NULL, "irc_modelist");
WEECHAT_HDATA_VAR(struct t_irc_channel, join_smart_filtered, HASHTABLE, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_channel, buffer, POINTER, 0, NULL, "buffer");
WEECHAT_HDATA_VAR(struct t_irc_channel, buffer_as_string, STRING, 0, NULL, NULL);
@@ -1629,6 +1658,7 @@ irc_channel_print_log (struct t_irc_channel *channel)
struct t_irc_channel_speaking *ptr_nick_speaking;
int i, index;
struct t_irc_nick *ptr_nick;
+ struct t_irc_modelist *ptr_modelist;
weechat_log_printf ("");
weechat_log_printf (" => channel %s (addr:0x%lx):", channel->name, channel);
@@ -1656,6 +1686,8 @@ irc_channel_print_log (struct t_irc_channel *channel)
weechat_log_printf (" nicks_speaking[1]. . . . : 0x%lx", channel->nicks_speaking[1]);
weechat_log_printf (" nicks_speaking_time. . . : 0x%lx", channel->nicks_speaking_time);
weechat_log_printf (" last_nick_speaking_time. : 0x%lx", channel->last_nick_speaking_time);
+ weechat_log_printf (" modelists. . . . . . . . : 0x%lx", channel->modelists);
+ weechat_log_printf (" last_modelist. . . . . . : 0x%lx", channel->last_modelist);
weechat_log_printf (" join_smart_filtered. . . : 0x%lx (hashtable: '%s')",
channel->join_smart_filtered,
weechat_hashtable_get_string (channel->join_smart_filtered,
@@ -1686,13 +1718,18 @@ irc_channel_print_log (struct t_irc_channel *channel)
ptr_nick_speaking;
ptr_nick_speaking = ptr_nick_speaking->next_nick)
{
- weechat_log_printf (" nick speaking time: '%s', time: %ld",
+ weechat_log_printf (" nick speaking time: '%s', time: %lld",
ptr_nick_speaking->nick,
- ptr_nick_speaking->time_last_message);
+ (long long)ptr_nick_speaking->time_last_message);
}
}
for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick)
{
irc_nick_print_log (ptr_nick);
}
+ for (ptr_modelist = channel->modelists; ptr_modelist;
+ ptr_modelist = ptr_modelist->next_modelist)
+ {
+ irc_modelist_print_log (ptr_modelist);
+ }
}
diff --git a/src/plugins/irc/irc-channel.h b/src/plugins/irc/irc-channel.h
index 73a68b712..d078d1d33 100644
--- a/src/plugins/irc/irc-channel.h
+++ b/src/plugins/irc/irc-channel.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_CHANNEL_H
-#define WEECHAT_IRC_CHANNEL_H 1
+#ifndef WEECHAT_PLUGIN_IRC_CHANNEL_H
+#define WEECHAT_PLUGIN_IRC_CHANNEL_H
#include <time.h>
@@ -32,6 +32,7 @@
#define IRC_CHANNEL_NICKS_SPEAKING_LIMIT 128
struct t_irc_server;
+struct t_irc_modelist;
struct t_irc_channel_speaking
{
@@ -71,6 +72,8 @@ struct t_irc_channel
struct t_irc_channel_speaking *nicks_speaking_time; /* for smart filter */
/* of join/part/quit messages */
struct t_irc_channel_speaking *last_nick_speaking_time;
+ struct t_irc_modelist *modelists; /* modelists in the channel */
+ struct t_irc_modelist *last_modelist; /* last modelist in the channel */
struct t_hashtable *join_smart_filtered; /* smart filtered joins */
struct t_gui_buffer *buffer; /* buffer allocated for channel */
char *buffer_as_string; /* used to return buffer info */
@@ -158,6 +161,8 @@ extern int irc_channel_autorejoin_cb (const void *pointer, void *data,
extern void irc_channel_display_nick_back_in_pv (struct t_irc_server *server,
struct t_irc_nick *nick,
const char *nickname);
+extern void irc_channel_modelist_set_state (struct t_irc_channel *channel,
+ int state);
extern struct t_hdata *irc_channel_hdata_channel_cb (const void *pointer,
void *data,
const char *hdata_name);
@@ -168,4 +173,4 @@ extern int irc_channel_add_to_infolist (struct t_infolist *infolist,
struct t_irc_channel *channel);
extern void irc_channel_print_log (struct t_irc_channel *channel);
-#endif /* WEECHAT_IRC_CHANNEL_H */
+#endif /* WEECHAT_PLUGIN_IRC_CHANNEL_H */
diff --git a/src/plugins/irc/irc-color.c b/src/plugins/irc/irc-color.c
index 20395c385..2f33e7db3 100644
--- a/src/plugins/irc/irc-color.c
+++ b/src/plugins/irc/irc-color.c
@@ -1,7 +1,7 @@
/*
* irc-color.c - IRC color decoding/encoding in messages
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-color.h b/src/plugins/irc/irc-color.h
index 218c20432..82004cff5 100644
--- a/src/plugins/irc/irc-color.h
+++ b/src/plugins/irc/irc-color.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_COLOR_H
-#define WEECHAT_IRC_COLOR_H 1
+#ifndef WEECHAT_PLUGIN_IRC_COLOR_H
+#define WEECHAT_PLUGIN_IRC_COLOR_H
#define IRC_NUM_COLORS 100
@@ -114,4 +114,4 @@ extern char *irc_color_for_tags (const char *color);
extern int irc_color_weechat_add_to_infolist (struct t_infolist *infolist);
extern void irc_color_end ();
-#endif /* WEECHAT_IRC_COLOR_H */
+#endif /* WEECHAT_PLUGIN_IRC_COLOR_H */
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index bb40e000d..22a1977e2 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -1,7 +1,7 @@
/*
* irc-command.c - IRC commands
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
* Copyright (C) 2006 Emmanuel Bouthenot <kolter@openics.org>
*
* This file is part of WeeChat, the extensible chat client.
@@ -30,6 +30,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
+#include <regex.h>
#include "../weechat-plugin.h"
#include "irc.h"
@@ -42,6 +43,7 @@
#include "irc-input.h"
#include "irc-message.h"
#include "irc-mode.h"
+#include "irc-modelist.h"
#include "irc-msgbuffer.h"
#include "irc-nick.h"
#include "irc-notify.h"
@@ -238,6 +240,10 @@ irc_command_mode_masks (struct t_irc_server *server,
char modes[128+1], masks[1024], *mask;
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick;
+ struct t_irc_modelist *ptr_modelist;
+ struct t_irc_modelist_item *ptr_item;
+ long number;
+ char *error;
if (irc_mode_get_chanmode_type (server, mode[0]) != 'A')
{
@@ -265,15 +271,31 @@ irc_command_mode_masks (struct t_irc_server *server,
masks[0] = '\0';
ptr_channel = irc_channel_search (server, channel_name);
+ ptr_modelist = irc_modelist_search (ptr_channel, mode[0]);
for (; argv[pos_masks]; pos_masks++)
{
mask = NULL;
- /* use default_ban_mask for nick arguments */
if (ptr_channel)
{
- if (!strchr (argv[pos_masks], '!')
+ /* use modelist item for number arguments */
+ if (ptr_modelist && (set[0] == '-'))
+ {
+ error = NULL;
+ number = strtol (argv[pos_masks], &error, 10);
+ if (error && !error[0])
+ {
+ ptr_item = irc_modelist_item_search_number (ptr_modelist,
+ number - 1);
+ if (ptr_item)
+ mask = strdup (ptr_item->mask);
+ }
+ }
+
+ /* use default_ban_mask for nick arguments */
+ if (!mask
+ && !strchr (argv[pos_masks], '!')
&& !strchr (argv[pos_masks], '@'))
{
ptr_nick = irc_nick_search (server, ptr_channel,
@@ -1544,8 +1566,8 @@ IRC_COMMAND_CALLBACK(ctcp)
{
/* generate argument for PING if not provided */
gettimeofday (&tv, NULL);
- snprintf (str_time, sizeof (str_time), "%ld %ld",
- (long)tv.tv_sec, (long)tv.tv_usec);
+ snprintf (str_time, sizeof (str_time), "%lld %ld",
+ (long long)tv.tv_sec, (long)tv.tv_usec);
ctcp_args = str_time;
}
else
@@ -2562,7 +2584,8 @@ irc_command_join_server (struct t_irc_server *server, const char *arguments,
}
}
if (manual_join
- && weechat_config_boolean (irc_config_look_buffer_open_before_join))
+ && weechat_config_boolean (irc_config_look_buffer_open_before_join)
+ && !irc_channel_search (server, pos_channel))
{
/*
* open the channel buffer immediately (do not wait for the
@@ -2914,98 +2937,95 @@ IRC_COMMAND_CALLBACK(links)
IRC_COMMAND_CALLBACK(list)
{
char buf[512], *ptr_channel_name, *ptr_server_name, *ptr_regex;
+ regex_t *new_regexp;
int i, ret;
IRC_BUFFER_GET_SERVER(buffer);
- IRC_COMMAND_CHECK_SERVER("list", 1);
/* make C compiler happy */
(void) pointer;
(void) data;
- if (ptr_server->cmd_list_regexp)
+ ptr_channel_name = NULL;
+ ptr_server_name = NULL;
+ ptr_regex = NULL;
+ new_regexp = NULL;
+
+ for (i = 1; i < argc; i++)
{
- regfree (ptr_server->cmd_list_regexp);
- free (ptr_server->cmd_list_regexp);
- ptr_server->cmd_list_regexp = NULL;
+ if (weechat_strcasecmp (argv[i], "-server") == 0)
+ {
+ if (argc <= i + 1)
+ WEECHAT_COMMAND_ERROR;
+ ptr_server = irc_server_search (argv[i + 1]);
+ if (!ptr_server)
+ WEECHAT_COMMAND_ERROR;
+ i++;
+ }
+ else if (weechat_strcasecmp (argv[i], "-re") == 0)
+ {
+ if (argc <= i + 1)
+ WEECHAT_COMMAND_ERROR;
+ ptr_regex = argv_eol[i + 1];
+ i++;
+ }
+ else if (!ptr_channel_name)
+ ptr_channel_name = argv[i];
+ else if (!ptr_server_name)
+ ptr_server_name = argv[i];
+ else
+ WEECHAT_COMMAND_ERROR;
}
- if (argc > 1)
+ IRC_COMMAND_CHECK_SERVER("list", 1);
+
+ if (ptr_regex)
{
- ptr_channel_name = NULL;
- ptr_server_name = NULL;
- ptr_regex = NULL;
- for (i = 1; i < argc; i++)
+ new_regexp = malloc (sizeof (*new_regexp));
+ if (!new_regexp)
{
- if (weechat_strcasecmp (argv[i], "-re") == 0)
- {
- if (i < argc - 1)
- {
- ptr_regex = argv_eol[i + 1];
- i++;
- }
- }
- else
- {
- if (!ptr_channel_name)
- ptr_channel_name = argv[i];
- else if (!ptr_server_name)
- ptr_server_name = argv[i];
- }
+ weechat_printf (
+ ptr_server->buffer,
+ _("%s%s: not enough memory for regular expression"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME);
+ return WEECHAT_RC_OK;
}
- if (!ptr_channel_name && !ptr_server_name && !ptr_regex)
+ ret = weechat_string_regcomp (new_regexp,
+ ptr_regex,
+ REG_EXTENDED | REG_ICASE | REG_NOSUB);
+ if (ret != 0)
{
- irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
- "LIST");
+ regerror (ret, new_regexp, buf, sizeof (buf));
+ weechat_printf (
+ ptr_server->buffer,
+ _("%s%s: \"%s\" is not a valid regular expression "
+ "(%s)"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME,
+ ptr_regex, buf);
+ free (new_regexp);
+ return WEECHAT_RC_OK;
}
- else
+ if (ptr_server->cmd_list_regexp)
{
- if (ptr_regex)
- {
- ptr_server->cmd_list_regexp = malloc (
- sizeof (*ptr_server->cmd_list_regexp));
- if (ptr_server->cmd_list_regexp)
- {
- if ((ret = weechat_string_regcomp (
- ptr_server->cmd_list_regexp, ptr_regex,
- REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0)
- {
- regerror (ret, ptr_server->cmd_list_regexp,
- buf, sizeof(buf));
- weechat_printf (
- ptr_server->buffer,
- _("%s%s: \"%s\" is not a valid regular expression "
- "(%s)"),
- weechat_prefix ("error"), IRC_PLUGIN_NAME,
- argv_eol[1], buf);
- free (ptr_server->cmd_list_regexp);
- ptr_server->cmd_list_regexp = NULL;
- return WEECHAT_RC_OK;
- }
- }
- else
- {
- weechat_printf (
- ptr_server->buffer,
- _("%s%s: not enough memory for regular expression"),
- weechat_prefix ("error"), IRC_PLUGIN_NAME);
- return WEECHAT_RC_OK;
- }
- }
- irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
- "LIST%s%s%s%s",
- (ptr_channel_name) ? " " : "",
- (ptr_channel_name) ? ptr_channel_name : "",
- (ptr_server_name) ? " " : "",
- (ptr_server_name) ? ptr_server_name : "");
+ regfree (ptr_server->cmd_list_regexp);
+ free (ptr_server->cmd_list_regexp);
}
+ ptr_server->cmd_list_regexp = new_regexp;
}
- else
+ else if (ptr_server->cmd_list_regexp)
{
- irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
- "LIST");
+ regfree (ptr_server->cmd_list_regexp);
+ free (ptr_server->cmd_list_regexp);
+ ptr_server->cmd_list_regexp = NULL;
}
+ irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
+ "LIST%s%s%s%s",
+ (ptr_channel_name) ? " " : "",
+ (ptr_channel_name) ? ptr_channel_name : "",
+ (ptr_server_name) ? " " : "",
+ (ptr_server_name) ? ptr_server_name : "");
+
return WEECHAT_RC_OK;
}
@@ -4606,13 +4626,22 @@ IRC_COMMAND_CALLBACK(saquit)
void
irc_command_display_server (struct t_irc_server *server, int with_detail)
{
- char *cmd_pwd_hidden;
+ char *cmd_pwd_hidden, str_nick[1024];
int num_channels, num_pv;
+ str_nick[0] = '\0';
+ if (server->nick)
+ {
+ snprintf (str_nick, sizeof (str_nick),
+ ", %s %s",
+ _("nick:"),
+ server->nick);
+ }
+
if (with_detail)
{
weechat_printf (NULL, "");
- weechat_printf (NULL, _("Server: %s%s %s[%s%s%s]%s%s"),
+ weechat_printf (NULL, _("Server: %s%s %s[%s%s%s]%s%s%s"),
IRC_COLOR_CHAT_SERVER,
server->name,
IRC_COLOR_CHAT_DELIMITERS,
@@ -4621,6 +4650,7 @@ irc_command_display_server (struct t_irc_server *server, int with_detail)
_("connected") : _("not connected"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_RESET,
+ str_nick,
(server->temp_server) ? _(" (temporary)") : "");
/* addresses */
if (weechat_config_option_is_null (server->options[IRC_SERVER_OPTION_ADDRESSES]))
@@ -4986,6 +5016,15 @@ irc_command_display_server (struct t_irc_server *server, int with_detail)
weechat_printf (NULL, " notify . . . . . . . : %s'%s'",
IRC_COLOR_CHAT_VALUE,
weechat_config_string (server->options[IRC_SERVER_OPTION_NOTIFY]));
+
+ /* split_msg_max_length */
+ if (weechat_config_option_is_null (server->options[IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH]))
+ weechat_printf (NULL, " split_msg_max_length : (%d)",
+ IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH));
+ else
+ weechat_printf (NULL, " split_msg_max_length : %s%d",
+ IRC_COLOR_CHAT_VALUE,
+ weechat_config_integer (server->options[IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH]));
}
else
{
@@ -4995,16 +5034,16 @@ irc_command_display_server (struct t_irc_server *server, int with_detail)
num_pv = irc_server_get_pv_count (server);
weechat_printf (
NULL,
- " %s %s%s %s[%s%s%s]%s%s, %d %s, %d pv",
+ " %s %s%s %s[%s%s%s]%s%s%s, %d %s, %d pv",
(server->is_connected) ? "*" : " ",
IRC_COLOR_CHAT_SERVER,
server->name,
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_RESET,
- (server->is_connected) ?
- _("connected") : _("not connected"),
+ (server->is_connected) ? _("connected") : _("not connected"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_RESET,
+ str_nick,
(server->temp_server) ? _(" (temporary)") : "",
num_channels,
NG_("channel", "channels", num_channels),
@@ -6563,20 +6602,21 @@ irc_command_init ()
"links",
N_("list all servernames which are known by the server answering the "
"query"),
- N_("[[<server>] <server_mask>]"),
- N_(" server: this server should answer the query\n"
+ N_("[[<target>] <server_mask>]"),
+ N_(" target: this remote server should answer the query\n"
"server_mask: list of servers must match this mask"),
NULL, &irc_command_links, NULL, NULL);
weechat_hook_command (
"list",
N_("list channels and their topic"),
- N_("[<channel>[,<channel>...]] [<server>] "
- "[-re <regex>]"),
- N_("channel: channel to list\n"
- " server: server name\n"
+ N_("[-server <server>] [-re <regex>] [<channel>[,<channel>...]] "
+ "[<target>]"),
+ N_(" server: send to this server (internal name)\n"
" regex: POSIX extended regular expression used to filter results "
"(case insensitive, can start by \"(?-i)\" to become case "
"sensitive)\n"
+ "channel: channel to list\n"
+ " target: server name\n"
"\n"
"Examples:\n"
" list all channels on server (can be very slow on large networks):\n"
@@ -6586,7 +6626,9 @@ irc_command_init ()
" list all channels beginning with \"#weechat\" (can be very slow "
"on large networks):\n"
" /list -re #weechat.*"),
- NULL, &irc_command_list, NULL, NULL);
+ "-server %(irc_servers)"
+ " || -re",
+ &irc_command_list, NULL, NULL);
weechat_hook_command (
"lusers",
N_("get statistics about the size of the IRC network"),
@@ -6732,9 +6774,9 @@ irc_command_init ()
weechat_hook_command (
"ping",
N_("send a ping to server"),
- N_("<server1> [<server2>]"),
- N_("server1: server\n"
- "server2: forward ping to this server"),
+ N_("<target1> [<target2>]"),
+ N_("target1: server\n"
+ "target2: forward ping to this server"),
NULL, &irc_command_ping, NULL, NULL);
weechat_hook_command (
"pong",
@@ -6849,18 +6891,20 @@ irc_command_init ()
weechat_hook_command (
"server",
N_("list, add or remove IRC servers"),
- N_("list|listfull [<server>]"
- " || add <server> <hostname>[/<port>] [-temp] [-<option>[=<value>]] "
+ N_("list|listfull [<name>]"
+ " || add <name> <hostname>[/<port>] [-temp] [-<option>[=<value>]] "
"[-no<option>]"
- " || copy|rename <server> <new_name>"
- " || reorder <server> [<server>...]"
- " || open <server>|-all [<server>...]"
- " || del|keep <server>"
+ " || copy|rename <name> <new_name>"
+ " || reorder <name> [<name>...]"
+ " || open <name>|-all [<name>...]"
+ " || del|keep <name>"
" || deloutq|jump|raw"),
N_(" list: list servers (without argument, this list is displayed)\n"
"listfull: list servers with detailed info for each server\n"
" add: add a new server\n"
- " server: server name, for internal and display use\n"
+ " name: server name, for internal and display use; this name "
+ "is used to connect to the server (/connect name) and to set server "
+ "options: irc.server.name.xxx\n"
"hostname: name or IP address of server, with optional port "
"(default: 6667), many addresses can be separated by a comma\n"
" -temp: add a temporary server (not saved)\n"
@@ -6919,16 +6963,16 @@ irc_command_init ()
weechat_hook_command (
"squit",
N_("disconnect server links"),
- N_("<server> <comment>"),
- N_( " server: server name\n"
+ N_("<target> <comment>"),
+ N_( " target: server name\n"
"comment: comment"),
NULL, &irc_command_squit, NULL, NULL);
weechat_hook_command (
"stats",
N_("query statistics about server"),
- N_("[<query> [<server>]]"),
+ N_("[<query> [<target>]]"),
N_(" query: c/h/i/k/l/m/o/y/u (see RFC1459)\n"
- "server: server name"),
+ "target: server name"),
NULL, &irc_command_stats, NULL, NULL);
weechat_hook_command (
"summon",
@@ -6963,17 +7007,21 @@ irc_command_init ()
weechat_hook_command (
"unban",
N_("unban nicks or hosts"),
- N_("[<channel>] <nick> [<nick>...]"),
+ N_("[<channel>] <nick>|<number> [<nick>|<number>...]"),
N_("channel: channel name\n"
- " nick: nick or host"),
- NULL, &irc_command_unban, NULL, NULL);
+ " nick: nick or host\n"
+ " number: ban number (as displayed by command /ban)"),
+ "%(irc_modelist_masks:b)|%(irc_modelist_numbers:b)",
+ &irc_command_unban, NULL, NULL);
weechat_hook_command (
"unquiet",
N_("unquiet nicks or hosts"),
- N_("[<channel>] <nick> [<nick>...]"),
+ N_("[<channel>] <nick>|<number> [<nick>|<number>...]"),
N_("channel: channel name\n"
- " nick: nick or host"),
- "%(irc_channel_nicks_hosts)", &irc_command_unquiet, NULL, NULL);
+ " nick: nick or host\n"
+ " number: quiet number (as displayed by command /quiet)"),
+ "%(irc_modelist_masks:q)|%(irc_modelist_numbers:q)",
+ &irc_command_unquiet, NULL, NULL);
weechat_hook_command (
"userhost",
N_("return a list of information about nicks"),
@@ -6989,8 +7037,8 @@ irc_command_init ()
weechat_hook_command (
"version",
N_("give the version info of nick or server (current or specified)"),
- N_("[<server>|<nick>]"),
- N_("server: server name\n"
+ N_("[<target>|<nick>]"),
+ N_("target: server name\n"
" nick: nick"),
"%(nicks)", &irc_command_version, NULL, NULL);
weechat_hook_command (
@@ -7024,8 +7072,8 @@ irc_command_init ()
weechat_hook_command (
"whois",
N_("query information about user(s)"),
- N_("[<server>] [<nick>[,<nick>...]]"),
- N_("server: server name\n"
+ N_("[<target>] [<nick>[,<nick>...]]"),
+ N_("target: server name\n"
" nick: nick (may be a mask)\n"
"\n"
"Without argument, this command will do a whois on:\n"
diff --git a/src/plugins/irc/irc-command.h b/src/plugins/irc/irc-command.h
index 67ddd506e..c6a31dc57 100644
--- a/src/plugins/irc/irc-command.h
+++ b/src/plugins/irc/irc-command.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_COMMAND_H
-#define WEECHAT_IRC_COMMAND_H 1
+#ifndef WEECHAT_PLUGIN_IRC_COMMAND_H
+#define WEECHAT_PLUGIN_IRC_COMMAND_H
struct t_irc_server;
struct t_irc_channel;
@@ -77,4 +77,4 @@ extern void irc_command_quit_server (struct t_irc_server *server,
const char *arguments);
extern void irc_command_init ();
-#endif /* WEECHAT_IRC_COMMAND_H */
+#endif /* WEECHAT_PLUGIN_IRC_COMMAND_H */
diff --git a/src/plugins/irc/irc-completion.c b/src/plugins/irc/irc-completion.c
index 3562e3d84..4e72a8570 100644
--- a/src/plugins/irc/irc-completion.c
+++ b/src/plugins/irc/irc-completion.c
@@ -1,7 +1,7 @@
/*
* irc-completion.c - completion for IRC commands
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -31,6 +31,7 @@
#include "irc-completion.h"
#include "irc-config.h"
#include "irc-ignore.h"
+#include "irc-modelist.h"
#include "irc-nick.h"
#include "irc-notify.h"
#include "irc-server.h"
@@ -421,6 +422,92 @@ irc_completion_channel_nicks_hosts_cb (const void *pointer, void *data,
}
/*
+ * Adds modelist masks of current channel to completion list.
+ */
+
+int
+irc_completion_modelist_masks_cb (const void *pointer, void *data,
+ const char *completion_item,
+ struct t_gui_buffer *buffer,
+ struct t_gui_completion *completion)
+{
+ char *pos;
+ struct t_irc_modelist *ptr_modelist;
+ struct t_irc_modelist_item *ptr_item;
+
+ IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ pos = strchr (completion_item, ':');
+ if (pos)
+ pos++;
+
+ if (pos && pos[0] && ptr_channel)
+ {
+ ptr_modelist = irc_modelist_search (ptr_channel, pos[0]);
+ if (ptr_modelist)
+ {
+ for (ptr_item = ptr_modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ weechat_hook_completion_list_add (completion,
+ ptr_item->mask,
+ 0, WEECHAT_LIST_POS_END);
+ }
+ }
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * Adds modelist numbers of current channel to completion list.
+ */
+
+int
+irc_completion_modelist_numbers_cb (const void *pointer, void *data,
+ const char *completion_item,
+ struct t_gui_buffer *buffer,
+ struct t_gui_completion *completion)
+{
+ char *pos, str_number[32];
+ struct t_irc_modelist *ptr_modelist;
+ struct t_irc_modelist_item *ptr_item;
+
+ IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ pos = strchr (completion_item, ':');
+ if (pos)
+ pos++;
+
+ if (pos && pos[0] && ptr_channel)
+ {
+ ptr_modelist = irc_modelist_search (ptr_channel, pos[0]);
+ if (ptr_modelist)
+ {
+ for (ptr_item = ptr_modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ snprintf (str_number, sizeof (str_number),
+ "%d", ptr_item->number + 1);
+ weechat_hook_completion_list_add (completion,
+ str_number,
+ 0, WEECHAT_LIST_POS_END);
+ }
+ }
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* Adds topic of current channel to completion list.
*/
@@ -758,6 +845,14 @@ irc_completion_init ()
weechat_hook_completion ("irc_channel_nicks_hosts",
N_("nicks and hostnames of current IRC channel"),
&irc_completion_channel_nicks_hosts_cb, NULL, NULL);
+ weechat_hook_completion ("irc_modelist_masks",
+ N_("modelist masks of current IRC channel; "
+ "required argument: modelist mode"),
+ &irc_completion_modelist_masks_cb, NULL, NULL);
+ weechat_hook_completion ("irc_modelist_numbers",
+ N_("modelist numbers of current IRC channel; "
+ "required argument: modelist mode"),
+ &irc_completion_modelist_numbers_cb, NULL, NULL);
weechat_hook_completion ("irc_channel_topic",
N_("topic of current IRC channel"),
&irc_completion_channel_topic_cb, NULL, NULL);
diff --git a/src/plugins/irc/irc-completion.h b/src/plugins/irc/irc-completion.h
index 5d644f44c..21659d1a5 100644
--- a/src/plugins/irc/irc-completion.h
+++ b/src/plugins/irc/irc-completion.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,9 +17,9 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_COMPLETION_H
-#define WEECHAT_IRC_COMPLETION_H 1
+#ifndef WEECHAT_PLUGIN_IRC_COMPLETION_H
+#define WEECHAT_PLUGIN_IRC_COMPLETION_H
extern void irc_completion_init ();
-#endif /* WEECHAT_IRC_COMPLETION_H */
+#endif /* WEECHAT_PLUGIN_IRC_COMPLETION_H */
diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c
index 1b1c85a98..04bccb25c 100644
--- a/src/plugins/irc/irc-config.c
+++ b/src/plugins/irc/irc-config.c
@@ -1,7 +1,7 @@
/*
* irc-config.c - IRC configuration options (file irc.conf)
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -23,7 +23,6 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
-#include <ctype.h>
#include <time.h>
#include <limits.h>
#include <pwd.h>
@@ -224,7 +223,7 @@ irc_config_compute_nick_colors ()
}
/* if colors are displayed for nicks in nicklist, refresh them */
- if (weechat_config_boolean(irc_config_look_color_nicks_in_nicklist))
+ if (weechat_config_boolean (irc_config_look_color_nicks_in_nicklist))
irc_nick_nicklist_set_color_all ();
}
@@ -995,11 +994,9 @@ irc_config_server_check_value_cb (const void *pointer, void *data,
{
int index_option, proxy_found;
const char *pos_error, *proxy_name;
+ char *error;
+ long number;
struct t_infolist *infolist;
-#ifdef HAVE_GNUTLS
- char *fingerprint_eval, **fingerprints, *str_sizes;
- int i, j, rc, algo, length;
-#endif /* HAVE_GNUTLS */
/* make C compiler happy */
(void) data;
@@ -1051,81 +1048,30 @@ irc_config_server_check_value_cb (const void *pointer, void *data,
return 0;
}
break;
- case IRC_SERVER_OPTION_SSL_FINGERPRINT:
-#ifdef HAVE_GNUTLS
+ case IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH:
if (!value || !value[0])
break;
- fingerprint_eval = weechat_string_eval_expression (
- value, NULL, NULL, NULL);
- if (!fingerprint_eval || !fingerprint_eval[0])
- {
- weechat_printf (
- NULL,
- _("%s%s: the evaluated fingerprint must not be "
- "empty"),
- weechat_prefix ("error"),
- IRC_PLUGIN_NAME);
- if (fingerprint_eval)
- free (fingerprint_eval);
- return 0;
- }
- fingerprints = weechat_string_split (
- (fingerprint_eval) ? fingerprint_eval : value,
- ",", 0, 0, NULL);
- if (!fingerprints)
+ error = NULL;
+ number = strtol (value, &error, 10);
+ if (!error || error[0])
{
- free (fingerprint_eval);
+ /*
+ * not a valid number, but we return 1 (OK) to let WeeChat
+ * display the appropriate error
+ */
return 1;
}
- rc = 0;
- for (i = 0; fingerprints[i]; i++)
- {
- length = strlen (fingerprints[i]);
- algo = irc_server_fingerprint_search_algo_with_size (
- length * 4);
- if (algo < 0)
- {
- rc = -1;
- break;
- }
- for (j = 0; j < length; j++)
- {
- if (!isxdigit ((unsigned char)fingerprints[i][j]))
- {
- rc = -2;
- break;
- }
- }
- if (rc < 0)
- break;
- }
- weechat_string_free_split (fingerprints);
- free (fingerprint_eval);
- switch (rc)
+ if ((number < 0)
+ || ((number > 0) && (number < 128))
+ || (number > 4096))
{
- case -1: /* invalid size */
- str_sizes = irc_server_fingerprint_str_sizes ();
- weechat_printf (
- NULL,
- _("%s%s: invalid fingerprint size, the "
- "number of hexadecimal digits must be "
- "one of: %s"),
- weechat_prefix ("error"),
- IRC_PLUGIN_NAME,
- (str_sizes) ? str_sizes : "?");
- if (str_sizes)
- free (str_sizes);
- return 0;
- case -2: /* invalid content */
- weechat_printf (
+ weechat_printf (
NULL,
- _("%s%s: invalid fingerprint, it must "
- "contain only hexadecimal digits (0-9, "
- "a-f)"),
+ _("%s%s: invalid length for split, it must be "
+ "either 0 or any integer between 128 and 4096"),
weechat_prefix ("error"), IRC_PLUGIN_NAME);
- return 0;
+ return 0;
}
-#endif /* HAVE_GNUTLS */
break;
}
}
@@ -1533,7 +1479,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
option_name, "string",
N_("list of hostname/port or IP/port for server (separated by "
"comma) "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1660,7 +1608,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
"fingerprints can be separated by commas; if this option "
"is set, the other checks on certificates are NOT "
"performed (option \"ssl_verify\") "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1693,7 +1643,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
config_file, section,
option_name, "string",
N_("password for server "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1757,7 +1709,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
option_name, "string",
N_("username for SASL authentication; this option is not used "
"for mechanism \"external\" "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1776,7 +1730,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
N_("password for SASL authentication; this option is not used "
"for mechanisms \"ecdsa-nist256p-challenge\" and "
"\"external\" "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1898,7 +1854,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
config_file, section,
option_name, "string",
N_("nicknames to use on server (separated by comma) "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1935,7 +1893,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
config_file, section,
option_name, "string",
N_("user name to use on server "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1952,7 +1912,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
config_file, section,
option_name, "string",
N_("real name to use on server "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -1989,7 +1951,10 @@ irc_config_server_new_option (struct t_config_file *config_file,
"executing command and the auto-join of channels; examples: "
"\"+R\" (to set mode \"R\"), \"+R-i\" (to set mode \"R\" "
"and remove \"i\"); see /help mode for the complete mode "
- "syntax (note: content is evaluated, see /help eval)"),
+ "syntax "
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -2009,7 +1974,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
"auto-join of channels (many commands can be separated by "
"\";\", use \"\\;\" for a semicolon, special variables "
"$nick, $channel and $server are replaced by their value) "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -2050,7 +2017,9 @@ irc_config_server_new_option (struct t_config_file *config_file,
"channels (separated by a space) (example: \"#channel1,"
"#channel2,#channel3 key1,key2\" where #channel1 and "
"#channel2 are protected by key1 and key2) "
- "(note: content is evaluated, see /help eval)"),
+ "(note: content is evaluated, see /help eval; server "
+ "options are evaluated with ${irc_server.xxx} and "
+ "${server} is replaced by the server name)"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
@@ -2264,6 +2233,29 @@ irc_config_server_new_option (struct t_config_file *config_file,
callback_change_data,
NULL, NULL, NULL);
break;
+ case IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH:
+ new_option = weechat_config_new_option (
+ config_file, section,
+ option_name, "integer",
+ N_("split outgoing IRC messages to fit in this number of chars; "
+ "the default value is 512, this is a safe and recommended "
+ "value; "
+ "value 0 disables the split (not recommended, unless you "
+ "know what you do); allowed values are 0 or "
+ "any integer between 128 and 4096; "
+ "this option should be changed only on non-standard IRC "
+ "servers, for example gateways like bitlbee"),
+ NULL, 0, 4096,
+ default_value, value,
+ null_value_allowed,
+ callback_check_value,
+ callback_check_value_pointer,
+ callback_check_value_data,
+ callback_change,
+ callback_change_pointer,
+ callback_change_data,
+ NULL, NULL, NULL);
+ break;
case IRC_SERVER_NUM_OPTIONS:
break;
}
@@ -2510,6 +2502,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
@@ -2816,9 +2809,10 @@ irc_config_init ()
irc_config_file, ptr_section,
"notice_welcome_redirect", "boolean",
N_("automatically redirect channel welcome notices to the channel "
- "buffer; such notices have the nick as target but a channel name in "
- "beginning of notice message, for example notices sent by freenode "
- "server which look like: \"[#channel] Welcome to this channel...\""),
+ "buffer; such notices have the nick as target but a channel name "
+ "in beginning of notice message, for example the ENTRYMSG notices "
+ "sent by Atheme IRC Services which look like: "
+ "\"[#channel] Welcome to this channel...\""),
NULL, 0, 0, "on", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
irc_config_look_notice_welcome_tags = weechat_config_new_option (
@@ -2968,6 +2962,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
@@ -3097,6 +3092,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
@@ -3242,6 +3238,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
irc_config_section_msgbuffer = ptr_section;
@@ -3258,6 +3255,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
irc_config_section_ctcp = ptr_section;
@@ -3274,6 +3272,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
@@ -3289,6 +3288,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
irc_config_section_server_default = ptr_section;
@@ -3307,6 +3307,7 @@ irc_config_init ()
if (!ptr_section)
{
weechat_config_free (irc_config_file);
+ irc_config_file = NULL;
return 0;
}
irc_config_section_server = ptr_section;
diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h
index ab745e702..e27313614 100644
--- a/src/plugins/irc/irc-config.h
+++ b/src/plugins/irc/irc-config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_CONFIG_H
-#define WEECHAT_IRC_CONFIG_H 1
+#ifndef WEECHAT_PLUGIN_IRC_CONFIG_H
+#define WEECHAT_PLUGIN_IRC_CONFIG_H
#define IRC_CONFIG_NAME "irc"
@@ -215,4 +215,4 @@ extern int irc_config_read ();
extern int irc_config_write (int write_temp_servers);
extern void irc_config_free ();
-#endif /* WEECHAT_IRC_CONFIG_H */
+#endif /* WEECHAT_PLUGIN_IRC_CONFIG_H */
diff --git a/src/plugins/irc/irc-ctcp.c b/src/plugins/irc/irc-ctcp.c
index 8afee681c..112e842cb 100644
--- a/src/plugins/irc/irc-ctcp.c
+++ b/src/plugins/irc/irc-ctcp.c
@@ -1,7 +1,7 @@
/*
* irc-ctcp.c - IRC CTCP protocol
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -452,9 +452,10 @@ irc_ctcp_replace_variables (struct t_irc_server *server, const char *format)
now = time (NULL);
local_time = localtime (&now);
setlocale (LC_ALL, "C");
- strftime (buf, sizeof (buf),
- weechat_config_string (irc_config_look_ctcp_time_format),
- local_time);
+ if (strftime (buf, sizeof (buf),
+ weechat_config_string (irc_config_look_ctcp_time_format),
+ local_time) == 0)
+ buf[0] = '\0';
setlocale (LC_ALL, "");
temp = weechat_string_replace (res, "$time", buf);
free (res);
@@ -466,9 +467,9 @@ irc_ctcp_replace_variables (struct t_irc_server *server, const char *format)
* $username: user name, example:
* name
*/
- username = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERNAME),
- NULL, NULL, NULL);
+ username = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERNAME));
if (username)
{
temp = weechat_string_replace (res, "$username", username);
@@ -483,9 +484,9 @@ irc_ctcp_replace_variables (struct t_irc_server *server, const char *format)
* $realname: real name, example:
* John doe
*/
- realname = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_REALNAME),
- NULL, NULL, NULL);
+ realname = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_REALNAME));
if (realname)
{
temp = weechat_string_replace (res, "$realname", realname);
@@ -1084,8 +1085,21 @@ irc_ctcp_recv (struct t_irc_server *server, time_t date, const char *command,
address, arguments + 1, pos_args, reply);
if (!reply || reply[0])
{
- irc_ctcp_reply_to_nick (server, command, channel, nick,
- arguments + 1, pos_args);
+ if (reply)
+ {
+ decoded_reply = irc_ctcp_replace_variables (server, reply);
+ if (decoded_reply)
+ {
+ irc_ctcp_reply_to_nick (server, command, channel, nick,
+ arguments + 1, decoded_reply);
+ free (decoded_reply);
+ }
+ }
+ else
+ {
+ irc_ctcp_reply_to_nick (server, command, channel, nick,
+ arguments + 1, pos_args);
+ }
}
}
/* CTCP DCC */
diff --git a/src/plugins/irc/irc-ctcp.h b/src/plugins/irc/irc-ctcp.h
index 6fe8b6999..8478bfbe3 100644
--- a/src/plugins/irc/irc-ctcp.h
+++ b/src/plugins/irc/irc-ctcp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_CTCP_H
-#define WEECHAT_IRC_CTCP_H 1
+#ifndef WEECHAT_PLUGIN_IRC_CTCP_H
+#define WEECHAT_PLUGIN_IRC_CTCP_H
#include <time.h>
@@ -44,4 +44,4 @@ extern void irc_ctcp_recv (struct t_irc_server *server, time_t date,
const char *remote_nick, char *arguments,
char *message);
-#endif /* WEECHAT_IRC_CTCP_H */
+#endif /* WEECHAT_PLUGIN_IRC_CTCP_H */
diff --git a/src/plugins/irc/irc-debug.c b/src/plugins/irc/irc-debug.c
index 64e1de89e..79e9ac7f0 100644
--- a/src/plugins/irc/irc-debug.c
+++ b/src/plugins/irc/irc-debug.c
@@ -1,7 +1,7 @@
/*
* irc-debug.c - debug functions for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-debug.h b/src/plugins/irc/irc-debug.h
index 5305487df..b7fb094dc 100644
--- a/src/plugins/irc/irc-debug.h
+++ b/src/plugins/irc/irc-debug.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,9 +17,9 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_DEBUG_H
-#define WEECHAT_IRC_DEBUG_H 1
+#ifndef WEECHAT_PLUGIN_IRC_DEBUG_H
+#define WEECHAT_PLUGIN_IRC_DEBUG_H
extern void irc_debug_init ();
-#endif /* WEECHAT_IRC_DEBUG_H */
+#endif /* WEECHAT_PLUGIN_IRC_DEBUG_H */
diff --git a/src/plugins/irc/irc-ignore.c b/src/plugins/irc/irc-ignore.c
index cfc45d6c6..c96777cb0 100644
--- a/src/plugins/irc/irc-ignore.c
+++ b/src/plugins/irc/irc-ignore.c
@@ -1,7 +1,7 @@
/*
* irc-ignore.c - ignore (nicks/hosts) management for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-ignore.h b/src/plugins/irc/irc-ignore.h
index 887342cb1..072345f10 100644
--- a/src/plugins/irc/irc-ignore.h
+++ b/src/plugins/irc/irc-ignore.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_IGNORE_H
-#define WEECHAT_IRC_IGNORE_H 1
+#ifndef WEECHAT_PLUGIN_IRC_IGNORE_H
+#define WEECHAT_PLUGIN_IRC_IGNORE_H
#include <regex.h>
@@ -58,4 +58,4 @@ extern int irc_ignore_add_to_infolist (struct t_infolist *infolist,
struct t_irc_ignore *ignore);
extern void irc_ignore_print_log ();
-#endif /* WEECHAT_IRC_IGNORE_H */
+#endif /* WEECHAT_PLUGIN_IRC_IGNORE_H */
diff --git a/src/plugins/irc/irc-info.c b/src/plugins/irc/irc-info.c
index b8dc6f6e1..9ba65334c 100644
--- a/src/plugins/irc/irc-info.c
+++ b/src/plugins/irc/irc-info.c
@@ -1,7 +1,7 @@
/*
* irc-info.c - info, infolist and hdata hooks for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -30,6 +30,7 @@
#include "irc-config.h"
#include "irc-ignore.h"
#include "irc-message.h"
+#include "irc-modelist.h"
#include "irc-nick.h"
#include "irc-notify.h"
#include "irc-protocol.h"
@@ -574,6 +575,211 @@ irc_info_infolist_irc_channel_cb (const void *pointer, void *data,
}
/*
+ * Returns IRC infolist "irc_modelist".
+ */
+
+struct t_infolist *
+irc_info_infolist_irc_modelist_cb (const void *pointer, void *data,
+ const char *infolist_name,
+ void *obj_pointer, const char *arguments)
+{
+ struct t_infolist *ptr_infolist;
+ struct t_irc_server *ptr_server;
+ struct t_irc_channel *ptr_channel;
+ struct t_irc_modelist *ptr_modelist;
+ char **argv;
+ int argc;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) infolist_name;
+
+ if (!arguments || !arguments[0])
+ return NULL;
+
+ ptr_server = NULL;
+ ptr_channel = NULL;
+ argv = weechat_string_split (arguments, ",", 0, 0, &argc);
+ if (!argv)
+ return NULL;
+
+ if (argc >= 2)
+ {
+ ptr_server = irc_server_search (argv[0]);
+ if (!ptr_server)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ ptr_channel = irc_channel_search (ptr_server, argv[1]);
+ if (!ptr_channel)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ if (!obj_pointer && (argc >= 3))
+ {
+ obj_pointer = irc_modelist_search (ptr_channel, argv[2][0]);
+
+ if (!obj_pointer)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ }
+ }
+ weechat_string_free_split (argv);
+
+ if (!ptr_server || !ptr_channel)
+ return NULL;
+
+ if (obj_pointer && !irc_modelist_valid (ptr_channel, obj_pointer))
+ return NULL;
+
+ ptr_infolist = weechat_infolist_new ();
+ if (!ptr_infolist)
+ return NULL;
+
+ if (obj_pointer)
+ {
+ /* build list with only one modelist */
+ if (!irc_modelist_add_to_infolist (ptr_infolist, obj_pointer))
+ {
+ weechat_infolist_free (ptr_infolist);
+ return NULL;
+ }
+ return ptr_infolist;
+ }
+ else
+ {
+ /* build list with all modelists of channel */
+ for (ptr_modelist = ptr_channel->modelists; ptr_modelist;
+ ptr_modelist = ptr_modelist->next_modelist)
+ {
+ if (!irc_modelist_add_to_infolist (ptr_infolist, ptr_modelist))
+ {
+ weechat_infolist_free (ptr_infolist);
+ return NULL;
+ }
+ }
+ return ptr_infolist;
+ }
+
+ return NULL;
+}
+
+/*
+ * Returns IRC infolist "irc_modelist_item".
+ */
+
+struct t_infolist *
+irc_info_infolist_irc_modelist_item_cb (const void *pointer, void *data,
+ const char *infolist_name,
+ void *obj_pointer, const char *arguments)
+{
+ struct t_infolist *ptr_infolist;
+ struct t_irc_server *ptr_server;
+ struct t_irc_channel *ptr_channel;
+ struct t_irc_modelist *ptr_modelist;
+ struct t_irc_modelist_item *ptr_item;
+ char **argv, *error;
+ int argc;
+ long number;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) infolist_name;
+
+ if (!arguments || !arguments[0])
+ return NULL;
+
+ ptr_server = NULL;
+ ptr_channel = NULL;
+ argv = weechat_string_split (arguments, ",", 0, 0, &argc);
+ if (!argv)
+ return NULL;
+
+ if (argc >= 3)
+ {
+ ptr_server = irc_server_search (argv[0]);
+ if (!ptr_server)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ ptr_channel = irc_channel_search (ptr_server, argv[1]);
+ if (!ptr_channel)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ ptr_modelist = irc_modelist_search (ptr_channel, argv[2][0]);
+ if (!ptr_modelist)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ if (!obj_pointer && (argc >= 4))
+ {
+ error = NULL;
+ number = strtol (argv[3], &error, 10);
+ if (!error || error[0] || (number < 0))
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ obj_pointer = irc_modelist_item_search_number (ptr_modelist,
+ (int)number);
+ if (!obj_pointer)
+ {
+ weechat_string_free_split (argv);
+ return NULL;
+ }
+ }
+ }
+ weechat_string_free_split (argv);
+
+ if (!ptr_server || !ptr_channel || !ptr_modelist)
+ return NULL;
+
+ if (obj_pointer && !irc_modelist_item_valid (ptr_modelist, obj_pointer))
+ return NULL;
+
+ ptr_infolist = weechat_infolist_new ();
+ if (!ptr_infolist)
+ return NULL;
+
+ if (obj_pointer)
+ {
+ /* build list with only one modelist item */
+ if (!irc_modelist_item_add_to_infolist (ptr_infolist, obj_pointer))
+ {
+ weechat_infolist_free (ptr_infolist);
+ return NULL;
+ }
+ return ptr_infolist;
+ }
+ else
+ {
+ /* build list with all modelist items of modelist */
+ for (ptr_item = ptr_modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ if (!irc_modelist_item_add_to_infolist (ptr_infolist, ptr_item))
+ {
+ weechat_infolist_free (ptr_infolist);
+ return NULL;
+ }
+ }
+ return ptr_infolist;
+ }
+
+ return NULL;
+}
+
+/*
* Returns IRC infolist "irc_nick".
*/
@@ -898,7 +1104,7 @@ irc_info_init ()
&irc_info_info_hashtable_irc_message_parse_cb, NULL, NULL);
weechat_hook_info_hashtable (
"irc_message_split",
- N_("split an IRC message (to fit in 512 bytes)"),
+ N_("split an IRC message (to fit in 512 bytes by default)"),
N_("\"message\": IRC message, \"server\": server name (optional)"),
/* TRANSLATORS: please do not translate key names (enclosed by quotes) */
N_("\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
@@ -920,6 +1126,18 @@ irc_info_init ()
N_("server,channel (channel is optional)"),
&irc_info_infolist_irc_channel_cb, NULL, NULL);
weechat_hook_infolist (
+ "irc_modelist",
+ N_("list of channel mode lists for an IRC channel"),
+ N_("mode list pointer (optional)"),
+ N_("server,channel,type (type is optional)"),
+ &irc_info_infolist_irc_modelist_cb, NULL, NULL);
+ weechat_hook_infolist (
+ "irc_modelist_item",
+ N_("list of items in a channel mode list"),
+ N_("mode list item pointer (optional)"),
+ N_("server,channel,type,number (number is optional)"),
+ &irc_info_infolist_irc_modelist_item_cb, NULL, NULL);
+ weechat_hook_infolist (
"irc_nick",
N_("list of nicks for an IRC channel"),
N_("nick pointer (optional)"),
@@ -949,6 +1167,12 @@ irc_info_init ()
"irc_nick", N_("irc nick"),
&irc_nick_hdata_nick_cb, NULL, NULL);
weechat_hook_hdata (
+ "irc_modelist", N_("irc modelist"),
+ &irc_modelist_hdata_modelist_cb, NULL, NULL);
+ weechat_hook_hdata (
+ "irc_modelist_item", N_("irc modelist item"),
+ &irc_modelist_hdata_item_cb, NULL, NULL);
+ weechat_hook_hdata (
"irc_channel", N_("irc channel"),
&irc_channel_hdata_channel_cb, NULL, NULL);
weechat_hook_hdata (
diff --git a/src/plugins/irc/irc-info.h b/src/plugins/irc/irc-info.h
index abe44cfb7..765f058c3 100644
--- a/src/plugins/irc/irc-info.h
+++ b/src/plugins/irc/irc-info.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,9 +17,9 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_INFO_H
-#define WEECHAT_IRC_INFO_H 1
+#ifndef WEECHAT_PLUGIN_IRC_INFO_H
+#define WEECHAT_PLUGIN_IRC_INFO_H
extern void irc_info_init ();
-#endif /* WEECHAT_IRC_INFO_H */
+#endif /* WEECHAT_PLUGIN_IRC_INFO_H */
diff --git a/src/plugins/irc/irc-input.c b/src/plugins/irc/irc-input.c
index 850642139..e2139c898 100644
--- a/src/plugins/irc/irc-input.c
+++ b/src/plugins/irc/irc-input.c
@@ -1,7 +1,7 @@
/*
* irc-input.c - input data management for IRC buffers
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -139,7 +139,8 @@ irc_input_user_message_display (struct t_gui_buffer *buffer, int action,
}
/*
- * Sends a PRIVMSG message, and split it if message size is > 512 bytes.
+ * Sends a PRIVMSG message, and split it if message size is > 512 bytes
+ * (by default).
*
* Warning: this function makes temporary changes in "message".
*/
diff --git a/src/plugins/irc/irc-input.h b/src/plugins/irc/irc-input.h
index 023aba39d..542340ef1 100644
--- a/src/plugins/irc/irc-input.h
+++ b/src/plugins/irc/irc-input.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_INPUT_H
-#define WEECHAT_IRC_INPUT_H 1
+#ifndef WEECHAT_PLUGIN_IRC_INPUT_H
+#define WEECHAT_PLUGIN_IRC_INPUT_H
struct t_gui_buffer;
@@ -31,4 +31,4 @@ extern int irc_input_send_cb (const void *pointer, void *data,
const char *signal, const char *type_data,
void *signal_data);
-#endif /* WEECHAT_IRC_INPUT_H */
+#endif /* WEECHAT_PLUGIN_IRC_INPUT_H */
diff --git a/src/plugins/irc/irc-message.c b/src/plugins/irc/irc-message.c
index 1d377c701..2df6ab2e8 100644
--- a/src/plugins/irc/irc-message.c
+++ b/src/plugins/irc/irc-message.c
@@ -1,7 +1,7 @@
/*
* irc-message.c - functions for IRC messages
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -20,13 +20,15 @@
*/
#include <stdlib.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "../weechat-plugin.h"
#include "irc.h"
-#include "irc-server.h"
#include "irc-channel.h"
+#include "irc-config.h"
+#include "irc-server.h"
/*
@@ -111,9 +113,9 @@ irc_message_parse (struct t_irc_server *server, const char *message,
if (ptr_message[0] == '@')
{
/*
- * read tags (they are optional and enabled only if client enabled
- * a server capability, see:
- * http://ircv3.atheme.org/specification/message-tags-3.2)
+ * Read tags: they are optional and enabled only if client enabled
+ * a server capability.
+ * See: https://ircv3.github.io/specs/core/message-tags-3.2.html
*/
pos = strchr (ptr_message, ' ');
if (pos)
@@ -653,13 +655,14 @@ irc_message_split_string (struct t_hashtable *hashtable,
const char *arguments,
const char *suffix,
const char delimiter,
- int max_length_host)
+ int max_length_host,
+ int max_length)
{
const char *pos, *pos_max, *pos_next, *pos_last_delim;
- char message[1024], *dup_arguments;
- int max_length, number;
+ char message[8192], *dup_arguments;
+ int number;
- max_length = 510;
+ max_length -= 2; /* by default: 512 - 2 = 510 bytes */
if (max_length_host >= 0)
max_length -= max_length_host;
else
@@ -707,7 +710,7 @@ irc_message_split_string (struct t_hashtable *hashtable,
pos = arguments;
pos_max = pos + max_length;
pos_last_delim = NULL;
- while (pos && pos[0])
+ while (pos[0])
{
if (pos[0] == delimiter)
pos_last_delim = pos;
@@ -753,12 +756,15 @@ irc_message_split_string (struct t_hashtable *hashtable,
int
irc_message_split_join (struct t_hashtable *hashtable,
const char *tags, const char *host,
- const char *arguments)
+ const char *arguments,
+ int max_length)
{
int number, channels_count, keys_count, length, length_no_channel;
int length_to_add, index_channel;
char **channels, **keys, *pos, *str;
- char msg_to_send[2048], keys_to_add[2048];
+ char msg_to_send[16384], keys_to_add[16384];
+
+ max_length -= 2; /* by default: 512 - 2 = 510 bytes */
number = 1;
@@ -799,7 +805,8 @@ irc_message_split_join (struct t_hashtable *hashtable,
length_to_add = 1 + strlen (channels[index_channel]);
if (index_channel < keys_count)
length_to_add += 1 + strlen (keys[index_channel]);
- if ((length + length_to_add < 510) || (length == length_no_channel))
+ if ((length + length_to_add < max_length)
+ || (length == length_no_channel))
{
if (length + length_to_add < (int)sizeof (msg_to_send))
{
@@ -864,9 +871,10 @@ int
irc_message_split_privmsg_notice (struct t_hashtable *hashtable,
char *tags, char *host, char *command,
char *target, char *arguments,
- int max_length_host)
+ int max_length_host,
+ int max_length)
{
- char prefix[512], suffix[2], *pos, saved_char;
+ char prefix[4096], suffix[2], *pos, saved_char;
int length, rc;
/*
@@ -903,7 +911,7 @@ irc_message_split_privmsg_notice (struct t_hashtable *hashtable,
rc = irc_message_split_string (hashtable, tags, host, command, target,
prefix, arguments, suffix,
- ' ', max_length_host);
+ ' ', max_length_host, max_length);
return rc;
}
@@ -919,9 +927,9 @@ irc_message_split_privmsg_notice (struct t_hashtable *hashtable,
int
irc_message_split_005 (struct t_hashtable *hashtable,
char *tags, char *host, char *command, char *target,
- char *arguments)
+ char *arguments, int max_length)
{
- char *pos, suffix[512];
+ char *pos, suffix[4096];
/*
* 005 message looks like:
@@ -941,7 +949,8 @@ irc_message_split_005 (struct t_hashtable *hashtable,
}
return irc_message_split_string (hashtable, tags, host, command, target,
- NULL, arguments, suffix, ' ', -1);
+ NULL, arguments, suffix, ' ', -1,
+ max_length);
}
/*
@@ -951,6 +960,10 @@ irc_message_split_005 (struct t_hashtable *hashtable,
* "\r\n", so full size is 512 bytes (the user data does not include the
* optional tags before the host).
*
+ * The 512 max length is the default (recommended) and can be changed with the
+ * server option called "split_msg_max_length" (0 to disable completely the
+ * split).
+ *
* The split takes care about type of message to do a split at best place in
* message.
*
@@ -972,9 +985,10 @@ struct t_hashtable *
irc_message_split (struct t_irc_server *server, const char *message)
{
struct t_hashtable *hashtable;
- char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512];
+ char **argv, **argv_eol, *tags, *host, *command, *arguments, target[4096];
char *pos, monitor_action[3];
int split_ok, argc, index_args, max_length_nick, max_length_host;
+ int split_msg_max_length;
split_ok = 0;
tags = NULL;
@@ -984,9 +998,29 @@ irc_message_split (struct t_irc_server *server, const char *message)
argv = NULL;
argv_eol = NULL;
+ if (server)
+ {
+ split_msg_max_length = IRC_SERVER_OPTION_INTEGER(
+ server, IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH);
+
+ /*
+ * split disabled? use a very high max_length so the message should
+ * never be split
+ */
+ if (split_msg_max_length == 0)
+ split_msg_max_length = INT_MAX - 16;
+ }
+ else
+ {
+ split_msg_max_length = 512; /* max length by default */
+ }
+
/* debug message */
if (weechat_irc_plugin->debug >= 2)
- weechat_printf (NULL, "irc_message_split: message='%s'", message);
+ {
+ weechat_printf (NULL, "irc_message_split: message='%s', max length=%d",
+ message, split_msg_max_length);
+ }
hashtable = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
@@ -1049,7 +1083,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
hashtable, tags, host, command, NULL, ":",
(argv_eol[index_args][0] == ':') ?
argv_eol[index_args] + 1 : argv_eol[index_args],
- NULL, ' ', max_length_host);
+ NULL, ' ', max_length_host, split_msg_max_length);
}
else if (weechat_strcasecmp (command, "monitor") == 0)
{
@@ -1064,7 +1098,8 @@ irc_message_split (struct t_irc_server *server, const char *message)
"%c ", argv_eol[index_args][0]);
split_ok = irc_message_split_string (
hashtable, tags, host, command, NULL, monitor_action,
- argv_eol[index_args] + 2, NULL, ',', max_length_host);
+ argv_eol[index_args] + 2, NULL, ',', max_length_host,
+ split_msg_max_length);
}
else
{
@@ -1072,17 +1107,17 @@ irc_message_split (struct t_irc_server *server, const char *message)
hashtable, tags, host, command, NULL, ":",
(argv_eol[index_args][0] == ':') ?
argv_eol[index_args] + 1 : argv_eol[index_args],
- NULL, ',', max_length_host);
+ NULL, ',', max_length_host, split_msg_max_length);
}
}
else if (weechat_strcasecmp (command, "join") == 0)
{
/* JOIN #channel1,#channel2,#channel3 key1,key2 */
- if (strlen (message) > 510)
+ if ((int)strlen (message) > split_msg_max_length - 2)
{
- /* split join if it's more than 510 bytes */
+ /* split join if it's too long */
split_ok = irc_message_split_join (hashtable, tags, host,
- arguments);
+ arguments, split_msg_max_length);
}
}
else if ((weechat_strcasecmp (command, "privmsg") == 0)
@@ -1098,7 +1133,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
hashtable, tags, host, command, argv[index_args],
(argv_eol[index_args + 1][0] == ':') ?
argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
- max_length_host);
+ max_length_host, split_msg_max_length);
}
}
else if (weechat_strcasecmp (command, "005") == 0)
@@ -1109,7 +1144,8 @@ irc_message_split (struct t_irc_server *server, const char *message)
split_ok = irc_message_split_005 (
hashtable, tags, host, command, argv[index_args],
(argv_eol[index_args + 1][0] == ':') ?
- argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1]);
+ argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
+ split_msg_max_length);
}
}
else if (weechat_strcasecmp (command, "353") == 0)
@@ -1128,7 +1164,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
hashtable, tags, host, command, target, ":",
(argv_eol[index_args + 2][0] == ':') ?
argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2],
- NULL, ' ', -1);
+ NULL, ' ', -1, split_msg_max_length);
}
else
{
@@ -1141,7 +1177,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
hashtable, tags, host, command, target, ":",
(argv_eol[index_args + 3][0] == ':') ?
argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3],
- NULL, ' ', -1);
+ NULL, ' ', -1, split_msg_max_length);
}
}
}
diff --git a/src/plugins/irc/irc-message.h b/src/plugins/irc/irc-message.h
index b1fa63e30..cbf2d331d 100644
--- a/src/plugins/irc/irc-message.h
+++ b/src/plugins/irc/irc-message.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_MESSAGE_H
-#define WEECHAT_IRC_MESSAGE_H 1
+#ifndef WEECHAT_PLUGIN_IRC_MESSAGE_H
+#define WEECHAT_PLUGIN_IRC_MESSAGE_H
struct t_irc_server;
struct t_irc_channel;
@@ -43,4 +43,4 @@ extern char *irc_message_replace_vars (struct t_irc_server *server,
extern struct t_hashtable *irc_message_split (struct t_irc_server *server,
const char *message);
-#endif /* WEECHAT_IRC_MESSAGE_H */
+#endif /* WEECHAT_PLUGIN_IRC_MESSAGE_H */
diff --git a/src/plugins/irc/irc-mode.c b/src/plugins/irc/irc-mode.c
index d828a13a4..b5d525c6c 100644
--- a/src/plugins/irc/irc-mode.c
+++ b/src/plugins/irc/irc-mode.c
@@ -1,7 +1,7 @@
/*
* irc-mode.c - IRC channel/user modes management
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <time.h>
#include "../weechat-plugin.h"
#include "irc.h"
@@ -30,6 +31,7 @@
#include "irc-server.h"
#include "irc-channel.h"
#include "irc-nick.h"
+#include "irc-modelist.h"
/*
@@ -317,12 +319,15 @@ irc_mode_smart_filtered (struct t_irc_server *server, char mode)
int
irc_mode_channel_set (struct t_irc_server *server,
struct t_irc_channel *channel,
+ const char *host,
const char *modes)
{
char *pos_args, *str_modes, set_flag, **argv, *pos, *ptr_arg, chanmode_type;
int argc, current_arg, update_channel_modes, channel_modes_updated;
int smart_filter;
struct t_irc_nick *ptr_nick;
+ struct t_irc_modelist *ptr_modelist;
+ struct t_irc_modelist_item *ptr_item;
if (!server || !channel || !modes)
return 0;
@@ -464,6 +469,27 @@ irc_mode_channel_set (struct t_irc_server *server,
}
}
}
+ else if (chanmode_type == 'A')
+ {
+ /* modelist modes */
+ ptr_modelist = irc_modelist_search (channel, pos[0]);
+ if (ptr_modelist)
+ {
+ if (set_flag == '+')
+ {
+ irc_modelist_item_new (ptr_modelist, ptr_arg,
+ host, time (NULL));
+ }
+ else if (set_flag == '-')
+ {
+ ptr_item = irc_modelist_item_search_mask (
+ ptr_modelist, ptr_arg);
+ if (ptr_item)
+ irc_modelist_item_free (ptr_modelist, ptr_item);
+ }
+ }
+ }
+
if (update_channel_modes)
{
irc_mode_channel_update (server, channel, set_flag,
diff --git a/src/plugins/irc/irc-mode.h b/src/plugins/irc/irc-mode.h
index 03313d983..857a8a8fc 100644
--- a/src/plugins/irc/irc-mode.h
+++ b/src/plugins/irc/irc-mode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_MODE_H
-#define WEECHAT_IRC_MODE_H 1
+#ifndef WEECHAT_PLUGIN_IRC_MODE_H
+#define WEECHAT_PLUGIN_IRC_MODE_H
struct t_irc_server;
struct t_irc_channel;
@@ -27,8 +27,9 @@ extern char irc_mode_get_chanmode_type (struct t_irc_server *server,
char chanmode);
extern int irc_mode_channel_set (struct t_irc_server *server,
struct t_irc_channel *channel,
+ const char *host,
const char *modes);
extern void irc_mode_user_set (struct t_irc_server *server, const char *modes,
int reset_modes);
-#endif /* WEECHAT_IRC_MODE_H */
+#endif /* WEECHAT_PLUGIN_IRC_MODE_H */
diff --git a/src/plugins/irc/irc-modelist.c b/src/plugins/irc/irc-modelist.c
new file mode 100644
index 000000000..d21b34971
--- /dev/null
+++ b/src/plugins/irc/irc-modelist.c
@@ -0,0 +1,505 @@
+/*
+ * irc-modelist.c - channel mode list management for IRC plugin
+ *
+ * Copyright (C) 2015 Simmo Saan <simmo.saan@gmail.com>
+ * Copyright (C) 2018 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "../weechat-plugin.h"
+#include "irc.h"
+#include "irc-channel.h"
+#include "irc-modelist.h"
+
+
+/*
+ * Checks if a modelist pointer is valid for a channel.
+ *
+ * Returns:
+ * 1: modelist exists for channel
+ * 0: modelist does not exist for channel
+ */
+
+int
+irc_modelist_valid (struct t_irc_channel *channel,
+ struct t_irc_modelist *modelist)
+{
+ struct t_irc_modelist *ptr_modelist;
+
+ if (!channel || !modelist)
+ return 0;
+
+ for (ptr_modelist = channel->modelists; ptr_modelist;
+ ptr_modelist = ptr_modelist->next_modelist)
+ {
+ if (ptr_modelist == modelist)
+ return 1;
+ }
+
+ /* modelist not found */
+ return 0;
+}
+
+/*
+ * Searches for a modelist by type.
+ *
+ * Returns pointer to modelist found, NULL if not found.
+ */
+
+struct t_irc_modelist *
+irc_modelist_search (struct t_irc_channel *channel, char type)
+{
+ struct t_irc_modelist *ptr_modelist;
+
+ if (!channel)
+ return NULL;
+
+ for (ptr_modelist = channel->modelists; ptr_modelist;
+ ptr_modelist = ptr_modelist->next_modelist)
+ {
+ if (ptr_modelist->type == type)
+ return ptr_modelist;
+ }
+ return NULL;
+}
+
+/*
+ * Creates a new modelist in a channel.
+ *
+ * Returns pointer to new modelist, NULL if error.
+ */
+
+struct t_irc_modelist *
+irc_modelist_new (struct t_irc_channel *channel, char type)
+{
+ struct t_irc_modelist *new_modelist;
+
+ /* alloc memory for new modelist */
+ if ((new_modelist = malloc (sizeof (*new_modelist))) == NULL)
+ {
+ weechat_printf (NULL,
+ _("%s%s: cannot allocate new modelist"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME);
+ return NULL;
+ }
+
+ /* initialize new modelist */
+ new_modelist->type = type;
+ new_modelist->state = IRC_MODELIST_STATE_EMPTY;
+ new_modelist->items = NULL;
+ new_modelist->last_item = NULL;
+
+ /* add new modelist to channel */
+ new_modelist->prev_modelist = channel->last_modelist;
+ new_modelist->next_modelist = NULL;
+ if (channel->modelists)
+ (channel->last_modelist)->next_modelist = new_modelist;
+ else
+ channel->modelists = new_modelist;
+ channel->last_modelist = new_modelist;
+
+ /* all is OK, return address of new modelist */
+ return new_modelist;
+}
+
+/*
+ * Frees a modelist and remove it from channel.
+ */
+
+void
+irc_modelist_free (struct t_irc_channel *channel,
+ struct t_irc_modelist *modelist)
+{
+ struct t_irc_modelist *new_modelists;
+
+ if (!channel || !modelist)
+ return;
+
+ /* remove modelist from channel modelists */
+ if (channel->last_modelist == modelist)
+ channel->last_modelist = modelist->prev_modelist;
+ if (modelist->prev_modelist)
+ {
+ (modelist->prev_modelist)->next_modelist = modelist->next_modelist;
+ new_modelists = channel->modelists;
+ }
+ else
+ new_modelists = modelist->next_modelist;
+
+ if (modelist->next_modelist)
+ (modelist->next_modelist)->prev_modelist = modelist->prev_modelist;
+
+ /* free linked lists */
+ irc_modelist_item_free_all (modelist);
+
+ free (modelist);
+
+ channel->modelists = new_modelists;
+}
+
+/*
+ * Frees all modelists for a channel.
+ */
+
+void
+irc_modelist_free_all (struct t_irc_channel *channel)
+{
+ while (channel->modelists)
+ {
+ irc_modelist_free (channel, channel->modelists);
+ }
+}
+
+/*
+ * Checks if a modelist item pointer is valid for a modelist.
+ *
+ * Returns:
+ * 1: item exists for modelist
+ * 0: item does not exist for modelist
+ */
+
+int
+irc_modelist_item_valid (struct t_irc_modelist *modelist,
+ struct t_irc_modelist_item *item)
+{
+ struct t_irc_modelist_item *ptr_item;
+
+ if (!modelist || !item)
+ return 0;
+
+ for (ptr_item = modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ if (ptr_item == item)
+ return 1;
+ }
+
+ /* item not found */
+ return 0;
+}
+
+/*
+ * Searches for an item by mask.
+ *
+ * Returns pointer to item found, NULL if not found.
+ */
+
+struct t_irc_modelist_item *
+irc_modelist_item_search_mask (struct t_irc_modelist *modelist, const char *mask)
+{
+ struct t_irc_modelist_item *ptr_item;
+
+ if (!modelist || !mask)
+ return NULL;
+
+ for (ptr_item = modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ if (strcmp (ptr_item->mask, mask) == 0)
+ return ptr_item;
+ }
+ return NULL;
+}
+
+/*
+ * Searches for an item by number.
+ *
+ * Returns pointer to item found, NULL if not found.
+ */
+
+struct t_irc_modelist_item *
+irc_modelist_item_search_number (struct t_irc_modelist *modelist, int number)
+{
+ struct t_irc_modelist_item *ptr_item;
+
+ if (!modelist)
+ return NULL;
+
+ for (ptr_item = modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ if (ptr_item->number == number)
+ return ptr_item;
+ }
+ return NULL;
+}
+
+/*
+ * Creates a new item in a modelist.
+ *
+ * Returns pointer to new item, NULL if error.
+ */
+
+struct t_irc_modelist_item *
+irc_modelist_item_new (struct t_irc_modelist *modelist,
+ const char *mask, const char *setter, time_t datetime)
+{
+ struct t_irc_modelist_item *new_item;
+
+ /* alloc memory for new item */
+ if ((new_item = malloc (sizeof (*new_item))) == NULL)
+ {
+ weechat_printf (NULL,
+ _("%s%s: cannot allocate new modelist item"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME);
+ return NULL;
+ }
+
+ /* initialize new item */
+ new_item->number = (modelist->last_item) ?
+ modelist->last_item->number + 1 : 0;
+ new_item->mask = strdup (mask);
+ new_item->setter = (setter) ? strdup (setter) : NULL;
+ new_item->datetime = datetime;
+
+ /* add new item to modelist */
+ new_item->prev_item = modelist->last_item;
+ new_item->next_item = NULL;
+ if (modelist->items)
+ (modelist->last_item)->next_item = new_item;
+ else
+ modelist->items = new_item;
+ modelist->last_item = new_item;
+
+ if ((modelist->state == IRC_MODELIST_STATE_EMPTY) ||
+ (modelist->state == IRC_MODELIST_STATE_RECEIVED))
+ {
+ modelist->state = IRC_MODELIST_STATE_MODIFIED;
+ }
+
+ /* all is OK, return address of new item */
+ return new_item;
+}
+
+/*
+ * Frees an item and remove it from modelist.
+ */
+
+void
+irc_modelist_item_free (struct t_irc_modelist *modelist,
+ struct t_irc_modelist_item *item)
+{
+ struct t_irc_modelist_item *new_items;
+
+ if (!modelist || !item)
+ return;
+
+ /* remove item from modelist list */
+ if (modelist->last_item == item)
+ modelist->last_item = item->prev_item;
+ if (item->prev_item)
+ {
+ (item->prev_item)->next_item = item->next_item;
+ new_items = modelist->items;
+ }
+ else
+ new_items = item->next_item;
+
+ if (item->next_item)
+ (item->next_item)->prev_item = item->prev_item;
+
+ /* free item data */
+ if (item->mask)
+ free (item->mask);
+ if (item->setter)
+ free (item->setter);
+ free (item);
+
+ modelist->items = new_items;
+
+ if (modelist->state == IRC_MODELIST_STATE_RECEIVED)
+ modelist->state = IRC_MODELIST_STATE_MODIFIED;
+}
+
+/*
+ * Frees all items for a modelist.
+ */
+
+void
+irc_modelist_item_free_all (struct t_irc_modelist *modelist)
+{
+ while (modelist->items)
+ {
+ irc_modelist_item_free (modelist, modelist->items);
+ }
+ modelist->state = IRC_MODELIST_STATE_EMPTY;
+}
+
+/*
+ * Returns hdata for modelist item.
+ */
+
+struct t_hdata *
+irc_modelist_hdata_item_cb (const void *pointer, void *data,
+ const char *hdata_name)
+{
+ struct t_hdata *hdata;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ hdata = weechat_hdata_new (hdata_name, "prev_item", "next_item",
+ 0, 0, NULL, NULL);
+ if (hdata)
+ {
+ WEECHAT_HDATA_VAR(struct t_irc_modelist_item, number, INTEGER, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist_item, mask, STRING, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist_item, setter, STRING, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist_item, datetime, TIME, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist_item, prev_item, POINTER, 0, NULL, hdata_name);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist_item, next_item, POINTER, 0, NULL, hdata_name);
+ }
+ return hdata;
+}
+
+/*
+ * Returns hdata for modelist.
+ */
+
+struct t_hdata *
+irc_modelist_hdata_modelist_cb (const void *pointer, void *data, const char *hdata_name)
+{
+ struct t_hdata *hdata;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ hdata = weechat_hdata_new (hdata_name, "prev_modelist", "next_modelist",
+ 0, 0, NULL, NULL);
+ if (hdata)
+ {
+ WEECHAT_HDATA_VAR(struct t_irc_modelist, type, CHAR, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist, state, INTEGER, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist, items, POINTER, 0, NULL, "irc_modelist_item");
+ WEECHAT_HDATA_VAR(struct t_irc_modelist, last_item, POINTER, 0, NULL, "irc_modelist_item");
+ WEECHAT_HDATA_VAR(struct t_irc_modelist, prev_modelist, POINTER, 0, NULL, hdata_name);
+ WEECHAT_HDATA_VAR(struct t_irc_modelist, next_modelist, POINTER, 0, NULL, hdata_name);
+ }
+ return hdata;
+}
+
+/*
+ * Adds a modelist item in an infolist.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+irc_modelist_item_add_to_infolist (struct t_infolist *infolist,
+ struct t_irc_modelist_item *item)
+{
+ struct t_infolist_item *ptr_item;
+
+ if (!infolist || !item)
+ return 0;
+
+ ptr_item = weechat_infolist_new_item (infolist);
+ if (!ptr_item)
+ return 0;
+
+ if (!weechat_infolist_new_var_integer (ptr_item, "number", item->number))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "mask", item->mask))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "setter", item->setter))
+ return 0;
+ if (!weechat_infolist_new_var_time (ptr_item, "datetime", item->datetime))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Adds a modelist in an infolist.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+irc_modelist_add_to_infolist (struct t_infolist *infolist,
+ struct t_irc_modelist *modelist)
+{
+ struct t_infolist_item *ptr_item;
+ char str_type[2];
+
+ if (!infolist || !modelist)
+ return 0;
+
+ ptr_item = weechat_infolist_new_item (infolist);
+ if (!ptr_item)
+ return 0;
+
+ str_type[0] = modelist->type;
+ str_type[1] = '\0';
+
+ if (!weechat_infolist_new_var_string (ptr_item, "type", str_type))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "state", modelist->state))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Prints modelist item infos in WeeChat log file (usually for crash dump).
+ */
+
+void
+irc_modelist_item_print_log (struct t_irc_modelist_item *item)
+{
+ weechat_log_printf ("");
+ weechat_log_printf (" => modelist item %d (addr:0x%lx):", item->number, item);
+ weechat_log_printf (" mask . . . . . . . . . . : '%s'", item->mask);
+ weechat_log_printf (" setter . . . . . . . . . : '%s'", item->setter);
+ weechat_log_printf (" datetime . . . . . . . . : %lld",
+ (long long)(item->datetime));
+ weechat_log_printf (" prev_item . . . . . . . : 0x%lx", item->prev_item);
+ weechat_log_printf (" next_item . . . . . . . : 0x%lx", item->next_item);
+}
+
+/*
+ * Prints modelist infos in WeeChat log file (usually for crash dump).
+ */
+
+void
+irc_modelist_print_log (struct t_irc_modelist *modelist)
+{
+ struct t_irc_modelist_item *ptr_item;
+
+ weechat_log_printf ("");
+ weechat_log_printf (" => modelist \"%c\" (addr:0x%lx):", modelist->type, modelist);
+ weechat_log_printf (" state. . . . . . . . . . : %d", modelist->state);
+ weechat_log_printf (" prev_modelist . . . . . : 0x%lx", modelist->prev_modelist);
+ weechat_log_printf (" next_modelist . . . . . : 0x%lx", modelist->next_modelist);
+ for (ptr_item = modelist->items; ptr_item; ptr_item = ptr_item->next_item)
+ {
+ irc_modelist_item_print_log (ptr_item);
+ }
+}
diff --git a/src/plugins/irc/irc-modelist.h b/src/plugins/irc/irc-modelist.h
new file mode 100644
index 000000000..1648ef9eb
--- /dev/null
+++ b/src/plugins/irc/irc-modelist.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 Simmo Saan <simmo.saan@gmail.com>
+ * Copyright (C) 2018 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef WEECHAT_PLUGIN_IRC_MODELIST_H
+#define WEECHAT_PLUGIN_IRC_MODELIST_H
+
+#include <time.h>
+
+/* modelist states */
+#define IRC_MODELIST_STATE_EMPTY 0
+#define IRC_MODELIST_STATE_RECEIVING 1
+#define IRC_MODELIST_STATE_RECEIVED 2
+#define IRC_MODELIST_STATE_MODIFIED 3
+
+struct t_irc_server;
+
+struct t_irc_modelist_item
+{
+ int number; /* item number */
+ char *mask; /* modelist mask */
+ char *setter; /* hostmask of setter (optional) */
+ time_t datetime; /* datetime of setting (optional)*/
+
+ struct t_irc_modelist_item *prev_item; /* pointer to previous item */
+ struct t_irc_modelist_item *next_item; /* pointer to next item */
+};
+
+struct t_irc_modelist
+{
+ char type; /* mode list channel A type */
+ int state; /* state */
+
+ struct t_irc_modelist_item *items; /* items in modelist */
+ struct t_irc_modelist_item *last_item; /* last item in modelist */
+
+ struct t_irc_modelist *prev_modelist; /* pointer to previous modelist */
+ struct t_irc_modelist *next_modelist; /* pointer to next modelist */
+};
+
+extern int irc_modelist_valid (struct t_irc_channel *channel,
+ struct t_irc_modelist *modelist);
+extern struct t_irc_modelist *irc_modelist_search (struct t_irc_channel *channel,
+ char type);
+extern struct t_irc_modelist *irc_modelist_new (struct t_irc_channel *channel,
+ char type);
+extern void irc_modelist_free (struct t_irc_channel *channel,
+ struct t_irc_modelist *modelist);
+extern void irc_modelist_free_all (struct t_irc_channel *channel);
+
+extern int irc_modelist_item_valid (struct t_irc_modelist *modelist,
+ struct t_irc_modelist_item *item);
+extern struct t_irc_modelist_item *irc_modelist_item_search_mask (struct t_irc_modelist *modelist,
+ const char *mask);
+extern struct t_irc_modelist_item *irc_modelist_item_search_number (struct t_irc_modelist *modelist,
+ int number);
+extern struct t_irc_modelist_item *irc_modelist_item_new (struct t_irc_modelist *modelist,
+ const char *mask,
+ const char *setter,
+ time_t datetime);
+extern void irc_modelist_item_free (struct t_irc_modelist *modelist,
+ struct t_irc_modelist_item *item);
+extern void irc_modelist_item_free_all (struct t_irc_modelist *modelist);
+
+extern struct t_hdata *irc_modelist_hdata_item_cb (const void *pointer,
+ void *data,
+ const char *hdata_name);
+extern struct t_hdata *irc_modelist_hdata_modelist_cb (const void *pointer,
+ void *data,
+ const char *hdata_name);
+extern int irc_modelist_item_add_to_infolist (struct t_infolist *infolist,
+ struct t_irc_modelist_item *item);
+extern int irc_modelist_add_to_infolist (struct t_infolist *infolist,
+ struct t_irc_modelist *modelist);
+extern void irc_modelist_item_print_log (struct t_irc_modelist_item *item);
+extern void irc_modelist_print_log (struct t_irc_modelist *modelist);
+
+#endif /* WEECHAT_PLUGIN_IRC_MODELIST_H */
diff --git a/src/plugins/irc/irc-msgbuffer.c b/src/plugins/irc/irc-msgbuffer.c
index 21339e7bc..ad57ecdb2 100644
--- a/src/plugins/irc/irc-msgbuffer.c
+++ b/src/plugins/irc/irc-msgbuffer.c
@@ -1,7 +1,7 @@
/*
* irc-msgbuffer.c - target buffer for IRC messages
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-msgbuffer.h b/src/plugins/irc/irc-msgbuffer.h
index c2e72fe05..c96bfa23a 100644
--- a/src/plugins/irc/irc-msgbuffer.h
+++ b/src/plugins/irc/irc-msgbuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_MSGBUFFER_H
-#define WEECHAT_IRC_MSGBUFFER_H 1
+#ifndef WEECHAT_PLUGIN_IRC_MSGBUFFER_H
+#define WEECHAT_PLUGIN_IRC_MSGBUFFER_H
enum t_irc_msgbuffer_target
{
@@ -38,4 +38,4 @@ extern struct t_gui_buffer *irc_msgbuffer_get_target_buffer (struct t_irc_server
const char *alias,
struct t_gui_buffer *default_buffer);
-#endif /* WEECHAT_IRC_MSGBUFFER_H */
+#endif /* WEECHAT_PLUGIN_IRC_MSGBUFFER_H */
diff --git a/src/plugins/irc/irc-nick.c b/src/plugins/irc/irc-nick.c
index 6559fc2ca..22e89da26 100644
--- a/src/plugins/irc/irc-nick.c
+++ b/src/plugins/irc/irc-nick.c
@@ -1,7 +1,7 @@
/*
* irc-nick.c - nick management for IRC plugin
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -320,7 +320,7 @@ irc_nick_get_color_for_nicklist (struct t_irc_server *server,
if (nick->away)
return nick_color_away;
- if (weechat_config_boolean(irc_config_look_color_nicks_in_nicklist))
+ if (weechat_config_boolean (irc_config_look_color_nicks_in_nicklist))
{
if (irc_server_strcasecmp (server, nick->name, server->nick) == 0)
return nick_color_self;
@@ -470,15 +470,8 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel,
/* remove old nick from nicklist */
irc_nick_nicklist_remove (server, channel, ptr_nick);
- /* update nick */
+ /* update nick prefixes */
irc_nick_set_prefixes (server, ptr_nick, prefixes);
- ptr_nick->away = away;
- if (ptr_nick->account)
- free (ptr_nick->account);
- ptr_nick->account = (account) ? strdup (account) : NULL;
- if (ptr_nick->realname)
- free (ptr_nick->realname);
- ptr_nick->realname = (realname) ? strdup (realname) : NULL;
/* add new nick in nicklist */
irc_nick_nicklist_add (server, channel, ptr_nick);
@@ -497,7 +490,8 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel,
new_nick->realname = (realname) ? strdup (realname) : NULL;
length = strlen (irc_server_get_prefix_chars (server));
new_nick->prefixes = malloc (length + 1);
- if (!new_nick->name || !new_nick->prefixes)
+ new_nick->prefix = malloc (2);
+ if (!new_nick->name || !new_nick->prefixes || !new_nick->prefix)
{
if (new_nick->name)
free (new_nick->name);
@@ -509,14 +503,13 @@ irc_nick_new (struct t_irc_server *server, struct t_irc_channel *channel,
free (new_nick->realname);
if (new_nick->prefixes)
free (new_nick->prefixes);
+ if (new_nick->prefix)
+ free (new_nick->prefix);
free (new_nick);
return NULL;
}
- if (new_nick->prefixes)
- {
- memset (new_nick->prefixes, ' ', length);
- new_nick->prefixes[length] = '\0';
- }
+ memset (new_nick->prefixes, ' ', length);
+ new_nick->prefixes[length] = '\0';
new_nick->prefix[0] = ' ';
new_nick->prefix[1] = '\0';
irc_nick_set_prefixes (server, new_nick, prefixes);
@@ -647,6 +640,8 @@ irc_nick_free (struct t_irc_server *server, struct t_irc_channel *channel,
free (nick->host);
if (nick->prefixes)
free (nick->prefixes);
+ if (nick->prefix)
+ free (nick->prefix);
if (nick->account)
free (nick->account);
if (nick->realname)
@@ -754,18 +749,11 @@ void
irc_nick_set_away (struct t_irc_server *server, struct t_irc_channel *channel,
struct t_irc_nick *nick, int is_away)
{
- if (!is_away
- || weechat_hashtable_has_key (server->cap_list, "away-notify")
- || ((IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK) > 0)
- && ((IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS) == 0)
- || (channel->nicks_count <= IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS)))))
+ if (is_away != nick->away)
{
- if ((is_away && !nick->away) || (!is_away && nick->away))
- {
- nick->away = is_away;
- irc_nick_nicklist_set (channel, nick, "color",
- irc_nick_get_color_for_nicklist (server, nick));
- }
+ nick->away = is_away;
+ irc_nick_nicklist_set (channel, nick, "color",
+ irc_nick_get_color_for_nicklist (server, nick));
}
}
diff --git a/src/plugins/irc/irc-nick.h b/src/plugins/irc/irc-nick.h
index f67ee6656..92ef6f199 100644
--- a/src/plugins/irc/irc-nick.h
+++ b/src/plugins/irc/irc-nick.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_NICK_H
-#define WEECHAT_IRC_NICK_H 1
+#ifndef WEECHAT_PLUGIN_IRC_NICK_H
+#define WEECHAT_PLUGIN_IRC_NICK_H
#define IRC_NICK_VALID_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHI" \
"JKLMNOPQRSTUVWXYZ0123456789-[]\\`_^{|}"
@@ -35,8 +35,8 @@ struct t_irc_nick
char *name; /* nickname */
char *host; /* full hostname */
char *prefixes; /* string with prefixes enabled for nick */
- char prefix[2]; /* current prefix (higher prefix set in */
- /* prefixes) */
+ char *prefix; /* current prefix (higher prefix set in */
+ /* prefixes); string with just one char */
int away; /* 1 if nick is away */
char *account; /* account name of the user */
char *realname; /* realname (aka gecos) of the user */
@@ -109,4 +109,4 @@ extern int irc_nick_add_to_infolist (struct t_infolist *infolist,
struct t_irc_nick *nick);
extern void irc_nick_print_log (struct t_irc_nick *nick);
-#endif /* WEECHAT_IRC_NICK_H */
+#endif /* WEECHAT_PLUGIN_IRC_NICK_H */
diff --git a/src/plugins/irc/irc-notify.c b/src/plugins/irc/irc-notify.c
index 579046b29..be847c100 100644
--- a/src/plugins/irc/irc-notify.c
+++ b/src/plugins/irc/irc-notify.c
@@ -1,7 +1,7 @@
/*
* irc-notify.c - notify lists for IRC plugin
*
- * Copyright (C) 2010-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2010-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-notify.h b/src/plugins/irc/irc-notify.h
index 0f6778b7e..81322778c 100644
--- a/src/plugins/irc/irc-notify.h
+++ b/src/plugins/irc/irc-notify.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2010-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_NOTIFY_H
-#define WEECHAT_IRC_NOTIFY_H 1
+#ifndef WEECHAT_PLUGIN_IRC_NOTIFY_H
+#define WEECHAT_PLUGIN_IRC_NOTIFY_H
struct t_irc_server;
@@ -75,4 +75,4 @@ extern void irc_notify_hook_timer_whois ();
extern void irc_notify_init ();
extern void irc_notify_end ();
-#endif /* WEECHAT_IRC_NOTIFY_H */
+#endif /* WEECHAT_PLUGIN_IRC_NOTIFY_H */
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 1b4fce045..340eb6589 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -1,7 +1,7 @@
/*
* irc-protocol.c - implementation of IRC protocol (RFCs 1459/2810/2811/2812/2813)
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
* Copyright (C) 2006 Emmanuel Bouthenot <kolter@openics.org>
* Copyright (C) 2014 Shawn Smith <ShawnSmith0828@gmail.com>
*
@@ -50,6 +50,7 @@
#include "irc-ignore.h"
#include "irc-message.h"
#include "irc-mode.h"
+#include "irc-modelist.h"
#include "irc-msgbuffer.h"
#include "irc-nick.h"
#include "irc-sasl.h"
@@ -252,12 +253,12 @@ IRC_PROTOCOL_CALLBACK(authenticate)
{
sasl_mechanism = IRC_SERVER_OPTION_INTEGER(
server, IRC_SERVER_OPTION_SASL_MECHANISM);
- sasl_username = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_USERNAME),
- NULL, NULL, NULL);
- sasl_password = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_PASSWORD),
- NULL, NULL, NULL);
+ sasl_username = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_USERNAME));
+ sasl_password = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_PASSWORD));
sasl_key = IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_KEY);
answer = NULL;
switch (sasl_mechanism)
@@ -697,7 +698,7 @@ IRC_PROTOCOL_CALLBACK(cap)
snprintf (str_msg_auth, sizeof (str_msg_auth),
"AUTHENTICATE %s",
irc_sasl_mechanism_string[sasl_mechanism]);
- weechat_string_toupper(str_msg_auth);
+ weechat_string_toupper (str_msg_auth);
irc_server_sendf (server, 0, NULL, str_msg_auth);
if (server->hook_timer_sasl)
weechat_unhook (server->hook_timer_sasl);
@@ -1162,6 +1163,9 @@ IRC_PROTOCOL_CALLBACK(kick)
*/
irc_nick_free_all (server, ptr_channel);
+ irc_channel_modelist_set_state (ptr_channel,
+ IRC_MODELIST_STATE_MODIFIED);
+
/* read option "autorejoin" in server */
rejoin = IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_AUTOREJOIN);
@@ -1276,6 +1280,9 @@ IRC_PROTOCOL_CALLBACK(kill)
*/
irc_nick_free_all (server, ptr_channel);
+ irc_channel_modelist_set_state (ptr_channel,
+ IRC_MODELIST_STATE_MODIFIED);
+
irc_bar_item_update_channel ();
}
else
@@ -1318,7 +1325,7 @@ IRC_PROTOCOL_CALLBACK(mode)
ptr_channel = irc_channel_search (server, argv[2]);
if (ptr_channel)
{
- smart_filter = irc_mode_channel_set (server, ptr_channel,
+ smart_filter = irc_mode_channel_set (server, ptr_channel, host,
pos_modes);
}
local_mode = (irc_server_strcasecmp (server, nick, server->nick) == 0);
@@ -1504,7 +1511,7 @@ IRC_PROTOCOL_CALLBACK(nick)
address),
_("%s%s%s%s is now known as %s%s%s"),
weechat_prefix ("network"),
- weechat_config_boolean(irc_config_look_color_nicks_in_server_messages) ?
+ weechat_config_boolean (irc_config_look_color_nicks_in_server_messages) ?
old_color : IRC_COLOR_CHAT_NICK,
nick,
IRC_COLOR_RESET,
@@ -1913,6 +1920,9 @@ IRC_PROTOCOL_CALLBACK(part)
{
irc_nick_free_all (server, ptr_channel);
+ irc_channel_modelist_set_state (ptr_channel,
+ IRC_MODELIST_STATE_MODIFIED);
+
/* cycling ? => rejoin channel immediately */
if (ptr_channel->cycle)
{
@@ -2652,9 +2662,9 @@ IRC_PROTOCOL_CALLBACK(001)
WEECHAT_HOOK_SIGNAL_STRING, server->name);
/* set usermode when connected */
- usermode = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERMODE),
- NULL, NULL, NULL);
+ usermode = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERMODE));
if (usermode && usermode[0])
{
irc_server_sendf (server,
@@ -2666,9 +2676,9 @@ IRC_PROTOCOL_CALLBACK(001)
free (usermode);
/* execute command when connected */
- server_command = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_COMMAND),
- NULL, NULL, NULL);
+ server_command = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_COMMAND));
if (server_command && server_command[0])
{
/* split command on ';' which can be escaped with '\;' */
@@ -3450,7 +3460,7 @@ IRC_PROTOCOL_CALLBACK(324)
irc_channel_set_modes (ptr_channel, ptr_modes);
if (argc > 4)
{
- (void) irc_mode_channel_set (server, ptr_channel,
+ (void) irc_mode_channel_set (server, ptr_channel, host,
ptr_channel->modes);
}
}
@@ -4034,14 +4044,36 @@ IRC_PROTOCOL_CALLBACK(346)
{
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
time_t datetime;
const char *nick_address;
+ char str_number[64];
IRC_PROTOCOL_MIN_ARGS(5);
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, 'I');
+
+ if (ptr_modelist)
+ {
+ /* start receiving new list */
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ irc_modelist_item_free_all (ptr_modelist);
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVING;
+ }
+
+ sprintf (str_number, "%s[%s%d%s] ",
+ IRC_COLOR_CHAT_DELIMITERS,
+ IRC_COLOR_RESET,
+ ((ptr_modelist->last_item) ? ptr_modelist->last_item->number + 1 : 0) + 1,
+ IRC_COLOR_CHAT_DELIMITERS);
+ }
+ else
+ str_number[0] = '\0';
+
if (argc >= 6)
{
nick_address = irc_protocol_nick_address (
@@ -4050,18 +4082,21 @@ IRC_PROTOCOL_CALLBACK(346)
if (argc >= 7)
{
datetime = (time_t)(atol (argv[6]));
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], argv[5], datetime);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "invitelist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
/* TRANSLATORS: "%s" after "on" is a date */
- _("%s%s[%s%s%s] %s%s%s invited by %s on %s"),
+ _("%s%s[%s%s%s] %s%s%s%s invited by %s on %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[4],
IRC_COLOR_RESET,
@@ -4070,17 +4105,20 @@ IRC_PROTOCOL_CALLBACK(346)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], argv[5], 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "invitelist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s] %s%s%s invited by %s"),
+ _("%s%s[%s%s%s] %s%s%s%s invited by %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[4],
IRC_COLOR_RESET,
@@ -4089,17 +4127,20 @@ IRC_PROTOCOL_CALLBACK(346)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], NULL, 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "invitelist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s] %s%s%s invited"),
+ _("%s%s[%s%s%s] %s%s%s%s invited"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[4],
IRC_COLOR_RESET);
@@ -4120,6 +4161,7 @@ IRC_PROTOCOL_CALLBACK(347)
char *pos_args;
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(4);
@@ -4129,6 +4171,19 @@ IRC_PROTOCOL_CALLBACK(347)
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, 'I');
+ if (ptr_modelist)
+ {
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ /*
+ * remove all items if no invite was received before
+ * the end of invite list
+ */
+ irc_modelist_item_free_all (ptr_modelist);
+ }
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
+ }
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "invitelist", ptr_buffer),
@@ -4159,14 +4214,36 @@ IRC_PROTOCOL_CALLBACK(348)
{
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
time_t datetime;
const char *nick_address;
+ char str_number[64];
IRC_PROTOCOL_MIN_ARGS(5);
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, 'e');
+
+ if (ptr_modelist)
+ {
+ /* start receiving new list */
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ irc_modelist_item_free_all (ptr_modelist);
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVING;
+ }
+
+ sprintf (str_number, " %s[%s%d%s]",
+ IRC_COLOR_CHAT_DELIMITERS,
+ IRC_COLOR_RESET,
+ ((ptr_modelist->last_item) ? ptr_modelist->last_item->number + 1 : 0) + 1,
+ IRC_COLOR_CHAT_DELIMITERS);
+ }
+ else
+ str_number[0] = '\0';
+
if (argc >= 6)
{
nick_address = irc_protocol_nick_address (
@@ -4175,18 +4252,21 @@ IRC_PROTOCOL_CALLBACK(348)
if (argc >= 7)
{
datetime = (time_t)(atol (argv[6]));
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], argv[5], datetime);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "exceptionlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
/* TRANSLATORS: "%s" after "on" is a date */
- _("%s%s[%s%s%s]%s exception %s%s%s by %s on %s"),
+ _("%s%s[%s%s%s]%s%s exception %s%s%s by %s on %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_RESET,
IRC_COLOR_CHAT_HOST,
argv[4],
@@ -4196,17 +4276,20 @@ IRC_PROTOCOL_CALLBACK(348)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], argv[5], 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "exceptionlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s]%s exception %s%s%s by %s"),
+ _("%s%s[%s%s%s]%s%s exception %s%s%s by %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_RESET,
IRC_COLOR_CHAT_HOST,
argv[4],
@@ -4216,17 +4299,20 @@ IRC_PROTOCOL_CALLBACK(348)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], NULL, 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "exceptionlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s]%s exception %s%s"),
+ _("%s%s[%s%s%s]%s%s exception %s%s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_RESET,
IRC_COLOR_CHAT_HOST,
argv[4]);
@@ -4247,6 +4333,7 @@ IRC_PROTOCOL_CALLBACK(349)
char *pos_args;
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(4);
@@ -4256,6 +4343,19 @@ IRC_PROTOCOL_CALLBACK(349)
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, 'e');
+ if (ptr_modelist)
+ {
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ /*
+ * remove all items if no exception was received before
+ * the end of exception list
+ */
+ irc_modelist_item_free_all (ptr_modelist);
+ }
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
+ }
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "exceptionlist", ptr_buffer),
@@ -4612,22 +4712,8 @@ IRC_PROTOCOL_CALLBACK(354)
/* update away flag in nick */
if (ptr_channel && ptr_nick)
{
- if (pos_attr
- && (weechat_hashtable_has_key (server->cap_list, "away-notify")
- || ((IRC_SERVER_OPTION_INTEGER(
- server, IRC_SERVER_OPTION_AWAY_CHECK) > 0)
- && ((IRC_SERVER_OPTION_INTEGER(
- server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS) == 0)
- || (ptr_channel->nicks_count <= IRC_SERVER_OPTION_INTEGER(
- server, IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS))))))
- {
- irc_nick_set_away (server, ptr_channel, ptr_nick,
- (pos_attr[0] == 'G') ? 1 : 0);
- }
- else
- {
- irc_nick_set_away (server, ptr_channel, ptr_nick, 0);
- }
+ irc_nick_set_away (server, ptr_channel, ptr_nick,
+ (pos_attr && (pos_attr[0] == 'G')) ? 1 : 0);
}
/* update account flag in nick */
@@ -4659,7 +4745,7 @@ IRC_PROTOCOL_CALLBACK(354)
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
"%s%s[%s%s%s] %s%s %s%s%s%s%s%s(%s%s@%s%s)%s %s%s%s%s(%s)",
- weechat_prefix("network"),
+ weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
@@ -4918,14 +5004,35 @@ IRC_PROTOCOL_CALLBACK(367)
{
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
time_t datetime;
const char *nick_address;
+ char str_number[64];
IRC_PROTOCOL_MIN_ARGS(5);
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, 'b');
+
+ if (ptr_modelist)
+ {
+ /* start receiving new list */
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ irc_modelist_item_free_all (ptr_modelist);
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVING;
+ }
+
+ sprintf (str_number, "%s[%s%d%s] ",
+ IRC_COLOR_CHAT_DELIMITERS,
+ IRC_COLOR_RESET,
+ ((ptr_modelist->last_item) ? ptr_modelist->last_item->number + 1 : 0) + 1,
+ IRC_COLOR_CHAT_DELIMITERS);
+ }
+ else
+ str_number[0] = '\0';
if (argc >= 6)
{
@@ -4935,18 +5042,21 @@ IRC_PROTOCOL_CALLBACK(367)
if (argc >= 7)
{
datetime = (time_t)(atol (argv[6]));
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], argv[5], datetime);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "banlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
/* TRANSLATORS: "%s" after "on" is a date */
- _("%s%s[%s%s%s] %s%s%s banned by %s on %s"),
+ _("%s%s[%s%s%s] %s%s%s%s banned by %s on %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[4],
IRC_COLOR_RESET,
@@ -4955,17 +5065,20 @@ IRC_PROTOCOL_CALLBACK(367)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], argv[5], 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "banlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s] %s%s%s banned by %s"),
+ _("%s%s[%s%s%s] %s%s%s%s banned by %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[4],
IRC_COLOR_RESET,
@@ -4974,17 +5087,20 @@ IRC_PROTOCOL_CALLBACK(367)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[4], NULL, 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "banlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s] %s%s%s banned"),
+ _("%s%s[%s%s%s] %s%s%s%s banned"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[4],
IRC_COLOR_RESET);
@@ -5005,6 +5121,7 @@ IRC_PROTOCOL_CALLBACK(368)
char *pos_args;
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(4);
@@ -5014,6 +5131,19 @@ IRC_PROTOCOL_CALLBACK(368)
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, 'b');
+ if (ptr_modelist)
+ {
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ /*
+ * remove all items if no ban was received before
+ * the end of ban list
+ */
+ irc_modelist_item_free_all (ptr_modelist);
+ }
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
+ }
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "banlist", ptr_buffer),
@@ -5345,14 +5475,35 @@ IRC_PROTOCOL_CALLBACK(728)
{
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
time_t datetime;
const char *nick_address;
+ char str_number[64];
IRC_PROTOCOL_MIN_ARGS(6);
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, argv[4][0]);
+
+ if (ptr_modelist)
+ {
+ /* start receiving new list */
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ irc_modelist_item_free_all (ptr_modelist);
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVING;
+ }
+
+ sprintf (str_number, "%s[%s%d%s] ",
+ IRC_COLOR_CHAT_DELIMITERS,
+ IRC_COLOR_RESET,
+ ((ptr_modelist->last_item) ? ptr_modelist->last_item->number + 1 : 0) + 1,
+ IRC_COLOR_CHAT_DELIMITERS);
+ }
+ else
+ str_number[0] = '\0';
if (argc >= 7)
{
@@ -5362,18 +5513,21 @@ IRC_PROTOCOL_CALLBACK(728)
if (argc >= 8)
{
datetime = (time_t)(atol (argv[7]));
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[5], argv[6], datetime);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "quietlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
/* TRANSLATORS: "%s" after "on" is a date */
- _("%s%s[%s%s%s] %s%s%s quieted by %s on %s"),
+ _("%s%s[%s%s%s] %s%s%s%s quieted by %s on %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[5],
IRC_COLOR_RESET,
@@ -5382,17 +5536,20 @@ IRC_PROTOCOL_CALLBACK(728)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[5], argv[6], 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "quietlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s] %s%s%s quieted by %s"),
+ _("%s%s[%s%s%s] %s%s%s%s quieted by %s"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[5],
IRC_COLOR_RESET,
@@ -5401,17 +5558,20 @@ IRC_PROTOCOL_CALLBACK(728)
}
else
{
+ if (ptr_modelist)
+ irc_modelist_item_new (ptr_modelist, argv[5], NULL, 0);
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "quietlist", ptr_buffer),
date,
irc_protocol_tags (command, "irc_numeric", NULL, NULL),
- _("%s%s[%s%s%s] %s%s%s quieted"),
+ _("%s%s[%s%s%s] %s%s%s%s quieted"),
weechat_prefix ("network"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_CHANNEL,
argv[3],
IRC_COLOR_CHAT_DELIMITERS,
+ str_number,
IRC_COLOR_CHAT_HOST,
argv[5],
IRC_COLOR_RESET);
@@ -5432,6 +5592,7 @@ IRC_PROTOCOL_CALLBACK(729)
char *pos_args;
struct t_irc_channel *ptr_channel;
struct t_gui_buffer *ptr_buffer;
+ struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(5);
@@ -5441,6 +5602,19 @@ IRC_PROTOCOL_CALLBACK(729)
ptr_channel = irc_channel_search (server, argv[3]);
ptr_buffer = (ptr_channel && ptr_channel->nicks) ?
ptr_channel->buffer : server->buffer;
+ ptr_modelist = irc_modelist_search (ptr_channel, argv[4][0]);
+ if (ptr_modelist)
+ {
+ if (ptr_modelist->state != IRC_MODELIST_STATE_RECEIVING)
+ {
+ /*
+ * remove all items if no quiet was received before
+ * the end of quiet list
+ */
+ irc_modelist_item_free_all (ptr_modelist);
+ }
+ ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
+ }
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "quietlist", ptr_buffer),
@@ -5843,16 +6017,15 @@ irc_protocol_get_message_tag_time (struct t_hashtable *tags)
void
irc_protocol_recv_command (struct t_irc_server *server,
const char *irc_message,
- const char *msg_tags,
const char *msg_command,
const char *msg_channel)
{
int i, cmd_found, return_code, argc, decode_color, keep_trailing_spaces;
int message_ignored;
- char *dup_irc_message, *pos_space;
+ char *message_colors_decoded, *pos_space, *tags;
struct t_irc_channel *ptr_channel;
t_irc_recv_func *cmd_recv_func;
- const char *cmd_name;
+ const char *cmd_name, *ptr_msg_after_tags;
time_t date;
const char *nick1, *address1, *host1;
char *nick, *address, *address_color, *host, *host_no_color, *host_color;
@@ -6014,29 +6187,48 @@ irc_protocol_recv_command (struct t_irc_server *server,
if (!msg_command)
return;
- dup_irc_message = NULL;
+ message_colors_decoded = NULL;
argv = NULL;
argv_eol = NULL;
hash_tags = NULL;
date = 0;
+ ptr_msg_after_tags = irc_message;
+
/* get tags as hashtable */
- if (msg_tags)
+ if (irc_message && (irc_message[0] == '@'))
{
- hash_tags = irc_protocol_get_message_tags (msg_tags);
- if (hash_tags)
- date = irc_protocol_get_message_tag_time (hash_tags);
+ pos_space = strchr (irc_message, ' ');
+ if (pos_space)
+ {
+ tags = weechat_strndup (irc_message + 1,
+ pos_space - (irc_message + 1));
+ if (tags)
+ {
+ hash_tags = irc_protocol_get_message_tags (tags);
+ if (hash_tags)
+ date = irc_protocol_get_message_tag_time (hash_tags);
+ free (tags);
+ }
+ ptr_msg_after_tags = pos_space;
+ while (ptr_msg_after_tags[0] == ' ')
+ {
+ ptr_msg_after_tags++;
+ }
+ }
+ else
+ ptr_msg_after_tags = NULL;
}
/* get nick/host/address from IRC message */
nick1 = NULL;
address1 = NULL;
host1 = NULL;
- if (irc_message && (irc_message[0] == ':'))
+ if (ptr_msg_after_tags && (ptr_msg_after_tags[0] == ':'))
{
- nick1 = irc_message_get_nick_from_host (irc_message);
- address1 = irc_message_get_address_from_host (irc_message);
- host1 = irc_message + 1;
+ nick1 = irc_message_get_nick_from_host (ptr_msg_after_tags);
+ address1 = irc_message_get_address_from_host (ptr_msg_after_tags);
+ host1 = ptr_msg_after_tags + 1;
}
nick = (nick1) ? strdup (nick1) : NULL;
address = (address1) ? strdup (address1) : NULL;
@@ -6124,23 +6316,23 @@ irc_protocol_recv_command (struct t_irc_server *server,
if (cmd_recv_func != NULL)
{
- if (irc_message)
+ if (ptr_msg_after_tags)
{
if (decode_color)
{
- dup_irc_message = irc_color_decode (
- irc_message,
+ message_colors_decoded = irc_color_decode (
+ ptr_msg_after_tags,
weechat_config_boolean (irc_config_network_colors_receive));
}
else
{
- dup_irc_message = strdup (irc_message);
+ message_colors_decoded = strdup (ptr_msg_after_tags);
}
}
else
- dup_irc_message = NULL;
- argv = weechat_string_split (dup_irc_message, " ", 0, 0, &argc);
- argv_eol = weechat_string_split (dup_irc_message, " ",
+ message_colors_decoded = NULL;
+ argv = weechat_string_split (message_colors_decoded, " ", 0, 0, &argc);
+ argv_eol = weechat_string_split (message_colors_decoded, " ",
1 + keep_trailing_spaces, 0, NULL);
return_code = (int) (cmd_recv_func) (server,
@@ -6186,8 +6378,8 @@ end:
free (host_no_color);
if (host_color)
free (host_color);
- if (dup_irc_message)
- free (dup_irc_message);
+ if (message_colors_decoded)
+ free (message_colors_decoded);
if (argv)
weechat_string_free_split (argv);
if (argv_eol)
diff --git a/src/plugins/irc/irc-protocol.h b/src/plugins/irc/irc-protocol.h
index a890fd866..e45b6977b 100644
--- a/src/plugins/irc/irc-protocol.h
+++ b/src/plugins/irc/irc-protocol.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_PROTOCOL_H
-#define WEECHAT_IRC_PROTOCOL_H 1
+#ifndef WEECHAT_PLUGIN_IRC_PROTOCOL_H
+#define WEECHAT_PLUGIN_IRC_PROTOCOL_H
#include <time.h>
@@ -87,8 +87,7 @@ extern const char *irc_protocol_tags (const char *command, const char *tags,
const char *nick, const char *address);
extern void irc_protocol_recv_command (struct t_irc_server *server,
const char *irc_message,
- const char *msg_tags,
const char *msg_command,
const char *msg_channel);
-#endif /* WEECHAT_IRC_PROTOCOL_H */
+#endif /* WEECHAT_PLUGIN_IRC_PROTOCOL_H */
diff --git a/src/plugins/irc/irc-raw.c b/src/plugins/irc/irc-raw.c
index d669aed10..ace1de3d8 100644
--- a/src/plugins/irc/irc-raw.c
+++ b/src/plugins/irc/irc-raw.c
@@ -1,7 +1,7 @@
/*
* irc-raw.c - functions for IRC raw data messages
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
diff --git a/src/plugins/irc/irc-raw.h b/src/plugins/irc/irc-raw.h
index d0601a10c..3ac0b04ad 100644
--- a/src/plugins/irc/irc-raw.h
+++ b/src/plugins/irc/irc-raw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_RAW_H
-#define WEECHAT_IRC_RAW_H 1
+#ifndef WEECHAT_PLUGIN_IRC_RAW_H
+#define WEECHAT_PLUGIN_IRC_RAW_H
#include <time.h>
@@ -61,4 +61,4 @@ extern void irc_raw_message_free_all ();
extern int irc_raw_add_to_infolist (struct t_infolist *infolist,
struct t_irc_raw_message *raw_message);
-#endif /* WEECHAT_IRC_RAW_H */
+#endif /* WEECHAT_PLUGIN_IRC_RAW_H */
diff --git a/src/plugins/irc/irc-redirect.c b/src/plugins/irc/irc-redirect.c
index 44648a00d..64fc30ac6 100644
--- a/src/plugins/irc/irc-redirect.c
+++ b/src/plugins/irc/irc-redirect.c
@@ -1,7 +1,7 @@
/*
* irc-redirect.c - redirection of IRC command output
*
- * Copyright (C) 2010-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2010-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -686,7 +686,7 @@ irc_redirect_message_add (struct t_irc_redirect *redirect, const char *message,
/* add message to output */
if (redirect->output)
{
- redirect->output_size += strlen("\n") + strlen (message);
+ redirect->output_size += strlen ("\n") + strlen (message);
output2 = realloc (redirect->output, redirect->output_size);
if (!output2)
{
@@ -1209,7 +1209,7 @@ irc_redirect_print_log (struct t_irc_server *server)
weechat_log_printf (" timeout . . . . . . : %d", ptr_redirect->timeout);
weechat_log_printf (" command . . . . . . : '%s'", ptr_redirect->command);
weechat_log_printf (" assigned_to_command : %d", ptr_redirect->assigned_to_command);
- weechat_log_printf (" start_time. . . . . : %ld", ptr_redirect->start_time);
+ weechat_log_printf (" start_time. . . . . : %lld", (long long)ptr_redirect->start_time);
weechat_log_printf (" cmd_start . . . . . : 0x%lx (hashtable: '%s')",
ptr_redirect->cmd_start,
weechat_hashtable_get_string (ptr_redirect->cmd_start, "keys_values"));
diff --git a/src/plugins/irc/irc-redirect.h b/src/plugins/irc/irc-redirect.h
index 3d3e09f9e..f94e6ad07 100644
--- a/src/plugins/irc/irc-redirect.h
+++ b/src/plugins/irc/irc-redirect.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2010-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_REDIRECT_H
-#define WEECHAT_IRC_REDIRECT_H 1
+#ifndef WEECHAT_PLUGIN_IRC_REDIRECT_H
+#define WEECHAT_PLUGIN_IRC_REDIRECT_H
#include <time.h>
@@ -132,4 +132,4 @@ extern int irc_redirect_command_hsignal_cb (const void *pointer, void *data,
extern void irc_redirect_init ();
extern void irc_redirect_end ();
-#endif /* WEECHAT_IRC_REDIRECT_H */
+#endif /* WEECHAT_PLUGIN_IRC_REDIRECT_H */
diff --git a/src/plugins/irc/irc-sasl.c b/src/plugins/irc/irc-sasl.c
index f397a656a..689e7ecb8 100644
--- a/src/plugins/irc/irc-sasl.c
+++ b/src/plugins/irc/irc-sasl.c
@@ -1,7 +1,7 @@
/*
* irc-sasl.c - SASL authentication with IRC server
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -493,7 +493,7 @@ irc_sasl_mechanism_dh_blowfish (const char *data_base64,
length_answer = 2 + length_key + length_username + length_password;
answer = malloc (length_answer);
ptr_answer = answer;
- *((unsigned int *)ptr_answer) = htons(length_key);
+ *((unsigned int *)ptr_answer) = htons (length_key);
ptr_answer += 2;
memcpy (ptr_answer, public_bin, length_key);
ptr_answer += length_key;
@@ -554,7 +554,7 @@ irc_sasl_mechanism_dh_aes (const char *data_base64,
secret_bin = NULL;
public_bin = NULL;
- if (irc_sasl_dh(data_base64, &public_bin, &secret_bin, &length_key) == 0)
+ if (irc_sasl_dh (data_base64, &public_bin, &secret_bin, &length_key) == 0)
goto aesend;
/* Select cipher algorithm: key length * 8 = cipher bit size */
@@ -596,7 +596,7 @@ irc_sasl_mechanism_dh_aes (const char *data_base64,
goto aesend;
if (gcry_cipher_setkey (gcrypt_handle, secret_bin, length_key) != 0)
goto aesend;
- if (gcry_cipher_setiv (gcrypt_handle, iv, sizeof(iv)) != 0)
+ if (gcry_cipher_setiv (gcrypt_handle, iv, sizeof (iv)) != 0)
goto aesend;
if (gcry_cipher_encrypt (gcrypt_handle,
userpass_crypted, length_userpass,
@@ -615,7 +615,7 @@ irc_sasl_mechanism_dh_aes (const char *data_base64,
length_answer = 2 + length_key + sizeof (iv) + length_userpass;
answer = malloc (length_answer);
ptr_answer = answer;
- *((unsigned int *)ptr_answer) = htons(length_key);
+ *((unsigned int *)ptr_answer) = htons (length_key);
ptr_answer += 2;
memcpy (ptr_answer, public_bin, length_key);
ptr_answer += length_key;
diff --git a/src/plugins/irc/irc-sasl.h b/src/plugins/irc/irc-sasl.h
index 5c2eb1604..38a930fa6 100644
--- a/src/plugins/irc/irc-sasl.h
+++ b/src/plugins/irc/irc-sasl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_SASL_H
-#define WEECHAT_IRC_SASL_H 1
+#ifndef WEECHAT_PLUGIN_IRC_SASL_H
+#define WEECHAT_PLUGIN_IRC_SASL_H
struct t_irc_server;
@@ -50,4 +50,4 @@ extern char *irc_sasl_mechanism_dh_aes (const char *data_base64,
const char *sasl_username,
const char *sasl_password);
-#endif /* WEECHAT_IRC_SASL_H */
+#endif /* WEECHAT_PLUGIN_IRC_SASL_H */
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index dd785c29a..2e43afab5 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -1,7 +1,7 @@
/*
* irc-server.c - I/O communication with IRC servers
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
* Copyright (C) 2005-2010 Emmanuel Bouthenot <kolter@openics.org>
* Copyright (C) 2012 Simon Arlott
*
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include <ctype.h>
#include <time.h>
#ifdef _WIN32
#include <winsock.h>
@@ -117,6 +118,7 @@ char *irc_server_options[IRC_SERVER_NUM_OPTIONS][2] =
{ "msg_part", "WeeChat ${info:version}" },
{ "msg_quit", "WeeChat ${info:version}" },
{ "notify", "" },
+ { "split_msg_max_length", "512" },
};
char *irc_server_casemapping_string[IRC_SERVER_NUM_CASEMAPPING] =
@@ -337,6 +339,152 @@ irc_server_strncasecmp (struct t_irc_server *server,
}
/*
+ * Evaluates a string using the server as context:
+ * ${irc_server.xxx} and ${server} are replaced by a server option and the
+ * server name.
+ *
+ * Returns the evaluated string.
+ *
+ * Note: result must be freed after use.
+ */
+
+char *
+irc_server_eval_expression (struct t_irc_server *server, const char *string)
+{
+ struct t_hashtable *pointers, *extra_vars;
+ char *value;
+
+ pointers = weechat_hashtable_new (
+ 32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_POINTER,
+ NULL, NULL);
+ extra_vars = weechat_hashtable_new (
+ 32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL, NULL);
+
+ if (server)
+ {
+ if (pointers)
+ weechat_hashtable_set (pointers, "irc_server", server);
+ if (extra_vars)
+ weechat_hashtable_set (extra_vars, "server", server->name);
+ }
+
+ value = weechat_string_eval_expression (string,
+ pointers, extra_vars, NULL);
+
+ if (pointers)
+ weechat_hashtable_free (pointers);
+ if (extra_vars)
+ weechat_hashtable_free (extra_vars);
+
+ return value;
+}
+
+/*
+ * Evaluates and returns the fingerprint.
+ *
+ * Returns the evaluated fingerprint, NULL if the fingerprint option is
+ * invalid.
+ *
+ * Note: result must be freed after use.
+ */
+
+char *
+irc_server_eval_fingerprint (struct t_irc_server *server)
+{
+#ifdef HAVE_GNUTLS
+ const char *ptr_fingerprint;
+ char *fingerprint_eval, **fingerprints, *str_sizes;
+ int i, j, rc, algo, length;
+
+ ptr_fingerprint = IRC_SERVER_OPTION_STRING(server,
+ IRC_SERVER_OPTION_SSL_FINGERPRINT);
+
+ /* empty fingerprint is just ignored (considered OK) */
+ if (!ptr_fingerprint || !ptr_fingerprint[0])
+ return strdup ("");
+
+ /* evaluate fingerprint */
+ fingerprint_eval = irc_server_eval_expression (server, ptr_fingerprint);
+ if (!fingerprint_eval || !fingerprint_eval[0])
+ {
+ weechat_printf (
+ server->buffer,
+ _("%s%s: the evaluated fingerprint for server \"%s\" must not be "
+ "empty"),
+ weechat_prefix ("error"),
+ IRC_PLUGIN_NAME,
+ server->name);
+ if (fingerprint_eval)
+ free (fingerprint_eval);
+ return NULL;
+ }
+
+ /* split fingerprint */
+ fingerprints = weechat_string_split (fingerprint_eval, ",", 0, 0, NULL);
+ if (!fingerprints)
+ return fingerprint_eval;
+
+ rc = 0;
+ for (i = 0; fingerprints[i]; i++)
+ {
+ length = strlen (fingerprints[i]);
+ algo = irc_server_fingerprint_search_algo_with_size (length * 4);
+ if (algo < 0)
+ {
+ rc = -1;
+ break;
+ }
+ for (j = 0; j < length; j++)
+ {
+ if (!isxdigit ((unsigned char)fingerprints[i][j]))
+ {
+ rc = -2;
+ break;
+ }
+ }
+ if (rc < 0)
+ break;
+ }
+ weechat_string_free_split (fingerprints);
+ switch (rc)
+ {
+ case -1: /* invalid size */
+ str_sizes = irc_server_fingerprint_str_sizes ();
+ weechat_printf (
+ server->buffer,
+ _("%s%s: invalid fingerprint size for server \"%s\", the "
+ "number of hexadecimal digits must be "
+ "one of: %s"),
+ weechat_prefix ("error"),
+ IRC_PLUGIN_NAME,
+ server->name,
+ (str_sizes) ? str_sizes : "?");
+ if (str_sizes)
+ free (str_sizes);
+ free (fingerprint_eval);
+ return NULL;
+ case -2: /* invalid content */
+ weechat_printf (
+ server->buffer,
+ _("%s%s: invalid fingerprint for server \"%s\", it must "
+ "contain only hexadecimal digits (0-9, "
+ "a-f)"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME, server->name);
+ free (fingerprint_eval);
+ return NULL;
+ }
+ return fingerprint_eval;
+#else
+ return strdup ("");
+#endif /* HAVE_GNUTLS */
+}
+
+/*
* Checks if SASL is enabled on server.
*
* Returns:
@@ -353,12 +501,12 @@ irc_server_sasl_enabled (struct t_irc_server *server)
sasl_mechanism = IRC_SERVER_OPTION_INTEGER(
server, IRC_SERVER_OPTION_SASL_MECHANISM);
- sasl_username = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_USERNAME),
- NULL, NULL, NULL);
- sasl_password = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_PASSWORD),
- NULL, NULL, NULL);
+ sasl_username = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_USERNAME));
+ sasl_password = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_PASSWORD));
sasl_key = IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_KEY);
/*
@@ -422,8 +570,7 @@ irc_server_set_addresses (struct t_irc_server *server, const char *addresses)
if (addresses && addresses[0])
{
- addresses_eval = weechat_string_eval_expression (addresses,
- NULL, NULL, NULL);
+ addresses_eval = irc_server_eval_expression (server, addresses);
if (server->addresses_eval
&& (strcmp (server->addresses_eval, addresses_eval) == 0))
{
@@ -550,7 +697,7 @@ irc_server_set_nicks (struct t_irc_server *server, const char *nicks)
}
/* evaluate value */
- nicks2 = weechat_string_eval_expression (nicks, NULL, NULL, NULL);
+ nicks2 = irc_server_eval_expression (server, nicks);
/* set new nicks */
server->nicks_array = weechat_string_split (
@@ -2498,7 +2645,10 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags,
(new_msg) ? new_msg : items[i],
NULL);
- /* split message if needed (max is 512 bytes including final "\r\n") */
+ /*
+ * split message if needed (max is 512 bytes by default,
+ * including the final "\r\n")
+ */
hashtable = irc_message_split (server,
(new_msg) ? new_msg : items[i]);
if (hashtable)
@@ -2707,8 +2857,8 @@ void
irc_server_msgq_flush ()
{
struct t_irc_message *next;
- char *ptr_data, *new_msg, *new_msg2, *ptr_msg, *ptr_msg2, *ptr_msg3, *pos;
- char *tags, *nick, *host, *command, *channel, *arguments;
+ char *ptr_data, *new_msg, *new_msg2, *ptr_msg, *ptr_msg2, *pos;
+ char *nick, *host, *command, *channel, *arguments;
char *msg_decoded, *msg_decoded_without_color;
char str_modifier[128], modifier_data[256];
int pos_channel, pos_text, pos_decode;
@@ -2773,7 +2923,7 @@ irc_server_msgq_flush ()
}
irc_message_parse (irc_recv_msgq->server, ptr_msg,
- &tags, NULL, &nick, &host,
+ NULL, NULL, &nick, &host,
&command, &channel, &arguments,
NULL, NULL, NULL,
&pos_channel, &pos_text);
@@ -2860,25 +3010,9 @@ irc_server_msgq_flush ()
else
{
/* message not redirected, display it */
- ptr_msg3 = ptr_msg2;
- if (ptr_msg3[0] == '@')
- {
- /* skip tags in message */
- ptr_msg3 = strchr (ptr_msg3, ' ');
- if (ptr_msg3)
- {
- while (ptr_msg3[0] == ' ')
- {
- ptr_msg3++;
- }
- }
- else
- ptr_msg3 = ptr_msg2;
- }
irc_protocol_recv_command (
irc_recv_msgq->server,
- ptr_msg3,
- tags,
+ ptr_msg2,
command,
channel);
}
@@ -3508,15 +3642,15 @@ irc_server_login (struct t_irc_server *server)
const char *capabilities;
char *password, *username, *realname, *username2;
- password = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_PASSWORD),
- NULL, NULL, NULL);
- username = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERNAME),
- NULL, NULL, NULL);
- realname = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_REALNAME),
- NULL, NULL, NULL);
+ password = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_PASSWORD));
+ username = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERNAME));
+ realname = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_REALNAME));
capabilities = IRC_SERVER_OPTION_STRING(
server, IRC_SERVER_OPTION_CAPABILITIES);
@@ -4235,8 +4369,12 @@ irc_server_gnutls_callback (const void *pointer, void *data,
/* get fingerprint option in server */
ptr_fingerprint = IRC_SERVER_OPTION_STRING(server,
IRC_SERVER_OPTION_SSL_FINGERPRINT);
- fingerprint_eval = weechat_string_eval_expression (ptr_fingerprint,
- NULL, NULL, NULL);
+ fingerprint_eval = irc_server_eval_fingerprint (server);
+ if (!fingerprint_eval)
+ {
+ rc = -1;
+ goto end;
+ }
/* set match options */
fingerprint_match = (ptr_fingerprint && ptr_fingerprint[0]) ? 0 : 1;
@@ -4969,9 +5107,9 @@ irc_server_autojoin_create_buffers (struct t_irc_server *server)
return;
/* evaluate server option "autojoin" */
- autojoin = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_AUTOJOIN),
- NULL, NULL, NULL);
+ autojoin = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_AUTOJOIN));
/* extract channel names from autojoin option */
if (autojoin && autojoin[0])
@@ -5042,9 +5180,9 @@ irc_server_autojoin_channels (struct t_irc_server *server)
else
{
/* auto-join when connecting to server for first time */
- autojoin = weechat_string_eval_expression (
- IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_AUTOJOIN),
- NULL, NULL, NULL);
+ autojoin = irc_server_eval_expression (
+ server,
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_AUTOJOIN));
if (!server->disable_autojoin && autojoin && autojoin[0])
irc_command_join_server (server, autojoin, 0, 0);
if (autojoin)
@@ -6079,26 +6217,26 @@ irc_server_print_log ()
weechat_log_printf (" chantypes. . . . . . : '%s'", ptr_server->chantypes);
weechat_log_printf (" chanmodes. . . . . . : '%s'", ptr_server->chanmodes);
weechat_log_printf (" monitor. . . . . . . : %d", ptr_server->monitor);
- weechat_log_printf (" monitor_time . . . . : %ld", ptr_server->monitor_time);
+ weechat_log_printf (" monitor_time . . . . : %lld", (long long)ptr_server->monitor_time);
weechat_log_printf (" reconnect_delay. . . : %d", ptr_server->reconnect_delay);
- weechat_log_printf (" reconnect_start. . . : %ld", ptr_server->reconnect_start);
- weechat_log_printf (" command_time . . . . : %ld", ptr_server->command_time);
+ weechat_log_printf (" reconnect_start. . . : %lld", (long long)ptr_server->reconnect_start);
+ weechat_log_printf (" command_time . . . . : %lld", (long long)ptr_server->command_time);
weechat_log_printf (" reconnect_join . . . : %d", ptr_server->reconnect_join);
weechat_log_printf (" disable_autojoin . . : %d", ptr_server->disable_autojoin);
weechat_log_printf (" is_away. . . . . . . : %d", ptr_server->is_away);
weechat_log_printf (" away_message . . . . : '%s'", ptr_server->away_message);
- weechat_log_printf (" away_time. . . . . . : %ld", ptr_server->away_time);
+ weechat_log_printf (" away_time. . . . . . : %lld", (long long)ptr_server->away_time);
weechat_log_printf (" lag. . . . . . . . . : %d", ptr_server->lag);
weechat_log_printf (" lag_displayed. . . . : %d", ptr_server->lag_displayed);
weechat_log_printf (" lag_check_time . . . : tv_sec:%d, tv_usec:%d",
ptr_server->lag_check_time.tv_sec,
ptr_server->lag_check_time.tv_usec);
- weechat_log_printf (" lag_next_check . . . : %ld", ptr_server->lag_next_check);
- weechat_log_printf (" lag_last_refresh . . : %ld", ptr_server->lag_last_refresh);
+ weechat_log_printf (" lag_next_check . . . : %lld", (long long)ptr_server->lag_next_check);
+ weechat_log_printf (" lag_last_refresh . . : %lld", (long long)ptr_server->lag_last_refresh);
weechat_log_printf (" cmd_list_regexp. . . : 0x%lx", ptr_server->cmd_list_regexp);
- weechat_log_printf (" last_user_message. . : %ld", ptr_server->last_user_message);
- weechat_log_printf (" last_away_check. . . : %ld", ptr_server->last_away_check);
- weechat_log_printf (" last_data_purge. . . : %ld", ptr_server->last_data_purge);
+ weechat_log_printf (" last_user_message. . : %lld", (long long)ptr_server->last_user_message);
+ weechat_log_printf (" last_away_check. . . : %lld", (long long)ptr_server->last_away_check);
+ weechat_log_printf (" last_data_purge. . . : %lld", (long long)ptr_server->last_data_purge);
for (i = 0; i < IRC_SERVER_NUM_OUTQUEUES_PRIO; i++)
{
weechat_log_printf (" outqueue[%02d] . . . . : 0x%lx", i, ptr_server->outqueue[i]);
diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h
index 74987e675..401f627bb 100644
--- a/src/plugins/irc/irc-server.h
+++ b/src/plugins/irc/irc-server.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
* Copyright (C) 2012 Simon Arlott
*
* This file is part of WeeChat, the extensible chat client.
@@ -18,8 +18,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_SERVER_H
-#define WEECHAT_IRC_SERVER_H 1
+#ifndef WEECHAT_PLUGIN_IRC_SERVER_H
+#define WEECHAT_PLUGIN_IRC_SERVER_H
#include <time.h>
#include <sys/time.h>
@@ -84,6 +84,7 @@ enum t_irc_server_option
IRC_SERVER_OPTION_MSG_PART, /* default part message */
IRC_SERVER_OPTION_MSG_QUIT, /* default quit message */
IRC_SERVER_OPTION_NOTIFY, /* notify list */
+ IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH, /* max length of messages */
/* number of server options */
IRC_SERVER_NUM_OPTIONS,
};
@@ -283,6 +284,8 @@ extern int irc_server_strcasecmp (struct t_irc_server *server,
extern int irc_server_strncasecmp (struct t_irc_server *server,
const char *string1, const char *string2,
int max);
+extern char *irc_server_eval_expression (struct t_irc_server *server,
+ const char *string);
extern int irc_server_sasl_enabled (struct t_irc_server *server);
extern char *irc_server_get_name_without_port (const char *name);
extern int irc_server_set_addresses (struct t_irc_server *server,
@@ -381,4 +384,4 @@ extern int irc_server_add_to_infolist (struct t_infolist *infolist,
struct t_irc_server *server);
extern void irc_server_print_log ();
-#endif /* WEECHAT_IRC_SERVER_H */
+#endif /* WEECHAT_PLUGIN_IRC_SERVER_H */
diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c
index 098132514..107981609 100644
--- a/src/plugins/irc/irc-upgrade.c
+++ b/src/plugins/irc/irc-upgrade.c
@@ -1,7 +1,7 @@
/*
* irc-upgrade.c - save/restore IRC plugin data when upgrading WeeChat
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -30,6 +30,7 @@
#include "irc-channel.h"
#include "irc-config.h"
#include "irc-input.h"
+#include "irc-modelist.h"
#include "irc-nick.h"
#include "irc-notify.h"
#include "irc-raw.h"
@@ -39,6 +40,7 @@
struct t_irc_server *irc_upgrade_current_server = NULL;
struct t_irc_channel *irc_upgrade_current_channel = NULL;
+struct t_irc_modelist *irc_upgrade_current_modelist = NULL;
/*
@@ -59,6 +61,8 @@ irc_upgrade_save_all_data (struct t_upgrade_file *upgrade_file)
struct t_irc_redirect *ptr_redirect;
struct t_irc_redirect_pattern *ptr_redirect_pattern;
struct t_irc_notify *ptr_notify;
+ struct t_irc_modelist *ptr_modelist;
+ struct t_irc_modelist_item *ptr_item;
struct t_irc_raw_message *ptr_raw_message;
int rc;
@@ -120,6 +124,46 @@ irc_upgrade_save_all_data (struct t_upgrade_file *upgrade_file)
if (!rc)
return 0;
}
+
+ for (ptr_modelist = ptr_channel->modelists; ptr_modelist;
+ ptr_modelist = ptr_modelist->next_modelist)
+ {
+ /* save modelist */
+ infolist = weechat_infolist_new ();
+ if (!infolist)
+ return 0;
+ if (!irc_modelist_add_to_infolist (infolist, ptr_modelist))
+ {
+ weechat_infolist_free (infolist);
+ return 0;
+ }
+ rc = weechat_upgrade_write_object (upgrade_file,
+ IRC_UPGRADE_TYPE_MODELIST,
+ infolist);
+ weechat_infolist_free (infolist);
+ if (!rc)
+ return 0;
+
+ for (ptr_item = ptr_modelist->items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ /* save modelist item */
+ infolist = weechat_infolist_new ();
+ if (!infolist)
+ return 0;
+ if (!irc_modelist_item_add_to_infolist (infolist, ptr_item))
+ {
+ weechat_infolist_free (infolist);
+ return 0;
+ }
+ rc = weechat_upgrade_write_object (upgrade_file,
+ IRC_UPGRADE_TYPE_MODELIST_ITEM,
+ infolist);
+ weechat_infolist_free (infolist);
+ if (!rc)
+ return 0;
+ }
+ }
}
/* save server redirects */
@@ -304,6 +348,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
struct t_irc_nick *ptr_nick;
struct t_irc_redirect *ptr_redirect;
struct t_irc_notify *ptr_notify;
+ struct t_irc_modelist_item *ptr_item;
struct t_gui_buffer *ptr_buffer;
/* make C compiler happy */
@@ -675,6 +720,33 @@ irc_upgrade_read_cb (const void *pointer, void *data,
}
}
break;
+ case IRC_UPGRADE_TYPE_MODELIST:
+ if (irc_upgrade_current_server && irc_upgrade_current_channel)
+ {
+ /* modelists are already created by the channel */
+ irc_upgrade_current_modelist = irc_modelist_search (
+ irc_upgrade_current_channel,
+ weechat_infolist_string (infolist, "type")[0]);
+ if (irc_upgrade_current_modelist)
+ {
+ irc_upgrade_current_modelist->state = weechat_infolist_integer (infolist, "state");
+ }
+ }
+ break;
+ case IRC_UPGRADE_TYPE_MODELIST_ITEM:
+ if (irc_upgrade_current_server && irc_upgrade_current_channel && irc_upgrade_current_modelist)
+ {
+ ptr_item = irc_modelist_item_new (
+ irc_upgrade_current_modelist,
+ weechat_infolist_string (infolist, "mask"),
+ weechat_infolist_string (infolist, "setter"),
+ weechat_infolist_time (infolist, "datetime"));
+ if (ptr_item)
+ {
+ ptr_item->number = weechat_infolist_integer (infolist, "number");
+ }
+ }
+ break;
case IRC_UPGRADE_TYPE_REDIRECT:
if (irc_upgrade_current_server)
{
diff --git a/src/plugins/irc/irc-upgrade.h b/src/plugins/irc/irc-upgrade.h
index 5b8c32729..fa2a0734c 100644
--- a/src/plugins/irc/irc-upgrade.h
+++ b/src/plugins/irc/irc-upgrade.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -17,8 +17,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_UPGRADE_H
-#define WEECHAT_IRC_UPGRADE_H 1
+#ifndef WEECHAT_PLUGIN_IRC_UPGRADE_H
+#define WEECHAT_PLUGIN_IRC_UPGRADE_H
#define IRC_UPGRADE_FILENAME "irc"
@@ -33,9 +33,11 @@ enum t_irc_upgrade_type
IRC_UPGRADE_TYPE_REDIRECT_PATTERN,
IRC_UPGRADE_TYPE_REDIRECT,
IRC_UPGRADE_TYPE_NOTIFY,
+ IRC_UPGRADE_TYPE_MODELIST,
+ IRC_UPGRADE_TYPE_MODELIST_ITEM,
};
extern int irc_upgrade_save ();
extern int irc_upgrade_load ();
-#endif /* WEECHAT_IRC_UPGRADE_H */
+#endif /* WEECHAT_PLUGIN_IRC_UPGRADE_H */
diff --git a/src/plugins/irc/irc.c b/src/plugins/irc/irc.c
index 8a1531575..3163e74b0 100644
--- a/src/plugins/irc/irc.c
+++ b/src/plugins/irc/irc.c
@@ -1,7 +1,7 @@
/*
* irc.c - IRC (Internet Relay Chat) plugin for WeeChat
*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -50,7 +50,7 @@ WEECHAT_PLUGIN_DESCRIPTION(N_("IRC (Internet Relay Chat) protocol"));
WEECHAT_PLUGIN_AUTHOR("Sébastien Helleu <flashcode@flashtux.org>");
WEECHAT_PLUGIN_VERSION(WEECHAT_VERSION);
WEECHAT_PLUGIN_LICENSE(WEECHAT_LICENSE);
-WEECHAT_PLUGIN_PRIORITY(5000);
+WEECHAT_PLUGIN_PRIORITY(6000);
struct t_weechat_plugin *weechat_irc_plugin = NULL;
diff --git a/src/plugins/irc/irc.h b/src/plugins/irc/irc.h
index 63befef64..2d22aa583 100644
--- a/src/plugins/irc/irc.h
+++ b/src/plugins/irc/irc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2017 Sébastien Helleu <flashcode@flashtux.org>
+ * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org>
* Copyright (C) 2006 Emmanuel Bouthenot <kolter@openics.org>
*
* This file is part of WeeChat, the extensible chat client.
@@ -18,8 +18,8 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WEECHAT_IRC_H
-#define WEECHAT_IRC_H 1
+#ifndef WEECHAT_PLUGIN_IRC_H
+#define WEECHAT_PLUGIN_IRC_H
#define weechat_plugin weechat_irc_plugin
#define IRC_PLUGIN_NAME "irc"
@@ -28,4 +28,4 @@ extern struct t_weechat_plugin *weechat_irc_plugin;
extern int irc_signal_upgrade_received;
-#endif /* WEECHAT_IRC_H */
+#endif /* WEECHAT_PLUGIN_IRC_H */