diff options
-rw-r--r-- | include/inspircd.h | 4 | ||||
-rw-r--r-- | include/users.h | 14 | ||||
-rw-r--r-- | src/commands/cmd_whois.cpp | 165 | ||||
-rw-r--r-- | src/modules/m_spanningtree/idle.cpp | 8 | ||||
-rw-r--r-- | src/users.cpp | 55 | ||||
-rw-r--r-- | src/whois.cpp | 97 |
6 files changed, 154 insertions, 189 deletions
diff --git a/include/inspircd.h b/include/inspircd.h index fa00902a4..df2ad1095 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -796,10 +796,6 @@ class CoreExport InspIRCd */ void SendWhoisLine(User* user, User* dest, int numeric, const char* format, ...) CUSTOM_PRINTF(5, 6); - /** Handle /WHOIS - */ - void DoWhois(User* user, User* dest,unsigned long signon, unsigned long idle, const char* nick); - /** Called to check whether a channel restriction mode applies to a user * @param User that is attempting some action * @param Channel that the action is being performed on diff --git a/include/users.h b/include/users.h index b9807a158..2cebc749d 100644 --- a/include/users.h +++ b/include/users.h @@ -657,20 +657,6 @@ class CoreExport User : public Extensible */ void SendAll(const char* command, const char* text, ...) CUSTOM_PRINTF(3, 4); - /** Compile a channel list for this user. Used internally by WHOIS - * @param source The user to prepare the channel list for - * @param spy Whether to return the spy channel list rather than the normal one - * @return This user's channel list - */ - std::string ChannelList(User* source, bool spy); - - /** Split the channel list in cl which came from dest, and spool it to this user - * Used internally by WHOIS - * @param dest The user the original channel list came from - * @param cl The channel list as a string obtained from User::ChannelList() - */ - void SplitChanList(User* dest, const std::string &cl); - /** Remove this user from all channels they are on, and delete any that are now empty. * This is used by QUIT, and will not send part messages! */ diff --git a/src/commands/cmd_whois.cpp b/src/commands/cmd_whois.cpp index 3a07fce7b..072e04769 100644 --- a/src/commands/cmd_whois.cpp +++ b/src/commands/cmd_whois.cpp @@ -26,23 +26,170 @@ * the same way, however, they can be fully unloaded, where these * may not. */ -class CommandWhois : public Command +class CommandWhois : public SplitCommand { + void SplitChanList(User* source, User* dest, const std::string& cl); + void DoWhois(User* user, User* dest, unsigned long signon, unsigned long idle); + std::string ChannelList(User* source, User* dest, bool spy); + public: /** Constructor for whois. */ - CommandWhois ( Module* parent) : Command(parent,"WHOIS",1) { Penalty = 2; syntax = "<nick>{,<nick>}"; } + CommandWhois ( Module* parent) : SplitCommand(parent,"WHOIS", 1) { Penalty = 2; syntax = "<nick>{,<nick>}"; } /** 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); + CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user); + CmdResult HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target); }; +std::string CommandWhois::ChannelList(User* source, User* dest, bool spy) +{ + std::string list; + + for (UCListIter i = dest->chans.begin(); i != dest->chans.end(); i++) + { + Channel* c = *i; + /* If the target is the sender, neither +p nor +s is set, or + * the channel contains the user, it is not a spy channel + */ + if (spy != (source == dest || !(c->IsModeSet('p') || c->IsModeSet('s')) || c->HasUser(source))) + list.append(c->GetPrefixChar(dest)).append(c->name).append(" "); + } + + return list; +} -CmdResult CommandWhois::Handle (const std::vector<std::string>& parameters, User *user) +void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl) +{ + std::string line; + std::ostringstream prefix; + std::string::size_type start, pos, length; + + prefix << source->nick << " " << dest->nick << " :"; + line = prefix.str(); + int namelen = ServerInstance->Config->ServerName.length() + 6; + + for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1) + { + length = (pos == std::string::npos) ? cl.length() : pos; + + if (line.length() + namelen + length - start > 510) + { + ServerInstance->SendWhoisLine(source, dest, 319, "%s", line.c_str()); + line = prefix.str(); + } + + if(pos == std::string::npos) + { + line.append(cl.substr(start, length - start)); + break; + } + else + { + line.append(cl.substr(start, length - start + 1)); + } + } + + if (line.length() != prefix.str().length()) + { + ServerInstance->SendWhoisLine(source, dest, 319, "%s", line.c_str()); + } +} + +void CommandWhois::DoWhois(User* user, User* dest, unsigned long signon, unsigned long idle) +{ + ServerInstance->SendWhoisLine(user, dest, 311, "%s %s %s %s * :%s",user->nick.c_str(), dest->nick.c_str(), dest->ident.c_str(), dest->dhost.c_str(), dest->fullname.c_str()); + if (user == dest || user->HasPrivPermission("users/auspex")) + { + ServerInstance->SendWhoisLine(user, dest, 378, "%s %s :is connecting from %s@%s %s", user->nick.c_str(), dest->nick.c_str(), dest->ident.c_str(), dest->host.c_str(), dest->GetIPString().c_str()); + } + + std::string cl = ChannelList(user, dest, false); + const ServerConfig::OperSpyWhoisState state = user->HasPrivPermission("users/auspex") ? ServerInstance->Config->OperSpyWhois : ServerConfig::SPYWHOIS_NONE; + + if (state == ServerConfig::SPYWHOIS_SINGLEMSG) + cl.append(ChannelList(user, dest, true)); + + SplitChanList(user, dest, cl); + + if (state == ServerConfig::SPYWHOIS_SPLITMSG) + { + std::string scl = ChannelList(user, dest, true); + if (scl.length()) + { + ServerInstance->SendWhoisLine(user, dest, 336, "%s %s :is on private/secret channels:",user->nick.c_str(), dest->nick.c_str()); + SplitChanList(user, dest, scl); + } + } + if (user != dest && !ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex")) + { + ServerInstance->SendWhoisLine(user, dest, 312, "%s %s %s :%s",user->nick.c_str(), dest->nick.c_str(), ServerInstance->Config->HideWhoisServer.c_str(), ServerInstance->Config->Network.c_str()); + } + else + { + std::string serverdesc = ServerInstance->GetServerDescription(dest->server); + ServerInstance->SendWhoisLine(user, dest, 312, "%s %s %s :%s",user->nick.c_str(), dest->nick.c_str(), dest->server.c_str(), serverdesc.c_str()); + } + + if (IS_AWAY(dest)) + { + ServerInstance->SendWhoisLine(user, dest, 301, "%s %s :%s",user->nick.c_str(), dest->nick.c_str(), dest->awaymsg.c_str()); + } + + if (IS_OPER(dest)) + { + if (ServerInstance->Config->GenericOper) + ServerInstance->SendWhoisLine(user, dest, 313, "%s %s :is an IRC operator",user->nick.c_str(), dest->nick.c_str()); + else + ServerInstance->SendWhoisLine(user, dest, 313, "%s %s :is %s %s on %s",user->nick.c_str(), dest->nick.c_str(), (strchr("AEIOUaeiou",dest->oper->name[0]) ? "an" : "a"),dest->oper->NameStr(), ServerInstance->Config->Network.c_str()); + } + + if (user == dest || user->HasPrivPermission("users/auspex")) + { + if (dest->IsModeSet('s') != 0) + { + ServerInstance->SendWhoisLine(user, dest, 379, "%s %s :is using modes +%s +%s", user->nick.c_str(), dest->nick.c_str(), dest->FormatModes(), dest->FormatNoticeMasks()); + } + else + { + ServerInstance->SendWhoisLine(user, dest, 379, "%s %s :is using modes +%s", user->nick.c_str(), dest->nick.c_str(), dest->FormatModes()); + } + } + + FOREACH_MOD(I_OnWhois,OnWhois(user,dest)); + + /* + * We only send these if we've been provided them. That is, if hidewhois is turned off, and user is local, or + * if remote whois is queried, too. This is to keep the user hidden, and also since you can't reliably tell remote time. -- w00t + */ + if ((idle) || (signon)) + { + ServerInstance->SendWhoisLine(user, dest, 317, "%s %s %lu %lu :seconds idle, signon time",user->nick.c_str(), dest->nick.c_str(), idle, signon); + } + + ServerInstance->SendWhoisLine(user, dest, 318, "%s %s :End of /WHOIS list.",user->nick.c_str(), dest->nick.c_str()); +} + +CmdResult CommandWhois::HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target) +{ + if (parameters.size() < 2) + return CMD_FAILURE; + + User* user = ServerInstance->FindUUID(parameters[0]); + if (!user) + return CMD_FAILURE; + + unsigned long idle = ConvToInt(parameters[1]); + DoWhois(user, target, target->signon, idle); + + return CMD_SUCCESS; +} + +CmdResult CommandWhois::HandleLocal(const std::vector<std::string>& parameters, LocalUser* user) { User *dest; int userindex = 0; @@ -51,7 +198,6 @@ CmdResult CommandWhois::Handle (const std::vector<std::string>& parameters, User if (ServerInstance->Parser->LoopCall(user, this, parameters, 0)) return CMD_SUCCESS; - /* * If 2 paramters are specified (/whois nick nick), ignore the first one like spanningtree * does, and use the second one, otherwise, use the only paramter. -- djGrrr @@ -59,10 +205,7 @@ CmdResult CommandWhois::Handle (const std::vector<std::string>& parameters, User if (parameters.size() > 1) userindex = 1; - if (IS_LOCAL(user)) - dest = ServerInstance->FindNickOnly(parameters[userindex]); - else - dest = ServerInstance->FindNick(parameters[userindex]); + dest = ServerInstance->FindNickOnly(parameters[userindex]); if ((dest) && (dest->registered == REG_ALL)) { @@ -81,7 +224,7 @@ CmdResult CommandWhois::Handle (const std::vector<std::string>& parameters, User signon = dest->signon; } - ServerInstance->DoWhois(user,dest,signon,idle,parameters[userindex].c_str()); + DoWhois(user,dest,signon,idle); } else { @@ -94,6 +237,4 @@ CmdResult CommandWhois::Handle (const std::vector<std::string>& parameters, User return CMD_SUCCESS; } - - COMMAND_INIT(CommandWhois) diff --git a/src/modules/m_spanningtree/idle.cpp b/src/modules/m_spanningtree/idle.cpp index 70453b975..5aa268a9e 100644 --- a/src/modules/m_spanningtree/idle.cpp +++ b/src/modules/m_spanningtree/idle.cpp @@ -63,13 +63,7 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist ¶ms) if ((who_to_send_to) && (IS_LOCAL(who_to_send_to))) { // an incoming reply to a whois we sent out - std::string nick_whoised = prefix; - unsigned long signon = atoi(params[1].c_str()); - unsigned long idle = atoi(params[2].c_str()); - if ((who_to_send_to) && (IS_LOCAL(who_to_send_to))) - { - ServerInstance->DoWhois(who_to_send_to, u, signon, idle, nick_whoised.c_str()); - } + ServerInstance->Parser->CallHandler("WHOIS", params, u); } else { diff --git a/src/users.cpp b/src/users.cpp index 5058cfcc2..42e905960 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1500,61 +1500,6 @@ void User::SendAll(const char* command, const char* text, ...) } } - -std::string User::ChannelList(User* source, bool spy) -{ - std::string list; - - for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) - { - Channel* c = *i; - /* If the target is the sender, neither +p nor +s is set, or - * the channel contains the user, it is not a spy channel - */ - if (spy != (source == this || !(c->IsModeSet('p') || c->IsModeSet('s')) || c->HasUser(source))) - list.append(c->GetPrefixChar(this)).append(c->name).append(" "); - } - - return list; -} - -void User::SplitChanList(User* dest, const std::string &cl) -{ - std::string line; - std::ostringstream prefix; - std::string::size_type start, pos, length; - - prefix << this->nick << " " << dest->nick << " :"; - line = prefix.str(); - int namelen = ServerInstance->Config->ServerName.length() + 6; - - for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1) - { - length = (pos == std::string::npos) ? cl.length() : pos; - - if (line.length() + namelen + length - start > 510) - { - ServerInstance->SendWhoisLine(this, dest, 319, "%s", line.c_str()); - line = prefix.str(); - } - - if(pos == std::string::npos) - { - line.append(cl.substr(start, length - start)); - break; - } - else - { - line.append(cl.substr(start, length - start + 1)); - } - } - - if (line.length() != prefix.str().length()) - { - ServerInstance->SendWhoisLine(this, dest, 319, "%s", line.c_str()); - } -} - /* * Sets a user's connection class. * If the class name is provided, it will be used. Otherwise, the class will be guessed using host/ip/ident/etc. diff --git a/src/whois.cpp b/src/whois.cpp deleted file mode 100644 index efed45ce3..000000000 --- a/src/whois.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * InspIRCd -- Internet Relay Chat Daemon - * - * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org> - * - * This file is part of InspIRCd. InspIRCd is free software: you can - * redistribute it and/or modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "inspircd.h" - -void InspIRCd::DoWhois(User* user, User* dest,unsigned long signon, unsigned long idle, const char* nick) -{ - this->SendWhoisLine(user, dest, 311, "%s %s %s %s * :%s",user->nick.c_str(), dest->nick.c_str(), dest->ident.c_str(), dest->dhost.c_str(), dest->fullname.c_str()); - if (user == dest || user->HasPrivPermission("users/auspex")) - { - this->SendWhoisLine(user, dest, 378, "%s %s :is connecting from %s@%s %s", user->nick.c_str(), dest->nick.c_str(), dest->ident.c_str(), dest->host.c_str(), dest->GetIPString().c_str()); - } - - std::string cl = dest->ChannelList(user, false); - const ServerConfig::OperSpyWhoisState state = user->HasPrivPermission("users/auspex") ? ServerInstance->Config->OperSpyWhois : ServerConfig::SPYWHOIS_NONE; - - if (state == ServerConfig::SPYWHOIS_SINGLEMSG) - cl.append(dest->ChannelList(user, true)); - - user->SplitChanList(dest,cl); - - if (state == ServerConfig::SPYWHOIS_SPLITMSG) - { - std::string scl = dest->ChannelList(user, true); - if (scl.length()) - { - SendWhoisLine(user, dest, 336, "%s %s :is on private/secret channels:",user->nick.c_str(), dest->nick.c_str()); - user->SplitChanList(dest,scl); - } - } - if (user != dest && !this->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex")) - { - this->SendWhoisLine(user, dest, 312, "%s %s %s :%s",user->nick.c_str(), dest->nick.c_str(), this->Config->HideWhoisServer.c_str(), this->Config->Network.c_str()); - } - else - { - std::string serverdesc = GetServerDescription(dest->server); - this->SendWhoisLine(user, dest, 312, "%s %s %s :%s",user->nick.c_str(), dest->nick.c_str(), dest->server.c_str(), serverdesc.c_str()); - } - - if (IS_AWAY(dest)) - { - this->SendWhoisLine(user, dest, 301, "%s %s :%s",user->nick.c_str(), dest->nick.c_str(), dest->awaymsg.c_str()); - } - - if (IS_OPER(dest)) - { - if (this->Config->GenericOper) - this->SendWhoisLine(user, dest, 313, "%s %s :is an IRC operator",user->nick.c_str(), dest->nick.c_str()); - else - this->SendWhoisLine(user, dest, 313, "%s %s :is %s %s on %s",user->nick.c_str(), dest->nick.c_str(), (strchr("AEIOUaeiou",dest->oper->name[0]) ? "an" : "a"),dest->oper->NameStr(), this->Config->Network.c_str()); - } - - if (user == dest || user->HasPrivPermission("users/auspex")) - { - if (dest->IsModeSet('s') != 0) - { - this->SendWhoisLine(user, dest, 379, "%s %s :is using modes +%s +%s", user->nick.c_str(), dest->nick.c_str(), dest->FormatModes(), dest->FormatNoticeMasks()); - } - else - { - this->SendWhoisLine(user, dest, 379, "%s %s :is using modes +%s", user->nick.c_str(), dest->nick.c_str(), dest->FormatModes()); - } - } - - FOREACH_MOD(I_OnWhois,OnWhois(user,dest)); - - /* - * We only send these if we've been provided them. That is, if hidewhois is turned off, and user is local, or - * if remote whois is queried, too. This is to keep the user hidden, and also since you can't reliably tell remote time. -- w00t - */ - if ((idle) || (signon)) - { - this->SendWhoisLine(user, dest, 317, "%s %s %lu %lu :seconds idle, signon time",user->nick.c_str(), dest->nick.c_str(), idle, signon); - } - - this->SendWhoisLine(user, dest, 318, "%s %s :End of /WHOIS list.",user->nick.c_str(), dest->nick.c_str()); -} - - - |