File: flood.c

package info (click to toggle)
ircii 20060725-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 5,648 kB
  • ctags: 3,794
  • sloc: ansic: 44,334; makefile: 1,091; sh: 524; perl: 127
file content (133 lines) | stat: -rw-r--r-- 2,884 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * flood.c: handle channel flooding. 
 *
 * This attempts to give you some protection from flooding.  Basically, it keeps
 * track of how far apart (timewise) messages come in from different people.
 * If a single nickname sends more than 3 messages in a row in under a
 * second, this is considered flooding.  It then activates the ON FLOOD with
 * the nickname and type (appropriate for use with IGNORE). 
 *
 * Thanks to Tomi Ollila <f36664r@puukko.hut.fi> for this one. 
 */

#include "irc.h"
IRCII_RCSID("@(#)$eterna: flood.c,v 1.19 2002/09/03 02:39:30 mrg Exp $");

#include "hook.h"
#include "ircaux.h"
#include "ignore.h"
#include "flood.h"
#include "vars.h"
#include "output.h"

static	char	*ignore_types[NUMBER_OF_FLOODS] =
{
	"MSG",
	"PUBLIC",
	"NOTICE",
	"WALL",
	"WALLOP"
};

typedef struct flood_stru
{
	u_char	*nick;
	int	type;
	u_char	flood;
	long	cnt;
	time_t	start;
}	Flooding;

static	Flooding *flood = (Flooding *) 0;

/*
 * check_flooding: This checks for message flooding of the type specified for
 * the given nickname.  This is described above.  This will return 0 if no
 * flooding took place, or flooding is not being monitored from a certain
 * person.  It will return 1 if flooding is being check for someone and an ON
 * FLOOD is activated. 
 *
 * NOTE:  flood's are never freed.
 */
int
check_flooding(nick, to, type, line)
	u_char	*nick;
	u_char	*to;
	int	type;
	u_char	*line;
{
	static	int	users = 0,
			pos = 0;
	int	i;
	time_t	flood_time,
	diff;
	Flooding *tmp;

	if (users != get_int_var(FLOOD_USERS_VAR))
	{
		if ((users = get_int_var(FLOOD_USERS_VAR)) == 0)
			return(1);
		if (flood)
			flood = (Flooding *) new_realloc(UP(flood), sizeof(Flooding) * users);
		else
			flood = (Flooding *) new_malloc(sizeof(Flooding) *
				users);
		for (i = 0; i < users; i++)
		{
			flood[i].nick = 0;
			flood[i].cnt = 0;
			flood[i].flood = 0;
		}
	}
	if (users == 0)
		return (1);
	for (i = 0; i < users; i++)
	{
		if (flood[i].nick && *(flood[i].nick))
		{
			if ((my_stricmp(nick, flood[i].nick) == 0) &&
					(type == flood[i].type))
				break;
		}
	}
	flood_time = time(0);
	if (i == users)
	{
		pos = (pos + 1) % users;
		tmp = &(flood[pos]);
		tmp->nick = 0;
		malloc_strcpy(&tmp->nick, nick);
		tmp->type = type;
		tmp->cnt = 1;
		tmp->start = flood_time;
		tmp->flood = 0;
		return (1);
	}
	else
		tmp = &(flood[i]);
	tmp->cnt++;
	diff = flood_time - tmp->start;
	if (tmp->cnt > get_int_var(FLOOD_AFTER_VAR))
	{
		if ((diff == 0) || (tmp->cnt / diff) >
				get_int_var(FLOOD_RATE_VAR))
		{
			if (tmp->flood == 0)
			{
				if (get_int_var(FLOOD_WARNING_VAR))
					say("%s flooding detected from %s",
						ignore_types[type], nick);
				tmp->flood = 1;
			}
			return (do_hook(FLOOD_LIST, "%s %s %s %s", nick,
				to, ignore_types[type], line));
		}
		else
		{
			tmp->flood = 0;
			tmp->cnt = 1;
			tmp->start = flood_time;
		}
	}
	return (1);
}