]>
Commit | Line | Data |
---|---|---|
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 | ||
13 | hlc_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 | ||
27 | hlc_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 | ||
48 | void hlc_del_all(void) | |
49 | { | |
50 | while (hlc_profiles) | |
51 | hlc_del(hlc_profiles); | |
52 | } | |
53 | ||
54 | hlc_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 | 63 | const 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 | ||
74 | static 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 | ||
101 | static 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 | ||
149 | static 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 | ||
166 | static 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 | ||
199 | static 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 | ||
215 | static int hlc_check_spam(hlc_profile *hlc_prof, huser *husr, const char *line) | |
216 | { | |
c5d9f7b4 P |
217 | if (husr->spam_val < (double)time(NULL)) |
218 | husr->spam_val = (double)time(NULL); | |
c86edd1d | 219 | |
c5d9f7b4 | 220 | husr->spam_val += ((double)(hlc_prof->constant_spam) * (double)strlen(line)); |
c86edd1d | 221 | |
c5d9f7b4 | 222 | if (((int)(husr->spam_val) - time(NULL)) >= (hlc_prof->tolerance_spam)) |
c86edd1d Q |
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 | 231 | int 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 | 255 | const 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 | } |