diff options
Diffstat (limited to 'src')
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> ¶ms) 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> ¶ms) { - 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> ¶ms, 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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, ¶m)) + 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> ¶ms) - { - 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> ¶ms) - { - 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> ¶ms) - { - 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> ¶ms) - { - 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> ¶ms) - { - 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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> ¶ms) { - 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; } } |