]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Update m_cloaking to use free-form keys instead of weakening the hash IV
[user/henk/code/inspircd.git] / src / mode.cpp
index 73b465917abfe5e0d88a0ba75a3f252418072481..c37407223e06ac9e8d73acb52afe28a68c41d2ba 100644 (file)
@@ -49,9 +49,9 @@
 /* +s (server notice masks) */
 #include "modes/umode_s.h"
 
-ModeHandler::ModeHandler(Module* Creator, char modeletter, ParamSpec Params, ModeType type)
-       : mode(modeletter), parameters_taken(Params), list(false), m_type(type), m_paramtype(TR_TEXT),
-       oper(false), prefix(0), count(0), levelrequired(HALFOP_VALUE), creator(Creator)
+ModeHandler::ModeHandler(Module* Creator, const std::string& Name, char modeletter, ParamSpec Params, ModeType type)
+       : m_paramtype(TR_TEXT), parameters_taken(Params), mode(modeletter), prefix(0), oper(false),
+       list(false), m_type(type), count(0), levelrequired(HALFOP_VALUE), creator(Creator), name(Name)
 {
 }
 
@@ -188,7 +188,8 @@ ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Chan
        return MODEACTION_DENY;
 }
 
-ModeWatcher::ModeWatcher(char modeletter, ModeType type) : mode(modeletter), m_type(type)
+ModeWatcher::ModeWatcher(Module* Creator, char modeletter, ModeType type)
+       : mode(modeletter), m_type(type), creator(Creator)
 {
 }
 
@@ -338,6 +339,12 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
                return MODEACTION_DENY;
        }
 
+       if (mh->GetTranslateType() == TR_NICK && !ServerInstance->FindNick(parameter))
+       {
+               user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel", user->nick.c_str(), parameter.c_str());
+               return MODEACTION_DENY;
+       }
+
        /* Call the handler for the mode */
        ModeAction ma = mh->OnModeChange(user, targetuser, chan, parameter, adding);
 
@@ -683,6 +690,22 @@ bool ModeParser::DelMode(ModeHandler* mh)
        return true;
 }
 
+void ModeParser::RemoveModes(Module* mod)
+{
+       for(int i=0; i < 256; i++)
+       {
+               ModeHandler* mh = modehandlers[i];
+               if (mh && mh->creator == mod)
+                       DelMode(mh);
+               for(unsigned int j=0; j < modewatchers[i].size(); j++)
+               {
+                       ModeWatcher* mw = modewatchers[i][j];
+                       if (mw && mw->creator == mod)
+                               DelModeWatcher(mw);
+               }
+       }
+}
+
 ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt)
 {
        unsigned char mask = 0;
@@ -958,58 +981,67 @@ void ModeHandler::RemoveMode(Channel* channel, irc::modestacker* stack)
        }
 }
 
-ModeParser::ModeParser()
+struct builtin_modes
 {
-       ModeHandler* modes[] =
+       ModeChannelSecret s;
+       ModeChannelPrivate p;
+       ModeChannelModerated m;
+       ModeChannelTopicOps t;
+
+       ModeChannelNoExternal n;
+       ModeChannelInviteOnly i;
+       ModeChannelKey k;
+       ModeChannelLimit l;
+
+       ModeChannelBan b;
+       ModeChannelOp o;
+       // halfop is added by configreader
+       ModeChannelVoice v;
+
+       ModeUserWallops uw;
+       ModeUserInvisible ui;
+       ModeUserOperator uo;
+       ModeUserServerNoticeMask us;
+
+       void init(ModeParser* modes)
        {
-               new ModeChannelSecret,
-               new ModeChannelPrivate,
-               new ModeChannelModerated,
-               new ModeChannelTopicOps,
-
-               new ModeChannelNoExternal,
-               new ModeChannelInviteOnly,
-               new ModeChannelKey,
-               new ModeChannelLimit,
-
-               new ModeChannelBan,
-               new ModeChannelOp,
-               new ModeChannelHalfOp,
-               new ModeChannelVoice,
+               modes->AddMode(&s);
+               modes->AddMode(&p);
+               modes->AddMode(&m);
+               modes->AddMode(&t);
+               modes->AddMode(&n);
+               modes->AddMode(&i);
+               modes->AddMode(&k);
+               modes->AddMode(&l);
+               modes->AddMode(&b);
+               modes->AddMode(&o);
+               modes->AddMode(&v);
+               modes->AddMode(&uw);
+               modes->AddMode(&ui);
+               modes->AddMode(&uo);
+               modes->AddMode(&us);
+       }
+};
 
-               new ModeUserWallops,
-               new ModeUserInvisible,
-               new ModeUserOperator,
-               new ModeUserServerNoticeMask,
-#define BUILTIN_MODE_COUNT 16
-       };
+static builtin_modes static_modes;
 
+ModeParser::ModeParser()
+{
        /* Clear mode handler list */
        memset(modehandlers, 0, sizeof(modehandlers));
 
        /* Last parse string */
        LastParse.clear();
 
-       /* Initialise the RFC mode letters */
-       for (int index = 0; index < BUILTIN_MODE_COUNT; index++)
-               this->AddMode(modes[index]);
-
        seq = 0;
        memset(&sent, 0, sizeof(sent));
+
+       static_modes.init(this);
 }
 
 ModeParser::~ModeParser()
 {
-       int count = 0;
-       for(int i=0; i < 256; i++)
-       {
-               ModeHandler* mh = modehandlers[i];
-               if (mh && mh->creator == NULL)
-               {
-                       count++;
-                       delete mh;
-               }
-       }
-       if (count != BUILTIN_MODE_COUNT)
-               throw CoreException("Mode handler found non-core modes remaining at deallocation");
+       ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
+       if (mh)
+               delete mh;
 }