summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-03-06 22:28:57 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-03-06 22:28:57 +0000
commit526f5a4a02882b19056fe755dff1f64b764ff313 (patch)
tree6a9e92e4f3f7088b18dcdde360d07c911ee174df
parenteacd707421be4f2612df9bde4517649061bb062e (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.h2
-rw-r--r--include/ctables.h2
-rw-r--r--include/mode.h14
-rw-r--r--include/modules.h6
-rw-r--r--include/u_listmode.h5
-rw-r--r--src/command_parse.cpp83
-rw-r--r--src/mode.cpp16
-rw-r--r--src/modes/cmode_h.cpp2
-rw-r--r--src/modes/cmode_o.cpp2
-rw-r--r--src/modes/cmode_v.cpp2
-rw-r--r--src/modules.cpp4
-rw-r--r--src/modules/m_chanprotect.cpp4
-rw-r--r--src/modules/m_operprefix.cpp2
-rw-r--r--src/modules/m_spanningtree/main.cpp10
-rw-r--r--src/modules/m_spanningtree/main.h4
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);