summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/configreader.cpp13
-rw-r--r--src/mode.cpp18
2 files changed, 28 insertions, 3 deletions
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 2ebc21233..f22f5f7b4 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -30,7 +30,7 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance)
*UserStats = *ModPath = *MyExecutable = *DisabledCommands = *PID = *SuffixQuit = '\0';
WhoWasGroupSize = WhoWasMaxGroups = WhoWasMaxKeep = 0;
log_file = NULL;
- HideModeLists = NoUserDns = forcedebug = OperSpyWhois = nofork = HideBans = HideSplits = UndernetMsgPrefix = false;
+ NoUserDns = forcedebug = OperSpyWhois = nofork = HideBans = HideSplits = UndernetMsgPrefix = false;
CycleHosts = writelog = AllowHalfop = true;
dns_timeout = DieDelay = 5;
MaxTargets = 20;
@@ -333,6 +333,14 @@ bool ValidateRules(ServerConfig* conf, const char* tag, const char* value, Value
return true;
}
+bool ValidateModeLists(ServerConfig* conf, const char* tag, const char* value, ValueItem &data)
+{
+ memset(conf->HideModeLists, 0, 256);
+ for (const unsigned char* x = (const unsigned char*)data.GetString(); *x; ++x)
+ conf->HideModeLists[*x] = true;
+ return true;
+}
+
bool ValidateWhoWas(ServerConfig* conf, const char* tag, const char* value, ValueItem &data)
{
conf->WhoWasMaxKeep = conf->GetInstance()->Duration(data.GetString());
@@ -558,6 +566,7 @@ void ServerConfig::Read(bool bail, userrec* user)
{
static char debug[MAXBUF]; /* Temporary buffer for debugging value */
static char maxkeep[MAXBUF]; /* Temporary buffer for WhoWasMaxKeep value */
+ static char hidemodes[MAXBUF]; /* Modes to not allow listing from users below halfop */
int rem = 0, add = 0; /* Number of modules added, number of modules removed */
std::ostringstream errstr; /* String stream containing the error output */
@@ -602,7 +611,7 @@ void ServerConfig::Read(bool bail, userrec* user)
{"options", "ircumsgprefix","0", new ValueContainerBool (&this->UndernetMsgPrefix), DT_BOOLEAN, NoValidation},
{"options", "announceinvites", "1", new ValueContainerBool (&this->AnnounceInvites), DT_BOOLEAN, NoValidation},
{"options", "hostintopic", "1", new ValueContainerBool (&this->FullHostInTopic), DT_BOOLEAN, NoValidation},
- {"options", "hidemodes", "0", new ValueContainerBool (&this->HideModeLists), DT_BOOLEAN, NoValidation},
+ {"options", "hidemodes", "", new ValueContainerChar (hidemodes), DT_CHARPTR, ValidateModeLists},
{"pid", "file", "", new ValueContainerChar (this->PID), DT_CHARPTR, NoValidation},
{"whowas", "groupsize", "10", new ValueContainerInt (&this->WhoWasGroupSize), DT_INTEGER, NoValidation},
{"whowas", "maxgroups", "10240", new ValueContainerInt (&this->WhoWasMaxGroups), DT_INTEGER, NoValidation},
diff --git a/src/mode.cpp b/src/mode.cpp
index 5e384ad9a..0229eddb1 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -283,8 +283,11 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
{
const char* mode = parameters[1];
int nonlistmodes_found = 0;
+ bool sent[256];
mask = MASK_CHANNEL;
+
+ memset(&sent, 0, 256);
while (mode && *mode)
{
@@ -294,7 +297,20 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
continue;
}
- if (ServerInstance->Config->HideModeLists && (targetchannel->GetStatus(user) < STATUS_HOP))
+ /* Ensure the user doesnt request the same mode twice,
+ * so they cant flood themselves off out of idiocy.
+ */
+ if (!sent[*mode])
+ {
+ sent[*mode] = true;
+ }
+ else
+ {
+ mode++;
+ continue;
+ }
+
+ if (ServerInstance->Config->HideModeLists[*mode] && (targetchannel->GetStatus(user) < STATUS_HOP))
{
user->WriteServ("482 %s %s :Only half-operators and above may view the +%c list",user->nick, targetchannel->name, *mode++);
continue;