]>
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"
33 static int add_hashed_target(struct Client
*source_p
, uint32_t hashv
);
36 find_allowing_channel(struct Client
*source_p
, struct Client
*target_p
)
39 struct membership
*msptr
;
41 RB_DLINK_FOREACH(ptr
, source_p
->user
->channel
.head
)
44 if (is_chanop_voiced(msptr
) && IsMember(target_p
, msptr
->chptr
))
51 add_target(struct Client
*source_p
, struct Client
*target_p
)
55 /* can msg themselves or services without using any target slots */
56 if(source_p
== target_p
|| IsService(target_p
))
59 /* special condition for those who have had PRIVMSG crippled to allow them
60 * to talk to IRCops still.
62 * XXX: is this controversial?
64 if(source_p
->localClient
->target_last
> rb_current_time() && IsOper(target_p
))
67 hashv
= fnv_hash_upper((const unsigned char *)use_id(target_p
), 32);
68 return add_hashed_target(source_p
, hashv
);
72 add_channel_target(struct Client
*source_p
, struct Channel
*chptr
)
76 hashv
= fnv_hash_upper((const unsigned char *)chptr
->chname
, 32);
77 return add_hashed_target(source_p
, hashv
);
81 add_hashed_target(struct Client
*source_p
, uint32_t hashv
)
86 targets
= source_p
->localClient
->targets
;
88 /* check for existing target, and move it to the head */
89 for(i
= 0; i
< TGCHANGE_NUM
+ TGCHANGE_REPLY
; i
++)
91 if(targets
[i
] == hashv
)
93 for(j
= i
; j
> 0; j
--)
94 targets
[j
] = targets
[j
- 1];
100 if(source_p
->localClient
->targets_free
< TGCHANGE_NUM
)
102 /* first message after connect, we may only start clearing
103 * slots after this message --anfl
105 if(!IsTGChange(source_p
))
107 SetTGChange(source_p
);
108 source_p
->localClient
->target_last
= rb_current_time();
110 /* clear as many targets as we can */
111 else if((i
= (rb_current_time() - source_p
->localClient
->target_last
) / 60))
113 if(i
+ source_p
->localClient
->targets_free
> TGCHANGE_NUM
)
114 source_p
->localClient
->targets_free
= TGCHANGE_NUM
;
116 source_p
->localClient
->targets_free
+= i
;
118 source_p
->localClient
->target_last
= rb_current_time();
120 /* cant clear any, full target list */
121 else if(source_p
->localClient
->targets_free
== 0)
123 ServerStats
.is_tgch
++;
124 add_tgchange(source_p
->sockhost
);
126 if (!IsTGExcessive(source_p
))
128 SetTGExcessive(source_p
);
129 sendto_realops_snomask(SNO_BOTS
, L_NETWIDE
,
130 "Excessive target change from %s (%s@%s)",
131 source_p
->name
, source_p
->username
,
138 /* no targets in use, reset their target_last so that they cant
139 * abuse a long idle to get targets back more quickly
143 source_p
->localClient
->target_last
= rb_current_time();
144 SetTGChange(source_p
);
147 for(i
= TGCHANGE_NUM
+ TGCHANGE_REPLY
- 1; i
> 0; i
--)
148 targets
[i
] = targets
[i
- 1];
150 source_p
->localClient
->targets_free
--;
155 add_reply_target(struct Client
*source_p
, struct Client
*target_p
)
161 /* can msg themselves or services without using any target slots */
162 if(source_p
== target_p
|| IsService(target_p
))
165 hashv
= fnv_hash_upper((const unsigned char *)use_id(target_p
), 32);
166 targets
= source_p
->localClient
->targets
;
168 /* check for existing target, and move it to the first reply slot
169 * if it is in a reply slot
171 for(i
= 0; i
< TGCHANGE_NUM
+ TGCHANGE_REPLY
; i
++)
173 if(targets
[i
] == hashv
)
177 for(j
= i
; j
> TGCHANGE_NUM
; j
--)
178 targets
[j
] = targets
[j
- 1];
179 targets
[TGCHANGE_NUM
] = hashv
;
184 for(i
= TGCHANGE_NUM
+ TGCHANGE_REPLY
- 1; i
> TGCHANGE_NUM
; i
--)
185 targets
[i
] = targets
[i
- 1];
186 targets
[TGCHANGE_NUM
] = hashv
;