1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-27 21:36:37 +02:00

irc: add indexed ban list, add completion for /unban and /unquiet (closes #597, task #11374, task #10876)

This commit is contained in:
Simmo Saan
2018-03-24 17:01:50 +01:00
committed by Sébastien Helleu
parent b2f971d4b0
commit d77e1ea499
15 changed files with 1160 additions and 20 deletions
+1
View File
@@ -253,6 +253,7 @@ WeeChat "core" is located in following directories:
|       irc-input.c | Input of commands/text.
|       irc-message.c | Functions to manipulate IRC messages.
|       irc-mode.c | Functions about channel/nick modes.
| irc-modelist.c | IRC channel mode lists (+b, +e, +I)
|       irc-msgbuffer.c | Target buffer for IRC messages.
|       irc-nick.c | IRC nicks.
|       irc-notify.c | IRC notify lists.
+1
View File
@@ -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
+2
View File
@@ -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 \
+18
View File
@@ -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"
@@ -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 *chanmodes;
/* create buffer for channel (or use existing one) */
ptr_buffer = irc_channel_create_buffer (server, channel_type,
@@ -479,6 +481,12 @@ 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 (chanmodes = irc_server_get_chanmodes (server); chanmodes[0] && chanmodes[0] != ','; chanmodes++)
{
irc_modelist_new (new_channel, chanmodes[0]);
}
new_channel->join_smart_filtered = NULL;
new_channel->buffer = ptr_buffer;
new_channel->buffer_as_string = NULL;
@@ -1387,6 +1395,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 +1481,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 +1640,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 +1668,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,
@@ -1695,4 +1709,8 @@ irc_channel_print_log (struct t_irc_channel *channel)
{
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);
}
}
+3
View File
@@ -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 */
+26 -6
View File
@@ -42,6 +42,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 +239,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 +270,30 @@ 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 (set[0] == '-' && ptr_modelist)
{
error = NULL;
number = strtol (argv[pos_masks], &error, 10);
if (error && !error[0])
{
ptr_item = irc_modelist_item_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,
@@ -6957,15 +6977,15 @@ irc_command_init ()
N_("unban nicks or hosts"),
N_("[<channel>] <nick> [<nick>...]"),
N_("channel: channel name\n"
" nick: nick or host"),
NULL, &irc_command_unban, NULL, NULL);
" nick: nick, host or ban number"),
"%(irc_modelist:b)", &irc_command_unban, NULL, NULL);
weechat_hook_command (
"unquiet",
N_("unquiet nicks or hosts"),
N_("[<channel>] <nick> [<nick>...]"),
N_("channel: channel name\n"
" nick: nick or host"),
"%(irc_channel_nicks_hosts)", &irc_command_unquiet, NULL, NULL);
" nick: nick, host or quiet number"),
"%(irc_modelist:q)", &irc_command_unquiet, NULL, NULL);
weechat_hook_command (
"userhost",
N_("return a list of information about nicks"),
+46
View File
@@ -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"
@@ -420,6 +421,47 @@ irc_completion_channel_nicks_hosts_cb (const void *pointer, void *data,
return WEECHAT_RC_OK;
}
/*
* Adds modelist masks current channel to completion list.
*/
int
irc_completion_modelist_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 topic of current channel to completion list.
*/
@@ -758,6 +800,10 @@ 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",
N_("modelist masks of current IRC channel; "
"required argument: modelist mode"),
&irc_completion_modelist_cb, NULL, NULL);
weechat_hook_completion ("irc_channel_topic",
N_("topic of current IRC channel"),
&irc_completion_channel_topic_cb, NULL, NULL);
+216
View File
@@ -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"
@@ -573,6 +574,203 @@ irc_info_infolist_irc_channel_cb (const void *pointer, void *data,
return NULL;
}
/*
* 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;
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 >= 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))
{
obj_pointer = irc_modelist_item_number (ptr_modelist, atoi(argv[3]));
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".
*/
@@ -919,6 +1117,18 @@ irc_info_init ()
N_("channel pointer (optional)"),
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 channel mode list items for 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"),
@@ -948,6 +1158,12 @@ irc_info_init ()
weechat_hook_hdata (
"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);
+23
View File
@@ -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,14 @@ 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;
if (!server || !channel || !modes)
return 0;
@@ -464,6 +468,25 @@ 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 == '-')
{
irc_modelist_item_free (ptr_modelist,
irc_modelist_item_search (ptr_modelist, ptr_arg));
}
}
}
if (update_channel_modes)
{
irc_mode_channel_update (server, channel, set_flag,
+1
View File
@@ -27,6 +27,7 @@ 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);
+495
View File
@@ -0,0 +1,495 @@
/*
* irc-modelist.c - channel mode list management for IRC plugin
*
* Copyright (C) 2015 Simmo Saan <simmo.saan@gmail.com>
*
* 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 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;
}
/*
* 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 channel from channels 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;
}
/*
* Searches for an item by mask.
*
* Returns pointer to item found, NULL if not found.
*/
struct t_irc_modelist_item *
irc_modelist_item_search (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_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;
}
/*
* 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;
}
/*
* 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);
}
}
/*
* 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;
}
/*
* 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, item->number);
weechat_log_printf (" mask . . . . . . . . . . : '%s'", item->mask);
weechat_log_printf (" setter . . . . . . . . . : '%s'", item->setter);
weechat_log_printf (" datetime . . . . . . . . : '%s'", 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);
}
}
+90
View File
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2015 Simmo Saan <simmo.saan@gmail.com>
*
* 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_IRC_MODELIST_H
#define WEECHAT_IRC_MODELIST_H 1
/* 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 */
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_item_valid (struct t_irc_modelist *modelist,
struct t_irc_modelist_item *item);
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_irc_modelist_item *irc_modelist_item_search (struct t_irc_modelist *modelist,
const char *mask);
extern struct t_irc_modelist_item *irc_modelist_item_number (struct t_irc_modelist *modelist,
int number);
extern int irc_modelist_valid (struct t_irc_channel *channel,
struct t_irc_modelist *modelist);
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 struct t_irc_modelist *irc_modelist_search (struct t_irc_channel *channel,
char type);
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_IRC_MODELIST_H */
+164 -14
View File
@@ -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"
@@ -947,6 +948,7 @@ IRC_PROTOCOL_CALLBACK(kick)
int rejoin;
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick, *ptr_nick_kicked;
struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(4);
IRC_PROTOCOL_CHECK_HOST;
@@ -1006,6 +1008,10 @@ IRC_PROTOCOL_CALLBACK(kick)
*/
irc_nick_free_all (server, ptr_channel);
for (ptr_modelist = ptr_channel->modelists; ptr_modelist;
ptr_modelist = ptr_modelist->next_modelist)
ptr_modelist->state = IRC_MODELIST_STATE_MODIFIED;
/* read option "autorejoin" in server */
rejoin = IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_AUTOREJOIN);
@@ -1066,6 +1072,7 @@ IRC_PROTOCOL_CALLBACK(kill)
char *pos_comment;
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick, *ptr_nick_killed;
struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(3);
IRC_PROTOCOL_CHECK_HOST;
@@ -1120,6 +1127,10 @@ IRC_PROTOCOL_CALLBACK(kill)
*/
irc_nick_free_all (server, ptr_channel);
for (ptr_modelist = ptr_channel->modelists; ptr_modelist;
ptr_modelist = ptr_modelist->next_modelist)
ptr_modelist->state = IRC_MODELIST_STATE_MODIFIED;
irc_bar_item_update_channel ();
}
else
@@ -1162,7 +1173,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);
@@ -1661,6 +1672,7 @@ IRC_PROTOCOL_CALLBACK(part)
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick;
struct t_irc_channel_speaking *ptr_nick_speaking;
struct t_irc_modelist *ptr_modelist;
IRC_PROTOCOL_MIN_ARGS(3);
IRC_PROTOCOL_CHECK_HOST;
@@ -1757,6 +1769,10 @@ IRC_PROTOCOL_CALLBACK(part)
{
irc_nick_free_all (server, ptr_channel);
for (ptr_modelist = ptr_channel->modelists; ptr_modelist;
ptr_modelist = ptr_modelist->next_modelist)
ptr_modelist->state = IRC_MODELIST_STATE_MODIFIED;
/* cycling ? => rejoin channel immediately */
if (ptr_channel->cycle)
{
@@ -3294,7 +3310,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);
}
}
@@ -3878,14 +3894,35 @@ 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 (
@@ -3894,18 +3931,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,
@@ -3914,17 +3954,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,
@@ -3933,17 +3976,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);
@@ -3964,6 +4010,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);
@@ -3973,6 +4020,9 @@ 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)
ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "invitelist", ptr_buffer),
@@ -4003,14 +4053,35 @@ 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 (
@@ -4019,18 +4090,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%sexception %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],
@@ -4040,17 +4114,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%sexception %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],
@@ -4060,17 +4137,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%sexception %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]);
@@ -4091,6 +4171,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);
@@ -4100,6 +4181,9 @@ 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)
ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "exceptionlist", ptr_buffer),
@@ -4761,14 +4845,34 @@ 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)
{
@@ -4778,18 +4882,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,
@@ -4798,17 +4905,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,
@@ -4817,17 +4927,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);
@@ -4848,6 +4961,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);
@@ -4857,6 +4971,9 @@ 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)
ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "banlist", ptr_buffer),
@@ -5188,14 +5305,34 @@ 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)
{
@@ -5205,18 +5342,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,
@@ -5225,17 +5365,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,
@@ -5244,17 +5387,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);
@@ -5275,6 +5421,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);
@@ -5284,6 +5431,9 @@ 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)
ptr_modelist->state = IRC_MODELIST_STATE_RECEIVED;
weechat_printf_date_tags (
irc_msgbuffer_get_target_buffer (
server, NULL, command, "quietlist", ptr_buffer),
+72
View File
@@ -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 */
@@ -657,6 +702,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)
{
+2
View File
@@ -33,6 +33,8 @@ 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 ();