]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Merge pull request #1162 from SaberUK/insp20+fix-deinstall
[user/henk/code/inspircd.git] / src / mode.cpp
index 21c9e7144884d7edb23f403e896d6dda4cc04b36..89ff37fa1e7fd0b709bd411c220abdf15cf6b1f4 100644 (file)
@@ -346,10 +346,19 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
                return MODEACTION_DENY;
        }
 
-       if (mh->GetTranslateType() == TR_NICK && !ServerInstance->FindNick(parameter))
+       if (mh->GetTranslateType() == TR_NICK)
        {
-               user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel", user->nick.c_str(), parameter.c_str());
-               return MODEACTION_DENY;
+               User* prefixtarget;
+               if (IS_LOCAL(user))
+                       prefixtarget = ServerInstance->FindNickOnly(parameter);
+               else
+                       prefixtarget = ServerInstance->FindNick(parameter);
+
+               if (!prefixtarget)
+               {
+                       user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel", user->nick.c_str(), parameter.c_str());
+                       return MODEACTION_DENY;
+               }
        }
 
        if (mh->GetPrefixRank() && chan)
@@ -378,16 +387,23 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
 
 void ModeParser::Process(const std::vector<std::string>& parameters, User *user, bool merge)
 {
-       std::string target = parameters[0];
+       const std::string& target = parameters[0];
        Channel* targetchannel = ServerInstance->FindChan(target);
-       User* targetuser  = ServerInstance->FindNick(target);
+       User* targetuser = NULL;
+       if (!targetchannel)
+       {
+               if (IS_LOCAL(user))
+                       targetuser = ServerInstance->FindNickOnly(target);
+               else
+                       targetuser = ServerInstance->FindNick(target);
+       }
        ModeType type = targetchannel ? MODETYPE_CHANNEL : MODETYPE_USER;
 
        LastParse.clear();
        LastParseParams.clear();
        LastParseTranslate.clear();
 
-       if (!targetchannel && !targetuser)
+       if ((!targetchannel) && ((!targetuser) || (IS_SERVER(targetuser))))
        {
                user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(),target.c_str());
                return;
@@ -442,7 +458,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                        continue;
                }
 
-               std::string parameter = "";
+               std::string parameter;
                int pcnt = mh->GetNumParams(adding);
                if (pcnt && param_at == parameters.size())
                {
@@ -454,7 +470,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
                {
                        parameter = parameters[param_at++];
                        /* Make sure the user isn't trying to slip in an invalid parameter */
-                       if ((parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos))
+                       if ((parameter.empty()) || (parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos))
                                continue;
                        if (merge && targetchannel && targetchannel->IsModeSet(modechar) && !mh->IsListMode())
                        {
@@ -675,15 +691,20 @@ bool ModeParser::DelMode(ModeHandler* mh)
        switch (mh->GetModeType())
        {
                case MODETYPE_USER:
-                       for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++)
+                       for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); )
                        {
-                               mh->RemoveMode(i->second);
+                               User* user = i->second;
+                               ++i;
+                               mh->RemoveMode(user);
                        }
                break;
                case MODETYPE_CHANNEL:
-                       for (chan_hash::iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
+                       for (chan_hash::iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); )
                        {
-                               mh->RemoveMode(i->second);
+                               // The channel may not be in the hash after RemoveMode(), see m_permchannels
+                               Channel* chan = i->second;
+                               ++i;
+                               mh->RemoveMode(chan);
                        }
                break;
        }
@@ -875,7 +896,7 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw)
        mw->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
        pos = (mw->GetModeChar()-65) | mask;
 
-       ModeWatchIter a = find(modewatchers[pos].begin(),modewatchers[pos].end(),mw);
+       ModeWatchIter a = std::find(modewatchers[pos].begin(),modewatchers[pos].end(),mw);
 
        if (a == modewatchers[pos].end())
        {