X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcoremods%2Fcore_message.cpp;h=a17157bade316116ef49376477f022f9f4b16f9f;hb=daf3be301d0181d14d1310b3ab5f79c8a85dfb46;hp=961307b06713b13b69a1b48c5250532e9e02a3c9;hpb=2680c7907a0b05f65214fc63043322d57a61f455;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/coremods/core_message.cpp b/src/coremods/core_message.cpp index 961307b06..a17157bad 100644 --- a/src/coremods/core_message.cpp +++ b/src/coremods/core_message.cpp @@ -21,6 +21,12 @@ #include "inspircd.h" +enum +{ + // From RFC 2812. + ERR_NOSUCHSERVICE = 408 +}; + class MessageDetailsImpl : public MessageDetails { public: @@ -158,7 +164,7 @@ class CommandMessage : public Command if (no_chan_priv && chan->IsModeSet(moderatedmode)) { // The moderated mode is set and the source has no status rank. - source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (+m)"); + source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (+m is set)"); return CMD_FAILURE; } @@ -297,7 +303,7 @@ class CommandMessage : public Command , moderatedmode(parent, "moderated") , noextmsgmode(parent, "noextmsg") { - syntax = "{,} "; + syntax = "[,]+ :"; } /** Handle command. @@ -305,7 +311,35 @@ class CommandMessage : public Command * @param user The user issuing the command * @return A value from CmdResult to indicate command success or failure. */ - CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE; + CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE + { + if (CommandParser::LoopCall(user, this, parameters, 0)) + return CMD_SUCCESS; + + // The specified message was empty. + if (parameters[1].empty()) + { + user->WriteNumeric(ERR_NOTEXTTOSEND, "No text to send"); + return CMD_FAILURE; + } + + // The target is a server glob. + if (parameters[0][0] == '$') + return HandleServerTarget(user, parameters); + + // If the message begins with a status character then look it up. + const char* target = parameters[0].c_str(); + PrefixMode* pmh = ServerInstance->Modes->FindPrefix(target[0]); + if (pmh) + target++; + + // The target is a channel name. + if (*target == '#') + return HandleChannelTarget(user, parameters, target, pmh); + + // The target is a nickname. + return HandleUserTarget(user, parameters); + } RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE { @@ -317,45 +351,80 @@ class CommandMessage : public Command } }; -CmdResult CommandMessage::Handle(User* user, const Params& parameters) +class CommandSQuery : public SplitCommand { - if (CommandParser::LoopCall(user, this, parameters, 0)) - return CMD_SUCCESS; + public: + CommandSQuery(Module* Creator) + : SplitCommand(Creator, "SQUERY", 2, 2) + { + syntax = " :"; + } - // The target is a server glob. - if (parameters[0][0] == '$') - return HandleServerTarget(user, parameters); + CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE + { + // The specified message was empty. + if (parameters[1].empty()) + { + user->WriteNumeric(ERR_NOTEXTTOSEND, "No text to send"); + return CMD_FAILURE; + } - // If the message begins with a status character then look it up. - const char* target = parameters[0].c_str(); - PrefixMode* pmh = ServerInstance->Modes->FindPrefix(target[0]); - if (pmh) - target++; + // The target can be either a nick or a nick@server mask. + User* target; + const char* targetserver = strchr(parameters[0].c_str(), '@'); + if (targetserver) + { + // The target is a user on a specific server (e.g. jto@tolsun.oulu.fi). + target = ServerInstance->FindNickOnly(parameters[0].substr(0, targetserver - parameters[0].c_str())); + if (target && strcasecmp(target->server->GetName().c_str(), targetserver + 1)) + target = NULL; + } + else + { + // The targer can be on any server. + target = ServerInstance->FindNickOnly(parameters[0]); + } - // The target is a channel name. - if (*target == '#') - return HandleChannelTarget(user, parameters, target, pmh); + if (!target || target->registered != REG_ALL || !target->server->IsULine()) + { + // The target user does not exist, is not fully registered, or is not a service. + user->WriteNumeric(ERR_NOSUCHSERVICE, parameters[0], "No such service"); + return CMD_FAILURE; + } - // The target is a nickname. - return HandleUserTarget(user, parameters); -} + // Fire the pre-message events. + MessageTarget msgtarget(target); + MessageDetailsImpl msgdetails(MSG_PRIVMSG, parameters[1], parameters.GetTags()); + if (!FirePreEvents(user, msgtarget, msgdetails)) + return CMD_FAILURE; + + // The SQUERY command targets a service on a U-lined server. This can never + // be on the server local to the source so we don't need to do any routing + // logic and can forward it as a PRIVMSG. + + // Fire the post-message event. + return FirePostEvent(user, msgtarget, msgdetails); + } +}; class ModuleCoreMessage : public Module { private: CommandMessage cmdprivmsg; CommandMessage cmdnotice; + CommandSQuery cmdsquery; public: ModuleCoreMessage() : cmdprivmsg(this, MSG_PRIVMSG) , cmdnotice(this, MSG_NOTICE) + , cmdsquery(this) { } Version GetVersion() CXX11_OVERRIDE { - return Version("PRIVMSG, NOTICE", VF_CORE|VF_VENDOR); + return Version("Provides the NOTICE, PRIVMSG, and SQUERY commands", VF_CORE|VF_VENDOR); } };