1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-30 06:46:38 +02:00

Reintroduce /ignore command to ignore IRC nicks/hosts, using regex

This commit is contained in:
Sebastien Helleu
2008-09-03 18:20:35 +02:00
parent 909d123692
commit e43dd39646
21 changed files with 2371 additions and 1039 deletions
+1
View File
@@ -24,6 +24,7 @@ irc-completion.c irc-completion.h
irc-config.c irc-config.h
irc-debug.c irc-debug.h
irc-display.c irc-display.h
irc-ignore.c irc-ignore.h
irc-info.c irc-info.h
irc-input.c irc-input.h
irc-mode.c irc-mode.h
+2
View File
@@ -38,6 +38,8 @@ irc_la_SOURCES = irc.c \
irc-debug.h \
irc-display.c \
irc-display.h \
irc-ignore.c \
irc-ignore.h \
irc-info.c \
irc-info.h \
irc-input.c \
+178
View File
@@ -38,6 +38,7 @@
#include "irc-channel.h"
#include "irc-nick.h"
#include "irc-display.h"
#include "irc-ignore.h"
/*
@@ -1285,6 +1286,159 @@ irc_command_halfop (void *data, struct t_gui_buffer *buffer, int argc,
return WEECHAT_RC_OK;
}
/*
* irc_command_ignore: add or remove ignore
*/
int
irc_command_ignore (void *data, struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
int i;
struct t_irc_ignore *ptr_ignore;
char *mask, *server, *channel, *error;
long number;
/* make C compiler happy */
(void) data;
(void) buffer;
(void) argv_eol;
if ((argc == 1)
|| ((argc == 2) && (weechat_strcasecmp (argv[1], "list") == 0)))
{
/* display all key bindings */
if (irc_ignore_list)
{
weechat_printf (NULL, "");
weechat_printf (NULL, _("%s: ignore list:"), "irc");
i = 0;
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
i++;
weechat_printf (NULL,
_(" %s[%s%d%s]%s mask: %s / server: %s / channel: %s"),
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT,
i,
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT,
ptr_ignore->mask,
(ptr_ignore->server) ?
ptr_ignore->server : "*",
(ptr_ignore->channel) ?
ptr_ignore->channel : "*");
}
}
else
weechat_printf (NULL, _("%s: no ignore in list"), "irc");
return WEECHAT_RC_OK;
}
/* add ignore */
if (weechat_strcasecmp (argv[1], "add") == 0)
{
if (argc < 3)
{
weechat_printf (NULL,
_("%s%s: missing arguments for \"%s\" "
"command"),
weechat_prefix ("error"), "irc",
"ignore add");
return WEECHAT_RC_ERROR;
}
mask = argv[2];
server = (argc > 3) ? argv[3] : NULL;
channel = (argc > 4) ? argv[4] : NULL;
if (irc_ignore_search (mask, server, channel))
{
weechat_printf (NULL,
_("%s%s: ignore already exists"),
weechat_prefix ("error"), "irc");
return WEECHAT_RC_ERROR;
}
if (irc_ignore_new (mask, server, channel))
{
weechat_printf (NULL, _("%s: ignore added"), "irc");
}
else
{
weechat_printf (NULL, _("%s%s: error adding ignore"),
weechat_prefix ("error"), "irc");
}
return WEECHAT_RC_OK;
}
/* delete ignore */
if (weechat_strcasecmp (argv[1], "del") == 0)
{
if (argc < 3)
{
weechat_printf (NULL,
_("%s%s: missing arguments for \"%s\" "
"command"),
weechat_prefix ("error"), "irc",
"ignore del");
return WEECHAT_RC_ERROR;
}
if (weechat_strcasecmp (argv[2], "-all") == 0)
{
if (irc_ignore_list)
{
irc_ignore_free_all ();
weechat_printf (NULL, _("%s: all ignore deleted"), "irc");
}
else
{
weechat_printf (NULL, _("%s: no ignore in list"), "irc");
}
}
else
{
error = NULL;
number = strtol (argv[2], &error, 10);
if (error && !error[0])
{
ptr_ignore = irc_ignore_search_by_number (number);
if (ptr_ignore)
{
irc_ignore_free (ptr_ignore);
weechat_printf (NULL, _("%s: ignore deleted"), "irc");
}
else
{
weechat_printf (NULL,
_("%s%s: ignore not found"),
weechat_prefix ("error"), "irc");
return WEECHAT_RC_ERROR;
}
}
else
{
weechat_printf (NULL,
_("%s%s: wrong ignore number"),
weechat_prefix ("error"), "irc");
return WEECHAT_RC_ERROR;
}
}
return WEECHAT_RC_OK;
}
weechat_printf (NULL,
_("%s%s: unknown option for \"%s\" "
"command"),
weechat_prefix ("error"), "irc", "ignore");
return WEECHAT_RC_ERROR;
}
/*
* irc_command_info: get information describing the server
*/
@@ -3602,6 +3756,30 @@ irc_command_init ()
N_("[nickname [nickname]]"),
"",
NULL, &irc_command_halfop, NULL);
weechat_hook_command ("ignore",
N_("ignore nicks/hosts from servers or channels"),
N_("[list] | [add nick/host [server [channel]]] | "
"[del number|-all]"),
N_(" list: list all ignore\n"
" add: add a ignore\n"
" del: del a ignore\n"
" number: number of ignore to delete (look at "
"list to find it)\n"
" -all: delete all ignore\n"
"nick/host: nick or host to ignore (regular "
"expression allowed)\n"
" server: internal server name where ignore "
"is working\n"
" channel: channel name where ignore is "
"working\n\n"
"Examples:\n"
" ignore nick \"toto\" everywhere:\n"
" /ignore add toto\n"
" ignore host \"toto@domain.com\" on freenode server:\n"
" /ignore add toto@domain.com freenode\n"
" ignore host \"toto*@*.domain.com\" on freenode/#weechat:\n"
" /ignore add toto*@*.domain.com freenode #weechat"),
NULL, &irc_command_ignore, NULL);
weechat_hook_command ("info",
N_("get information describing the server"),
N_("[target]"),
+87
View File
@@ -29,6 +29,7 @@
#include "../weechat-plugin.h"
#include "irc.h"
#include "irc-config.h"
#include "irc-ignore.h"
#include "irc-server.h"
@@ -444,6 +445,8 @@ irc_config_reload (void *data, struct t_config_file *config_file)
ptr_server->reloaded_from_config = 0;
}
irc_ignore_free_all ();
rc = weechat_config_reload (config_file);
if (rc == WEECHAT_CONFIG_READ_OK)
@@ -478,6 +481,72 @@ irc_config_reload (void *data, struct t_config_file *config_file)
return rc;
}
/*
* irc_config_ignore_read: read ignore option from config file
* return 1 if ok, 0 if error
*/
int
irc_config_ignore_read (void *data,
struct t_config_file *config_file,
struct t_config_section *section,
const char *option_name, const char *value)
{
char **argv, **argv_eol;
int argc;
/* make C compiler happy */
(void) data;
(void) config_file;
(void) section;
if (option_name)
{
if (value && value[0])
{
argv = weechat_string_explode (value, ";", 0, 0, &argc);
argv_eol = weechat_string_explode (value, ";", 1, 0, NULL);
if (argv && argv_eol && (argc >= 3))
{
irc_ignore_new (argv_eol[2], argv[0], argv[1]);
}
if (argv)
weechat_string_free_exploded (argv);
if (argv_eol)
weechat_string_free_exploded (argv_eol);
}
}
return 1;
}
/*
* irc_config_ignore_write: write ignore section in configuration file
*/
void
irc_config_ignore_write (void *data, struct t_config_file *config_file,
const char *section_name)
{
struct t_irc_ignore *ptr_ignore;
/* make C compiler happy */
(void) data;
weechat_config_write_line (config_file, section_name, NULL);
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
weechat_config_write_line (config_file,
"ignore",
"%s;%s;%s",
(ptr_ignore->server) ? ptr_ignore->server : "*",
(ptr_ignore->channel) ? ptr_ignore->channel : "*",
ptr_ignore->mask);
}
}
/*
* irc_config_server_write_default: write default server section in configuration file
*/
@@ -847,6 +916,7 @@ irc_config_init ()
if (!irc_config_file)
return 0;
/* look */
ptr_section = weechat_config_new_section (irc_config_file, "look",
0, 0,
NULL, NULL, NULL, NULL,
@@ -905,6 +975,7 @@ irc_config_init ()
N_("display notices as private messages"),
NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL);
/* network */
ptr_section = weechat_config_new_section (irc_config_file, "network",
0, 0,
NULL, NULL, NULL, NULL,
@@ -980,6 +1051,7 @@ irc_config_init ()
N_("send unknown commands to IRC server"),
NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL);
/* log */
ptr_section = weechat_config_new_section (irc_config_file, "log",
0, 0,
NULL, NULL, NULL, NULL,
@@ -1010,7 +1082,21 @@ irc_config_init ()
"hide_nickserv_pwd", "boolean",
N_("hide password displayed by nickserv"),
NULL, 0, 0, "on", NULL, NULL, &irc_config_change_log, NULL, NULL, NULL);
/* filters */
ptr_section = weechat_config_new_section (irc_config_file, "ignore",
0, 0,
&irc_config_ignore_read, NULL,
&irc_config_ignore_write, NULL,
&irc_config_ignore_write, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (irc_config_file);
return 0;
}
/* server_default */
ptr_section = weechat_config_new_section (irc_config_file, "server_default",
0, 0,
NULL, NULL, NULL, NULL,
@@ -1025,6 +1111,7 @@ irc_config_init ()
irc_config_server_create_default_options (ptr_section);
/* server */
ptr_section = weechat_config_new_section (irc_config_file, "server",
1, 1,
NULL, NULL,
+286
View File
@@ -0,0 +1,286 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* irc-ignore.c: manages ignore list (nicks/hosts) on IRC servers/channels */
#include <stdlib.h>
#include <string.h>
#include "../weechat-plugin.h"
#include "irc.h"
#include "irc-ignore.h"
#include "irc-channel.h"
#include "irc-server.h"
struct t_irc_ignore *irc_ignore_list = NULL; /* list of ignore */
struct t_irc_ignore *last_irc_ignore = NULL; /* last ignore in list */
/*
* irc_ignore_valid: check if a ignore pointer exists
* return 1 if ignore exists
* 0 if ignore is not found
*/
int
irc_ignore_valid (struct t_irc_ignore *ignore)
{
struct t_irc_ignore *ptr_ignore;
if (!ignore)
return 0;
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
if (ptr_ignore == ignore)
return 1;
}
/* ignore not found */
return 0;
}
/*
* irc_ignore_search: search a ignore
*/
struct t_irc_ignore *
irc_ignore_search (const char *mask, const char *server, const char *channel)
{
struct t_irc_ignore *ptr_ignore;
char any[2] = "*";
if (!server)
server = any;
if (!channel)
channel = any;
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
if ((strcmp (ptr_ignore->mask, mask) == 0)
&& (weechat_strcasecmp (ptr_ignore->server, server) == 0)
&& (weechat_strcasecmp (ptr_ignore->channel, channel) == 0))
{
return ptr_ignore;
}
}
/* ignore not found */
return NULL;
}
/*
* irc_ignore_search_by_number: search a ignore by number (first is #1)
*/
struct t_irc_ignore *
irc_ignore_search_by_number (int number)
{
struct t_irc_ignore *ptr_ignore;
int i;
i = 1;
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
if (i == number)
return ptr_ignore;
i++;
}
/* ignore not found */
return NULL;
}
/*
* irc_ignore_new: add new ignore
*/
struct t_irc_ignore *
irc_ignore_new (const char *mask, const char *server, const char *channel)
{
struct t_irc_ignore *new_ignore;
regex_t *regex;
if (!mask)
return NULL;
regex = malloc (sizeof (*regex));
if (!regex)
return NULL;
if (regcomp (regex, mask, REG_NOSUB | REG_ICASE) != 0)
{
free (regex);
return NULL;
}
new_ignore = malloc (sizeof (*new_ignore));
if (new_ignore)
{
new_ignore->mask = strdup (mask);
new_ignore->regex_mask = regex;
new_ignore->server = (server) ? strdup (server) : strdup ("*");
new_ignore->channel = (channel) ? strdup (channel) : strdup ("*");
/* add ignore to ignore list */
new_ignore->prev_ignore = last_irc_ignore;
if (irc_ignore_list)
last_irc_ignore->next_ignore = new_ignore;
else
irc_ignore_list = new_ignore;
last_irc_ignore = new_ignore;
new_ignore->next_ignore = NULL;
}
return new_ignore;
}
/*
* irc_ignore_check: check if a message (from an IRC server) should be ignored
* or not
* return: 1 if message will be ignored
* 0 if message will be displayed (NOT ignored)
*/
int
irc_ignore_check (struct t_irc_server *server, struct t_irc_channel *channel,
char *nick, char *host)
{
struct t_irc_ignore *ptr_ignore;
int server_match, channel_match, regex_match;
if (!server)
return 0;
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
server_match = 0;
channel_match = 0;
regex_match = 0;
if (!server || (strcmp (ptr_ignore->server, "*") == 0))
server_match = 1;
else
server_match = (weechat_strcasecmp (ptr_ignore->server,
server->name) == 0);
if (!channel || (strcmp (ptr_ignore->channel, "*") == 0))
channel_match = 1;
else
{
channel_match = (weechat_strcasecmp (ptr_ignore->channel,
channel->name) == 0);
}
if (server_match && channel_match)
{
if (nick && (strcmp (ptr_ignore->mask, nick) == 0))
return 1;
if (host && regexec (ptr_ignore->regex_mask, host, 0, NULL, 0) == 0)
return 1;
}
}
return 0;
}
/*
* irc_ignore_free: remove a ignore
*/
void
irc_ignore_free (struct t_irc_ignore *ignore)
{
weechat_hook_signal_send ("irc_ignore_removing",
WEECHAT_HOOK_SIGNAL_POINTER, ignore);
/* free data */
if (ignore->mask)
free (ignore->mask);
if (ignore->regex_mask)
{
regfree (ignore->regex_mask);
free (ignore->regex_mask);
}
if (ignore->server)
free (ignore->server);
if (ignore->channel)
free (ignore->channel);
/* remove filter from filters list */
if (ignore->prev_ignore)
ignore->prev_ignore->next_ignore = ignore->next_ignore;
if (ignore->next_ignore)
ignore->next_ignore->prev_ignore = ignore->prev_ignore;
if (irc_ignore_list == ignore)
irc_ignore_list = ignore->next_ignore;
if (last_irc_ignore == ignore)
last_irc_ignore = ignore->prev_ignore;
free (ignore);
weechat_hook_signal_send ("irc_ignore_removed",
WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
/*
* irc_ignore_free_all: remove all ignore
*/
void
irc_ignore_free_all ()
{
while (irc_ignore_list)
{
irc_ignore_free (irc_ignore_list);
}
}
/*
* irc_ignore_add_to_infolist: add a ignore in an infolist
* return 1 if ok, 0 if error
*/
int
irc_ignore_add_to_infolist (struct t_infolist *infolist,
struct t_irc_ignore *ignore)
{
struct t_infolist_item *ptr_item;
if (!infolist || !ignore)
return 0;
ptr_item = weechat_infolist_new_item (infolist);
if (!ptr_item)
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "mask", ignore->mask))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "server", ignore->server))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "channel", ignore->channel))
return 0;
return 1;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_IRC_IGNORE_H
#define __WEECHAT_IRC_IGNORE_H 1
#include <regex.h>
struct t_irc_server;
struct t_irc_channel;
struct t_irc_ignore
{
char *mask; /* nick / host mask */
regex_t *regex_mask; /* regex for mask */
char *server; /* server name */
char *channel; /* channel name */
struct t_irc_ignore *prev_ignore; /* link to previous ignore */
struct t_irc_ignore *next_ignore; /* link to next ignore */
};
extern struct t_irc_ignore *irc_ignore_list;
extern int irc_ignore_valid (struct t_irc_ignore *ignore);
extern struct t_irc_ignore *irc_ignore_search (const char *mask,
const char *server,
const char *channel);
extern struct t_irc_ignore *irc_ignore_search_by_number (int number);
extern struct t_irc_ignore *irc_ignore_new (const char *mask,
const char *server,
const char *channel);
extern int irc_ignore_check (struct t_irc_server *server,
struct t_irc_channel *channel,
char *nick, char *host);
extern void irc_ignore_free (struct t_irc_ignore *ignore);
extern void irc_ignore_free_all ();
extern int irc_ignore_add_to_infolist (struct t_infolist *infolist,
struct t_irc_ignore *ignore);
#endif /* irc-ignore.h */
+38
View File
@@ -26,6 +26,7 @@
#include "../weechat-plugin.h"
#include "irc.h"
#include "irc-channel.h"
#include "irc-ignore.h"
#include "irc-nick.h"
#include "irc-protocol.h"
#include "irc-server.h"
@@ -172,6 +173,7 @@ irc_info_get_infolist_cb (void *data, const char *infolist_name,
struct t_irc_server *ptr_server;
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick;
struct t_irc_ignore *ptr_ignore;
char *pos_comma, *server_name;
/* make C compiler happy */
@@ -314,6 +316,40 @@ irc_info_get_infolist_cb (void *data, const char *infolist_name,
}
}
}
else if (weechat_strcasecmp (infolist_name, "irc_ignore") == 0)
{
if (pointer && !irc_ignore_valid (pointer))
return NULL;
ptr_infolist = weechat_infolist_new ();
if (ptr_infolist)
{
if (pointer)
{
/* build list with only one ignore */
if (!irc_ignore_add_to_infolist (ptr_infolist, pointer))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
return ptr_infolist;
}
else
{
/* build list with all ignore */
for (ptr_ignore = irc_ignore_list; ptr_ignore;
ptr_ignore = ptr_ignore->next_ignore)
{
if (!irc_ignore_add_to_infolist (ptr_infolist, ptr_ignore))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
}
return ptr_infolist;
}
}
}
return NULL;
}
@@ -340,4 +376,6 @@ irc_info_init ()
&irc_info_get_infolist_cb, NULL);
weechat_hook_infolist ("irc_nick", N_("list of nicks for an IRC channel"),
&irc_info_get_infolist_cb, NULL);
weechat_hook_infolist ("irc_ignore", N_("list of IRC ignore"),
&irc_info_get_infolist_cb, NULL);
}
File diff suppressed because it is too large Load Diff
+14
View File
@@ -20,6 +20,20 @@
#ifndef __WEECHAT_IRC_PROTOCOL_H
#define __WEECHAT_IRC_PROTOCOL_H 1
#define IRC_PROTOCOL_GET_HOST \
char *nick, *address, *host; \
if (argv[0][0] == ':') \
{ \
nick = irc_protocol_get_nick_from_host (argv[0]); \
address = irc_protocol_get_address_from_host (argv[0]); \
host = argv[0] + 1; \
} \
else \
{ \
nick = NULL; \
address = NULL; \
host = NULL; \
}
#define IRC_PROTOCOL_MIN_ARGS(__min_args) \
if (argc < __min_args) \
{ \