unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
inchannel.c (3991B)
1 /* 2 * Extended ban: "in channel?" (+b ~c:#chan) 3 * (C) Copyright 2003-.. Bram Matthys (Syzop) and the UnrealIRCd team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 1, or (at your option) 8 * any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 #include "unrealircd.h" 20 21 ModuleHeader MOD_HEADER 22 = { 23 "extbans/inchannel", 24 "4.2", 25 "ExtBan ~c - banned when in specified channel", 26 "UnrealIRCd Team", 27 "unrealircd-6", 28 }; 29 30 /* Forward declarations */ 31 int extban_inchannel_is_ok(BanContext *b); 32 const char *extban_inchannel_conv_param(BanContext *b, Extban *extban); 33 int extban_inchannel_is_banned(BanContext *b); 34 35 /** Called upon module init */ 36 MOD_INIT() 37 { 38 ExtbanInfo req; 39 40 memset(&req, 0, sizeof(req)); 41 req.letter = 'c'; 42 req.name = "channel"; 43 req.is_ok = extban_inchannel_is_ok; 44 req.conv_param = extban_inchannel_conv_param; 45 req.is_banned = extban_inchannel_is_banned; 46 req.is_banned_events = BANCHK_ALL|BANCHK_TKL; 47 req.options = EXTBOPT_INVEX; /* for +I too */ 48 if (!ExtbanAdd(modinfo->handle, req)) 49 { 50 config_error("could not register extended ban type"); 51 return MOD_FAILED; 52 } 53 54 MARK_AS_OFFICIAL_MODULE(modinfo); 55 56 return MOD_SUCCESS; 57 } 58 59 /** Called upon module load */ 60 MOD_LOAD() 61 { 62 return MOD_SUCCESS; 63 } 64 65 /** Called upon unload */ 66 MOD_UNLOAD() 67 { 68 return MOD_SUCCESS; 69 } 70 71 const char *extban_inchannel_conv_param(BanContext *b, Extban *extban) 72 { 73 static char retbuf[CHANNELLEN+6]; 74 char *chan, *p, symbol='\0'; 75 76 strlcpy(retbuf, b->banstr, sizeof(retbuf)); 77 chan = retbuf; 78 79 if ((*chan == '+') || (*chan == '%') || (*chan == '%') || 80 (*chan == '@') || (*chan == '&') || (*chan == '~')) 81 chan++; 82 83 if ((*chan != '#') && (*chan != '*') && (*chan != '?')) 84 return NULL; 85 86 if (!valid_channelname(chan)) 87 return NULL; 88 89 p = strchr(chan, ':'); /* ~r:#chan:*.blah.net is not allowed (for now) */ 90 if (p) 91 *p = '\0'; 92 93 /* on a sidenote '#' is allowed because it's a valid channel (atm) */ 94 return retbuf; 95 } 96 97 /* The only purpose of this function is a temporary workaround to prevent a desync.. pfff */ 98 int extban_inchannel_is_ok(BanContext *b) 99 { 100 const char *p = b->banstr; 101 102 if ((b->is_ok_check == EXBCHK_PARAM) && MyUser(b->client) && (b->what == MODE_ADD) && (strlen(b->banstr) > 3)) 103 { 104 if ((*p == '+') || (*p == '%') || (*p == '%') || 105 (*p == '@') || (*p == '&') || (*p == '~')) 106 p++; 107 108 if (*p != '#') 109 { 110 sendnotice(b->client, "Please use a # in the channelname (eg: ~c:#*blah*)"); 111 return 0; 112 } 113 } 114 return 1; 115 } 116 117 static int extban_inchannel_compareflags(char symbol, const char *member_modes) 118 { 119 const char *required_modes = NULL; 120 121 if (symbol == '+') 122 required_modes = "vhoaq"; 123 else if (symbol == '%') 124 required_modes = "hoaq"; 125 else if (symbol == '@') 126 required_modes = "oaq"; 127 else if (symbol == '&') 128 required_modes = "aq"; 129 else if (symbol == '~') 130 required_modes = "q"; 131 else 132 return 0; /* unknown prefix character */ 133 134 if (check_channel_access_string(member_modes, required_modes)) 135 return 1; 136 137 return 0; 138 } 139 140 int extban_inchannel_is_banned(BanContext *b) 141 { 142 Membership *lp; 143 const char *p = b->banstr; 144 char symbol = '\0'; 145 146 if (*p != '#') 147 { 148 symbol = *p; 149 p++; 150 } 151 152 for (lp = b->client->user->channel; lp; lp = lp->next) 153 { 154 if (match_esc(p, lp->channel->name)) 155 { 156 /* Channel matched, check symbol if needed (+/%/@/etc) */ 157 if (symbol) 158 { 159 if (extban_inchannel_compareflags(symbol, lp->member_modes)) 160 return 1; 161 } else 162 return 1; 163 } 164 } 165 166 return 0; 167 } 168