diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-03-06 22:28:57 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-03-06 22:28:57 +0000 |
commit | 526f5a4a02882b19056fe755dff1f64b764ff313 (patch) | |
tree | 6a9e92e4f3f7088b18dcdde360d07c911ee174df | |
parent | eacd707421be4f2612df9bde4517649061bb062e (diff) |
Construct explicit parameter type list for MODE parameters
Previously, we used TR_SPACENICKLIST on the parameters. This worked only because
usually, if anything in the list parsed as a nick, then it was a nick. However,
some modes like +k and +g allow free-form text, which could also resolve as a
nick. Add extra parameters to allow modes to specify their TranslateType,
defaulting to TR_TEXT.
This fixes bug #757, found by Taros
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11180 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/command_parse.h | 2 | ||||
-rw-r--r-- | include/ctables.h | 2 | ||||
-rw-r--r-- | include/mode.h | 14 | ||||
-rw-r--r-- | include/modules.h | 6 | ||||
-rw-r--r-- | include/u_listmode.h | 5 | ||||
-rw-r--r-- | src/command_parse.cpp | 83 | ||||
-rw-r--r-- | src/mode.cpp | 16 | ||||
-rw-r--r-- | src/modes/cmode_h.cpp | 2 | ||||
-rw-r--r-- | src/modes/cmode_o.cpp | 2 | ||||
-rw-r--r-- | src/modes/cmode_v.cpp | 2 | ||||
-rw-r--r-- | src/modules.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_chanprotect.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_operprefix.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.h | 4 |
15 files changed, 92 insertions, 66 deletions
diff --git a/include/command_parse.h b/include/command_parse.h index b3ae3236a..21dae89dd 100644 --- a/include/command_parse.h +++ b/include/command_parse.h @@ -202,6 +202,8 @@ class CoreExport CommandParser : public classbase * @return returns the number of substitutions made. Will always be 0 or 1 for TR_TEXT and 0..n for other types. */ int TranslateUIDs(TranslateType to, const std::string &source, std::string &dest); + + int TranslateUIDs(const std::vector<TranslateType> to, const std::string &source, std::string &dest); }; /** Command handler class for the RELOAD command. diff --git a/include/ctables.h b/include/ctables.h index 3e10e7c23..d7c2a2050 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -33,8 +33,6 @@ enum TranslateType TR_END, /* End of known parameters, everything after this is TR_TEXT */ TR_TEXT, /* Raw text, leave as-is */ TR_NICK, /* Nickname, translate to UUID for server->server */ - TR_NICKLIST, /* Comma seperated nickname list, translate to UUIDs */ - TR_SPACENICKLIST, /* Space seperated nickname list, translate to UUIDs */ TR_CUSTOM /* Custom translation handled by EncodeParameter/DecodeParameter */ }; diff --git a/include/mode.h b/include/mode.h index f78fcda9c..525a26208 100644 --- a/include/mode.h +++ b/include/mode.h @@ -17,6 +17,7 @@ /* Forward declarations. */ class User; +#include "ctables.h" #include "channels.h" /** @@ -126,6 +127,10 @@ class CoreExport ModeHandler : public Extensible */ ModeType m_type; /** + * The mode parameter translation type + */ + TranslateType m_paramtype; + /** * True if the mode requires oper status * to set. */ @@ -161,7 +166,8 @@ class CoreExport ModeHandler : public Extensible * and the rank values OP_VALUE, HALFOP_VALUE and VOICE_VALUE respectively. Any prefixes you define should have unique values proportional * to these three defaults or proportional to another mode in a module you depend on. See src/cmode_o.cpp as an example. */ - ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix = 0, char prefixrequired = '%'); + ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, + char mprefix = 0, char prefixrequired = '%', TranslateType translate = TR_TEXT); /** * The default destructor does nothing */ @@ -191,10 +197,14 @@ class CoreExport ModeHandler : public Extensible */ virtual unsigned int GetPrefixRank(); /** - * Returns the modes type + * Returns the mode's type */ ModeType GetModeType(); /** + * Returns the mode's parameter translation type + */ + TranslateType GetTranslateType(); + /** * Returns true if the mode can only be set/unset by an oper */ bool NeedsOper(); diff --git a/include/modules.h b/include/modules.h index 536313d8f..90aeb178e 100644 --- a/include/modules.h +++ b/include/modules.h @@ -739,8 +739,9 @@ class CoreExport Module : public Extensible * @param dest The target of the modes (User* or Channel*) * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) * @param text The actual modes and their parameters if any + * @param translate The translation types of the mode parameters */ - virtual void OnMode(User* user, void* dest, int target_type, const std::string &text); + virtual void OnMode(User* user, void* dest, int target_type, const std::string &text, const std::vector<TranslateType> &translate); /** Allows modules to alter or create server descriptions * Whenever a module requires a server description, for example for display in @@ -847,8 +848,9 @@ class CoreExport Module : public Extensible * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL * @param target The Channel* or User* that modes should be sent for * @param modeline The modes and parameters to be sent + * @param translate The translation types of the mode parameters */ - virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline); + virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline, const std::vector<TranslateType> &translate); /** Implemented by modules which provide the ability to link servers. * These modules will implement this method, which allows metadata (extra data added to diff --git a/include/u_listmode.h b/include/u_listmode.h index b08ad8d4d..88b5fb3ee 100644 --- a/include/u_listmode.h +++ b/include/u_listmode.h @@ -423,18 +423,21 @@ class ListModeBase : public ModeHandler chan->GetExt(infokey, mlist); irc::modestacker modestack(ServerInstance, true); std::deque<std::string> stackresult; + std::vector<TranslateType> types; + types.push_back(TR_TEXT); if (mlist) { for (modelist::iterator it = mlist->begin(); it != mlist->end(); it++) { modestack.Push(std::string(1, mode)[0], it->mask); + types.push_back(this->GetTranslateType()); } } while (modestack.GetStackedLine(stackresult)) { irc::stringjoiner mode_join(" ", stackresult, 0, stackresult.size() - 1); std::string line = mode_join.GetJoined(); - proto->ProtoSendMode(opaque, TYPE_CHANNEL, chan, line); + proto->ProtoSendMode(opaque, TYPE_CHANNEL, chan, line, types); } } diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 7c18c8ab1..d0b114816 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -609,32 +609,24 @@ void CommandParser::SetupCommandTable() this->CreateCommand(new CommandReload(ServerInstance)); } -int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, std::string &dest) +int CommandParser::TranslateUIDs(const std::vector<TranslateType> to, const std::string &source, std::string &dest) { + irc::spacesepstream items(source); + std::vector<TranslateType>::const_iterator types = to.begin(); User* user = NULL; std::string item; int translations = 0; dest.clear(); - switch (to) + while (items.GetToken(item)) { - case TR_NICK: - /* Translate single nickname */ - user = ServerInstance->FindNick(source); - if (user) - { - dest = user->uuid; - translations++; - } - else - dest = source; - break; - case TR_NICKLIST: + TranslateType t = *types; + types++; + + switch (t) { - /* Translate comma seperated list of nicknames */ - irc::commasepstream items(source); - while (items.GetToken(item)) - { + case TR_NICK: + /* Translate single nickname */ user = ServerInstance->FindNick(item); if (user) { @@ -643,31 +635,42 @@ int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, st } else dest.append(item); - dest.append(","); - } - if (!dest.empty()) - dest.erase(dest.end() - 1); + break; + break; + case TR_END: + case TR_TEXT: + default: + /* Do nothing */ + dest.append(item); + break; } - break; - case TR_SPACENICKLIST: - { - /* Translate space seperated list of nicknames */ - irc::spacesepstream items(source); - while (items.GetToken(item)) + dest.append(" "); + } + + if (!dest.empty()) + dest.erase(dest.end() - 1); + return translations; +} + +int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, std::string &dest) +{ + User* user = NULL; + std::string item; + int translations = 0; + dest.clear(); + + switch (to) + { + case TR_NICK: + /* Translate single nickname */ + user = ServerInstance->FindNick(source); + if (user) { - user = ServerInstance->FindNick(item); - if (user) - { - dest.append(user->uuid); - translations++; - } - else - dest.append(item); - dest.append(" "); + dest = user->uuid; + translations++; } - if (!dest.empty()) - dest.erase(dest.end() - 1); - } + else + dest = source; break; case TR_END: case TR_TEXT: diff --git a/src/mode.cpp b/src/mode.cpp index e7f918e62..da8f10294 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -52,8 +52,8 @@ /* +s (server notice masks) */ #include "modes/umode_s.h" -ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired) - : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired) +ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix, char prefixrequired, TranslateType translate) + : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), m_paramtype(translate), oper(operonly), prefix(mprefix), count(0), prefixneeded(prefixrequired) { } @@ -97,6 +97,11 @@ ModeType ModeHandler::GetModeType() return m_type; } +TranslateType ModeHandler::GetTranslateType() +{ + return m_paramtype; +} + bool ModeHandler::NeedsOper() { return oper; @@ -498,6 +503,8 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user, std::string mode_sequence = parameters[1]; std::string parameter; std::ostringstream parameter_list; + std::vector<TranslateType> parameter_xlate; + parameter_xlate.push_back(TR_TEXT); std::string output_sequence; bool adding = true, state_change = false; unsigned char handler_id = 0; @@ -710,6 +717,7 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user, if ((modehandlers[handler_id]->GetNumParams(adding)) && (!parameter.empty())) { parameter_list << " " << parameter; + parameter_xlate.push_back(modehandlers[handler_id]->GetTranslateType()); parameter_count++; /* Does this mode have a prefix? */ if (modehandlers[handler_id]->GetPrefix() && targetchannel) @@ -768,13 +776,13 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user, if (type == MODETYPE_CHANNEL) { targetchannel->WriteChannel(user, "MODE %s %s%s", targetchannel->name.c_str(), output_sequence.c_str(), parameter_list.str().c_str()); - FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str())); + FOREACH_MOD(I_OnMode,OnMode(user, targetchannel, TYPE_CHANNEL, output_sequence + parameter_list.str(), parameter_xlate)); this->LastParse = targetchannel->name; } else { user->WriteTo(targetuser, "MODE %s %s%s", targetuser->nick.c_str(), output_sequence.c_str(), parameter_list.str().c_str()); - FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence + parameter_list.str())); + FOREACH_MOD(I_OnMode,OnMode(user, targetuser, TYPE_USER, output_sequence + parameter_list.str(), parameter_xlate)); this->LastParse = targetuser->nick; } } diff --git a/src/modes/cmode_h.cpp b/src/modes/cmode_h.cpp index c3bb92576..0d6da2778 100644 --- a/src/modes/cmode_h.cpp +++ b/src/modes/cmode_h.cpp @@ -19,7 +19,7 @@ #include "modules.h" #include "modes/cmode_h.h" -ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false, '%', '@') +ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false, '%', '@', TR_NICK) { } diff --git a/src/modes/cmode_o.cpp b/src/modes/cmode_o.cpp index 7b27788fc..16ea2ffb7 100644 --- a/src/modes/cmode_o.cpp +++ b/src/modes/cmode_o.cpp @@ -19,7 +19,7 @@ #include "modules.h" #include "modes/cmode_o.h" -ModeChannelOp::ModeChannelOp(InspIRCd* Instance) : ModeHandler(Instance, 'o', 1, 1, true, MODETYPE_CHANNEL, false, '@', '@') +ModeChannelOp::ModeChannelOp(InspIRCd* Instance) : ModeHandler(Instance, 'o', 1, 1, true, MODETYPE_CHANNEL, false, '@', '@', TR_NICK) { } diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp index a89f5705f..47befbac9 100644 --- a/src/modes/cmode_v.cpp +++ b/src/modes/cmode_v.cpp @@ -20,7 +20,7 @@ #include "modules.h" #include "modes/cmode_v.h" -ModeChannelVoice::ModeChannelVoice(InspIRCd* Instance) : ModeHandler(Instance, 'v', 1, 1, true, MODETYPE_CHANNEL, false, '+') +ModeChannelVoice::ModeChannelVoice(InspIRCd* Instance) : ModeHandler(Instance, 'v', 1, 1, true, MODETYPE_CHANNEL, false, '+', '%', TR_NICK) { } diff --git a/src/modules.cpp b/src/modules.cpp index db14fd1e6..2d8c9387f 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -116,7 +116,7 @@ void Module::OnPostJoin(User*, Channel*) { } void Module::OnUserPart(User*, Channel*, std::string&, bool&) { } void Module::OnRehash(User*, const std::string&) { } int Module::OnUserPreJoin(User*, Channel*, const char*, std::string&, const std::string&) { return 0; } -void Module::OnMode(User*, void*, int, const std::string&) { } +void Module::OnMode(User*, void*, int, const std::string&, const std::vector<TranslateType>&) { } Version Module::GetVersion() { return Version("Misconfigured", VF_VENDOR, -1); } void Module::OnOper(User*, const std::string&) { } void Module::OnPostOper(User*, const std::string&, const std::string &) { } @@ -170,7 +170,7 @@ void Module::OnPostLocalTopicChange(User*, Channel*, const std::string&) { } void Module::OnGetServerDescription(const std::string&, std::string&) { } void Module::OnSyncUser(User*, Module*, void*) { } void Module::OnSyncChannel(Channel*, Module*, void*) { } -void Module::ProtoSendMode(void*, TargetTypeFlags, void*, const std::string&) { } +void Module::ProtoSendMode(void*, TargetTypeFlags, void*, const std::string&, const std::vector<TranslateType>&) { } void Module::OnSyncChannelMetaData(Channel*, Module*, void*, const std::string&, bool) { } void Module::OnSyncUserMetaData(User*, Module*, void*, const std::string&, bool) { } void Module::OnSyncOtherMetaData(Module*, void*, bool) { } diff --git a/src/modules/m_chanprotect.cpp b/src/modules/m_chanprotect.cpp index 85c8660a2..627857175 100644 --- a/src/modules/m_chanprotect.cpp +++ b/src/modules/m_chanprotect.cpp @@ -159,7 +159,7 @@ class ChanFounder : public ModeHandler, public FounderProtectBase { public: ChanFounder(InspIRCd* Instance, char my_prefix, bool &depriv_self, bool &depriv_others) - : ModeHandler(Instance, 'q', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0), + : ModeHandler(Instance, 'q', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0, TR_NICK), FounderProtectBase(Instance, "cm_founder_", "founder", 386, 387, depriv_self, depriv_others) { } unsigned int GetPrefixRank() @@ -235,7 +235,7 @@ class ChanProtect : public ModeHandler, public FounderProtectBase { public: ChanProtect(InspIRCd* Instance, char my_prefix, bool &depriv_self, bool &depriv_others) - : ModeHandler(Instance, 'a', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0), + : ModeHandler(Instance, 'a', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0, TR_NICK), FounderProtectBase(Instance,"cm_protect_","protected user", 388, 389, depriv_self, depriv_others) { } unsigned int GetPrefixRank() diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index 0dd762878..7fda38bb3 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -51,7 +51,7 @@ void AddPrefixChan(User* user, Channel* channel) class OperPrefixMode : public ModeHandler { public: - OperPrefixMode(InspIRCd* Instance, char pfx) : ModeHandler(Instance, 'y', 1, 1, true, MODETYPE_CHANNEL, false, pfx) { } + OperPrefixMode(InspIRCd* Instance, char pfx) : ModeHandler(Instance, 'y', 1, 1, true, MODETYPE_CHANNEL, false, pfx, pfx, TR_NICK) { } unsigned int GetPrefixRank() { diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index da393858c..51a9eb025 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -800,7 +800,7 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x) } } -void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::string &text) +void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::string &text, const std::vector<TranslateType> &translate) { if ((IS_LOCAL(user)) && (user->registered == REG_ALL)) { @@ -808,7 +808,7 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s std::string command; std::string output_text; - ServerInstance->Parser->TranslateUIDs(TR_SPACENICKLIST, text, output_text); + ServerInstance->Parser->TranslateUIDs(translate, text, output_text); if (target_type == TYPE_USER) { @@ -851,19 +851,19 @@ int ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg) return 0; } -void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline) +void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline, const std::vector<TranslateType> &translate) { TreeSocket* s = (TreeSocket*)opaque; std::string output_text; - ServerInstance->Parser->TranslateUIDs(TR_SPACENICKLIST, modeline, output_text); + ServerInstance->Parser->TranslateUIDs(translate, modeline, output_text); if (target) { if (target_type == TYPE_USER) { User* u = (User*)target; - s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" FMODE "+u->uuid+" "+ConvToStr(u->age)+" "+output_text); + s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" MODE "+u->uuid+" "+output_text); } else if (target_type == TYPE_CHANNEL) { diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 1dd7692c1..19ec2d43c 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -174,10 +174,10 @@ class ModuleSpanningTree : public Module void OnLine(User* source, const std::string &host, bool adding, char linetype, long duration, const std::string &reason); virtual void OnAddLine(User *u, XLine *x); virtual void OnDelLine(User *u, XLine *x); - virtual void OnMode(User* user, void* dest, int target_type, const std::string &text); + virtual void OnMode(User* user, void* dest, int target_type, const std::string &text, const std::vector<TranslateType> &translate); virtual int OnStats(char statschar, User* user, string_list &results); virtual int OnSetAway(User* user, const std::string &awaymsg); - virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline); + virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline, const std::vector<TranslateType> &translate); virtual void ProtoSendMetaData(void* opaque, TargetTypeFlags target_type, void* target, const std::string &extname, const std::string &extdata); virtual void OnEvent(Event* event); virtual void OnLoadModule(Module* mod,const std::string &name); |