]>
jfr.im git - solanum.git/blob - ircd/tgchange.c
2 * charybdis: an advanced Internet Relay Chat Daemon(ircd).
3 * tgchange.c - code for restricting private messages
5 * Copyright (C) 2004-2005 Lee Hardy <lee@leeh.co.uk>
6 * Copyright (C) 2005-2010 Jilles Tjoelker <jilles@stack.nl>
7 * Copyright (C) 2004-2005 ircd-ratbox development team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
32 #include "s_newconf.h"
36 static int add_hashed_target(struct Client
*source_p
, uint32_t hashv
);
39 find_allowing_channel(struct Client
*source_p
, struct Client
*target_p
)
42 struct membership
*msptr
;
44 RB_DLINK_FOREACH(ptr
, source_p
->user
->channel
.head
)
47 if (is_chanop_voiced(msptr
) && IsMember(target_p
, msptr
->chptr
))
54 add_target(struct Client
*source_p
, struct Client
*target_p
)
58 /* can msg themselves or services without using any target slots */
59 if(source_p
== target_p
|| IsService(target_p
))
62 /* special condition for those who have had PRIVMSG crippled to allow them
63 * to talk to IRCops still.
65 * XXX: is this controversial?
67 if(source_p
->localClient
->target_last
> rb_current_time() && IsOper(target_p
))
70 hashv
= fnv_hash_upper((const unsigned char *)use_id(target_p
), 32);
71 return add_hashed_target(source_p
, hashv
);
75 add_channel_target(struct Client
*source_p
, struct Channel
*chptr
)
79 if(!ConfigChannel
.channel_target_change
)
82 hashv
= fnv_hash_upper((const unsigned char *)chptr
->chname
, 32);
83 return add_hashed_target(source_p
, hashv
);
87 add_hashed_target(struct Client
*source_p
, uint32_t hashv
)
92 targets
= source_p
->localClient
->targets
;
94 /* check for existing target, and move it to the head */
95 for(i
= 0; i
< TGCHANGE_NUM
+ TGCHANGE_REPLY
; i
++)
97 if(targets
[i
] == hashv
)
99 for(j
= i
; j
> 0; j
--)
100 targets
[j
] = targets
[j
- 1];
106 if(source_p
->localClient
->targets_free
< TGCHANGE_NUM
)
108 /* first message after connect, we may only start clearing
109 * slots after this message --anfl
111 if(!IsTGChange(source_p
))
113 SetTGChange(source_p
);
114 source_p
->localClient
->target_last
= rb_current_time();
116 /* clear as many targets as we can */
117 else if((i
= (rb_current_time() - source_p
->localClient
->target_last
) / 60))
119 if(i
+ source_p
->localClient
->targets_free
> TGCHANGE_NUM
)
120 source_p
->localClient
->targets_free
= TGCHANGE_NUM
;
122 source_p
->localClient
->targets_free
+= i
;
124 source_p
->localClient
->target_last
= rb_current_time();
126 /* cant clear any, full target list */
127 else if(source_p
->localClient
->targets_free
== 0)
129 ServerStats
.is_tgch
++;
130 add_tgchange(source_p
->sockhost
);
132 if (!IsTGExcessive(source_p
))
134 SetTGExcessive(source_p
);
135 /* This is sent to L_ALL because it's regenerated on all servers
136 * that have the TGINFO module loaded.
138 sendto_realops_snomask(SNO_BOTS
, L_ALL
,
139 "Excessive target change from %s (%s@%s)",
140 source_p
->name
, source_p
->username
,
144 sendto_match_servs(source_p
, "*", CAP_ENCAP
, NOCAPS
,
150 /* no targets in use, reset their target_last so that they cant
151 * abuse a long idle to get targets back more quickly
155 source_p
->localClient
->target_last
= rb_current_time();
156 SetTGChange(source_p
);
159 for(i
= TGCHANGE_NUM
+ TGCHANGE_REPLY
- 1; i
> 0; i
--)
160 targets
[i
] = targets
[i
- 1];
162 source_p
->localClient
->targets_free
--;
167 add_reply_target(struct Client
*source_p
, struct Client
*target_p
)
173 /* can msg themselves or services without using any target slots */
174 if(source_p
== target_p
|| IsService(target_p
))
177 hashv
= fnv_hash_upper((const unsigned char *)use_id(target_p
), 32);
178 targets
= source_p
->localClient
->targets
;
180 /* check for existing target, and move it to the first reply slot
181 * if it is in a reply slot
183 for(i
= 0; i
< TGCHANGE_NUM
+ TGCHANGE_REPLY
; i
++)
185 if(targets
[i
] == hashv
)
189 for(j
= i
; j
> TGCHANGE_NUM
; j
--)
190 targets
[j
] = targets
[j
- 1];
191 targets
[TGCHANGE_NUM
] = hashv
;
196 for(i
= TGCHANGE_NUM
+ TGCHANGE_REPLY
- 1; i
> TGCHANGE_NUM
; i
--)
197 targets
[i
] = targets
[i
- 1];
198 targets
[TGCHANGE_NUM
] = hashv
;