diff options
author | Timo Sirainen <cras@irssi.org> | 2000-04-26 08:03:38 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2000-04-26 08:03:38 +0000 |
commit | c95034c6de1bf72536595e1e3431d8ec64b9880e (patch) | |
tree | e51aa4528257ed8aa9d53640649519f299aaf0c7 /src/irc/flood | |
parent | d01b094151705d433bc43cae9eeb304e6f110a17 (diff) | |
download | irssi-c95034c6de1bf72536595e1e3431d8ec64b9880e.zip |
..adding new files..
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@171 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc/flood')
-rw-r--r-- | src/irc/flood/Makefile.am | 12 | ||||
-rw-r--r-- | src/irc/flood/autoignore.c | 250 | ||||
-rw-r--r-- | src/irc/flood/autoignore.h | 18 | ||||
-rw-r--r-- | src/irc/flood/flood.c | 212 | ||||
-rw-r--r-- | src/irc/flood/flood.h | 7 | ||||
-rw-r--r-- | src/irc/flood/module.h | 12 |
6 files changed, 511 insertions, 0 deletions
diff --git a/src/irc/flood/Makefile.am b/src/irc/flood/Makefile.am new file mode 100644 index 00000000..1ebebff4 --- /dev/null +++ b/src/irc/flood/Makefile.am @@ -0,0 +1,12 @@ +noinst_LTLIBRARIES = libirc_flood.la + +INCLUDES = $(GLIB_CFLAGS) \ + -I$(top_srcdir)/src -I$(top_srcdir)/src/core/ -I$(top_srcdir)/src/irc/core/ + +libirc_flood_la_SOURCES = \ + autoignore.c \ + flood.c + +noinst_HEADERS = \ + autoignore.h \ + flood.h diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c new file mode 100644 index 00000000..528ac618 --- /dev/null +++ b/src/irc/flood/autoignore.c @@ -0,0 +1,250 @@ +/* + autoignore.c : irssi + + Copyright (C) 1999-2000 Timo Sirainen + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "modules.h" +#include "signals.h" +#include "commands.h" +#include "levels.h" +#include "misc.h" +#include "settings.h" +#include "common-setup.h" + +#include "irc-server.h" +#include "ignore.h" + +#include "autoignore.h" + +static int ignore_tag; + +GSList *server_autoignores(IRC_SERVER_REC *server) +{ + MODULE_SERVER_REC *rec; + + g_return_val_if_fail(server != NULL, NULL); + + rec = MODULE_DATA(server); + return rec->ignorelist; +} + +static void autoignore_remove_rec(IRC_SERVER_REC *server, AUTOIGNORE_REC *rec) +{ + MODULE_SERVER_REC *mserver; + + g_return_if_fail(server != NULL); + g_return_if_fail(rec != NULL); + + signal_emit("autoignore remove", 2, server, rec); + + g_free(rec->nick); + g_free(rec); + + mserver = MODULE_DATA(server); + mserver->ignorelist = g_slist_remove(mserver->ignorelist, rec); +} + +static AUTOIGNORE_REC *autoignore_find(IRC_SERVER_REC *server, const char *mask) +{ + MODULE_SERVER_REC *mserver; + GSList *tmp; + + g_return_val_if_fail(server != NULL, NULL); + g_return_val_if_fail(mask != NULL, NULL); + + mserver = MODULE_DATA(server); + for (tmp = mserver->ignorelist; tmp != NULL; tmp = tmp->next) { + AUTOIGNORE_REC *rec = tmp->data; + + if (g_strcasecmp(rec->nick, mask) == 0) + return rec; + } + + return NULL; +} + +/* timeout function: unignore old ignores.. */ +static void autoignore_timeout_server(IRC_SERVER_REC *server) +{ + MODULE_SERVER_REC *mserver; + GSList *tmp, *next; + time_t t; + + g_return_if_fail(server != NULL); + + mserver = MODULE_DATA(server); + t = time(NULL); + t -= mserver->ignore_lastcheck; + + for (tmp = mserver->ignorelist; tmp != NULL; tmp = next) { + AUTOIGNORE_REC *rec = tmp->data; + + next = tmp->next; + if (rec->timeleft > t) + rec->timeleft -= t; + else + autoignore_remove_rec(server, rec); + } + + mserver->ignore_lastcheck = time(NULL); +} + +static int autoignore_timeout(void) +{ + g_slist_foreach(servers, (GFunc) autoignore_timeout_server, NULL); + return 1; +} + +static void autoignore_init_server(IRC_SERVER_REC *server) +{ + MODULE_SERVER_REC *mserver; + + g_return_if_fail(server != NULL); + + mserver = MODULE_DATA(server); + mserver->ignorelist = NULL; + mserver->ignore_lastcheck = time(NULL)-AUTOIGNORE_TIMECHECK; +} + +static void autoignore_deinit_server(IRC_SERVER_REC *server) +{ + MODULE_SERVER_REC *mserver; + + g_return_if_fail(server != NULL); + + mserver = MODULE_DATA(server); + while (mserver->ignorelist != NULL) + autoignore_remove_rec(server, (AUTOIGNORE_REC *) mserver->ignorelist->data); +} + +IGNORE_REC *ignore_find_server(IRC_SERVER_REC *server, const char *mask) +{ + GSList *tmp; + + for (tmp = ignores; tmp != NULL; tmp = tmp->next) { + IGNORE_REC *rec = tmp->data; + + if (rec->servertag != NULL && + g_strcasecmp(rec->mask, mask) == 0 && + g_strcasecmp(rec->servertag, server->tag) == 0) + return rec; + } + + return NULL; +} + +void autoignore_add(IRC_SERVER_REC *server, const char *nick, int level) +{ + MODULE_SERVER_REC *mserver; + AUTOIGNORE_REC *rec; + IGNORE_REC *irec; + int igtime; + + g_return_if_fail(server != NULL); + g_return_if_fail(nick != NULL); + if (level == 0) return; + + igtime = settings_get_int("autoignore_time"); + if (igtime <= 0) return; + + irec = ignore_find_server(server, nick); + if (irec == NULL) { + irec = g_new0(IGNORE_REC, 1); + irec->servertag = g_strdup(server->tag); + irec->mask = g_strdup(nick); + irec->level = level; + ignore_add_rec(irec); + } else { + irec->level |= level; + ignore_update_rec(irec); + } + + rec = autoignore_find(server, nick); + if (rec != NULL) { + /* already being ignored */ + rec->timeleft = igtime; + return; + } + + rec = g_new(AUTOIGNORE_REC, 1); + rec->nick = g_strdup(nick); + rec->timeleft = igtime; + rec->level = level; + + mserver = MODULE_DATA(server); + mserver->ignorelist = g_slist_append(mserver->ignorelist, rec); + + signal_emit("autoignore new", 2, server, rec); +} + +int autoignore_remove(IRC_SERVER_REC *server, const char *mask, int level) +{ + AUTOIGNORE_REC *rec; + IGNORE_REC *irec; + + g_return_val_if_fail(server != NULL, FALSE); + g_return_val_if_fail(mask != NULL, FALSE); + + irec = ignore_find_server(server, mask); + if (irec != NULL) { + irec->level &= ~level; + ignore_update_rec(irec); + } + + rec = autoignore_find(server, mask); + if (rec != NULL && (level & rec->level)) { + rec->level &= ~level; + if (rec->level == 0) autoignore_remove_rec(server, rec); + return TRUE; + } + + return FALSE; +} + +static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host, const char *levelstr) +{ + int level, check_level; + + level = level2bits(levelstr); + check_level = level2bits(settings_get_str("autoignore_levels")); + + if (level & check_level) + autoignore_add(server, nick, level); +} + +void autoignore_init(void) +{ + settings_add_int("flood", "autoignore_time", 300); + settings_add_str("flood", "autoignore_levels", "ctcps"); + + ignore_tag = g_timeout_add(AUTOIGNORE_TIMECHECK, (GSourceFunc) autoignore_timeout, NULL); + + signal_add("server connected", (SIGNAL_FUNC) autoignore_init_server); + signal_add("server disconnected", (SIGNAL_FUNC) autoignore_deinit_server); + signal_add("flood", (SIGNAL_FUNC) sig_flood); +} + +void autoignore_deinit(void) +{ + g_source_remove(ignore_tag); + + signal_remove("server connected", (SIGNAL_FUNC) autoignore_init_server); + signal_remove("server disconnected", (SIGNAL_FUNC) autoignore_deinit_server); + signal_remove("flood", (SIGNAL_FUNC) sig_flood); +} diff --git a/src/irc/flood/autoignore.h b/src/irc/flood/autoignore.h new file mode 100644 index 00000000..efa01d27 --- /dev/null +++ b/src/irc/flood/autoignore.h @@ -0,0 +1,18 @@ +#ifndef __AUTOIGNORE_H +#define __AUTOIGNORE_H + +typedef struct { + char *nick; + int timeleft; + int level; +} AUTOIGNORE_REC; + +GSList *server_autoignores(IRC_SERVER_REC *server); + +void autoignore_add(IRC_SERVER_REC *server, const char *nick, int level); +int autoignore_remove(IRC_SERVER_REC *server, const char *mask, int level); + +void autoignore_init(void); +void autoignore_deinit(void); + +#endif diff --git a/src/irc/flood/flood.c b/src/irc/flood/flood.c new file mode 100644 index 00000000..5522243e --- /dev/null +++ b/src/irc/flood/flood.c @@ -0,0 +1,212 @@ +/* + + flood.c : Flood protection (see also ctcp.c) + + Copyright (C) 1999 Timo Sirainen + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "modules.h" +#include "signals.h" +#include "levels.h" +#include "misc.h" +#include "settings.h" + +#include "irc.h" +#include "irc-server.h" +#include "autoignore.h" +#include "ignore.h" + +typedef struct { + char *nick; + int level; + int msgcount; +} FLOOD_REC; + +static int flood_tag; +static int flood_max_msgs; + +static int flood_hash_deinit(const char *key, FLOOD_REC *rec) +{ + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(rec != NULL, FALSE); + + g_free(rec->nick); + g_free(rec); + return TRUE; +} + +/* timeout function: flood protection */ +static int flood_timeout(void) +{ + MODULE_SERVER_REC *mserver; + GSList *tmp; + + /* remove everyone from flood list */ + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; + + mserver = MODULE_DATA(rec); + g_hash_table_foreach_remove(mserver->floodlist, (GHRFunc) flood_hash_deinit, NULL); + } + return 1; +} + +/* Initialize flood protection */ +static void flood_init_server(IRC_SERVER_REC *server) +{ + MODULE_SERVER_REC *rec; + + g_return_if_fail(server != NULL); + + rec = g_new0(MODULE_SERVER_REC, 1); + MODULE_DATA_SET(server, rec); + + rec->floodlist = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal); +} + +/* Deinitialize flood protection */ +static void flood_deinit_server(IRC_SERVER_REC *server) +{ + MODULE_SERVER_REC *mserver; + + g_return_if_fail(server != NULL); + + mserver = MODULE_DATA(server); + if (mserver != NULL && mserver->floodlist != NULL) { + g_hash_table_freeze(mserver->floodlist); + g_hash_table_foreach(mserver->floodlist, (GHFunc) flood_hash_deinit, NULL); + g_hash_table_thaw(mserver->floodlist); + g_hash_table_destroy(mserver->floodlist); + } + g_free(mserver); +} + +/* All messages should go through here.. */ +static void flood_newmsg(IRC_SERVER_REC *server, int level, const char *nick, const char *host, const char *target) +{ + MODULE_SERVER_REC *mserver; + FLOOD_REC *rec; + char *levelstr; + + g_return_if_fail(server != NULL); + g_return_if_fail(nick != NULL); + + mserver = MODULE_DATA(server); + rec = g_hash_table_lookup(mserver->floodlist, nick); + if (rec != NULL) { + if (++rec->msgcount > flood_max_msgs) { + /* flooding! */ + levelstr = bits2level(rec->level); + signal_emit("flood", 5, server, nick, host, levelstr, target); + g_free(levelstr); + } + return; + } + + rec = g_new(FLOOD_REC, 1); + rec->level = level; + rec->msgcount = 1; + rec->nick = g_strdup(nick); + + g_hash_table_insert(mserver->floodlist, rec->nick, rec); +} + +static void flood_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) +{ + int publiclevel; + char *params, *target, *text; + + g_return_if_fail(data != NULL); + g_return_if_fail(server != NULL); + + if (nick == NULL) { + /* don't try to ignore server messages.. */ + return; + } + + params = event_get_params(data, 2, &target, &text); + + if (*text == 1) { + /* CTCP */ + if (!ignore_check(server, nick, addr, target, text, MSGLEVEL_CTCPS)) + flood_newmsg(server, MSGLEVEL_CTCPS, nick, addr, target); + } else { + publiclevel = ischannel(*target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS; + + if (addr != NULL && !ignore_check(server, nick, addr, target, text, publiclevel)) + flood_newmsg(server, publiclevel, nick, addr, target); + } + + g_free(params); +} + +static void flood_notice(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) +{ + char *params, *target, *text; + + g_return_if_fail(text != NULL); + g_return_if_fail(server != NULL); + + if (nick == NULL) { + /* don't try to ignore server messages.. */ + return; + } + + params = event_get_params(data, 2, &target, &text); + if (addr != NULL && !ignore_check(server, nick, addr, target, text, MSGLEVEL_NOTICES)) + flood_newmsg(server, MSGLEVEL_NOTICES | ischannel(*target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS, nick, addr, target); + + g_free(params); +} + +static void read_settings(void) +{ + if (flood_tag != -1) g_source_remove(flood_tag); + flood_tag = g_timeout_add(settings_get_int("flood_timecheck"), (GSourceFunc) flood_timeout, NULL); + + flood_max_msgs = settings_get_int("flood_max_msgs"); +} + +void flood_init(void) +{ + settings_add_int("flood", "flood_timecheck", 1000); + settings_add_int("flood", "flood_max_msgs", 5); + + flood_tag = -1; + read_settings(); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); + signal_add_first("server connected", (SIGNAL_FUNC) flood_init_server); + signal_add("server disconnected", (SIGNAL_FUNC) flood_deinit_server); + signal_add("event privmsg", (SIGNAL_FUNC) flood_privmsg); + signal_add("event notice", (SIGNAL_FUNC) flood_notice); + + autoignore_init(); +} + +void flood_deinit(void) +{ + autoignore_deinit(); + + if (flood_tag != -1) g_source_remove(flood_tag); + + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + signal_remove("server connected", (SIGNAL_FUNC) flood_init_server); + signal_remove("server disconnected", (SIGNAL_FUNC) flood_deinit_server); + signal_remove("event privmsg", (SIGNAL_FUNC) flood_privmsg); + signal_remove("event notice", (SIGNAL_FUNC) flood_notice); +} diff --git a/src/irc/flood/flood.h b/src/irc/flood/flood.h new file mode 100644 index 00000000..e6454729 --- /dev/null +++ b/src/irc/flood/flood.h @@ -0,0 +1,7 @@ +#ifndef __FLOOD_H +#define __FLOOD_H + +void flood_init(void); +void flood_deinit(void); + +#endif diff --git a/src/irc/flood/module.h b/src/irc/flood/module.h new file mode 100644 index 00000000..9abdbf41 --- /dev/null +++ b/src/irc/flood/module.h @@ -0,0 +1,12 @@ +#include "common.h" + +typedef struct { + /* Flood protection */ + GHashTable *floodlist; + + /* Auto ignore list */ + GSList *ignorelist; + time_t ignore_lastcheck; +} MODULE_SERVER_REC; + +#define MODULE_NAME "irc/flood" |