summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-10-30 01:04:13 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-10-30 01:04:13 +0000
commit6a9fa9f4d2ead592eb51a014491ce3aaee2029e8 (patch)
tree454479f2c8ef69a52e461416be42fd94d8b15955 /src
parent5fc268b7509f20cbf1243b99f2669033b93db00e (diff)
Rewrote all of the defcon code, and moved most of it to os_defcon. This fixes defcon to have the ability to use modes introduced to Anope at a later time than on startup (eg, from the IRCd), amongst other things
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2597 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/channels.c4
-rw-r--r--src/chanserv.c31
-rw-r--r--src/commands.c20
-rw-r--r--src/config.c41
-rw-r--r--src/core/cs_register.c6
-rw-r--r--src/core/cs_set.c5
-rw-r--r--src/core/ms_sendall.c5
-rw-r--r--src/core/ms_staff.c5
-rw-r--r--src/core/ns_group.c5
-rw-r--r--src/core/ns_register.c6
-rw-r--r--src/core/os_defcon.c436
-rw-r--r--src/init.c8
-rw-r--r--src/main.c7
-rw-r--r--src/memoserv.c6
-rw-r--r--src/modes.cpp1
-rw-r--r--src/modules/hs_request.c3
-rw-r--r--src/operserv.c241
-rw-r--r--src/sessions.c7
-rw-r--r--src/users.c15
19 files changed, 492 insertions, 360 deletions
diff --git a/src/channels.c b/src/channels.c
index dbc39e409..3e921e182 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -1884,6 +1884,8 @@ Channel *chan_create(const char *chan, time_t ts)
restore_topic(chan);
}
+ FOREACH_MOD(I_OnChannelCreate, OnChannelCreate(c));
+
return c;
}
@@ -1895,6 +1897,8 @@ void chan_delete(Channel * c)
{
BanData *bd, *next;
+ FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(c));
+
if (debug)
alog("debug: Deleting channel %s", c->name);
diff --git a/src/chanserv.c b/src/chanserv.c
index 4175b625e..a6aee4aaf 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -813,8 +813,7 @@ void check_modes(Channel * c)
c->RemoveMode(CMODE_REGISTERED);
ircdproto->SendMode(whosends(ci), c->name, "-r");
}
- /* Channels that are not regged also need the defcon modes.. ~ Viper */
- /* return; */
+ return;
}
*end++ = '+';
@@ -823,8 +822,8 @@ void check_modes(Channel * c)
{
cm = it->second;
- /* If this channel does not have the mode and the mode is mlocked/defcon'd */
- if (!c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)))
+ /* If this channel does not have the mode and the mode is mlocked */
+ if (!c->HasMode(cm->Name) && ci->HasMLock(cm->Name, true))
{
*end++ = it->first;
c->SetMode(cm->Name);
@@ -833,14 +832,7 @@ void check_modes(Channel * c)
if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
-
- param.clear();
- if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))
- DefConModesCI.GetParam(cmp->Name, &param);
- else if (ci)
- ci->GetParam(cmp->Name, &param);
- else
- alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name);
+ ci->GetParam(cmp->Name, &param);
if (!param.empty())
{
@@ -852,19 +844,12 @@ void check_modes(Channel * c)
}
}
}
- /* If this is a param mode and its mlocked or defcon has it set negative */
- else if (cm->Type == MODE_PARAM && c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))))
+ /* If this is a param mode and its mlocked and is set negative */
+ else if (cm->Type == MODE_PARAM && c->HasMode(cm->Name) && ci->HasMLock(cm->Name, true))
{
cmp = static_cast<ChannelModeParam *>(cm);
-
c->GetParam(cmp->Name, &param);
-
- if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))
- DefConModesCI.GetParam(cmp->Name, &ciparam);
- else if (ci)
- ci->GetParam(cmp->Name, &ciparam);
- else
- alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name);
+ ci->GetParam(cmp->Name, &ciparam);
if (!param.empty() && !ciparam.empty() && param != ciparam)
{
@@ -889,7 +874,7 @@ void check_modes(Channel * c)
cm = it->second;
/* If the channel has the mode */
- if (c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, false)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, false)))
+ if (c->HasMode(cm->Name) && ci->HasMLock(cm->Name, false))
{
*end++ = it->first;
c->RemoveMode(cm->Name);
diff --git a/src/commands.c b/src/commands.c
index 960f5ac06..9247307a3 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -54,25 +54,18 @@ void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[], const char *
Command *c = findCommand(cmdTable, cmd);
int retVal = MOD_CONT;
ChannelInfo *ci;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(service, u, cmd, c));
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
if (!c)
{
- if ((!checkDefCon(DEFCON_SILENT_OPER_ONLY)) || is_oper(u))
- {
- notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service);
- }
+ notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service);
return;
}
- if ((checkDefCon(DEFCON_OPER_ONLY) || checkDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u))
- {
- if (!checkDefCon(DEFCON_SILENT_OPER_ONLY))
- {
- notice_lang(service, u, OPER_DEFCON_DENIED);
- return;
- }
- }
-
if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED))
{
// Command requires registered users only
@@ -120,7 +113,6 @@ void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[], const char *
return;
}
- EventReturn MOD_RESULT = EVENT_CONTINUE;
FOREACH_RESULT(I_OnPreCommand, OnPreCommand(u, c->service, c->name.c_str(), params));
if (MOD_RESULT == EVENT_STOP)
return;
diff --git a/src/config.c b/src/config.c
index 1cdb0ef92..89342ff13 100644
--- a/src/config.c
+++ b/src/config.c
@@ -235,7 +235,6 @@ static std::string DefCon1;
static std::string DefCon2;
static std::string DefCon3;
static std::string DefCon4;
-int DefCon[6];
time_t DefConTimeOut;
int DefConSessionLimit;
time_t DefConAKILL;
@@ -1952,8 +1951,9 @@ int read_config(int reload)
**/
if (DefConLevel) {
/* Build DefCon's */
- DefCon[0] = 0;
- for (int level = 1; level < 5; ++level) {
+ DefCon.reserve(6);
+ DefCon[5].reset();
+ for (unsigned int level = 1; level < 5; ++level) {
DefCon[level] = 0;
std::string *levelDefinition = NULL;
switch (level) {
@@ -1972,28 +1972,33 @@ int read_config(int reload)
spacesepstream operations(*levelDefinition);
std::string operation;
while (operations.GetToken(operation)) {
- if (operation == "nonewchannels") DefCon[level] |= DEFCON_NO_NEW_CHANNELS;
- else if (operation == "nonewnicks") DefCon[level] |= DEFCON_NO_NEW_NICKS;
- else if (operation == "nomlockchanges") DefCon[level] |= DEFCON_NO_MLOCK_CHANGE;
- else if (operation == "forcechanmodes") DefCon[level] |= DEFCON_FORCE_CHAN_MODES;
- else if (operation == "reducedsessions") DefCon[level] |= DEFCON_REDUCE_SESSION;
- else if (operation == "nonewclients") DefCon[level] |= DEFCON_NO_NEW_CLIENTS;
- else if (operation == "operonly") DefCon[level] |= DEFCON_OPER_ONLY;
- else if (operation == "silentoperonly") DefCon[level] |= DEFCON_SILENT_OPER_ONLY;
- else if (operation == "akillnewclients") DefCon[level] |= DEFCON_AKILL_NEW_CLIENTS;
- else if (operation == "nonewmemos") DefCon[level] |= DEFCON_NO_NEW_MEMOS;
+ if (operation == "nonewchannels") AddDefCon(level, DEFCON_NO_NEW_CHANNELS);
+ else if (operation == "nonewnicks") AddDefCon(level, DEFCON_NO_NEW_NICKS);
+ else if (operation == "nomlockchanges") AddDefCon(level, DEFCON_NO_MLOCK_CHANGE);
+ else if (operation == "forcechanmodes") AddDefCon(level, DEFCON_FORCE_CHAN_MODES);
+ else if (operation == "reducedsessions") AddDefCon(level, DEFCON_REDUCE_SESSION);
+ else if (operation == "nonewclients") AddDefCon(level, DEFCON_NO_NEW_CLIENTS);
+ else if (operation == "operonly") AddDefCon(level, DEFCON_OPER_ONLY);
+ else if (operation == "silentoperonly") AddDefCon(level, DEFCON_SILENT_OPER_ONLY);
+ else if (operation == "akillnewclients") AddDefCon(level, DEFCON_AKILL_NEW_CLIENTS);
+ else if (operation == "nonewmemos") AddDefCon(level, DEFCON_NO_NEW_MEMOS);
}
}
- DefCon[5] = 0; /* DefCon level 5 is always normal operation */
- for (defconCount = 1; defconCount <= 5; defconCount++) { /* Check any defcon needed settings */
- if (DefCon[defconCount] & DEFCON_REDUCE_SESSION) {
+
+ /* Check any defcon needed settings */
+ for (defconCount = 1; defconCount <= 5; defconCount++)
+ {
+ if (CheckDefCon(defconCount, DEFCON_REDUCE_SESSION))
+ {
CHECK(DefConSessionLimit);
}
- if (DefCon[defconCount] & DEFCON_AKILL_NEW_CLIENTS) {
+ if (CheckDefCon(defconCount, DEFCON_AKILL_NEW_CLIENTS))
+ {
CHECK(DefConAKILL);
CHECK(DefConAkillReason);
}
- if (DefCon[defconCount] & DEFCON_FORCE_CHAN_MODES) {
+ if (CheckDefCon(defconCount, DEFCON_FORCE_CHAN_MODES))
+ {
CHECK(DefConChanModes);
}
}
diff --git a/src/core/cs_register.c b/src/core/cs_register.c
index 89985fb93..62737d4aa 100644
--- a/src/core/cs_register.c
+++ b/src/core/cs_register.c
@@ -41,12 +41,6 @@ class CommandCSRegister : public Command
return MOD_CONT;
}
- if (checkDefCon(DEFCON_NO_NEW_CHANNELS))
- {
- notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
-
if (*chan == '&')
notice_lang(s_ChanServ, u, CHAN_REGISTER_NOT_LOCAL);
else if (*chan != '#')
diff --git a/src/core/cs_set.c b/src/core/cs_set.c
index 0036a752a..716144d2c 100644
--- a/src/core/cs_set.c
+++ b/src/core/cs_set.c
@@ -193,11 +193,6 @@ class CommandCSSet : public Command
ChannelMode *cm;
ChannelModeParam *cmp;
- if (checkDefCon(DEFCON_NO_MLOCK_CHANGE)) {
- notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
-
ci->ClearMLock();
if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
diff --git a/src/core/ms_sendall.c b/src/core/ms_sendall.c
index b9636f5fb..56dfbf1c2 100644
--- a/src/core/ms_sendall.c
+++ b/src/core/ms_sendall.c
@@ -33,11 +33,6 @@ class CommandMSSendAll : public Command
notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED);
return MOD_CONT;
}
- else if (checkDefCon(DEFCON_NO_NEW_MEMOS))
- {
- notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
for (i = 0; i < 1024; ++i)
{
diff --git a/src/core/ms_staff.c b/src/core/ms_staff.c
index af2e510f4..e472a0108 100644
--- a/src/core/ms_staff.c
+++ b/src/core/ms_staff.c
@@ -33,11 +33,6 @@ class CommandMSStaff : public Command
notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED);
return MOD_CONT;
}
- else if (checkDefCon(DEFCON_NO_NEW_MEMOS))
- {
- notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
for (i = 0; i < 1024; ++i)
{
diff --git a/src/core/ns_group.c b/src/core/ns_group.c
index ec00ec69d..47499bd75 100644
--- a/src/core/ns_group.c
+++ b/src/core/ns_group.c
@@ -43,11 +43,6 @@ class CommandNSGroup : public Command
notice_lang(s_NickServ, u, NICK_GROUP_DISABLED);
return MOD_CONT;
}
- if (checkDefCon(DEFCON_NO_NEW_NICKS))
- {
- notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
if (!ircdproto->IsNickValid(u->nick))
{
diff --git a/src/core/ns_register.c b/src/core/ns_register.c
index 2e580e61c..f0d4c693f 100644
--- a/src/core/ns_register.c
+++ b/src/core/ns_register.c
@@ -201,12 +201,6 @@ class CommandNSRegister : public CommandNSConfirm
return MOD_CONT;
}
- if (checkDefCon(DEFCON_NO_NEW_NICKS))
- {
- notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
-
if (!is_oper(u) && NickRegDelay && time(NULL) - u->my_signon < NickRegDelay)
{
notice_lang(s_NickServ, u, NICK_REG_DELAY, NickRegDelay);
diff --git a/src/core/os_defcon.c b/src/core/os_defcon.c
index 4227bc458..426fac779 100644
--- a/src/core/os_defcon.c
+++ b/src/core/os_defcon.c
@@ -16,6 +16,44 @@
#include "module.h"
void defcon_sendlvls(User *u);
+void runDefCon();
+void defconParseModeString(const char *str);
+void resetDefCon(int level);
+static char *defconReverseModes(const char *modes);
+class DefConTimeout;
+static DefConTimeout *timeout;
+
+class DefConTimeout : public Timer
+{
+ int level;
+
+ public:
+ DefConTimeout(int newlevel) : Timer(DefConTimeOut), level(newlevel) { }
+
+ void Tick(time_t)
+ {
+ if (DefConLevel != level)
+ {
+ DefConLevel = level;
+ FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level));
+ alog("Defcon level timeout, returning to lvl %d", level);
+ ircdproto->SendGlobops(s_OperServ, getstring(OPER_DEFCON_WALL), s_OperServ, level);
+
+ if (GlobalOnDefcon)
+ {
+ if (DefConOffMessage)
+ oper_global(NULL, "%s", DefConOffMessage);
+ else
+ oper_global(NULL, getstring(DEFCON_GLOBAL), DefConLevel);
+
+ if (GlobalOnDefconMore && !DefConOffMessage)
+ oper_global(NULL, "%s", DefconMessage);
+ }
+
+ runDefCon();
+ }
+ }
+};
class CommandOSDEFCON : public Command
{
@@ -30,12 +68,6 @@ class CommandOSDEFCON : public Command
int newLevel = 0;
const char *langglobal = getstring(DEFCON_GLOBAL);
- if (!DefConLevel) /* If we dont have a .conf setting! */
- {
- notice_lang(s_OperServ, u, OPER_DEFCON_NO_CONF);
- return MOD_CONT;
- }
-
if (!lvl)
{
notice_lang(s_OperServ, u, OPER_DEFCON_CHANGED, DefConLevel);
@@ -52,7 +84,15 @@ class CommandOSDEFCON : public Command
FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(newLevel));
- DefContimer = time(NULL);
+ if (timeout)
+ {
+ TimerManager::DelTimer(timeout);
+ timeout = NULL;
+ }
+
+ if (DefConTimeOut)
+ timeout = new DefConTimeout(5);
+
notice_lang(s_OperServ, u, OPER_DEFCON_CHANGED, DefConLevel);
defcon_sendlvls(u);
alog("Defcon level changed to %d by Oper %s", newLevel, u->nick);
@@ -97,12 +137,209 @@ class OSDEFCON : public Module
this->SetVersion("$Id$");
this->SetType(CORE);
+ if (!DefConLevel)
+ {
+ throw ModuleException("Invalid configuration settings");
+ }
+
+ Implementation i[] = { I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
+ ModuleManager::Attach(i, this, 8);
+
this->AddCommand(OPERSERV, new CommandOSDEFCON());
+
+ defconParseModeString(DefConChanModes);
}
+
void OperServHelp(User *u)
{
notice_lang(s_OperServ, u, OPER_HELP_CMD_DEFCON);
}
+
+ EventReturn OnPreUserConnect(User *u)
+ {
+ std::string mask;
+
+ if (u && is_sync(u->server) && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(u->server->name))
+ {
+ if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ mask = "*@" + std::string(u->host);
+ alog("DEFCON: adding akill for %s", mask.c_str());
+ add_akill(NULL, mask.c_str(), s_OperServ,
+ time(NULL) + DefConAKILL,
+ DefConAkillReason ? DefConAkillReason :
+ "DEFCON AKILL");
+ }
+
+ if (CheckDefCon(DEFCON_NO_NEW_CLIENTS) || CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
+ kill_user(s_OperServ, u->nick, DefConAkillReason);
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnChannelModeSet(Channel *c, ChannelModeName Name)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
+
+ if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesCI.HasMLock(Name, false))
+ {
+ c->RemoveMode(Name);
+ ircdproto->SendMode(findbot(s_OperServ), c->name, "-%c", cm->ModeChar);
+ }
+ }
+
+ void OnChannelModeUnset(Channel *c, ChannelModeName Name)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
+
+ if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesCI.HasMLock(Name, true))
+ {
+ std::string param;
+ DefConModesCI.GetParam(Name, &param);
+
+ c->SetMode(Name);
+
+ std::string buf = "+" + std::string(&cm->ModeChar);
+ if (!param.empty())
+ buf += " " + param;
+ ircdproto->SendMode(findbot(s_OperServ), c->name, buf.c_str());
+ }
+ }
+
+ EventReturn OnPreCommandRun(const char *service, User *u, const char *cmd, Command *c)
+ {
+ if (!c)
+ {
+ if (CheckDefCon(DEFCON_SILENT_OPER_ONLY) && !is_oper(u))
+ return EVENT_STOP;
+ }
+ if ((CheckDefCon(DEFCON_OPER_ONLY) || CheckDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u))
+ {
+ if (!CheckDefCon(DEFCON_SILENT_OPER_ONLY))
+ {
+ notice_lang(service, u, OPER_DEFCON_DENIED);
+ }
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> &params)
+ {
+ if (service == s_NickServ)
+ {
+ if (command == "SET")
+ {
+ if (!params.empty() && params[0] == "MLOCK")
+ {
+ if (CheckDefCon(DEFCON_NO_MLOCK_CHANGE))
+ {
+ notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (command == "REGISTER" || command == "GROUP")
+ {
+ if (CheckDefCon(DEFCON_NO_NEW_NICKS))
+ {
+ notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (service == s_ChanServ)
+ {
+ if (command == "REGISTER")
+ {
+ if (CheckDefCon(DEFCON_NO_NEW_CHANNELS))
+ {
+ notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (service == s_MemoServ)
+ {
+ if (command == "SEND" || command == "SENDALL")
+ {
+ if (CheckDefCon(DEFCON_NO_NEW_MEMOS))
+ {
+ notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
+ return EVENT_STOP;
+ }
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnUserConnect(User *u)
+ {
+ Session *session = findsession(u->host);
+ Exception *exception = find_hostip_exception(u->host, u->hostip);
+
+ if (CheckDefCon(DEFCON_REDUCE_SESSION) && !exception)
+ {
+ if (session && session->count > DefConSessionLimit)
+ {
+ if (SessionLimitExceeded)
+ ircdproto->SendMessage(findbot(s_OperServ), u->nick, SessionLimitExceeded, u->host);
+ if (SessionLimitDetailsLoc)
+ ircdproto->SendMessage(findbot(s_OperServ), u->nick, "%s", SessionLimitDetailsLoc);
+
+ kill_user(s_OperServ, u->nick, "Session limit exceeded");
+ session->hits++;
+ if (MaxSessionKill && session->hits >= MaxSessionKill)
+ {
+ char akillmask[BUFSIZE];
+ snprintf(akillmask, sizeof(akillmask), "*@%s", u->host);
+ add_akill(NULL, akillmask, s_OperServ, time(NULL) + SessionAutoKillExpiry, "Session limit exceeded");
+ ircdproto->SendGlobops(s_OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
+ }
+ }
+ }
+ }
+
+ void OnChannelModeAdd(ChannelMode *cm)
+ {
+ if (DefConChanModes)
+ {
+ std::string modes = DefConChanModes;
+
+ if (modes.find(cm->ModeChar) != std::string::npos)
+ {
+ /* New mode has been added to Anope, check to see if defcon
+ * requires it
+ */
+ defconParseModeString(DefConChanModes);
+ }
+ }
+ }
+
+ void OnChannelCreate(Channel *c)
+ {
+ char *myModes;
+ int ac;
+ const char **av;
+
+ if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
+ {
+ myModes = sstrdup(DefConChanModes);
+ ac = split_buf(myModes, &av, 1);
+
+ ircdproto->SendMode(findbot(s_OperServ), c->name, "%s", DefConChanModes);
+ chan_set_modes(s_OperServ, c, ac, av, 1);
+
+ free(av);
+ delete [] myModes;
+ }
+ }
};
/**
@@ -110,26 +347,191 @@ class OSDEFCON : public Module
**/
void defcon_sendlvls(User *u)
{
- if (checkDefCon(DEFCON_NO_NEW_CHANNELS))
+ if (CheckDefCon(DEFCON_NO_NEW_CHANNELS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_CHANNELS);
- if (checkDefCon(DEFCON_NO_NEW_NICKS))
+ if (CheckDefCon(DEFCON_NO_NEW_NICKS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_NICKS);
- if (checkDefCon(DEFCON_NO_MLOCK_CHANGE))
+ if (CheckDefCon(DEFCON_NO_MLOCK_CHANGE))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_MLOCK_CHANGE);
- if (checkDefCon(DEFCON_FORCE_CHAN_MODES) && DefConChanModes)
+ if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && DefConChanModes)
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_FORCE_CHAN_MODES, DefConChanModes);
- if (checkDefCon(DEFCON_REDUCE_SESSION))
+ if (CheckDefCon(DEFCON_REDUCE_SESSION))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_REDUCE_SESSION, DefConSessionLimit);
- if (checkDefCon(DEFCON_NO_NEW_CLIENTS))
+ if (CheckDefCon(DEFCON_NO_NEW_CLIENTS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_CLIENTS);
- if (checkDefCon(DEFCON_OPER_ONLY))
+ if (CheckDefCon(DEFCON_OPER_ONLY))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_OPER_ONLY);
- if (checkDefCon(DEFCON_SILENT_OPER_ONLY))
+ if (CheckDefCon(DEFCON_SILENT_OPER_ONLY))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_SILENT_OPER_ONLY);
- if (checkDefCon(DEFCON_AKILL_NEW_CLIENTS))
+ if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_AKILL_NEW_CLIENTS);
- if (checkDefCon(DEFCON_NO_NEW_MEMOS))
+ if (CheckDefCon(DEFCON_NO_NEW_MEMOS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_MEMOS);
}
+void runDefCon()
+{
+ char *newmodes;
+
+ if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
+ {
+ if (DefConChanModes && !DefConModesSet)
+ {
+ if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-')
+ {
+ alog("DEFCON: setting %s on all chan's", DefConChanModes);
+ DefConModesSet = 1;
+ do_mass_mode(DefConChanModes);
+ }
+ }
+ }
+ else
+ {
+ if (DefConChanModes && (DefConModesSet != 0))
+ {
+ if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-')
+ {
+ DefConModesSet = 0;
+ if ((newmodes = defconReverseModes(DefConChanModes)))
+ {
+ alog("DEFCON: setting %s on all chan's", newmodes);
+ do_mass_mode(newmodes);
+ delete [] newmodes;
+ }
+ }
+ }
+ }
+}
+
+/* Parse the defcon mlock mode string and set the correct global vars.
+ *
+ * @param str mode string to parse
+ * @return 1 if accepted, 0 if failed
+ */
+void defconParseModeString(const char *str)
+{
+ int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
+ unsigned char mode;
+ ChannelMode *cm;
+ ChannelModeParam *cmp;
+ std::string modes, param;
+
+ if (!str)
+ return;
+
+ spacesepstream ss(str);
+
+ DefConModesCI.ClearMLock();
+ ss.GetToken(modes);
+
+ /* Loop while there are modes to set */
+ for (unsigned i = 0; i < modes.size(); ++i)
+ {
+ mode = modes[i];
+
+ switch (mode)
+ {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add < 0)
+ continue;
+ }
+
+ if ((cm = ModeManager::FindChannelModeByChar(mode)))
+ {
+ if (!cm->CanSet(NULL))
+ {
+ alog("DefConChanModes mode character '%c' cannot be locked", mode);
+ continue;
+ }
+ else if (add)
+ {
+ DefConModesCI.SetMLock(cm->Name, true);
+ DefConModesCI.RemoveMLock(cm->Name, false);
+
+ if (cm->Type == MODE_PARAM)
+ {
+ cmp = static_cast<ChannelModeParam *>(cm);
+
+ if (!ss.GetToken(param))
+ {
+ alog("DefConChanModes mode character '%c' has no parameter while one is expected", mode);
+ continue;
+ }
+
+ if (!cmp->IsValid(param.c_str()))
+ continue;
+
+ DefConModesCI.SetParam(cmp->Name, param);
+ }
+ }
+ else
+ {
+ DefConModesCI.RemoveMLock(cm->Name, true);
+
+ if (DefConModesCI.HasMLock(cm->Name, true))
+ {
+ DefConModesCI.RemoveMLock(cm->Name, true);
+
+ if (cm->Type == MODE_PARAM)
+ {
+ cmp = static_cast<ChannelModeParam *>(cm);
+
+ DefConModesCI.UnsetParam(cmp->Name);
+ }
+ }
+ }
+ }
+ }
+
+ if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)))
+ {
+ /* We can't mlock +L if +l is not mlocked as well. */
+ if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_LIMIT, true))
+ {
+ DefConModesCI.RemoveMLock(CMODE_REDIRECT, true);
+ DefConModesCI.UnsetParam(CMODE_REDIRECT);
+ alog("DefConChanModes must lock mode +l as well to lock mode +L");
+ }
+ }
+
+ /* Some ircd we can't set NOKNOCK without INVITE */
+ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
+ if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK)))
+ {
+ if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_INVITE, true))
+ {
+ DefConModesCI.RemoveMLock(CMODE_NOKNOCK, true);
+ alog("DefConChanModes must lock mode +i as well to lock mode +K");
+ }
+ }
+}
+
+static char *defconReverseModes(const char *modes)
+{
+ char *newmodes = NULL;
+ unsigned i = 0;
+ if (!modes) {
+ return NULL;
+ }
+ if (!(newmodes = new char[strlen(modes) + 1])) {
+ return NULL;
+ }
+ for (i = 0; i < strlen(modes); i++) {
+ if (modes[i] == '+')
+ newmodes[i] = '-';
+ else if (modes[i] == '-')
+ newmodes[i] = '+';
+ else
+ newmodes[i] = modes[i];
+ }
+ newmodes[i] = '\0';
+ return newmodes;
+}
+
MODULE_INIT(OSDEFCON)
diff --git a/src/init.c b/src/init.c
index 6373f79c7..4acf9540d 100644
--- a/src/init.c
+++ b/src/init.c
@@ -406,14 +406,6 @@ int init_secondary(int ac, char **av)
/* Parse all remaining command-line options. */
parse_options(ac, av);
- /* Parse the defcon mode string if needed */
- if (DefConLevel) {
- if (!defconParseModeString(DefConChanModes)) {
- fprintf(stderr,
- "services.conf: The given DefConChanModes mode string was incorrect (see log for exact errors)\n");
- return -1;
- }
- }
#ifndef _WIN32
if (!nofork) {
if ((i = fork()) < 0) {
diff --git a/src/main.c b/src/main.c
index 4d9bfb1c1..1d2d05f1a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -366,7 +366,6 @@ int main(int ac, char **av, char **envp)
time_t last_update; /* When did we last update the databases? */
time_t last_expire; /* When did we last expire nicks/channels? */
time_t last_check; /* When did we last check timeouts? */
- time_t last_DefCon; /* When was DefCon last checked? */
int i;
char *progname;
@@ -429,7 +428,6 @@ int main(int ac, char **av, char **envp)
last_update = time(NULL);
last_expire = time(NULL);
last_check = time(NULL);
- last_DefCon = time(NULL);
started = 1;
@@ -481,11 +479,6 @@ int main(int ac, char **av, char **envp)
last_update = t;
}
- if ((DefConTimeOut) && (t - last_DefCon >= DefConTimeOut)) {
- resetDefCon(5);
- last_DefCon = t;
- }
-
if (delayed_quit)
break;
diff --git a/src/memoserv.c b/src/memoserv.c
index 8a508e552..64e7d831f 100644
--- a/src/memoserv.c
+++ b/src/memoserv.c
@@ -201,9 +201,6 @@ void memo_send(User * u, const char *name, const char *text, int z)
if (readonly) {
notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED);
- } else if (checkDefCon(DEFCON_NO_NEW_MEMOS)) {
- notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
- return;
} else if (!text) {
if (z == 0)
syntax_error(s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX);
@@ -388,7 +385,8 @@ void rsend_notify(User * u, Memo * m, const char *chan)
const char *fmt;
/* Only send receipt if memos are allowed */
- if ((!readonly) && (!checkDefCon(DEFCON_NO_NEW_MEMOS))) {
+ if ((!readonly))
+ {
/* Get nick alias for sender */
na = findnick(m->sender);
diff --git a/src/modes.cpp b/src/modes.cpp
index 652c94f0c..463e82945 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -10,6 +10,7 @@
*/
#include "services.h"
+#include "modules.h"
std::map<char, UserMode *> ModeManager::UserModesByChar;
std::map<UserModeName, UserMode *> ModeManager::UserModesByName;
diff --git a/src/modules/hs_request.c b/src/modules/hs_request.c
index 4f710db51..779629521 100644
--- a/src/modules/hs_request.c
+++ b/src/modules/hs_request.c
@@ -822,9 +822,6 @@ void req_send_memos(User *u, char *vIdent, char *vHost)
char host[BUFSIZE];
std::list<std::pair<std::string, std::string> >::iterator it;
- if (checkDefCon(DEFCON_NO_NEW_MEMOS))
- return;
-
if (vIdent)
snprintf(host, sizeof(host), "%s@%s", vIdent, vHost);
else
diff --git a/src/operserv.c b/src/operserv.c
index 84c5dd366..76d680a99 100644
--- a/src/operserv.c
+++ b/src/operserv.c
@@ -31,12 +31,8 @@ static void free_sqline_entry(SList * slist, void *item);
static int is_szline_entry_equal(SList * slist, void *item1, void *item2);
static void free_szline_entry(SList * slist, void *item);
-time_t DefContimer;
+std::vector<std::bitset<32> > DefCon;
int DefConModesSet = 0;
-char *defconReverseModes(const char *modes);
-
-uint32 DefConModesOn; /* Modes to be enabled during DefCon */
-uint32 DefConModesOff; /* Modes to be disabled during DefCon */
ChannelInfo DefConModesCI; /* ChannelInfo containg params for locked modes
* during DefCon; I would've done this nicer if i
* could, but all damn mode functions require a
@@ -495,14 +491,6 @@ int check_akill(const char *nick, const char *username, const char *host,
int i;
Akill *ak;
- /**
- * If DefCon is set to NO new users - kill the user ;).
- **/
- if (checkDefCon(DEFCON_NO_NEW_CLIENTS)) {
- kill_user(s_OperServ, nick, DefConAkillReason);
- return 1;
- }
-
if (akills.count == 0)
return 0;
@@ -1173,217 +1161,42 @@ static int is_szline_entry_equal(SList * slist, void *item1, void *item2)
/*************************************************************************/
-/**
- * Returns 1 if the passed level is part of the CURRENT defcon, else 0 is returned
- **/
-int checkDefCon(int level)
-{
- return DefCon[DefConLevel] & level;
-}
-
-/**
- * Automaticaly re-set the DefCon level if the time limit has expired.
- **/
-void resetDefCon(int level)
+/** Check if a certain defcon option is currently in affect
+ * @param Level The level
+ * @return true and false
+ */
+bool CheckDefCon(DefconLevel Level)
{
- char strLevel[5];
- snprintf(strLevel, 4, "%d", level);
- if (DefConLevel != level) {
- if ((DefContimer)
- && (time(NULL) - DefContimer >= DefConTimeOut)) {
- DefConLevel = level;
- FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(strLevel));
- alog("Defcon level timeout, returning to lvl %d", level);
- ircdproto->SendGlobops(s_OperServ,
- getstring(OPER_DEFCON_WALL),
- s_OperServ, level);
- if (GlobalOnDefcon) {
- if (DefConOffMessage) {
- oper_global(NULL, "%s", DefConOffMessage);
- } else {
- oper_global(NULL, getstring(DEFCON_GLOBAL),
- DefConLevel);
- }
- }
- if (GlobalOnDefconMore && !DefConOffMessage) {
- oper_global(NULL, "%s", DefconMessage);
- }
- runDefCon();
- }
- }
+ if (DefConLevel)
+ return DefCon[DefConLevel][(size_t)Level];
+ return false;
}
-/**
- * Run DefCon level specific Functions.
- **/
-void runDefCon()
+/** Check if a certain defcon option is in a certain defcon level
+ * @param level The defcon level
+ * @param Level The defcon level name
+ * @return true or false
+ */
+bool CheckDefCon(int level, DefconLevel Level)
{
- char *newmodes;
- if (checkDefCon(DEFCON_FORCE_CHAN_MODES)) {
- if (DefConChanModes && !DefConModesSet) {
- if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
- alog("DEFCON: setting %s on all chan's", DefConChanModes);
- DefConModesSet = 1;
- do_mass_mode(DefConChanModes);
- }
- }
- } else {
- if (DefConChanModes && (DefConModesSet != 0)) {
- if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
- DefConModesSet = 0;
- if ((newmodes = defconReverseModes(DefConChanModes))) {
- alog("DEFCON: setting %s on all chan's", newmodes);
- do_mass_mode(newmodes);
- delete [] newmodes;
- }
- }
- }
- }
+ return DefCon[level][(size_t)Level];
}
-/**
- * Reverse the mode string, used for remove DEFCON chan modes.
- **/
-char *defconReverseModes(const char *modes)
+/** Add a defcon level option to a defcon level
+ * @param level The defcon level
+ * @param Level The defcon level option
+ */
+void AddDefCon(int level, DefconLevel Level)
{
- char *newmodes = NULL;
- unsigned i = 0;
- if (!modes) {
- return NULL;
- }
- if (!(newmodes = new char[strlen(modes) + 1])) {
- return NULL;
- }
- for (i = 0; i < strlen(modes); i++) {
- if (modes[i] == '+')
- newmodes[i] = '-';
- else if (modes[i] == '-')
- newmodes[i] = '+';
- else
- newmodes[i] = modes[i];
- }
- newmodes[i] = '\0';
- return newmodes;
+ DefCon[level][(size_t)Level] = true;
}
-/* Parse the defcon mlock mode string and set the correct global vars.
- *
- * @param str mode string to parse
- * @return 1 if accepted, 0 if failed
+/** Remove a defcon level option from a defcon level
+ * @param level The defcon level
+ * @param Level The defcon level option
*/
-int defconParseModeString(const char *str)
+void DelDefCon(int level, DefconLevel Level)
{
- int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
- unsigned char mode;
- ChannelMode *cm;
- ChannelModeParam *cmp;
- char *str_copy = sstrdup(str); /* We need this copy as str is const -GD */
- char *param; /* Store parameters during mode parsing */
-
- /* Reinitialize everything */
- DefConModesOn = 0;
- DefConModesOff = 0;
-
- /* Initialize strtok() internal buffer */
- strtok(str_copy, " ");
-
- /* Loop while there are modes to set */
- while ((mode = *str++) && (mode != ' ')) {
- switch (mode) {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- default:
- if (add < 0)
- continue;
- }
-
- if ((cm = ModeManager::FindChannelModeByChar(mode)))
- {
- if (!cm->CanSet(NULL))
- {
- alog("DefConCHanModes mode character '%c' cannot be locked", mode);
- delete [] str_copy;
- return 0;
- }
- else if (add)
- {
- DefConModesCI.SetMLock(cm->Name, true);
- DefConModesCI.RemoveMLock(cm->Name, false);
-
- if (cm->Type == MODE_PARAM)
- {
- cmp = static_cast<ChannelModeParam *>(cm);
-
- if (!(param = strtok(NULL, " ")))
- {
- alog("DefConChanModes mode character '%c' has no parameter while one is expected", mode);
- delete [] str_copy;
- return 0;
- }
-
- if (!cmp->IsValid(param))
- continue;
-
- DefConModesCI.SetParam(cmp->Name, param);
- }
- }
- else
- {
- DefConModesCI.RemoveMLock(cm->Name, true);
-
- if (DefConModesCI.HasMLock(cm->Name, true))
- {
- DefConModesCI.RemoveMLock(cm->Name, true);
-
- if (cm->Type == MODE_PARAM)
- {
- cmp = static_cast<ChannelModeParam *>(cm);
-
- DefConModesCI.UnsetParam(cmp->Name);
- }
- }
- }
- }
- else
- {
- alog("DefConChanModes unknown mode character '%c'", mode);
- delete [] str_copy;
- return 0;
- }
- } /* while (*param) */
-
- delete [] str_copy;
-
- if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)))
- {
- /* We can't mlock +L if +l is not mlocked as well. */
- if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_LIMIT, true))
- {
- DefConModesCI.RemoveMLock(CMODE_REDIRECT, true);
- DefConModesCI.UnsetParam(CMODE_REDIRECT);
- alog("DefConChanModes must lock mode +l as well to lock mode +L");
- return 0;
- }
- }
-
- /* Some ircd we can't set NOKNOCK without INVITE */
- /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
- if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK)))
- {
- if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_INVITE, true))
- {
- DefConModesCI.RemoveMLock(CMODE_NOKNOCK, true);
- alog("DefConChanModes must lock mode +i as well to lock mode +K");
- return 0;
- }
- }
-
- /* Everything is set fine, return 1 */
- return 1;
+ DefCon[level][(size_t)Level] = false;
}
-/*************************************************************************/
diff --git a/src/sessions.c b/src/sessions.c
index 3ea37d9ca..014b9da01 100644
--- a/src/sessions.c
+++ b/src/sessions.c
@@ -138,12 +138,7 @@ int add_session(const char *nick, const char *host, char *hostip)
if (session) {
exception = find_hostip_exception(host, hostip);
- if (checkDefCon(DEFCON_REDUCE_SESSION)) {
- sessionlimit =
- exception ? exception->limit : DefConSessionLimit;
- } else {
- sessionlimit = exception ? exception->limit : DefSessionLimit;
- }
+ sessionlimit = exception ? exception->limit : DefSessionLimit;
if (sessionlimit != 0 && session->count >= sessionlimit) {
if (SessionLimitExceeded)
diff --git a/src/users.c b/src/users.c
index 8a30cd739..32dadbbba 100644
--- a/src/users.c
+++ b/src/users.c
@@ -627,7 +627,6 @@ User *do_nick(const char *source, const char *nick, const char *username, const
NickAlias *old_na; /* Old nick rec */
int nc_changed = 1; /* Did nick core change? */
int status = 0; /* Status to apply */
- char mask[USERMAX + HOSTMAX + 2];
char *logrealname;
std::string oldnick; /* stores the old nick of the user, so we can pass it to OnUserNickChange */
@@ -709,22 +708,10 @@ User *do_nick(const char *source, const char *nick, const char *username, const
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreUserConnect, OnPreUserConnect(user));
if (MOD_RESULT == EVENT_STOP)
- return;
+ return NULL;
check_akill(nick, username, host, vhost, ipbuf);
- if (is_sync(findserver(servlist, server)) && checkDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(server))
- {
- strlcpy(mask, "*@", sizeof(mask));
- strlcat(mask, host, sizeof(mask));
- alog("DEFCON: adding akill for %s", mask);
- add_akill(NULL, mask, s_OperServ,
- time(NULL) + DefConAKILL,
- DefConAkillReason ? DefConAkillReason :
- "DEFCON AKILL");
- check_akill(nick, username, host, vhost, ipbuf);
- }
-
if (ircd->sgline)
check_sgline(nick, realname);