]> jfr.im git - irc/quakenet/newserv.git/blame - helpmod2/hlamer.c
Large reorganisation of all Makefiles, including new configure script.
[irc/quakenet/newserv.git] / helpmod2 / hlamer.c
CommitLineData
c86edd1d
Q
1#include <string.h>
2#include <ctype.h>
3#include <stdlib.h>
4
c86edd1d
Q
5#include "huser.h"
6#include "hban.h"
7#include "hchannel.h"
8#include "haccount.h"
9#include "helpmod.h"
10
11#include "hgen.h"
12
13hlc_profile* hlc_add(const char *str)
14{
15 hlc_profile *tmp;
16
17 if (hlc_get(str) != NULL)
18 return NULL;
19
20 tmp = (hlc_profile*)malloc(sizeof(hlc_profile));
21 tmp->name = getsstring(str, strlen(str));
22 tmp->next = hlc_profiles;
23 hlc_profiles = tmp;
24 return tmp;
25}
26
27hlc_profile *hlc_del(hlc_profile *hlc_prof)
28{
29 hchannel *hchan = hchannels;
30 hlc_profile **ptr = &hlc_profiles;
31
32 for (;hchan;hchan = hchan->next)
33 if (hchan->lc_profile == hlc_prof)
34 hchan->lc_profile = NULL;
35
36 for (;*ptr;ptr = &(*ptr)->next)
37 if (*ptr == hlc_prof)
38 {
39 hlc_profile *tmp = (*ptr)->next;
40 freesstring ((*ptr)->name);
41 free(*ptr);
42 *ptr = tmp;
43 return NULL;
44 }
45 return hlc_prof;
46}
47
48void hlc_del_all(void)
49{
50 while (hlc_profiles)
51 hlc_del(hlc_profiles);
52}
53
54hlc_profile *hlc_get(const char *str)
55{
56 hlc_profile *hlc_prof = hlc_profiles;
57 for (;hlc_prof;hlc_prof = hlc_prof->next)
58 if (!ci_strcmp(hlc_prof->name->content, str))
59 return hlc_prof;
60 return NULL;
61}
62
9af95c3d 63const char *hlc_get_cname(hlc_component comp)
64{
65 switch (comp)
66 {
67 default:
68 return "Error, contact strutsi";
69 }
70}
71
c86edd1d
Q
72/* static functions, used internally */
73
74static int hlc_violation_handle(hchannel *hchan, huser* husr, int violation)
75{
9af95c3d 76 if (husr->lc[violation] >= hchan->lc_profile->tolerance_remove) /* get rid of the thing */
77 {
78 const char *banmask = hban_ban_string(husr->real_user, HBAN_HOST);
79 char reason_buffer[128];
052247fa 80 sprintf(reason_buffer, "Excessive violations: %s", hlc_get_violation_name(violation));
9af95c3d 81 hban_add(banmask, reason_buffer, time(NULL) + HLC_DEFAULT_BANTIME, 0);
82
83 if (IsAccount(husr->real_user))
84 haccount_add(huser_get_auth(husr), H_LAMER);
85
86 return !0;
87 }
88 if (husr->lc[violation] >= hchan->lc_profile->tolerance_kick) /* get rid of the thing */
89 {
9af95c3d 90 helpmod_kick(hchan, husr, "Channel rule violation: %s", hlc_get_violation_name(violation));
91 return !0;
92 }
93 if (husr->lc[violation] >= hchan->lc_profile->tolerance_warn) /* get rid of the thing */
94 {
052247fa 95 helpmod_reply(husr, NULL, "You are violating the channel rule of %s : %s. Continuous violation of this rule will result in you being removed from %s", hchannel_get_name(hchan), hlc_get_violation_name(violation), hchannel_get_name(hchan));
9af95c3d 96 }
c86edd1d
Q
97 return 0;
98
99}
100
101static int hlc_check_caps(hlc_profile *hlc_prof, huser *husr, const char *line)
102{
103 int caps = 0;
104 int noncaps = 0;
105 int i;
052247fa
CP
106 int firstword;
107
108 if (strchr(line, ' '))
109 firstword = strchr(line, ' ') - line;
110 else
111 firstword = 0;
112
113 /* Handle the thing sent with /me */
114 if (!strncmp(line, "\1ACTION", 6 + 1))
115 line+=(6 + 1);
116 else if (firstword && firstword < NICKLEN + 3)
117 {
118 char buffer[NICKLEN + 3];
119 strncpy(buffer, line, firstword);
120 buffer[firstword] = '\0';
121 if (buffer[firstword - 1] == ':')
122 buffer[firstword - 1] = '\0';
123 if (getnickbynick(buffer))
124 line+=firstword + 1;
125 }
c86edd1d
Q
126
127 for (i = 0;line[i];i++)
128 {
129 if (isalpha(line[i]))
130 {
131 if (isupper(line[i]))
132 caps++;
133 else
134 noncaps++;
135 }
136 }
137
138 if ((noncaps + caps) < hlc_prof->caps_min_count)
139 return 0;
140
141 if (((100 * caps) / (caps + noncaps)) >= hlc_prof->caps_max_percentage) /* violation */
142 {
143 return ++husr->lc[HLC_CAPS];
144 }
145 else
146 return 0;
147}
148
149static int hlc_check_repeat(hlc_profile *hlc_prof, huser *husr, const char *line)
150{
151 if (!strncmp(husr->last_line, line, strlen(husr->last_line)) && (strlen(husr->last_line) >= hlc_prof->repeats_min_length))
152 husr->last_line_repeats++;
9af95c3d 153 else if (!strcmp(husr->last_line, line))
154 husr->last_line_repeats++;
c86edd1d
Q
155 else
156 husr->last_line_repeats = 0;
157
158 strcpy(husr->last_line, line);
159
160 if (husr->last_line_repeats >= hlc_prof->repeats_max_count && strlen(line) >= hlc_prof->repeats_min_length) /* violation */
161 return ++husr->lc[HLC_REPEAT];
162 else
163 return 0;
164}
165
166static int hlc_check_character_repeats(hlc_profile *hlc_prof, huser *husr, const char *line)
167{
168 char chr = '\0';
169 int i;
f011b15a 170 int repeats = 0;
c86edd1d
Q
171
172 for (i = 0;line[i];i++)
173 if (line[i] == chr)
174 {
175 repeats++;
176 if (repeats >= hlc_prof->character_repeat_max_count && isalnum(chr)) /* violation */
177 return ++husr->lc[HLC_CHARACTER_REPEAT];
178 else if (repeats >= hlc_prof->symbol_repeat_max_count && ispunct(chr)) /* violation */
179 return ++husr->lc[HLC_CHARACTER_REPEAT];
180 }
181 else
182 {
183 repeats = 0;
184 chr = line[i];
185 }
186 for (i=0, repeats = 0; line[i]; i++)
187 {
188 if (ispunct(line[i]))
189 repeats++;
190 else
191 repeats = 0;
192
193 if (repeats >= hlc_prof->symbol_max_count)
194 return ++husr->lc[HLC_CHARACTER_REPEAT];
195 }
196 return 0;
197}
198
199static int hlc_check_flood(hlc_profile *hlc_prof, huser *husr, const char *line)
200{
201 if (husr->flood_val < time(NULL))
202 husr->flood_val = time(NULL);
203 else
204 husr->flood_val++;
205
9af95c3d 206 if ((husr->flood_val - time(NULL)) > (hlc_prof->tolerance_flood))
c86edd1d
Q
207 {
208 husr->flood_val = time(NULL);
209 return ++husr->lc[HLC_FLOOD];
210 }
211
212 return 0;
213}
214
215static int hlc_check_spam(hlc_profile *hlc_prof, huser *husr, const char *line)
216{
217 if (husr->spam_val < (float)time(NULL))
218 husr->spam_val = (float)time(NULL);
219
220 husr->spam_val += (hlc_prof->constant_spam * (double)strlen(line));
221
222 if (((int)husr->spam_val - time(NULL)) >= (hlc_prof->tolerance_spam))
223 {
224 husr->spam_val = time(NULL);
225 return ++husr->lc[HLC_SPAM];
226 }
227 return 0;
228}
229
230/* checks a string for lameness, returns non-zero if lameness is present */
e908ecfa 231int hlc_check(hchannel *hchan, huser* husr, const char *line)
c86edd1d 232{
c86edd1d
Q
233 if (hchan == NULL || hchan->lc_profile == NULL)
234 return 0;
235
9af95c3d 236 if (hlc_check_flood(hchan->lc_profile, husr, line))
237 if (hlc_violation_handle(hchan, husr, HLC_FLOOD))
238 return -1;
239 if (hlc_check_spam(hchan->lc_profile, husr, line))
240 if (hlc_violation_handle(hchan, husr, HLC_SPAM))
241 return -1;
c86edd1d
Q
242 if (hlc_check_caps(hchan->lc_profile, husr, line))
243 if (hlc_violation_handle(hchan, husr, HLC_CAPS))
244 return -1;
245 if (hlc_check_repeat(hchan->lc_profile, husr, line))
246 if (hlc_violation_handle(hchan, husr, HLC_REPEAT))
247 return -1;
248 if (hlc_check_character_repeats(hchan->lc_profile, husr, line))
249 if (hlc_violation_handle(hchan, husr, HLC_CHARACTER_REPEAT))
250 return -1;
c86edd1d
Q
251
252 return 0;
253}
254
9af95c3d 255const char *hlc_get_violation_name(hlc_violation violation)
256{
257 switch (violation)
258 {
259 case HLC_CAPS:
260 return "Excessive use of capital letters";
261 case HLC_REPEAT:
262 return "Repeating";
263 case HLC_CHARACTER_REPEAT:
264 return "Improper use of language";
265 case HLC_FLOOD:
266 return "Flooding";
267 case HLC_SPAM:
268 return "Spamming";
269 default:
270 return "Error, please contact strutsi";
271 }
272}