]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/mode.cpp
Same again
[user/henk/code/inspircd.git] / src / mode.cpp
index f74a2ac603afd05a3f90be5bff123c9c0d147baf..ea51ce71dec18367e64bb103726d4ce02a0a010f 100644 (file)
@@ -244,16 +244,23 @@ void ModeParser::DisplayCurrentModes(userrec *user, userrec* targetuser, chanrec
        {
                /* Display channel's current mode string */
                user->WriteServ("324 %s %s +%s",user->nick, targetchannel->name, targetchannel->ChanModes(targetchannel->HasUser(user)));
-               user->WriteServ("329 %s %s %d", user->nick, targetchannel->name, targetchannel->created);
+               user->WriteServ("329 %s %s %lu", user->nick, targetchannel->name, (unsigned long)targetchannel->age);
                return;
        }
        else if (targetuser)
        {
-               /* Display user's current mode string */
-               user->WriteServ("221 %s :+%s",targetuser->nick,targetuser->FormatModes());
-               if (*targetuser->oper)
-                       user->WriteServ("008 %s +%s :Server notice mask", targetuser->nick, targetuser->FormatNoticeMasks());
-               return;
+               if ((targetuser == user) || (*user->oper))
+               {
+                       /* Display user's current mode string */
+                       user->WriteServ("221 %s :+%s",targetuser->nick,targetuser->FormatModes());
+                       if (*targetuser->oper)
+                               user->WriteServ("008 %s +%s :Server notice mask", targetuser->nick, targetuser->FormatNoticeMasks());
+                       return;
+               }
+               else
+               {
+                       user->WriteServ("502 %s :Can't change mode for other users", user->nick);
+               }
        }
 
        /* No such nick/channel */
@@ -269,7 +276,11 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
        chanrec* targetchannel = ServerInstance->FindChan(parameters[0]);
        userrec* targetuser  = ServerInstance->FindNick(parameters[0]);
 
-       ServerInstance->Log(DEBUG,"ModeParser::Process start");
+       ServerInstance->Log(DEBUG,"ModeParser::Process start: pcnt=%d",pcnt);
+       for (int j = 0; j < pcnt; j++)
+               ServerInstance->Log(DEBUG,"    parameters[%d] = '%s'", j, parameters[j]);
+
+       LastParse = "";
 
        /* Special case for displaying the list for listmodes,
         * e.g. MODE #chan b, or MODE #chan +b without a parameter
@@ -336,6 +347,11 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
                {
                        type = MODETYPE_USER;
                        mask = MASK_USER;
+                       if ((user != targetuser) && (!ServerInstance->ULine(user->server)))
+                       {
+                               user->WriteServ("502 %s :Can't change mode for other users", user->nick);
+                               return;
+                       }
                }
                else
                {
@@ -416,6 +432,7 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
                                                                /* This mode expects a parameter, do we have any parameters left in our list to use? */
                                                                if (parameter_counter < pcnt)
                                                                {
+                                                                       ServerInstance->Log(DEBUG,"parameter_counter = %d, pcnt = %d", parameter_counter, pcnt);
                                                                        parameter = parameters[parameter_counter++];
 
                                                                        /* Yerk, invalid! */
@@ -509,10 +526,12 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
                                if (type == MODETYPE_CHANNEL)
                                {
                                        targetchannel->WriteChannelWithServ(ServerInstance->Config->ServerName, "MODE %s %s%s", targetchannel->name, output_sequence.c_str(), parameter_list.str().c_str());
+                                       this->LastParse = targetchannel->name;
                                }
                                else
                                {
                                        targetuser->WriteServ("MODE %s %s%s",targetuser->nick,output_sequence.c_str(), parameter_list.str().c_str());
+                                       this->LastParse = targetuser->nick;
                                }
                        }
                        else
@@ -522,17 +541,28 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
                                        ServerInstance->Log(DEBUG,"Write output sequence and parameters to channel: %s %s%s",targetchannel->name,output_sequence.c_str(),parameter_list.str().c_str());
                                        targetchannel->WriteChannel(user,"MODE %s %s%s",targetchannel->name,output_sequence.c_str(),parameter_list.str().c_str());
                                        FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str()));
