diff options
Diffstat (limited to 'src/commands/cmd_who.cpp')
-rw-r--r-- | src/commands/cmd_who.cpp | 90 |
1 files changed, 41 insertions, 49 deletions
diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp index f8926b9f7..a059a3f9c 100644 --- a/src/commands/cmd_who.cpp +++ b/src/commands/cmd_who.cpp @@ -39,13 +39,34 @@ class CommandWho : public Command bool opt_local; bool opt_far; bool opt_time; + ChanModeReference secretmode; + ChanModeReference privatemode; + UserModeReference invisiblemode; + + Channel* get_first_visible_channel(User *u) + { + UCListIter i = u->chans.begin(); + while (i != u->chans.end()) + { + Channel* c = *i++; + if (!c->IsModeSet(secretmode)) + return c; + } + return NULL; + } public: /** Constructor for who. */ - CommandWho ( Module* parent) : Command(parent,"WHO", 1) { + CommandWho(Module* parent) + : Command(parent, "WHO", 1) + , secretmode(parent, "secret") + , privatemode(parent, "private") + , invisiblemode(parent, "invisible") + { syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]"; } + void SendWhoLine(User* user, const std::vector<std::string>& parms, const std::string &initial, Channel* ch, User* u, std::vector<std::string> &whoresults); /** Handle command. * @param parameters The parameters to the comamnd @@ -57,19 +78,6 @@ class CommandWho : public Command bool whomatch(User* cuser, User* user, const char* matchtext); }; - -static Channel* get_first_visible_channel(User *u) -{ - UCListIter i = u->chans.begin(); - while (i != u->chans.end()) - { - Channel* c = *i++; - if (!c->IsModeSet('s')) - return c; - } - return NULL; -} - bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext) { bool match = false; @@ -138,7 +146,7 @@ bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext) match = InspIRCd::Match(user->awaymsg, matchtext); else if (opt_time) { - long seconds = ServerInstance->Duration(matchtext); + long seconds = InspIRCd::Duration(matchtext); // Okay, so time matching, we want all users connected `seconds' ago if (user->age >= ServerInstance->Time() - seconds) @@ -160,7 +168,7 @@ bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext) /* Don't allow server name matches if HideWhoisServer is enabled, unless the command user has the priv */ if (!match && (ServerInstance->Config->HideWhoisServer.empty() || cuser->HasPrivPermission("users/auspex"))) - match = InspIRCd::Match(user->server, matchtext); + match = InspIRCd::Match(user->server->GetName(), matchtext); return match; } @@ -180,7 +188,7 @@ bool CommandWho::CanView(Channel* chan, User* user) if (user->HasPrivPermission("users/auspex")) 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')) + else if (!chan->IsModeSet(secretmode) && !chan->IsModeSet(privatemode)) return true; return false; @@ -196,12 +204,12 @@ void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, if (!ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex")) wholine.append(ServerInstance->Config->HideWhoisServer); else - wholine.append(u->server); - + wholine.append(u->server->GetName()); + wholine.append(" " + u->nick + " "); /* away? */ - if (IS_AWAY(u)) + if (u->IsAway()) { wholine.append("G"); } @@ -211,7 +219,7 @@ void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, } /* oper? */ - if (IS_OPER(u)) + if (u->IsOper()) { wholine.push_back('*'); } @@ -221,7 +229,7 @@ void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, wholine.append(" :0 " + u->fullname); - FOREACH_MOD(I_OnSendWhoLine, OnSendWhoLine(user, parms, u, wholine)); + FOREACH_MOD(OnSendWhoLine, (user, parms, u, wholine)); if (!wholine.empty()) whoresults.push_back(wholine); @@ -249,33 +257,17 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * opt_far = false; opt_time = false; - Channel *ch = NULL; std::vector<std::string> whoresults; std::string initial = "352 " + user->nick + " "; - char matchtext[MAXBUF]; - bool usingwildcards = false; - /* Change '0' into '*' so the wildcard matcher can grok it */ - if (parameters[0] == "0") - strlcpy(matchtext, "*", MAXBUF); - else - strlcpy(matchtext, parameters[0].c_str(), MAXBUF); + std::string matchtext = ((parameters[0] == "0") ? "*" : parameters[0]); - for (const char* check = matchtext; *check; check++) - { - if (*check == '*' || *check == '?' || *check == '.') - { - usingwildcards = true; - break; - } - } + // WHO flags count as a wildcard + bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?.") != std::string::npos)); if (parameters.size() > 1) { - /* Fix for bug #444, WHO flags count as a wildcard */ - usingwildcards = true; - for (std::string::const_iterator iter = parameters[1].begin(); iter != parameters[1].end(); ++iter) { switch (*iter) @@ -325,7 +317,7 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * /* who on a channel? */ - ch = ServerInstance->FindChan(matchtext); + Channel* ch = ServerInstance->FindChan(matchtext); if (ch) { @@ -342,11 +334,11 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * if (user != i->first) { /* opers only, please */ - if (opt_viewopersonly && !IS_OPER(i->first)) + if (opt_viewopersonly && !i->first->IsOper()) continue; /* If we're not inside the channel, hide +i users */ - if (i->first->IsModeSet('i') && !inside && !user->HasPrivPermission("users/auspex")) + if (i->first->IsModeSet(invisiblemode) && !inside && !user->HasPrivPermission("users/auspex")) continue; } @@ -364,11 +356,11 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * { User* oper = *i; - if (whomatch(user, oper, matchtext)) + if (whomatch(user, oper, matchtext.c_str())) { if (!user->SharesChannelWith(oper)) { - if (usingwildcards && (!oper->IsModeSet('i')) && (!user->HasPrivPermission("users/auspex"))) + if (usingwildcards && (!oper->IsModeSet(invisiblemode)) && (!user->HasPrivPermission("users/auspex"))) continue; } @@ -380,11 +372,11 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * { for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++) { - if (whomatch(user, i->second, matchtext)) + if (whomatch(user, i->second, matchtext.c_str())) { if (!user->SharesChannelWith(i->second)) { - if (usingwildcards && (i->second->IsModeSet('i')) && (!user->HasPrivPermission("users/auspex"))) + if (usingwildcards && (i->second->IsModeSet(invisiblemode)) && (!user->HasPrivPermission("users/auspex"))) continue; } @@ -396,7 +388,7 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * /* Send the results out */ for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++) user->WriteServ(*n); - user->WriteNumeric(315, "%s %s :End of /WHO list.",user->nick.c_str(), *parameters[0].c_str() ? parameters[0].c_str() : "*"); + user->WriteNumeric(RPL_ENDOFWHO, "%s :End of /WHO list.", *parameters[0].c_str() ? parameters[0].c_str() : "*"); // Penalize the user a bit for large queries // (add one unit of penalty per 200 results) |