summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/example.conf5
-rw-r--r--include/config.h2
-rw-r--r--include/protocol.h5
-rw-r--r--modules/commands/cs_ban.cpp19
-rw-r--r--modules/commands/cs_mode.cpp7
-rw-r--r--src/config.cpp1
-rw-r--r--src/protocol.cpp5
7 files changed, 38 insertions, 6 deletions
diff --git a/data/example.conf b/data/example.conf
index 9f7b27576..de2fbffc1 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -273,6 +273,11 @@ networkinfo
/* Set this to the maximum allowed channel length on your network.
*/
chanlen = 32
+
+ /* The maximum number of list modes settable on a channel (such as b, e, I).
+ * Comment out or set to 0 to disable.
+ */
+ modelistsize = 100
}
/*
diff --git a/include/config.h b/include/config.h
index 4ea182c0d..36a4836c8 100644
--- a/include/config.h
+++ b/include/config.h
@@ -375,6 +375,8 @@ class CoreExport ServerConfig
unsigned HostLen;
/* Max length of channel names */
unsigned ChanLen;
+ /* Max length of b/e/I lists */
+ unsigned ListSize;
/* User and group to run as */
Anope::string User;
diff --git a/include/protocol.h b/include/protocol.h
index 9ff0167c9..8953d25e5 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -223,6 +223,11 @@ class CoreExport IRCDProto : public Service
virtual bool IsIdentValid(const Anope::string &);
virtual bool IsHostValid(const Anope::string &);
virtual bool IsExtbanValid(const Anope::string &) { return false; }
+
+ /** Retrieve the maximum number of list modes settable on this channel
+ * Defaults to Config->ListSize
+ */
+ virtual unsigned GetMaxListFor(Channel *c);
};
class CoreExport MessageSource
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index 52c372fb4..e46bfcecb 100644
--- a/modules/commands/cs_ban.cpp
+++ b/modules/commands/cs_ban.cpp
@@ -53,6 +53,18 @@ class CommandCSBan : public Command
return;
}
+ Channel *c = ci->c;
+ if (c == NULL)
+ {
+ source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
+ return;
+ }
+ else if (IRCD->GetMaxListFor(c) && c->HasMode("BAN") >= IRCD->GetMaxListFor(c))
+ {
+ source.Reply(_("The ban list for %s is full."), c->name.c_str());
+ return;
+ }
+
Anope::string expiry, target, reason;
time_t ban_time;
if (params[1][0] == '+')
@@ -82,15 +94,12 @@ class CommandCSBan : public Command
if (reason.length() > Config->CSReasonMax)
reason = reason.substr(0, Config->CSReasonMax);
- Channel *c = ci->c;
User *u = source.GetUser();
User *u2 = User::Find(target, true);
AccessGroup u_access = source.AccessFor(ci);
- if (!c)
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- else if (!u_access.HasPriv("BAN") && !source.HasPriv("chanserv/kick"))
+ if (!u_access.HasPriv("BAN") && !source.HasPriv("chanserv/kick"))
source.Reply(ACCESS_DENIED);
else if (u2)
{
@@ -102,7 +111,7 @@ class CommandCSBan : public Command
* Dont ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
- else if (ci->c->MatchesList(u2, "EXCEPT"))
+ else if (c->MatchesList(u2, "EXCEPT"))
source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
else if (u2->IsProtected())
source.Reply(ACCESS_DENIED);
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
index d44e7e07b..823b60f8e 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -102,6 +102,8 @@ class CommandCSMode : public Command
Anope::string mode_param;
if (((cm->type == MODE_STATUS || cm->type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
source.Reply(_("Missing parameter for mode %c."), cm->mchar);
+ else if (cm->type == MODE_LIST && ci->c && IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) >= IRCD->GetMaxListFor(ci->c))
+ source.Reply(_("List for mode %c is full."), cm->mchar);
else
{
ci->SetMLock(cm, adding, mode_param, source.GetNick());
@@ -371,7 +373,10 @@ class CommandCSMode : public Command
if (!sep.GetToken(param))
break;
if (adding)
- ci->c->SetMode(NULL, cm, param);
+ {
+ if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
+ ci->c->SetMode(NULL, cm, param);
+ }
else
{
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = ci->c->GetModeList(cm->name);
diff --git a/src/config.cpp b/src/config.cpp
index 3e52b4ae9..1c2aae988 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1139,6 +1139,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"networkinfo", "userlen", "10", new ValueContainerUInt(&conf->UserLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
{"networkinfo", "hostlen", "64", new ValueContainerUInt(&conf->HostLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
{"networkinfo", "chanlen", "32", new ValueContainerUInt(&conf->ChanLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
+ {"networkinfo", "modelistsize", "0", new ValueContainerUInt(&conf->ListSize), DT_UINTEGER, NoValidation},
{"options", "user", "", new ValueContainerString(&conf->User), DT_STRING, NoValidation},
{"options", "group", "", new ValueContainerString(&conf->Group), DT_STRING, NoValidation},
{"options", "casemap", "ascii", new ValueContainerString(&conf->CaseMap), DT_STRING, NoValidation},
diff --git a/src/protocol.cpp b/src/protocol.cpp
index c14f1ee68..35f302ba8 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -385,6 +385,11 @@ void IRCDProto::SendOper(User *u)
u->SetMode(OperServ, "OPER");
}
+unsigned IRCDProto::GetMaxListFor(Channel *c)
+{
+ return c->HasMode("LBAN") ? 0 : Config->ListSize;
+}
+
MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL)
{
if (src.empty())