From 8e475017a6f87ac936993fa9791a6634683dd512 Mon Sep 17 00:00:00 2001 From: brain Date: Sat, 1 May 2004 12:44:07 +0000 Subject: Added Module::OnAccessCheck Added ListMode support Fixed Extensible class bug git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@759 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/InspIRCd.dev | 12 +- src/InspIRCd.layout | 101 +++++++------- src/base.cpp | 13 +- src/inspircd.cpp | 30 +++-- src/mode.cpp | 379 +++++++++++++++++++++++++++++++--------------------- src/modules.cpp | 44 +++++- src/users.cpp | 4 - 7 files changed, 364 insertions(+), 219 deletions(-) (limited to 'src') diff --git a/src/InspIRCd.dev b/src/InspIRCd.dev index f553ce649..2012957fc 100644 --- a/src/InspIRCd.dev +++ b/src/InspIRCd.dev @@ -1,7 +1,7 @@ [Project] FileName=InspIRCd.dev Name=InspIRCd - The Inspire Internet Relay Chat Daemon -UnitCount=50 +UnitCount=51 Type=1 Ver=1 ObjFiles= @@ -545,3 +545,13 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= +[Unit51] +FileName=modules\m_chanprotect.cpp +CompileCpp=1 +Folder=Modules +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout index 06ccc0a28..1e1e0138c 100644 --- a/src/InspIRCd.layout +++ b/src/InspIRCd.layout @@ -1,5 +1,5 @@ [Editors] -Focused=6 +Focused=-1 Order=2,4,6,3,7,25,5,24,39,42,43,-1,1,46,0,49 [Editor_0] @@ -13,9 +13,9 @@ LeftChar=1 [Editor_1] Open=1 Top=0 -CursorCol=2 -CursorRow=211 -TopLine=180 +CursorCol=23 +CursorRow=1610 +TopLine=1575 LeftChar=1 [Editor_2] @@ -37,9 +37,9 @@ LeftChar=1 [Editor_4] Open=1 Top=0 -CursorCol=71 -CursorRow=120 -TopLine=92 +CursorCol=1 +CursorRow=330 +TopLine=298 LeftChar=1 [Editor_5] @@ -52,9 +52,9 @@ LeftChar=1 [Editor_6] Open=1 -Top=1 -CursorCol=24 -CursorRow=140 +Top=0 +CursorCol=1 +CursorRow=117 TopLine=94 LeftChar=1 @@ -77,17 +77,17 @@ LeftChar=1 [Editor_9] Open=1 Top=0 -CursorCol=1 -CursorRow=113 +CursorCol=3 +CursorRow=66 TopLine=26 LeftChar=1 [Editor_10] Open=1 Top=0 -CursorCol=1 -CursorRow=102 -TopLine=76 +CursorCol=13 +CursorRow=62 +TopLine=49 LeftChar=1 [Editor_11] @@ -103,7 +103,7 @@ Open=1 Top=0 CursorCol=32 CursorRow=191 -TopLine=154 +TopLine=1 LeftChar=1 [Editor_13] @@ -141,9 +141,9 @@ LeftChar=1 [Editor_17] Open=1 Top=0 -CursorCol=1 -CursorRow=2 -TopLine=1 +CursorCol=46 +CursorRow=114 +TopLine=106 LeftChar=1 [Editor_18] @@ -164,10 +164,10 @@ LeftChar=1 [Editor_20] Open=1 -Top=0 -CursorCol=107 -CursorRow=164 -TopLine=140 +Top=1 +CursorCol=1 +CursorRow=40 +TopLine=1 LeftChar=1 [Editor_21] @@ -189,9 +189,9 @@ LeftChar=1 [Editor_23] Open=1 Top=0 -CursorCol=1 -CursorRow=69 -TopLine=14 +CursorCol=28 +CursorRow=42 +TopLine=2 LeftChar=1 [Editor_24] @@ -206,21 +206,21 @@ Open=1 Top=0 CursorCol=1 CursorRow=23 -TopLine=1 +TopLine=46 LeftChar=1 [Editor_26] Open=1 Top=0 -CursorCol=1 -CursorRow=13 -TopLine=23 +CursorCol=13 +CursorRow=49 +TopLine=32 LeftChar=1 [Editor_27] Open=1 Top=0 -CursorCol=3 -CursorRow=67 -TopLine=34 +CursorCol=13 +CursorRow=50 +TopLine=6 LeftChar=1 [Editor_28] Open=1 @@ -251,7 +251,7 @@ CursorRow=40 TopLine=8 LeftChar=1 [Editor_32] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=1 @@ -262,7 +262,7 @@ Open=1 Top=0 CursorCol=23 CursorRow=36 -TopLine=1 +TopLine=10 LeftChar=1 [Editor_34] Open=1 @@ -288,9 +288,9 @@ LeftChar=1 [Editor_37] Open=1 Top=0 -CursorCol=5 -CursorRow=90 -TopLine=63 +CursorCol=13 +CursorRow=160 +TopLine=1 LeftChar=1 [Editor_38] Open=1 @@ -323,16 +323,16 @@ LeftChar=1 [Editor_42] Open=1 Top=0 -CursorCol=10 -CursorRow=538 -TopLine=510 +CursorCol=128 +CursorRow=1210 +TopLine=1187 LeftChar=1 [Editor_43] Open=1 Top=0 CursorCol=1 -CursorRow=86 -TopLine=49 +CursorRow=217 +TopLine=203 LeftChar=1 [Editor_44] Open=1 @@ -358,8 +358,8 @@ LeftChar=1 [Editor_47] Open=1 Top=0 -CursorCol=1 -CursorRow=52 +CursorCol=32 +CursorRow=46 TopLine=4 LeftChar=1 [Editor_48] @@ -372,7 +372,14 @@ LeftChar=1 [Editor_49] Open=1 Top=0 -CursorCol=1 -CursorRow=32 +CursorCol=31 +CursorRow=14 TopLine=1 LeftChar=1 +[Editor_50] +Open=1 +Top=0 +CursorCol=1 +CursorRow=9 +TopLine=37 +LeftChar=1 diff --git a/src/base.cpp b/src/base.cpp index 7e545694b..f1f66bd93 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -3,13 +3,16 @@ #include #include #include +#include "inspircd.h" +#include "modules.h" -bool Extensible::Extend(std::string key, VoidPointer p) +bool Extensible::Extend(std::string key, char* p) { // only add an item if it doesnt already exist if (this->Extension_Items.find(key) == this->Extension_Items.end()) { - this->Extension_Items[key] == p; + this->Extension_Items[key] = p; + log(DEBUG,"Extending object with item %s",key.c_str()); return true; } // item already exists, return false @@ -22,17 +25,21 @@ bool Extensible::Shrink(std::string key) if (this->Extension_Items.find(key) != this->Extension_Items.end()) { this->Extension_Items.erase(this->Extension_Items.find(key)); + log(DEBUG,"Shrinking object with item %s",key.c_str()); return true; } return false; } -VoidPointer Extensible::GetExt(std::string key) +char* Extensible::GetExt(std::string key) { + log(DEBUG,"Checking extension items for %s",key.c_str()); if (this->Extension_Items.find(key) != this->Extension_Items.end()) { + log(DEBUG,"Found item %s %s",key.c_str(),(this->Extension_Items.find(key))->second); return (this->Extension_Items.find(key))->second; } + log(DEBUG,"Cant find item %s",key.c_str()); return NULL; } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index f313c64c7..310ef4043 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -1310,6 +1310,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri if (!FindChan(cname)) { + int MOD_RESULT = 0; FOREACH_RESULT(OnUserPreJoin(user,NULL,cname)); if (MOD_RESULT) { return NULL; @@ -1347,6 +1348,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri // and bans (used by servers) if (!override) { + int MOD_RESULT = 0; FOREACH_RESULT(OnUserPreJoin(user,Ptr,cname)); if (MOD_RESULT) { return NULL; @@ -1600,18 +1602,28 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) WriteServ(src->fd,"441 %s %s %s :They are not on that channel",src->nick, user->nick, Ptr->name); return; } - if (((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) && (!is_uline(src->server))) + + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(src,user,Ptr,AC_KICK)); + + if (MOD_RESULT == ACR_DENY) + return; + + if (MOD_RESULT == ACR_DEFAULT) { - if (cstatus(src,Ptr) == STATUS_HOP) - { - WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name); - } - else + if (((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) && (!is_uline(src->server))) { - WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name); + if (cstatus(src,Ptr) == STATUS_HOP) + { + WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name); + } + else + { + WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name); + } + + return; } - - return; } for (int i =0; i != MAXCHANS; i++) diff --git a/src/mode.cpp b/src/mode.cpp index c5f179f24..4a7c56bd3 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -71,47 +71,56 @@ char* give_ops(userrec *user,char *dest,chanrec *chan,int status) log(DEFAULT,"*** BUG *** give_ops was given an invalid parameter"); return NULL; } - if ((status < STATUS_OP) && (!is_uline(user->server))) + + if (!isnick(dest)) + { + log(DEFAULT,"the target nickname given to give_ops was invalid"); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + return NULL; + } + d = Find(dest); + if (!d) { - log(DEBUG,"%s cant give ops to %s because they nave status %d and needs %d",user->nick,dest,status,STATUS_OP); - WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + log(DEFAULT,"the target nickname given to give_ops couldnt be found"); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); return NULL; } else { - if (!isnick(dest)) - { - log(DEFAULT,"the target nickname given to give_ops was invalid"); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_OP)); + + if (MOD_RESULT == ACR_DENY) return NULL; - } - d = Find(dest); - if (!d) + if (MOD_RESULT == ACR_DEFAULT) { - log(DEFAULT,"the target nickname given to give_ops couldnt be found"); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; + if ((status < STATUS_OP) && (!is_uline(user->server))) + { + log(DEBUG,"%s cant give ops to %s because they nave status %d and needs %d",user->nick,dest,status,STATUS_OP); + WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + return NULL; + } } - else + + + for (int i = 0; i != MAXCHANS; i++) { - for (int i = 0; i != MAXCHANS; i++) + if ((d->chans[i].channel != NULL) && (chan != NULL)) + if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if ((d->chans[i].channel != NULL) && (chan != NULL)) - if (!strcasecmp(d->chans[i].channel->name,chan->name)) + if (d->chans[i].uc_modes & UCMODE_OP) { - if (d->chans[i].uc_modes & UCMODE_OP) - { - /* mode already set on user, dont allow multiple */ - log(DEFAULT,"The target user given to give_ops was already opped on the channel"); - return NULL; - } - d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_OP; - log(DEBUG,"gave ops: %s %s",d->chans[i].channel->name,d->nick); - return d->nick; + /* mode already set on user, dont allow multiple */ + log(DEFAULT,"The target user given to give_ops was already opped on the channel"); + return NULL; } + d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_OP; + log(DEBUG,"gave ops: %s %s",d->chans[i].channel->name,d->nick); + return d->nick; } - log(DEFAULT,"The target channel given to give_ops was not in the users mode list"); } + log(DEFAULT,"The target channel given to give_ops was not in the users mode list"); } return NULL; } @@ -126,40 +135,47 @@ char* give_hops(userrec *user,char *dest,chanrec *chan,int status) log(DEFAULT,"*** BUG *** give_hops was given an invalid parameter"); return NULL; } - if ((status < STATUS_OP) && (!is_uline(user->server))) + + d = Find(dest); + if (!isnick(dest)) + { + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + return NULL; + } + if (!d) { - WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); return NULL; } else { - d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_HALFOP)); + + if (MOD_RESULT == ACR_DENY) return NULL; - } - if (!d) + if (MOD_RESULT == ACR_DEFAULT) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; + if ((status < STATUS_OP) && (!is_uline(user->server))) + { + WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + return NULL; + } } - else + + for (int i = 0; i != MAXCHANS; i++) { - for (int i = 0; i != MAXCHANS; i++) + if ((d->chans[i].channel != NULL) && (chan != NULL)) + if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if ((d->chans[i].channel != NULL) && (chan != NULL)) - if (!strcasecmp(d->chans[i].channel->name,chan->name)) + if (d->chans[i].uc_modes & UCMODE_HOP) { - if (d->chans[i].uc_modes & UCMODE_HOP) - { - /* mode already set on user, dont allow multiple */ - return NULL; - } - d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_HOP; - log(DEBUG,"gave h-ops: %s %s",d->chans[i].channel->name,d->nick); - return d->nick; + /* mode already set on user, dont allow multiple */ + return NULL; } + d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_HOP; + log(DEBUG,"gave h-ops: %s %s",d->chans[i].channel->name,d->nick); + return d->nick; } } } @@ -176,40 +192,47 @@ char* give_voice(userrec *user,char *dest,chanrec *chan,int status) log(DEFAULT,"*** BUG *** give_voice was given an invalid parameter"); return NULL; } - if ((status < STATUS_HOP) && (!is_uline(user->server))) + + d = Find(dest); + if (!isnick(dest)) + { + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + return NULL; + } + if (!d) { - WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); return NULL; } else { - d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_VOICE)); + + if (MOD_RESULT == ACR_DENY) return NULL; - } - if (!d) + if (MOD_RESULT == ACR_DEFAULT) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; + if ((status < STATUS_HOP) && (!is_uline(user->server))) + { + WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name); + return NULL; + } } - else + + for (int i = 0; i != MAXCHANS; i++) { - for (int i = 0; i != MAXCHANS; i++) + if ((d->chans[i].channel != NULL) && (chan != NULL)) + if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if ((d->chans[i].channel != NULL) && (chan != NULL)) - if (!strcasecmp(d->chans[i].channel->name,chan->name)) + if (d->chans[i].uc_modes & UCMODE_VOICE) { - if (d->chans[i].uc_modes & UCMODE_VOICE) - { - /* mode already set on user, dont allow multiple */ - return NULL; - } - d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_VOICE; - log(DEBUG,"gave voice: %s %s",d->chans[i].channel->name,d->nick); - return d->nick; + /* mode already set on user, dont allow multiple */ + return NULL; } + d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_VOICE; + log(DEBUG,"gave voice: %s %s",d->chans[i].channel->name,d->nick); + return d->nick; } } } @@ -226,46 +249,52 @@ char* take_ops(userrec *user,char *dest,chanrec *chan,int status) log(DEFAULT,"*** BUG *** take_ops was given an invalid parameter"); return NULL; } - if ((status < STATUS_OP) && (!is_uline(user->server))) + + d = Find(dest); + if (!isnick(dest)) + { + log(DEBUG,"take_ops was given an invalid target nickname of %s",dest); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + return NULL; + } + if (!d) { - log(DEBUG,"%s cant give ops to %s because they have status %d and needs %d",user->nick,dest,status,STATUS_OP); - WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + log(DEBUG,"take_ops couldnt resolve the target nickname: %s",dest); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); return NULL; } else { - d = Find(dest); - if (!isnick(dest)) - { - log(DEBUG,"take_ops was given an invalid target nickname of %s",dest); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_DEOP)); + + if (MOD_RESULT == ACR_DENY) return NULL; - } - if (!d) + if (MOD_RESULT == ACR_DEFAULT) { - log(DEBUG,"take_ops couldnt resolve the target nickname: %s",dest); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; + if ((status < STATUS_OP) && (!is_uline(user->server))) + { + WriteServ(user->fd,"482 %s %s :You are not a channel operator",user->nick, chan->name); + return NULL; + } } - else + + for (int i = 0; i != MAXCHANS; i++) { - for (int i = 0; i != MAXCHANS; i++) + if ((d->chans[i].channel != NULL) && (chan != NULL)) + if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if ((d->chans[i].channel != NULL) && (chan != NULL)) - if (!strcasecmp(d->chans[i].channel->name,chan->name)) + if ((d->chans[i].uc_modes & UCMODE_OP) == 0) { - if ((d->chans[i].uc_modes & UCMODE_OP) == 0) - { - /* mode already set on user, dont allow multiple */ - return NULL; - } - d->chans[i].uc_modes ^= UCMODE_OP; - log(DEBUG,"took ops: %s %s",d->chans[i].channel->name,d->nick); - return d->nick; + /* mode already set on user, dont allow multiple */ + return NULL; } + d->chans[i].uc_modes ^= UCMODE_OP; + log(DEBUG,"took ops: %s %s",d->chans[i].channel->name,d->nick); + return d->nick; } - log(DEBUG,"take_ops couldnt locate the target channel in the target users list"); } + log(DEBUG,"take_ops couldnt locate the target channel in the target users list"); } return NULL; } @@ -280,40 +309,47 @@ char* take_hops(userrec *user,char *dest,chanrec *chan,int status) log(DEFAULT,"*** BUG *** take_hops was given an invalid parameter"); return NULL; } - if ((status < STATUS_OP) && (!is_uline(user->server))) + + d = Find(dest); + if (!isnick(dest)) + { + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + return NULL; + } + if (!d) { - WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); return NULL; } else { - d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_DEHALFOP)); + + if (MOD_RESULT == ACR_DENY) return NULL; - } - if (!d) + if (MOD_RESULT == ACR_DEFAULT) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; + if ((status < STATUS_OP) && (!is_uline(user->server))) + { + WriteServ(user->fd,"482 %s %s :You are not a channel operator",user->nick, chan->name); + return NULL; + } } - else + + for (int i = 0; i != MAXCHANS; i++) { - for (int i = 0; i != MAXCHANS; i++) + if ((d->chans[i].channel != NULL) && (chan != NULL)) + if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if ((d->chans[i].channel != NULL) && (chan != NULL)) - if (!strcasecmp(d->chans[i].channel->name,chan->name)) + if ((d->chans[i].uc_modes & UCMODE_HOP) == 0) { - if ((d->chans[i].uc_modes & UCMODE_HOP) == 0) - { - /* mode already set on user, dont allow multiple */ - return NULL; - } - d->chans[i].uc_modes ^= UCMODE_HOP; - log(DEBUG,"took h-ops: %s %s",d->chans[i].channel->name,d->nick); - return d->nick; + /* mode already set on user, dont allow multiple */ + return NULL; } + d->chans[i].uc_modes ^= UCMODE_HOP; + log(DEBUG,"took h-ops: %s %s",d->chans[i].channel->name,d->nick); + return d->nick; } } } @@ -330,40 +366,47 @@ char* take_voice(userrec *user,char *dest,chanrec *chan,int status) log(DEFAULT,"*** BUG *** take_voice was given an invalid parameter"); return NULL; } - if ((status < STATUS_HOP) && (!is_uline(user->server))) + + d = Find(dest); + if (!isnick(dest)) + { + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + return NULL; + } + if (!d) { - WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name); + WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); return NULL; } else { - d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_DEVOICE)); + + if (MOD_RESULT == ACR_DENY) return NULL; - } - if (!d) + if (MOD_RESULT == ACR_DEFAULT) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; + if ((status < STATUS_HOP) && (!is_uline(user->server))) + { + WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name); + return NULL; + } } - else + + for (int i = 0; i != MAXCHANS; i++) { - for (int i = 0; i != MAXCHANS; i++) + if ((d->chans[i].channel != NULL) && (chan != NULL)) + if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if ((d->chans[i].channel != NULL) && (chan != NULL)) - if (!strcasecmp(d->chans[i].channel->name,chan->name)) + if ((d->chans[i].uc_modes & UCMODE_VOICE) == 0) { - if ((d->chans[i].uc_modes & UCMODE_VOICE) == 0) - { - /* mode already set on user, dont allow multiple */ - return NULL; - } - d->chans[i].uc_modes ^= UCMODE_VOICE; - log(DEBUG,"took voice: %s %s",d->chans[i].channel->name,d->nick); - return d->nick; + /* mode already set on user, dont allow multiple */ + return NULL; } + d->chans[i].uc_modes ^= UCMODE_VOICE; + log(DEBUG,"took voice: %s %s",d->chans[i].channel->name,d->nick); + return d->nick; } } } @@ -463,6 +506,12 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int return; } + int MOD_RESULT = 0; + FOREACH_RESULT(OnAccessCheck(user,NULL,chan,AC_GENERAL_MODE)); + + if (MOD_RESULT == ACR_DENY) + return; + log(DEBUG,"process_modes: start: parameters=%d",pcnt); strcpy(modelist,parameters[1]); /* mode list, e.g. +oo-o */ @@ -753,8 +802,11 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int p.clear(); if (((!strchr(chan->custom_modes,modechar)) && (!mdir)) || ((strchr(chan->custom_modes,modechar)) && (mdir))) { - log(DEBUG,"Mode %c isnt set on %s but trying to remove!",modechar,chan->name); - break; + if (!ModeIsListMode(modechar,MT_CHANNEL)) + { + log(DEBUG,"Mode %c isnt set on %s but trying to remove!",modechar,chan->name); + break; + } } if (ModeDefined(modechar,MT_CHANNEL)) { @@ -785,27 +837,46 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int { if (!handled) { - if (modules[i]->OnExtendedMode(user,chan,modechar,MT_CHANNEL,mdir,p)) + int t = modules[i]->OnExtendedMode(user,chan,modechar,MT_CHANNEL,mdir,p); + if (t != 0) { log(DEBUG,"OnExtendedMode returned nonzero for a module"); char app[] = {modechar, 0}; - if (ptr>0) + if (ModeIsListMode(modechar,MT_CHANNEL)) { - if ((modelist[ptr-1] == '+') || (modelist[ptr-1] == '-')) + if (t == -1) { - strcat(outlist, app); + pc++; } - else if (!strchr(outlist,modechar)) + else { - strcat(outlist, app); + if (ptr>0) + { + strcat(outlist, app); + } + strcpy(outpars[pc++],parameters[param++]); } } - chan->SetCustomMode(modechar,mdir); - // include parameters in output if mode has them - if ((ModeDefinedOn(modechar,MT_CHANNEL)>0) && (mdir)) + else { - chan->SetCustomModeParam(modelist[ptr],parameters[param],mdir); - strcpy(outpars[pc++],parameters[param++]); + if (ptr>0) + { + if ((modelist[ptr-1] == '+') || (modelist[ptr-1] == '-')) + { + strcat(outlist, app); + } + else if (!strchr(outlist,modechar)) + { + strcat(outlist, app); + } + } + chan->SetCustomMode(modechar,mdir); + // include parameters in output if mode has them + if ((ModeDefinedOn(modechar,MT_CHANNEL)>0) && (mdir)) + { + chan->SetCustomModeParam(modelist[ptr],parameters[param],mdir); + strcpy(outpars[pc++],parameters[param++]); + } } // break, because only one module can handle the mode. handled = true; diff --git a/src/modules.cpp b/src/modules.cpp index d2f012977..d4d647d7e 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -26,6 +26,7 @@ public: int params_when_on; int params_when_off; bool needsoper; + bool list; ExtMode(char mc, int ty, bool oper, int p_on, int p_off) : modechar(mc), type(ty), needsoper(oper), params_when_on(p_on), params_when_off(p_off) { }; }; @@ -49,6 +50,20 @@ bool ModeDefined(char modechar, int type) return false; } +bool ModeIsListMode(char modechar, int type) +{ + log(DEBUG,"Size of extmodes vector is %d",EMode.size()); + for (ExtModeListIter i = EMode.begin(); i < EMode.end(); i++) + { + log(DEBUG,"i->modechar==%c, modechar=%c, i->type=%d, type=%d",i->modechar,modechar,i->type,type); + if ((i->modechar == modechar) && (i->type == type) && (i->list == true)) + { + return true; + } + } + return false; +} + bool ModeDefinedOper(char modechar, int type) { log(DEBUG,"Size of extmodes vector is %d",EMode.size()); @@ -99,6 +114,19 @@ bool DoAddExtendedMode(char modechar, int type, bool requires_oper, int params_o return true; } +// turns a mode into a listmode +void ModeMakeList(char modechar) +{ + for (ExtModeListIter i = EMode.begin(); i < EMode.end(); i++) + { + if ((i->modechar == modechar) && (i->type == MT_CHANNEL)) + { + i->list = true; + return; + } + } + return; +} // version is a simple class for holding a modules version number @@ -119,7 +147,7 @@ void Module::OnPacketReceive(char *p) { } void Module::OnRehash() { } void Module::OnServerRaw(std::string &raw, bool inbound, userrec* user) { } int Module::OnUserPreJoin(userrec* user, chanrec* chan, const char* cname) { return 0; } -bool Module::OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list ¶ms) { return false; } +int Module::OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list ¶ms) { return false; } Version Module::GetVersion() { return Version(1,0,0,0); } void Module::OnOper(userrec* user) { }; void Module::OnInfo(userrec* user) { }; @@ -127,6 +155,7 @@ void Module::OnWhois(userrec* source, userrec* dest) { }; int Module::OnUserPreMessage(userrec* user,void* dest,int target_type, std::string text) { return 0; }; int Module::OnUserPreNotice(userrec* user,void* dest,int target_type, std::string text) { return 0; }; int Module::OnUserPreNick(userrec* user, std::string newnick) { return 0; }; +int Module::OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type) { return ACR_DEFAULT; }; // server is a wrapper class that provides methods to all of the C-style // exports in the core @@ -297,6 +326,11 @@ std::string Server::ChanMode(userrec* User, chanrec* Chan) return cmode(User,Chan); } +bool Server::IsOnChannel(userrec* User, chanrec* Chan) +{ + return has_channel(User,Chan); +} + std::string Server::GetServerName() { return getservername(); @@ -334,6 +368,14 @@ bool Server::AddExtendedMode(char modechar, int type, bool requires_oper, int pa return DoAddExtendedMode(modechar,type,requires_oper,params_when_on,params_when_off); } +bool Server::AddExtendedListMode(char modechar) +{ + bool res = DoAddExtendedMode(modechar,MT_CHANNEL,false,1,1); + if (res) + ModeMakeList(modechar); + return res; +} + int Server::CountUsers(chanrec* c) { return usercount(c); diff --git a/src/users.cpp b/src/users.cpp index b523033ba..cdb93a40f 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -114,7 +114,6 @@ bool userrec::HasPermission(char* command) log(DEBUG,"*** HasPermission: %s is an oper of type '%s'",this->nick,this->oper); ConfValue("type","classes",j,Classes,&config_f); char* myclass = strtok_r(Classes," ",&savept); - //myclass = savept; while (myclass) { log(DEBUG,"*** HasPermission: checking classtype '%s'",myclass); @@ -128,7 +127,6 @@ bool userrec::HasPermission(char* command) mycmd = strtok_r(CommandList," ",&savept2); - //mycmd = savept2; while (mycmd) { if (!strcasecmp(mycmd,command)) @@ -137,12 +135,10 @@ bool userrec::HasPermission(char* command) return true; } mycmd = strtok_r(NULL," ",&savept2); - //mycmd = savept2; } } } myclass = strtok_r(NULL," ",&savept); - //myclass = savept; } } } -- cgit v1.2.3