X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=cmd_neonserv_mode.c;h=f7f2db17a4ff352541e3fa4e9c43718eece33171;hb=795115bf680185ae01043bd1222b78bfed8c1d87;hp=835899737108fb034d00db318673076ba27f68a1;hpb=2a0b9f96516033221544df57e8eda9ef9f80b53f;p=NeonServV5.git diff --git a/cmd_neonserv_mode.c b/cmd_neonserv_mode.c index 8358997..f7f2db1 100644 --- a/cmd_neonserv_mode.c +++ b/cmd_neonserv_mode.c @@ -1,4 +1,6 @@ +#include "cmd_neonserv.h" + /* * argv[0] - modes * argv[1-*] - parameters @@ -13,7 +15,7 @@ struct neonserv_cmd_mode_cache { char *mode; }; -static CMD_BIND(neonserv_cmd_mode) { +CMD_BIND(neonserv_cmd_mode) { struct neonserv_cmd_mode_cache *cache = malloc(sizeof(*cache)); if (!cache) { perror("malloc() failed"); @@ -36,11 +38,13 @@ static USERLIST_CALLBACK(neonserv_cmd_mode_userlist_lookup) { static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mode) { MYSQL_ROW row, defaults = NULL; - int i, arg, add = 1; + int i, arg, add = 1, skip = 0; unsigned int modetype; int db_canop, db_canvoice, db_canban, db_enfmodes; struct ModeNode *modelock = createModeNode(NULL), *changemodes = createModeNode(NULL); struct ModeBuffer *modeBuf; + struct UserNode *cuser; + struct ChanUser *chanuser; modeBuf = initModeBuffer(client, chan); printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); row = mysql_fetch_row(mysql_use()); @@ -87,15 +91,21 @@ static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientS return; } carg = argv[arg++]; - if(uaccess < (modeStr[i] == 'o' ? db_canop : db_canvoice)) { - reply(textclient, user, "NS_MODE_ENFOPS", chan->name); - if(modeStr[i] == 'o') db_canop = -1; - else db_canvoice = -1; - break; + if(modeStr[i] == 'o') { + if(uaccess < db_canop) { + reply(textclient, user, "NS_MODE_ENFOPS", chan->name); + db_canop = -1; + break; + } + if(db_canop == -1) break; + } else { + if(uaccess < db_canvoice) { + reply(textclient, user, "NS_MODE_ENFVOICE", chan->name); + db_canvoice = -1; + break; + } + if(db_canvoice == -1) break; } - if((modeStr[i] == 'o' ? db_canop : db_canvoice) == -1) break; - struct UserNode *cuser; - struct ChanUser *chanuser; cuser = searchUserByNick(carg); if(!cuser) { //check for an invisible user @@ -125,7 +135,57 @@ static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientS modeBufferSet(modeBuf, add, modeStr[i], carg); break; case 'b': - + if(arg == argc) { + reply(textclient, user, "NS_MODE_INVALID", modeStr[i]); + return; + } + carg = argv[arg++]; + if(uaccess < db_canban) { + reply(textclient, user, "NS_MODE_CANBAN", chan->name); + db_canban = -1; + break; + } + if(db_canban == -1) break; + char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3]; + char usermask[NICKLEN+USERLEN+HOSTLEN+3]; + struct BanNode *ban; + int match_count = 0; + carg = make_banmask(carg, hostmask_buffer); + if(add) { + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { + cuser = chanuser->user; + sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host); + if(!match(carg, usermask)) { + if(isNetworkService(chanuser->user)) { + reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick); + skip = 1; + break; + } + if(isUserProtected(chan, cuser, user)) { + reply(textclient, user, "NS_USER_PROTECTED", cuser->nick); + skip = 1; + break; + } + match_count++; + if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) { + skip = 1; + reply(textclient, user, "NS_LAME_MASK", carg); + break; + } + } + } + } else { + skip = 1; + for(ban = chan->bans; ban; ban = ban->next) { + if(!match(carg, ban->mask)) { + skip = 0; + break; + } + } + } + if(!skip) { + modeBufferSet(modeBuf, add, 'b', carg); + } break; default: modetype = getModeType(modelock, modeStr[i]);