]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/cmd_who.cpp
Fixed an issue that could cause empty parameters in module commands to not be sent...
[user/henk/code/inspircd.git] / src / cmd_who.cpp
index de504faf253d12a6a92144ca71732751d64c059e..07370f31eddaa422f7dafc03f68cb8ce54bee1a3 100644 (file)
  * ---------------------------------------------------
  */
 
-#include "configreader.h"
-#include "users.h"
-#include "modules.h"
+#include "inspircd.h"
 #include "wildcard.h"
 #include "commands/cmd_who.h"
 
-/* get the last 'visible' chan of a user */
-static char *getlastchanname(userrec *u)
+static char *get_first_visible_channel(userrec *u)
 {
        UCListIter i = u->chans.begin();
        if (i != u->chans.end())
@@ -110,7 +107,7 @@ bool cmd_who::whomatch(userrec* user, const char* matchtext)
 
 
 
-extern "C" command_t* init_command(InspIRCd* Instance)
+extern "C" DllExport command_t* init_command(InspIRCd* Instance)
 {
        return new cmd_who(Instance);
 }
@@ -120,22 +117,24 @@ bool cmd_who::CanView(chanrec* chan, userrec* user)
        if (!user || !chan)
                return false;
 
-       /* Execute items in fastest-to-execute first order */
-
+       /* Bug #383 - moved higher up the list, because if we are in the channel
+        * we can see all its users
+        */
+       if (chan->HasUser(user))
+               return true;
        /* Opers see all */
        if (IS_OPER(user))
                return true;
+       /* Cant see inside a +s or a +p channel unless we are a member (see above) */
        else if (!chan->IsModeSet('s') && !chan->IsModeSet('p'))
                return true;
-       else if (chan->HasUser(user))
-               return true;
 
        return false;
 }
 
 void cmd_who::SendWhoLine(userrec* user, const std::string &initial, chanrec* ch, userrec* u, std::vector<std::string> &whoresults)
 {
-       std::string lcn = getlastchanname(u);
+       std::string lcn = get_first_visible_channel(u);
        chanrec* chlast = ServerInstance->FindChan(lcn);
 
        /* Not visible to this user */
@@ -193,12 +192,22 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
        std::string initial = "352 " + std::string(user->nick) + " ";
 
        const char* matchtext = NULL;
+       bool usingwildcards = false;
 
        /* Change '0' into '*' so the wildcard matcher can grok it */
        matchtext = parameters[0];
        if (!strcmp(matchtext,"0"))
                matchtext = "*";
 
+       for (const char* check = matchtext; *check; check++)
+       {
+               if (*check == '*' || *check == '?')
+               {
+                       usingwildcards = true;
+                       break;
+               }
+       }
+
        if (pcnt > 1)
        {
                /* parse flags */
@@ -264,13 +273,17 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
        
                        for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
                        {
-                               /* opers only, please */
-                               if (opt_viewopersonly && !IS_OPER(i->first))
-                                       continue;
+                               /* None of this applies if we WHO ourselves */
+                               if (user != i->first)
+                               {
+                                       /* opers only, please */
+                                       if (opt_viewopersonly && !IS_OPER(i->first))
+                                               continue;
        
-                               /* If we're not inside the channel, hide +i users */
-                               if (i->first->IsModeSet('i') && !inside)
-                                       continue;
+                                       /* If we're not inside the channel, hide +i users */
+                                       if (i->first->IsModeSet('i') && !inside)
+                                               continue;
+                               }
        
                                SendWhoLine(user, initial, ch, i->first, whoresults);
                        }
@@ -279,7 +292,6 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
        else
        {
                /* Match against wildcard of nick, server or host */
-
                if (opt_viewopersonly)
                {
                        /* Showing only opers */
@@ -289,8 +301,11 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
 
                                if (whomatch(oper, matchtext))
                                {
-                                       if ((!oper->IsModeSet('i')) && (!IS_OPER(user)))
-                                               continue;
+                                       if (!user->SharesChannelWith(oper))
+                                       {
+                                               if (usingwildcards && (!oper->IsModeSet('i')) && (!IS_OPER(user)))
+                                                       continue;
+                                       }
 
                                        SendWhoLine(user, initial, NULL, oper, whoresults);
                                }
@@ -302,8 +317,11 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
                        {
                                if (whomatch(i->second, matchtext))
                                {
-                                       if ((i->second->IsModeSet('i')) && (!IS_OPER(user)))
-                                               continue;
+                                       if (!user->SharesChannelWith(i->second))
+                                       {
+                                               if (usingwildcards && (i->second->IsModeSet('i')) && (!IS_OPER(user)))
+                                                       continue;
+                                       }
 
                                        SendWhoLine(user, initial, NULL, i->second, whoresults);
                                }
@@ -311,7 +329,7 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
                }
        }
        /* Send the results out */
-       if ((whoresults.size() <= (size_t)ServerInstance->Config->MaxWhoResults) || opt_unlimit)
+       if ((ServerInstance->Config->MaxWhoResults && (whoresults.size() <= (size_t)ServerInstance->Config->MaxWhoResults)) || opt_unlimit)
        {
                for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++)
                        user->WriteServ(*n);
@@ -325,3 +343,4 @@ CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
                return CMD_FAILURE;
        }
 }
+