]>
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 | ||
9af95c3d | 65 | const char *hlc_get_cname(hlc_component comp) |
66 | { | |
67 | switch (comp) | |
68 | { | |
69 | default: | |
70 | return "Error, contact strutsi"; | |
71 | } | |
72 | } | |
73 | ||
c86edd1d Q |
74 | /* static functions, used internally */ |
75 | ||
76 | static int hlc_violation_handle(hchannel *hchan, huser* husr, int violation) | |
77 | { | |
9af95c3d | 78 | if (husr->lc[violation] >= hchan->lc_profile->tolerance_remove) /* get rid of the thing */ |
79 | { | |
80 | const char *banmask = hban_ban_string(husr->real_user, HBAN_HOST); | |
81 | char reason_buffer[128]; | |
052247fa | 82 | sprintf(reason_buffer, "Excessive violations: %s", hlc_get_violation_name(violation)); |
9af95c3d | 83 | hban_add(banmask, reason_buffer, time(NULL) + HLC_DEFAULT_BANTIME, 0); |
84 | ||
85 | if (IsAccount(husr->real_user)) | |
86 | haccount_add(huser_get_auth(husr), H_LAMER); | |
87 | ||
88 | return !0; | |
89 | } | |
90 | if (husr->lc[violation] >= hchan->lc_profile->tolerance_kick) /* get rid of the thing */ | |
91 | { | |
9af95c3d | 92 | helpmod_kick(hchan, husr, "Channel rule violation: %s", hlc_get_violation_name(violation)); |
93 | return !0; | |
94 | } | |
95 | if (husr->lc[violation] >= hchan->lc_profile->tolerance_warn) /* get rid of the thing */ | |
96 | { | |
052247fa | 97 | 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 | 98 | } |
c86edd1d Q |
99 | return 0; |
100 | ||
101 | } | |
102 | ||
103 | static int hlc_check_caps(hlc_profile *hlc_prof, huser *husr, const char *line) | |
104 | { | |
105 | int caps = 0; | |
106 | int noncaps = 0; | |
107 | int i; | |
052247fa CP |
108 | int firstword; |
109 | ||
110 | if (strchr(line, ' ')) | |
111 | firstword = strchr(line, ' ') - line; | |
112 | else | |
113 | firstword = 0; | |
114 | ||
115 | /* Handle the thing sent with /me */ | |
116 | if (!strncmp(line, "\1ACTION", 6 + 1)) | |
117 | line+=(6 + 1); | |
118 | else if (firstword && firstword < NICKLEN + 3) | |
119 | { | |
120 | char buffer[NICKLEN + 3]; | |
121 | strncpy(buffer, line, firstword); | |
122 | buffer[firstword] = '\0'; | |
123 | if (buffer[firstword - 1] == ':') | |
124 | buffer[firstword - 1] = '\0'; | |
125 | if (getnickbynick(buffer)) | |
126 | line+=firstword + 1; | |
127 | } | |
c86edd1d Q |
128 | |
129 | for (i = 0;line[i];i++) | |
130 | { | |
131 | if (isalpha(line[i])) | |
132 | { | |
133 | if (isupper(line[i])) | |
134 | caps++; | |
135 | else | |
136 | noncaps++; | |
137 | } | |
138 | } | |
139 | ||
140 | if ((noncaps + caps) < hlc_prof->caps_min_count) | |
141 | return 0; | |
142 | ||
143 | if (((100 * caps) / (caps + noncaps)) >= hlc_prof->caps_max_percentage) /* violation */ | |
144 | { | |
145 | return ++husr->lc[HLC_CAPS]; | |
146 | } | |
147 | else | |
148 | return 0; | |
149 | } | |
150 | ||
151 | static int hlc_check_repeat(hlc_profile *hlc_prof, huser *husr, const char *line) | |
152 | { | |
153 | if (!strncmp(husr->last_line, line, strlen(husr->last_line)) && (strlen(husr->last_line) >= hlc_prof->repeats_min_length)) | |
154 | husr->last_line_repeats++; | |
9af95c3d | 155 | else if (!strcmp(husr->last_line, line)) |
156 | husr->last_line_repeats++; | |
c86edd1d Q |
157 | else |
158 | husr->last_line_repeats = 0; | |
159 | ||
160 | strcpy(husr->last_line, line); | |
161 | ||
162 | if (husr->last_line_repeats >= hlc_prof->repeats_max_count && strlen(line) >= hlc_prof->repeats_min_length) /* violation */ | |
163 | return ++husr->lc[HLC_REPEAT]; | |
164 | else | |
165 | return 0; | |
166 | } | |
167 | ||
168 | static int hlc_check_character_repeats(hlc_profile *hlc_prof, huser *husr, const char *line) | |
169 | { | |
170 | char chr = '\0'; | |
171 | int i; | |
f011b15a | 172 | int repeats = 0; |
c86edd1d Q |
173 | |
174 | for (i = 0;line[i];i++) | |
175 | if (line[i] == chr) | |
176 | { | |
177 | repeats++; | |
178 | if (repeats >= hlc_prof->character_repeat_max_count && isalnum(chr)) /* violation */ | |
179 | return ++husr->lc[HLC_CHARACTER_REPEAT]; | |
180 | else if (repeats >= hlc_prof->symbol_repeat_max_count && ispunct(chr)) /* violation */ | |
181 | return ++husr->lc[HLC_CHARACTER_REPEAT]; | |
182 | } | |
183 | else | |
184 | { | |
185 | repeats = 0; | |
186 | chr = line[i]; | |
187 | } | |
188 | for (i=0, repeats = 0; line[i]; i++) | |
189 | { | |
190 | if (ispunct(line[i])) | |
191 | repeats++; | |
192 | else | |
193 | repeats = 0; | |
194 | ||
195 | if (repeats >= hlc_prof->symbol_max_count) | |
196 | return ++husr->lc[HLC_CHARACTER_REPEAT]; | |
197 | } | |
198 | return 0; | |
199 | } | |
200 | ||
201 | static int hlc_check_flood(hlc_profile *hlc_prof, huser *husr, const char *line) | |
202 | { | |
203 | if (husr->flood_val < time(NULL)) | |
204 | husr->flood_val = time(NULL); | |
205 | else | |
206 | husr->flood_val++; | |
207 | ||
9af95c3d | 208 | if ((husr->flood_val - time(NULL)) > (hlc_prof->tolerance_flood)) |
c86edd1d Q |
209 | { |
210 | husr->flood_val = time(NULL); | |
211 | return ++husr->lc[HLC_FLOOD]; | |
212 | } | |
213 | ||
214 | return 0; | |
215 | } | |
216 | ||
217 | static int hlc_check_spam(hlc_profile *hlc_prof, huser *husr, const char *line) | |
218 | { | |
219 | if (husr->spam_val < (float)time(NULL)) | |
220 | husr->spam_val = (float)time(NULL); | |
221 | ||
222 | husr->spam_val += (hlc_prof->constant_spam * (double)strlen(line)); | |
223 | ||
224 | if (((int)husr->spam_val - time(NULL)) >= (hlc_prof->tolerance_spam)) | |
225 | { | |
226 | husr->spam_val = time(NULL); | |
227 | return ++husr->lc[HLC_SPAM]; | |
228 | } | |
229 | return 0; | |
230 | } | |
231 | ||
232 | /* checks a string for lameness, returns non-zero if lameness is present */ | |
e908ecfa | 233 | int hlc_check(hchannel *hchan, huser* husr, const char *line) |
c86edd1d | 234 | { |
c86edd1d Q |
235 | if (hchan == NULL || hchan->lc_profile == NULL) |
236 | return 0; | |
237 | ||
9af95c3d | 238 | if (hlc_check_flood(hchan->lc_profile, husr, line)) |
239 | if (hlc_violation_handle(hchan, husr, HLC_FLOOD)) | |
240 | return -1; | |
241 | if (hlc_check_spam(hchan->lc_profile, husr, line)) | |
242 | if (hlc_violation_handle(hchan, husr, HLC_SPAM)) | |
243 | return -1; | |
c86edd1d Q |
244 | if (hlc_check_caps(hchan->lc_profile, husr, line)) |
245 | if (hlc_violation_handle(hchan, husr, HLC_CAPS)) | |
246 | return -1; | |
247 | if (hlc_check_repeat(hchan->lc_profile, husr, line)) | |
248 | if (hlc_violation_handle(hchan, husr, HLC_REPEAT)) | |
249 | return -1; | |
250 | if (hlc_check_character_repeats(hchan->lc_profile, husr, line)) | |
251 | if (hlc_violation_handle(hchan, husr, HLC_CHARACTER_REPEAT)) | |
252 | return -1; | |
c86edd1d Q |
253 | |
254 | return 0; | |
255 | } | |
256 | ||
9af95c3d | 257 | const char *hlc_get_violation_name(hlc_violation violation) |
258 | { | |
259 | switch (violation) | |
260 | { | |
261 | case HLC_CAPS: | |
262 | return "Excessive use of capital letters"; | |
263 | case HLC_REPEAT: | |
264 | return "Repeating"; | |
265 | case HLC_CHARACTER_REPEAT: | |
266 | return "Improper use of language"; | |
267 | case HLC_FLOOD: | |
268 | return "Flooding"; | |
269 | case HLC_SPAM: | |
270 | return "Spamming"; | |
271 | default: | |
272 | return "Error, please contact strutsi"; | |
273 | } | |
274 | } |