]> jfr.im git - irc/quakenet/newserv.git/blob - helpmod2/hlamer.c
MORE TIDYING
[irc/quakenet/newserv.git] / helpmod2 / hlamer.c
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 const char *hlc_get_cname(hlc_component comp)
66 {
67 switch (comp)
68 {
69 default:
70 return "Error, contact strutsi";
71 }
72 }
73
74 /* static functions, used internally */
75
76 static int hlc_violation_handle(hchannel *hchan, huser* husr, int violation)
77 {
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];
82 sprintf(reason_buffer, "Excessive violations: %s", hlc_get_violation_name(violation));
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 {
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 {
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));
98 }
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;
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 }
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++;
155 else if (!strcmp(husr->last_line, line))
156 husr->last_line_repeats++;
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;
172 int repeats = 0;
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
208 if ((husr->flood_val - time(NULL)) > (hlc_prof->tolerance_flood))
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 */
233 int hlc_check(hchannel *hchan, huser* husr, const char *line)
234 {
235 if (hchan == NULL || hchan->lc_profile == NULL)
236 return 0;
237
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;
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;
253
254 return 0;
255 }
256
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 }