]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/cmd_who.cpp
Stability fix
[user/henk/code/inspircd.git] / src / cmd_who.cpp
index 06c99ac60df27b5467f009bb87ecfedcbb88c151..01c7bfff5900f2cb1abf1eb5ad5e35d20c54e45c 100644 (file)
@@ -1,15 +1,15 @@
-/*       +------------------------------------+
- *       | Inspire Internet Relay Chat Daemon |
- *       +------------------------------------+
+/*   +------------------------------------+
+ *   | Inspire Internet Relay Chat Daemon |
+ *   +------------------------------------+
  *
  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- *                       E-mail:
- *                <brain@chatspike.net>
- *                <Craig@chatspike.net>
+ *   E-mail:
+ *<brain@chatspike.net>
+ *<Craig@chatspike.net>
  *
  * Written by Craig Edwards, Craig McLure, and others.
  * This program is free but copyrighted software; see
- *            the file COPYING for details.
+ *the file COPYING for details.
  *
  * ---------------------------------------------------
  */
@@ -46,6 +46,13 @@ static char *getlastchanname(userrec *u)
 
 void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
 {
+       /*
+        * XXX - RFC says:
+        *   The <name> passed to WHO is matched against users' host, server, real
+        *   name and nickname
+        * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
+        */
+
        bool opt_viewopersonly = false;
        chanrec *ch = NULL;
        std::vector<std::string> whoresults;
@@ -85,6 +92,7 @@ void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
                                continue;
 
 
+                       /* XXX - code duplication; this could be more efficient -- w00t */
                        std::string wholine = initial;
 
                        wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
@@ -113,142 +121,101 @@ void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
        else
        {
                /* uhggle. who on .. something else. */
+               userrec *u = Find(parameters[0]);
 
-//   The <name> passed to WHO is matched against users' host, server, real
-//   name and nickname
-
-       }
-
-
-       return;
+               if (u)
+               {
+                       /* who on a single user */
+                       std::string wholine = initial;
 
+                       wholine = wholine + getlastchanname(u) + " " + u->ident + " " + u->dhost + " " + 
+                                       u->server + " " + u->nick + " ";
 
+                       /* away? */
+                       if (*u->awaymsg)
+                       {
+                               wholine.append("G");
+                       }
+                       else
+                       {
+                               wholine.append("H");
+                       }
 
+                       /* oper? */
+                       if (*u->oper)
+                       {
+                               wholine.append("*");
+                       }
 
+                       wholine = wholine + cmode(u, ch) + " :0 " + u->fullname;
+                       whoresults.push_back(wholine);
+               }
 
+               if (*parameters[0] == '*' || *parameters[0] == '0')
+               {
+                       if (!opt_viewopersonly && !*user->oper)
+                               return; /* No way, jose */
 
+                       if (opt_viewopersonly)
+                       {
+                               for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
+                               {
+                                       userrec* oper = (userrec*)*i;
 
+                                       std::string wholine = initial;
 
+                                       wholine = wholine + getlastchanname(oper) + " " + oper->ident + " " + oper->dhost + " " + 
+                                                       oper->server + " " + oper->nick + " ";
 
+                                       /* away? */
+                                       if (*oper->awaymsg)
+                                       {
+                                               wholine.append("G");
+                                       }
+                                       else
+                                       {
+                                               wholine.append("H");
+                                       }
 
-       chanrec* Ptr = NULL;
-       char tmp[10];
-       
-       if (pcnt == 1)
-       {
-               if ((IS_SINGLE(parameters[0],'0')) || (IS_SINGLE(parameters[0],'*')))
-               {
-                       if ((user->chans.size()) && (((ucrec*)*(user->chans.begin()))->channel))
-                       {
-                               int n_list = 0;
-                               for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
-                               {
-                                       Ptr = ((ucrec*)*(i->second->chans.begin()))->channel;
-                                       // suggested by phidjit and FCS
-                                       if ((!common_channels(user,i->second)) && (isnick(i->second->nick)))
+                                       /* oper? */
+                                       if (*oper->oper)
                                        {
-                                               // Bug Fix #29
-                                               *tmp = 0;
-                                               if (*i->second->awaymsg) {
-                                                       charlcat(tmp, 'G', 9);
-                                               } else {
-                                                       charlcat(tmp, 'H', 9);
-                                               }
-                                               if (*i->second->oper) { charlcat(tmp, '*', 9); }
-                                               WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr ? Ptr->name : "*", i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
-                                               if (n_list++ > Config->MaxWhoResults)
-                                               {
-                                                       WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
-                                                       break;
-                                               }
+                                               wholine.append("*");
                                        }
+
+                                       wholine = wholine + cmode(oper, ch) + " :0 " + oper->fullname;
+                                       whoresults.push_back(wholine);
                                }
                        }
-                       if (Ptr)
-                       {
-                               WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick , parameters[0]);
-                       }
                        else
                        {
-                               WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
-                       }
-                       return;
-               }
-               if (parameters[0][0] == '#')
-               {
-                       Ptr = FindChan(parameters[0]);
-                       if (Ptr)
-                       {
-                               int n_list = 0;
-                               for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+                               for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
                                {
-                                       if ((Ptr->HasUser(i->second)) && (isnick(i->second->nick)))
+                                       std::string wholine = initial;
+
+                                       wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
+                                                       i->second->server + " " + i->second->nick + " ";
+
+                                       /* away? */
+                                       if (*(i->second)->awaymsg)
+                                       {
+                                               wholine.append("G");
+                                       }
+                                       else
                                        {
-                                               // Fix Bug #29 - Part 2..
-                                               *tmp = 0;
-                                               if (*i->second->awaymsg) {
-                                                       charlcat(tmp, 'G', 9);
-                                               } else {
-                                                       charlcat(tmp, 'H', 9);
-                                               }
-                                               if (*i->second->oper) { charlcat(tmp, '*', 9); }
-                                               strlcat(tmp, cmode(i->second, Ptr),5);
-                                               WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr->name, i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
-                                               n_list++;
-                                               if (n_list > Config->MaxWhoResults)
-                                               {
-                                                       WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
-                                                       break;
-                                               }
+                                               wholine.append("H");
+                                       }
 
+                                       /* oper? */
+                                       if (*(i->second)->oper)
+                                       {
+                                               wholine.append("*");
                                        }
+
+                                       wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
+                                       whoresults.push_back(wholine);
                                }
-                               WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
-                       }
-                       else
-                       {
-                               WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
-                       }
-               }
-               else
-               {
-                       userrec* u = Find(parameters[0]);
-                       if (u)
-                       {
-                               // Bug Fix #29 -- Part 29..
-                               *tmp = 0;
-                               if (*u->awaymsg) {
-                                       charlcat(tmp, 'G' ,9);
-                               } else {
-                                       charlcat(tmp, 'H' ,9);
-                               }
-                               if (*u->oper) { charlcat(tmp, '*' ,9); }
-                               WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->chans.size() && ((ucrec*)*(u->chans.begin()))->channel ? ((ucrec*)*(u->chans.begin()))->channel->name
-                               : "*", u->ident, u->dhost, u->server, u->nick, tmp, u->fullname);
-                       }
-                       WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
-               }
-       }
-       if (pcnt == 2)
-       {
-               if ((IS_SINGLE(parameters[0],'0')) || (IS_SINGLE(parameters[0],'*')) && (IS_SINGLE(parameters[1],'o')))
-               {
-                       for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
-                       {
-                               // If i were a rich man.. I wouldn't need to me making these bugfixes..
-                               // But i'm a poor bastard with nothing better to do.
-                               userrec* oper = *i;
-                               *tmp = 0;
-                               if (*oper->awaymsg) {
-                                       charlcat(tmp, 'G' ,9);
-                               } else {
-                                       charlcat(tmp, 'H' ,9);
-                               }
-                               WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s", user->nick, oper->chans.size() && ((ucrec*)*(oper->chans.begin()))->channel ? ((ucrec*)*(oper->chans.begin()))->channel->name
-                               : "*", oper->ident, oper->dhost, oper->server, oper->nick, tmp, oper->fullname);
                        }
-                       WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
-                       return;
                }
        }
 }