+                                       this->LastParse = targetchannel->name;
                                }
                                else
                                {
                                        user->WriteTo(targetuser,"MODE %s %s%s",targetuser->nick,output_sequence.c_str(), parameter_list.str().c_str());
-                                       FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence));
+                                       FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence + parameter_list.str()));
+                                       this->LastParse = targetuser->nick;
                                }
                        }
+
+                       LastParse.append(" ");
+                       LastParse.append(output_sequence);
+                       LastParse.append(parameter_list.str());
                }
        }
 }
 
+const std::string& ModeParser::GetLastParse()
+{
+       return LastParse;
+}
+
 void ModeParser::CleanMask(std::string &mask)
 {
        std::string::size_type pos_of_pling = mask.find_first_of('!');
@@ -580,8 +610,9 @@ bool ModeParser::AddMode(ModeHandler* mh, unsigned const char modeletter)
 
        /* A mode prefix of ',' is not acceptable, it would fuck up server to server.
         * A mode prefix of ':' will fuck up both server to server, and client to server.
+        * A mode prefix of '#' will mess up /whois and /privmsg
         */
-       if ((mh->GetPrefix() == ',') || (mh->GetPrefix() == ':'))
+       if ((mh->GetPrefix() == ',') || (mh->GetPrefix() == ':') || (mh->GetPrefix() == '#'))
                return false;
 
        mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
@@ -711,6 +742,9 @@ std::string ModeParser::ModeString(userrec* user, chanrec* channel)
        std::string types;
        std::string pars;
 
+       if (!channel || !user)
+               return "";
+
        for (unsigned char mode = 'A'; mode <= 'z'; mode++)
        {
                unsigned char pos = (mode-65) | MASK_CHANNEL;
@@ -719,7 +753,7 @@ std::string ModeParser::ModeString(userrec* user, chanrec* channel)
                {
                        ModePair ret;
                        ret = mh->ModeSet(NULL, user, channel, user->nick);
-                       if (ret.first)
+                       if ((ret.first) && (ret.second == user->nick))
                        {
                                pars.append(" ");
                                pars.append(user->nick);
@@ -841,7 +875,7 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw)
        if (!mw)
                return false;
 
-       if ((mw->GetModeType() < 'A') || (mw->GetModeType() > 'z'))
+       if ((mw->GetModeChar() < 'A') || (mw->GetModeChar() > 'z'))
                return false;
 
        mw->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
@@ -850,7 +884,10 @@ bool ModeParser::DelModeWatcher(ModeWatcher* mw)
        ModeWatchIter a = find(modewatchers[pos].begin(),modewatchers[pos].end(),mw);
 
        if (a == modewatchers[pos].end())
+       {
+               ServerInstance->Log(DEBUG, "ModeParser::DelModeWatcher: Couldn't find watcher for mode %c in list", mw->GetModeChar());
                return false;
+       }
 
        modewatchers[pos].erase(a);
        ServerInstance->Log(DEBUG,"ModeParser::DelModeWatcher: stopped watching mode %c",mw->GetModeChar());
@@ -867,14 +904,8 @@ void ModeHandler::RemoveMode(userrec* user)
 
        if (user->IsModeSet(this->GetModeChar()))
        {
-               userrec* n = new userrec(ServerInstance);
-
                sprintf(moderemove,"-%c",this->GetModeChar());
-               n->SetFd(FD_MAGIC_NUMBER);
-
-               ServerInstance->SendMode(parameters, 2, n);
-
-               delete n;
+               ServerInstance->Parser->CallHandler("MODE", parameters, 2, user);
        }
 }
 
@@ -905,6 +936,9 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
        memset(modehandlers, 0, sizeof(modehandlers));
        memset(modewatchers, 0, sizeof(modewatchers));
 
+       /* Last parse string */
+       LastParse = "";
+
        /* Initialise the RFC mode letters */
 
        /* Start with channel simple modes, no params */
@@ -932,4 +966,3 @@ ModeParser::ModeParser(InspIRCd* Instance) : ServerInstance(Instance)
        this->AddMode(new ModeUserOperator(Instance), 'o');
        this->AddMode(new ModeUserServerNoticeMask(Instance), 'n');
 }
-