summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile4
-rw-r--r--src/actions.c40
-rw-r--r--src/bots.cpp3
-rw-r--r--src/config.c12
-rw-r--r--src/core/bs_bot.c15
-rw-r--r--src/core/cs_drop.c3
-rw-r--r--src/core/cs_forbid.c3
-rw-r--r--src/core/db_plain.cpp99
-rw-r--r--src/core/hs_delall.c8
-rw-r--r--src/core/ns_drop.c5
-rw-r--r--src/core/ns_forbid.c5
-rw-r--r--src/core/ns_group.c20
-rw-r--r--src/core/ns_saset.c14
-rw-r--r--src/core/ns_set.c18
-rw-r--r--src/core/ns_suspend.c8
-rw-r--r--src/core/os_akill.c336
-rw-r--r--src/core/os_chankill.c10
-rw-r--r--src/core/os_defcon.c24
-rw-r--r--src/core/os_sgline.c410
-rw-r--r--src/core/os_snline.cpp426
-rw-r--r--src/core/os_sqline.c324
-rw-r--r--src/core/os_stats.c114
-rw-r--r--src/core/os_szline.c321
-rw-r--r--src/hostserv.c4
-rw-r--r--src/init.c3
-rw-r--r--src/main.c10
-rw-r--r--src/memoserv.c7
-rw-r--r--src/misc.c14
-rw-r--r--src/modules/mysql/db_mysql_read.cpp57
-rw-r--r--src/modules/mysql/db_mysql_write.cpp77
-rw-r--r--src/nickalias.cpp10
-rw-r--r--src/nickcore.cpp1
-rw-r--r--src/nickserv.c6
-rw-r--r--src/operserv.c1325
-rw-r--r--src/protocol/bahamut.c46
-rw-r--r--src/protocol/inspircd11.c32
-rw-r--r--src/protocol/inspircd12.cpp34
-rw-r--r--src/protocol/ratbox.c30
-rw-r--r--src/protocol/unreal32.c48
-rw-r--r--src/regchannel.cpp9
-rw-r--r--src/send.c18
-rw-r--r--src/sessions.c8
-rw-r--r--src/slist.c395
-rw-r--r--src/tools/db-convert.c4
-rw-r--r--src/users.c15
45 files changed, 1877 insertions, 2498 deletions
diff --git a/src/Makefile b/src/Makefile
index 04d33b040..e7c8ba2fb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,14 +1,14 @@
OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o commands.o compat.o \
config.o configreader.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
memory.o memoserv.o messages.o misc.o modes.o modules.o module.o modulemanager.o nickalias.o \
- nickcore.o nickserv.o operserv.o process.o protocol.o regchannel.o send.o servers.o sessions.o slist.o \
+ nickcore.o nickserv.o operserv.o process.o protocol.o regchannel.o send.o servers.o sessions.o \
sockets.o threadengine.o threadengine_pthread.o timers.o opertype.o users.o wildcard.o
INCLUDES = ../include/commands.h ../include/language.h \
../include/sysconf.h ../include/config.h \
../include/services.h ../include/regchannel.h \
../include/timers.h ../include/extern.h \
- ../include/modules.h ../include/slist.h ../include/hashcomp.h \
+ ../include/modules.h ../include/operserv.h ../include/hashcomp.h \
../include/threadengine.h ../include/mail.h
MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
diff --git a/src/actions.c b/src/actions.c
index e3f199e80..00ed01100 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -70,46 +70,6 @@ void kill_user(const std::string &source, const std::string &user, const std::st
/*************************************************************************/
/**
- * Check and enforce SQlines
- * @param mask of the sqline
- * @param reason for the sqline
- * @return void
- */
-void sqline(const std::string &mask, const std::string &reason)
-{
- if (ircd->chansqline)
- {
- if (mask[0] == '#')
- {
- ircdproto->SendSQLine(mask, reason);
-
- for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit)
- {
- Channel *c = cit->second;
-
- if (!Anope::Match(c->name, mask, false))
- continue;
- for (CUserList::iterator it = c->users.begin(); it != c->users.end();)
- {
- UserContainer *uc = *it;
- ++it;
-
- if (is_oper(uc->user))
- continue;
- c->Kick(NULL, uc->user, "%s", reason.c_str());
- }
- }
- }
- else
- ircdproto->SendSQLine(mask, reason);
- }
- else
- ircdproto->SendSQLine(mask, reason);
-}
-
-/*************************************************************************/
-
-/**
* Unban the nick from a channel
* @param ci channel info for the channel
* @param nick to remove the ban for
diff --git a/src/bots.cpp b/src/bots.cpp
index 034472774..3c23da7d4 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -68,7 +68,8 @@ BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std::
if (Me && Me->GetUplink()->IsSynced())
{
ircdproto->SendClientIntroduction(this->nick, this->user, this->host, this->real, ircd->pseudoclient_mode, this->uid);
- ircdproto->SendSQLine(this->nick, "Reserved for services");
+ XLine x(this->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
}
}
diff --git a/src/config.c b/src/config.c
index 1dd312723..a1264abce 100644
--- a/src/config.c
+++ b/src/config.c
@@ -738,11 +738,11 @@ int ServerConfig::Read(bool bail)
{"operserv", "logmaxusers", "no", new ValueContainerBool(&Config.LogMaxUsers), DT_BOOLEAN, NoValidation},
{"operserv", "autokillexpiry", "0", new ValueContainerTime(&Config.AutokillExpiry), DT_TIME, ValidateNotZero},
{"operserv", "chankillexpiry", "0", new ValueContainerTime(&Config.ChankillExpiry), DT_TIME, ValidateNotZero},
- {"operserv", "sglineexpiry", "0", new ValueContainerTime(&Config.SGLineExpiry), DT_TIME, ValidateNotZero},
+ {"operserv", "snlineexpiry", "0", new ValueContainerTime(&Config.SNLineExpiry), DT_TIME, ValidateNotZero},
{"operserv", "sqlineexpiry", "0", new ValueContainerTime(&Config.SQLineExpiry), DT_TIME, ValidateNotZero},
{"operserv", "szlineexpiry", "0", new ValueContainerTime(&Config.SZLineExpiry), DT_TIME, ValidateNotZero},
{"operserv", "akillonadd", "no", new ValueContainerBool(&Config.AkillOnAdd), DT_BOOLEAN, NoValidation},
- {"operserv", "killonsgline", "no", new ValueContainerBool(&Config.KillonSGline), DT_BOOLEAN, NoValidation},
+ {"operserv", "killonsnline", "no", new ValueContainerBool(&Config.KillonSNline), DT_BOOLEAN, NoValidation},
{"operserv", "killonsqline", "no", new ValueContainerBool(&Config.KillonSQline), DT_BOOLEAN, NoValidation},
{"operserv", "notifications", "", new ValueContainerString(&OSNotifications), DT_STRING, NoValidation},
{"operserv", "limitsessions", "no", new ValueContainerBool(&Config.LimitSessions), DT_BOOLEAN, NoValidation},
@@ -1633,8 +1633,8 @@ int read_config(int reload)
}
}
- Config.WallOper = Config.WallBadOS = Config.WallOSGlobal = Config.WallOSMode = Config.WallOSClearmodes = Config.WallOSKick = Config.WallOSAkill = Config.WallOSSGLine = Config.WallOSSQLine =
- Config.WallOSSZLine = Config.WallOSNoOp = Config.WallOSJupe = Config.WallAkillExpire = Config.WallSGLineExpire = Config.WallSQLineExpire = Config.WallSZLineExpire = Config.WallExceptionExpire = Config.WallGetpass = Config.WallSetpass = Config.WallForbid =
+ Config.WallOper = Config.WallBadOS = Config.WallOSGlobal = Config.WallOSMode = Config.WallOSClearmodes = Config.WallOSKick = Config.WallOSAkill = Config.WallOSSNLine = Config.WallOSSQLine =
+ Config.WallOSSZLine = Config.WallOSNoOp = Config.WallOSJupe = Config.WallAkillExpire = Config.WallSNLineExpire = Config.WallSQLineExpire = Config.WallSZLineExpire = Config.WallExceptionExpire = Config.WallGetpass = Config.WallSetpass = Config.WallForbid =
Config.WallDrop = false;
if (!OSNotifications.empty()) {
spacesepstream notifications(OSNotifications);
@@ -1647,13 +1647,13 @@ int read_config(int reload)
else if (notice == "osclearmodes") Config.WallOSClearmodes = true;
else if (notice == "oskick") Config.WallOSKick = true;
else if (notice == "osakill") Config.WallOSAkill = true;
- else if (notice == "ossgline") Config.WallOSSGLine = true;
+ else if (notice == "ossnline") Config.WallOSSNLine = true;
else if (notice == "ossqline") Config.WallOSSQLine = true;
else if (notice == "osszline") Config.WallOSSZLine = true;
else if (notice == "osnoop") Config.WallOSNoOp = true;
else if (notice == "osjupe") Config.WallOSJupe = true;
else if (notice == "akillexpire") Config.WallAkillExpire = true;
- else if (notice == "sglineexpire") Config.WallSGLineExpire = true;
+ else if (notice == "snlineexpire") Config.WallSNLineExpire = true;
else if (notice == "sqlineexpire") Config.WallSQLineExpire = true;
else if (notice == "szlineexpire") Config.WallSZLineExpire = true;
else if (notice == "exceptionexpire") Config.WallExceptionExpire = true;
diff --git a/src/core/bs_bot.c b/src/core/bs_bot.c
index d8cb3db6d..2c5888554 100644
--- a/src/core/bs_bot.c
+++ b/src/core/bs_bot.c
@@ -242,7 +242,8 @@ class CommandBSBot : public Command
the old nick. */
if (ircd->sqline)
{
- ircdproto->SendSQLineDel(bi->nick);
+ XLine x(bi->nick.c_str());
+ ircdproto->SendSQLineDel(&x);
}
/* We check whether user with this nick is online, and kill it if so */
@@ -251,9 +252,11 @@ class CommandBSBot : public Command
if (user)
ircdproto->SendQuit(bi, "Quit: Be right back");
- else {
+ else
+ {
ircdproto->SendChangeBotNick(bi, nick);
- ircdproto->SendSQLine(bi->nick, "Reserved for services");
+ XLine x(bi->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
}
if (bi->nick != nick)
@@ -273,7 +276,8 @@ class CommandBSBot : public Command
bi->uid = ts6_uid_retrieve();
}
ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid);
- ircdproto->SendSQLine(bi->nick, "Reserved for services");
+ XLine x(bi->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
bi->RejoinAll();
}
@@ -309,7 +313,8 @@ class CommandBSBot : public Command
FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi));
ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick.c_str());
- ircdproto->SendSQLineDel(bi->nick);
+ XLine x(bi->nick.c_str());
+ ircdproto->SendSQLineDel(&x);
delete bi;
notice_lang(Config.s_BotServ, u, BOT_BOT_DELETED, nick);
diff --git a/src/core/cs_drop.c b/src/core/cs_drop.c
index baae58026..afeb522a9 100644
--- a/src/core/cs_drop.c
+++ b/src/core/cs_drop.c
@@ -66,7 +66,8 @@ class CommandCSDrop : public Command
if (ircd->chansqline && (ci->HasFlag(CI_FORBIDDEN)))
{
- ircdproto->SendSQLineDel(ci->name.c_str());
+ XLine x(ci->name.c_str());
+ ircdproto->SendSQLineDel(&x);
}
Alog() << Config.s_ChanServ << ": Channel " << ci->name << " dropped by " << u->GetMask() << " (founder: "
diff --git a/src/core/cs_forbid.c b/src/core/cs_forbid.c
index 06447c800..141865bf7 100644
--- a/src/core/cs_forbid.c
+++ b/src/core/cs_forbid.c
@@ -87,7 +87,8 @@ class CommandCSForbid : public Command
if (ircd->chansqline)
{
- ircdproto->SendSQLine(ci->name, reason ? reason : "Forbidden");
+ XLine x(chan, "Forbidden");
+ ircdproto->SendSQLine(&x);
}
Alog() << Config.s_ChanServ << ": " << u->nick << " set FORBID for channel " << ci->name;
diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp
index 710d4eb50..98212539e 100644
--- a/src/core/db_plain.cpp
+++ b/src/core/db_plain.cpp
@@ -458,31 +458,42 @@ static void LoadOperInfo(const std::vector<std::string> &params)
maxusercnt = atol(params[1].c_str());
maxusertime = strtol(params[2].c_str(), NULL, 10);
}
- else if (params[0] == "SGLINE" || params[0] == "SQLINE" || params[0] == "SZLINE")
+ else if (params[0] == "SNLINE" || params[0] == "SQLINE" || params[0] == "SZLINE")
{
- SXLine *sx = new SXLine;
- sx->mask = sstrdup(params[1].c_str());
- sx->by = sstrdup(params[2].c_str());
- sx->seton = atol(params[3].c_str());
- sx->expires = atol(params[4].c_str());
- sx->reason = sstrdup(params[5].c_str());
- if (params[0] == "SGLINE")
- slist_add(&sglines, sx);
- else if (params[0] == "SQLINE")
- slist_add(&sqlines, sx);
- else if (params[0] == "SZLINE")
- slist_add(&szlines, sx);
+ ci::string mask = params[1].c_str();
+ ci::string by = params[2].c_str();
+ time_t seton = atol(params[3].c_str());
+ time_t expires = atol(params[4].c_str());
+ std::string reason = params[5];
+
+ XLine *x = NULL;
+ if (params[0] == "SNLINE" && SNLine)
+ x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ else if (params[0] == "SQLINE" && SQLine)
+ x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ else if (params[0] == "SZLINE" && SZLine)
+ x = SZLine->Add(NULL, NULL, mask, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
- else if (params[0] == "AKILL")
+ else if (params[0] == "AKILL" && SGLine)
{
- Akill *ak = new Akill;
- ak->user = sstrdup(params[1].c_str());
- ak->host = sstrdup(params[2].c_str());
- ak->by = sstrdup(params[3].c_str());
- ak->seton = atol(params[4].c_str());
- ak->expires = atol(params[5].c_str());
- ak->reason = sstrdup(params[6].c_str());
- slist_add(&akills, ak);
+ ci::string user = params[1].c_str();
+ ci::string host = params[2].c_str();
+ ci::string by = params[3].c_str();
+ time_t seton = atol(params[4].c_str());
+ time_t expires = atol(params[5].c_str());
+ std::string reason = params[6];
+
+ XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
else if (params[0] == "EXCEPTION")
{
@@ -1133,7 +1144,7 @@ class DBPlain : public Module
}
db << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << endl;
if (ci->capsmin)
- db << "MD BI CAPSMINS " << ci->capsmin << endl;
+ db << "MD BI CAPSMIN " << ci->capsmin << endl;
if (ci->capspercent)
db << "MD BI CAPSPERCENT " << ci->capspercent << endl;
if (ci->floodlines)
@@ -1153,28 +1164,42 @@ class DBPlain : public Module
FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, ci));
}
- for (int i = 0; i < akills.count; ++i)
+ db << "OS STATS " << maxusercnt << " " << maxusertime << endl;
+
+ if (SGLine)
{
- Akill *ak = static_cast<Akill *>(akills.list[i]);
- db << "OS AKILL " << ak->user << " " << ak->host << " " << ak->by << " " << ak->seton << " " << ak->expires << " :" << ak->reason << endl;
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
+ {
+ XLine *x = SGLine->GetEntry(i);
+ db << "OS AKILL " << x->GetUser() << " " << x->GetHost() << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- db << "OS STATS " << maxusercnt << " " << maxusertime << endl;
- SXLine *sx;
- for (int i = 0; i < sglines.count; ++i)
+ if (SNLine)
{
- sx = static_cast<SXLine *>(sglines.list[i]);
- db << "OS SGLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl;
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ XLine *x = SNLine->GetEntry(i);
+ db << "OS SNLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- for (int i = 0; i < sqlines.count; ++i)
+
+ if (SQLine)
{
- sx = static_cast<SXLine *>(sqlines.list[i]);
- db << "OS SQLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl;
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
+ {
+ XLine *x = SQLine->GetEntry(i);
+ db << "OS SQLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- for (int i = 0; i < szlines.count; ++i)
+
+ if (SZLine)
{
- sx = static_cast<SXLine *>(szlines.list[i]);
- db << "OS SZLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl;
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
+ {
+ XLine *x = SZLine->GetEntry(i);
+ db << "OS SZLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
for (int i = 0; i < nexceptions; i++)
diff --git a/src/core/hs_delall.c b/src/core/hs_delall.c
index 05c67660d..aaab9b6e1 100644
--- a/src/core/hs_delall.c
+++ b/src/core/hs_delall.c
@@ -23,10 +23,8 @@ class CommandHSDelAll : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- int i;
const char *nick = params[0].c_str();
NickAlias *na;
- NickCore *nc;
if ((na = findnick(nick)))
{
if (na->HasFlag(NS_FORBIDDEN))
@@ -35,10 +33,10 @@ class CommandHSDelAll : public Command
return MOD_CONT;
}
FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na));
- nc = na->nc;
- for (i = 0; i < nc->aliases.count; ++i)
+ NickCore *nc = na->nc;
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it)
{
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
+ na = *it;
na->hostinfo.RemoveVhost();
}
Alog() << "vHosts for all nicks in group \002" << nc->display << "\002 deleted by oper \002" << u->nick << "\002";
diff --git a/src/core/ns_drop.c b/src/core/ns_drop.c
index 72f99cf7a..16c73f04a 100644
--- a/src/core/ns_drop.c
+++ b/src/core/ns_drop.c
@@ -69,7 +69,10 @@ class CommandNSDrop : public Command
notice_lang(Config.s_NickServ, u, READ_ONLY_MODE);
if (ircd->sqline && (na->HasFlag(NS_FORBIDDEN)))
- ircdproto->SendSQLineDel(na->nick);
+ {
+ XLine x(na->nick);
+ ircdproto->SendSQLineDel(&x);
+ }
Alog() << Config.s_NickServ << ": " << u->GetMask() << " dropped nickname " << na->nick << " (group " << na->nc->display << ") (e-mail: " << (na->nc->email ? na->nc->email : "none") << ")";
delete na;
diff --git a/src/core/ns_forbid.c b/src/core/ns_forbid.c
index e4c179243..70943ceeb 100644
--- a/src/core/ns_forbid.c
+++ b/src/core/ns_forbid.c
@@ -69,7 +69,10 @@ class CommandNSForbid : public Command
if (ircd->sqline)
- ircdproto->SendSQLine(na->nick, reason ? reason : "Forbidden");
+ {
+ XLine x(na->nick, reason ? reason : "Forbidden");
+ ircdproto->SendSQLine(&x);
+ }
if (Config.WallForbid)
ircdproto->SendGlobops(NickServ, "\2%s\2 used FORBID on \2%s\2", u->nick.c_str(), nick);
diff --git a/src/core/ns_group.c b/src/core/ns_group.c
index 10478f8a1..dd6f9b3be 100644
--- a/src/core/ns_group.c
+++ b/src/core/ns_group.c
@@ -80,7 +80,7 @@ class CommandNSGroup : public Command
notice_lang(Config.s_NickServ, u, NICK_GROUP_SAME, target->nick);
else if (na && na->nc != u->Account())
notice_lang(Config.s_NickServ, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ);
- else if (Config.NSMaxAliases && (target->nc->aliases.count >= Config.NSMaxAliases) && !target->nc->IsServicesOper())
+ else if (Config.NSMaxAliases && (target->nc->aliases.size() >= Config.NSMaxAliases) && !target->nc->IsServicesOper())
notice_lang(Config.s_NickServ, u, NICK_GROUP_TOO_MANY, target->nick, Config.s_NickServ, Config.s_NickServ);
else if (enc_check_password(pass, target->nc->pass) != 1)
{
@@ -163,7 +163,7 @@ class CommandNSUngroup : public Command
const char *nick = params.size() ? params[0].c_str() : NULL;
NickAlias *na = nick ? findnick(nick) : findnick(u->nick);
- if (u->Account()->aliases.count == 1)
+ if (u->Account()->aliases.size() == 1)
notice_lang(Config.s_NickServ, u, NICK_UNGROUP_ONE_NICK);
else if (!na)
notice_lang(Config.s_NickServ, u, NICK_X_NOT_REGISTERED, nick ? nick : u->nick.c_str());
@@ -173,14 +173,19 @@ class CommandNSUngroup : public Command
{
NickCore *oldcore = na->nc;
- slist_remove(&oldcore->aliases, na);
+ std::list<NickAlias *>::iterator it = std::find(oldcore->aliases.begin(), oldcore->aliases.end(), na);
+ if (it != oldcore->aliases.end())
+ {
+ oldcore->aliases.erase(it);
+ }
+
if (!stricmp(oldcore->display, na->nick))
{
change_core_display(oldcore);
}
na->nc = new NickCore(na->nick);
- slist_add(&na->nc->aliases, na);
+ na->nc->aliases.push_back(na);
na->nc->pass = oldcore->pass;
if (oldcore->email)
@@ -224,7 +229,6 @@ class CommandNSGList : public Command
const char *nick = params.size() ? params[0].c_str() : NULL;
NickCore *nc = u->Account();
- int i;
if (nick && (stricmp(nick, u->nick.c_str()) && !u->Account()->IsServicesOper()))
notice_lang(Config.s_NickServ, u, ACCESS_DENIED, Config.s_NickServ);
@@ -238,9 +242,9 @@ class CommandNSGList : public Command
int wont_expire;
notice_lang(Config.s_NickServ, u, nick ? NICK_GLIST_HEADER_X : NICK_GLIST_HEADER, nc->display);
- for (i = 0; i < nc->aliases.count; ++i)
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it)
{
- NickAlias *na2 = static_cast<NickAlias *>(nc->aliases.list[i]);
+ NickAlias *na2 = *it;
if (!(wont_expire = na2->HasFlag(NS_NO_EXPIRE)))
{
@@ -250,7 +254,7 @@ class CommandNSGList : public Command
}
notice_lang(Config.s_NickServ, u, wont_expire ? NICK_GLIST_REPLY_NOEXPIRE : NICK_GLIST_REPLY, na2->nick, buf);
}
- notice_lang(Config.s_NickServ, u, NICK_GLIST_FOOTER, nc->aliases.count);
+ notice_lang(Config.s_NickServ, u, NICK_GLIST_FOOTER, nc->aliases.size());
}
return MOD_CONT;
}
diff --git a/src/core/ns_saset.c b/src/core/ns_saset.c
index 3bedbd301..7117ffab7 100644
--- a/src/core/ns_saset.c
+++ b/src/core/ns_saset.c
@@ -20,8 +20,6 @@ private:
CommandReturn DoSetDisplay(User *u, const std::vector<ci::string> &params, NickCore *nc)
{
ci::string param = params.size() > 2 ? params[2] : "";
- int i;
- NickAlias *na;
if (param.empty())
{
@@ -30,17 +28,9 @@ private:
}
/* First check whether param is a valid nick of the group */
- for (i = 0; i < nc->aliases.count; ++i)
- {
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
- if (na->nick == param)
- {
- param = na->nick; /* Because case may differ */
- break;
- }
- }
+ NickAlias *na = findnick(param);
- if (i == nc->aliases.count)
+ if (!na || na->nc != nc)
{
notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_INVALID, nc->display);
return MOD_CONT;
diff --git a/src/core/ns_set.c b/src/core/ns_set.c
index 79561af76..1325f6b32 100644
--- a/src/core/ns_set.c
+++ b/src/core/ns_set.c
@@ -27,21 +27,9 @@ class CommandNSSet : public Command
return MOD_CONT;
}
- int i;
- NickAlias *na;
-
- /* First check whether param is a valid nick of the group */
- for (i = 0; i < nc->aliases.count; ++i)
- {
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
- if (na->nick == param)
- {
- param = na->nick; /* Because case may differ */
- break;
- }
- }
-
- if (i == nc->aliases.count)
+ NickAlias *na = findnick(param);
+
+ if (!na || na->nc != nc)
{
notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_INVALID);
return MOD_CONT;
diff --git a/src/core/ns_suspend.c b/src/core/ns_suspend.c
index 1f0b885a4..94408adac 100644
--- a/src/core/ns_suspend.c
+++ b/src/core/ns_suspend.c
@@ -23,11 +23,10 @@ class CommandNSSuspend : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- NickAlias *na, *na2;
+ NickAlias *na;
User *u2;
const char *nick = params[0].c_str();
const char *reason = params[1].c_str();
- int i;
if (readonly)
{
@@ -61,9 +60,10 @@ class CommandNSSuspend : public Command
na->nc->UnsetFlag(NI_KILL_QUICK);
na->nc->UnsetFlag(NI_KILL_IMMED);
- for (i = 0; i < na->nc->aliases.count; ++i)
+ for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(); it != na->nc->aliases.end(); ++it)
{
- na2 = static_cast<NickAlias *>(na->nc->aliases.list[i]);
+ NickAlias *na2 = *it;
+
if (na2->nc == na->nc)
{
if (na2->last_quit)
diff --git a/src/core/os_akill.c b/src/core/os_akill.c
index 590767bbe..47a2b9dd1 100644
--- a/src/core/os_akill.c
+++ b/src/core/os_akill.c
@@ -14,24 +14,123 @@
#include "module.h"
-int akill_view_callback(SList *slist, int number, void *item, va_list args);
-int akill_list_callback(SList *slist, int number, void *item, va_list args);
-int akill_view(int number, Akill *ak, User *u, int *sent_header);
-int akill_list(int number, Akill *ak, User *u, int *sent_header);
+class AkillDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ AkillDelCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), Deleted(0)
+ {
+ }
+
+ ~AkillDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
+ else if (Deleted == 1)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SGLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SGLine->DelXLine(x);
+ }
+};
+
+class AkillListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ AkillListCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), SentHeader(false)
+ {
+ }
+
+ ~AkillListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
+ else
+ notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SGLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
-static int akill_del_callback(SList *slist, void *item, va_list args)
+class AkillViewCallback : public AkillListCallback
{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, static_cast<Akill *>(item)));
- return 1;
-}
+ public:
+ AkillViewCallback(User *_u, const std::string &numlist) : AkillListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SGLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, expirebuf, x->Reason.c_str());
+ }
+};
class CommandOSAKill : public Command
{
private:
CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
{
- int deleted = 0;
unsigned last_param = 2;
const char *expiry, *mask;
char reason[BUFSIZE];
@@ -68,37 +167,13 @@ class CommandOSAKill : public Command
return MOD_CONT;
}
snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
- if (mask && *reason) {
- /* We first do some sanity check on the proposed mask. */
- if (strchr(mask, '!'))
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_NICK);
- return MOD_CONT;
- }
-
- if (!strchr(mask, '@'))
- {
- notice_lang(Config.s_OperServ, u, BAD_USERHOST_MASK);
- return MOD_CONT;
- }
+ if (mask && *reason)
+ {
+ XLine *x = SGLine->Add(OperServ, u, mask, expires, reason);
- if (mask && strspn(mask, "~@.*?") == strlen(mask))
- {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
+ if (!x)
return MOD_CONT;
- }
-
- std::string realreason;
- if (Config.AddAkiller)
- realreason = "[" + u->nick + "] " + std::string(reason);
- else
- realreason = reason;
- deleted = add_akill(u, mask, u->nick.c_str(), expires, realreason.c_str());
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, deleted);
notice_lang(Config.s_OperServ, u, OPER_AKILL_ADDED, mask);
if (Config.WallOSAkill)
@@ -131,7 +206,7 @@ class CommandOSAKill : public Command
snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
}
- ircdproto->SendGlobops(OperServ, "%s added an AKILL for %s (%s) (%s)", u->nick.c_str(), mask, realreason.c_str(), buf);
+ ircdproto->SendGlobops(OperServ, "%s added an AKILL for %s (%s) (%s)", u->nick.c_str(), mask, reason, buf);
}
if (readonly)
@@ -145,49 +220,36 @@ class CommandOSAKill : public Command
CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[0] : "";
- if (!mask)
+ if (mask.empty())
{
this->OnSyntaxError(u, "DEL");
return MOD_CONT;
}
- if (!akills.count)
+ if (SGLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
return MOD_CONT;
}
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&akills, mask, akill_del_callback, u);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, res);
- }
+ if (isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkillDelCallback(u, mask.c_str()))->Process();
else
{
- if ((res = slist_indexof(&akills, const_cast<void *>(static_cast<const void *>(mask)))) == -1) // XXX: possibly unsafe cast
+ XLine *x = SGLine->HasEntry(mask);
+
+ if (!x)
{
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NOT_FOUND, mask);
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NOT_FOUND, mask.c_str());
return MOD_CONT;
}
- FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, static_cast<Akill *>(akills.list[res])));
+ FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, x));
- slist_delete(&akills, res);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED, mask);
+ AkillDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED, mask.c_str());
}
if (readonly)
@@ -198,41 +260,37 @@ class CommandOSAKill : public Command
CommandReturn DoList(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res, sent_header = 0;
-
- if (!akills.count)
+ if (SGLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
return MOD_CONT;
}
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[1] : "";
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&akills, mask, &akill_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- return MOD_CONT;
- }
- else
- notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkillListCallback(u, mask.c_str()))->Process();
else
{
- int i;
- char amask[BUFSIZE];
+ bool SentHeader = false;
- for (i = 0; i < akills.count; ++i)
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
{
- snprintf(amask, sizeof(amask), "%s@%s", (static_cast<Akill *>(akills.list[i]))->user, (static_cast<Akill *>(akills.list[i]))->host);
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- akill_list(i + 1, static_cast<Akill *>(akills.list[i]), u, &sent_header);
+ XLine *x = SGLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER);
+ }
+
+ AkillListCallback::DoList(u, x, i);
+ }
}
- if (!sent_header)
+ if (!SentHeader)
notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
else
notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
@@ -243,39 +301,37 @@ class CommandOSAKill : public Command
CommandReturn DoView(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res, sent_header = 0;
-
- if (!akills.count)
+ if (SGLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
return MOD_CONT;
}
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[1] : "";
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&akills, mask, &akill_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- return MOD_CONT;
- }
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkillViewCallback(u, mask.c_str()))->Process();
else
{
- int i;
- char amask[BUFSIZE];
+ bool SentHeader = false;
- for (i = 0; i < akills.count; ++i)
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
{
- snprintf(amask, sizeof(amask), "%s@%s", (static_cast<Akill *>(akills.list[i]))->user, (static_cast<Akill *>(akills.list[i]))->host);
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- akill_view(i + 1, static_cast<Akill *>(akills.list[i]), u, &sent_header);
+ XLine *x = SGLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER);
+ }
+
+ AkillViewCallback::DoList(u, x, i);
+ }
}
- if (!sent_header)
+ if (!SentHeader)
notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
}
@@ -285,7 +341,7 @@ class CommandOSAKill : public Command
CommandReturn DoClear(User *u)
{
FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, NULL));
- slist_clear(&akills, 1);
+ SGLine->Clear();
notice_lang(Config.s_OperServ, u, OPER_AKILL_CLEAR);
return MOD_CONT;
@@ -344,66 +400,4 @@ class OSAKill : public Module
}
};
-int akill_view(int number, Akill *ak, User *u, int *sent_header)
-{
- char mask[BUFSIZE];
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!ak)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER);
- *sent_header = 1;
- }
-
- snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host);
- tm = *localtime(&ak->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), ak->expires);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_FORMAT, number, mask, ak->by, timebuf, expirebuf, ak->reason);
-
- return 1;
-}
-
-/* Lists an AKILL entry, prefixing it with the header if needed */
-int akill_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return akill_list(number, static_cast<Akill *>(item), u, sent_header);
-}
-
-/* Callback for enumeration purposes */
-int akill_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return akill_view(number, static_cast<Akill *>(item), u, sent_header);
-}
-
-/* Lists an AKILL entry, prefixing it with the header if needed */
-int akill_list(int number, Akill *ak, User *u, int *sent_header)
-{
- char mask[BUFSIZE];
-
- if (!ak)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER);
- *sent_header = 1;
- }
-
- snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_FORMAT, number, mask, ak->reason);
-
- return 1;
-}
-
MODULE_INIT(OSAKill)
diff --git a/src/core/os_chankill.c b/src/core/os_chankill.c
index 6d06f75c5..aa6ffa142 100644
--- a/src/core/os_chankill.c
+++ b/src/core/os_chankill.c
@@ -26,7 +26,6 @@ class CommandOSChanKill : public Command
const char *expiry, *channel;
char reason[BUFSIZE];
time_t expires;
- char *mask = new char[Config.UserLen + Config.HostLen + 2];
unsigned last_param = 1;
Channel *c;
@@ -46,7 +45,6 @@ class CommandOSChanKill : public Command
if (expires != 0 && expires < 60)
{
notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- delete [] mask;
return MOD_CONT;
}
else if (expires > 0)
@@ -55,7 +53,6 @@ class CommandOSChanKill : public Command
if (params.size() <= last_param)
{
this->OnSyntaxError(u, "");
- delete [] mask;
return MOD_CONT;
}
snprintf(reason, sizeof(reason), "%s%s", params[last_param].c_str(), (params.size() > last_param + 1 ? params[last_param + 1].c_str() : ""));
@@ -77,10 +74,8 @@ class CommandOSChanKill : public Command
if (is_oper(uc->user))
continue;
- strlcpy(mask, "*@", Config.UserLen + Config.HostLen + 2); /* Use *@" for the akill's, */
- strlcat(mask, uc->user->host, Config.UserLen + Config.HostLen + 2);
- add_akill(NULL, mask, Config.s_OperServ, expires, realreason.c_str());
- check_akill(uc->user->nick.c_str(), uc->user->GetIdent().c_str(), uc->user->host, NULL, NULL);
+ SGLine->Add(OperServ, u, ci::string("*@") + uc->user->host, expires, realreason);
+ SGLine->Check(uc->user);
}
if (Config.WallOSAkill)
ircdproto->SendGlobops(OperServ, "%s used CHANKILL on %s (%s)", u->nick.c_str(), channel, realreason.c_str());
@@ -88,7 +83,6 @@ class CommandOSChanKill : public Command
else
notice_lang(Config.s_OperServ, u, CHAN_X_NOT_IN_USE, channel);
}
- delete [] mask;
return MOD_CONT;
}
diff --git a/src/core/os_defcon.c b/src/core/os_defcon.c
index edb2a51aa..6f9197a2b 100644
--- a/src/core/os_defcon.c
+++ b/src/core/os_defcon.c
@@ -160,12 +160,10 @@ class OSDEFCON : public Module
{
if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
{
- std::string mask = "*@" + std::string(u->host);
- Alog() << "DEFCON: adding akill for " << mask;
- add_akill(NULL, mask.c_str(), Config.s_OperServ,
- time(NULL) + Config.DefConAKILL,
- Config.DefConAkillReason ? Config.DefConAkillReason :
- "DEFCON AKILL");
+ Alog() << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add(NULL, NULL, ci::string("*@") + u->host, time(NULL) + Config.DefConAKILL, Config.DefConAkillReason ? Config.DefConAkillReason : "DEFCON AKILL");
+ if (x)
+ x->By = Config.s_OperServ;
}
if (CheckDefCon(DEFCON_NO_NEW_CLIENTS) || CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
@@ -199,7 +197,7 @@ class OSDEFCON : public Module
{
std::string param;
- if (GetDefConParam(Name, &param))
+ if (GetDefConParam(Name, param))
{
c->SetMode(OperServ, Name, param);
}
@@ -301,10 +299,8 @@ class OSDEFCON : public Module
session->hits++;
if (Config.MaxSessionKill && session->hits >= Config.MaxSessionKill)
{
- char akillmask[BUFSIZE];
- snprintf(akillmask, sizeof(akillmask), "*@%s", u->host);
- add_akill(NULL, akillmask, Config.s_OperServ, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
- ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
+ SGLine->Add(NULL, NULL, ci::string("*@") + u->host, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
+ ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host);
}
}
}
@@ -373,18 +369,18 @@ void runDefCon()
if (Config.DefConChanModes[0] == '+' || Config.DefConChanModes[0] == '-')
{
Alog() << "DEFCON: setting " << Config.DefConChanModes << " on all channels";
- DefConModesSet = 1;
+ DefConModesSet = true;
MassChannelModes(OperServ, Config.DefConChanModes);
}
}
}
else
{
- if (Config.DefConChanModes && (DefConModesSet != 0))
+ if (Config.DefConChanModes && DefConModesSet)
{
if (Config.DefConChanModes[0] == '+' || Config.DefConChanModes[0] == '-')
{
- DefConModesSet = 0;
+ DefConModesSet = false;
if ((newmodes = defconReverseModes(Config.DefConChanModes)))
{
Alog() << "DEFCON: setting " << newmodes << " on all channels";
diff --git a/src/core/os_sgline.c b/src/core/os_sgline.c
deleted file mode 100644
index 27b062ee0..000000000
--- a/src/core/os_sgline.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-#include "hashcomp.h"
-
-int sgline_view_callback(SList *slist, int number, void *item, va_list args);
-int sgline_list_callback(SList *slist, int number, void *item, va_list args);
-int sgline_view(int number, SXLine *sx, User *u, int *sent_header);
-int sgline_list(int number, SXLine *sx, User *u, int *sent_header);
-
-static int sxline_del_callback(SList *slist, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SGLINE));
- return 1;
-}
-
-class CommandOSSGLine : public Command
-{
- private:
- CommandReturn OnAdd(User *u, const std::vector<ci::string> &params)
- {
- int deleted = 0;
- unsigned last_param = 2;
- const char *param, *expiry;
- char rest[BUFSIZE];
- time_t expires;
-
- param = params.size() > 1 ? params[1].c_str() : NULL;
- if (param && *param == '+')
- {
- expiry = param;
- param = params.size() > 2 ? params[2].c_str() : NULL;
- last_param = 3;
- }
- else
- expiry = NULL;
-
- expires = expiry ? dotime(expiry) : Config.SGLineExpiry;
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (expiry && isdigit(expiry[strlen(expiry) - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- return MOD_CONT;
- }
- else if (expires > 0)
- expires += time(NULL);
-
- if (!param)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
- snprintf(rest, sizeof(rest), "%s%s%s", param, params.size() > last_param ? " " : "", params.size() > last_param ? params[last_param].c_str() : "");
-
- if (std::string(rest).find(':') == std::string::npos)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
-
- sepstream sep(rest, ':');
- std::string mask;
- sep.GetToken(mask);
- std::string reason = sep.GetRemaining();
-
- if (!mask.empty() && !reason.empty()) {
- /* Clean up the last character of the mask if it is a space
- * See bug #761
- */
- unsigned masklen = mask.size();
- if (mask[masklen - 1] == ' ')
- mask.erase(masklen - 1);
-
- const char *cmask = mask.c_str();
-
- /* We first do some sanity check on the proposed mask. */
-
- if (!mask.empty() && strspn(cmask, "*?") == strlen(cmask)) {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, cmask);
- return MOD_CONT;
- }
-
- deleted = add_sgline(u, cmask, u->nick.c_str(), expires, reason.c_str());
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, deleted);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_ADDED, cmask);
-
- if (Config.WallOSSGLine)
- {
- char buf[128];
-
- if (!expires)
- strcpy(buf, "does not expire");
- else
- {
- int wall_expiry = expires - time(NULL);
- const char *s = NULL;
-
- if (wall_expiry >= 86400)
- {
- wall_expiry /= 86400;
- s = "day";
- }
- else if (wall_expiry >= 3600)
- {
- wall_expiry /= 3600;
- s = "hour";
- }
- else if (wall_expiry >= 60)
- {
- wall_expiry /= 60;
- s = "minute";
- }
-
- snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
- }
-
- ircdproto->SendGlobops(OperServ, "%s added an SGLINE for %s (%s)", u->nick.c_str(), cmask, buf);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- }
- else
- this->OnSyntaxError(u, "ADD");
-
- return MOD_CONT;
- }
-
- CommandReturn OnDel(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
- {
- this->OnSyntaxError(u, "DEL");
- return MOD_CONT;
- }
-
- if (!sglines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&sglines, mask, sxline_del_callback);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, res);
- }
- else {
- if ((res = slist_indexof(&sglines, const_cast<char *>(mask))) == -1)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NOT_FOUND, mask);
- return MOD_CONT;
- }
-
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(sglines.list[res]), SX_SGLINE));
- slist_delete(&sglines, res);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED, mask);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- return MOD_CONT;
- }
-
- CommandReturn OnList(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!sglines.count) {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sglines, mask, &sgline_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < sglines.count; ++i)
- {
- amask = (static_cast<SXLine *>(sglines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sgline_list(i + 1, static_cast<SXLine *>(sglines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- else
- notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SGLine");
- }
-
- return MOD_CONT;
- }
-
- CommandReturn OnView(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!sglines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sglines, mask, &sgline_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < sglines.count; ++i)
- {
- amask = (static_cast<SXLine *>(sglines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sgline_view(i + 1, static_cast<SXLine *>(sglines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- }
-
- return MOD_CONT;
- }
-
- CommandReturn OnClear(User *u)
- {
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SGLINE));
- slist_clear(&sglines, 1);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_CLEAR);
-
- return MOD_CONT;
- }
- public:
- CommandOSSGLine() : Command("SGLINE", 1, 3, "operserv/sgline")
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- ci::string cmd = params[0];
-
- if (cmd == "ADD")
- return this->OnAdd(u, params);
- else if (cmd == "DEL")
- return this->OnDel(u, params);
- else if (cmd == "LIST")
- return this->OnList(u, params);
- else if (cmd == "VIEW")
- return this->OnView(u, params);
- else if (cmd == "CLEAR")
- return this->OnClear(u);
- else
- this->OnSyntaxError(u, "");
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_OperServ, u, OPER_HELP_SGLINE);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
- }
-};
-
-class OSSGLine : public Module
-{
- public:
- OSSGLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
-
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(OperServ, new CommandOSSGLine());
-
- if (!ircd->sgline)
- throw ModuleException("Your IRCd does not support SGLine");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SGLINE);
- }
-};
-
-/* Lists an SGLINE entry, prefixing it with the header if needed */
-int sgline_view(int number, SXLine *sx, User *u, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_VIEW_HEADER);
- *sent_header = 1;
- }
-
- tm = *localtime(&sx->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sgline_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sgline_view(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Lists an SGLINE entry, prefixing it with the header if needed */
-int sgline_list(int number, SXLine *sx, User *u, int *sent_header)
-{
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_HEADER);
- *sent_header = 1;
- }
-
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_FORMAT, number, sx->mask, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sgline_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sgline_list(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-MODULE_INIT(OSSGLine)
diff --git a/src/core/os_snline.cpp b/src/core/os_snline.cpp
new file mode 100644
index 000000000..503b63b5c
--- /dev/null
+++ b/src/core/os_snline.cpp
@@ -0,0 +1,426 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+#include "hashcomp.h"
+
+class SNLineDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ SNLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), Deleted(0)
+ {
+ }
+
+ ~SNLineDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ else if (Deleted == 0)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SNLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SNLine->DelXLine(x);
+ }
+};
+
+class SNLineListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ SNLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), SentHeader(false)
+ {
+ }
+
+ ~SNLineListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ XLine *x = SNLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class SNLineViewCallback : public SNLineListCallback
+{
+ public:
+ SNLineViewCallback(User *_u, const std::string &numlist) : SNLineListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SNLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, expirebuf, x->Reason.c_str());
+ }
+};
+
+class CommandOSSNLine : public Command
+{
+ private:
+ CommandReturn OnAdd(User *u, const std::vector<ci::string> &params)
+ {
+ unsigned last_param = 2;
+ const char *param, *expiry;
+ char rest[BUFSIZE];
+ time_t expires;
+
+ param = params.size() > 1 ? params[1].c_str() : NULL;
+ if (param && *param == '+')
+ {
+ expiry = param;
+ param = params.size() > 2 ? params[2].c_str() : NULL;
+ last_param = 3;
+ }
+ else
+ expiry = NULL;
+
+ expires = expiry ? dotime(expiry) : Config.SNLineExpiry;
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (expiry && isdigit(expiry[strlen(expiry) - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires && expires < 60)
+ {
+ notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
+ return MOD_CONT;
+ }
+ else if (expires > 0)
+ expires += time(NULL);
+
+ if (!param)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+ snprintf(rest, sizeof(rest), "%s%s%s", param, params.size() > last_param ? " " : "", params.size() > last_param ? params[last_param].c_str() : "");
+
+ if (std::string(rest).find(':') == std::string::npos)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+
+ sepstream sep(rest, ':');
+ ci::string mask;
+ sep.GetToken(mask);
+ std::string reason = sep.GetRemaining();
+
+ if (!mask.empty() && !reason.empty()) {
+ /* Clean up the last character of the mask if it is a space
+ * See bug #761
+ */
+ unsigned masklen = mask.size();
+ if (mask[masklen - 1] == ' ')
+ mask.erase(masklen - 1);
+
+ XLine *x = SNLine->Add(OperServ, u, mask, expires, reason);
+
+ if (!x)
+ return MOD_CONT;
+
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_ADDED, mask.c_str());
+
+ if (Config.WallOSSNLine)
+ {
+ char buf[128];
+
+ if (!expires)
+ strcpy(buf, "does not expire");
+ else
+ {
+ int wall_expiry = expires - time(NULL);
+ const char *s = NULL;
+
+ if (wall_expiry >= 86400)
+ {
+ wall_expiry /= 86400;
+ s = "day";
+ }
+ else if (wall_expiry >= 3600)
+ {
+ wall_expiry /= 3600;
+ s = "hour";
+ }
+ else if (wall_expiry >= 60)
+ {
+ wall_expiry /= 60;
+ s = "minute";
+ }
+
+ snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
+ }
+
+ ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SNLINE for %s (%s)", u->nick.c_str(), mask.c_str(), buf);
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ }
+ else
+ this->OnSyntaxError(u, "ADD");
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnDel(User *u, const std::vector<ci::string> &params)
+ {
+ if (SNLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(u, "DEL");
+ return MOD_CONT;
+ }
+
+ if (isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SNLineDelCallback(u, mask.c_str()))->Process();
+ else
+ {
+ XLine *x = SNLine->HasEntry(mask);
+
+ if (!x)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NOT_FOUND, mask.c_str());
+ return MOD_CONT;
+ }
+
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SNLINE));
+
+ SNLineDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED, mask.c_str());
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnList(User *u, const std::vector<ci::string> &params)
+ {
+ if (SNLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SNLineListCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ XLine *x = SNLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_HEADER);
+ }
+
+ SNLineListCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ else
+ notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SNLine");
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnView(User *u, const std::vector<ci::string> &params)
+ {
+ if (SNLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SNLineViewCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ XLine *x = SNLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_HEADER);
+ }
+
+ SNLineViewCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnClear(User *u)
+ {
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SNLINE));
+ SNLine->Clear();
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_CLEAR);
+
+ return MOD_CONT;
+ }
+ public:
+ CommandOSSNLine() : Command("SNLINE", 1, 3, "operserv/snline")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ci::string cmd = params[0];
+
+ if (cmd == "ADD")
+ return this->OnAdd(u, params);
+ else if (cmd == "DEL")
+ return this->OnDel(u, params);
+ else if (cmd == "LIST")
+ return this->OnList(u, params);
+ else if (cmd == "VIEW")
+ return this->OnView(u, params);
+ else if (cmd == "CLEAR")
+ return this->OnClear(u);
+ else
+ this->OnSyntaxError(u, "");
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_OperServ, u, OPER_HELP_SNLINE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_OperServ, u, "SNLINE", OPER_SNLINE_SYNTAX);
+ }
+};
+
+class OSSNLine : public Module
+{
+ public:
+ OSSNLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ this->AddCommand(OperServ, new CommandOSSNLine());
+
+ if (!ircd->snline)
+ throw ModuleException("Your IRCd does not support SNLine");
+
+ ModuleManager::Attach(I_OnOperServHelp, this);
+ }
+ void OnOperServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SNLINE);
+ }
+};
+
+MODULE_INIT(OSSNLine)
diff --git a/src/core/os_sqline.c b/src/core/os_sqline.c
index b73c3ce8b..89864c69e 100644
--- a/src/core/os_sqline.c
+++ b/src/core/os_sqline.c
@@ -14,24 +14,122 @@
#include "module.h"
-int sqline_view_callback(SList *slist, int number, void *item, va_list args);
-int sqline_list_callback(SList *slist, int number, void *item, va_list args);
-int sqline_view(int number, SXLine *sx, User *u, int *sent_header);
-int sqline_list(int number, SXLine *sx, User *u, int *sent_header);
+class SQLineDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ SQLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), Deleted(0)
+ {
+ }
+
+ ~SQLineDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
+ else if (Deleted == 0)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SQLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SQLine->DelXLine(x);
+ }
+};
-static int sxline_del_callback(SList *slist, void *item, va_list args)
+class SQLineListCallback : public NumberList
{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SQLINE));
- return 1;
-}
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ SQLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), SentHeader(false)
+ {
+ }
+
+ ~SQLineListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ XLine *x = SQLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class SQLineViewCallback : public SQLineListCallback
+{
+ public:
+ SQLineViewCallback(User *_u, const std::string &numlist) : SQLineListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SQLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf,
+expirebuf, x->Reason.c_str());
+ }
+};
+
class CommandOSSQLine : public Command
{
private:
CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
{
- int deleted = 0;
unsigned last_param = 2;
const char *expiry, *mask;
char reason[BUFSIZE];
@@ -70,25 +168,11 @@ class CommandOSSQLine : public Command
snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
if (mask && *reason)
{
- /* We first do some sanity check on the proposed mask. */
- if (strspn(mask, "*") == strlen(mask))
- {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
+ XLine *x = SQLine->Add(OperServ, u, mask, expires, reason);
+
+ if (!x)
return MOD_CONT;
- }
- /* Channel SQLINEs are only supported on Bahamut servers */
- if (*mask == '#' && !ircd->chansqline)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANNELS_UNSUPPORTED);
- return MOD_CONT;
- }
-
- deleted = add_sqline(u, mask, u->nick.c_str(), expires, reason);
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, deleted);
notice_lang(Config.s_OperServ, u, OPER_SQLINE_ADDED, mask);
if (Config.WallOSSQLine)
@@ -136,47 +220,36 @@ class CommandOSSQLine : public Command
CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
+ if (SQLine->GetList().empty())
{
- this->OnSyntaxError(u, "DEL");
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
return MOD_CONT;
}
- if (!sqlines.count)
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
{
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
+ this->OnSyntaxError(u, "DEL");
return MOD_CONT;
}
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SQLineDelCallback(u, mask.c_str()))->Process();
+ else
{
- /* Deleting a range */
- res = slist_delete_range(&sqlines, mask, sxline_del_callback);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, res);
- }
- else {
- if ((res = slist_indexof(&sqlines, const_cast<char *>(mask))) == -1)
+ XLine *x = SQLine->HasEntry(mask);
+
+ if (!x)
{
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NOT_FOUND, mask);
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NOT_FOUND, mask.c_str());
return MOD_CONT;
}
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(sqlines.list[res]), SX_SQLINE));
- slist_delete(&sqlines, res);
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED, mask);
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SQLINE));
+
+ SQLineDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED, mask.c_str());
}
if (readonly)
@@ -187,39 +260,37 @@ class CommandOSSQLine : public Command
CommandReturn DoList(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res, sent_header = 0;
-
- if (!sqlines.count)
+ if (SQLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
return MOD_CONT;
}
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[1] : "";
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sqlines, mask, &sqline_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SQLineListCallback(u, mask.c_str()))->Process();
else
{
- int i;
- char *amask;
+ bool SentHeader = false;
- for (i = 0; i < sqlines.count; ++i)
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
{
- amask = (static_cast<SXLine *>(sqlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sqline_list(i + 1, static_cast<SXLine *>(sqlines.list[i]), u, &sent_header);
+ XLine *x = SQLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER);
+ }
+
+ SQLineListCallback::DoList(u, x, i);
+ }
}
- if (!sent_header)
+ if (!SentHeader)
notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
else
notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SQLine");
@@ -230,39 +301,37 @@ class CommandOSSQLine : public Command
CommandReturn DoView(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res, sent_header = 0;
-
- if (!sqlines.count)
+ if (SQLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
return MOD_CONT;
}
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[1] : "";
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sqlines, mask, &sqline_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SQLineViewCallback(u, mask.c_str()))->Process();
else
{
- int i;
- char *amask;
+ bool SentHeader = false;
- for (i = 0; i < sqlines.count; ++i)
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
{
- amask = (static_cast<SXLine *>(sqlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sqline_view(i + 1, static_cast<SXLine *>(sqlines.list[i]), u, &sent_header);
+ XLine *x = SQLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER);
+ }
+
+ SQLineViewCallback::DoList(u, x, i);
+ }
}
- if (!sent_header)
+ if (!SentHeader)
notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
}
@@ -271,8 +340,8 @@ class CommandOSSQLine : public Command
CommandReturn DoClear(User *u)
{
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SQLINE));
- slist_clear(&sqlines, 1);
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SQLINE));
+ SGLine->Clear();
notice_lang(Config.s_OperServ, u, OPER_SQLINE_CLEAR);
return MOD_CONT;
@@ -335,61 +404,4 @@ class OSSQLine : public Module
}
};
-int sqline_view(int number, SXLine *sx, User *u, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER);
- *sent_header = 1;
- }
-
- tm = *localtime(&sx->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires);
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sqline_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sqline_view(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Lists an SQLINE entry, prefixing it with the header if needed */
-int sqline_list(int number, SXLine *sx, User *u, int *sent_header)
-{
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER);
- *sent_header = 1;
- }
-
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_FORMAT, number, sx->mask, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sqline_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sqline_list(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
MODULE_INIT(OSSQLine)
diff --git a/src/core/os_stats.c b/src/core/os_stats.c
index f98e94a19..fb9623771 100644
--- a/src/core/os_stats.c
+++ b/src/core/os_stats.c
@@ -46,7 +46,7 @@ class CommandOSStats : public Command
{
int timeout;
/* AKILLs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_COUNT, akills.count);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_COUNT, SGLine->GetCount());
timeout = Config.AutokillExpiry + 59;
if (timeout >= 172800)
notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_DAYS, timeout / 86400);
@@ -62,30 +62,30 @@ class CommandOSStats : public Command
notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_MIN);
else
notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_NONE);
- if (ircd->sgline)
+ if (ircd->snline)
{
- /* SGLINEs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_COUNT, sglines.count);
- timeout = Config.SGLineExpiry + 59;
+ /* SNLINEs */
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_COUNT, SNLine->GetCount());
+ timeout = Config.SNLineExpiry + 59;
if (timeout >= 172800)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_DAYS, timeout / 86400);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_DAYS, timeout / 86400);
else if (timeout >= 86400)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_DAY);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_DAY);
else if (timeout >= 7200)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_HOURS, timeout / 3600);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_HOURS, timeout / 3600);
else if (timeout >= 3600)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_HOUR);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_HOUR);
else if (timeout >= 120)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_MINS, timeout / 60);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_MINS, timeout / 60);
else if (timeout >= 60)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_MIN);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_MIN);
else
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_NONE);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_NONE);
}
if (ircd->sqline)
{
/* SQLINEs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_COUNT, sqlines.count);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_COUNT, SQLine->GetCount());
timeout = Config.SQLineExpiry + 59;
if (timeout >= 172800)
notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_EXPIRE_DAYS, timeout / 86400);
@@ -105,7 +105,7 @@ class CommandOSStats : public Command
if (ircd->szline)
{
/* SZLINEs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_COUNT, szlines.count);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_COUNT, SZLine->GetCount());
timeout = Config.SZLineExpiry + 59;
if (timeout >= 172800)
notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_EXPIRE_DAYS, timeout / 86400);
@@ -316,64 +316,74 @@ class OSStats : public Module
void get_operserv_stats(long *nrec, long *memuse)
{
- int i;
+ unsigned i;
long mem = 0, count = 0, mem2 = 0, count2 = 0;
- Akill *ak;
- SXLine *sx;
+ XLine *x;
- count += akills.count;
- mem += akills.capacity;
- mem += akills.count * sizeof(Akill);
+ count += SGLine->GetCount();
+ mem += SGLine->GetCount() * sizeof(XLine);
- for (i = 0; i < akills.count; ++i)
+ for (i = 0; i < SGLine->GetCount(); ++i)
{
- ak = static_cast<Akill *>(akills.list[i]);
- mem += strlen(ak->user) + 1;
- mem += strlen(ak->host) + 1;
- mem += strlen(ak->by) + 1;
- mem += strlen(ak->reason) + 1;
+ x = SGLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
- if (ircd->sgline)
+ if (ircd->snline)
{
- count += sglines.count;
- mem += sglines.capacity;
- mem += sglines.count * sizeof(SXLine);
+ count += SNLine->GetCount();
+ mem += SNLine->GetCount() * sizeof(XLine);
- for (i = 0; i < sglines.count; ++i)
+ for (i = 0; i < SNLine->GetCount(); ++i)
{
- sx = static_cast<SXLine *>(sglines.list[i]);
- mem += strlen(sx->mask) + 1;
- mem += strlen(sx->by) + 1;
- mem += strlen(sx->reason) + 1;
+ x = SNLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
}
if (ircd->sqline)
{
- count += sqlines.count;
- mem += sqlines.capacity;
- mem += sqlines.count * sizeof(SXLine);
+ count += SQLine->GetCount();
+ mem += SGLine->GetCount() * sizeof(XLine);
- for (i = 0; i < sqlines.count; ++i)
+ for (i = 0; i < SQLine->GetCount(); ++i)
{
- sx = static_cast<SXLine *>(sqlines.list[i]);
- mem += strlen(sx->mask) + 1;
- mem += strlen(sx->by) + 1;
- mem += strlen(sx->reason) + 1;
+ x = SNLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
}
if (ircd->szline)
{
- count += szlines.count;
- mem += szlines.capacity;
- mem += szlines.count * sizeof(SXLine);
-
- for (i = 0; i < szlines.count; ++i)
+ count += SZLine->GetCount();
+ mem += SZLine->GetCount() * sizeof(XLine);
+
+ for (i = 0; i < SZLine->GetCount(); ++i)
{
- sx = static_cast<SXLine *>(szlines.list[i]);
- mem += strlen(sx->mask) + 1;
- mem += strlen(sx->by) + 1;
- mem += strlen(sx->reason) + 1;
+ x = SZLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
}
diff --git a/src/core/os_szline.c b/src/core/os_szline.c
index b45c5eed2..674b8d7d5 100644
--- a/src/core/os_szline.c
+++ b/src/core/os_szline.c
@@ -14,24 +14,122 @@
#include "module.h"
-int szline_view_callback(SList *slist, int number, void *item, va_list args);
-int szline_list_callback(SList *slist, int number, void *item, va_list args);
-int szline_view(int number, SXLine *sx, User *u, int *sent_header);
-int szline_list(int number, SXLine *sx, User *u, int *sent_header);
+class SZLineDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ SZLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), Deleted(0)
+ {
+ }
+
+ ~SZLineDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
+ else if (Deleted == 0)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SZLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SZLine->DelXLine(x);
+ }
+};
-static int sxline_del_callback(SList *slist, void *item, va_list args)
+class SZLineListCallback : public NumberList
{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SZLINE));
- return 1;
-}
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ SZLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist), u(_u), SentHeader(false)
+ {
+ }
+
+ ~SZLineListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ XLine *x = SZLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class SZLineViewCallback : public SZLineListCallback
+{
+ public:
+ SZLineViewCallback(User *_u, const std::string &numlist) : SZLineListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SZLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf,
+expirebuf, x->Reason.c_str());
+ }
+};
+
class CommandOSSZLine : public Command
{
private:
CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
{
- int deleted = 0;
unsigned last_param = 2;
const char *expiry, *mask;
char reason[BUFSIZE];
@@ -70,25 +168,11 @@ class CommandOSSZLine : public Command
snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
if (mask && *reason)
{
- /* We first do some sanity check on the proposed mask. */
+ XLine *x = SZLine->Add(OperServ, u, mask, expires, reason);
- if (strchr(mask, '!') || strchr(mask, '@'))
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_ONLY_IPS);
+ if (!x)
return MOD_CONT;
- }
- if (strspn(mask, "*?") == strlen(mask))
- {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
- return MOD_CONT;
- }
-
- deleted = add_szline(u, mask, u->nick.c_str(), expires, reason);
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, deleted);
notice_lang(Config.s_OperServ, u, OPER_SZLINE_ADDED, mask);
if (Config.WallOSSZLine)
@@ -136,48 +220,36 @@ class CommandOSSZLine : public Command
CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
+ if (SZLine->GetList().empty())
{
- this->OnSyntaxError(u, "DEL");
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
return MOD_CONT;
}
- if (!szlines.count)
+ const ci::string mask = params.size() > 1 ? params[1].c_str() : "";
+
+ if (mask.empty())
{
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
+ this->OnSyntaxError(u, "DEL");
return MOD_CONT;
}
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&szlines, mask, sxline_del_callback);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, res);
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SZLineDelCallback(u, mask.c_str()))->Process();
else
{
- if ((res = slist_indexof(&szlines, const_cast<char *>(mask))) == -1)
+ XLine *x = SZLine->HasEntry(mask);
+
+ if (!x)
{
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NOT_FOUND, mask);
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NOT_FOUND, mask.c_str());
return MOD_CONT;
}
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(szlines.list[res]), SX_SZLINE));
- slist_delete(&szlines, res);
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED, mask);
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SZLINE));
+
+ SZLineDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED, mask.c_str());
}
if (readonly)
@@ -188,39 +260,37 @@ class CommandOSSZLine : public Command
CommandReturn DoList(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res, sent_header = 0;
-
- if (!szlines.count)
+ if (SZLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
return MOD_CONT;
}
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[1] : "";
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&szlines, mask, &szline_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SZLineListCallback(u, mask.c_str()))->Process();
else
{
- int i;
- char *amask;
+ bool SentHeader = false;
- for (i = 0; i < szlines.count; ++i)
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
{
- amask = (static_cast<SXLine *>(szlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- szline_list(i + 1, static_cast<SXLine *>(szlines.list[i]), u, &sent_header);
+ XLine *x = SZLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER);
+ }
+
+ SZLineListCallback::DoList(u, x, i);
+ }
}
- if (!sent_header)
+ if (!SentHeader)
notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
}
@@ -229,39 +299,37 @@ class CommandOSSZLine : public Command
CommandReturn DoView(User *u, const std::vector<ci::string> &params)
{
- const char *mask;
- int res, sent_header = 0;
-
- if (!szlines.count)
+ if (SZLine->GetList().empty())
{
notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
return MOD_CONT;
}
- mask = params.size() > 1 ? params[1].c_str() : NULL;
+ const ci::string mask = params.size() > 1 ? params[1] : "";
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&szlines, mask, &szline_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SZLineViewCallback(u, mask.c_str()))->Process();
else
{
- int i;
- char *amask;
+ bool SentHeader = false;
- for (i = 0; i < szlines.count; ++i)
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
{
- amask = (static_cast<SXLine *>(szlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- szline_view(i + 1, static_cast<SXLine *>(szlines.list[i]), u, &sent_header);
+ XLine *x = SZLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER);
+ }
+
+ SZLineViewCallback::DoList(u, x, i);
+ }
}
- if (!sent_header)
+ if (!SentHeader)
notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
}
@@ -270,8 +338,8 @@ class CommandOSSZLine : public Command
CommandReturn DoClear(User *u)
{
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SZLINE));
- slist_clear(&szlines, 1);
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SZLINE));
+ SZLine->Clear();
notice_lang(Config.s_OperServ, u, OPER_SZLINE_CLEAR);
return MOD_CONT;
@@ -334,61 +402,4 @@ class OSSZLine : public Module
}
};
-int szline_view(int number, SXLine *sx, User *u, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER);
- *sent_header = 1;
- }
-
- tm = *localtime(&sx->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires);
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int szline_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return szline_view(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Callback for enumeration purposes */
-int szline_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return szline_list(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Lists an SZLINE entry, prefixing it with the header if needed */
-int szline_list(int number, SXLine *sx, User *u, int *sent_header)
-{
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER);
- *sent_header = 1;
- }
-
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_FORMAT, number, sx->mask, sx->reason);
-
- return 1;
-}
-
MODULE_INIT(OSSZLine)
diff --git a/src/hostserv.c b/src/hostserv.c
index ec46cdc86..9d7362903 100644
--- a/src/hostserv.c
+++ b/src/hostserv.c
@@ -177,9 +177,9 @@ void HostServSyncVhosts(NickAlias *na)
if (!na || !na->hostinfo.HasVhost())
return;
- for (int i = 0; i < na->nc->aliases.count; i++)
+ for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(); it != na->nc->aliases.end(); ++it)
{
- NickAlias *nick = static_cast<NickAlias *>(na->nc->aliases.list[i]);
+ NickAlias *nick = *it;
nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator());
}
}
diff --git a/src/init.c b/src/init.c
index faa37764b..2c2a64ed4 100644
--- a/src/init.c
+++ b/src/init.c
@@ -43,7 +43,8 @@ void introduce_user(const std::string &user)
if (user.empty() || ci_bi_nick == user)
{
ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid);
- ircdproto->SendSQLine(bi->nick, "Reserved for services");
+ XLine x(bi->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
}
}
}
diff --git a/src/main.c b/src/main.c
index 8b95d4a2c..d4746cf93 100644
--- a/src/main.c
+++ b/src/main.c
@@ -155,16 +155,6 @@ extern void expire_all()
expire_nicks();
expire_chans();
expire_requests();
- expire_akills();
- if (ircd->sgline) {
- expire_sglines();
- }
- if (ircd->sqline) {
- expire_sqlines();
- }
- if (ircd->szline) {
- expire_szlines();
- }
expire_exceptions();
FOREACH_MOD(I_OnDatabaseExpire, OnDatabaseExpire());
diff --git a/src/memoserv.c b/src/memoserv.c
index 11121cee3..4d33bde3e 100644
--- a/src/memoserv.c
+++ b/src/memoserv.c
@@ -272,7 +272,6 @@ void memo_send(User * u, const char *name, const char *text, int z)
if (z == 0 || z == 3)
notice_lang(Config.s_MemoServ, u, MEMO_SENT, name);
if (!ischan) {
- NickAlias *na;
NickCore *nc = (findnick(name))->nc;
FOREACH_MOD(I_OnMemoSend, OnMemoSend(u, nc, m));
@@ -280,10 +279,10 @@ void memo_send(User * u, const char *name, const char *text, int z)
if (Config.MSNotifyAll) {
if ((nc->HasFlag(NI_MEMO_RECEIVE))
&& get_ignore(name) == NULL) {
- int i;
- for (i = 0; i < nc->aliases.count; i++) {
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it)
+ {
+ NickAlias *na = *it;
User *user = finduser(na->nick);
if (user && user->IsIdentified())
notice_lang(Config.s_MemoServ, user,
diff --git a/src/misc.c b/src/misc.c
index d7060660e..22ea81432 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -226,6 +226,7 @@ const char *merge_args(int argc, char **argv)
NumberList::NumberList(const std::string &list)
{
+ char *error;
commasepstream sep(list);
std::string token;
@@ -238,9 +239,8 @@ NumberList::NumberList(const std::string &list)
if (!h)
{
- errno = 0;
- unsigned num = strtol(token.c_str(), NULL, 10);
- if (!errno)
+ unsigned num = strtol(token.c_str(), &error, 10);
+ if (*error == '\0')
{
numbers.insert(num);
}
@@ -255,11 +255,11 @@ NumberList::NumberList(const std::string &list)
}
else
{
+ char *error2;
*h++ = '\0';
- errno = 0;
- unsigned num1 = strtol(token.c_str(), NULL, 10);
- unsigned num2 = strtol(h, NULL, 10);
- if (!errno)
+ unsigned num1 = strtol(token.c_str(), &error, 10);
+ unsigned num2 = strtol(h, &error2, 10);
+ if (*error == '\0' && *error2 == '\0')
{
for (unsigned i = num1; i <= num2; ++i)
{
diff --git a/src/modules/mysql/db_mysql_read.cpp b/src/modules/mysql/db_mysql_read.cpp
index 1b4ce33fa..3c5fb359a 100644
--- a/src/modules/mysql/db_mysql_read.cpp
+++ b/src/modules/mysql/db_mysql_read.cpp
@@ -620,42 +620,51 @@ static void LoadDatabase()
query << "SELECT * FROM `anope_os_akills`";
qres = StoreQuery(query);
- if (qres)
+ if (qres && SGLine)
{
for (size_t i = 0; i < qres.size(); ++i)
{
- Akill *ak = new Akill;
- ak->user = sstrdup(qres[i]["user"].c_str());
- ak->host = sstrdup(qres[i]["host"].c_str());
- ak->by = sstrdup(qres[i]["xby"].c_str());
- ak->reason = sstrdup(qres[i]["reason"].c_str());
- ak->seton = atol(qres[i]["seton"].c_str());
- ak->expires = atol(qres[i]["expire"].c_str());
- slist_add(&akills, ak);
+ ci::string user = qres[i]["user"].c_str();
+ ci::string host = qres[i]["host"].c_str();
+ ci::string by = qres[i]["xby"].c_str();
+ std::string reason = SQLAssign(qres[i]["reason"]);
+ time_t seton = atol(qres[i]["seton"].c_str());
+ time_t expires = atol(qres[i]["expire"].c_str());
+
+ XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
}
- query << "SELECT * FROM `anope_os_sxlines`";
+ query << "SELECT * FROM `anope_os_xlines`";
qres = StoreQuery(query);
if (qres)
{
for (size_t i = 0; i < qres.size(); ++i)
{
- SXLine *sx = new SXLine;
- sx->mask = sstrdup(qres[i]["mask"].c_str());
- sx->by = sstrdup(qres[i]["xby"].c_str());
- sx->reason = sstrdup(qres[i]["reason"].c_str());
- sx->seton = atol(qres[i]["seton"].c_str());
- sx->expires = atol(qres[i]["expires"].c_str());
- if (qres[i]["type"] == "SGLINE")
- slist_add(&sglines, sx);
- else if (qres[i]["type"] == "SQLINE")
- slist_add(&sqlines, sx);
- else if (qres[i]["type"] == "SZLINE")
- slist_add(&szlines, sx);
- else
- delete sx;
+ ci::string mask = qres[i]["mask"].c_str();
+ ci::string by = qres[i]["xby"].c_str();
+ std::string reason = SQLAssign(qres[i]["reason"]);
+ time_t seton = atol(qres[i]["seton"].c_str());
+ time_t expires = atol(qres[i]["expires"].c_str());
+
+ XLine *x = NULL;
+ if (qres[i]["type"] == "SNLINE" && SNLine)
+ x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ else if (qres[i]["type"] == "SQLINE" && SQLine)
+ x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ else if (qres[i]["type"] == "SZLINE" && SZLine)
+ x = SZLine->Add(NULL, NULL,mask, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
}
}
diff --git a/src/modules/mysql/db_mysql_write.cpp b/src/modules/mysql/db_mysql_write.cpp
index 1888195f3..427be43bd 100644
--- a/src/modules/mysql/db_mysql_write.cpp
+++ b/src/modules/mysql/db_mysql_write.cpp
@@ -235,9 +235,7 @@ static void SaveDatabases()
for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- NickAlias *na = it->second;
-
- me->OnNickRegister(na);
+ me->OnNickRegister(it->second);
}
query << "TRUNCATE TABLE `anope_ns_core`";
@@ -269,8 +267,7 @@ static void SaveDatabases()
for (botinfo_map::const_iterator it = BotList.begin(); it != BotList.end(); ++it)
{
- BotInfo *bi = it->second;
- me->OnBotCreate(bi);
+ me->OnBotCreate(it->second);
}
query << "TRUNCATE TABLE `anope_cs_info`";
@@ -311,7 +308,7 @@ static void SaveDatabases()
me->OnAkickAdd(NULL, ci, ak);
}
-
+
for (int k = 0; k < CA_SIZE; ++k)
{
query << "INSERT DELAYED INTO `anope_cs_levels` (channel, position, level) VALUES(" << mysqlpp::quote << ci->name << ", '" << k << "', '" << ci->levels[k] << "') ON DUPLICATE KEY UPDATE position=VALUES(position), level=VALUES(level)";
@@ -334,32 +331,36 @@ static void SaveDatabases()
me->OnMakeNickRequest(it->second);
}
- for (int i = 0; i < akills.count; ++i)
+ if (SGLine)
{
- Akill *ak = static_cast<Akill *>(akills.list[i]);
-
- me->OnAddAkill(NULL, ak);
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
+ {
+ me->OnAddAkill(NULL, SGLine->GetEntry(i));
+ }
}
- for (int i = 0; i < sglines.count; ++i)
+ if (SZLine)
{
- SXLine *x = static_cast<SXLine *>(sglines.list[i]);
-
- me->OnAddSXLine(NULL, x, SX_SGLINE);
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
+ {
+ me->OnAddXLine(NULL, SZLine->GetEntry(i), X_SZLINE);
+ }
}
- for (int i = 0; i < sqlines.count; ++i)
+ if (SQLine)
{
- SXLine *x = static_cast<SXLine *>(sqlines.list[i]);
-
- me->OnAddSXLine(NULL, x, SX_SQLINE);
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
+ {
+ me->OnAddXLine(NULL, SQLine->GetEntry(i), X_SQLINE);
+ }
}
- for (int i = 0; i < szlines.count; ++i)
+ if (SNLine)
{
- SXLine *x = static_cast<SXLine *>(szlines.list[i]);
-
- me->OnAddSXLine(NULL, x, SX_SZLINE);
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ me->OnAddXLine(NULL, SNLine->GetEntry(i), X_SNLINE);
+ }
}
for (int i = 0; i < nexceptions; ++i)
@@ -433,7 +434,7 @@ class DBMySQLWrite : public DBMySQL
I_OnMemoSend, I_OnMemoDel,
/* OperServ */
I_OnOperServHelp, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
- I_OnAddSXLine, I_OnDelSXLine
+ I_OnAddXLine, I_OnDelXLine
};
ModuleManager::Attach(i, this, 40);
}
@@ -450,7 +451,7 @@ class DBMySQLWrite : public DBMySQL
query << "TRUNCATE TABLE `anope_os_core`";
ExecuteQuery(query);
query << "INSERT DELAYED INTO `anope_os_core` (maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count) VALUES(";
- query << maxusercnt << ", " << maxusertime << ", " << akills.count << ", " << sqlines.count << ", " << sglines.count << ", " << szlines.count << ")";
+ query << maxusercnt << ", " << maxusertime << ", " << (SGLine ? SGLine->GetCount() : 0) << ", " << (SQLine ? SQLine->GetCount() : 0) << ", " << (SNLine ? SNLine->GetCount() : 0) << ", " << (SZLine ? SZLine->GetCount() : 0) << ")";
ExecuteQuery(query);
for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
@@ -1028,21 +1029,21 @@ class DBMySQLWrite : public DBMySQL
ExecuteQuery(query);
}
- EventReturn OnAddAkill(User *, Akill *ak)
+ EventReturn OnAddAkill(User *, XLine *ak)
{
mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_os_akills` (user, host, xby, reason, seton, expire) VALUES(";
- query << mysqlpp::quote << ak->user << ", " << mysqlpp::quote << ak->host << ", " << mysqlpp::quote << ak->by;
- query << ", " << mysqlpp::quote << ak->reason << ", " << ak->seton << ", " << ak->expires << ")";
+ query << mysqlpp::quote << ak->GetUser().c_str() << ", " << mysqlpp::quote << ak->GetHost().c_str() << ", " << mysqlpp::quote << ak->By.c_str();
+ query << ", " << mysqlpp::quote << ak->Reason << ", " << ak->Created << ", " << ak->Expires << ")";
ExecuteQuery(query);
return EVENT_CONTINUE;
}
- void OnDelAkill(User *, Akill *ak)
+ void OnDelAkill(User *, XLine *ak)
{
mysqlpp::Query query(me->Con);
if (ak)
- query << "DELETE FROM `anope_os_akills` WHERE `host` = " << mysqlpp::quote << ak->host;
+ query << "DELETE FROM `anope_os_akills` WHERE `host` = " << mysqlpp::quote << ak->GetHost().c_str();
else
query << "TRUNCATE TABLE `anope_os_akills`";
ExecuteQuery(query);
@@ -1065,27 +1066,27 @@ class DBMySQLWrite : public DBMySQL
ExecuteQuery(query);
}
- EventReturn OnAddSXLine(User *, SXLine *sx, SXLineType Type)
+ EventReturn OnAddXLine(User *, XLine *x, XLineType Type)
{
mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_os_sxlines` (type, mask, xby, reason, seton, expire) VALUES('";
- query << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "', ";
- query << mysqlpp::quote << sx->mask << ", " << mysqlpp::quote << sx->by << ", " << mysqlpp::quote << sx->reason;
- query << ", " << sx->seton << ", " << sx->expires << ")";
+ query << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "', ";
+ query << mysqlpp::quote << x->Mask.c_str() << ", " << mysqlpp::quote << x->By.c_str() << ", " << mysqlpp::quote << x->Reason;
+ query << ", " << x->Created << ", " << x->Expires << ")";
ExecuteQuery(query);
return EVENT_CONTINUE;
}
- void OnDelSXLine(User *, SXLine *sx, SXLineType Type)
+ void OnDelXLine(User *, XLine *x, XLineType Type)
{
mysqlpp::Query query(me->Con);
- if (sx)
+ if (x)
{
- query << "DELETE FROM `anope_os_sxlines` WHERE `mask` = " << mysqlpp::quote << sx->mask << " AND `type` = '";
- query << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "'";
+ query << "DELETE FROM `anope_os_xlines` WHERE `mask` = " << mysqlpp::quote << x->Mask.c_str() << " AND `type` = '";
+ query << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "'";
}
else
- query << "DELETE FROM `anope_os_sxlines` WHERE `type` = '" << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "'";
+ query << "DELETE FROM `anope_os_xlines` WHERE `type` = '" << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "'";
ExecuteQuery(query);
}
};
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
index 95d5bc4e9..a196145b9 100644
--- a/src/nickalias.cpp
+++ b/src/nickalias.cpp
@@ -42,7 +42,7 @@ NickAlias::NickAlias(const std::string &nickname, NickCore *nickcore)
this->nick = sstrdup(nickname.c_str());
this->nc = nickcore;
- slist_add(&nc->aliases, this);
+ nc->aliases.push_back(this);
NickAliasList[this->nick] = this;
@@ -88,8 +88,12 @@ NickAlias::~NickAlias()
if (this->nc)
{
/* Next: see if our core is still useful. */
- slist_remove(&this->nc->aliases, this);
- if (this->nc->aliases.count == 0)
+ std::list<NickAlias *>::iterator it = std::find(this->nc->aliases.begin(), this->nc->aliases.end(), this);
+ if (it != this->nc->aliases.end())
+ {
+ nc->aliases.erase(it);
+ }
+ if (this->nc->aliases.empty())
{
delete this->nc;
this->nc = NULL;
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
index 3becf8ab4..cf92b0b3d 100644
--- a/src/nickcore.cpp
+++ b/src/nickcore.cpp
@@ -16,7 +16,6 @@ NickCore::NickCore(const std::string &coredisplay)
lastmail = 0;
this->display = sstrdup(coredisplay.c_str());
- slist_init(&this->aliases);
/* Set default nick core flags */
for (size_t t = NI_BEGIN + 1; t != NI_END; ++t)
diff --git a/src/nickserv.c b/src/nickserv.c
index be1ed5470..c3b3d31c6 100644
--- a/src/nickserv.c
+++ b/src/nickserv.c
@@ -148,7 +148,7 @@ void get_core_stats(long *nrec, long *memuse)
mem += strlen(nc->memos.memos[j]->text) + 1;
}
- mem += sizeof(void *) * nc->aliases.count;
+ mem += sizeof(NickAlias *) * nc->aliases.size();
}
*nrec = count;
*memuse = mem;
@@ -485,9 +485,9 @@ void change_core_display(NickCore * nc, const char *newdisplay)
void change_core_display(NickCore * nc)
{
NickAlias *na;
- if (nc->aliases.count <= 0)
+ if (nc->aliases.empty())
return;
- na = static_cast<NickAlias *>(nc->aliases.list[0]);
+ na = nc->aliases.front();
change_core_display(nc,na->nick);
}
diff --git a/src/operserv.c b/src/operserv.c
index fda5f5fd8..c8432b9f9 100644
--- a/src/operserv.c
+++ b/src/operserv.c
@@ -15,27 +15,10 @@
#include "modules.h"
#include "language.h"
-/*************************************************************************/
-
-/* AKILL, SGLINE, SQLINE and SZLINE lists */
-SList akills, sglines, sqlines, szlines;
-
-/*************************************************************************/
-
-static int is_akill_entry_equal(SList * slist, void *item1, void *item2);
-static void free_akill_entry(SList * slist, void *item);
-static int is_sgline_entry_equal(SList * slist, void *item1, void *item2);
-static void free_sgline_entry(SList * slist, void *item);
-static int is_sqline_entry_equal(SList * slist, void *item1, void *item2);
-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);
-
-/* News items */
std::vector<NewsItem *> News;
std::vector<std::bitset<32> > DefCon;
-int DefConModesSet = 0;
+bool DefConModesSet = false;
/* Defcon modes mlocked on */
Flags<ChannelModeName> DefConModesOn;
/* Defcon modes mlocked off */
@@ -43,20 +26,53 @@ Flags<ChannelModeName> DefConModesOff;
/* Map of Modesa and Params for DefCon */
std::map<ChannelModeName, std::string> DefConModesOnParams;
+XLineManager *SGLine, *SZLine, *SQLine, *SNLine;
+
+void os_init()
+{
+ ModuleManager::LoadModuleList(Config.OperServCoreModules);
+
+ /* Yes, these are in this order for a reason. Most violent->least violent. */
+ XLineManager::RegisterXLineManager(SGLine = new SGLineManager());
+ XLineManager::RegisterXLineManager(SZLine = new SZLineManager());
+ XLineManager::RegisterXLineManager(SQLine = new SQLineManager());
+ XLineManager::RegisterXLineManager(SNLine = new SNLineManager());
+}
+
+void operserv(User * u, char *buf)
+{
+ const char *cmd, *s;
+
+ Alog() << Config.s_OperServ << ": " << u->nick << ": " << buf;
+
+ cmd = strtok(buf, " ");
+ if (!cmd)
+ return;
+ else if (!stricmp(cmd, "\1PING")) {
+ if (!(s = strtok(NULL, ""))) {
+ s = "";
+ }
+ ircdproto->SendCTCP(OperServ, u->nick.c_str(), "PING %s", s);
+ }
+ else {
+ mod_run_cmd(OperServ, u, cmd);
+ }
+}
+
bool SetDefConParam(ChannelModeName Name, std::string &buf)
{
return DefConModesOnParams.insert(std::make_pair(Name, buf)).second;
}
-bool GetDefConParam(ChannelModeName Name, std::string *buf)
+bool GetDefConParam(ChannelModeName Name, std::string &buf)
{
std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name);
- buf->clear();
+ buf.clear();
if (it != DefConModesOnParams.end())
{
- *buf = it->second;
+ buf = it->second;
return true;
}
@@ -73,83 +89,44 @@ void UnsetDefConParam(ChannelModeName Name)
}
}
-/*************************************************************************/
-
-void moduleAddOperServCmds();
-/*************************************************************************/
-
-/* Options for the lists */
-SListOpts akopts = { 0, NULL, &is_akill_entry_equal, &free_akill_entry };
-
-SListOpts sgopts = { 0, NULL, &is_sgline_entry_equal, &free_sgline_entry };
-SListOpts sqopts =
- { SLISTF_SORT, NULL, &is_sqline_entry_equal, &free_sqline_entry };
-SListOpts szopts = { 0, NULL, &is_szline_entry_equal, &free_szline_entry };
-
-/*************************************************************************/
-/* *INDENT-OFF* */
-void moduleAddOperServCmds() {
- ModuleManager::LoadModuleList(Config.OperServCoreModules);
+/** Check if a certain defcon option is currently in affect
+ * @param Level The level
+ * @return true and false
+ */
+bool CheckDefCon(DefconLevel Level)
+{
+ if (Config.DefConLevel)
+ return DefCon[Config.DefConLevel][Level];
+ return false;
}
-/* *INDENT-ON* */
-/*************************************************************************/
-/*************************************************************************/
-
-/* OperServ initialization. */
-
-void os_init()
+/** 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)
{
- moduleAddOperServCmds();
-
- slist_init(&akills);
- akills.opts = &akopts;
-
- if (ircd->sgline) {
- slist_init(&sglines);
- sglines.opts = &sgopts;
- }
- if (ircd->sqline) {
- slist_init(&sqlines);
- sqlines.opts = &sqopts;
- }
- if (ircd->szline) {
- slist_init(&szlines);
- szlines.opts = &szopts;
- }
+ return DefCon[level][Level];
}
-/*************************************************************************/
-
-/* Main OperServ routine. */
-
-void operserv(User * u, char *buf)
+/** 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)
{
- const char *cmd;
- const char *s;
-
- Alog() << Config.s_OperServ << ": " << u->nick << ": " << buf;
-
- cmd = strtok(buf, " ");
- if (!cmd) {
- return;
- } else if (stricmp(cmd, "\1PING") == 0) {
- if (!(s = strtok(NULL, ""))) {
- s = "";
- }
- ircdproto->SendCTCP(OperServ, u->nick.c_str(), "PING %s", s);
- } else {
- mod_run_cmd(OperServ, u, cmd);
- }
+ DefCon[level][Level] = true;
}
-/*************************************************************************/
-/*********************** OperServ command functions **********************/
-/*******************************
- * ******************************************/
-
-/*************************************************************************/
-
+/** Remove a defcon level option from a defcon level
+ * @param level The defcon level
+ * @param Level The defcon level option
+ */
+void DelDefCon(int level, DefconLevel Level)
+{
+ DefCon[level][Level] = false;
+}
void server_global(Server *s, const std::string &message)
{
@@ -175,7 +152,6 @@ void oper_global(char *nick, const char *fmt, ...)
vsnprintf(msg, sizeof(msg), fmt, args);
va_end(args);
- /* I don't like the way this is coded... */
if (nick && !Config.AnonymousGlobal)
{
std::string rmsg = std::string("[") + nick + std::string("] ") + msg;
@@ -188,868 +164,665 @@ void oper_global(char *nick, const char *fmt, ...)
/**************************************************************************/
-/* Adds an AKILL to the list. Returns >= 0 on success, -1 if it fails, -2
- * if only the expiry time was changed.
- * The success result is the number of AKILLs that were deleted to successfully add one.
- */
+/* List of XLine managers we check users against in XLineManager::CheckAll */
+std::list<XLineManager *> XLineManager::XLineManagers;
-int add_akill(User * u, const char *mask, const char *by, const time_t expires,
- const char *reason)
+XLine::XLine(const ci::string &mask, const std::string &reason) : Mask(mask), Reason(reason)
{
- int deleted = 0, i;
- char *user, *mask2, *host;
- Akill *entry;
+ Expires = Created = 0;
+}
- if (!mask) {
- return -1;
- }
+XLine::XLine(const ci::string &mask, const ci::string &by, const time_t expires, const std::string &reason) : Mask(mask), By(by), Created(time(NULL)), Expires(expires), Reason(reason)
+{
+}
- /* Checks whether there is an AKILL that already covers
- * the one we want to add, and whether there are AKILLs
- * that would be covered by this one. The masks AND the
- * expiry times are used to determine this, because some
- * AKILLs may become useful when another one expires.
- * If so, warn the user in the first case and cleanup
- * the useless AKILLs in the second.
- */
-
- if (akills.count > 0) {
-
- for (i = akills.count - 1; i >= 0; i--) {
- char amask[BUFSIZE];
-
- entry = static_cast<Akill *>(akills.list[i]);
-
- if (!entry)
- continue;
-
- snprintf(amask, sizeof(amask), "%s@%s", entry->user,
- entry->host);
-
- if (!stricmp(amask, mask)) {
- /* We change the AKILL expiry time if its current one is less than the new.
- * This is preferable to be sure we don't change an important AKILL
- * accidentely.
- */
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_CHANGED,
- amask);
- return -2;
- }
- }
+ci::string XLine::GetNick() const
+{
+ size_t nick_t = Mask.find('!');
- if (Anope::Match(mask, amask, false)
- && (entry->expires >= expires || entry->expires == 0)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_ALREADY_COVERED,
- mask, amask);
- return -1;
- }
+ if (nick_t == ci::string::npos)
+ return "";
- if (Anope::Match(amask, mask, false)
- && (entry->expires <= expires || expires == 0)) {
- slist_delete(&akills, i);
- deleted++;
- }
- }
+ return Mask.substr(0, nick_t - 1);
+}
- }
+ci::string XLine::GetUser() const
+{
+ size_t user_t = Mask.find('!'), host_t = Mask.find('@');
- /* We can now check whether the list is full or not. */
- if (slist_full(&akills)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_REACHED_LIMIT,
- akills.limit);
- return -1;
+ if (user_t == ci::string::npos)
+ {
+ return Mask.substr(0, host_t);
}
-
- /* We can now (really) add the AKILL. */
- mask2 = sstrdup(mask);
- host = strchr(mask2, '@');
-
- if (!host) {
- delete [] mask2;
- return -1;
+ else if (host_t != ci::string::npos)
+ {
+ return Mask.substr((user_t != ci::string::npos ? user_t + 1 : 0), host_t);
}
-
- user = mask2;
- *host = 0;
- host++;
-
- entry = new Akill;
-
- if (!entry) {
- delete [] mask2;
- return -1;
+ else
+ {
+ return "";
}
+}
- entry->user = sstrdup(user);
- entry->host = sstrdup(host);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
+ci::string XLine::GetHost() const
+{
+ size_t host_t = Mask.find('@');
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddAkill, OnAddAkill(u, entry));
- if (MOD_RESULT == EVENT_STOP)
+ if (host_t == ci::string::npos)
{
- delete entry;
- return -1;
+ return Mask;
+ }
+ else
+ {
+ return Mask.substr(host_t + 1);
}
-
- slist_add(&akills, entry);
-
- if (Config.AkillOnAdd)
- ircdproto->SendAkill(entry);
-
- delete [] mask2;
-
- return deleted;
}
-/* Does the user match any AKILLs? */
+/** Constructor
+ */
+XLineManager::XLineManager()
+{
+}
-int check_akill(const char *nick, const char *username, const char *host,
- const char *vhost, const char *ip)
+/** Destructor
+ * Clears all XLines in this XLineManager
+ */
+XLineManager::~XLineManager()
{
- int i;
- Akill *ak;
+ Clear();
+}
- if (akills.count == 0)
- return 0;
+ /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
+ * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
+ * clients and one handing them free olines, you would want the akilling one first. This way if a client
+ * matches an entry on both of the XLineManagers, they would be akilled.
+ * @param xlm THe XLineManager
+ */
+void XLineManager::RegisterXLineManager(XLineManager *xlm)
+{
+ XLineManagers.push_back(xlm);
+}
- for (i = 0; i < akills.count; i++) {
- ak = static_cast<Akill *>(akills.list[i]);
- if (!ak)
- continue;
- if (Anope::Match(username, ak->user, false)
- && Anope::Match(host, ak->host, false)) {
- ircdproto->SendAkill(ak);
- return 1;
- }
- if (ircd->vhost) {
- if (vhost) {
- if (Anope::Match(username, ak->user, false)
- && Anope::Match(vhost, ak->host, false)) {
- ircdproto->SendAkill(ak);
- return 1;
- }
- }
- }
- if (ircd->nickip) {
- if (ip) {
- if (Anope::Match(username, ak->user, false)
- && Anope::Match(ip, ak->host, false)) {
- ircdproto->SendAkill(ak);
- return 1;
- }
- }
- }
+/** Unregister a XLineManager
+ * @param xlm The XLineManager
+ */
+void XLineManager::UnregisterXLineManager(XLineManager *xlm)
+{
+ std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm);
+ if (it != XLineManagers.end())
+ {
+ XLineManagers.erase(it);
}
-
- return 0;
}
-/* Delete any expired autokills. */
-
-void expire_akills()
+/* Check a user against all known XLineManagers
+ * @param u The user
+ * @return A pair of the XLineManager the user was found in and the XLine they matched, both may be NULL for no match
+ */
+std::pair<XLineManager *, XLine *> XLineManager::CheckAll(User *u)
{
- int i;
- time_t now = time(NULL);
- Akill *ak;
+ std::pair<XLineManager *, XLine *> ret(NULL, NULL);
- for (i = akills.count - 1; i >= 0; i--) {
- ak = static_cast<Akill *>(akills.list[i]);
+ for (std::list<XLineManager *>::iterator it = XLineManagers.begin(); it != XLineManagers.end(); ++it)
+ {
+ XLineManager *xlm = *it;
- if (!ak->expires || ak->expires > now)
- continue;
+ XLine *x = xlm->Check(u);
- if (Config.WallAkillExpire)
- ircdproto->SendGlobops(OperServ, "AKILL on %s@%s has expired",
- ak->user, ak->host);
- slist_delete(&akills, i);
+ if (x)
+ {
+ ret.first = xlm;
+ ret.second = x;;
+ break;
+ }
}
+
+ return ret;
}
-static void free_akill_entry(SList * slist, void *item)
+/** Get the number of XLines in this XLineManager
+ * @return The number of XLines
+ */
+const size_t XLineManager::GetCount() const
{
- Akill *ak = static_cast<Akill *>(item);
-
- /* Remove the AKILLs from all the servers */
- ircdproto->SendAkillDel(ak);
+ return XLines.size();
+}
- /* Free the structure */
- delete [] ak->user;
- delete [] ak->host;
- delete [] ak->by;
- delete [] ak->reason;
- delete ak;
+/** Get the XLine list
+ * @return The list
+ */
+const std::deque<XLine *>& XLineManager::GetList() const
+{
+ return XLines;
}
-/* item1 is not an Akill pointer, but a char
+/** Add an entry to this XLineManager
+ * @param x The entry
*/
-
-static int is_akill_entry_equal(SList * slist, void *item1, void *item2)
+void XLineManager::AddXLine(XLine *x)
{
- char *ak1 = static_cast<char *>(item1), buf[BUFSIZE];
- Akill *ak2 = static_cast<Akill *>(item2);
-
- if (!ak1 || !ak2)
- return 0;
-
- snprintf(buf, sizeof(buf), "%s@%s", ak2->user, ak2->host);
-
- if (!stricmp(ak1, buf))
- return 1;
- else
- return 0;
+ XLines.push_back(x);
}
-
-/*************************************************************************/
-
-/* Adds an SGLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if
- * only the expiry time changed.
- * The success result is the number of SGLINEs that were deleted to successfully add one.
+/** Delete an entry from this XLineManager
+ * @param x The entry
+ * @return true if the entry was found and deleted, else false
*/
-
-int add_sgline(User * u, const char *mask, const char *by, time_t expires,
- const char *reason)
+bool XLineManager::DelXLine(XLine *x)
{
- int deleted = 0, i;
- SXLine *entry;
-
- /* Checks whether there is an SGLINE that already covers
- * the one we want to add, and whether there are SGLINEs
- * that would be covered by this one.
- * If so, warn the user in the first case and cleanup
- * the useless SGLINEs in the second.
- */
-
- if (!mask) {
- return -1;
- }
+ std::deque<XLine *>::iterator it = std::find(XLines.begin(), XLines.end(), x);
- if (sglines.count > 0) {
-
- for (i = sglines.count - 1; i >= 0; i--) {
- entry = static_cast<SXLine *>(sglines.list[i]);
-
- if (!entry)
- continue;
-
- if (!stricmp(entry->mask, mask)) {
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_CHANGED,
- entry->mask);
- return -2;
- }
- }
-
- if (Anope::Match(mask, entry->mask, false )
- && (entry->expires >= expires || entry->expires == 0)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_ALREADY_COVERED,
- mask, entry->mask);
- return -1;
- }
-
- if (Anope::Match(entry->mask, mask, false)
- && (entry->expires <= expires || expires == 0)) {
- slist_delete(&sglines, i);
- deleted++;
- }
- }
-
- }
+ if (it != XLines.end())
+ {
+ delete x;
+ XLines.erase(it);
- /* We can now check whether the list is full or not. */
- if (slist_full(&sglines)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_REACHED_LIMIT,
- sglines.limit);
- return -1;
+ return true;
}
- /* We can now (really) add the SGLINE. */
- entry = new SXLine;
- if (!entry)
- return -1;
+ return false;
+}
- entry->mask = sstrdup(mask);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
+/** Gets an entry by index
+ * @param index The index
+ * @return The XLine, or NULL if the index is out of bounds
+ */
+XLine *XLineManager::GetEntry(unsigned index) const
+{
+ if (index >= XLines.size())
+ return NULL;
+
+ return XLines[index];
+}
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SGLINE));
- if (MOD_RESULT == EVENT_STOP)
+/** Clear the XLine list
+ */
+void XLineManager::Clear()
+{
+ for (std::deque<XLine *>::iterator it = XLines.begin(); it != XLines.end(); ++it)
{
- delete entry;
- return -1;
+ delete *it;
}
+ XLines.clear();
+}
+
+/** Add an entry to this XLine Manager
+ * @param bi The bot error replies should be sent from
+ * @param u The user adding the XLine
+ * @param mask The mask of the XLine
+ * @param expires When this should expire
+ * @param reaosn The reason
+ * @return A pointer to the XLine
+ */
+XLine *XLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ return NULL;
+}
- slist_add(&sglines, entry);
+/** Delete an XLine, eg, remove it from the IRCd.
+ * @param x The xline
+ */
+void XLineManager::Del(XLine *x)
+{
+}
- ircdproto->SendSGLine(entry);
+/** Checks if a mask can/should be added to the XLineManager
+ * @param mask The mask
+ * @param expires When the mask would expire
+ * @return A pair of int and XLine*.
+ * 1 - Mask already exists
+ * 2 - Mask already exists, but the expiry time was changed
+ * 3 - Mask is already covered by another mask
+ * In each case the XLine it matches/is covered by is returned in XLine*
+ */
+std::pair<int, XLine *> XLineManager::CanAdd(const ci::string &mask, time_t expires)
+{
+ std::pair<int, XLine *> ret(0, NULL);
- if (Config.KillonSGline && !ircd->sglineenforce)
+ for (unsigned i = 0; i < GetCount(); ++i)
{
- char buf[BUFSIZE];
- snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason);
+ XLine *x = GetEntry(i);
+ ret.second = x;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ if (x->Mask == mask)
{
- User *u2 = it->second;
- ++it;
-
- if (!is_oper(u2) && Anope::Match(u2->realname, entry->mask, false))
+ if (x->Expires == 0 || x->Expires >= expires)
+ {
+ ret.first = 1;
+ break;
+ }
+ else
{
- kill_user(Config.ServerName, u2->nick, buf);
+ x->Expires = expires;
+
+ ret.first = 2;
+ break;
}
}
+ else if (Anope::Match(mask, x->Mask) && (x->Expires == 0 || x->Expires >= expires))
+ {
+ ret.first = 3;
+ break;
+ }
+ else if (Anope::Match(x->Mask, mask) && (expires == 0 || x->Expires <= expires))
+ {
+ this->DelXLine(x);
+ --i;
+ }
}
- return deleted;
-}
-/* Does the user match any SGLINEs? */
+ return ret;
+}
-int check_sgline(const char *nick, const char *realname)
+/** Checks if this list has an entry
+ * @param mask The mask
+ * @return The XLine the user matches, or NULL
+ */
+XLine *XLineManager::HasEntry(const ci::string &mask) const
{
- int i;
- SXLine *sx;
-
- if (sglines.count == 0)
- return 0;
-
- for (i = 0; i < sglines.count; i++) {
- sx = static_cast<SXLine *>(sglines.list[i]);
- if (!sx)
- continue;
+ for (unsigned i = 0; i < XLines.size(); ++i)
+ {
+ XLine *x = XLines[i];
- if (Anope::Match(realname, sx->mask, false)) {
- ircdproto->SendSGLine(sx);
- /* We kill nick since s_sgline can't */
- ircdproto->SendSVSKill(NULL, finduser(nick), "G-Lined: %s", sx->reason);
- return 1;
+ if (x->Mask == mask)
+ {
+ return x;
}
}
- return 0;
+ return NULL;
}
-/* Delete any expired SGLINEs. */
-
-void expire_sglines()
+/** Check a user against all of the xlines in this XLineManager
+ * @param u The user
+ * @return The xline the user marches, if any. Also calls OnMatch()
+ */
+XLine *XLineManager::Check(User *u)
{
- int i;
- time_t now = time(NULL);
- SXLine *sx;
+ const time_t now = time(NULL);
- for (i = sglines.count - 1; i >= 0; i--) {
- sx = static_cast<SXLine *>(sglines.list[i]);
+ for (std::deque<XLine *>::iterator it = XLines.begin(); it != XLines.end(); ++it)
+ {
+ XLine *x = *it;
- if (!sx->expires || sx->expires > now)
+ if (x->Expires && x->Expires < now)
+ {
+ OnExpire(x);
+ delete x;
+ it = XLines.erase(it);
+ --it;
continue;
+ }
- if (Config.WallSGLineExpire)
- ircdproto->SendGlobops(OperServ, "SGLINE on \2%s\2 has expired",
- sx->mask);
- slist_delete(&sglines, i);
- }
-}
+ if (!x->GetNick().empty() && !Anope::Match(u->nick.c_str(), x->GetNick()))
+ continue;
-static void free_sgline_entry(SList * slist, void *item)
-{
- SXLine *sx = static_cast<SXLine *>(item);
+ if (!x->GetUser().empty() && !Anope::Match(u->GetIdent().c_str(), x->GetUser()))
+ continue;
- /* Remove the SGLINE from all the servers */
- ircdproto->SendSGLineDel(sx);
+ if (x->GetNick().empty() && x->GetUser().empty() || ((u->hostip && Anope::Match(u->hostip, x->GetHost())) || Anope::Match(u->host, x->GetHost()) || (!u->chost.empty() && Anope::Match(u->chost.c_str(), x->GetHost())) || (u->vhost && Anope::Match(u->vhost, x->GetHost()))))
+ {
+ OnMatch(u, x);
+ return x;
+ }
+ }
- /* Free the structure */
- delete [] sx->mask;
- delete [] sx->by;
- delete [] sx->reason;
- delete sx;
+ return NULL;
}
-/* item1 is not an SXLine pointer, but a char */
-
-static int is_sgline_entry_equal(SList * slist, void *item1, void *item2)
+/** Called when a user matches a xline in this XLineManager
+ * @param u The user
+ * @param x The XLine they match
+ */
+void XLineManager::OnMatch(User *u, XLine *x)
{
- char *sx1 = static_cast<char *>(item1);
- SXLine *sx2 = static_cast<SXLine *>(item2);
-
- if (!sx1 || !sx2)
- return 0;
-
- if (!stricmp(sx1, sx2->mask))
- return 1;
- else
- return 0;
}
-/*************************************************************************/
-
-/* Adds an SQLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if
- * only the expiry time changed.
- * The success result is the number of SQLINEs that were deleted to successfully add one.
+/** Called when an XLine expires
+ * @param x The xline
*/
+void XLineManager::OnExpire(XLine *x)
+{
+}
-int add_sqline(User * u, const char *mask, const char *by, time_t expires,
- const char *reason)
+XLine *SGLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
{
- int deleted = 0, i;
- SXLine *entry;
-
- /* Checks whether there is an SQLINE that already covers
- * the one we want to add, and whether there are SQLINEs
- * that would be covered by this one.
- * If so, warn the user in the first case and cleanup
- * the useless SQLINEs in the second.
- */
-
- if (!mask) {
- return -1;
+ if (mask.find('!') != ci::string::npos)
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_NO_NICK);
+ return NULL;
}
- if (sqlines.count > 0) {
-
- for (i = sqlines.count - 1; i >= 0; i--) {
- entry = static_cast<SXLine *>(sqlines.list[i]);
-
- if (!entry)
- continue;
-
- if ((*mask == '#' && *entry->mask != '#') ||
- (*mask != '#' && *entry->mask == '#'))
- continue;
-
- if (!stricmp(entry->mask, mask)) {
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANGED,
- entry->mask);
- return -2;
- }
- }
+ if (mask.find('@') == ci::string::npos)
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, BAD_USERHOST_MASK);
+ return NULL;
+ }
- if (Anope::Match(mask, entry->mask, false)
- && (entry->expires >= expires || entry->expires == 0)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_ALREADY_COVERED,
- mask, entry->mask);
- return -1;
- }
+ if (strspn(mask.c_str(), "~@.*?") == mask.length())
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
- if (Anope::Match(entry->mask, mask, false)
- && (entry->expires <= expires || expires == 0)) {
- slist_delete(&sqlines, i);
- deleted++;
- }
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
}
+ return canAdd.second;
}
- /* We can now check whether the list is full or not. */
- if (slist_full(&sqlines)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_REACHED_LIMIT,
- sqlines.limit);
- return -1;
- }
-
- /* We can now (really) add the SQLINE. */
- entry = new SXLine;
- if (!entry)
- return -1;
-
- entry->mask = sstrdup(mask);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
+ std::string realreason = reason;
+ if (u && Config.AddAkiller)
+ realreason = "[" + u->nick + "]" + reason;
+
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, realreason);
EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SQLINE));
+ FOREACH_RESULT(I_OnAddAkill, OnAddAkill(u, x));
if (MOD_RESULT == EVENT_STOP)
{
- delete entry;
- return -1;
+ delete x;
+ return NULL;
}
+
+ this->AddXLine(x);
- slist_add(&sqlines, entry);
-
- sqline(entry->mask, entry->reason);
-
- if (Config.KillonSQline)
- {
- char buf[BUFSIZE];
- snprintf(buf, (BUFSIZE - 1), "Q-Lined: %s", entry->reason);
-
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
- {
- User *u2 = it->second;
- ++it;
-
- if (!is_oper(u2) && Anope::Match(u2->nick, entry->mask, false))
- {
- kill_user(Config.ServerName, u2->nick, buf);
- }
- }
- }
-
- return deleted;
+ if (Config.AkillOnAdd)
+ ircdproto->SendAkill(x);
+
+ return x;
}
-/* Does the user match any SQLINEs? */
-
-int check_sqline(const char *nick, int nick_change)
+void SGLineManager::Del(XLine *x)
{
- int i;
- SXLine *sx;
- char reason[300];
+ ircdproto->SendAkillDel(x);
+}
- if (sqlines.count == 0)
- return 0;
+void SGLineManager::OnMatch(User *u, XLine *x)
+{
+ ircdproto->SendAkill(x);
+}
- for (i = 0; i < sqlines.count; i++) {
- sx = static_cast<SXLine *>(sqlines.list[i]);
- if (!sx)
- continue;
+void SGLineManager::OnExpire(XLine *x)
+{
+ if (Config.WallAkillExpire)
+ ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str());
+}
- if (ircd->chansqline) {
- if (*sx->mask == '#')
- continue;
- }
+XLine *SNLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ if (!mask.empty() && strspn(mask.c_str(), "*?") == mask.length())
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
- if (Anope::Match(nick, sx->mask, false)) {
- sqline(sx->mask, sx->reason);
- /* We kill nick since s_sqline can't */
- snprintf(reason, sizeof(reason), "Q-Lined: %s", sx->reason);
- kill_user(Config.s_OperServ, nick, reason);
- return 1;
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_SNLINE_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_SNLINE_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_SNLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
}
+
+ return canAdd.second;
}
- return 0;
-}
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason);
-int check_chan_sqline(const char *chan)
-{
- int i;
- SXLine *sx;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SNLINE));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return NULL;
+ }
- if (sqlines.count == 0)
- return 0;
+ this->AddXLine(x);
- for (i = 0; i < sqlines.count; i++) {
- sx = static_cast<SXLine *>(sqlines.list[i]);
- if (!sx)
- continue;
+ if (Config.KillonSNline && !ircd->sglineenforce)
+ {
+ std::string rreason = "G-Lined: " + reason;
- if (*sx->mask != '#')
- continue;
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *user = it->second;
+ ++it;
- if (Anope::Match(chan, sx->mask, false)) {
- sqline(sx->mask, sx->reason);
- return 1;
+ if (!is_oper(user) && Anope::Match(user->realname, x->Mask))
+ {
+ kill_user(Config.ServerName, user->nick, rreason.c_str());
+ }
}
}
- return 0;
+ return x;
}
-/* Delete any expired SQLINEs. */
-
-void expire_sqlines()
+void SNLineManager::Del(XLine *x)
{
- int i;
- time_t now = time(NULL);
- SXLine *sx;
-
- for (i = sqlines.count - 1; i >= 0; i--) {
- sx = static_cast<SXLine *>(sqlines.list[i]);
-
- if (!sx->expires || sx->expires > now)
- continue;
-
- if (Config.WallSQLineExpire)
- ircdproto->SendGlobops(OperServ, "SQLINE on \2%s\2 has expired",
- sx->mask);
-
- slist_delete(&sqlines, i);
- }
+ ircdproto->SendSGLineDel(x);
}
-static void free_sqline_entry(SList * slist, void *item)
+void SNLineManager::OnMatch(User *u, XLine *x)
{
- SXLine *sx = static_cast<SXLine *>(item);
-
- /* Remove the SQLINE from all the servers */
- ircdproto->SendSQLineDel(sx->mask);
+ ircdproto->SendSGLine(x);
- /* Free the structure */
- delete [] sx->mask;
- delete [] sx->by;
- delete [] sx->reason;
- delete sx;
+ std::string reason = "G-Lined: " + x->Reason;
+ kill_user(Config.s_OperServ, u->nick, reason.c_str());
}
-/* item1 is not an SXLine pointer, but a char */
-
-static int is_sqline_entry_equal(SList * slist, void *item1, void *item2)
+void SNLineManager::OnExpire(XLine *x)
{
- char *sx1 = static_cast<char *>(item1);
- SXLine *sx2 = static_cast<SXLine *>(item2);
-
- if (!sx1 || !sx2)
- return 0;
-
- if (!stricmp(sx1, sx2->mask))
- return 1;
- else
- return 0;
+ if (Config.WallSNLineExpire)
+ ircdproto->SendGlobops(OperServ, "SNLINE on \2%s\2 has expired", x->Mask.c_str());
}
-/*************************************************************************/
-
-/* Adds an SZLINE to the list. Returns >= 0 on success, -1 on error, -2 if
- * only the expiry time changed.
- * The success result is the number of SZLINEs that were deleted to successfully add one.
- */
-
-int add_szline(User * u, const char *mask, const char *by, time_t expires,
- const char *reason)
+XLine *SQLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
{
- int deleted = 0, i;
- SXLine *entry;
-
- if (!mask) {
- return -1;
+ if (strspn(mask.c_str(), "*") == mask.length())
+ {
+ if (bi && u)
+ notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
}
- /* Checks whether there is an SZLINE that already covers
- * the one we want to add, and whether there are SZLINEs
- * that would be covered by this one.
- * If so, warn the user in the first case and cleanup
- * the useless SZLINEs in the second.
- */
-
- if (szlines.count > 0) {
-
- for (i = szlines.count - 1; i >= 0; i--) {
- entry = static_cast<SXLine *>(szlines.list[i]);
-
- if (!entry)
- continue;
-
- if (!stricmp(entry->mask, mask)) {
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_EXISTS,
- mask);
- return -2;
- }
- }
-
- if (Anope::Match(mask, entry->mask, false)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_ALREADY_COVERED,
- mask, entry->mask);
- return -1;
- }
+ if (mask[0] == '#' && !ircd->chansqline)
+ {
+ if (bi && u)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANNELS_UNSUPPORTED);
+ return NULL;
+ }
- if (Anope::Match(entry->mask, mask, false)) {
- slist_delete(&szlines, i);
- deleted++;
- }
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_SQLINE_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_SQLINE_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_SQLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
}
+ return canAdd.second;
}
- /* We can now check whether the list is full or not. */
- if (slist_full(&szlines)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_REACHED_LIMIT,
- szlines.limit);
- return -1;
- }
-
- /* We can now (really) add the SZLINE. */
- entry = new SXLine;
- if (!entry)
- return -1;
-
- entry->mask = sstrdup(mask);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason);
EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SZLINE));
+ FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SQLINE));
if (MOD_RESULT == EVENT_STOP)
{
- delete entry;
- return -1;
+ delete x;
+ return NULL;
}
- slist_add(&szlines, entry);
- ircdproto->SendSZLine(entry);
-
- return deleted;
-}
-
-/* Check and enforce any Zlines that we have */
-int check_szline(const char *nick, char *ip)
-{
- int i;
- SXLine *sx;
-
- if (szlines.count == 0) {
- return 0;
- }
+ this->AddXLine(x);
- if (!ip) {
- return 0;
- }
+ if (Config.KillonSQline)
+ {
+ std::string rreason = "Q-Lined: " + reason;
- for (i = 0; i < szlines.count; i++) {
- sx = static_cast<SXLine *>(szlines.list[i]);
- if (!sx) {
- continue;
+ if (mask[0] == '#')
+ {
+ for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit)
+ {
+ Channel *c = cit->second;
+
+ if (!Anope::Match(c->name.c_str(), mask))
+ continue;
+ for (CUserList::iterator it = c->users.begin(); it != c->users.end();)
+ {
+ UserContainer *uc = *it;
+ ++it;
+
+ if (is_oper(uc->user))
+ continue;
+ c->Kick(NULL, uc->user, "%s", reason.c_str());
+ }
+ }
}
+ else
+ {
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *user = it->second;
+ ++it;
- if (Anope::Match(ip, sx->mask, false)) {
- ircdproto->SendSZLine(sx);
- return 1;
+ if (!is_oper(user) && Anope::Match(user->nick.c_str(), x->Mask))
+ {
+ kill_user(Config.ServerName, user->nick, rreason.c_str());
+ }
+ }
}
}
- return 0;
-}
+ ircdproto->SendSQLine(x);
+ return x;
+}
-/* Delete any expired SZLINEs. */
+void SQLineManager::Del(XLine *x)
+{
+ ircdproto->SendSQLineDel(x);
+}
-void expire_szlines()
+void SQLineManager::OnMatch(User *u, XLine *x)
{
- int i;
- time_t now = time(NULL);
- SXLine *sx;
+ ircdproto->SendSQLine(x);
- for (i = szlines.count - 1; i >= 0; i--) {
- sx = static_cast<SXLine *>(szlines.list[i]);
+ char reason[300];
+ snprintf(reason, sizeof(reason), "Q-Lined: %s", x->Reason.c_str());
+ kill_user(Config.s_OperServ, u->nick, reason);
+}
- if (!sx->expires || sx->expires > now)
- continue;
+void SQLineManager::OnExpire(XLine *x)
+{
+ if (Config.WallSQLineExpire)
+ ircdproto->SendGlobops(OperServ, "SQLINE on \2%s\2 has expired", x->Mask.c_str());
+}
+
+bool SQLineManager::Check(Channel *c)
+{
+ if (ircd->chansqline && SQLine)
+ {
+ for (std::deque<XLine *>::const_iterator it = SGLine->GetList().begin(); it != SGLine->GetList().end(); ++it)
+ {
+ XLine *x = *it;
- if (Config.WallSZLineExpire)
- ircdproto->SendGlobops(OperServ, "SZLINE on \2%s\2 has expired",
- sx->mask);
- slist_delete(&szlines, i);
+ if (Anope::Match(c->name.c_str(), x->Mask))
+ {
+ return true;
+ }
+ }
}
+
+ return false;
}
-static void free_szline_entry(SList * slist, void *item)
+XLine *SZLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
{
- SXLine *sx = static_cast<SXLine *>(item);
+ if (mask.find('!') != ci::string::npos || mask.find('@') != ci::string::npos)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_ONLY_IPS);
+ return NULL;
+ }
- /* Remove the SZLINE from all the servers */
- ircdproto->SendSZLineDel(sx);
+ if (strspn(mask.c_str(), "*?") == mask.length())
+ {
+ notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
- /* Free the structure */
- delete [] sx->mask;
- delete [] sx->by;
- delete [] sx->reason;
- delete sx;
-}
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_SZLINE_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_SZLINE_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_SZLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
+ }
-/* item1 is not an SXLine pointer, but a char
- */
+ return canAdd.second;
+ }
-static int is_szline_entry_equal(SList * slist, void *item1, void *item2)
-{
- char *sx1 = static_cast<char *>(item1);
- SXLine *sx2 = static_cast<SXLine *>(item2);
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason);
- if (!sx1 || !sx2)
- return 0;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SZLINE));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return NULL;
+ }
- if (!stricmp(sx1, sx2->mask))
- return 1;
- else
- return 0;
-}
+ this->AddXLine(x);
-/*************************************************************************/
+ ircdproto->SendSZLine(x);
-/** Check if a certain defcon option is currently in affect
- * @param Level The level
- * @return true and false
- */
-bool CheckDefCon(DefconLevel Level)
-{
- if (Config.DefConLevel)
- return DefCon[Config.DefConLevel][Level];
- return false;
+ return x;
}
-/** 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)
+void SZLineManager::Del(XLine *x)
{
- return DefCon[level][Level];
+ ircdproto->SendSZLineDel(x);
}
-/** 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)
+void SZLineManager::OnMatch(User *u, XLine *x)
{
- DefCon[level][Level] = true;
+ ircdproto->SendSZLine(x);
}
-/** Remove a defcon level option from a defcon level
- * @param level The defcon level
- * @param Level The defcon level option
- */
-void DelDefCon(int level, DefconLevel Level)
+void SZLineManager::OnExpire(XLine *x)
{
- DefCon[level][Level] = false;
+ if (Config.WallSZLineExpire)
+ ircdproto->SendGlobops(OperServ, "SZLINE on \2%s\2 has expired", x->Mask.c_str());
}
diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.c
index 14dc68cb5..040144737 100644
--- a/src/protocol/bahamut.c
+++ b/src/protocol/bahamut.c
@@ -23,7 +23,7 @@ IRCDVar myIrcd[] = {
"+o", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
0, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
3, /* Number of server args */
@@ -141,35 +141,33 @@ class BahamutIRCdProto : public IRCDProto
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(NULL, "SQLINE %s :%s", mask.c_str(), reason.c_str());
+ send_cmd(NULL, "SQLINE %s :%s", x->Mask.c_str(), x->Reason.c_str());
}
- /* UNSGLINE */
- void SendSGLineDel(SXLine *sx)
+ /* UNSLINE */
+ void SendSGLineDel(XLine *x)
{
- send_cmd(NULL, "UNSGLINE 0 :%s", sx->mask);
+ send_cmd(NULL, "UNSGLINE 0 :%s", x->Mask.c_str());
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
/* this will likely fail so its only here for legacy */
- send_cmd(NULL, "UNSZLINE 0 %s", sx->mask);
+ send_cmd(NULL, "UNSZLINE 0 %s", x->Mask.c_str());
/* this is how we are supposed to deal with it */
- send_cmd(NULL, "RAKILL %s *", sx->mask);
+ send_cmd(NULL, "RAKILL %s *", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
/* this will likely fail so its only here for legacy */
- send_cmd(NULL, "SZLINE %s :%s", sx->mask, sx->reason);
+ send_cmd(NULL, "SZLINE %s :%s", x->Mask.c_str(), x->Reason.c_str());
/* this is how we are supposed to deal with it */
- send_cmd(NULL, "AKILL %s * %d %s %ld :%s", sx->mask, 172800, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(NULL, "AKILL %s * %d %s %ld :%s", x->Mask.c_str(), 172800, x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSNOOP */
@@ -179,15 +177,15 @@ class BahamutIRCdProto : public IRCDProto
}
/* SGLINE */
- void SendSGLine(SXLine *sx)
+ void SendSGLine(XLine *x)
{
- send_cmd(NULL, "SGLINE %d :%s:%s", static_cast<int>(strlen(sx->mask)), sx->mask, sx->reason);
+ send_cmd(NULL, "SGLINE %d :%s:%s", x->Mask.length(), x->Mask.c_str(), x->Reason.c_str());
}
/* RAKILL */
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- send_cmd(NULL, "RAKILL %s %s", ak->host, ak->user);
+ send_cmd(NULL, "RAKILL %s %s", x->GetHost().c_str(), x->GetUser().c_str());
}
/* TOPIC */
@@ -197,11 +195,9 @@ class BahamutIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(NULL, "UNSQLINE %s", user.c_str());
+ send_cmd(NULL, "UNSQLINE %s", x->Mask.c_str());
}
/* JOIN - SJOIN */
@@ -210,12 +206,12 @@ class BahamutIRCdProto : public IRCDProto
send_cmd(user->nick, "SJOIN %ld %s", static_cast<long>(chantime), channel);
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
+ time_t timeleft = x->Expires - time(NULL);
if (timeleft > 172800) timeleft = 172800;
- send_cmd(NULL, "AKILL %s %s %d %s %ld :%s", ak->host, ak->user, static_cast<int>(timeleft), ak->by, static_cast<long>(time(NULL)), ak->reason);
+ send_cmd(NULL, "AKILL %s %s %d %s %ld :%s", x->GetHost().c_str(), x->GetUser().c_str(), static_cast<int>(timeleft), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/*
diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c
index 4c698edad..8fe766824 100644
--- a/src/protocol/inspircd11.c
+++ b/src/protocol/inspircd11.c
@@ -40,7 +40,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
4, /* Number of server args */
@@ -119,9 +119,9 @@ void inspircd_cmd_pass(const char *pass)
class InspIRCdProto : public IRCDProto
{
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- send_cmd(Config.s_OperServ, "GLINE %s@%s", ak->user, ak->host);
+ send_cmd(Config.s_OperServ, "GLINE %s", x->Mask.c_str());
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -142,13 +142,13 @@ class InspIRCdProto : public IRCDProto
}
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
+ time_t timeleft = x->Expires - time(NULL);
if (timeleft > 172800)
timeleft = 172800;
- send_cmd(Config.ServerName, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason);
+ send_cmd(Config.ServerName, "ADDLINE G %s %s %ld %ld :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -214,19 +214,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(Config.s_OperServ, "QLINE %s", user.c_str());
+ send_cmd(Config.s_OperServ, "QLINE %s", x->Mask.c_str());
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(Config.ServerName, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str());
+ send_cmd(Config.ServerName, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SQUIT */
@@ -281,15 +277,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(Config.s_OperServ, "ZLINE %s", sx->mask);
+ send_cmd(Config.s_OperServ, "ZLINE %s", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(Config.ServerName, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(Config.ServerName, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSMODE +- */
diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp
index d326b6820..5fa330197 100644
--- a/src/protocol/inspircd12.cpp
+++ b/src/protocol/inspircd12.cpp
@@ -40,7 +40,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 0, /* Supports SGlines */
+ 0, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
4, /* Number of server args */
@@ -123,10 +123,10 @@ void inspircd_cmd_pass(const char *pass)
class InspIRCdProto : public IRCDProto
{
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
BotInfo *bi = OperServ;
- send_cmd(bi->uid, "GLINE %s@%s", ak->user, ak->host);
+ send_cmd(bi->uid, "GLINE %s", x->Mask.c_str());
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -147,14 +147,14 @@ class InspIRCdProto : public IRCDProto
}
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
- if (timeleft > 172800 || !ak->expires)
+ time_t timeleft = x->Expires - time(NULL);
+ if (timeleft > 172800 || !x->Expires)
timeleft = 172800;
BotInfo *bi = OperServ;
- send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason);
+ send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -219,19 +219,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(TS6SID, "DELLINE Q %s", user.c_str());
+ send_cmd(TS6SID, "DELLINE Q %s", x->Mask.c_str());
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str());
+ send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SQUIT */
@@ -288,15 +284,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(TS6SID, "DELLINE Z %s", sx->mask);
+ send_cmd(TS6SID, "DELLINE Z %s", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSMODE -r */
diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c
index 58ab14154..95ccf6392 100644
--- a/src/protocol/ratbox.c
+++ b/src/protocol/ratbox.c
@@ -23,7 +23,7 @@ IRCDVar myIrcd[] = {
"+o", /* Channel Umode used by Botserv bots */
0, /* SVSNICK */
0, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
0, /* Supports SZlines */
3, /* Number of server args */
@@ -136,36 +136,32 @@ class RatboxProto : public IRCDTS6Proto
send_cmd(TS6SID, "OPERWALL :%s", buf);
}
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(TS6SID, "RESV * %s :%s", mask.c_str(), reason.c_str());
+ send_cmd(TS6SID, "RESV * %s :%s", x->Mask.c_str(), x->Reason.c_str());
}
- void SendSGLineDel(SXLine *sx)
+ void SendSGLineDel(XLine *x)
{
BotInfo *bi = OperServ;
- send_cmd(bi ? bi->uid : Config.s_OperServ, "UNXLINE * %s", sx->mask);
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "UNXLINE * %s", x->Mask.c_str());
}
- void SendSGLine(SXLine *sx)
+ void SendSGLine(XLine *x)
{
BotInfo *bi = OperServ;
- send_cmd(bi ? bi->uid : Config.s_OperServ, "XLINE * %s 0 :%s", sx->mask, sx->reason);
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "XLINE * %s 0 :%s", x->Mask.c_str(), x->Reason.c_str());
}
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
BotInfo *bi = OperServ;
- send_cmd(bi ? bi->uid : Config.s_OperServ, "UNKLINE * %s %s", ak->user, ak->host);
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "UNKLINE * %s %s", x->GetUser().c_str(), x->GetHost().c_str());
}
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(TS6SID, "UNRESV * %s", user.c_str());
+ send_cmd(TS6SID, "UNRESV * %s", x->Mask.c_str());
}
void SendJoin(BotInfo *user, const char *channel, time_t chantime)
@@ -173,10 +169,10 @@ class RatboxProto : public IRCDTS6Proto
send_cmd(NULL, "SJOIN %ld %s + :%s", static_cast<long>(chantime), channel, user->uid.c_str());
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
BotInfo *bi = OperServ;
- send_cmd(bi ? bi->uid : Config.s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(ak->expires - time(NULL)), ak->user, ak->host, ak->reason);
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(x->Expires - time(NULL)), x->GetUser().c_str(), x->GetHost().c_str(), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c
index b14c48343..4d90e6bcf 100644
--- a/src/protocol/unreal32.c
+++ b/src/protocol/unreal32.c
@@ -23,7 +23,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
3, /* Number of server args */
@@ -133,9 +133,9 @@ class UnrealIRCdProto : public IRCDProto
send_cmd(NULL, "f %s %s", server, set ? "+" : "-");
}
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- send_cmd(NULL, "BD - G %s %s %s", ak->user, ak->host, Config.s_OperServ);
+ send_cmd(NULL, "BD - G %s %s %s", x->GetUser().c_str(), x->GetHost().c_str(), Config.s_OperServ);
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -153,12 +153,12 @@ class UnrealIRCdProto : public IRCDProto
ModeManager::ProcessModes();
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
+ time_t timeleft = x->Expires - time(NULL);
if (timeleft > 172800) timeleft = 172800;
- send_cmd(NULL, "BD + G %s %s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL) + timeleft), static_cast<long>(ak->expires), ak->reason);
+ send_cmd(NULL, "BD + G %s %s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL) + timeleft), static_cast<long>(x->Expires), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -228,31 +228,21 @@ class UnrealIRCdProto : public IRCDProto
}
/* unsqline
- ** parv[0] = sender
- ** parv[1] = nickmask
*/
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(NULL, "d %s", user.c_str());
+ send_cmd(NULL, "d %s", x->Mask.c_str());
}
/* SQLINE */
/*
- ** parv[0] = sender
- ** parv[1] = nickmask
- ** parv[2] = reason
- **
** - Unreal will translate this to TKL for us
**
*/
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(NULL, "c %s :%s", mask.c_str(), reason.c_str());
+ send_cmd(NULL, "c %s :%s", x->Mask.c_str(), x->Reason.c_str());
}
/*
@@ -309,33 +299,33 @@ class UnrealIRCdProto : public IRCDProto
/*
* SVSNLINE - :realname mask
*/
- void SendSGLineDel(SXLine *sx)
+ void SendSGLineDel(XLine *x)
{
- send_cmd(NULL, "BR - :%s", sx->mask);
+ send_cmd(NULL, "BR - :%s", x->Mask.c_str());
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(NULL, "BD - Z * %s %s", sx->mask, Config.s_OperServ);
+ send_cmd(NULL, "BD - Z * %s %s", x->Mask.c_str(), Config.s_OperServ);
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(NULL, "BD + Z * %s %s %ld %ld :%s", sx->mask, sx->by, static_cast<long>(time(NULL) + 172800), static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(NULL, "BD + Z * %s %s %ld %ld :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL) + 172800), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SGLINE */
/*
* SVSNLINE + reason_where_is_space :realname mask with spaces
*/
- void SendSGLine(SXLine *sx)
+ void SendSGLine(XLine *x)
{
char edited_reason[BUFSIZE];
- strlcpy(edited_reason, sx->reason, BUFSIZE);
+ strlcpy(edited_reason, x->Reason.c_str(), BUFSIZE);
strnrepl(edited_reason, BUFSIZE, " ", "_");
- send_cmd(NULL, "BR + %s :%s", edited_reason, sx->mask);
+ send_cmd(NULL, "BR + %s :%s", edited_reason, x->Mask.c_str());
}
/* SVSMODE -b */
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index d214eb6bd..8ee823e33 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -603,6 +603,12 @@ bool ChannelInfo::CheckKick(User *user)
* as this will likely lead to kick/rejoin floods. ~ Viper */
if (user->server->IsULined())
return false;
+
+ if (!do_kick && user->IsProtected())
+ return false;
+
+ if (ircd->chansqline && SQLineManager::Check(this->c))
+ do_kick = true;
if (!is_oper(user) && (this->HasFlag(CI_SUSPENDED) || this->HasFlag(CI_FORBIDDEN)))
{
@@ -612,9 +618,6 @@ bool ChannelInfo::CheckKick(User *user)
do_kick = true;
}
- if (!do_kick && user->IsProtected())
- return false;
-
if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1)
return false;
diff --git a/src/send.c b/src/send.c
index e16856598..4209e2a1b 100644
--- a/src/send.c
+++ b/src/send.c
@@ -32,6 +32,15 @@ void send_cmd(const char *source, const char *fmt, ...)
vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ if (!UplinkSock)
+ {
+ if (source)
+ Alog(LOG_DEBUG) << "Attemtped to send \"" << source << " " << buf << "\" with UplinkSock NULL";
+ else
+ Alog(LOG_DEBUG) << "Attemtped to send \"" << buf << "\" with UplinkSock NULL";
+ return;
+ }
+
if (source)
{
UplinkSock->Write(":%s %s", source, buf);
@@ -59,6 +68,15 @@ void send_cmd(const std::string &source, const char *fmt, ...)
vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ if (!UplinkSock)
+ {
+ if (!source.empty())
+ Alog(LOG_DEBUG) << "Attemtped to send \"" << source << " " << buf << "\" with UplinkSock NULL";
+ else
+ Alog(LOG_DEBUG) << "Attemtped to send " << buf << "\" with UplinkSock NULL";
+ return;
+ }
+
if (!source.empty())
{
UplinkSock->Write(":%s %s", source.c_str(), buf);
diff --git a/src/sessions.c b/src/sessions.c
index cef071443..e0c20e185 100644
--- a/src/sessions.c
+++ b/src/sessions.c
@@ -140,10 +140,10 @@ int add_session(const char *nick, const char *host, char *hostip)
if (Config.MaxSessionKill && session->hits >= Config.MaxSessionKill) {
char akillmask[BUFSIZE];
snprintf(akillmask, sizeof(akillmask), "*@%s", host);
- add_akill(NULL, akillmask, Config.s_OperServ,
- time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
- ircdproto->SendGlobops(OperServ,
- "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
+ XLine *x = new XLine(ci::string("*@") + host, Config.s_OperServ, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
+ if (x)
+ x->By = Config.s_OperServ;
+ ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
}
return 0;
} else {
diff --git a/src/slist.c b/src/slist.c
deleted file mode 100644
index d01d58ecd..000000000
--- a/src/slist.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Services list handler implementation.
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-
-#include "services.h"
-#include "slist.h"
-
-static SListOpts slist_defopts = { 0, NULL, NULL, NULL };
-
-/*************************************************************************/
-
-/**
- * Adds a pointer to the list. Returns the index of the new item.
- * Returns -2 if there are too many items in the list, -3 if the
- * item already exists when the flags of the list contain SLISTF_NODUP.
- * @param slist Slist Struct
- * @param item Item being added
- * @return int
- */
-int slist_add(SList * slist, void *item)
-{
- if (slist->limit != 0 && slist->count >= slist->limit)
- return -2;
- if (slist->opts && (slist->opts->flags & SLISTF_NODUP)
- && slist_indexof(slist, item) != -1)
- return -3;
- if (slist->capacity == slist->count)
- slist_setcapacity(slist, slist->capacity + 1);
-
- if (slist->opts && (slist->opts->flags & SLISTF_SORT)
- && slist->opts->compareitem) {
- int i;
-
- for (i = 0; i < slist->count; i++) {
- if (slist->opts->compareitem(slist, item, slist->list[i]) <= 0) {
- memmove(&slist->list[i + 1], &slist->list[i],
- sizeof(void *) * (slist->count - i));
- slist->list[i] = item;
- break;
- }
- }
-
- if (i == slist->count)
- slist->list[slist->count] = item;
- } else {
- slist->list[slist->count] = item;
- }
-
- return slist->count++;
-}
-
-/*************************************************************************/
-
-/**
- * Clears the list. If free is 1, the freeitem function will be called
- * for each item before clearing.
- * @param slist Slist Struct
- * @param mustfree What is being freed
- * @return void
- */
-void slist_clear(SList * slist, int mustfree)
-{
- if (mustfree && slist->opts && slist->opts->freeitem && slist->count) {
- int i;
-
- for (i = 0; i < slist->count; i++)
- if (slist->list[i])
- slist->opts->freeitem(slist, slist->list[i]);
- }
-
- if (slist->list) {
- free(slist->list);
- slist->list = NULL;
- }
- slist->capacity = 0;
- slist->count = 0;
-}
-
-/*************************************************************************/
-
-/**
- * Deletes an item from the list, by index. Returns 1 if successful,
- * 0 otherwise.
- * @param slist Slist Struct
- * @param index beign deleted
- * @return int Returns 1 if successful, 0 otherwise.
- */
-int slist_delete(SList * slist, int index)
-{
- /* Range check */
- if (index >= slist->count)
- return 0;
-
- if (slist->list[index] && slist->opts && slist->opts->freeitem)
- slist->opts->freeitem(slist, slist->list[index]);
-
- slist->list[index] = NULL;
- slist->count--;
-
- if (index < slist->count)
- memmove(&slist->list[index], &slist->list[index + 1],
- sizeof(void *) * (slist->count - index));
-
- slist_setcapacity(slist, slist->capacity - 1);
-
- return 1;
-}
-
-/*************************************************************************/
-
-/**
- * Deletes a range of entries. Return -1 if the permission was denied,
- * 0 if no records were deleted, or the number of records deleted
- * @param slist Slist Struct
- * @param range Range to delete
- * @param cb Call back function
- * @param ... various args
- * @return int
- */
-int slist_delete_range(SList * slist, const char *crange, slist_delcheckcb_t cb, ...)
-{
- int count = 0, i, n1, n2;
- va_list args, preserve;
- char *range = const_cast<char *>(crange); // XXX: unsafe cast
-
- va_start(args, cb);
-
- for (;;) {
- n1 = n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
-
- if (*range == '-') {
- range++;
- range += strcspn(range, "0123456789,");
- if (isdigit(*range)) {
- n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
- }
- }
-
- for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
-
- if (!slist->list[i - 1])
- continue;
-
- /* copy this off the stack for safety's sake --nenolod */
- VA_COPY(preserve, args);
-
- if (cb && !cb(slist, slist->list[i - 1], preserve)) {
- va_end(preserve);
- return -1;
- }
-
- /* if it's to be freed, lets free it */
- if (slist->opts && slist->opts->freeitem)
- slist->opts->freeitem(slist, slist->list[i - 1]);
- slist->list[i - 1] = NULL;
-
- /* and release the copied list */
- va_end(preserve);
-
- count++;
- }
-
- range += strcspn(range, ",");
- if (*range)
- range++;
- else
- break;
- }
-
- /* We only really delete the items from the list after having processed
- * everything because it would change the position of the items in the
- * list otherwise.
- */
- slist_pack(slist);
-
- va_end(args);
- return count;
-}
-
-/*************************************************************************/
-
-/**
- * Enumerates all entries of the list. If range is not NULL, will only
- * enumerate entries that are in the range. Returns the total number
- * of entries enumerated.
- * @param slit Slist struct
- * @param range Range to enum
- * @param cb Call back function
- * @param ... various args
- * @return int
- */
-int slist_enum(SList * slist, const char *crange, slist_enumcb_t cb, ...)
-{
- int count = 0, i, res;
- va_list args, preserve;
- char *range = const_cast<char *>(crange); // XXX: unsafe cast
-
- va_start(args, cb);
-
- if (!range) {
- for (i = 0; i < slist->count; i++) {
- if (!slist->list[i]) {
- Alog() << "SList: warning: NULL pointer in the list (?)";
- continue;
- }
-
- /* copy off stack for safety */
- VA_COPY(preserve, args);
-
- res = cb(slist, i + 1, slist->list[i], preserve);
- if (res < 0) {
- va_end(preserve);
- break;
- }
-
- /* and release our copy */
- va_end(preserve);
-
- count += res;
- }
- } else {
- int n1, n2;
-
- for (;;) {
- res = 0;
- n1 = n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
- if (*range == '-') {
- range++;
- range += strcspn(range, "0123456789,");
- if (isdigit(*range)) {
- n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
- }
- }
- for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
- if (!slist->list[i - 1]) {
- Alog() << "SList: warning: NULL pointer in the list (?)";
- continue;
- }
-
- /* copy off stack for safety */
- VA_COPY(preserve, args);
-
- res = cb(slist, i, slist->list[i - 1], preserve);
- if (res < 0) {
- va_end(preserve);
- break;
- }
- count += res;
-
- /* and release our copy */
- va_end(preserve);
- }
- if (res < -1)
- break;
- range += strcspn(range, ",");
- if (*range)
- range++;
- else
- break;
- }
- }
-
- va_end(args);
-
- return count;
-}
-
-/*************************************************************************/
-
-/**
- * Determines whether the list is full.
- * @param slist Slist Struct
- * @return int
- */
-int slist_full(SList * slist)
-{
- if (slist->limit != 0 && slist->count >= slist->limit)
- return 1;
- else
- return 0;
-}
-
-/*************************************************************************/
-
-/**
- * Initialization of the list.
- * @param slist Slist Struct
- * @return int
- */
-void slist_init(SList * slist)
-{
- memset(slist, 0, sizeof(SList));
- slist->limit = SLIST_DEFAULT_LIMIT;
- slist->opts = &slist_defopts;
-}
-
-/*************************************************************************/
-
-/**
- * Returns the index of an item in the list, -1 if inexistant.
- * @param slist Slist Struct
- * @param item Item index
- * @return int
- */
-int slist_indexof(SList * slist, void *item)
-{
- int16 i;
- void *entry;
-
- if (slist->count == 0)
- return -1;
-
- for (i = 0, entry = slist->list[0]; i < slist->count;
- i++, entry = slist->list[i]) {
- if ((slist->opts
- && slist->opts->isequal) ? (slist->opts->isequal(slist, item,
- entry))
- : (item == entry))
- return i;
- }
-
- return -1;
-}
-
-/*************************************************************************/
-
-/**
- * Removes all NULL pointers from the list.
- * @param slist Slist Struct
- * @return void
- */
-void slist_pack(SList * slist)
-{
- int i;
-
- for (i = slist->count - 1; i >= 0; i--)
- if (!slist->list[i])
- slist_delete(slist, i);
-}
-
-/*************************************************************************/
-
-/**
- * Removes a specific item from the list. Returns the old index of the
- * deleted item, or -1 if the item was not found.
- * @param slist Slist Struct
- * @param item to remove
- * @return int
- */
-int slist_remove(SList * slist, void *item)
-{
- int index = slist_indexof(slist, item);
- if (index == -1)
- return -1;
- slist_delete(slist, index);
- return index;
-}
-
-/*************************************************************************/
-
-/**
- * Sets the maximum capacity of the list
- * @param slist Slist Struct
- * @param capacity How large the list can be
- * @return int
- */
-int slist_setcapacity(SList * slist, int16 capacity)
-{
- if (slist->capacity == capacity)
- return 1;
- slist->capacity = capacity;
- if (slist->capacity)
- slist->list =
- static_cast<void **>(srealloc(slist->list, sizeof(void *) * slist->capacity));
- else {
- free(slist->list);
- slist->list = NULL;
- }
- if (slist->capacity < slist->count)
- slist->count = slist->capacity;
- return 1;
-}
diff --git a/src/tools/db-convert.c b/src/tools/db-convert.c
index 0f8a35ebc..4e3d01034 100644
--- a/src/tools/db-convert.c
+++ b/src/tools/db-convert.c
@@ -969,7 +969,7 @@ int main(int argc, char *argv[])
fs << "OS AKILL " << user << " " << host << " " << by << " " << seton << " " << expires << " :" << reason << std::endl;
free(user); free(host); free(by); free(reason);
}
- /* SGLINES */
+ /* SNLINES */
read_int16(&capacity, f);
for (i = 0; i < capacity; i++)
{
@@ -978,7 +978,7 @@ int main(int argc, char *argv[])
SAFE(read_string(&reason, f));
SAFE(read_int32(&seton, f));
SAFE(read_int32(&expires, f));
- fs << "OS SGLINE " << mask << " " << by << " " << seton << " " << expires << " :" << reason << std::endl;
+ fs << "OS SNLINE " << mask << " " << by << " " << seton << " " << expires << " :" << reason << std::endl;
free(mask); free(by); free(reason);
}
/* SQLINES */
diff --git a/src/users.c b/src/users.c
index 4311f8d33..946f70f6a 100644
--- a/src/users.c
+++ b/src/users.c
@@ -849,20 +849,11 @@ User *do_nick(const char *source, const char *nick, const char *username, const
if (MOD_RESULT == EVENT_STOP)
return finduser(nick);
- check_akill(nick, username, host, vhost, ipbuf);
-
- if (ircd->sgline)
- check_sgline(nick, realname);
-
- if (ircd->sqline)
- check_sqline(nick, 0);
-
- if (ircd->szline && ircd->nickip)
- check_szline(nick, ipbuf);
-
if (Config.LimitSessions && !serv->IsULined())
add_session(nick, host, ipbuf);
+ XLineManager::CheckAll(user);
+
/* User is no longer connected, return */
if (!finduser(nick))
return NULL;
@@ -937,7 +928,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
if (ircd->sqline)
{
- if (!is_oper(user) && check_sqline(user->nick.c_str(), 1))
+ if (!is_oper(user) && SQLine->Check(user))
return NULL;
}
}