X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=89ff37fa1e7fd0b709bd411c220abdf15cf6b1f4;hb=4c751dbbe8945e5efc230a59b0ed51c2ba10cf92;hp=0957184b7c05a2700254829bbab273f248061092;hpb=2d2e0469b8ac7c64c9dc22f7074db8fc245e2f13;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index 0957184b7..89ff37fa1 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -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& 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; @@ -454,7 +470,7 @@ void ModeParser::Process(const std::vector& 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()) {