]> jfr.im git - irc/quakenet/newserv.git/blob - helpmod2/hlamer.c
Large reorganisation of all Makefiles, including new configure script.
[irc/quakenet/newserv.git] / helpmod2 / hlamer.c
1 #include <string.h>
2 #include <ctype.h>
3 #include <stdlib.h>
4
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
63 const char *hlc_get_cname(hlc_component comp)
64 {
65 switch (comp)
66 {
67 default:
68 return "Error, contact strutsi";
69 }
70 }
71
72 /* static functions, used internally */
73
74 static int hlc_violation_handle(hchannel *hchan, huser* husr, int violation)
75 {
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];
80 sprintf(reason_buffer, "Excessive violations: %s", hlc_get_violation_name(violation));
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 {
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 {
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));
96 }
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;
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 }
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++;
153 else if (!strcmp(husr->last_line, line))
154 husr->last_line_repeats++;
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;
170 int repeats = 0;
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
206 if ((husr->flood_val - time(NULL)) > (hlc_prof->tolerance_flood))
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 {
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 */
231 int hlc_check(hchannel *hchan, huser* husr, const char *line)
232 {
233 if (hchan == NULL || hchan->lc_profile == NULL)
234 return 0;
235
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;
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;
251
252 return 0;
253 }
254
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 }