]>
jfr.im git - solanum.git/blob - src/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
31 #include "s_newconf.h"
34 static int add_hashed_target(struct Client
*source_p
, uint32_t hashv
);
37 find_allowing_channel(struct Client
*source_p
, struct Client
*target_p
)
40 struct membership
*msptr
;
42 RB_DLINK_FOREACH(ptr
, source_p
->user
->channel
.head
)
45 if (is_chanop_voiced(msptr
) && IsMember(target_p
, msptr
->chptr
))
52 add_target(struct Client
*source_p
, struct Client
*target_p
)
56 /* can msg themselves or services without using any target slots */
57 if(source_p
== target_p
|| IsService(target_p
))
60 /* special condition for those who have had PRIVMSG crippled to allow them
61 * to talk to IRCops still.
63 * XXX: is this controversial?
65 if(source_p
->localClient
->target_last
> rb_current_time() && IsOper(target_p
))
68 hashv
= fnv_hash_upper((const unsigned char *)use_id(target_p
), 32);
69 return add_hashed_target(source_p
, hashv
);
73 add_channel_target(struct Client
*source_p
, struct Channel
*chptr
)
77 hashv
= fnv_hash_upper((const unsigned char *)chptr
->chname
, 32);
78 return add_hashed_target(source_p
, hashv
);
82 add_hashed_target(struct Client
*source_p
, uint32_t hashv
)
87 targets
= source_p
->localClient
->targets
;
89 /* check for existing target, and move it to the head */
90 for(i
= 0; i
< TGCHANGE_NUM
+ TGCHANGE_REPLY
; i
++)
92 if(targets
[i
] == hashv
)
94 for(j
= i
; j
> 0; j
--)
95 targets
[j
] = targets
[j
- 1];
101 if(source_p
->localClient
->targets_free
< TGCHANGE_NUM
)
103 /* first message after connect, we may only start clearing
104 * slots after this message --anfl
106 if(!IsTGChange(source_p
))
108 SetTGChange(source_p
);
109 source_p
->localClient
->target_last
= rb_current_time();
111 /* clear as many targets as we can */
112 else if((i
= (rb_current_time() - source_p
->localClient
->target_last
) / 60))
114 if(i
+ source_p
->localClient
->targets_free
> TGCHANGE_NUM
)
115 source_p
->localClient
->targets_free
= TGCHANGE_NUM
;
117 source_p
->localClient
->targets_free
+= i
;
119 source_p
->localClient
->target_last
= rb_current_time();
121 /* cant clear any, full target list */
122 else if(source_p
->localClient
->targets_free
== 0)
124 ServerStats
.is_tgch
++;
125 add_tgchange(source_p
->sockhost
);
127 if (!IsTGExcessive(source_p
))
129 SetTGExcessive(source_p
);
130 /* This is sent to L_ALL because it's regenerated on all servers
131 * that have the TGINFO module loaded.
133 sendto_realops_snomask(SNO_BOTS
, L_ALL
,
134 "Excessive target change from %s (%s@%s)",
135 source_p
->name
, source_p
->username
,
139 sendto_match_servs(source_p
, "*", CAP_ENCAP
, NOCAPS
,
145 /* no targets in use, reset their target_last so that they cant
146 * abuse a long idle to get targets back more quickly
150 source_p
->localClient
->target_last
= rb_current_time();
151 SetTGChange(source_p
);
154 for(i
= TGCHANGE_NUM
+ TGCHANGE_REPLY
- 1; i
> 0; i
--)
155 targets
[i
] = targets
[i
- 1];
157 source_p
->localClient
->targets_free
--;
162 add_reply_target(struct Client
*source_p
, struct Client
*target_p
)
168 /* can msg themselves or services without using any target slots */
169 if(source_p
== target_p
|| IsService(target_p
))
172 hashv
= fnv_hash_upper((const unsigned char *)use_id(target_p
), 32);
173 targets
= source_p
->localClient
->targets
;
175 /* check for existing target, and move it to the first reply slot
176 * if it is in a reply slot
178 for(i
= 0; i
< TGCHANGE_NUM
+ TGCHANGE_REPLY
; i
++)
180 if(targets
[i
] == hashv
)
184 for(j
= i
; j
> TGCHANGE_NUM
; j
--)
185 targets
[j
] = targets
[j
- 1];
186 targets
[TGCHANGE_NUM
] = hashv
;
191 for(i
= TGCHANGE_NUM
+ TGCHANGE_REPLY
- 1; i
> TGCHANGE_NUM
; i
--)
192 targets
[i
] = targets
[i
- 1];
193 targets
[TGCHANGE_NUM
] = hashv
;