]>
jfr.im git - irc/quakenet/newserv.git/blob - channel/channelbans.c
8 #include "../nick/nick.h"
9 #include "../lib/irc_string.h"
10 #include "../irc/irc_config.h"
11 #include "../irc/irc.h"
12 #include "../lib/irc_ipv6.h"
16 * Returns true iff the supplied nick* matches the supplied ban*
18 * "visibleonly" flag indicates that we shouldn't check against the real
19 * host if it's masked.
22 int nickmatchban(nick
*np
, chanban
*bp
, int visibleonly
) {
23 char fakehost
[HOSTLEN
+1];
26 /* nick/ident section: return 0 (no match) if they don't match */
27 if (bp
->flags
& CHANBAN_INVALID
)
30 /* Pick up the visible username. If a sethost username is set, the real
31 * username is not checked. */
33 if (IsSetHost(np
) && np
->shident
)
34 ident
=np
->shident
->content
;
36 if (bp
->flags
& CHANBAN_USEREXACT
&&
37 ircd_strcmp(ident
,bp
->user
->content
))
40 if (bp
->flags
& CHANBAN_NICKEXACT
&& ircd_strcmp(np
->nick
,bp
->nick
->content
))
43 if (bp
->flags
& CHANBAN_USERMASK
&&
44 !match2strings(bp
->user
->content
,ident
))
47 if (bp
->flags
& CHANBAN_NICKMASK
&& !match2strings(bp
->nick
->content
,np
->nick
))
50 /* host section. Return 1 (match) if they do match
51 * Note that if user or ident was specified, they've already been checked
54 if (bp
->flags
& CHANBAN_HOSTANY
)
57 if ((bp
->flags
& CHANBAN_IP
) && !(visibleonly
&& (IsSetHost(np
) || (IsAccount(np
) && IsHideHost(np
))))) {
58 if (ipmask_check(&(np
->ipnode
->prefix
->sin
), &(bp
->ipaddr
), bp
->prefixlen
))
62 /* Hostname bans need to be checked against +x host, +h host (if set)
63 * and actual host. Note that the +x host is only generated (and checked) if it's
64 * possible for the ban to match a hidden host.. */
66 if ((bp
->flags
& CHANBAN_HIDDENHOST
) && IsAccount(np
)) {
67 sprintf(fakehost
,"%s.%s",np
->authname
, HIS_HIDDENHOST
);
69 if ((bp
->flags
& CHANBAN_HOSTEXACT
) &&
70 !ircd_strcmp(fakehost
, bp
->host
->content
))
73 if ((bp
->flags
& CHANBAN_HOSTMASK
) &&
74 match2strings(bp
->host
->content
, fakehost
))
79 if ((bp
->flags
& CHANBAN_HOSTEXACT
) &&
80 !ircd_strcmp(np
->sethost
->content
, bp
->host
->content
))
83 if ((bp
->flags
& CHANBAN_HOSTMASK
) &&
84 match2strings(bp
->host
->content
, np
->sethost
->content
))
88 /* If we are only checking visible host and the host is somehow masked, don't check
89 * against the real one. */
90 if (visibleonly
&& (IsSetHost(np
) || (IsAccount(np
) && IsHideHost(np
))))
93 if (bp
->flags
& CHANBAN_HOSTEXACT
&& !ircd_strcmp(np
->host
->name
->content
,bp
->host
->content
))
96 if (bp
->flags
& CHANBAN_HOSTMASK
&& match2strings(bp
->host
->content
,np
->host
->name
->content
))
104 * Returns true iff the supplied nick* is banned on the supplied chan*
106 * Pass the visibleonly flag on to nickbanned().
108 int nickbanned(nick
*np
, channel
*cp
, int visibleonly
) {
111 for (cbp
=cp
->bans
;cbp
;cbp
=cbp
->next
) {
112 if (nickmatchban(np
,cbp
,visibleonly
))
121 * Set the specified ban; if it completely encloses any existing bans
124 * Returns 1 if the ban was set, or 0 if the ban was not set because an
125 * existing ban overlapped it.
128 int setban(channel
*cp
, const char *ban
) {
129 chanban
**cbh
,*cbp
,*cbp2
;
133 /* Don't set our ban if something encloses it */
134 for (cbp2
=cp
->bans
;cbp2
;cbp2
=cbp2
->next
) {
135 if (banoverlap(cbp2
, cbp
)) {
136 /* This ban overlaps the one we are adding. Abort. */
142 /* Remove enclosed bans first */
143 for (cbh
=&(cp
->bans
);*cbh
;) {
144 if (banoverlap(cbp
,*cbh
)) {
148 /* Break out of the loop if we just deleted the last ban */
153 cbh
=(chanban
**)&((*cbh
)->next
);
157 /* Now set the new ban */
158 cbp
->next
=(struct chanban
*)cp
->bans
;
166 * Remove the specified ban iff an exact match is found
167 * Returns 1 if the ban was cleared, 0 if the ban didn't exist.
168 * If "optional" is 0 and the ban didn't exist, flags an error
171 int clearban(channel
*cp
, const char *ban
, int optional
) {
172 chanban
**cbh
,*cbp
,*cbp2
;
181 for (cbh
=&(cp
->bans
);*cbh
;cbh
=(chanban
**)&((*cbh
)->next
)) {
182 if (banequal(cbp
,*cbh
)) {
191 if (!found
&& !optional
) {
192 Error("channel",ERR_DEBUG
,"Couldn't remove ban %s from %s. Dumping banlist:",ban
,cp
->index
->name
->content
);
193 for (cbp2
=cp
->bans
;cbp2
;cbp2
=cbp2
->next
) {
194 Error("channel",ERR_DEBUG
,"%s %d %s",cp
->index
->name
->content
, i
++, bantostringdebug(cbp2
));
205 * Just free all the bans on the channel
208 void clearallbans(channel
*cp
) {
211 for (cbp
=cp
->bans
;cbp
;cbp
=ncbp
) {
212 ncbp
=(chanban
*)cbp
->next
;