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