From d3dc9a1307adc40425bf162f1f867a39e535f501 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 4 May 2000 10:32:42 +0000 Subject: .. lots of changes .. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@197 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- src/irc/flood/autoignore.c | 4 +- src/irc/flood/flood.c | 122 +++++++++++++++++++++++++++++++++------------ 2 files changed, 93 insertions(+), 33 deletions(-) (limited to 'src/irc/flood') diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 528ac618..da384dd9 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -217,11 +217,11 @@ int autoignore_remove(IRC_SERVER_REC *server, const char *mask, int level) return FALSE; } -static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host, const char *levelstr) +static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host, gpointer levelp) { int level, check_level; - level = level2bits(levelstr); + level = GPOINTER_TO_INT(levelp); check_level = level2bits(settings_get_str("autoignore_levels")); if (level & check_level) diff --git a/src/irc/flood/flood.c b/src/irc/flood/flood.c index 5522243e..7fb4773d 100644 --- a/src/irc/flood/flood.c +++ b/src/irc/flood/flood.c @@ -1,8 +1,7 @@ /* + flood.c : Flood protection - flood.c : Flood protection (see also ctcp.c) - - Copyright (C) 1999 Timo Sirainen + 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 @@ -32,36 +31,59 @@ #include "ignore.h" typedef struct { - char *nick; + char *target; int level; + int msgcount; + time_t first; +} FLOOD_ITEM_REC; + +typedef struct { + char *nick; + GSList *items; } FLOOD_REC; static int flood_tag; -static int flood_max_msgs; +static int flood_max_msgs, flood_timecheck; -static int flood_hash_deinit(const char *key, FLOOD_REC *rec) +static int flood_hash_deinit(const char *key, FLOOD_REC *flood, gpointer nowp) { + GSList *tmp, *next; + time_t now; + g_return_val_if_fail(key != NULL, FALSE); - g_return_val_if_fail(rec != NULL, FALSE); + g_return_val_if_fail(flood != NULL, FALSE); + + now = (time_t) GPOINTER_TO_INT(nowp); + for (tmp = flood->items; tmp != NULL; tmp = next) { + FLOOD_ITEM_REC *rec = tmp->data; - g_free(rec->nick); - g_free(rec); + next = tmp->next; + if (now-rec->first >= flood_timecheck) + flood->items = g_slist_remove(flood->items, rec); + } + + if (flood->items != NULL) + return FALSE; + + g_free(flood->nick); + g_free(flood); return TRUE; } -/* timeout function: flood protection */ static int flood_timeout(void) { MODULE_SERVER_REC *mserver; GSList *tmp; + time_t now; - /* remove everyone from flood list */ + /* remove the old people from flood lists */ + now = time(NULL); 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); + g_hash_table_foreach_remove(mserver->floodlist, (GHRFunc) flood_hash_deinit, GINT_TO_POINTER((int) now)); } return 1; } @@ -88,6 +110,8 @@ static void flood_deinit_server(IRC_SERVER_REC *server) mserver = MODULE_DATA(server); if (mserver != NULL && mserver->floodlist != NULL) { + flood_timecheck = 0; + g_hash_table_freeze(mserver->floodlist); g_hash_table_foreach(mserver->floodlist, (GHFunc) flood_hash_deinit, NULL); g_hash_table_thaw(mserver->floodlist); @@ -96,34 +120,55 @@ static void flood_deinit_server(IRC_SERVER_REC *server) g_free(mserver); } +static FLOOD_ITEM_REC *flood_find(FLOOD_REC *flood, int level, const char *target) +{ + GSList *tmp; + + for (tmp = flood->items; tmp != NULL; tmp = tmp->next) { + FLOOD_ITEM_REC *rec = tmp->data; + + if (rec->level == level && g_strcasecmp(rec->target, target) == 0) + return rec; + } + + return NULL; +} + /* 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; + FLOOD_REC *flood; + FLOOD_ITEM_REC *rec; g_return_if_fail(server != NULL); g_return_if_fail(nick != NULL); mserver = MODULE_DATA(server); - rec = g_hash_table_lookup(mserver->floodlist, nick); + flood = g_hash_table_lookup(mserver->floodlist, nick); + + rec = flood == NULL ? NULL : flood_find(flood, level, target); 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); + signal_emit("flood", 5, server, nick, host, GINT_TO_POINTER(rec->level), target); } return; } - rec = g_new(FLOOD_REC, 1); + if (flood == NULL) { + flood = g_new0(FLOOD_REC, 1); + flood->nick = g_strdup(nick); + g_hash_table_insert(mserver->floodlist, flood->nick, flood); + } + + rec = g_new0(FLOOD_ITEM_REC, 1); rec->level = level; + rec->first = time(NULL); rec->msgcount = 1; - rec->nick = g_strdup(nick); + rec->target = g_strdup(target); - g_hash_table_insert(mserver->floodlist, rec->nick, rec); + flood->items = g_slist_append(flood->items, rec); } static void flood_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) @@ -141,7 +186,7 @@ static void flood_privmsg(const char *data, IRC_SERVER_REC *server, const char * params = event_get_params(data, 2, &target, &text); - if (*text == 1) { + if (*text == 1 && g_strncasecmp(text+1, "ACTION", 6) != 0) { /* CTCP */ if (!ignore_check(server, nick, addr, target, text, MSGLEVEL_CTCPS)) flood_newmsg(server, MSGLEVEL_CTCPS, nick, addr, target); @@ -176,24 +221,37 @@ static void flood_notice(const char *data, IRC_SERVER_REC *server, const char *n 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); + int time; + flood_timecheck = settings_get_int("flood_timecheck"); flood_max_msgs = settings_get_int("flood_max_msgs"); + + time = flood_timecheck > 500 ? 500 : + (flood_timecheck > 0 && flood_timecheck < 100) ? 100 : + flood_timecheck; + + if (flood_tag != -1) { + g_source_remove(flood_tag); + flood_tag = -1; + } + + if (time > 0 && flood_max_msgs > 0) { + flood_tag = g_timeout_add(time, (GSourceFunc) flood_timeout, NULL); + signal_add("event privmsg", (SIGNAL_FUNC) flood_privmsg); + signal_add("event notice", (SIGNAL_FUNC) flood_notice); + } } void flood_init(void) { - settings_add_int("flood", "flood_timecheck", 1000); - settings_add_int("flood", "flood_max_msgs", 5); + settings_add_int("flood", "flood_timecheck", 5000); + settings_add_int("flood", "flood_max_msgs", 4); 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(); } @@ -202,11 +260,13 @@ void flood_deinit(void) { autoignore_deinit(); - if (flood_tag != -1) g_source_remove(flood_tag); + if (flood_tag != -1) { + g_source_remove(flood_tag); + signal_remove("event privmsg", (SIGNAL_FUNC) flood_privmsg); + signal_remove("event notice", (SIGNAL_FUNC) flood_notice); + } 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); } -- cgit v1.2.3