* +------------------------------------+
*
* InspIRCd: (C) 2002-2009 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
*/
#include "inspircd.h"
-#include "commands/cmd_who.h"
+
+/** Handle /WHO. These command handlers can be reloaded by the core,
+ * and handle basic RFC1459 commands. Commands within modules work
+ * the same way, however, they can be fully unloaded, where these
+ * may not.
+ */
+class CommandWho : public Command
+{
+ bool CanView(Channel* chan, User* user);
+ bool opt_viewopersonly;
+ bool opt_showrealhost;
+ bool opt_unlimit;
+ bool opt_realname;
+ bool opt_mode;
+ bool opt_ident;
+ bool opt_metadata;
+ bool opt_port;
+ bool opt_away;
+ bool opt_local;
+ bool opt_far;
+ bool opt_time;
+
+ public:
+ /** Constructor for who.
+ */
+ CommandWho (InspIRCd* Instance, Module* parent) : Command(Instance,parent,"WHO", 0, 1, false, 2) { syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]"; }
+ void SendWhoLine(User* user, const std::string &initial, Channel* ch, User* u, std::vector<std::string> &whoresults);
+ /** Handle command.
+ * @param parameters The parameters to the comamnd
+ * @param pcnt The number of parameters passed to teh command
+ * @param user The user issuing the command
+ * @return A value from CmdResult to indicate command success or failure.
+ */
+ CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+ bool whomatch(User* cuser, User* user, const char* matchtext);
+};
+
static const std::string star = "*";
static const std::string& get_first_visible_channel(User *u)
{
UCListIter i = u->chans.begin();
- if (i != u->chans.end())
+ while (i != u->chans.end())
{
- if (!i->first->IsModeSet('s'))
- return i->first->name;
+ Channel* c = *i++;
+ if (!c->IsModeSet('s'))
+ return c->name;
}
return star;
}
-bool CommandWho::whomatch(User* user, const char* matchtext)
+bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext)
{
bool match = false;
bool positive = false;
- char* dummy = NULL;
if (user->registered != REG_ALL)
return false;
* -- w00t
*/
if (opt_metadata)
- match = user->GetExt(matchtext, dummy);
+ match = user->GetExtList().find(matchtext) != user->GetExtList().end();
else if (opt_realname)
match = InspIRCd::Match(user->fullname, matchtext);
else if (opt_showrealhost)
irc::portparser portrange(matchtext, false);
long portno = -1;
while ((portno = portrange.GetToken()))
- if (portno == user->GetPort())
+ if (portno == user->GetServerPort())
{
match = true;
break;
if (!match)
match = InspIRCd::Match(user->nick, matchtext);
- if (!match)
+ /* Don't allow server name matches if HideWhoisServer is enabled, unless the command user has the priv */
+ if (!match && (!*ServerInstance->Config->HideWhoisServer || cuser->HasPrivPermission("users/auspex")))
match = InspIRCd::Match(user->server, matchtext);
return match;
-extern "C" DllExport Command* init_command(InspIRCd* Instance)
-{
- return new CommandWho(Instance);
-}
-
bool CommandWho::CanView(Channel* chan, User* user)
{
if (!user || !chan)
void CommandWho::SendWhoLine(User* user, const std::string &initial, Channel* ch, User* u, std::vector<std::string> &whoresults)
{
- /* Not visible to this user */
- if (u->Visibility && !u->Visibility->VisibleTo(user))
- return;
-
const std::string& lcn = get_first_visible_channel(u);
Channel* chlast = ServerInstance->FindChan(lcn);
}
wholine = wholine + (ch ? ch->GetPrefixChar(u) : (chlast ? chlast->GetPrefixChar(u) : "")) + " :0 " + u->fullname;
- whoresults.push_back(wholine);
+
+ FOREACH_MOD(I_OnSendWhoLine, OnSendWhoLine(user, u, ch, wholine));
+
+ if (!wholine.empty())
+ whoresults.push_back(wholine);
}
CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User *user)
bool inside = ch->HasUser(user);
/* who on a channel. */
- CUList *cu = ch->GetUsers();
+ const UserMembList *cu = ch->GetUsers();
- for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
+ for (UserMembCIter i = cu->begin(); i != cu->end(); i++)
{
/* None of this applies if we WHO ourselves */
if (user != i->first)
{
User* oper = *i;
- if (whomatch(oper, matchtext))
+ if (whomatch(user, oper, matchtext))
{
if (!user->SharesChannelWith(oper))
{
{
for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++)
{
- if (whomatch(i->second, matchtext))
+ if (whomatch(user, i->second, matchtext))
{
if (!user->SharesChannelWith(i->second))
{
return CMD_FAILURE;
}
}
+
+COMMAND_INIT(CommandWho)