]> jfr.im git - irc/quakenet/newserv.git/blame - helpmod2/hhooks.c
GLINES: fix null pointer deref in trustgline / trustungline
[irc/quakenet/newserv.git] / helpmod2 / hhooks.c
CommitLineData
c86edd1d
Q
1#include <string.h>
2#include <assert.h>
3
c86edd1d
Q
4#include "helpmod.h"
5#include "hchannel.h"
6#include "haccount.h"
7#include "huser.h"
8#include "hban.h"
9#include "hqueue.h"
10#include "hgen.h"
11#include "hstat.h"
9af95c3d 12/*
c86edd1d
Q
13void helpmod_hook_quit(int unused, void *args)
14{
15 nick *nck = ((nick**)args)[0];
16 huser *husr = huser_get(nck);
9af95c3d 17 / * it was someone we didn't even know * /
c86edd1d
Q
18 if (husr == NULL)
19 return;
20}
9af95c3d 21*/
22
c86edd1d
Q
23/*
24void helpmod_hook_part(int unused, void *args)
25{
26 channel *chan = ((channel**)args)[0];
27 hchannel *hchan = hchannel_get_by_channel(chan);
28 nick *nck = ((nick**)args)[1];
29 huser *husr;
30
c86edd1d
Q
31}
32*/
052247fa 33static void helpmod_hook_join(int unused, void *args)
c86edd1d
Q
34{
35 channel *chan = ((channel**)args)[0];
36 hchannel *hchan = hchannel_get_by_channel(chan);
37 nick *nck = ((nick**)args)[1];
38 huser *husr;
39
6daae5b5 40 /* if we're not on this channel or the target is G, the event is of no interest */
41 if (hchan == NULL || nck == helpmodnick)
c86edd1d
Q
42 return;
43
44 husr = huser_get(nck);
45
46 assert(husr != NULL); /* hook_channel_newnick should fix this */
47
9af95c3d 48 if ((hchan->flags & H_JOINFLOOD_PROTECTION) && !(hchan->flags & H_PASSIVE))
c86edd1d 49 {
e908ecfa 50 if (hchan->jf_control < time(NULL))
51 hchan->jf_control = time(NULL);
52 else
53 hchan->jf_control++;
c86edd1d 54
052247fa 55 if (hchan->jf_control - time(NULL) > 12 && !IsRegOnly(hchan))
e908ecfa 56 {
57 if (hchan->flags & H_REPORT && hchannel_is_valid(hchan->report_to))
9af95c3d 58 helpmod_message_channel(hchan->report_to, "Warning: Possible join flood on %s, setting +r", hchannel_get_name(hchan));
59 hchannel_activate_join_flood(hchan);
60 }
c86edd1d
Q
61 }
62
e908ecfa 63 if (hchan->flags & H_PASSIVE)
64 return;
65
c86edd1d
Q
66 if (hchan->flags & H_DO_STATS)
67 hstat_add_join(hchan);
68
69 if (hchan->flags & H_TROJAN_REMOVAL && huser_is_trojan(husr))
70 {
71 hban_huser(husr, "Trojan client", time(NULL) + 4 * HDEF_d, 1);
72 return;
73 }
74
052247fa 75 if (huser_get_level(husr) >= H_STAFF && (huser_get_account_flags(husr) & H_AUTO_OP) && hchannel_authority(hchan, husr))
c86edd1d
Q
76 helpmod_channick_modes(husr, hchan ,MC_OP,HNOW);
77
052247fa 78 if (huser_get_level(husr) >= H_TRIAL && (huser_get_account_flags(husr) & H_AUTO_VOICE) && hchannel_authority(hchan, husr))
c86edd1d
Q
79 helpmod_channick_modes(husr, hchan, MC_VOICE,HNOW);
80
81 if (hchan->flags & H_WELCOME && *hchan->real_channel->index->name->content)
82 helpmod_reply(husr, chan, "[%s] %s", hchan->real_channel->index->name->content, hchan->welcome);
83
84
85 if (hchan->flags & H_QUEUE && hchan->flags & H_QUEUE_SPAMMY)
86 {
87 if (huser_get_level(husr) < H_STAFF)
88 helpmod_reply(husr, NULL, "Channel %s is using a queue system. This means you will have to wait for support. Your queue position is #%d and currently the average time in queue is %s. Please wait for your turn and do not attempt to contact channel operators directly", hchannel_get_name(hchan), hqueue_get_position(hchan, husr), helpmod_strtime(hqueue_average_time(hchan)));
89 }
90 if (IsModerated(hchan->real_channel) && !(hchan->flags & H_QUEUE) && (hchan->flags & H_ANTI_IDLE))
91 { /* being nice to users */
92 if (huser_get_level(husr) < H_STAFF)
93 helpmod_reply(husr, NULL, "Channel %s is currently moderated and there are anti-idle measures in place. This usually means that there is no one to handle your problem at this time. Please try again later and don't forget to read the FAQ at www.quakenet.org", hchannel_get_name(hchan));
94 }
95}
96
052247fa 97static void helpmod_hook_channel_newnick(int unused, void *args)
c86edd1d
Q
98{
99 channel *chan = ((channel**)args)[0];
100 hchannel *hchan = hchannel_get_by_channel(chan);
101 nick *nck = ((nick**)args)[1];
102 huser *husr;
103
6daae5b5 104 /* if we're not on this channel or the target is G, the event is of no interest */
105 if (hchan == NULL || nck == helpmodnick)
c86edd1d
Q
106 return;
107
108 if ((husr = huser_get(nck)) == NULL)
109 husr = huser_add(nck);
3a839281 110
c86edd1d
Q
111 assert(huser_on_channel(husr, hchan) == NULL);
112 assert(hchannel_on_channel(hchan, husr) == NULL);
113
114 hchannel_add_user(hchan, husr);
115 huser_add_channel(husr, hchan);
116
e908ecfa 117 if (hchan->flags & H_PASSIVE)
118 return;
119
052247fa
CP
120 huser_activity(husr, NULL);
121
122 if (huser_get_level(husr) == H_LAMER || (huser_get_level(husr) <= H_TRIAL && hban_check(nck)))
c86edd1d
Q
123 {
124 hban *hb = hban_check(nck);
c86edd1d 125
ce659137 126 const char *banmask = hban_ban_string(nck, HBAN_HOST);
127 helpmod_setban(hchan, banmask, time(NULL) + 1 * HDEF_d, MCB_ADD, HNOW);
c86edd1d 128
ce659137 129 if (hb)
2c6379d2 130 helpmod_kick(hchan, husr, "%s", hban_get_reason(hb));
ce659137 131 else
132 helpmod_kick(hchan, husr, "Your presence on channel %s is not wanted", hchannel_get_name(hchan));
133
134 return;
c86edd1d
Q
135 }
136 if (hchan->flags & H_QUEUE)
137 hqueue_handle_queue(hchan, NULL);
138}
139
052247fa 140static void helpmod_hook_channel_lostnick(int unused, void *args)
c86edd1d
Q
141{
142 channel *chan = ((channel**)args)[0];
143 hchannel *hchan = hchannel_get_by_channel(chan);
144 huser_channel *huserchan;
145 nick *nck = ((nick**)args)[1];
146 huser *husr;
147
6daae5b5 148 /* In event that G was kicked, nothing is done */
149 if (nck == helpmodnick)
150 return;
151
c86edd1d
Q
152 /* hackery, can't think of a better way to do this */
153 huser *oper = NULL;
154 int handle_queue = 0;
155
156 /* if we're not on this channel, the event is of no interest */
157 if (hchan == NULL)
158 return;
159
160 husr = huser_get(nck);
161
162 assert(husr != NULL);
163
164 huserchan = huser_on_channel(husr, hchan);
3a839281 165
c86edd1d
Q
166 assert(hchannel_on_channel(hchan, husr) != NULL);
167 assert(huserchan != NULL);
168
e908ecfa 169 if ((hchan->flags & H_QUEUE) && (hchan->flags & H_QUEUE_MAINTAIN) && !(hchan->flags & H_PASSIVE)) /* && (huser_get_level(husr) == H_PEON) && (huserchan->flags & HCUMODE_VOICE) && (hchannel_count_queue(hchan)))*/
170 if (serverlist[homeserver(husr->real_user->numeric)].linkstate != LS_SQUIT)
c86edd1d
Q
171 /* if it was a netsplit, we do not trigger autoqueue */
172 {
173 oper = huserchan->responsible_oper;
174 handle_queue = !0;
175 }
176
177 hchannel_del_user(hchan, husr);
178 huser_del_channel(husr, hchan);
179
180 if (nck == helpmodnick)
181 { /* if H left the channel, we remove all the users from the channel */
182 while (hchan->channel_users)
183 {
c86edd1d
Q
184 huser_del_channel(hchan->channel_users->husr, hchan);
185 hchannel_del_user(hchan, hchan->channel_users->husr);
186 }
187 }
188
189 else if (handle_queue)
190 hqueue_handle_queue(hchan, oper);
191}
192
052247fa 193static void helpmod_hook_nick_lostnick(int unused, void *args)
c86edd1d 194{
9af95c3d 195 nick *nck = (nick*)args;
c86edd1d
Q
196 huser *husr = huser_get(nck);
197
198 /* it was someone we didn't even know */
199 if (husr == NULL)
e908ecfa 200 return;
c86edd1d
Q
201
202 huser_del(husr);
203}
204
052247fa 205static void helpmod_hook_channel_opped(int unused, void *args)
c86edd1d
Q
206{
207 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
208 huser_channel *huserchan;
209 huser *husr, *husr2;
210
211 if (hchan == NULL)
212 return;
213
214 husr = huser_get(((nick**)args)[2]);
215 husr2 = huser_get(((nick**)args)[1]);
216
217 assert(husr != NULL);
218
219 huserchan = huser_on_channel(husr, hchan);
220
221 assert(huserchan != NULL);
222
223 huserchan->flags |= HCUMODE_OP;
224
e908ecfa 225 if (hchan->flags & H_PASSIVE)
226 return;
227
c86edd1d 228 /* if the +o was given by a network service, G will not interfere */
3a839281 229 if (husr2 == NULL || strlen(huser_get_nick(husr2)) == 1)
c86edd1d
Q
230 return;
231
232 if (huser_get_level(husr) < H_STAFF)
233 helpmod_channick_modes(husr, hchan, MC_DEOP ,HNOW);
234}
235
052247fa 236static void helpmod_hook_channel_deopped(int unused, void *args)
c86edd1d
Q
237{
238 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
239 huser_channel *huserchan;
240 huser *husr;
241
242 if (hchan == NULL)
243 return;
244
245 husr = huser_get(((nick**)args)[2]);
246
247 assert(husr != NULL);
248
249 huserchan = huser_on_channel(husr, hchan);
250
251 assert(huserchan != NULL);
252
253 huserchan->flags &= ~HCUMODE_OP;
c86edd1d
Q
254}
255
052247fa 256static void helpmod_hook_channel_voiced(int unused, void *args)
c86edd1d
Q
257{
258 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
259 huser_channel *huserchan;
260 huser *husr;
261
262 if (hchan == NULL)
263 return;
264 husr = huser_get(((nick**)args)[2]);
265
266 assert(husr != NULL);
267
268 huserchan = huser_on_channel(husr, hchan);
269
270 assert(huserchan != NULL);
271
272 huserchan->flags |= HCUMODE_VOICE;
273
274 if (hchan->flags & H_QUEUE)
275 {
276 huserchan->flags |= HQUEUE_DONE;
277 huserchan->last_activity = time(NULL);
278 }
279}
280
052247fa 281static void helpmod_hook_channel_devoiced(int unused, void *args)
c86edd1d
Q
282{
283 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
284 huser_channel *huserchan;
285 huser *husr;
286
287 if (hchan == NULL)
288 return;
289
290 husr = huser_get(((nick**)args)[2]);
291
292 assert(husr != NULL);
293
294 huserchan = huser_on_channel(husr, hchan);
295
296 assert(huserchan != NULL);
297
298 huserchan->flags &= ~HCUMODE_VOICE;
299
e908ecfa 300 if (hchan->flags & H_PASSIVE)
301 return;
302
c86edd1d
Q
303 if ((hchan->flags & H_QUEUE) && (hchan->flags & H_QUEUE_MAINTAIN) && (huser_get_level(husr) == H_PEON) && (huserchan->flags & HCUMODE_VOICE) && (hchannel_count_queue(hchan)))
304 {
305 if (serverlist[homeserver(husr->real_user->numeric)].linkstate != LS_SQUIT)
306 { /* if it was a netsplit, we do not trigger autoqueue */
307 hqueue_handle_queue(hchan, huserchan->responsible_oper);
c86edd1d
Q
308 }
309 }
310}
311
052247fa 312static void helpmod_hook_channel_topic(int unused, void *args)
c86edd1d
Q
313{
314 hchannel *hchan = hchannel_get_by_channel(((channel**)args)[0]);
315 huser *husr;
316
e908ecfa 317 if (hchan == NULL || hchan->flags & H_PASSIVE)
c86edd1d
Q
318 return;
319
320 husr = huser_get(((nick**)args)[2]);
321
322 if (hchan->flags & H_HANDLE_TOPIC)
323 {
324 if (husr != NULL && huser_get_level(husr) >= H_OPER)
325 {
326 htopic_del_all(&hchan->topic);
327 htopic_add(&hchan->topic, hchan->real_channel->topic->content, 0);
328 }
329 else
330 {
331 hchannel_set_topic(hchan);
332 }
333 }
334}
335
052247fa 336static void helpmod_hook_nick_account(int unused, void *args)
c86edd1d
Q
337{
338 nick *nck = (nick*)args;
339 huser *husr = huser_get(nck);
12e8bdaa 340 huser_channel *huserchan, *huserchannext;
c86edd1d
Q
341 if (husr == NULL)
342 return;
343 else
052247fa
CP
344 husr->account = haccount_get_by_name(nck->authname);
345
12e8bdaa
P
346 if (huser_get_level(husr) == H_LAMER) {
347 for (huserchan = husr->hchannels; huserchan; huserchan = huserchannext) {
348 huserchannext = huserchan->next;
349 helpmod_kick(huserchan->hchan, husr, "Your presence on channel %s is not wanted", hchannel_get_name(huserchan->hchan));
350 }
351 }
c86edd1d
Q
352}
353
052247fa 354static void helpmod_hook_server_newserver(int unused, void *args)
9af95c3d 355{
356 hchannel *hchan;
c3db6f7e 357 long numeric = (long)args;
9af95c3d 358 server srv = serverlist[numeric];
359
360 /* check linkstate to prevent spam */
361 if (srv.linkstate == LS_LINKING)
362 {
363 for (hchan = hchannels;hchan != NULL;hchan = hchan->next)
364 if ((hchan->flags & H_HANDLE_TOPIC) && (hchan->topic != NULL))
365 hchannel_set_topic(hchan);
366 }
367}
368
c86edd1d
Q
369void helpmod_registerhooks(void)
370{
9af95c3d 371/* registerhook(HOOK_NICK_QUIT, &helpmod_hook_quit); */
c86edd1d 372 /*if (registerhook(HOOK_CHANNEL_PART, &helpmod_hook_part));*/
ce659137 373 registerhook(HOOK_CHANNEL_JOIN, &helpmod_hook_join);
374 registerhook(HOOK_NICK_LOSTNICK, &helpmod_hook_nick_lostnick);
375 registerhook(HOOK_CHANNEL_NEWNICK, &helpmod_hook_channel_newnick);
376 registerhook(HOOK_CHANNEL_LOSTNICK, &helpmod_hook_channel_lostnick);
377 registerhook(HOOK_CHANNEL_OPPED, &helpmod_hook_channel_opped);
378 registerhook(HOOK_CHANNEL_DEOPPED, &helpmod_hook_channel_deopped);
379 registerhook(HOOK_CHANNEL_VOICED, &helpmod_hook_channel_voiced);
380 registerhook(HOOK_CHANNEL_DEVOICED, &helpmod_hook_channel_devoiced);
381 registerhook(HOOK_CHANNEL_TOPIC, &helpmod_hook_channel_topic);
382 registerhook(HOOK_NICK_ACCOUNT, &helpmod_hook_nick_account);
9af95c3d 383 registerhook(HOOK_SERVER_NEWSERVER, &helpmod_hook_server_newserver);
c86edd1d
Q
384}
385
386void helpmod_deregisterhooks(void)
387{
9af95c3d 388/* deregisterhook(HOOK_NICK_QUIT, &helpmod_hook_quit); */
c86edd1d 389 /*if (deregisterhook(HOOK_CHANNEL_PART, &helpmod_hook_part));*/
ce659137 390 deregisterhook(HOOK_CHANNEL_JOIN, &helpmod_hook_join);
391 deregisterhook(HOOK_NICK_LOSTNICK, &helpmod_hook_nick_lostnick);
392 deregisterhook(HOOK_CHANNEL_NEWNICK, &helpmod_hook_channel_newnick);
393 deregisterhook(HOOK_CHANNEL_LOSTNICK, &helpmod_hook_channel_lostnick);
394 deregisterhook(HOOK_CHANNEL_OPPED, &helpmod_hook_channel_opped);
395 deregisterhook(HOOK_CHANNEL_DEOPPED, &helpmod_hook_channel_deopped);
396 deregisterhook(HOOK_CHANNEL_VOICED, &helpmod_hook_channel_voiced);
397 deregisterhook(HOOK_CHANNEL_DEVOICED, &helpmod_hook_channel_devoiced);
398 deregisterhook(HOOK_CHANNEL_TOPIC, &helpmod_hook_channel_topic);
399 deregisterhook(HOOK_NICK_ACCOUNT, &helpmod_hook_nick_account);
9af95c3d 400 deregisterhook(HOOK_SERVER_NEWSERVER, &helpmod_hook_server_newserver);
c86edd1d 401}