summaryrefslogtreecommitdiff
path: root/modules/commands
diff options
context:
space:
mode:
Diffstat (limited to 'modules/commands')
-rw-r--r--modules/commands/bs_assign.cpp256
-rw-r--r--modules/commands/bs_badwords.cpp469
-rw-r--r--modules/commands/bs_bot.cpp385
-rw-r--r--modules/commands/bs_botlist.cpp82
-rw-r--r--modules/commands/bs_control.cpp146
-rw-r--r--modules/commands/bs_info.cpp134
-rw-r--r--modules/commands/bs_kick.cpp1474
-rw-r--r--modules/commands/bs_set.cpp225
-rw-r--r--modules/commands/cs_access.cpp904
-rw-r--r--modules/commands/cs_akick.cpp572
-rw-r--r--modules/commands/cs_ban.cpp248
-rw-r--r--modules/commands/cs_clone.cpp261
-rw-r--r--modules/commands/cs_drop.cpp95
-rw-r--r--modules/commands/cs_enforce.cpp292
-rw-r--r--modules/commands/cs_entrymsg.cpp289
-rw-r--r--modules/commands/cs_flags.cpp504
-rw-r--r--modules/commands/cs_getkey.cpp73
-rw-r--r--modules/commands/cs_info.cpp98
-rw-r--r--modules/commands/cs_invite.cpp111
-rw-r--r--modules/commands/cs_kick.cpp147
-rw-r--r--modules/commands/cs_list.cpp266
-rw-r--r--modules/commands/cs_log.cpp399
-rw-r--r--modules/commands/cs_mode.cpp1012
-rw-r--r--modules/commands/cs_register.cpp124
-rw-r--r--modules/commands/cs_seen.cpp459
-rw-r--r--modules/commands/cs_set.cpp1356
-rw-r--r--modules/commands/cs_set_misc.cpp218
-rw-r--r--modules/commands/cs_status.cpp125
-rw-r--r--modules/commands/cs_suspend.cpp285
-rw-r--r--modules/commands/cs_sync.cpp66
-rw-r--r--modules/commands/cs_topic.cpp270
-rw-r--r--modules/commands/cs_unban.cpp126
-rw-r--r--modules/commands/cs_updown.cpp243
-rw-r--r--modules/commands/cs_xop.cpp635
-rw-r--r--modules/commands/gl_global.cpp60
-rw-r--r--modules/commands/greet.cpp216
-rw-r--r--modules/commands/help.cpp205
-rw-r--r--modules/commands/hs_del.cpp113
-rw-r--r--modules/commands/hs_group.cpp117
-rw-r--r--modules/commands/hs_list.cpp160
-rw-r--r--modules/commands/hs_off.cpp69
-rw-r--r--modules/commands/hs_on.cpp75
-rw-r--r--modules/commands/hs_request.cpp394
-rw-r--r--modules/commands/hs_set.cpp229
-rw-r--r--modules/commands/ms_cancel.cpp81
-rw-r--r--modules/commands/ms_check.cpp87
-rw-r--r--modules/commands/ms_del.cpp151
-rw-r--r--modules/commands/ms_ignore.cpp132
-rw-r--r--modules/commands/ms_info.cpp231
-rw-r--r--modules/commands/ms_list.cpp164
-rw-r--r--modules/commands/ms_read.cpp216
-rw-r--r--modules/commands/ms_rsend.cpp104
-rw-r--r--modules/commands/ms_send.cpp88
-rw-r--r--modules/commands/ms_sendall.cpp70
-rw-r--r--modules/commands/ms_set.cpp315
-rw-r--r--modules/commands/ms_staff.cpp67
-rw-r--r--modules/commands/ns_access.cpp206
-rw-r--r--modules/commands/ns_ajoin.cpp405
-rw-r--r--modules/commands/ns_alist.cpp149
-rw-r--r--modules/commands/ns_cert.cpp407
-rw-r--r--modules/commands/ns_drop.cpp86
-rw-r--r--modules/commands/ns_getemail.cpp74
-rw-r--r--modules/commands/ns_getpass.cpp74
-rw-r--r--modules/commands/ns_group.cpp384
-rw-r--r--modules/commands/ns_identify.cpp128
-rw-r--r--modules/commands/ns_info.cpp282
-rw-r--r--modules/commands/ns_list.cpp301
-rw-r--r--modules/commands/ns_logout.cpp91
-rw-r--r--modules/commands/ns_recover.cpp295
-rw-r--r--modules/commands/ns_register.cpp429
-rw-r--r--modules/commands/ns_resetpass.cpp143
-rw-r--r--modules/commands/ns_set.cpp1341
-rw-r--r--modules/commands/ns_set_misc.cpp233
-rw-r--r--modules/commands/ns_status.cpp87
-rw-r--r--modules/commands/ns_suspend.cpp288
-rw-r--r--modules/commands/ns_update.cpp62
-rw-r--r--modules/commands/os_akill.cpp483
-rw-r--r--modules/commands/os_chankill.cpp119
-rw-r--r--modules/commands/os_config.cpp150
-rw-r--r--modules/commands/os_defcon.cpp603
-rw-r--r--modules/commands/os_dns.cpp949
-rw-r--r--modules/commands/os_forbid.cpp559
-rw-r--r--modules/commands/os_ignore.cpp416
-rw-r--r--modules/commands/os_info.cpp290
-rw-r--r--modules/commands/os_jupe.cpp80
-rw-r--r--modules/commands/os_kick.cpp84
-rw-r--r--modules/commands/os_kill.cpp67
-rw-r--r--modules/commands/os_list.cpp246
-rw-r--r--modules/commands/os_login.cpp132
-rw-r--r--modules/commands/os_logsearch.cpp156
-rw-r--r--modules/commands/os_mode.cpp192
-rw-r--r--modules/commands/os_modinfo.cpp214
-rw-r--r--modules/commands/os_module.cpp188
-rw-r--r--modules/commands/os_news.cpp464
-rw-r--r--modules/commands/os_noop.cpp100
-rw-r--r--modules/commands/os_oline.cpp78
-rw-r--r--modules/commands/os_oper.cpp293
-rw-r--r--modules/commands/os_reload.cpp67
-rw-r--r--modules/commands/os_session.cpp737
-rw-r--r--modules/commands/os_set.cpp267
-rw-r--r--modules/commands/os_shutdown.cpp108
-rw-r--r--modules/commands/os_stats.cpp276
-rw-r--r--modules/commands/os_svs.cpp178
-rw-r--r--modules/commands/os_sxline.cpp732
-rw-r--r--modules/commands/os_update.cpp52
105 files changed, 0 insertions, 29438 deletions
diff --git a/modules/commands/bs_assign.cpp b/modules/commands/bs_assign.cpp
deleted file mode 100644
index 0d1989fe9..000000000
--- a/modules/commands/bs_assign.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandBSAssign : public Command
-{
- public:
- CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2)
- {
- this->SetDesc(_("Assigns a bot to a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &nick = params[1];
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot assignment is temporarily disabled."));
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- BotInfo *bi = BotInfo::Find(nick, true);
- if (!bi)
- {
- source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
- return;
- }
-
- AccessGroup access = source.AccessFor(ci);
- if (ci->HasExt("BS_NOBOT") || (!access.HasPriv("ASSIGN") && !source.HasPriv("botserv/administration")))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (bi->oper_only && !source.HasPriv("botserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (ci->bi == bi)
- {
- source.Reply(_("Bot \002%s\002 is already assigned to channel \002%s\002."), ci->bi->nick.c_str(), chan.c_str());
- return;
- }
-
- bool override = !access.HasPriv("ASSIGN");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << bi->nick;
-
- bi->Assign(source.GetUser(), ci);
- source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Assigns the specified bot to a channel. You\n"
- "can then configure the bot for the channel so it fits\n"
- "your needs."));
- return true;
- }
-};
-
-class CommandBSUnassign : public Command
-{
- public:
- CommandBSUnassign(Module *creator) : Command(creator, "botserv/unassign", 1, 1)
- {
- this->SetDesc(_("Unassigns a bot from a channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot assignment is temporarily disabled."));
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- AccessGroup access = source.AccessFor(ci);
- if (!source.HasPriv("botserv/administration") && !access.HasPriv("ASSIGN"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!ci->bi)
- {
- source.Reply(BOT_NOT_ASSIGNED);
- return;
- }
-
- if (ci->HasExt("PERSIST") && !ModeManager::FindChannelModeByName("PERM"))
- {
- source.Reply(_("You cannot unassign bots while persist is set on the channel."));
- return;
- }
-
- bool override = !access.HasPriv("ASSIGN");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << ci->bi->nick;
-
- ci->bi->UnAssign(source.GetUser(), ci);
- source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Unassigns a bot from a channel. When you use this command,\n"
- "the bot won't join the channel anymore. However, bot\n"
- "configuration for the channel is kept, so you will always\n"
- "be able to reassign a bot later without having to reconfigure\n"
- "it entirely."));
- return true;
- }
-};
-
-class CommandBSSetNoBot : public Command
-{
- public:
- CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("Prevent a bot from being assigned to a channel"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &value = params[1];
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot modification is temporarily disabled."));
- return;
- }
-
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (value.equals_ci("ON"))
- {
- Log(LOG_ADMIN, source, this, ci) << "to enable nobot";
-
- ci->Extend<bool>("BS_NOBOT");
- if (ci->bi)
- ci->bi->UnAssign(source.GetUser(), ci);
- source.Reply(_("No-bot mode is now \002on\002 on channel %s."), ci->name.c_str());
- }
- else if (value.equals_ci("OFF"))
- {
- Log(LOG_ADMIN, source, this, ci) << "to disable nobot";
-
- ci->Shrink<bool>("BS_NOBOT");
- source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "This option makes a channel unassignable. If a bot\n"
- "is already assigned to the channel, it is unassigned\n"
- "automatically when you enable it."));
- return true;
- }
-};
-
-class BSAssign : public Module
-{
- ExtensibleItem<bool> nobot;
-
- CommandBSAssign commandbsassign;
- CommandBSUnassign commandbsunassign;
- CommandBSSetNoBot commandbssetnobot;
-
- public:
- BSAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- nobot(this, "BS_NOBOT"),
- commandbsassign(this), commandbsunassign(this), commandbssetnobot(this)
- {
- }
-
- void OnInvite(User *source, Channel *c, User *targ) anope_override
- {
- BotInfo *bi;
- if (Anope::ReadOnly || !c->ci || targ->server != Me || !(bi = dynamic_cast<BotInfo *>(targ)))
- return;
-
- AccessGroup access = c->ci->AccessFor(source);
- if (nobot.HasExt(c->ci) || (!access.HasPriv("ASSIGN") && !source->HasPriv("botserv/administration")))
- {
- targ->SendMessage(bi, ACCESS_DENIED);
- return;
- }
-
- if (bi->oper_only && !source->HasPriv("botserv/administration"))
- {
- targ->SendMessage(bi, ACCESS_DENIED);
- return;
- }
-
- if (c->ci->bi == bi)
- {
- targ->SendMessage(bi, _("Bot \002%s\002 is already assigned to channel \002%s\002."), c->ci->bi->nick.c_str(), c->name.c_str());
- return;
- }
-
- bi->Assign(source, c->ci);
- targ->SendMessage(bi, _("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), c->name.c_str());
- }
-
- void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
- {
- if (nobot.HasExt(ci))
- info.AddOption(_("No bot"));
- }
-};
-
-MODULE_INIT(BSAssign)
diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp
deleted file mode 100644
index 57731b168..000000000
--- a/modules/commands/bs_badwords.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 "modules/bs_badwords.h"
-
-struct BadWordImpl : BadWord, Serializable
-{
- BadWordImpl() : Serializable("BadWord") { }
- ~BadWordImpl();
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["ci"] << this->chan;
- data["word"] << this->word;
- data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
-};
-
-struct BadWordsImpl : BadWords
-{
- Serialize::Reference<ChannelInfo> ci;
- typedef std::vector<BadWordImpl *> list;
- Serialize::Checker<list> badwords;
-
- BadWordsImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), badwords("BadWord") { }
-
- ~BadWordsImpl();
-
- BadWord* AddBadWord(const Anope::string &word, BadWordType type) anope_override
- {
- BadWordImpl *bw = new BadWordImpl();
- bw->chan = ci->name;
- bw->word = word;
- bw->type = type;
-
- this->badwords->push_back(bw);
-
- FOREACH_MOD(OnBadWordAdd, (ci, bw));
-
- return bw;
- }
-
- BadWord* GetBadWord(unsigned index) const anope_override
- {
- if (this->badwords->empty() || index >= this->badwords->size())
- return NULL;
-
- BadWordImpl *bw = (*this->badwords)[index];
- bw->QueueUpdate();
- return bw;
- }
-
- unsigned GetBadWordCount() const anope_override
- {
- return this->badwords->size();
- }
-
- void EraseBadWord(unsigned index) anope_override
- {
- if (this->badwords->empty() || index >= this->badwords->size())
- return;
-
- FOREACH_MOD(OnBadWordDel, (ci, (*this->badwords)[index]));
-
- delete this->badwords->at(index);
- }
-
- void ClearBadWords() anope_override
- {
- while (!this->badwords->empty())
- delete this->badwords->back();
- }
-
- void Check() anope_override
- {
- if (this->badwords->empty())
- ci->Shrink<BadWords>("badwords");
- }
-};
-
-BadWordsImpl::~BadWordsImpl()
-{
- for (list::iterator it = badwords->begin(); it != badwords->end();)
- {
- BadWord *bw = *it;
- ++it;
- delete bw;
- }
-}
-
-BadWordImpl::~BadWordImpl()
-{
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci)
- {
- BadWordsImpl *badwords = ci->GetExt<BadWordsImpl>("badwords");
- if (badwords)
- {
- BadWordsImpl::list::iterator it = std::find(badwords->badwords->begin(), badwords->badwords->end(), this);
- if (it != badwords->badwords->end())
- badwords->badwords->erase(it);
- }
- }
-}
-
-Serializable* BadWordImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci, sword;
-
- data["ci"] >> sci;
- data["word"] >> sword;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- unsigned int n;
- data["type"] >> n;
-
- BadWordImpl *bw;
- if (obj)
- bw = anope_dynamic_static_cast<BadWordImpl *>(obj);
- else
- bw = new BadWordImpl();
- bw->chan = sci;
- bw->word = sword;
- bw->type = static_cast<BadWordType>(n);
-
- BadWordsImpl *bws = ci->Require<BadWordsImpl>("badwords");
- if (!obj)
- bws->badwords->push_back(bw);
-
- return bw;
-}
-
-class BadwordsDelCallback : public NumberList
-{
- CommandSource &source;
- ChannelInfo *ci;
- BadWords *bw;
- Command *c;
- unsigned deleted;
- bool override;
- public:
- BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), deleted(0), override(false)
- {
- if (!source.AccessFor(ci).HasPriv("BADWORDS") && source.HasPriv("botserv/administration"))
- this->override = true;
- bw = ci->Require<BadWords>("badwords");
- }
-
- ~BadwordsDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from %s bad words list."), ci->name.c_str());
- else
- source.Reply(_("Deleted %d entries from %s bad words list."), deleted, ci->name.c_str());
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!bw || !Number || Number > bw->GetBadWordCount())
- return;
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "DEL " << bw->GetBadWord(Number - 1)->word;
- ++deleted;
- bw->EraseBadWord(Number - 1);
- }
-};
-
-class CommandBSBadwords : public Command
-{
- private:
- void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
- {
- bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "LIST";
- ListFormatter list(source.GetAccount());
- BadWords *bw = ci->GetExt<BadWords>("badwords");
-
- list.AddColumn(_("Number")).AddColumn(_("Word")).AddColumn(_("Type"));
-
- if (!bw || !bw->GetBadWordCount())
- {
- source.Reply(_("%s bad words list is empty."), ci->name.c_str());
- return;
- }
- else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class BadwordsListCallback : public NumberList
- {
- ListFormatter &list;
- BadWords *bw;
- public:
- BadwordsListCallback(ListFormatter &_list, BadWords *_bw, const Anope::string &numlist) : NumberList(numlist, false), list(_list), bw(_bw)
- {
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > bw->GetBadWordCount())
- return;
-
- const BadWord *b = bw->GetBadWord(Number - 1);
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(Number);
- entry["Word"] = b->word;
- entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : ""));
- this->list.AddEntry(entry);
- }
- }
- nl_list(list, bw, word);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = bw->GetBadWordCount(); i < end; ++i)
- {
- const BadWord *b = bw->GetBadWord(i);
-
- if (!word.empty() && !Anope::Match(b->word, word))
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Word"] = b->word;
- entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : ""));
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Bad words list for %s:"), ci->name.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of bad words list."));
- }
- }
-
- void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
- {
- size_t pos = word.rfind(' ');
- BadWordType bwtype = BW_ANY;
- Anope::string realword = word;
- BadWords *badwords = ci->Require<BadWords>("badwords");
-
- if (pos != Anope::string::npos)
- {
- Anope::string opt = word.substr(pos + 1);
- if (!opt.empty())
- {
- if (opt.equals_ci("SINGLE"))
- bwtype = BW_SINGLE;
- else if (opt.equals_ci("START"))
- bwtype = BW_START;
- else if (opt.equals_ci("END"))
- bwtype = BW_END;
- }
- realword = word.substr(0, pos);
- }
-
- unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax");
- if (badwords->GetBadWordCount() >= badwordsmax)
- {
- source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax);
- return;
- }
-
- bool casesensitive = Config->GetModule(this->module)->Get<bool>("casesensitive");
-
- for (unsigned i = 0, end = badwords->GetBadWordCount(); i < end; ++i)
- {
- const BadWord *bw = badwords->GetBadWord(i);
-
- if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && realword.equals_ci(bw->word)))
- {
- source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str());
- return;
- }
- }
-
- bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ADD " << realword;
- badwords->AddBadWord(realword, bwtype);
-
- source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
- }
-
- void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
- {
- BadWords *badwords = ci->GetExt<BadWords>("badwords");
-
- if (!badwords || !badwords->GetBadWordCount())
- {
- source.Reply(_("%s bad words list is empty."), ci->name.c_str());
- return;
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- BadwordsDelCallback list(source, ci, this, word);
- list.Process();
- }
- else
- {
- unsigned i, end;
- const BadWord *badword;
-
- for (i = 0, end = badwords->GetBadWordCount(); i < end; ++i)
- {
- badword = badwords->GetBadWord(i);
-
- if (word.equals_ci(badword->word))
- break;
- }
-
- if (i == end)
- {
- source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str());
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "DEL " << badword->word;
-
- source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
-
- badwords->EraseBadWord(i);
- }
-
- badwords->Check();
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("BADWORDS");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "CLEAR";
-
- BadWords *badwords = ci->GetExt<BadWords>("badwords");
- if (badwords)
- badwords->ClearBadWords();
- source.Reply(_("Bad words list is now empty."));
- }
-
- public:
- CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3)
- {
- this->SetDesc(_("Maintains the bad words list"));
- this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]"));
- this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[1];
- const Anope::string &word = params.size() > 2 ? params[2] : "";
- bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR");
-
- if (!need_args && word.empty())
- {
- this->OnSyntaxError(source, cmd);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("BADWORDS") && (!need_args || !source.HasPriv("botserv/administration")))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bad words list modification is temporarily disabled."));
- return;
- }
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, ci, word);
- else if (cmd.equals_ci("DEL"))
- return this->DoDelete(source, ci, word);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, ci, word);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Maintains the \002bad words list\002 for a channel. The bad\n"
- "words list determines which words are to be kicked\n"
- "when the bad words kicker is enabled. For more information,\n"
- "type \002%s%s HELP KICK %s\002.\n"
- " \n"
- "The \002ADD\002 command adds the given word to the\n"
- "bad words list. If SINGLE is specified, a kick will be\n"
- "done only if a user says the entire word. If START is\n"
- "specified, a kick will be done if a user says a word\n"
- "that starts with \037word\037. If END is specified, a kick\n"
- "will be done if a user says a word that ends with\n"
- "\037word\037. If you don't specify anything, a kick will\n"
- "be issued every time \037word\037 is said by a user.\n"
- " \n"), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
- source.Reply(_("The \002DEL\002 command removes the given word from the\n"
- "bad words list. If a list of entry numbers is given, those\n"
- "entries are deleted. (See the example for LIST below.)\n"
- " \n"
- "The \002LIST\002 command displays the bad words list. If\n"
- "a wildcard mask is given, only those entries matching the\n"
- "mask are displayed. If a list of entry numbers is given,\n"
- "only those entries are shown; for example:\n"
- " \002#channel LIST 2-5,7-9\002\n"
- " Lists bad words entries numbered 2 through 5 and\n"
- " 7 through 9.\n"
- " \n"
- "The \002CLEAR\002 command clears all entries from the\n"
- "bad words list."));
- return true;
- }
-};
-
-class BSBadwords : public Module
-{
- CommandBSBadwords commandbsbadwords;
- ExtensibleItem<BadWordsImpl> badwords;
- Serialize::Type badword_type;
-
- public:
- BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsbadwords(this), badwords(this, "badwords"), badword_type("BadWord", BadWordImpl::Unserialize)
- {
- }
-};
-
-MODULE_INIT(BSBadwords)
diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp
deleted file mode 100644
index 6a152937a..000000000
--- a/modules/commands/bs_bot.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandBSBot : public Command
-{
- private:
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &nick = params[1];
- const Anope::string &user = params[2];
- const Anope::string &host = params[3];
- const Anope::string &real = params[4];
-
- if (BotInfo::Find(nick, true))
- {
- source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
- return;
- }
-
- Configuration::Block *networkinfo = Config->GetBlock("networkinfo");
-
- if (nick.length() > networkinfo->Get<unsigned>("nicklen"))
- {
- source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen"));
- return;
- }
-
- if (user.length() > networkinfo->Get<unsigned>("userlen"))
- {
- source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen"));
- return;
- }
-
- if (host.length() > networkinfo->Get<unsigned>("hostlen"))
- {
- source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsNickValid(nick))
- {
- source.Reply(_("Bot nicks may only contain valid nick characters."));
- return;
- }
-
- if (!IRCD->IsIdentValid(user))
- {
- source.Reply(_("Bot idents may only contain valid ident characters."));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(_("Bot hosts may only contain valid host characters."));
- return;
- }
-
- /* We check whether the nick is registered, and inform the user
- * if so. You need to drop the nick manually before you can use
- * it as a bot nick from now on -GD
- */
- if (NickAlias::Find(nick))
- {
- source.Reply(NICK_ALREADY_REGISTERED, nick.c_str());
- return;
- }
-
- User *u = User::Find(nick, true);
- if (u)
- {
- source.Reply(_("Nick \002%s\002 is currently in use."), u->nick.c_str());
- return;
- }
-
- BotInfo *bi = new BotInfo(nick, user, host, real);
-
- Log(LOG_ADMIN, source, this) << "ADD " << bi->GetMask() << " " << bi->realname;
-
- source.Reply(_("%s!%s@%s (%s) added to the bot list."), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
-
- FOREACH_MOD(OnBotCreate, (bi));
- return;
- }
-
- void DoChange(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &oldnick = params[1];
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
- const Anope::string &user = params.size() > 3 ? params[3] : "";
- const Anope::string &host = params.size() > 4 ? params[4] : "";
- const Anope::string &real = params.size() > 5 ? params[5] : "";
-
- if (oldnick.empty() || nick.empty())
- {
- this->OnSyntaxError(source, "CHANGE");
- return;
- }
-
- BotInfo *bi = BotInfo::Find(oldnick, true);
- if (!bi)
- {
- source.Reply(BOT_DOES_NOT_EXIST, oldnick.c_str());
- return;
- }
-
- if (bi->conf)
- {
- source.Reply(_("Bot %s is not changeable."), bi->nick.c_str());
- return;
- }
-
- Configuration::Block *networkinfo = Config->GetBlock("networkinfo");
-
- if (nick.length() > networkinfo->Get<unsigned>("nicklen"))
- {
- source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen"));
- return;
- }
-
- if (user.length() > networkinfo->Get<unsigned>("userlen"))
- {
- source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen"));
- return;
- }
-
- if (host.length() > networkinfo->Get<unsigned>("hostlen"))
- {
- source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen"));
- return;
- }
-
- /* Checks whether there *are* changes.
- * Case sensitive because we may want to change just the case.
- * And we must finally check that the nick is not already
- * taken by another bot.
- */
- if (nick.equals_cs(bi->nick) && (!user.empty() ? user.equals_cs(bi->GetIdent()) : 1) && (!host.empty() ? host.equals_cs(bi->host) : 1) && (!real.empty() ? real.equals_cs(bi->realname) : 1))
- {
- source.Reply(_("The old information is the same as the new information specified."));
- return;
- }
-
- if (!IRCD->IsNickValid(nick))
- {
- source.Reply(_("Bot nicks may only contain valid nick characters."));
- return;
- }
-
- if (!user.empty() && !IRCD->IsIdentValid(user))
- {
- source.Reply(_("Bot idents may only contain valid ident characters."));
- return;
- }
-
- if (!host.empty() && !IRCD->IsHostValid(host))
- {
- source.Reply(_("Bot hosts may only contain valid host characters."));
- return;
- }
-
- if (!nick.equals_ci(bi->nick))
- {
- if (BotInfo::Find(nick, true))
- {
- source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
- return;
- }
-
- if (User::Find(nick, true))
- {
- source.Reply(_("Nick \002%s\002 is currently in use."), nick.c_str());
- return;
- }
- }
-
- if (!nick.equals_ci(bi->nick))
- {
- /* We check whether the nick is registered, and inform the user
- * if so. You need to drop the nick manually before you can use
- * it as a bot nick from now on -GD
- */
- if (NickAlias::Find(nick))
- {
- source.Reply(NICK_ALREADY_REGISTERED, nick.c_str());
- return;
- }
-
- /* The new nick is really different, so we remove the Q line for the old nick. */
- XLine x_del(bi->nick);
- IRCD->SendSQLineDel(&x_del);
-
- /* Add a Q line for the new nick */
- XLine x(nick, "Reserved for services");
- IRCD->SendSQLine(NULL, &x);
- }
-
- if (!user.empty())
- {
- IRCD->SendQuit(bi, "Quit: Be right back");
- bi->introduced = false;
- }
- else
- IRCD->SendNickChange(bi, nick);
-
- if (!nick.equals_cs(bi->nick))
- bi->SetNewNick(nick);
-
- if (!user.empty() && !user.equals_cs(bi->GetIdent()))
- bi->SetIdent(user);
- if (!host.empty() && !host.equals_cs(bi->host))
- bi->host = host;
- if (!real.empty() && !real.equals_cs(bi->realname))
- bi->realname = real;
-
- if (!user.empty())
- bi->OnKill();
-
- source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
- Log(LOG_ADMIN, source, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
-
- FOREACH_MOD(OnBotChange, (bi));
- return;
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &nick = params[1];
-
- if (nick.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- BotInfo *bi = BotInfo::Find(nick, true);
- if (!bi)
- {
- source.Reply(BOT_DOES_NOT_EXIST, nick.c_str());
- return;
- }
-
- if (bi->conf)
- {
- source.Reply(_("Bot %s is not deletable."), bi->nick.c_str());
- return;
- }
-
- FOREACH_MOD(OnBotDelete, (bi));
-
- Log(LOG_ADMIN, source, this) << "DEL " << bi->nick;
-
- source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str());
- delete bi;
- return;
- }
- public:
- CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6)
- {
- this->SetDesc(_("Maintains network bot list"));
- this->SetSyntax(_("\002ADD \037nick\037 \037user\037 \037host\037 \037real\037\002"));
- this->SetSyntax(_("\002CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002"));
- this->SetSyntax(_("\002DEL \037nick\037\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot modification is temporarily disabled."));
- return;
- }
-
- if (cmd.equals_ci("ADD"))
- {
- // ADD nick user host real - 5
- if (!source.HasCommand("botserv/bot/add"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params.size() < 5)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- std::vector<Anope::string> tempparams = params;
- // ADD takes less params than CHANGE, so we need to take 6 if given and append it with a space to 5.
- if (tempparams.size() >= 6)
- tempparams[4] = tempparams[4] + " " + tempparams[5];
-
- return this->DoAdd(source, tempparams);
- }
- else if (cmd.equals_ci("CHANGE"))
- {
- // CHANGE oldn newn user host real - 6
- // but only oldn and newn are required
- if (!source.HasCommand("botserv/bot/change"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params.size() < 3)
- {
- this->OnSyntaxError(source, "CHANGE");
- return;
- }
-
- return this->DoChange(source, params);
- }
- else if (cmd.equals_ci("DEL"))
- {
- // DEL nick
- if (!source.HasCommand("botserv/bot/del"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params.size() < 1)
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- return this->DoDel(source, params);
- }
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to create, modify, and delete\n"
- "bots that users will be able to use on their own\n"
- "channels.\n"
- " \n"
- "\002BOT ADD\002 adds a bot with the given nickname, username,\n"
- "hostname and realname. Since no integrity checks are done\n"
- "for these settings, be really careful.\n"
- " \n"
- "\002BOT CHANGE\002 allows you to change the nickname, username, hostname\n"
- "or realname of a bot without deleting it (and\n"
- "all the data associated with it).\n"
- " \n"
- "\002BOT DEL\002 removes the given bot from the bot list.\n"
- " \n"
- "\002Note\002: You cannot create a bot with a nick that is\n"
- "currently registered. If an unregistered user is currently\n"
- "using the nick, they will be killed."));
- return true;
- }
-};
-
-class BSBot : public Module
-{
- CommandBSBot commandbsbot;
-
- public:
- BSBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsbot(this)
- {
-
- }
-};
-
-MODULE_INIT(BSBot)
diff --git a/modules/commands/bs_botlist.cpp b/modules/commands/bs_botlist.cpp
deleted file mode 100644
index 089c2894d..000000000
--- a/modules/commands/bs_botlist.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandBSBotList : public Command
-{
- public:
- CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0)
- {
- this->SetDesc(_("Lists available bots"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned count = 0;
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Nick")).AddColumn(_("Mask"));
-
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- {
- BotInfo *bi = it->second;
-
- if (source.HasPriv("botserv/administration") || !bi->oper_only)
- {
- ++count;
- ListFormatter::ListEntry entry;
- entry["Nick"] = (bi->oper_only ? "* " : "") + bi->nick;
- entry["Mask"] = bi->GetIdent() + "@" + bi->host;
- list.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- if (!count)
- source.Reply(_("There are no bots available at this time.\n"
- "Ask a Services Operator to create one!"));
- else
- {
- source.Reply(_("Bot list:"));
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("%d bots available."), count);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all available bots on this network.\n"
- "Bots prefixed by a * are reserved for IRC Operators."));
- return true;
- }
-};
-
-class BSBotList : public Module
-{
- CommandBSBotList commandbsbotlist;
-
- public:
- BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsbotlist(this)
- {
-
- }
-};
-
-MODULE_INIT(BSBotList)
diff --git a/modules/commands/bs_control.cpp b/modules/commands/bs_control.cpp
deleted file mode 100644
index bdacf8dd1..000000000
--- a/modules/commands/bs_control.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandBSSay : public Command
-{
- public:
- CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2)
- {
- this->SetDesc(_("Makes the bot say the specified text on the specified channel"));
- this->SetSyntax(_("\037channel\037 \037text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &text = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("SAY") && !source.HasPriv("botserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!ci->bi)
- {
- source.Reply(BOT_NOT_ASSIGNED);
- return;
- }
-
- if (!ci->c || !ci->c->FindUser(ci->bi))
- {
- source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str());
- return;
- }
-
- if (text[0] == '\001')
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- IRCD->SendPrivmsg(*ci->bi, ci->name, "%s", text.c_str());
- ci->bi->lastmsg = Anope::CurTime;
-
- bool override = !source.AccessFor(ci).HasPriv("SAY");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << text;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the bot say the specified text on the specified channel."));
- return true;
- }
-};
-
-class CommandBSAct : public Command
-{
- public:
- CommandBSAct(Module *creator) : Command(creator, "botserv/act", 2, 2)
- {
- this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
- this->SetSyntax(_("\037channel\037 \037text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string message = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("SAY") && !source.HasPriv("botserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!ci->bi)
- {
- source.Reply(BOT_NOT_ASSIGNED);
- return;
- }
-
- if (!ci->c || !ci->c->FindUser(ci->bi))
- {
- source.Reply(BOT_NOT_ON_CHANNEL, ci->name.c_str());
- return;
- }
-
- message = message.replace_all_cs("\1", "");
- if (message.empty())
- return;
-
- IRCD->SendAction(*ci->bi, ci->name, "%s", message.c_str());
- ci->bi->lastmsg = Anope::CurTime;
-
- bool override = !source.AccessFor(ci).HasPriv("SAY");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to say: " << message;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the bot do the equivalent of a \"/me\" command\n"
- "on the specified channel using the specified text."));
- return true;
- }
-};
-
-class BSControl : public Module
-{
- CommandBSSay commandbssay;
- CommandBSAct commandbsact;
-
- public:
- BSControl(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbssay(this), commandbsact(this)
- {
-
- }
-};
-
-MODULE_INIT(BSControl)
diff --git a/modules/commands/bs_info.cpp b/modules/commands/bs_info.cpp
deleted file mode 100644
index 76dcfa4f4..000000000
--- a/modules/commands/bs_info.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandBSInfo : public Command
-{
- private:
- void send_bot_channels(std::vector<Anope::string> &buffers, const BotInfo *bi)
- {
- Anope::string buf;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (ci->bi == bi)
- {
- buf += " " + ci->name + " ";
- if (buf.length() > 300)
- {
- buffers.push_back(buf);
- buf.clear();
- }
- }
- }
- if (!buf.empty())
- buffers.push_back(buf);
- }
-
- public:
- CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
- {
- this->SetSyntax(_("{\037channel\037 | \037nickname\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &query = params[0];
-
- BotInfo *bi = BotInfo::Find(query, true);
- ChannelInfo *ci = ChannelInfo::Find(query);
- InfoFormatter info(source.nc);
-
- if (bi)
- {
- source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
- info[_("Mask")] = bi->GetIdent() + "@" + bi->host;
- info[_("Real name")] = bi->realname;
- info[_("Created")] = Anope::strftime(bi->created, source.GetAccount());
- info[_("Options")] = bi->oper_only ? _("Private") : _("None");
- info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)";
-
- FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- if (source.HasPriv("botserv/administration"))
- {
- std::vector<Anope::string> buf;
- this->send_bot_channels(buf, bi);
- for (unsigned i = 0; i < buf.size(); ++i)
- source.Reply(buf[i]);
- }
-
- }
- else if (ci)
- {
- if (!source.AccessFor(ci).HasPriv("INFO") && !source.HasPriv("botserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- source.Reply(CHAN_INFO_HEADER, ci->name.c_str());
- info[_("Bot nick")] = ci->bi ? ci->bi->nick : _("not assigned yet");
-
- Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
- Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
-
- FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- else
- source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to see %s information about a channel or a bot.\n"
- "If the parameter is a channel, then you'll get information\n"
- "such as enabled kickers. If the parameter is a nick,\n"
- "you'll get information about a bot, such as creation\n"
- "time or number of channels it is on."), source.service->nick.c_str());
- return true;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Allows you to see %s information about a channel or a bot")), source.service->nick.c_str());
- }
-};
-
-class BSInfo : public Module
-{
- CommandBSInfo commandbsinfo;
-
- public:
- BSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsinfo(this)
- {
-
- }
-};
-
-MODULE_INIT(BSInfo)
diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp
deleted file mode 100644
index 1897bc5e6..000000000
--- a/modules/commands/bs_kick.cpp
+++ /dev/null
@@ -1,1474 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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 "modules/bs_kick.h"
-#include "modules/bs_badwords.h"
-
-static Module *me;
-
-struct KickerDataImpl : KickerData
-{
- KickerDataImpl(Extensible *obj)
- {
- amsgs = badwords = bolds = caps = colors = flood = italics = repeat = reverses = underlines = false;
- for (int16_t i = 0; i < TTB_SIZE; ++i)
- ttb[i] = 0;
- capsmin = capspercent = 0;
- floodlines = floodsecs = 0;
- repeattimes = 0;
-
- dontkickops = dontkickvoices = false;
- }
-
- void Check(ChannelInfo *ci) anope_override
- {
- if (amsgs || badwords || bolds || caps || colors || flood || italics || repeat || reverses || underlines)
- return;
-
- ci->Shrink<KickerData>("kickerdata");
- }
-
- struct ExtensibleItem : ::ExtensibleItem<KickerDataImpl>
- {
- ExtensibleItem(Module *m, const Anope::string &ename) : ::ExtensibleItem<KickerDataImpl>(m, ename) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- const ChannelInfo *ci = anope_dynamic_static_cast<const ChannelInfo *>(e);
- KickerData *kd = this->Get(ci);
- if (kd == NULL)
- return;
-
- data["kickerdata:amsgs"] << kd->amsgs;
- data["kickerdata:badwords"] << kd->badwords;
- data["kickerdata:bolds"] << kd->bolds;
- data["kickerdata:caps"] << kd->caps;
- data["kickerdata:colors"] << kd->colors;
- data["kickerdata:flood"] << kd->flood;
- data["kickerdata:italics"] << kd->italics;
- data["kickerdata:repeat"] << kd->repeat;
- data["kickerdata:reverses"] << kd->reverses;
- data["kickerdata:underlines"] << kd->underlines;
-
- data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin;
- data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent;
- data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines;
- data.SetType("floodsecs", Serialize::Data::DT_INT); data["floodsecs"] << kd->floodsecs;
- data.SetType("repeattimes", Serialize::Data::DT_INT); data["repeattimes"] << kd->repeattimes;
- for (int16_t i = 0; i < TTB_SIZE; ++i)
- data["ttb"] << kd->ttb[i] << " ";
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(e);
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- data["kickerdata:amsgs"] >> kd->amsgs;
- data["kickerdata:badwords"] >> kd->badwords;
- data["kickerdata:bolds"] >> kd->bolds;
- data["kickerdata:caps"] >> kd->caps;
- data["kickerdata:colors"] >> kd->colors;
- data["kickerdata:flood"] >> kd->flood;
- data["kickerdata:italics"] >> kd->italics;
- data["kickerdata:repeat"] >> kd->repeat;
- data["kickerdata:reverses"] >> kd->reverses;
- data["kickerdata:underlines"] >> kd->underlines;
-
- data["capsmin"] >> kd->capsmin;
- data["capspercent"] >> kd->capspercent;
- data["floodlines"] >> kd->floodlines;
- data["floodsecs"] >> kd->floodsecs;
- data["repeattimes"] >> kd->repeattimes;
-
- Anope::string ttb, tok;
- data["ttb"] >> ttb;
- spacesepstream sep(ttb);
- for (int i = 0; sep.GetToken(tok) && i < TTB_SIZE; ++i)
- try
- {
- kd->ttb[i] = convertTo<int16_t>(tok);
- }
- catch (const ConvertException &) { }
-
- kd->Check(ci);
- }
- };
-};
-
-class CommandBSKick : public Command
-{
- public:
- CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 0)
- {
- this->SetDesc(_("Configures kickers"));
- this->SetSyntax(_("\037option\037 \037channel\037 {\037ON|OFF\037} [\037settings\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Configures bot kickers. \037option\037 can be one of:"));
-
- Anope::string this_name = source.command;
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> command("Command", info.name);
- if (command)
- {
- source.command = c_name;
- command->OnServHelp(source);
- }
- }
- }
-
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option.\n"
- " \n"
- "Note: access to this command is controlled by the\n"
- "level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
-
- return true;
- }
-};
-
-class CommandBSKickBase : public Command
-{
- public:
- CommandBSKickBase(Module *creator, const Anope::string &cname, int minarg, int maxarg) : Command(creator, cname, minarg, maxarg)
- {
- }
-
- virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override = 0;
-
- virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override = 0;
-
- protected:
- bool CheckArguments(CommandSource &source, const std::vector<Anope::string> &params, ChannelInfo* &ci)
- {
- const Anope::string &chan = params[0];
- const Anope::string &option = params[1];
-
- ci = ChannelInfo::Find(chan);
-
- if (Anope::ReadOnly)
- source.Reply(_("Sorry, kicker configuration is temporarily disabled."));
- else if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (option.empty())
- this->OnSyntaxError(source, "");
- else if (!option.equals_ci("ON") && !option.equals_ci("OFF"))
- this->OnSyntaxError(source, "");
- else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("botserv/administration"))
- source.Reply(ACCESS_DENIED);
- else if (!ci->bi)
- source.Reply(BOT_NOT_ASSIGNED);
- else
- return true;
-
- return false;
- }
-
- void Process(CommandSource &source, ChannelInfo *ci, const Anope::string &param, const Anope::string &ttb, size_t ttb_idx, const Anope::string &optname, KickerData *kd, bool &val)
- {
- if (param.equals_ci("ON"))
- {
- if (!ttb.empty())
- {
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
-
- kd->ttb[ttb_idx] = i;
- }
- else
- kd->ttb[ttb_idx] = 0;
-
- val = true;
- if (kd->ttb[ttb_idx])
- source.Reply(_("Bot will now kick for \002%s\002, and will place a ban\n"
- "after %d kicks for the same user."), optname.c_str(), kd->ttb[ttb_idx]);
- else
- source.Reply(_("Bot will now kick for \002%s\002."), optname.c_str());
-
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable the " << optname << " kicker";
- }
- else if (param.equals_ci("OFF"))
- {
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable the " << optname << " kicker";
-
- val = false;
- source.Reply(_("Bot won't kick for \002%s\002 anymore."), optname.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-};
-
-class CommandBSKickAMSG : public CommandBSKickBase
-{
- public:
- CommandBSKickAMSG(Module *creator) : CommandBSKickBase(creator, "botserv/kick/amsg", 2, 3)
- {
- this->SetDesc(_("Configures AMSG kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_AMSGS, "AMSG", kd, kd->amsgs);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- BotInfo *bi = Config->GetClient("BotServ");
- source.Reply(_("Sets the AMSG kicker on or off. When enabled, the bot will\n"
- "kick users who send the same message to multiple channels\n"
- "where %s bots are.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before they get banned. Don't give ttb to disable\n"
- "the ban system once activated."), bi ? bi->nick.c_str() : "BotServ");
- return true;
- }
-};
-
-class CommandBSKickBadwords : public CommandBSKickBase
-{
- public:
- CommandBSKickBadwords(Module *creator) : CommandBSKickBase(creator, "botserv/kick/badwords", 2, 3)
- {
- this->SetDesc(_("Configures badwords kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_BADWORDS, "badwords", kd, kd->badwords);
- kd->Check(ci);
- }
-
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the bad words kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who say certain words\n"
- "on the channels.\n"
- "You can define bad words for your channel using the\n"
- "\002BADWORDS\002 command. Type \002%s%s HELP BADWORDS\002 for\n"
- "more information.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandBSKickBolds : public CommandBSKickBase
-{
- public:
- CommandBSKickBolds(Module *creator) : CommandBSKickBase(creator, "botserv/kick/bolds", 2, 3)
- {
- this->SetDesc(_("Configures bolds kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_BOLDS, "bolds", kd, kd->bolds);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the bolds kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use bolds.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickCaps : public CommandBSKickBase
-{
- public:
- CommandBSKickCaps(Module *creator) : CommandBSKickBase(creator, "botserv/kick/caps", 2, 5)
- {
- this->SetDesc(_("Configures caps kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (!CheckArguments(source, params, ci))
- return;
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- if (params[1].equals_ci("ON"))
- {
- const Anope::string &ttb = params.size() > 2 ? params[2] : "",
- &min = params.size() > 3 ? params[3] : "",
- &percent = params.size() > 4 ? params[4] : "";
-
- if (!ttb.empty())
- {
- try
- {
- kd->ttb[TTB_CAPS] = convertTo<int16_t>(ttb);
- if (kd->ttb[TTB_CAPS] < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- kd->ttb[TTB_CAPS] = 0;
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
- }
- else
- kd->ttb[TTB_CAPS] = 0;
-
- kd->capsmin = 10;
- try
- {
- kd->capsmin = convertTo<int16_t>(min);
- }
- catch (const ConvertException &) { }
- if (kd->capsmin < 1)
- kd->capsmin = 10;
-
- kd->capspercent = 25;
- try
- {
- kd->capspercent = convertTo<int16_t>(percent);
- }
- catch (const ConvertException &) { }
- if (kd->capspercent < 1 || kd->capspercent > 100)
- kd->capspercent = 25;
-
- kd->caps = true;
- if (kd->ttb[TTB_CAPS])
- source.Reply(_("Bot will now kick for \002caps\002 (they must constitute at least\n"
- "%d characters and %d%% of the entire message), and will\n"
- "place a ban after %d kicks for the same user."), kd->capsmin, kd->capspercent, kd->ttb[TTB_CAPS]);
- else
- source.Reply(_("Bot will now kick for \002caps\002 (they must constitute at least\n"
- "%d characters and %d%% of the entire message)."), kd->capsmin, kd->capspercent);
- }
- else
- {
- kd->caps = false;
- source.Reply(_("Bot won't kick for \002caps\002 anymore."));
- }
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the caps kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who are talking in\n"
- "CAPS.\n"
- "The bot kicks only if there are at least \002min\002 caps\n"
- "and they constitute at least \002percent\002%% of the total\n"
- "text line (if not given, it defaults to 10 characters\n"
- "and 25%%).\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickColors : public CommandBSKickBase
-{
- public:
- CommandBSKickColors(Module *creator) : CommandBSKickBase(creator, "botserv/kick/colors", 2, 3)
- {
- this->SetDesc(_("Configures color kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_COLORS, "colors", kd, kd->colors);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the colors kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use colors.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickFlood : public CommandBSKickBase
-{
- public:
- CommandBSKickFlood(Module *creator) : CommandBSKickBase(creator, "botserv/kick/flood", 2, 5)
- {
- this->SetDesc(_("Configures flood kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (!CheckArguments(source, params, ci))
- return;
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- if (params[1].equals_ci("ON"))
- {
- const Anope::string &ttb = params.size() > 2 ? params[2] : "",
- &lines = params.size() > 3 ? params[3] : "",
- &secs = params.size() > 4 ? params[4] : "";
-
- if (!ttb.empty())
- {
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
-
- kd->ttb[TTB_FLOOD] = i;
- }
- else
- kd->ttb[TTB_FLOOD] = 0;
-
- kd->floodlines = 6;
- try
- {
- kd->floodlines = convertTo<int16_t>(lines);
- }
- catch (const ConvertException &) { }
- if (kd->floodlines < 2)
- kd->floodlines = 6;
-
- kd->floodsecs = 10;
- try
- {
- kd->floodsecs = convertTo<int16_t>(secs);
- }
- catch (const ConvertException &) { }
- if (kd->floodsecs < 1)
- kd->floodsecs = 10;
- if (kd->floodsecs > Config->GetModule(me)->Get<time_t>("keepdata"))
- kd->floodsecs = Config->GetModule(me)->Get<time_t>("keepdata");
-
- kd->flood = true;
- if (kd->ttb[TTB_FLOOD])
- source.Reply(_("Bot will now kick for \002flood\002 (%d lines in %d seconds\n"
- "and will place a ban after %d kicks for the same user."), kd->floodlines, kd->floodsecs, kd->ttb[TTB_FLOOD]);
- else
- source.Reply(_("Bot will now kick for \002flood\002 (%d lines in %d seconds)."), kd->floodlines, kd->floodsecs);
- }
- else if (params[1].equals_ci("OFF"))
- {
- kd->flood = false;
- source.Reply(_("Bot won't kick for \002flood\002 anymore."));
- }
- else
- this->OnSyntaxError(source, params[1]);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the flood kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who are flooding\n"
- "the channel using at least \002ln\002 lines in \002secs\002 seconds\n"
- "(if not given, it defaults to 6 lines in 10 seconds).\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickItalics : public CommandBSKickBase
-{
- public:
- CommandBSKickItalics(Module *creator) : CommandBSKickBase(creator, "botserv/kick/italics", 2, 3)
- {
- this->SetDesc(_("Configures italics kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_ITALICS, "italics", kd, kd->italics);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the italics kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use italics.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickRepeat : public CommandBSKickBase
-{
- public:
- CommandBSKickRepeat(Module *creator) : CommandBSKickBase(creator, "botserv/kick/repeat", 2, 4)
- {
- this->SetDesc(_("Configures repeat kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (!CheckArguments(source, params, ci))
- return;
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
-
- if (params[1].equals_ci("ON"))
- {
- const Anope::string &ttb = params.size() > 2 ? params[2] : "",
- &times = params.size() > 3 ? params[3] : "";
-
- if (!ttb.empty())
- {
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
- return;
- }
-
- kd->ttb[TTB_REPEAT] = i;
- }
- else
- kd->ttb[TTB_REPEAT] = 0;
-
- kd->repeattimes = 3;
- try
- {
- kd->repeattimes = convertTo<int16_t>(times);
- }
- catch (const ConvertException &) { }
- if (kd->repeattimes < 1)
- kd->repeattimes = 3;
-
- kd->repeat = true;
- if (kd->ttb[TTB_REPEAT])
- {
- if (kd->repeattimes != 1)
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d times), and will place a ban after %d\n"
- "kicks for the same user."), kd->repeattimes, kd->ttb[TTB_REPEAT]);
- else
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d time), and will place a ban after %d\n"
- "kicks for the same user."), kd->repeattimes, kd->ttb[TTB_REPEAT]);
- }
- else
- {
- if (kd->repeattimes != 1)
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d times)."), kd->repeattimes);
- else
- source.Reply(_("Bot will now kick for \002repeats\002 (users that repeat the\n"
- "same message %d time)."), kd->repeattimes);
- }
- }
- else if (params[1].equals_ci("OFF"))
- {
- kd->repeat = false;
- source.Reply(_("Bot won't kick for \002repeats\002 anymore."));
- }
- else
- this->OnSyntaxError(source, params[1]);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the repeat kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who are repeating\n"
- "themselves \002num\002 times (if num is not given, it\n"
- "defaults to 3).\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickReverses : public CommandBSKickBase
-{
- public:
- CommandBSKickReverses(Module *creator) : CommandBSKickBase(creator, "botserv/kick/reverses", 2, 3)
- {
- this->SetDesc(_("Configures reverses kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_REVERSES, "reverses", kd, kd->reverses);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the reverses kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use reverses.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSKickUnderlines : public CommandBSKickBase
-{
- public:
- CommandBSKickUnderlines(Module *creator) : CommandBSKickBase(creator, "botserv/kick/underlines", 2, 3)
- {
- this->SetDesc(_("Configures underlines kicker"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci;
- if (CheckArguments(source, params, ci))
- {
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- Process(source, ci, params[1], params.size() > 2 ? params[2] : "", TTB_UNDERLINES, "underlines", kd, kd->underlines);
- kd->Check(ci);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the underlines kicker on or off. When enabled, this\n"
- "option tells the bot to kick users who use underlines.\n"
- " \n"
- "\037ttb\037 is the number of times a user can be kicked\n"
- "before it gets banned. Don't give ttb to disable\n"
- "the ban system once activated."));
- return true;
- }
-};
-
-class CommandBSSetDontKickOps : public Command
-{
- public:
- CommandBSSetDontKickOps(Module *creator, const Anope::string &sname = "botserv/set/dontkickops") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("To protect ops against bot kicks"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- AccessGroup access = source.AccessFor(ci);
- if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot option setting is temporarily disabled."));
- return;
- }
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- if (params[1].equals_ci("ON"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickops";
-
- kd->dontkickops = true;
- source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickops";
-
- kd->dontkickops = false;
- source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Enables or disables \002ops protection\002 mode on a channel.\n"
- "When it is enabled, ops won't be kicked by the bot\n"
- "even if they don't match the NOKICK level."));
- return true;
- }
-};
-
-class CommandBSSetDontKickVoices : public Command
-{
- public:
- CommandBSSetDontKickVoices(Module *creator, const Anope::string &sname = "botserv/set/dontkickvoices") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("To protect voices against bot kicks"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- AccessGroup access = source.AccessFor(ci);
- if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, bot option setting is temporarily disabled."));
- return;
- }
-
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- if (params[1].equals_ci("ON"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickvoices";
-
- kd->dontkickvoices = true;
- source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickvoices";
-
- kd->dontkickvoices = false;
- source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
-
- kd->Check(ci);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Enables or disables \002voices protection\002 mode on a channel.\n"
- "When it is enabled, voices won't be kicked by the bot\n"
- "even if they don't match the NOKICK level."));
- return true;
- }
-};
-
-struct BanData
-{
- struct Data
- {
- Anope::string mask;
- time_t last_use;
- int16_t ttb[TTB_SIZE];
-
- Data()
- {
- last_use = 0;
- for (int i = 0; i < TTB_SIZE; ++i)
- this->ttb[i] = 0;
- }
- };
-
- private:
- typedef Anope::map<Data> data_type;
- data_type data_map;
-
- public:
- BanData(Extensible *) { }
-
- Data &get(const Anope::string &key)
- {
- return this->data_map[key];
- }
-
- bool empty() const
- {
- return this->data_map.empty();
- }
-
- void purge()
- {
- time_t keepdata = Config->GetModule(me)->Get<time_t>("keepdata");
- for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
- {
- const Anope::string &user = it->first;
- Data &bd = it->second;
- ++it;
-
- if (Anope::CurTime - bd.last_use > keepdata)
- data_map.erase(user);
- }
- }
-};
-
-struct UserData
-{
- UserData(Extensible *)
- {
- last_use = last_start = Anope::CurTime;
- lines = times = 0;
- lastline.clear();
- }
-
- /* Data validity */
- time_t last_use;
-
- /* for flood kicker */
- int16_t lines;
- time_t last_start;
-
- /* for repeat kicker */
- Anope::string lasttarget;
- int16_t times;
-
- Anope::string lastline;
-};
-
-class BanDataPurger : public Timer
-{
- public:
- BanDataPurger(Module *o) : Timer(o, 300, Anope::CurTime, true) { }
-
- void Tick(time_t) anope_override
- {
- Log(LOG_DEBUG) << "bs_main: Running bandata purger";
-
- for (channel_map::iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
- {
- Channel *c = it->second;
-
- BanData *bd = c->GetExt<BanData>("bandata");
- if (bd != NULL)
- {
- bd->purge();
- if (bd->empty())
- c->Shrink<BanData>("bandata");
- }
- }
- }
-};
-
-class BSKick : public Module
-{
- ExtensibleItem<BanData> bandata;
- ExtensibleItem<UserData> userdata;
- KickerDataImpl::ExtensibleItem kickerdata;
-
- CommandBSKick commandbskick;
- CommandBSKickAMSG commandbskickamsg;
- CommandBSKickBadwords commandbskickbadwords;
- CommandBSKickBolds commandbskickbolds;
- CommandBSKickCaps commandbskickcaps;
- CommandBSKickColors commandbskickcolors;
- CommandBSKickFlood commandbskickflood;
- CommandBSKickItalics commandbskickitalics;
- CommandBSKickRepeat commandbskickrepeat;
- CommandBSKickReverses commandbskickreverse;
- CommandBSKickUnderlines commandbskickunderlines;
-
- CommandBSSetDontKickOps commandbssetdontkickops;
- CommandBSSetDontKickVoices commandbssetdontkickvoices;
-
- BanDataPurger purger;
-
- BanData::Data &GetBanData(User *u, Channel *c)
- {
- BanData *bd = bandata.Require(c);
- return bd->get(u->GetMask());
- }
-
- UserData *GetUserData(User *u, Channel *c)
- {
- ChanUserContainer *uc = c->FindUser(u);
- if (uc == NULL)
- return NULL;
-
- UserData *ud = userdata.Require(uc);
- return ud;
- }
-
- void check_ban(ChannelInfo *ci, User *u, KickerData *kd, int ttbtype)
- {
- /* Don't ban ulines or protected users */
- if (u->IsProtected())
- return;
-
- BanData::Data &bd = this->GetBanData(u, ci->c);
-
- ++bd.ttb[ttbtype];
- if (kd->ttb[ttbtype] && bd.ttb[ttbtype] >= kd->ttb[ttbtype])
- {
- /* Should not use == here because bd.ttb[ttbtype] could possibly be > kd->ttb[ttbtype]
- * if the TTB was changed after it was not set (0) before and the user had already been
- * kicked a few times. Bug #1056 - Adam */
-
- bd.ttb[ttbtype] = 0;
-
- Anope::string mask = ci->GetIdealBan(u);
-
- ci->c->SetMode(NULL, "BAN", mask);
- FOREACH_MOD(OnBotBan, (u, ci, mask));
- }
- }
-
- void bot_kick(ChannelInfo *ci, User *u, const char *message, ...)
- {
- va_list args;
- char buf[1024];
-
- if (!ci || !ci->bi || !ci->c || !u || u->IsProtected() || !ci->c->FindUser(u))
- return;
-
- Anope::string fmt = Language::Translate(u, message);
- va_start(args, message);
- vsnprintf(buf, sizeof(buf), fmt.c_str(), args);
- va_end(args);
-
- ci->c->Kick(ci->bi, u, "%s", buf);
- }
-
- public:
- BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- bandata(this, "bandata"),
- userdata(this, "userdata"),
- kickerdata(this, "kickerdata"),
-
- commandbskick(this),
- commandbskickamsg(this), commandbskickbadwords(this), commandbskickbolds(this), commandbskickcaps(this),
- commandbskickcolors(this), commandbskickflood(this), commandbskickitalics(this), commandbskickrepeat(this),
- commandbskickreverse(this), commandbskickunderlines(this),
-
- commandbssetdontkickops(this), commandbssetdontkickvoices(this),
-
- purger(this)
- {
- me = this;
-
- }
-
- void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
- {
- if (!ci)
- return;
-
- Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
- Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
- KickerData *kd = kickerdata.Get(ci);
-
- if (kd && kd->badwords)
- {
- if (kd->ttb[TTB_BADWORDS])
- info[_("Bad words kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), kd->ttb[TTB_BADWORDS]);
- else
- info[_("Bad words kicker")] = enabled;
- }
- else
- info[_("Bad words kicker")] = disabled;
-
- if (kd && kd->bolds)
- {
- if (kd->ttb[TTB_BOLDS])
- info[_("Bolds kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), kd->ttb[TTB_BOLDS]);
- else
- info[_("Bolds kicker")] = enabled;
- }
- else
- info[_("Bolds kicker")] = disabled;
-
- if (kd && kd->caps)
- {
- if (kd->ttb[TTB_CAPS])
- info[_("Caps kicker")] = Anope::printf(_("%s (%d kick(s) to ban; minimum %d/%d%%)"), enabled.c_str(), kd->ttb[TTB_CAPS], kd->capsmin, kd->capspercent);
- else
- info[_("Caps kicker")] = Anope::printf(_("%s (minimum %d/%d%%)"), enabled.c_str(), kd->capsmin, kd->capspercent);
- }
- else
- info[_("Caps kicker")] = disabled;
-
- if (kd && kd->colors)
- {
- if (kd->ttb[TTB_COLORS])
- info[_("Colors kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_COLORS]);
- else
- info[_("Colors kicker")] = enabled;
- }
- else
- info[_("Colors kicker")] = disabled;
-
- if (kd && kd->flood)
- {
- if (kd->ttb[TTB_FLOOD])
- info[_("Flood kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d lines in %ds)"), enabled.c_str(), kd->ttb[TTB_FLOOD], kd->floodlines, kd->floodsecs);
- else
- info[_("Flood kicker")] = Anope::printf(_("%s (%d lines in %ds)"), enabled.c_str(), kd->floodlines, kd->floodsecs);
- }
- else
- info[_("Flood kicker")] = disabled;
-
- if (kd && kd->repeat)
- {
- if (kd->ttb[TTB_REPEAT])
- info[_("Repeat kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d times)"), enabled.c_str(), kd->ttb[TTB_REPEAT], kd->repeattimes);
- else
- info[_("Repeat kicker")] = Anope::printf(_("%s (%d times)"), enabled.c_str(), kd->repeattimes);
- }
- else
- info[_("Repeat kicker")] = disabled;
-
- if (kd && kd->reverses)
- {
- if (kd->ttb[TTB_REVERSES])
- info[_("Reverses kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_REVERSES]);
- else
- info[_("Reverses kicker")] = enabled;
- }
- else
- info[_("Reverses kicker")] = disabled;
-
- if (kd && kd->underlines)
- {
- if (kd->ttb[TTB_UNDERLINES])
- info[_("Underlines kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_UNDERLINES]);
- else
- info[_("Underlines kicker")] = enabled;
- }
- else
- info[_("Underlines kicker")] = disabled;
-
- if (kd && kd->italics)
- {
- if (kd->ttb[TTB_ITALICS])
- info[_("Italics kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_ITALICS]);
- else
- info[_("Italics kicker")] = enabled;
- }
- else
- info[_("Italics kicker")] = disabled;
-
- if (kd && kd->amsgs)
- {
- if (kd->ttb[TTB_AMSGS])
- info[_("AMSG kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), kd->ttb[TTB_AMSGS]);
- else
- info[_("AMSG kicker")] = enabled;
- }
- else
- info[_("AMSG kicker")] = disabled;
-
- if (kd && kd->dontkickops)
- info.AddOption(_("Ops protection"));
- if (kd && kd->dontkickvoices)
- info.AddOption(_("Voices protection"));
- }
-
- void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
- {
- /* Now we can make kicker stuff. We try to order the checks
- * from the fastest one to the slowest one, since there's
- * no need to process other kickers if a user is kicked before
- * the last kicker check.
- *
- * But FIRST we check whether the user is protected in any
- * way.
- */
- ChannelInfo *ci = c->ci;
- if (ci == NULL)
- return;
- KickerData *kd = kickerdata.Get(ci);
- if (kd == NULL)
- return;
-
- if (ci->AccessFor(u).HasPriv("NOKICK"))
- return;
- else if (kd->dontkickops && (c->HasUserStatus(u, "HALFOP") || c->HasUserStatus(u, "OP") || c->HasUserStatus(u, "PROTECT") || c->HasUserStatus(u, "OWNER")))
- return;
- else if (kd->dontkickvoices && c->HasUserStatus(u, "VOICE"))
- return;
-
- Anope::string realbuf = msg;
-
- /* If it's a /me, cut the CTCP part because the ACTION will cause
- * problems with the caps or badwords kicker
- */
- if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
- {
- realbuf.erase(0, 8);
- realbuf.erase(realbuf.length() - 1);
- }
-
- if (realbuf.empty())
- return;
-
- /* Bolds kicker */
- if (kd->bolds && realbuf.find(2) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_BOLDS);
- bot_kick(ci, u, _("Don't use bolds on this channel!"));
- return;
- }
-
- /* Color kicker */
- if (kd->colors && realbuf.find(3) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_COLORS);
- bot_kick(ci, u, _("Don't use colors on this channel!"));
- return;
- }
-
- /* Reverses kicker */
- if (kd->reverses && realbuf.find(22) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_REVERSES);
- bot_kick(ci, u, _("Don't use reverses on this channel!"));
- return;
- }
-
- /* Italics kicker */
- if (kd->italics && realbuf.find(29) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_ITALICS);
- bot_kick(ci, u, _("Don't use italics on this channel!"));
- return;
- }
-
- /* Underlines kicker */
- if (kd->underlines && realbuf.find(31) != Anope::string::npos)
- {
- check_ban(ci, u, kd, TTB_UNDERLINES);
- bot_kick(ci, u, _("Don't use underlines on this channel!"));
- return;
- }
-
- /* Caps kicker */
- if (kd->caps && realbuf.length() >= static_cast<unsigned>(kd->capsmin))
- {
- int i = 0, l = 0;
-
- for (unsigned j = 0, end = realbuf.length(); j < end; ++j)
- {
- if (isupper(realbuf[j]))
- ++i;
- else if (islower(realbuf[j]))
- ++l;
- }
-
- /* i counts uppercase chars, l counts lowercase chars. Only
- * alphabetic chars (so islower || isupper) qualify for the
- * percentage of caps to kick for; the rest is ignored. -GD
- */
-
- if ((i || l) && i >= kd->capsmin && i * 100 / (i + l) >= kd->capspercent)
- {
- check_ban(ci, u, kd, TTB_CAPS);
- bot_kick(ci, u, _("Turn caps lock OFF!"));
- return;
- }
- }
-
- /* Bad words kicker */
- if (kd->badwords)
- {
- bool mustkick = false;
- BadWords *badwords = ci->GetExt<BadWords>("badwords");
-
- /* Normalize the buffer */
- Anope::string nbuf = Anope::NormalizeBuffer(realbuf);
- bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive");
-
- /* Normalize can return an empty string if this only conains control codes etc */
- if (badwords && !nbuf.empty())
- for (unsigned i = 0; i < badwords->GetBadWordCount(); ++i)
- {
- const BadWord *bw = badwords->GetBadWord(i);
-
- if (bw->word.empty())
- continue; // Shouldn't happen
-
- if (bw->word.length() > nbuf.length())
- continue; // This can't ever match
-
- if (bw->type == BW_ANY && ((casesensitive && nbuf.find(bw->word) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
- mustkick = true;
- else if (bw->type == BW_SINGLE)
- {
- size_t len = bw->word.length();
-
- if ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf)))
- mustkick = true;
- else if (nbuf.find(' ') == len && ((casesensitive && bw->word.equals_cs(nbuf.substr(0, len))) || (!casesensitive && bw->word.equals_ci(nbuf.substr(0, len)))))
- mustkick = true;
- else
- {
- if (len < nbuf.length() && nbuf.rfind(' ') == nbuf.length() - len - 1 && ((casesensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!casesensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
- mustkick = true;
- else
- {
- Anope::string wordbuf = " " + bw->word + " ";
-
- if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
- mustkick = true;
- }
- }
- }
- else if (bw->type == BW_START)
- {
- size_t len = bw->word.length();
-
- if ((casesensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(0, len).equals_ci(bw->word)))
- mustkick = true;
- else
- {
- Anope::string wordbuf = " " + bw->word;
-
- if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
- mustkick = true;
- }
- }
- else if (bw->type == BW_END)
- {
- size_t len = bw->word.length();
-
- if ((casesensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
- mustkick = true;
- else
- {
- Anope::string wordbuf = bw->word + " ";
-
- if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
- mustkick = true;
- }
- }
-
- if (mustkick)
- {
- check_ban(ci, u, kd, TTB_BADWORDS);
- if (Config->GetModule(me)->Get<bool>("gentlebadwordreason"))
- bot_kick(ci, u, _("Watch your language!"));
- else
- bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str());
-
- return;
- }
- } /* for */
- } /* if badwords */
-
- UserData *ud = GetUserData(u, c);
-
- if (ud)
- {
- /* Flood kicker */
- if (kd->flood)
- {
- if (Anope::CurTime - ud->last_start > kd->floodsecs)
- {
- ud->last_start = Anope::CurTime;
- ud->lines = 0;
- }
-
- ++ud->lines;
- if (ud->lines >= kd->floodlines)
- {
- check_ban(ci, u, kd, TTB_FLOOD);
- bot_kick(ci, u, _("Stop flooding!"));
- return;
- }
- }
-
- /* Repeat kicker */
- if (kd->repeat)
- {
- if (!ud->lastline.equals_ci(realbuf))
- ud->times = 0;
- else
- ++ud->times;
-
- if (ud->times >= kd->repeattimes)
- {
- check_ban(ci, u, kd, TTB_REPEAT);
- bot_kick(ci, u, _("Stop repeating yourself!"));
- return;
- }
- }
-
- if (ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
- {
- for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();)
- {
- Channel *chan = it->second->chan;
- ++it;
-
- if (chan->ci && kd->amsgs && !chan->ci->AccessFor(u).HasPriv("NOKICK"))
- {
- check_ban(chan->ci, u, kd, TTB_AMSGS);
- bot_kick(chan->ci, u, _("Don't use AMSGs!"));
- }
- }
- }
-
- ud->lasttarget = ci->name;
- ud->lastline = realbuf;
- }
- }
-};
-
-MODULE_INIT(BSKick)
diff --git a/modules/commands/bs_set.cpp b/modules/commands/bs_set.cpp
deleted file mode 100644
index 9e0bac56a..000000000
--- a/modules/commands/bs_set.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/* BotServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandBSSet : public Command
-{
- public:
- CommandBSSet(Module *creator) : Command(creator, "botserv/set", 3, 3)
- {
- this->SetDesc(_("Configures bot options"));
- this->SetSyntax(_("\037option\037 \037(channel | bot)\037 \037settings\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Configures bot options.\n"
- " \n"
- "Available options:"));
- bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
- hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
- Anope::string this_name = source.command;
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> command("Command", info.name);
- if (command)
- {
- // XXX dup
- if (hide_registered_commands && !command->AllowUnregistered() && !source.GetAccount())
- continue;
-
- if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- source.command = it->first;
- command->OnServHelp(source);
- }
- }
- }
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
- "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
-
- return true;
- }
-};
-
-class CommandBSSetBanExpire : public Command
-{
- public:
- class UnbanTimer : public Timer
- {
- Anope::string chname;
- Anope::string mask;
-
- public:
- UnbanTimer(Module *creator, const Anope::string &ch, const Anope::string &bmask, time_t t) : Timer(creator, t), chname(ch), mask(bmask) { }
-
- void Tick(time_t) anope_override
- {
- Channel *c = Channel::Find(chname);
- if (c)
- c->RemoveMode(NULL, "BAN", mask);
- }
- };
-
- CommandBSSetBanExpire(Module *creator, const Anope::string &sname = "botserv/set/banexpire") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("Configures the time bot bans expire in"));
- this->SetSyntax(_("\037channel\037 \037time\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &arg = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- AccessGroup access = source.AccessFor(ci);
- if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, changing bot options is temporarily disabled."));
- return;
- }
-
- time_t t = Anope::DoTime(arg);
- if (t == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
-
- /* cap at 1 day */
- if (t > 86400)
- {
- source.Reply(_("Ban expiry may not be longer than 1 day."));
- return;
- }
-
- ci->banexpire = t;
-
- bool override = !access.HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change banexpire to " << ci->banexpire;
-
- if (!ci->banexpire)
- source.Reply(_("Bot bans will no longer automatically expire."));
- else
- source.Reply(_("Bot bans will automatically expire after %s."), Anope::Duration(ci->banexpire, source.GetAccount()).c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Sets the time bot bans expire in. If enabled, any bans placed by\n"
- "bots, such as flood kicker, badwords kicker, etc. will automatically\n"
- "be removed after the given time. Set to 0 to disable bans from\n"
- "automatically expiring."));
- return true;
- }
-};
-
-class CommandBSSetPrivate : public Command
-{
- public:
- CommandBSSetPrivate(Module *creator, const Anope::string &sname = "botserv/set/private") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("Prevent a bot from being assigned by non IRC operators"));
- this->SetSyntax(_("\037botname\037 {\037ON|OFF\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- BotInfo *bi = BotInfo::Find(params[0], true);
- const Anope::string &value = params[1];
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (bi == NULL)
- {
- source.Reply(BOT_DOES_NOT_EXIST, params[0].c_str());
- return;
- }
-
- if (value.equals_ci("ON"))
- {
- bi->oper_only = true;
- source.Reply(_("Private mode of bot %s is now \002on\002."), bi->nick.c_str());
- }
- else if (value.equals_ci("OFF"))
- {
- bi->oper_only = false;
- source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "This option prevents a bot from being assigned to a\n"
- "channel by users that aren't IRC Operators."));
- return true;
- }
-};
-
-class BSSet : public Module
-{
- CommandBSSet commandbsset;
- CommandBSSetBanExpire commandbssetbanexpire;
- CommandBSSetPrivate commandbssetprivate;
-
- public:
- BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandbsset(this), commandbssetbanexpire(this),
- commandbssetprivate(this)
- {
- }
-
- void OnBotBan(User *u, ChannelInfo *ci, const Anope::string &mask) anope_override
- {
- if (!ci->banexpire)
- return;
-
- new CommandBSSetBanExpire::UnbanTimer(this, ci->name, mask, ci->banexpire);
- }
-};
-
-MODULE_INIT(BSSet)
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
deleted file mode 100644
index 6e9b79c6a..000000000
--- a/modules/commands/cs_access.cpp
+++ /dev/null
@@ -1,904 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-static std::map<Anope::string, int16_t, ci::less> defaultLevels;
-
-static inline void reset_levels(ChannelInfo *ci)
-{
- ci->ClearLevels();
- for (std::map<Anope::string, int16_t, ci::less>::iterator it = defaultLevels.begin(), it_end = defaultLevels.end(); it != it_end; ++it)
- ci->SetLevel(it->first, it->second);
-}
-
-class AccessChanAccess : public ChanAccess
-{
- public:
- int level;
-
- AccessChanAccess(AccessProvider *p) : ChanAccess(p), level(0)
- {
- }
-
- bool HasPriv(const Anope::string &name) const anope_override
- {
- return this->ci->GetLevel(name) != ACCESS_INVALID && this->level >= this->ci->GetLevel(name);
- }
-
- Anope::string AccessSerialize() const
- {
- return stringify(this->level);
- }
-
- void AccessUnserialize(const Anope::string &data) anope_override
- {
- try
- {
- this->level = convertTo<int>(data);
- }
- catch (const ConvertException &)
- {
- }
- }
-
- bool operator>(const ChanAccess &other) const anope_override
- {
- if (this->provider != other.provider)
- return ChanAccess::operator>(other);
- else
- return this->level > anope_dynamic_static_cast<const AccessChanAccess *>(&other)->level;
- }
-
- bool operator<(const ChanAccess &other) const anope_override
- {
- if (this->provider != other.provider)
- return ChanAccess::operator<(other);
- else
- return this->level < anope_dynamic_static_cast<const AccessChanAccess *>(&other)->level;
- }
-};
-
-class AccessAccessProvider : public AccessProvider
-{
- public:
- static AccessAccessProvider *me;
-
- AccessAccessProvider(Module *o) : AccessProvider(o, "access/access")
- {
- me = this;
- }
-
- ChanAccess *Create() anope_override
- {
- return new AccessChanAccess(this);
- }
-};
-AccessAccessProvider* AccessAccessProvider::me;
-
-class CommandCSAccess : public Command
-{
- void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params[2];
- Privilege *p = NULL;
- int level = ACCESS_INVALID;
-
- try
- {
- level = convertTo<int>(params[3]);
- }
- catch (const ConvertException &)
- {
- p = PrivilegeManager::FindPrivilege(params[3]);
- if (p != NULL && defaultLevels[p->name])
- level = defaultLevels[p->name];
- }
-
- if (!level)
- {
- source.Reply(_("Access level must be non-zero."));
- return;
- }
- else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
- {
- source.Reply(CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci);
- const ChanAccess *highest = u_access.Highest();
-
- AccessChanAccess tmp_access(AccessAccessProvider::me);
- tmp_access.ci = ci;
- tmp_access.level = level;
-
- bool override = false;
- const NickAlias *na = NULL;
-
- if ((!highest || *highest <= tmp_access) && !u_access.founder)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- if (IRCD->IsChannelValid(mask))
- {
- if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- ChannelInfo *targ_ci = ChannelInfo::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->name;
- }
- else
- {
- na = NickAlias::Find(mask);
-
- if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
- {
- source.Reply(_("Masks and unregistered users may not be on access lists."));
- return;
- }
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (na)
- mask = na->nick;
- }
-
- for (unsigned i = ci->GetAccessCount(); i > 0; --i)
- {
- const ChanAccess *access = ci->GetAccess(i - 1);
- if ((na && na->nc == access->GetAccount()) || mask.equals_ci(access->Mask()))
- {
- /* Don't allow lowering from a level >= u_level */
- if ((!highest || *access >= *highest) && !u_access.founder && !source.HasPriv("chanserv/access/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- delete ci->EraseAccess(i - 1);
- break;
- }
- }
-
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- if (access_max && ci->GetDeepAccessCount() >= access_max)
- {
- source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
- return;
- }
-
- ServiceReference<AccessProvider> provider("AccessProvider", "access/access");
- if (!provider)
- return;
- AccessChanAccess *access = anope_dynamic_static_cast<AccessChanAccess *>(provider->Create());
- access->SetMask(mask, ci);
- access->creator = source.GetNick();
- access->level = level;
- access->last_seen = 0;
- access->created = Anope::CurTime;
- ci->AddAccess(access);
-
- FOREACH_MOD(OnAccessAdd, (ci, source, access));
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << " with level " << level;
- if (p != NULL)
- source.Reply(_("\002%s\002 added to %s access list at privilege %s (level %d)"), access->Mask().c_str(), ci->name.c_str(), p->name.c_str(), level);
- else
- source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->Mask().c_str(), ci->name.c_str(), level);
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params[2];
-
- if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask))
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (!ci->GetAccessCount())
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class AccessDelCallback : public NumberList
- {
- CommandSource &source;
- ChannelInfo *ci;
- Command *c;
- unsigned deleted;
- Anope::string Nicks;
- bool denied;
- bool override;
- public:
- AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), deleted(0), denied(false), override(false)
- {
- if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && source.HasPriv("chanserv/access/modify"))
- this->override = true;
- }
-
- ~AccessDelCallback()
- {
- if (denied && !deleted)
- source.Reply(ACCESS_DENIED);
- else if (!deleted)
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << Nicks;
-
- if (deleted == 1)
- source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str());
- else
- source.Reply(_("Deleted %d entries from %s access list."), deleted, ci->name.c_str());
- }
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > ci->GetAccessCount())
- return;
-
- ChanAccess *access = ci->GetAccess(Number - 1);
-
- AccessGroup ag = source.AccessFor(ci);
- const ChanAccess *u_highest = ag.Highest();
-
- if ((!u_highest || *u_highest <= *access) && !ag.founder && !this->override && access->GetAccount() != source.nc)
- {
- denied = true;
- return;
- }
-
- ++deleted;
- if (!Nicks.empty())
- Nicks += ", " + access->Mask();
- else
- Nicks = access->Mask();
-
- ci->EraseAccess(Number - 1);
-
- FOREACH_MOD(OnAccessDel, (ci, source, access));
- delete access;
- }
- }
- delcallback(source, ci, this, mask);
- delcallback.Process();
- }
- else
- {
- AccessGroup u_access = source.AccessFor(ci);
- const ChanAccess *highest = u_access.Highest();
-
- for (unsigned i = ci->GetAccessCount(); i > 0; --i)
- {
- ChanAccess *access = ci->GetAccess(i - 1);
- if (mask.equals_ci(access->Mask()))
- {
- if (access->GetAccount() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else
- {
- source.Reply(_("\002%s\002 deleted from %s access list."), access->Mask().c_str(), ci->name.c_str());
- bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && access->GetAccount() != source.nc;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->Mask();
-
- ci->EraseAccess(i - 1);
- FOREACH_MOD(OnAccessDel, (ci, source, access));
- delete access;
- }
- return;
- }
- }
-
- source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
- }
-
- return;
- }
-
- void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
-
- if (!ci->GetAccessCount())
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class AccessListCallback : public NumberList
- {
- ListFormatter &list;
- ChannelInfo *ci;
-
- public:
- AccessListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAccessCount())
- return;
-
- const ChanAccess *access = ci->GetAccess(number - 1);
-
- Anope::string timebuf;
- if (ci->c)
- for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
- {
- ChannelInfo *p;
- if (access->Matches(cit->second->user, cit->second->user->Account(), p))
- timebuf = "Now";
- }
- if (timebuf.empty())
- {
- if (access->last_seen == 0)
- timebuf = "Never";
- else
- timebuf = Anope::strftime(access->last_seen, NULL, true);
- }
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- entry["Level"] = access->AccessSerialize();
- entry["Mask"] = access->Mask();
- entry["By"] = access->creator;
- entry["Last seen"] = timebuf;
- this->list.AddEntry(entry);
- }
- }
- nl_list(list, ci, nick);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
- {
- const ChanAccess *access = ci->GetAccess(i);
-
- if (!nick.empty() && !Anope::Match(access->Mask(), nick))
- continue;
-
- Anope::string timebuf;
- if (ci->c)
- for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
- {
- ChannelInfo *p;
- if (access->Matches(cit->second->user, cit->second->user->Account(), p))
- timebuf = "Now";
- }
- if (timebuf.empty())
- {
- if (access->last_seen == 0)
- timebuf = "Never";
- else
- timebuf = Anope::strftime(access->last_seen, NULL, true);
- }
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Level"] = access->AccessSerialize();
- entry["Mask"] = access->Mask();
- entry["By"] = access->creator;
- entry["Last seen"] = timebuf;
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Access list for %s:"), ci->name.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of access list"));
- }
-
- return;
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Level")).AddColumn(_("Mask"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Level")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Last seen"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- if (!source.IsFounder(ci) && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else
- {
- FOREACH_MOD(OnAccessClear, (ci, source));
-
- ci->ClearAccess();
-
- source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
-
- bool override = !source.IsFounder(ci);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
- }
-
- return;
- }
-
- public:
- CommandCSAccess(Module *creator) : Command(creator, "chanserv/access", 2, 4)
- {
- this->SetDesc(_("Modify the list of privileged users"));
- this->SetSyntax(_("\037channel\037 ADD \037mask\037 \037level\037"));
- this->SetSyntax(_("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[1];
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
- const Anope::string &s = params.size() > 3 ? params[3] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
- bool is_clear = cmd.equals_ci("CLEAR");
- bool is_del = cmd.equals_ci("DEL");
-
- bool has_access = false;
- if (source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (is_list && source.HasPriv("chanserv/access/list"))
- has_access = true;
- else if (is_list && source.AccessFor(ci).HasPriv("ACCESS_LIST"))
- has_access = true;
- else if (source.AccessFor(ci).HasPriv("ACCESS_CHANGE"))
- has_access = true;
- else if (is_del)
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na && na->nc == source.GetAccount())
- has_access = true;
- }
-
- /* If LIST, we don't *require* any parameters, but we can take any.
- * If DEL, we require a nick and no level.
- * Else (ADD), we require a level (which implies a nick). */
- if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
- this->OnSyntaxError(source, cmd);
- else if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (Anope::ReadOnly && !is_list)
- source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
- else if (cmd.equals_ci("ADD"))
- this->DoAdd(source, ci, params);
- else if (cmd.equals_ci("DEL"))
- this->DoDel(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- this->DoList(source, ci, params);
- else if (cmd.equals_ci("VIEW"))
- this->DoView(source, ci, params);
- else if (cmd.equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Maintains the \002access list\002 for a channel. The access\n"
- "list specifies which users are allowed chanop status or\n"
- "access to %s commands on the channel. Different\n"
- "user levels allow for access to different subsets of\n"
- "privileges. Any registered user not on the access list has\n"
- "a user level of 0, and any unregistered user has a user level\n"
- "of -1."), source.service->nick.c_str());
- source.Reply(" ");
- source.Reply(_("The \002ACCESS ADD\002 command adds the given mask to the\n"
- "access list with the given user level; if the mask is\n"
- "already present on the list, its access level is changed to\n"
- "the level specified in the command. The \037level\037 specified\n"
- "may be a numerical level or the name of a privilege (eg AUTOOP).\n"
- "When a user joins the channel the access they receive is from the\n"
- "highest level entry in the access list."));
- if (!Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- source.Reply(_("The given mask may also be a channel, which will use the\n"
- "access list from the other channel up to the given \037level\037."));
- source.Reply(" ");
- source.Reply(_("The \002ACCESS DEL\002 command removes the given nick from the\n"
- "access list. If a list of entry numbers is given, those\n"
- "entries are deleted. (See the example for LIST below.)\n"
- "You may remove yourself from an access list, even if you\n"
- "do not have access to modify that list otherwise."));
- source.Reply(" ");
- source.Reply(_("The \002ACCESS LIST\002 command displays the access list. If\n"
- "a wildcard mask is given, only those entries matching the\n"
- "mask are displayed. If a list of entry numbers is given,\n"
- "only those entries are shown; for example:\n"
- " \002ACCESS #channel LIST 2-5,7-9\002\n"
- " Lists access entries numbered 2 through 5 and\n"
- " 7 through 9.\n"
- " \n"
- "The \002ACCESS VIEW\002 command displays the access list similar\n"
- "to \002ACCESS LIST\002 but shows the creator and last used time.\n"
- " \n"
- "The \002ACCESS CLEAR\002 command clears all entries of the\n"
- "access list."));
- source.Reply(" ");
-
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("chanserv/levels", bi, cmd))
- source.Reply(_("\002User access levels\002 can be seen by using the\n"
- "\002%s\002 command; type \002%s%s HELP LEVELS\002 for\n"
- "information."), cmd.c_str(), Config->StrictPrivmsg.c_str(), bi->nick.c_str());
- return true;
- }
-};
-
-class CommandCSLevels : public Command
-{
- void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &what = params[2];
- const Anope::string &lev = params[3];
-
- int level;
-
- if (lev.equals_ci("FOUNDER"))
- level = ACCESS_FOUNDER;
- else
- {
- try
- {
- level = convertTo<int>(lev);
- }
- catch (const ConvertException &)
- {
- this->OnSyntaxError(source, "SET");
- return;
- }
- }
-
- if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
- source.Reply(_("Level must be between %d and %d inclusive."), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- else
- {
- Privilege *p = PrivilegeManager::FindPrivilege(what);
- if (p == NULL)
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
- else
- {
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << p->name << " to level " << level;
-
- ci->SetLevel(p->name, level);
- FOREACH_MOD(OnLevelChange, (source, ci, p->name, level));
-
- if (level == ACCESS_FOUNDER)
- source.Reply(_("Level for %s on channel %s changed to founder only."), p->name.c_str(), ci->name.c_str());
- else
- source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), p->name.c_str(), ci->name.c_str(), level);
- }
- }
- }
-
- void DoDisable(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &what = params[2];
-
- /* Don't allow disabling of the founder level. It would be hard to change it back if you don't have access to use this command */
- if (what.equals_ci("FOUNDER"))
- {
- source.Reply(_("You can not disable the founder privilege because it would be impossible to reenable it at a later time."));
- return;
- }
-
- Privilege *p = PrivilegeManager::FindPrivilege(what);
- if (p != NULL)
- {
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable " << p->name;
-
- ci->SetLevel(p->name, ACCESS_INVALID);
- FOREACH_MOD(OnLevelChange, (source, ci, p->name, ACCESS_INVALID));
-
- source.Reply(_("\002%s\002 disabled on channel %s."), p->name.c_str(), ci->name.c_str());
- return;
- }
-
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci)
- {
- source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Level"));
-
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
-
- for (unsigned i = 0; i < privs.size(); ++i)
- {
- const Privilege &p = privs[i];
- int16_t j = ci->GetLevel(p.name);
-
- ListFormatter::ListEntry entry;
- entry["Name"] = p.name;
-
- if (j == ACCESS_INVALID)
- entry["Level"] = Language::Translate(source.GetAccount(), _("(disabled)"));
- else if (j == ACCESS_FOUNDER)
- entry["Level"] = Language::Translate(source.GetAccount(), _("(founder only)"));
- else
- entry["Level"] = stringify(j);
-
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- void DoReset(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to reset all levels";
-
- reset_levels(ci);
- FOREACH_MOD(OnLevelChange, (source, ci, "ALL", 0));
-
- source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
- return;
- }
-
- public:
- CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4)
- {
- this->SetDesc(_("Redefine the meanings of access levels"));
- this->SetSyntax(_("\037channel\037 SET \037type\037 \037level\037"));
- this->SetSyntax(_("\037channel\037 {DIS | DISABLE} \037type\037"));
- this->SetSyntax(_("\037channel\037 LIST"));
- this->SetSyntax(_("\037channel\037 RESET"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[1];
- const Anope::string &what = params.size() > 2 ? params[2] : "";
- const Anope::string &s = params.size() > 3 ? params[3] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- bool has_access = false;
- if (source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (cmd.equals_ci("LIST") && source.HasPriv("chanserv/access/list"))
- has_access = true;
- else if (source.AccessFor(ci).HasPriv("FOUNDER"))
- has_access = true;
-
- /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
- * one; else, we want none.
- */
- if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
- this->OnSyntaxError(source, cmd);
- else if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (Anope::ReadOnly && !cmd.equals_ci("LIST"))
- source.Reply(READ_ONLY_MODE);
- else if (cmd.equals_ci("SET"))
- this->DoSet(source, ci, params);
- else if (cmd.equals_ci("DIS") || cmd.equals_ci("DISABLE"))
- this->DoDisable(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- this->DoList(source, ci);
- else if (cmd.equals_ci("RESET"))
- this->DoReset(source, ci);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (subcommand.equals_ci("DESC"))
- {
- source.Reply(_("The following feature/function names are available:"));
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Description"));
-
- const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (unsigned i = 0; i < privs.size(); ++i)
- {
- const Privilege &p = privs[i];
- ListFormatter::ListEntry entry;
- entry["Name"] = p.name;
- entry["Description"] = Language::Translate(source.nc, p.desc.c_str());
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- else
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("The \002LEVELS\002 command allows fine control over the meaning of\n"
- "the numeric access levels used for channels. With this\n"
- "command, you can define the access level required for most\n"
- "of %s's functions. (The \002SET FOUNDER\002 and this command\n"
- "are always restricted to the channel founder.)\n"
- " \n"
- "\002LEVELS SET\002 allows the access level for a function or group of\n"
- "functions to be changed. \002LEVELS DISABLE\002 (or \002DIS\002 for short)\n"
- "disables an automatic feature or disallows access to a\n"
- "function by anyone, INCLUDING the founder (although, the founder\n"
- "can always reenable it). Use \002LEVELS SET founder\002 to make a level\n"
- "founder only.\n"
- " \n"
- "\002LEVELS LIST\002 shows the current levels for each function or\n"
- "group of functions. \002LEVELS RESET\002 resets the levels to the\n"
- "default levels of a newly-created channel.\n"
- " \n"
- "For a list of the features and functions whose levels can be\n"
- "set, see \002HELP LEVELS DESC\002."), source.service->nick.c_str());
- }
- return true;
- }
-};
-
-class CSAccess : public Module
-{
- AccessAccessProvider accessprovider;
- CommandCSAccess commandcsaccess;
- CommandCSLevels commandcslevels;
-
- public:
- CSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- accessprovider(this), commandcsaccess(this), commandcslevels(this)
- {
- this->SetPermanent(true);
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- defaultLevels.clear();
-
- for (int i = 0; i < conf->CountBlock("privilege"); ++i)
- {
- Configuration::Block *priv = conf->GetBlock("privilege", i);
-
- const Anope::string &pname = priv->Get<const Anope::string>("name");
-
- Privilege *p = PrivilegeManager::FindPrivilege(pname);
- if (p == NULL)
- continue;
-
- const Anope::string &value = priv->Get<const Anope::string>("level");
- if (value.empty())
- continue;
- else if (value.equals_ci("founder"))
- defaultLevels[p->name] = ACCESS_FOUNDER;
- else if (value.equals_ci("disabled"))
- defaultLevels[p->name] = ACCESS_INVALID;
- else
- defaultLevels[p->name] = priv->Get<int16_t>("level");
- }
- }
-
- void OnCreateChan(ChannelInfo *ci) anope_override
- {
- reset_levels(ci);
- }
-
- EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) anope_override
- {
- if (group->ci == NULL)
- return EVENT_CONTINUE;
- /* Special case. Allows a level of -1 to match anyone, and a level of 0 to match anyone identified. */
- int16_t level = group->ci->GetLevel(priv);
- if (level == -1)
- return EVENT_ALLOW;
- else if (level == 0 && group->nc)
- return EVENT_ALLOW;
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(CSAccess)
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
deleted file mode 100644
index cb0a49ccb..000000000
--- a/modules/commands/cs_akick.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSAKick : public Command
-{
- void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params[2];
- Anope::string reason = params.size() > 3 ? params[3] : "";
- const NickAlias *na = NickAlias::Find(mask);
- NickCore *nc = NULL;
- const AutoKick *akick;
- unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
-
- if (reason.length() > reasonmax)
- reason = reason.substr(0, reasonmax);
-
- if (IRCD->IsExtbanValid(mask))
- ; /* If this is an extban don't try to complete the mask */
- else if (IRCD->IsChannelValid(mask))
- {
- /* Also don't try to complete the mask if this is a channel */
-
- if (mask.equals_ci(ci->name) && ci->HasExt("PEACE"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- else if (!na)
- {
- /* If the mask contains a realname the reason must be prepended with a : */
- if (mask.find('#') != Anope::string::npos)
- {
- size_t r = reason.find(':');
- if (r != Anope::string::npos)
- {
- mask += " " + reason.substr(0, r);
- mask.trim();
- reason = reason.substr(r + 1);
- reason.trim();
- }
- else
- {
- mask = mask + " " + reason;
- reason.clear();
- }
- }
-
- Entry e("", mask);
-
- mask = (e.nick.empty() ? "*" : e.nick) + "!"
- + (e.user.empty() ? "*" : e.user) + "@"
- + (e.host.empty() ? "*" : e.host);
- if (!e.real.empty())
- mask += "#" + e.real;
- }
- else
- nc = na->nc;
-
- /* Check excepts BEFORE we get this far */
- if (ci->c)
- {
- std::vector<Anope::string> modes = ci->c->GetModeList("EXCEPT");
- for (unsigned int i = 0; i < modes.size(); ++i)
- {
- if (Anope::Match(modes[i], mask))
- {
- source.Reply(CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
- return;
- }
- }
- }
-
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- /* Opers overriding get to bypass PEACE */
- if (override)
- ;
- /* These peace checks are only for masks */
- else if (IRCD->IsChannelValid(mask))
- ;
- /* Check whether target nick has equal/higher access
- * or whether the mask matches a user with higher/equal access - Viper */
- else if (ci->HasExt("PEACE") && nc)
- {
- AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
- if (nc == ci->GetFounder() || nc_access >= u_access)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- else if (ci->HasExt("PEACE"))
- {
- /* Match against all currently online users with equal or
- * higher access. - Viper */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u2 = it->second;
-
- AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
- Entry entry_mask("", mask);
-
- if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- /* Match against the lastusermask of all nickalias's with equal
- * or higher access. - Viper */
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- {
- na = it->second;
-
- AccessGroup nc_access = ci->AccessFor(na->nc), u_access = source.AccessFor(ci);
- if (na->nc && (na->nc == ci->GetFounder() || nc_access >= u_access))
- {
- Anope::string buf = na->nick + "!" + na->last_usermask;
- if (Anope::Match(buf, mask))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- }
- }
-
- for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
- {
- akick = ci->GetAkick(j);
- if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
- {
- source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->nc ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
- return;
- }
- }
-
- if (ci->GetAkickCount() >= Config->GetModule(this->owner)->Get<unsigned>("autokickmax"))
- {
- source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner)->Get<unsigned>("autokickmax"));
- return;
- }
-
- if (nc)
- akick = ci->AddAkick(source.GetNick(), nc, reason);
- else
- akick = ci->AddAkick(source.GetNick(), mask, reason);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << (reason == "" ? "" : ": ") << reason;
-
- FOREACH_MOD(OnAkickAdd, (source, ci, akick));
-
- source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
-
- this->DoEnforce(source, ci);
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &mask = params[2];
- unsigned i, end;
-
- if (!ci->GetAkickCount())
- {
- source.Reply(_("%s autokick list is empty."), ci->name.c_str());
- return;
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class AkickDelCallback : public NumberList
- {
- CommandSource &source;
- ChannelInfo *ci;
- Command *c;
- unsigned deleted;
- AccessGroup ag;
- public:
- AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), deleted(0), ag(source.AccessFor(ci))
- {
- }
-
- ~AkickDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
- else
- source.Reply(_("Deleted %d entries from %s autokick list."), deleted, ci->name.c_str());
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAkickCount())
- return;
-
- const AutoKick *akick = ci->GetAkick(number - 1);
-
- FOREACH_MOD(OnAkickDel, (source, ci, akick));
-
- bool override = !ag.HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << (akick->nc ? akick->nc->display : akick->mask);
-
- ++deleted;
- ci->EraseAkick(number - 1);
- }
- }
- delcallback(source, ci, this, mask);
- delcallback.Process();
- }
- else
- {
- const NickAlias *na = NickAlias::Find(mask);
- const NickCore *nc = na ? *na->nc : NULL;
-
- for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
- {
- const AutoKick *akick = ci->GetAkick(i);
-
- if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
- break;
- }
-
- if (i == ci->GetAkickCount())
- {
- source.Reply(_("\002%s\002 not found on %s autokick list."), mask.c_str(), ci->name.c_str());
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
-
- FOREACH_MOD(OnAkickDel, (source, ci, ci->GetAkick(i)));
-
- ci->EraseAkick(i);
-
- source.Reply(_("\002%s\002 deleted from %s autokick list."), mask.c_str(), ci->name.c_str());
- }
- }
-
- void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &mask = params.size() > 2 ? params[2] : "";
-
- if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class AkickListCallback : public NumberList
- {
- ListFormatter &list;
- ChannelInfo *ci;
-
- public:
- AkickListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAkickCount())
- return;
-
- const AutoKick *akick = ci->GetAkick(number - 1);
-
- Anope::string timebuf, lastused;
- if (akick->addtime)
- timebuf = Anope::strftime(akick->addtime, NULL, true);
- else
- timebuf = UNKNOWN;
- if (akick->last_used)
- lastused = Anope::strftime(akick->last_used, NULL, true);
- else
- lastused = UNKNOWN;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- if (akick->nc)
- entry["Mask"] = akick->nc->display;
- else
- entry["Mask"] = akick->mask;
- entry["Creator"] = akick->creator;
- entry["Created"] = timebuf;
- entry["Last used"] = lastused;
- entry["Reason"] = akick->reason;
- this->list.AddEntry(entry);
- }
- }
- nl_list(list, ci, mask);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
- {
- const AutoKick *akick = ci->GetAkick(i);
-
- if (!mask.empty())
- {
- if (!akick->nc && !Anope::Match(akick->mask, mask))
- continue;
- if (akick->nc && !Anope::Match(akick->nc->display, mask))
- continue;
- }
-
- Anope::string timebuf, lastused;
- if (akick->addtime)
- timebuf = Anope::strftime(akick->addtime, NULL, true);
- else
- timebuf = UNKNOWN;
- if (akick->last_used)
- lastused = Anope::strftime(akick->last_used, NULL, true);
- else
- lastused = UNKNOWN;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- if (akick->nc)
- entry["Mask"] = akick->nc->display;
- else
- entry["Mask"] = akick->mask;
- entry["Creator"] = akick->creator;
- entry["Created"] = timebuf;
- entry["Last used"] = lastused;
- entry["Reason"] = akick->reason;
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Autokick list for %s:"), ci->name.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of autokick list"));
- }
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAkickCount())
- {
- source.Reply(_("%s autokick list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (!ci->GetAkickCount())
- {
- source.Reply(_("%s autokick list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Last used")).AddColumn(_("Reason"));
- this->ProcessList(source, ci, params, list);
- }
-
- void DoEnforce(CommandSource &source, ChannelInfo *ci)
- {
- Channel *c = ci->c;
- int count = 0;
-
- if (!c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- return;
- }
-
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- if (c->CheckKick(uc->user))
- ++count;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ENFORCE, affects " << count << " users";
-
- source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the akick list";
-
- ci->ClearAkick();
- source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
- }
-
- public:
- CommandCSAKick(Module *creator) : Command(creator, "chanserv/akick", 2, 4)
- {
- this->SetDesc(_("Maintain the AutoKick list"));
- this->SetSyntax(_("\037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]"));
- this->SetSyntax(_("\037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 ENFORCE"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string chan = params[0];
- Anope::string cmd = params[1];
- Anope::string mask = params.size() > 2 ? params[2] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
-
- bool has_access = false;
- if (source.AccessFor(ci).HasPriv("AKICK") || source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (is_list && source.HasPriv("chanserv/access/list"))
- has_access = true;
-
- if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
- this->OnSyntaxError(source, cmd);
- else if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && Anope::ReadOnly)
- source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
- else if (cmd.equals_ci("ADD"))
- this->DoAdd(source, ci, params);
- else if (cmd.equals_ci("DEL"))
- this->DoDel(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- this->DoList(source, ci, params);
- else if (cmd.equals_ci("VIEW"))
- this->DoView(source, ci, params);
- else if (cmd.equals_ci("ENFORCE"))
- this->DoEnforce(source, ci);
- else if (cmd.equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- BotInfo *bi = Config->GetClient("NickServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Maintains the \002AutoKick list\002 for a channel. If a user\n"
- "on the AutoKick list attempts to join the channel,\n"
- "%s will ban that user from the channel, then kick\n"
- "the user.\n"
- " \n"
- "The \002AKICK ADD\002 command adds the given nick or usermask\n"
- "to the AutoKick list. If a \037reason\037 is given with\n"
- "the command, that reason will be used when the user is\n"
- "kicked; if not, the default reason is \"User has been\n"
- "banned from the channel\".\n"
- "When akicking a \037registered nick\037 the %s account\n"
- "will be added to the akick list instead of the mask.\n"
- "All users within that nickgroup will then be akicked.\n"),
- source.service->nick.c_str(), bi ? bi->nick.c_str() : "NickServ");
- source.Reply(_(
- " \n"
- "The \002AKICK DEL\002 command removes the given nick or mask\n"
- "from the AutoKick list. It does not, however, remove any\n"
- "bans placed by an AutoKick; those must be removed\n"
- "manually.\n"
- " \n"
- "The \002AKICK LIST\002 command displays the AutoKick list, or\n"
- "optionally only those AutoKick entries which match the\n"
- "given mask.\n"
- " \n"
- "The \002AKICK VIEW\002 command is a more verbose version of the\n"
- "\002AKICK LIST\002 command.\n"
- " \n"
- "The \002AKICK ENFORCE\002 command causes %s to enforce the\n"
- "current AKICK list by removing those users who match an\n"
- "AKICK mask.\n"
- " \n"
- "The \002AKICK CLEAR\002 command clears all entries of the\n"
- "akick list."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CSAKick : public Module
-{
- CommandCSAKick commandcsakick;
-
- public:
- CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsakick(this)
- {
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- if (!c->ci || c->MatchesList(u, "EXCEPT"))
- return EVENT_CONTINUE;
-
- for (unsigned j = 0, end = c->ci->GetAkickCount(); j < end; ++j)
- {
- AutoKick *autokick = c->ci->GetAkick(j);
- bool kick = false;
-
- if (autokick->nc)
- kick = autokick->nc == u->Account();
- else if (IRCD->IsChannelValid(autokick->mask))
- {
- Channel *chan = Channel::Find(autokick->mask);
- kick = chan != NULL && chan->FindUser(u);
- }
- else
- kick = Entry("BAN", autokick->mask).Matches(u);
-
- if (kick)
- {
- Log(LOG_DEBUG_2) << u->nick << " matched akick " << (autokick->nc ? autokick->nc->display : autokick->mask);
- autokick->last_used = Anope::CurTime;
- if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos)
- mask = autokick->mask;
- reason = autokick->reason;
- if (reason.empty())
- {
- reason = Language::Translate(u, Config->GetModule(this)->Get<const Anope::string>("autokickreason").c_str());
- reason = reason.replace_all_cs("%n", u->nick)
- .replace_all_cs("%c", c->name);
- }
- if (reason.empty())
- reason = Language::Translate(u, _("User has been banned from the channel"));
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(CSAKick)
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
deleted file mode 100644
index 1cf316b88..000000000
--- a/modules/commands/cs_ban.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-static Module *me;
-
-class TempBan : public Timer
-{
- private:
- Anope::string channel;
- Anope::string mask;
- Anope::string mode;
-
- public:
- TempBan(time_t seconds, Channel *c, const Anope::string &banmask, const Anope::string &mod) : Timer(me, seconds), channel(c->name), mask(banmask), mode(mod) { }
-
- void Tick(time_t ctime) anope_override
- {
- Channel *c = Channel::Find(this->channel);
- if (c)
- c->RemoveMode(NULL, mode, this->mask);
- }
-};
-
-class CommandCSBan : public Command
-{
- public:
- CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 4)
- {
- this->SetDesc(_("Bans a given nick or mask on a channel"));
- this->SetSyntax(_("\037channel\037 [+\037expiry\037] {\037nick\037 | \037mask\037} [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- Configuration::Block *block = Config->GetCommand(source);
- const Anope::string &mode = block->Get<Anope::string>("mode", "BAN");
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- Channel *c = ci->c;
- if (c == NULL)
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
- else if (IRCD->GetMaxListFor(c) && c->HasMode(mode) >= IRCD->GetMaxListFor(c))
- {
- source.Reply(_("The %s list for %s is full."), mode.lower().c_str(), c->name.c_str());
- return;
- }
-
- Anope::string expiry, target, reason;
- time_t ban_time;
- if (params[1][0] == '+')
- {
- ban_time = Anope::DoTime(params[1]);
- if (ban_time == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- if (params.size() < 3)
- {
- this->SendSyntax(source);
- return;
- }
- target = params[2];
- reason = "Requested";
- if (params.size() > 3)
- reason = params[3];
- }
- else
- {
- ban_time = 0;
- target = params[1];
- reason = "Requested";
- if (params.size() > 2)
- reason = params[2];
- if (params.size() > 3)
- reason += " " + params[3];
- }
-
- unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
- if (reason.length() > reasonmax)
- reason = reason.substr(0, reasonmax);
-
- Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
- signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
-
- User *u = source.GetUser();
- User *u2 = User::Find(target, true);
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (!u_access.HasPriv("BAN") && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- else if (u2)
- {
- AccessGroup u2_access = ci->AccessFor(u2);
-
- if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- /*
- * Don't ban/kick the user on channels where he is excepted
- * to prevent services <-> server wars.
- */
- else if (c->MatchesList(u2, "EXCEPT"))
- source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
- else if (u2->IsProtected())
- source.Reply(ACCESS_DENIED);
- else
- {
- Anope::string mask = ci->GetIdealBan(u2);
-
- bool override = !u_access.HasPriv("BAN") || (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
-
- if (!c->HasMode(mode, mask))
- {
- c->SetMode(NULL, mode, mask);
- if (ban_time)
- {
- new TempBan(ban_time, c, mask, mode);
- source.Reply(_("Ban on \002%s\002 expires in %s."), mask.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str());
- }
- }
-
- /* We still allow host banning while not allowing to kick */
- if (!c->FindUser(u2))
- return;
-
- if (block->Get<bool>("kick", "yes"))
- {
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK")))
- {
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
- }
- }
- }
- else
- {
- bool founder = u_access.HasPriv("FOUNDER");
- bool override = !founder && !u_access.HasPriv("BAN");
-
- Anope::string mask = IRCD->NormalizeMask(target);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
-
- if (!c->HasMode(mode, mask))
- {
- c->SetMode(NULL, mode, mask);
- if (ban_time)
- {
- new TempBan(ban_time, c, mask, mode);
- source.Reply(_("Ban on \002%s\002 expires in %s."), mask.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str());
- }
- }
-
- int matched = 0, kicked = 0;
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- Entry e(mode, mask);
- if (e.Matches(uc->user))
- {
- ++matched;
-
- AccessGroup u2_access = ci->AccessFor(uc->user);
-
- if (matched > 1 && !founder)
- continue;
- if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access)
- continue;
- else if (ci->c->MatchesList(uc->user, "EXCEPT"))
- continue;
- else if (uc->user->IsProtected())
- continue;
-
- if (block->Get<bool>("kick", "yes"))
- {
- ++kicked;
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- {
- reason += " (Matches " + mask + ")";
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
- }
- }
- }
-
- if (matched)
- source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, mask.c_str(), c->name.c_str());
- else
- source.Reply(_("No users on %s match %s."), c->name.c_str(), mask.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Bans a given nick or mask on a channel. An optional expiry may\n"
- "be given to cause services to remove the ban after a set amount\n"
- "of time.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access\n"
- "and above on the channel. Channel founders may ban masks."));
- return true;
- }
-};
-
-class CSBan : public Module
-{
- CommandCSBan commandcsban;
-
- public:
- CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsban(this)
- {
- me = this;
- }
-};
-
-MODULE_INIT(CSBan)
diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp
deleted file mode 100644
index a4ec31c1e..000000000
--- a/modules/commands/cs_clone.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/bs_badwords.h"
-
-class CommandCSClone : public Command
-{
- void CopySetting(ChannelInfo *ci, ChannelInfo *target_ci, const Anope::string &setting)
- {
- if (ci->HasExt(setting))
- target_ci->Extend<bool>(setting);
- }
-
- void CopyAccess(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- std::set<Anope::string> masks;
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- unsigned count = 0;
-
- for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i)
- masks.insert(target_ci->GetAccess(i)->Mask());
-
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- const ChanAccess *taccess = ci->GetAccess(i);
- AccessProvider *provider = taccess->provider;
-
- if (access_max && target_ci->GetDeepAccessCount() >= access_max)
- break;
-
- if (masks.count(taccess->Mask()))
- continue;
- masks.insert(taccess->Mask());
-
- ChanAccess *newaccess = provider->Create();
- newaccess->SetMask(taccess->Mask(), target_ci);
- newaccess->creator = taccess->creator;
- newaccess->last_seen = taccess->last_seen;
- newaccess->created = taccess->created;
- newaccess->AccessUnserialize(taccess->AccessSerialize());
-
- target_ci->AddAccess(newaccess);
-
- ++count;
- }
-
- source.Reply(_("%d access entries from \002%s\002 have been cloned to \002%s\002."), count, ci->name.c_str(), target_ci->name.c_str());
- }
-
- void CopyAkick(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- target_ci->ClearAkick();
- for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
- {
- const AutoKick *akick = ci->GetAkick(i);
- if (akick->nc)
- target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
- else
- target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
- }
-
- source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
-
- void CopyBadwords(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- BadWords *target_badwords = target_ci->Require<BadWords>("badwords"),
- *badwords = ci->Require<BadWords>("badwords");
-
- if (!target_badwords || !badwords)
- {
- source.Reply(ACCESS_DENIED); // BotServ doesn't exist/badwords isn't loaded
- return;
- }
-
- target_badwords->ClearBadWords();
-
- for (unsigned i = 0; i < badwords->GetBadWordCount(); ++i)
- {
- const BadWord *bw = badwords->GetBadWord(i);
- target_badwords->AddBadWord(bw->word, bw->type);
- }
-
- badwords->Check();
- target_badwords->Check();
-
- source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
-
- void CopyLevels(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
- {
- const Anope::map<int16_t> &cilevels = ci->GetLevelEntries();
-
- for (Anope::map<int16_t>::const_iterator it = cilevels.begin(); it != cilevels.end(); ++it)
- {
- target_ci->SetLevel(it->first, it->second);
- }
-
- source.Reply(_("All level entries from \002%s\002 have been cloned into \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
-
-public:
- CommandCSClone(Module *creator) : Command(creator, "chanserv/clone", 2, 3)
- {
- this->SetDesc(_("Copy all settings from one channel to another"));
- this->SetSyntax(_("\037channel\037 \037target\037 [\037what\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &channel = params[0];
- const Anope::string &target = params[1];
- Anope::string what = params.size() > 2 ? params[2] : "";
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- User *u = source.GetUser();
- ChannelInfo *ci = ChannelInfo::Find(channel);
- bool override = false;
-
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- return;
- }
-
- ChannelInfo *target_ci = ChannelInfo::Find(target);
- if (!target_ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
- return;
- }
-
- if (ci == target_ci)
- {
- source.Reply(_("Cannot clone channel \002%s\002 to itself!"), target.c_str());
- return;
- }
-
- if (!source.IsFounder(ci) || !source.IsFounder(target_ci))
- {
- if (!source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (what.equals_ci("ALL"))
- what.clear();
-
- if (what.empty())
- {
- delete target_ci;
- target_ci = new ChannelInfo(*ci);
- target_ci->name = target;
- target_ci->time_registered = Anope::CurTime;
- (*RegisteredChannelList)[target_ci->name] = target_ci;
- target_ci->c = Channel::Find(target_ci->name);
-
- target_ci->bi = NULL;
- if (ci->bi)
- ci->bi->Assign(u, target_ci);
-
- if (target_ci->c)
- {
- target_ci->c->ci = target_ci;
-
- target_ci->c->CheckModes();
-
- target_ci->c->SetCorrectModes(u, true);
- }
-
- if (target_ci->c && !target_ci->c->topic.empty())
- {
- target_ci->last_topic = target_ci->c->topic;
- target_ci->last_topic_setter = target_ci->c->topic_setter;
- target_ci->last_topic_time = target_ci->c->topic_time;
- }
- else
- target_ci->last_topic_setter = source.service->nick;
-
- const Anope::string settings[] = { "NOAUTOOP", "CS_KEEP_MODES", "PEACE", "PERSIST", "RESTRICTED",
- "CS_SECURE", "SECUREFOUNDER", "SECUREOPS", "SIGNKICK", "SIGNKICK_LEVEL", "CS_NO_EXPIRE" };
-
- for (unsigned int i = 0; i < sizeof(settings) / sizeof(Anope::string); ++i)
- CopySetting(ci, target_ci, settings[i]);
-
- CopyAccess(source, ci, target_ci);
- CopyAkick(source, ci, target_ci);
- CopyBadwords(source, ci, target_ci);
- CopyLevels(source, ci, target_ci);
-
- FOREACH_MOD(OnChanRegistered, (target_ci));
-
- source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
- }
- else if (what.equals_ci("ACCESS"))
- {
- CopyAccess(source, ci, target_ci);
- }
- else if (what.equals_ci("AKICK"))
- {
- CopyAkick(source, ci, target_ci);
- }
- else if (what.equals_ci("BADWORDS"))
- {
- CopyBadwords(source, ci, target_ci);
- }
- else if (what.equals_ci("LEVELS"))
- {
- CopyLevels(source, ci, target_ci);
- }
- else
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->name;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Copies all settings, access, akicks, etc from \002channel\002 to the\n"
- "\002target\002 channel. If \037what\037 is \002ACCESS\002, \002AKICK\002, \002BADWORDS\002,\n"
- "or \002LEVELS\002 then only the respective settings are cloned.\n"
- "You must be the founder of \037channel\037 and \037target\037."));
- return true;
- }
-};
-
-class CSClone : public Module
-{
- CommandCSClone commandcsclone;
-
- public:
- CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsclone(this)
- {
-
- }
-};
-
-MODULE_INIT(CSClone)
diff --git a/modules/commands/cs_drop.cpp b/modules/commands/cs_drop.cpp
deleted file mode 100644
index 83299aee5..000000000
--- a/modules/commands/cs_drop.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSDrop : public Command
-{
- public:
- CommandCSDrop(Module *creator) : Command(creator, "chanserv/drop", 1, 2)
- {
- this->SetDesc(_("Cancel the registration of a channel"));
- this->SetSyntax(_("\037channel\037 \037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- if (Anope::ReadOnly && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(_("Sorry, channel de-registration is temporarily disabled.")); // XXX: READ_ONLY_MODE?
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (params.size() < 2 || !chan.equals_ci(params[1]))
- {
- source.Reply(_("You must enter the channel name twice as a confirmation that you wish to drop \002%s\002."), chan.c_str());
- return;
- }
-
- if ((ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && !source.HasCommand("chanserv/drop"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnChanDrop, MOD_RESULT, (source, ci));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- bool override = (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"));
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "(founder was: " << (ci->GetFounder() ? ci->GetFounder()->display : "none") << ")";
-
- Reference<Channel> c = ci->c;
- delete ci;
-
- source.Reply(_("Channel \002%s\002 has been dropped."), chan.c_str());
-
- if (c)
- c->CheckModes();
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- if (source.IsServicesOper())
- source.Reply(_("Unregisters the specified channel. Only \002Services Operators\002\n"
- "can drop a channel of which they are not the founder of."));
- else
- source.Reply(_("Unregisters the named channel. Can only be used by\n"
- "the \002channel founder\002."));
-
- return true;
- }
-};
-
-class CSDrop : public Module
-{
- CommandCSDrop commandcsdrop;
-
- public:
- CSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsdrop(this)
- {
-
- }
-};
-
-MODULE_INIT(CSDrop)
diff --git a/modules/commands/cs_enforce.cpp b/modules/commands/cs_enforce.cpp
deleted file mode 100644
index b9f700284..000000000
--- a/modules/commands/cs_enforce.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Original Coder: GeniusDex <geniusdex@anope.org>
- *
- * Please read COPYING and README for further details.
- *
- * Send any bug reports to the Anope Coder, as he will be able
- * to deal with it best.
- */
-
-#include "module.h"
-
-class CommandCSEnforce : public Command
-{
- private:
- void DoSecureOps(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce secureops";
-
- /* Dirty hack to allow Channel::SetCorrectModes to work ok.
- * We pretend like SECUREOPS is on so it doesn't ignore that
- * part of the code. This way we can enforce SECUREOPS even
- * if it's off.
- */
- bool hadsecureops = ci->HasExt("SECUREOPS");
- ci->Extend<bool>("SECUREOPS");
-
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
-
- ci->c->SetCorrectModes(uc->user, false);
- }
-
- if (!hadsecureops)
- ci->Shrink<bool>("SECUREOPS");
-
- source.Reply(_("Secureops enforced on %s."), ci->name.c_str());
- }
-
- void DoRestricted(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce restricted";
-
- std::vector<User *> users;
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (user->IsProtected())
- continue;
-
- if (ci->AccessFor(user).empty())
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- {
- User *user = users[i];
-
- Anope::string mask = ci->GetIdealBan(user);
- Anope::string reason = Language::Translate(user, _("RESTRICTED enforced by ")) + source.GetNick();
- ci->c->SetMode(NULL, "BAN", mask);
- ci->c->Kick(NULL, user, "%s", reason.c_str());
- }
-
- source.Reply(_("Restricted enforced on %s."), ci->name.c_str());
- }
-
- void DoRegOnly(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce registered only";
-
- std::vector<User *> users;
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (user->IsProtected())
- continue;
-
- if (!user->IsIdentified())
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- {
- User *user = users[i];
-
- Anope::string mask = ci->GetIdealBan(user);
- Anope::string reason = Language::Translate(user, _("REGONLY enforced by ")) + source.GetNick();
- if (!ci->c->HasMode("REGISTEREDONLY"))
- ci->c->SetMode(NULL, "BAN", mask);
- ci->c->Kick(NULL, user, "%s", reason.c_str());
- }
-
- source.Reply(_("Registered only enforced on %s."), ci->name.c_str());
- }
-
- void DoSSLOnly(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce SSL only";
-
- std::vector<User *> users;
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (user->IsProtected())
- continue;
-
- if (!user->HasMode("SSL") && !user->HasExt("ssl"))
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- {
- User *user = users[i];
-
- Anope::string mask = ci->GetIdealBan(user);
- Anope::string reason = Language::Translate(user, _("SSLONLY enforced by ")) + source.GetNick();
- if (!ci->c->HasMode("SSL"))
- ci->c->SetMode(NULL, "BAN", mask);
- ci->c->Kick(NULL, user, "%s", reason.c_str());
- }
-
- source.Reply(_("SSL only enforced on %s."), ci->name.c_str());
- }
-
- void DoBans(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce bans";
-
- std::vector<User *> users;
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (user->IsProtected())
- continue;
-
- if (ci->c->MatchesList(user, "BAN") && !ci->c->MatchesList(user, "EXCEPT"))
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- {
- User *user = users[i];
-
- Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick();
- ci->c->Kick(NULL, user, "%s", reason.c_str());
- }
-
- source.Reply(_("Bans enforced on %s."), ci->name.c_str());
- }
-
- void DoLimit(CommandSource &source, ChannelInfo *ci)
- {
- bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce limit";
-
- Anope::string l_str;
- if (!ci->c->GetParam("LIMIT", l_str))
- {
- source.Reply(_("No limit is set on %s."), ci->name.c_str());
- return;
- }
-
- int l;
- try
- {
- l = convertTo<int>(l_str);
- if (l < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("The limit on %s is not valid."), ci->name.c_str());
- return;
- }
-
- std::vector<User *> users;
- /* The newer users are at the end of the list, so kick users starting from the end */
- for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (user->IsProtected())
- continue;
-
- if (!ci->AccessFor(user).empty())
- continue;
-
- if (ci->c->users.size() - users.size() <= static_cast<unsigned>(l))
- continue;
-
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- {
- User *user = users[i];
-
- Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick();
- ci->c->Kick(NULL, user, "%s", reason.c_str());
- }
-
- source.Reply(_("LIMIT enforced on %s, %d users removed."), ci->name.c_str(), users.size());
- }
-
- public:
- CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 2, 2)
- {
- this->SetDesc(_("Enforce various channel modes and set options"));
- this->SetSyntax(_("\037channel\037 \037what\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &what = params.size() > 1 ? params[1] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!ci)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- else if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else if (what.equals_ci("SECUREOPS"))
- this->DoSecureOps(source, ci);
- else if (what.equals_ci("RESTRICTED"))
- this->DoRestricted(source, ci);
- else if (what.equals_ci("REGONLY"))
- this->DoRegOnly(source, ci);
- else if (what.equals_ci("SSLONLY"))
- this->DoSSLOnly(source, ci);
- else if (what.equals_ci("BANS"))
- this->DoBans(source, ci);
- else if (what.equals_ci("LIMIT"))
- this->DoLimit(source, ci);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enforce various channel modes and set options. The \037channel\037\n"
- "option indicates what channel to enforce the modes and options\n"
- "on. The \037what\037 option indicates what modes and options to\n"
- "enforce, and can be any of \002SECUREOPS\002, \002RESTRICTED\002, \002REGONLY\002, \002SSLONLY\002,\n"
- "\002BANS\002, or \002LIMIT\002.\n"
- " \n"
- "Use \002SECUREOPS\002 to enforce the SECUREOPS option, even if it is not\n"
- "enabled. Use \002RESTRICTED\002 to enfore the RESTRICTED option, also\n"
- "if it's not enabled. Use \002REGONLY\002 to kick all unregistered users\n"
- "from the channel. Use \002SSLONLY\002 to kick all users not using a secure\n"
- "connection from the channel. \002BANS\002 will enforce bans on the channel by\n"
- "kicking users affected by them, and \002LIMIT\002 will kick users until the\n"
- "user count drops below the channel limit, if one is set."));
- return true;
- }
-};
-
-class CSEnforce : public Module
-{
- CommandCSEnforce commandcsenforce;
-
- public:
- CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsenforce(this)
- {
-
- }
-};
-
-MODULE_INIT(CSEnforce)
diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp
deleted file mode 100644
index 796aa5148..000000000
--- a/modules/commands/cs_entrymsg.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/cs_entrymsg.h"
-
-struct EntryMsgImpl : EntryMsg, Serializable
-{
- EntryMsgImpl() : Serializable("EntryMsg")
- {
- }
-
- EntryMsgImpl(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime) : Serializable("EntryMsg")
- {
- this->chan = c->name;
- this->creator = cname;
- this->message = cmessage;
- this->when = ct;
- }
-
- ~EntryMsgImpl();
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["ci"] << this->chan;
- data["creator"] << this->creator;
- data["message"] << this->message;
- data.SetType("when", Serialize::Data::DT_INT); data["when"] << this->when;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct EntryMessageListImpl : EntryMessageList
-{
- EntryMessageListImpl(Extensible *) { }
-
- EntryMsg* Create() anope_override
- {
- return new EntryMsgImpl();
- }
-};
-
-EntryMsgImpl::~EntryMsgImpl()
-{
- ChannelInfo *ci = ChannelInfo::Find(this->chan);
- if (!ci)
- return;
-
- EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
- if (!messages)
- return;
-
- std::vector<EntryMsg *>::iterator it = std::find((*messages)->begin(), (*messages)->end(), this);
- if (it != (*messages)->end())
- (*messages)->erase(it);
-}
-
-
-Serializable* EntryMsgImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci, screator, smessage;
- time_t swhen;
-
- data["ci"] >> sci;
- data["creator"] >> screator;
- data["message"] >> smessage;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- if (obj)
- {
- EntryMsgImpl *msg = anope_dynamic_static_cast<EntryMsgImpl *>(obj);
- msg->chan = ci->name;
- data["creator"] >> msg->creator;
- data["message"] >> msg->message;
- data["when"] >> msg->when;
- return msg;
- }
-
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- data["when"] >> swhen;
-
- EntryMsgImpl *m = new EntryMsgImpl(ci, screator, smessage, swhen);
- (*messages)->push_back(m);
- return m;
-}
-
-class CommandEntryMessage : public Command
-{
- private:
- void DoList(CommandSource &source, ChannelInfo *ci)
- {
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- if ((*messages)->empty())
- {
- source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
- return;
- }
-
- source.Reply(_("Entry message list for \002%s\002:"), ci->name.c_str());
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Message"));
- for (unsigned i = 0; i < (*messages)->size(); ++i)
- {
- EntryMsg *msg = (*messages)->at(i);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Creator"] = msg->creator;
- entry["Created"] = Anope::strftime(msg->when, NULL, true);
- entry["Message"] = msg->message;
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of entry message list."));
- }
-
- void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
- {
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries"))
- source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
- else
- {
- (*messages)->push_back(new EntryMsgImpl(ci, source.GetNick(), message));
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
- source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str());
- }
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
- {
- EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
-
- if (!message.is_pos_number_only())
- source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
- else if ((*messages)->empty())
- source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
- else
- {
- try
- {
- unsigned i = convertTo<unsigned>(message);
- if (i > 0 && i <= (*messages)->size())
- {
- delete (*messages)->at(i - 1);
- if ((*messages)->empty())
- ci->Shrink<EntryMessageList>("entrymsg");
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
- source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str());
- }
- else
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
- }
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- ci->Shrink<EntryMessageList>("entrymsg");
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
- source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str());
- }
-
- public:
- CommandEntryMessage(Module *creator) : Command(creator, "chanserv/entrymsg", 2, 3)
- {
- this->SetDesc(_("Manage the channel's entry messages"));
- this->SetSyntax(_("\037channel\037 ADD \037message\037"));
- this->SetSyntax(_("\037channel\037 DEL \037num\037"));
- this->SetSyntax(_("\037channel\037 LIST"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (Anope::ReadOnly && !params[1].equals_ci("LIST"))
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("LIST"))
- this->DoList(source, ci);
- else if (params[1].equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else if (params.size() < 3)
- this->OnSyntaxError(source, "");
- else if (params[1].equals_ci("ADD"))
- this->DoAdd(source, ci, params[2]);
- else if (params[1].equals_ci("DEL"))
- this->DoDel(source, ci, params[2]);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Controls what messages will be sent to users when they join the channel."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG ADD\002 command adds the given message to\n"
- "the list of messages shown to users when they join\n"
- "the channel."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG DEL\002 command removes the specified message from\n"
- "the list of messages shown to users when they join\n"
- "the channel. You can remove a message by specifying its number\n"
- "which you can get by listing the messages as explained below."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG LIST\002 command displays a listing of messages\n"
- "shown to users when they join the channel."));
- source.Reply(" ");
- source.Reply(_("The \002ENTRYMSG CLEAR\002 command clears all entries from\n"
- "the list of messages shown to users when they join\n"
- "the channel, effectively disabling entry messages."));
- source.Reply(" ");
- source.Reply(_("Adding, deleting, or clearing entry messages requires the\n"
- "SET permission."));
- return true;
- }
-};
-
-class CSEntryMessage : public Module
-{
- CommandEntryMessage commandentrymsg;
- ExtensibleItem<EntryMessageListImpl> eml;
- Serialize::Type entrymsg_type;
-
- public:
- CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandentrymsg(this),
- eml(this, "entrymsg"), entrymsg_type("EntryMsg", EntryMsgImpl::Unserialize)
- {
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (u && c && c->ci && u->server->IsSynced())
- {
- EntryMessageList *messages = c->ci->GetExt<EntryMessageList>("entrymsg");
-
- if (messages != NULL)
- for (unsigned i = 0; i < (*messages)->size(); ++i)
- u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str());
- }
- }
-};
-
-MODULE_INIT(CSEntryMessage)
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
deleted file mode 100644
index 477cc2468..000000000
--- a/modules/commands/cs_flags.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-static std::map<Anope::string, char> defaultFlags;
-
-class FlagsChanAccess : public ChanAccess
-{
- public:
- std::set<char> flags;
-
- FlagsChanAccess(AccessProvider *p) : ChanAccess(p)
- {
- }
-
- bool HasPriv(const Anope::string &priv) const anope_override
- {
- std::map<Anope::string, char>::iterator it = defaultFlags.find(priv);
- if (it != defaultFlags.end() && this->flags.count(it->second) > 0)
- return true;
- return false;
- }
-
- Anope::string AccessSerialize() const
- {
- return Anope::string(this->flags.begin(), this->flags.end());
- }
-
- void AccessUnserialize(const Anope::string &data) anope_override
- {
- for (unsigned i = data.length(); i > 0; --i)
- this->flags.insert(data[i - 1]);
- }
-
- static Anope::string DetermineFlags(const ChanAccess *access)
- {
- if (access->provider->name == "access/flags")
- return access->AccessSerialize();
-
- std::set<char> buffer;
-
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- if (access->HasPriv(it->first))
- buffer.insert(it->second);
-
- if (buffer.empty())
- return "(none)";
- else
- return Anope::string(buffer.begin(), buffer.end());
- }
-};
-
-class FlagsAccessProvider : public AccessProvider
-{
- public:
- static FlagsAccessProvider *ap;
-
- FlagsAccessProvider(Module *o) : AccessProvider(o, "access/flags")
- {
- ap = this;
- }
-
- ChanAccess *Create() anope_override
- {
- return new FlagsChanAccess(this);
- }
-};
-FlagsAccessProvider* FlagsAccessProvider::ap;
-
-class CommandCSFlags : public Command
-{
- void DoModify(CommandSource &source, ChannelInfo *ci, Anope::string mask, const Anope::string &flags)
- {
- if (flags.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci);
- const ChanAccess *highest = u_access.Highest();
- const NickAlias *na = NULL;
-
- if (IRCD->IsChannelValid(mask))
- {
- if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- ChannelInfo *targ_ci = ChannelInfo::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->name;
- }
- else
- {
- na = NickAlias::Find(mask);
- if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
- {
- source.Reply(_("Masks and unregistered users may not be on access lists."));
- return;
- }
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (na)
- mask = na->nick;
- }
-
- ChanAccess *current = NULL;
- unsigned current_idx;
- std::set<char> current_flags;
- bool override = false;
- for (current_idx = ci->GetAccessCount(); current_idx > 0; --current_idx)
- {
- ChanAccess *access = ci->GetAccess(current_idx - 1);
- if ((na && na->nc == access->GetAccount()) || mask.equals_ci(access->Mask()))
- {
- // Flags allows removing others that have the same access as you,
- // but no other access system does.
- if (highest && highest->provider != FlagsAccessProvider::ap && !u_access.founder)
- // operator<= on the non-me entry!
- if (*highest <= *access)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- current = access;
- Anope::string cur_flags = FlagsChanAccess::DetermineFlags(access);
- for (unsigned j = cur_flags.length(); j > 0; --j)
- current_flags.insert(cur_flags[j - 1]);
- break;
- }
- }
-
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- if (access_max && ci->GetDeepAccessCount() >= access_max)
- {
- source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
- return;
- }
-
- Privilege *p = NULL;
- bool add = true;
- for (size_t i = 0; i < flags.length(); ++i)
- {
- char f = flags[i];
- switch (f)
- {
- case '+':
- add = true;
- break;
- case '-':
- add = false;
- break;
- case '*':
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- {
- bool has = current_flags.count(it->second);
- // If we are adding a flag they already have or removing one they don't have, don't bother
- if (add == has)
- continue;
-
- if (!u_access.HasPriv(it->first) && !u_access.founder)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- continue;
- }
-
- if (add)
- current_flags.insert(it->second);
- else
- current_flags.erase(it->second);
- }
- break;
- default:
- p = PrivilegeManager::FindPrivilege(flags.substr(i));
- if (p != NULL && defaultFlags[p->name])
- {
- f = defaultFlags[p->name];
- i = flags.length();
- }
-
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- {
- if (f != it->second)
- continue;
- else if (!u_access.HasPriv(it->first) && !u_access.founder)
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(_("You cannot set the \002%c\002 flag."), f);
- break;
- }
- }
- if (add)
- current_flags.insert(f);
- else
- current_flags.erase(f);
- break;
- }
- }
- }
- if (current_flags.empty())
- {
- if (current != NULL)
- {
- ci->EraseAccess(current_idx - 1);
- FOREACH_MOD(OnAccessDel, (ci, source, current));
- delete current;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
- source.Reply(_("\002%s\002 removed from the %s access list."), mask.c_str(), ci->name.c_str());
- }
- else
- {
- source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
- }
- return;
- }
-
- ServiceReference<AccessProvider> provider("AccessProvider", "access/flags");
- if (!provider)
- return;
- FlagsChanAccess *access = anope_dynamic_static_cast<FlagsChanAccess *>(provider->Create());
- access->SetMask(mask, ci);
- access->creator = source.GetNick();
- access->last_seen = current ? current->last_seen : 0;
- access->created = Anope::CurTime;
- access->flags = current_flags;
-
- if (current != NULL)
- delete current;
-
- ci->AddAccess(access);
-
- FOREACH_MOD(OnAccessAdd, (ci, source, access));
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to modify " << mask << "'s flags to " << access->AccessSerialize();
- if (p != NULL)
- {
- if (add)
- source.Reply(_("Privilege \002%s\002 added to \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
- else
- source.Reply(_("Privilege \002%s\002 removed from \002%s\002 on \002%s\002, new flags are +\002%s\002"), p->name.c_str(), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
- }
- else
- source.Reply(_("Flags for \002%s\002 on %s set to +\002%s\002"), access->Mask().c_str(), ci->name.c_str(), access->AccessSerialize().c_str());
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &arg = params.size() > 2 ? params[2] : "";
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s access list is empty."), ci->name.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Flags")).AddColumn(_("Creator")).AddColumn(_("Created"));
-
- unsigned count = 0;
- for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
- {
- const ChanAccess *access = ci->GetAccess(i);
- const Anope::string &flags = FlagsChanAccess::DetermineFlags(access);
-
- if (!arg.empty())
- {
- if (arg[0] == '+')
- {
- bool pass = true;
- for (size_t j = 1; j < arg.length(); ++j)
- if (flags.find(arg[j]) == Anope::string::npos)
- pass = false;
- if (pass == false)
- continue;
- }
- else if (!Anope::Match(access->Mask(), arg))
- continue;
- }
-
- ListFormatter::ListEntry entry;
- ++count;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = access->Mask();
- entry["Flags"] = flags;
- entry["Creator"] = access->creator;
- entry["Created"] = Anope::strftime(access->created, source.nc, true);
- list.AddEntry(entry);
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Flags list for %s"), ci->name.c_str());
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- if (count == ci->GetAccessCount())
- source.Reply(_("End of access list."));
- else
- source.Reply(_("End of access list - %d/%d entries shown."), count, ci->GetAccessCount());
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- if (!source.IsFounder(ci) && !source.HasPriv("chanserv/access/modify"))
- source.Reply(ACCESS_DENIED);
- else
- {
- ci->ClearAccess();
-
- FOREACH_MOD(OnAccessClear, (ci, source));
-
- source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
-
- bool override = !source.IsFounder(ci);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
- }
-
- return;
- }
-
- public:
- CommandCSFlags(Module *creator) : Command(creator, "chanserv/flags", 1, 4)
- {
- this->SetDesc(_("Modify the list of privileged users"));
- this->SetSyntax(_("\037channel\037 [MODIFY] \037mask\037 \037changes\037"));
- this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | +\037flags\037]"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &cmd = params.size() > 1 ? params[1] : "";
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- bool is_list = cmd.empty() || cmd.equals_ci("LIST");
- bool has_access = false;
- if (source.HasPriv("chanserv/access/modify"))
- has_access = true;
- else if (is_list && source.HasPriv("chanserv/access/list"))
- has_access = true;
- else if (is_list && source.AccessFor(ci).HasPriv("ACCESS_LIST"))
- has_access = true;
- else if (source.AccessFor(ci).HasPriv("ACCESS_CHANGE"))
- has_access = true;
-
- if (!has_access)
- source.Reply(ACCESS_DENIED);
- else if (Anope::ReadOnly && !is_list)
- source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
- else if (is_list)
- this->DoList(source, ci, params);
- else if (cmd.equals_ci("CLEAR"))
- this->DoClear(source, ci);
- else
- {
- Anope::string mask, flags;
- if (cmd.equals_ci("MODIFY"))
- {
- mask = params.size() > 2 ? params[2] : "";
- flags = params.size() > 3 ? params[3] : "";
- }
- else
- {
- mask = cmd;
- flags = params.size() > 2 ? params[2] : "";
- }
-
- this->DoModify(source, ci, mask, flags);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("%s is another way to modify the channel access list, similar to\n"
- "the XOP and ACCESS methods."), source.command.c_str());
- source.Reply(" ");
- source.Reply(_("The \002MODIFY\002 command allows you to modify the access list. If the mask is\n"
- "not already on the access list it is added, then the changes are applied.\n"
- "If the mask has no more flags, then the mask is removed from the access list.\n"
- "Additionally, you may use +* or -* to add or remove all flags, respectively. You are\n"
- "only able to modify the access list if you have the proper permission on the channel,\n"
- "and even then you can only give other people access to the equivalent of what your access is."));
- source.Reply(" ");
- source.Reply(_("The \002LIST\002 command allows you to list existing entries on the channel access list.\n"
- "If a mask is given, the mask is wildcard matched against all existing entries on the\n"
- "access list, and only those entries are returned. If a set of flags is given, only those\n"
- "on the access list with the specified flags are returned."));
- source.Reply(" ");
- source.Reply(_("The \002CLEAR\002 command clears the channel access list. This requires channel founder access."));
- source.Reply(" ");
- source.Reply(_("The available flags are:"));
-
- typedef std::multimap<char, Anope::string, ci::less> reverse_map;
- reverse_map reverse;
- for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
- reverse.insert(std::make_pair(it->second, it->first));
-
- for (reverse_map::iterator it = reverse.begin(), it_end = reverse.end(); it != it_end; ++it)
- {
- Privilege *p = PrivilegeManager::FindPrivilege(it->second);
- if (p == NULL)
- continue;
- source.Reply(" %c - %s", it->first, Language::Translate(source.nc, p->desc.c_str()));
- }
-
- return true;
- }
-};
-
-class CSFlags : public Module
-{
- FlagsAccessProvider accessprovider;
- CommandCSFlags commandcsflags;
-
- public:
- CSFlags(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- accessprovider(this), commandcsflags(this)
- {
- this->SetPermanent(true);
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- defaultFlags.clear();
-
- for (int i = 0; i < conf->CountBlock("privilege"); ++i)
- {
- Configuration::Block *priv = conf->GetBlock("privilege", i);
-
- const Anope::string &pname = priv->Get<const Anope::string>("name");
-
- Privilege *p = PrivilegeManager::FindPrivilege(pname);
- if (p == NULL)
- continue;
-
- const Anope::string &value = priv->Get<const Anope::string>("flag");
- if (value.empty())
- continue;
-
- defaultFlags[p->name] = value[0];
- }
- }
-};
-
-MODULE_INIT(CSFlags)
diff --git a/modules/commands/cs_getkey.cpp b/modules/commands/cs_getkey.cpp
deleted file mode 100644
index b9d58393d..000000000
--- a/modules/commands/cs_getkey.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSGetKey : public Command
-{
- public:
- CommandCSGetKey(Module *creator) : Command(creator, "chanserv/getkey", 1, 1)
- {
- this->SetDesc(_("Returns the key of the given channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("GETKEY") && !source.HasCommand("chanserv/getkey"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Anope::string key;
- if (!ci->c || !ci->c->GetParam("KEY", key))
- {
- source.Reply(_("Channel \002%s\002 has no key."), chan.c_str());
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("GETKEY");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
-
- source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns the key of the given channel."));
- return true;
- }
-};
-
-class CSGetKey : public Module
-{
- CommandCSGetKey commandcsgetkey;
-
- public:
- CSGetKey(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsgetkey(this)
- {
-
- }
-};
-
-MODULE_INIT(CSGetKey)
diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp
deleted file mode 100644
index 8ebcc8e40..000000000
--- a/modules/commands/cs_info.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSInfo : public Command
-{
- public:
- CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
- {
- this->SetDesc(_("Lists information about the specified registered channel"));
- this->SetSyntax(_("\037channel\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- NickCore *nc = source.nc;
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- bool has_auspex = source.HasPriv("chanserv/auspex");
- bool show_all = false;
-
- /* Should we show all fields? Only for sadmins and identified users */
- if (source.AccessFor(ci).HasPriv("INFO") || has_auspex)
- show_all = true;
-
- InfoFormatter info(nc);
-
- source.Reply(CHAN_INFO_HEADER, chan.c_str());
- if (ci->GetFounder())
- info[_("Founder")] = ci->GetFounder()->display;
-
- if (show_all && ci->GetSuccessor())
- info[_("Successor")] = ci->GetSuccessor()->display;
-
- if (!ci->desc.empty())
- info[_("Description")] = ci->desc;
-
- info[_("Registered")] = Anope::strftime(ci->time_registered, source.GetAccount());
- info[_("Last used")] = Anope::strftime(ci->last_used, source.GetAccount());
-
- if (show_all)
- {
- info[_("Ban type")] = stringify(ci->bantype);
- }
-
- FOREACH_MOD(OnChanInfo, (source, ci, info, show_all));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists information about the specified registered channel,\n"
- "including its founder, time of registration, last\n"
- "time used, and description. If the user issuing the\n"
- "command has the appropriate access for it, then the\n"
- "successor, last topic set, settings and expiration\n"
- "time will also be displayed when applicable."));
- return true;
- }
-};
-
-class CSInfo : public Module
-{
- CommandCSInfo commandcsinfo;
-
- public:
- CSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsinfo(this)
- {
-
- }
-};
-
-MODULE_INIT(CSInfo)
diff --git a/modules/commands/cs_invite.cpp b/modules/commands/cs_invite.cpp
deleted file mode 100644
index a95e25b30..000000000
--- a/modules/commands/cs_invite.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSInvite : public Command
-{
- public:
- CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
- {
- this->SetDesc(_("Invites you or an optionally specified nick into a channel"));
- this->SetSyntax(_("\037channel\037 [\037nick\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
-
- User *u = source.GetUser();
- Channel *c = Channel::Find(chan);
-
- if (!c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
-
- ChannelInfo *ci = c->ci;
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("INVITE") && !source.HasCommand("chanserv/invite"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- User *u2;
- if (params.size() == 1)
- u2 = u;
- else
- u2 = User::Find(params[1], true);
-
- if (!u2)
- {
- source.Reply(NICK_X_NOT_IN_USE, params.size() > 1 ? params[1].c_str() : source.GetNick().c_str());
- return;
- }
-
- if (c->FindUser(u2))
- {
- if (u2 == u)
- source.Reply(_("You are already in \002%s\002!"), c->name.c_str());
- else
- source.Reply(_("\002%s\002 is already in \002%s\002!"), u2->nick.c_str(), c->name.c_str());
- }
- else
- {
- bool override = !source.AccessFor(ci).HasPriv("INVITE");
-
- IRCD->SendInvite(ci->WhoSends(), c, u2);
- if (u2 != u)
- {
- source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
- u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002 by \002%s\002."), c->name.c_str(), source.GetNick().c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
- }
- else
- {
- u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells %s to invite you or an optionally specified\n"
- "nick into the given channel.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access and above\n"
- "on the channel."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CSInvite : public Module
-{
- CommandCSInvite commandcsinvite;
-
- public:
- CSInvite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsinvite(this)
- {
-
- }
-};
-
-MODULE_INIT(CSInvite)
diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp
deleted file mode 100644
index d552efb23..000000000
--- a/modules/commands/cs_kick.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSKick : public Command
-{
- public:
- CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
- {
- this->SetDesc(_("Kicks a specified nick from a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
- this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &target = params[1];
- Anope::string reason = params.size() > 2 ? params[2] : "Requested";
-
- User *u = source.GetUser();
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- Channel *c = Channel::Find(params[0]);
- User *u2 = User::Find(target, true);
-
- if (!c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
- else if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
- if (reason.length() > reasonmax)
- reason = reason.substr(0, reasonmax);
-
- Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
- signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (!u_access.HasPriv("KICK") && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- else if (u2)
- {
- AccessGroup u2_access = ci->AccessFor(u2);
- if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
- source.Reply(ACCESS_DENIED);
- else if (u2->IsProtected())
- source.Reply(ACCESS_DENIED);
- else if (!c->FindUser(u2))
- source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
- else
- {
- bool override = !u_access.HasPriv("KICK") || (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
-
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- {
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
- }
- }
- else if (u_access.HasPriv("FOUNDER"))
- {
- Anope::string mask = IRCD->NormalizeMask(target);
-
- Log(LOG_COMMAND, source, this, ci) << "for " << mask;
-
- int matched = 0, kicked = 0;
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- Entry e("", mask);
- if (e.Matches(uc->user))
- {
- ++matched;
-
- AccessGroup u2_access = ci->AccessFor(uc->user);
- if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access)
- continue;
- else if (uc->user->IsProtected())
- continue;
-
- ++kicked;
- if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- {
- reason += " (Matches " + mask + ")";
- signkickformat = signkickformat.replace_all_cs("%m", reason);
- c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
- }
- else
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
- }
- }
-
- if (matched)
- source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, mask.c_str(), c->name.c_str());
- else
- source.Reply(_("No users on %s match %s."), c->name.c_str(), mask.c_str());
- }
- else
- source.Reply(NICK_X_NOT_IN_USE, target.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Kicks a specified nick from a channel.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access\n"
- "and above on the channel. Channel founders can also specify masks."));
- return true;
- }
-};
-
-class CSKick : public Module
-{
- CommandCSKick commandcskick;
-
- public:
- CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcskick(this)
- {
-
- }
-};
-
-MODULE_INIT(CSKick)
diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp
deleted file mode 100644
index bb2fd854d..000000000
--- a/modules/commands/cs_list.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/cs_mode.h"
-
-class CommandCSList : public Command
-{
- public:
- CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
- {
- this->SetDesc(_("Lists all registered channels matching the given pattern"));
- this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string pattern = params[0];
- unsigned nchans;
- bool is_servadmin = source.HasCommand("chanserv/list");
- int count = 0, from = 0, to = 0;
- bool suspended = false, channoexpire = false;
-
- if (pattern[0] == '#')
- {
- Anope::string n1, n2;
- sepstream(pattern.substr(1), '-').GetToken(n1, 0);
- sepstream(pattern, '-').GetToken(n2, 1);
-
- try
- {
- from = convertTo<int>(n1);
- to = convertTo<int>(n2);
- }
- catch (const ConvertException &)
- {
- source.Reply(LIST_INCORRECT_RANGE);
- source.Reply(_("To search for channels starting with #, search for the channel\n"
- "name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
- return;
- }
-
- pattern = "*";
- }
-
- nchans = 0;
-
- if (is_servadmin && params.size() > 1)
- {
- Anope::string keyword;
- spacesepstream keywords(params[1]);
- while (keywords.GetToken(keyword))
- {
- if (keyword.equals_ci("SUSPENDED"))
- suspended = true;
- if (keyword.equals_ci("NOEXPIRE"))
- channoexpire = true;
- }
- }
-
- Anope::string spattern = "#" + pattern;
- unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
-
- source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Description"));
-
- Anope::map<ChannelInfo *> ordered_map;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- ordered_map[it->first] = it->second;
-
- for (Anope::map<ChannelInfo *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (!is_servadmin)
- {
- if (ci->HasExt("CS_PRIVATE") || ci->HasExt("CS_SUSPENDED"))
- continue;
- if (ci->c && ci->c->HasMode("SECRET"))
- continue;
-
- ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
- const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL;
- if (secret && secret->set)
- continue;
- }
-
- if (suspended && !ci->HasExt("CS_SUSPENDED"))
- continue;
-
- if (channoexpire && !ci->HasExt("CS_NO_EXPIRE"))
- continue;
-
- if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true) || Anope::Match(ci->desc, pattern, false, true) || Anope::Match(ci->last_topic, pattern, false, true))
- {
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax)
- {
- bool isnoexpire = false;
- if (is_servadmin && (ci->HasExt("CS_NO_EXPIRE")))
- isnoexpire = true;
-
- ListFormatter::ListEntry entry;
- entry["Name"] = (isnoexpire ? "!" : "") + ci->name;
- if (ci->HasExt("CS_SUSPENDED"))
- entry["Description"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
- else
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- }
- ++count;
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all registered channels matching the given pattern.\n"
- "Channels with the \002PRIVATE\002 option set will only be\n"
- "displayed to Services Operators with the proper access.\n"
- "Channels with the \002NOEXPIRE\002 option set will have\n"
- "a \002!\002 prefixed to the channel for Services Operators to see.\n"
- " \n"
- "Note that a preceding '#' specifies a range, channel names\n"
- "are to be written without '#'.\n"
- " \n"
- "If the SUSPENDED or NOEXPIRE options are given, only channels\n"
- "which, respectively, are SUSPENDED or have the NOEXPIRE\n"
- "flag set will be displayed. If multiple options are given,\n"
- "all channels matching at least one option will be displayed.\n"
- "Note that these options are limited to \037Services Operators\037.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002LIST *anope*\002\n"
- " Lists all registered channels with \002anope\002 in their\n"
- " names (case insensitive).\n"
- " \n"
- " \002LIST * NOEXPIRE\002\n"
- " Lists all registered channels which have been set to not expire.\n"
- " \n"
- " \002LIST #51-100\002\n"
- " Lists all registered channels within the given range (51-100)."));
-
- if (!Config->GetBlock("options")->Get<const Anope::string>("regexengine").empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<const Anope::string>("regexengine").c_str());
- }
-
- return true;
- }
-};
-
-class CommandCSSetPrivate : public Command
-{
- public:
- CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Hide channel from the LIST command"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private";
- ci->Extend<bool>("CS_PRIVATE");
- source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private";
- ci->Shrink<bool>("CS_PRIVATE");
- source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "PRIVATE");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002private\002 option for a channel."));
-
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("chanserv/list", bi, cmd))
- source.Reply(_("When \002private\002 is set, the channel will not appear in\n"
- "%s's %s command."), bi->nick.c_str(), cmd.c_str());
- return true;
- }
-};
-
-class CSList : public Module
-{
- CommandCSList commandcslist;
- CommandCSSetPrivate commandcssetprivate;
-
- SerializableExtensibleItem<bool> priv;
-
- public:
- CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcslist(this), commandcssetprivate(this), priv(this, "CS_PRIVATE")
- {
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- if (priv.HasExt(ci))
- info.AddOption(_("Private"));
- }
-};
-
-MODULE_INIT(CSList)
diff --git a/modules/commands/cs_log.cpp b/modules/commands/cs_log.cpp
deleted file mode 100644
index 8fd996f27..000000000
--- a/modules/commands/cs_log.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/cs_log.h"
-
-struct LogSettingImpl : LogSetting, Serializable
-{
- LogSettingImpl() : Serializable("LogSetting")
- {
- }
-
- ~LogSettingImpl()
- {
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci)
- {
- LogSettings *ls = ci->GetExt<LogSettings>("logsettings");
- if (ls)
- {
- LogSettings::iterator it = std::find((*ls)->begin(), (*ls)->end(), this);
- if (it != (*ls)->end())
- (*ls)->erase(it);
- }
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["ci"] << chan;
- data["service_name"] << service_name;
- data["command_service"] << command_service;
- data["command_name"] << command_name;
- data["method"] << method;
- data["extra"] << extra;
- data["creator"] << creator;
- data.SetType("created", Serialize::Data::DT_INT); data["created"] << created;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string sci;
- data["ci"] >> sci;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (ci == NULL)
- return NULL;
-
- LogSettingImpl *ls;
- if (obj)
- ls = anope_dynamic_static_cast<LogSettingImpl *>(obj);
- else
- {
- LogSettings *lsettings = ci->Require<LogSettings>("logsettings");
- ls = new LogSettingImpl();
- (*lsettings)->push_back(ls);
- }
-
- ls->chan = ci->name;
- data["service_name"] >> ls->service_name;
- data["command_service"] >> ls->command_service;
- data["command_name"] >> ls->command_name;
- data["method"] >> ls->method;
- data["extra"] >> ls->extra;
- data["creator"] >> ls->creator;
- data["created"] >> ls->created;
-
- return ls;
- }
-};
-
-struct LogSettingsImpl : LogSettings
-{
- LogSettingsImpl(Extensible *) { }
-
- ~LogSettingsImpl()
- {
- for (iterator it = (*this)->begin(); it != (*this)->end();)
- {
- LogSetting *ls = *it;
- ++it;
- delete ls;
- }
- }
-
- LogSetting *Create() anope_override
- {
- return new LogSettingImpl();
- }
-};
-
-class CommandCSLog : public Command
-{
-public:
- CommandCSLog(Module *creator) : Command(creator, "chanserv/log", 1, 4)
- {
- this->SetDesc(_("Configures channel logging settings"));
- this->SetSyntax(_("\037channel\037"));
- this->SetSyntax(_("\037channel\037 \037command\037 \037method\037 [\037status\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &channel = params[0];
-
- ChannelInfo *ci = ChannelInfo::Find(channel);
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- else if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else if (params.size() == 1)
- {
- LogSettings *ls = ci->Require<LogSettings>("logsettings");
- if (!ls || (*ls)->empty())
- source.Reply(_("There currently are no logging configurations for %s."), ci->name.c_str());
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Service")).AddColumn(_("Command")).AddColumn(_("Method")).AddColumn("");
-
- for (unsigned i = 0; i < (*ls)->size(); ++i)
- {
- const LogSetting *log = (*ls)->at(i);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Service"] = log->command_service;
- entry["Command"] = !log->command_name.empty() ? log->command_name : log->service_name;
- entry["Method"] = log->method;
- entry[""] = log->extra;
- list.AddEntry(entry);
- }
-
- source.Reply(_("Log list for %s:"), ci->name.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else if (params.size() > 2)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- LogSettings *ls = ci->Require<LogSettings>("logsettings");
- const Anope::string &command = params[1];
- const Anope::string &method = params[2];
- const Anope::string &extra = params.size() > 3 ? params[3] : "";
-
- size_t sl = command.find('/');
- if (sl == Anope::string::npos)
- {
- source.Reply(_("%s is not a valid command."), command.c_str());
- return;
- }
-
- Anope::string service = command.substr(0, sl),
- command_name = command.substr(sl + 1);
- BotInfo *bi = BotInfo::Find(service, true);
-
- Anope::string service_name;
-
- /* Allow either a command name or a service name. */
- if (bi && bi->commands.count(command_name))
- {
- /* Get service name from command */
- service_name = bi->commands[command_name].name;
- }
- else if (ServiceReference<Command>("Command", command.lower()))
- {
- /* This is the service name, don't use any specific command */
- service_name = command;
- bi = NULL;
- command_name.clear();
- }
- else
- {
- source.Reply(_("%s is not a valid command."), command.c_str());
- return;
- }
-
- if (!method.equals_ci("MESSAGE") && !method.equals_ci("NOTICE") && !method.equals_ci("MEMO"))
- {
- source.Reply(_("%s is not a valid logging method."), method.c_str());
- return;
- }
-
- for (unsigned i = 0; i < extra.length(); ++i)
- if (ModeManager::GetStatusChar(extra[i]) == 0)
- {
- source.Reply(_("%c is an unknown status mode."), extra[i]);
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("SET");
-
- for (unsigned i = (*ls)->size(); i > 0; --i)
- {
- LogSetting *log = (*ls)->at(i - 1);
-
- if (log->service_name == service_name && log->method.equals_ci(method) && command_name.equals_ci(log->command_name))
- {
- if (log->extra == extra)
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to remove logging for " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
- source.Reply(_("Logging for command %s on %s with log method %s%s%s has been removed."), !log->command_name.empty() ? log->command_name.c_str() : log->service_name.c_str(), !log->command_service.empty() ? log->command_service.c_str() : "any service", method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
- delete log;
- }
- else
- {
- log->extra = extra;
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to change logging for " << command << " to method " << method << (extra == "" ? "" : " ") << extra;
- source.Reply(_("Logging changed for command %s on %s, now using log method %s%s%s."), !log->command_name.empty() ? log->command_name.c_str() : log->service_name.c_str(), !log->command_service.empty() ? log->command_service.c_str() : "any service", method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
- }
- return;
- }
- }
-
- LogSetting *log = new LogSettingImpl();
- log->chan = ci->name;
- log->service_name = service_name;
- if (bi)
- log->command_service = bi->nick;
- log->command_name = command_name;
- log->method = method;
- log->extra = extra;
- log->created = Anope::CurTime;
- log->creator = source.GetNick();
-
- (*ls)->push_back(log);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to log " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
-
- source.Reply(_("Logging is now active for command %s on %s, using log method %s%s%s."), !command_name.empty() ? command_name.c_str() : service_name.c_str(), bi ? bi->nick.c_str() : "any service", method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("The %s command allows users to configure logging settings\n"
- "for their channel. If no parameters are given this command\n"
- "lists the current logging methods in place for this channel.\n"
- " \n"
- "Otherwise, \037command\037 must be a command name, and \037method\037\n"
- "is one of the following logging methods:\n"
- " \n"
- " MESSAGE [status], NOTICE [status], MEMO\n"
- " \n"
- "Which are used to message, notice, and memo the channel respectively.\n"
- "With MESSAGE or NOTICE you must have a service bot assigned to and joined\n"
- "to your channel. Status may be a channel status such as @ or +.\n"
- " \n"
- "To remove a logging method use the same syntax as you would to add it.\n"
- " \n"
- "Example:\n"
- " %s #anope chanserv/access MESSAGE @\n"
- " Would message any channel operators whenever someone used the\n"
- " ACCESS command on ChanServ on the channel."),
- source.command.upper().c_str(), source.command.upper().c_str());
- return true;
- }
-};
-
-class CSLog : public Module
-{
- ServiceReference<MemoServService> MSService;
- CommandCSLog commandcslog;
- ExtensibleItem<LogSettingsImpl> logsettings;
- Serialize::Type logsetting_type;
-
- struct LogDefault
- {
- Anope::string service, command, method;
- };
-
- std::vector<LogDefault> defaults;
-
- public:
- CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- MSService("MemoServService", "MemoServ"), commandcslog(this),
- logsettings(this, "logsettings"), logsetting_type("LogSetting", LogSettingImpl::Unserialize)
- {
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- defaults.clear();
-
- for (int i = 0; i < block->CountBlock("default"); ++i)
- {
- Configuration::Block *def = block->GetBlock("default", i);
-
- LogDefault ld;
-
- ld.service = def->Get<const Anope::string>("service");
- ld.command = def->Get<const Anope::string>("command");
- ld.method = def->Get<const Anope::string>("method");
-
- defaults.push_back(ld);
- }
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- if (defaults.empty())
- return;
-
- LogSettings *ls = logsettings.Require(ci);
- for (unsigned i = 0; i < defaults.size(); ++i)
- {
- LogDefault &d = defaults[i];
-
- LogSetting *log = new LogSettingImpl();
- log->chan = ci->name;
-
- if (!d.service.empty())
- {
- log->service_name = d.service.lower() + "/" + d.command.lower();
- log->command_service = d.service;
- log->command_name = d.command;
- }
- else
- log->service_name = d.command;
-
- spacesepstream sep(d.method);
- sep.GetToken(log->method);
- log->extra = sep.GetRemaining();
-
- log->created = Anope::CurTime;
- log->creator = ci->GetFounder() ? ci->GetFounder()->display : "(default)";
-
- (*ls)->push_back(log);
- }
- }
-
- void OnLog(Log *l) anope_override
- {
- if (l->type != LOG_COMMAND || l->u == NULL || l->c == NULL || l->ci == NULL || !Me || !Me->IsSynced())
- return;
-
- LogSettings *ls = logsettings.Get(l->ci);
- if (ls)
- for (unsigned i = 0; i < (*ls)->size(); ++i)
- {
- const LogSetting *log = (*ls)->at(i);
-
- /* wrong command */
- if (log->service_name != l->c->name)
- continue;
-
- /* if a command name is given check the service and the command */
- if (!log->command_name.empty())
- {
- /* wrong service (only check if not a fantasy command, though) */
- if (!l->source->c && log->command_service != l->source->service->nick)
- continue;
-
- if (!log->command_name.equals_ci(l->source->command))
- continue;
- }
-
- Anope::string buffer = l->u->nick + " used " + l->source->command.upper() + " " + l->buf.str();
-
- if (log->method.equals_ci("MEMO") && MSService && l->ci->WhoSends() != NULL)
- MSService->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true);
- else if (l->source->c)
- /* Sending a channel message or notice in response to a fantasy command */;
- else if (log->method.equals_ci("MESSAGE") && l->ci->c)
- {
- IRCD->SendPrivmsg(l->ci->WhoSends(), log->extra + l->ci->c->name, "%s", buffer.c_str());
- l->ci->WhoSends()->lastmsg = Anope::CurTime;
- }
- else if (log->method.equals_ci("NOTICE") && l->ci->c)
- IRCD->SendNotice(l->ci->WhoSends(), log->extra + l->ci->c->name, "%s", buffer.c_str());
- }
- }
-};
-
-MODULE_INIT(CSLog)
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
deleted file mode 100644
index 2acef50f7..000000000
--- a/modules/commands/cs_mode.cpp
+++ /dev/null
@@ -1,1012 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/cs_mode.h"
-
-struct ModeLockImpl : ModeLock, Serializable
-{
- ModeLockImpl() : Serializable("ModeLock")
- {
- }
-
- ~ModeLockImpl()
- {
- ChannelInfo *chan = ChannelInfo::Find(ci);
- if (chan)
- {
- ModeLocks *ml = chan->GetExt<ModeLocks>("modelocks");
- if (ml)
- ml->RemoveMLock(this);
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct ModeLocksImpl : ModeLocks
-{
- Serialize::Reference<ChannelInfo> ci;
- Serialize::Checker<ModeList> mlocks;
-
- ModeLocksImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), mlocks("ModeLock")
- {
- }
-
- ~ModeLocksImpl()
- {
- ModeList modelist;
- mlocks->swap(modelist);
- for (ModeList::iterator it = modelist.begin(); it != modelist.end(); ++it)
- {
- ModeLock *ml = *it;
- delete ml;
- }
- }
-
- bool HasMLock(ChannelMode *mode, const Anope::string &param, bool status) const anope_override
- {
- if (!mode)
- return false;
-
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- const ModeLock *ml = *it;
-
- if (ml->name == mode->name && ml->set == status && ml->param == param)
- return true;
- }
-
- return false;
- }
-
- bool SetMLock(ChannelMode *mode, bool status, const Anope::string &param, Anope::string setter, time_t created = Anope::CurTime) anope_override
- {
- if (!mode)
- return false;
-
- RemoveMLock(mode, status, param);
-
- if (setter.empty())
- setter = ci->GetFounder() ? ci->GetFounder()->display : "Unknown";
-
- ModeLock *ml = new ModeLockImpl();
- ml->ci = ci->name;
- ml->set = status;
- ml->name = mode->name;
- ml->param = param;
- ml->setter = setter;
- ml->created = created;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnMLock, MOD_RESULT, (this->ci, ml));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete ml;
- return false;
- }
-
- this->mlocks->push_back(ml);
- return true;
- }
-
- bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string &param = "") anope_override
- {
- if (!mode)
- return false;
-
- for (ModeList::iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
-
- if (m->name == mode->name)
- {
- // For list or status modes, we must check the parameter
- if (mode->type == MODE_LIST || mode->type == MODE_STATUS)
- if (m->param != param)
- continue;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnUnMLock, MOD_RESULT, (this->ci, m));
- if (MOD_RESULT == EVENT_STOP)
- break;
-
- delete m;
- return true;
- }
- }
-
- return false;
- }
-
- void RemoveMLock(ModeLock *mlock) anope_override
- {
- ModeList::iterator it = std::find(this->mlocks->begin(), this->mlocks->end(), mlock);
- if (it != this->mlocks->end())
- this->mlocks->erase(it);
- }
-
- void ClearMLock() anope_override
- {
- ModeList ml;
- this->mlocks->swap(ml);
- for (unsigned i = 0; i < ml.size(); ++i)
- delete ml[i];
- }
-
- const ModeList &GetMLock() const anope_override
- {
- return this->mlocks;
- }
-
- std::list<ModeLock *> GetModeLockList(const Anope::string &name) anope_override
- {
- std::list<ModeLock *> mlist;
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
- if (m->name == name)
- mlist.push_back(m);
- }
- return mlist;
- }
-
- const ModeLock *GetMLock(const Anope::string &mname, const Anope::string &param = "") anope_override
- {
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
-
- if (m->name == mname && m->param == param)
- return m;
- }
-
- return NULL;
- }
-
- Anope::string GetMLockAsString(bool complete) const anope_override
- {
- Anope::string pos = "+", neg = "-", params;
-
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
-
- if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
- continue;
-
- if (ml->set)
- pos += cm->mchar;
- else
- neg += cm->mchar;
-
- if (complete && ml->set && !ml->param.empty() && cm->type == MODE_PARAM)
- params += " " + ml->param;
- }
-
- if (pos.length() == 1)
- pos.clear();
- if (neg.length() == 1)
- neg.clear();
-
- return pos + neg + params;
- }
-
- void Check() anope_override
- {
- if (this->mlocks->empty())
- ci->Shrink<ModeLocks>("modelocks");
- }
-};
-
-void ModeLockImpl::Serialize(Serialize::Data &data) const
-{
- data["ci"] << this->ci;
- data["set"] << this->set;
- data["name"] << this->name;
- data["param"] << this->param;
- data["setter"] << this->setter;
- data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
-}
-
-Serializable* ModeLockImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci;
-
- data["ci"] >> sci;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- ModeLockImpl *ml;
- if (obj)
- ml = anope_dynamic_static_cast<ModeLockImpl *>(obj);
- else
- {
- ml = new ModeLockImpl();
- ml->ci = ci->name;
- }
-
- data["set"] >> ml->set;
- data["created"] >> ml->created;
- data["setter"] >> ml->setter;
- data["name"] >> ml->name;
- data["param"] >> ml->param;
-
- if (!obj)
- ci->Require<ModeLocksImpl>("modelocks")->mlocks->push_back(ml);
-
- return ml;
-}
-
-class CommandCSMode : public Command
-{
- bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm, bool self)
- {
- if (!ci || !cm || cm->type != MODE_STATUS)
- return false;
-
- return source.AccessFor(ci).HasPriv(cm->name + (self ? "ME" : ""));
- }
-
- void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- User *u = source.GetUser();
- const Anope::string &subcommand = params[2];
- const Anope::string &param = params.size() > 3 ? params[3] : "";
-
- bool override = !source.AccessFor(ci).HasPriv("MODE");
- ModeLocks *modelocks = ci->Require<ModeLocks>("modelocks");
-
- if (Anope::ReadOnly && !subcommand.equals_ci("LIST"))
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if ((subcommand.equals_ci("ADD") || subcommand.equals_ci("SET")) && !param.empty())
- {
- /* If setting, remove the existing locks */
- if (subcommand.equals_ci("SET"))
- {
- const ModeLocks::ModeList mlocks = modelocks->GetMLock();
- for (ModeLocks::ModeList::const_iterator it = mlocks.begin(); it != mlocks.end(); ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (cm && cm->CanSet(source.GetUser()))
- modelocks->RemoveMLock(cm, ml->set, ml->param);
- }
- }
-
- spacesepstream sep(param);
- Anope::string modes;
-
- sep.GetToken(modes);
-
- Anope::string pos = "+", neg = "-", pos_params, neg_params;
-
- int adding = 1;
- bool needreply = true;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- default:
- needreply = false;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm)
- {
- source.Reply(_("Unknown mode character %c ignored."), modes[i]);
- break;
- }
- else if (u && !cm->CanSet(u))
- {
- source.Reply(_("You may not (un)lock mode %c."), modes[i]);
- break;
- }
-
- Anope::string mode_param;
- if (((cm->type == MODE_STATUS || cm->type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
- source.Reply(_("Missing parameter for mode %c."), cm->mchar);
- else if (cm->type == MODE_LIST && ci->c && IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) >= IRCD->GetMaxListFor(ci->c))
- source.Reply(_("List for mode %c is full."), cm->mchar);
- else if (modelocks->GetMLock().size() >= Config->GetModule(this->owner)->Get<unsigned>("max", "32"))
- source.Reply(_("The mode lock list of \002%s\002 is full."), ci->name.c_str());
- else
- {
- modelocks->SetMLock(cm, adding, mode_param, source.GetNick());
-
- if (adding)
- {
- pos += cm->mchar;
- if (!mode_param.empty())
- pos_params += " " + mode_param;
- }
- else
- {
- neg += cm->mchar;
- if (!mode_param.empty())
- neg_params += " " + mode_param;
- }
- }
- }
- }
-
- if (pos == "+")
- pos.clear();
- if (neg == "-")
- neg.clear();
- Anope::string reply = pos + neg + pos_params + neg_params;
-
- if (!reply.empty())
- {
- source.Reply(_("%s locked on %s."), reply.c_str(), ci->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << reply;
- }
- else if (needreply)
- source.Reply(_("Nothing to do."));
-
- if (ci->c)
- ci->c->CheckModes();
- }
- else if (subcommand.equals_ci("DEL") && !param.empty())
- {
- spacesepstream sep(param);
- Anope::string modes;
-
- sep.GetToken(modes);
-
- int adding = 1;
- bool needreply = true;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- default:
- needreply = false;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm)
- {
- source.Reply(_("Unknown mode character %c ignored."), modes[i]);
- break;
- }
- else if (u && !cm->CanSet(u))
- {
- source.Reply(_("You may not (un)lock mode %c."), modes[i]);
- break;
- }
-
- Anope::string mode_param;
- if (cm->type != MODE_REGULAR && !sep.GetToken(mode_param))
- source.Reply(_("Missing parameter for mode %c."), cm->mchar);
- else
- {
- if (modelocks->RemoveMLock(cm, adding, mode_param))
- {
- if (!mode_param.empty())
- mode_param = " " + mode_param;
- source.Reply(_("%c%c%s has been unlocked from %s."), adding == 1 ? '+' : '-', cm->mchar, mode_param.c_str(), ci->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to unlock " << (adding ? '+' : '-') << cm->mchar << mode_param;
- }
- else
- source.Reply(_("%c%c is not locked on %s."), adding == 1 ? '+' : '-', cm->mchar, ci->name.c_str());
- }
- }
- }
-
- if (needreply)
- source.Reply(_("Nothing to do."));
- }
- else if (subcommand.equals_ci("LIST"))
- {
- const ModeLocks::ModeList mlocks = modelocks->GetMLock();
- if (mlocks.empty())
- {
- source.Reply(_("Channel %s has no mode locks."), ci->name.c_str());
- }
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mode")).AddColumn(_("Param")).AddColumn(_("Creator")).AddColumn(_("Created"));
-
- for (ModeLocks::ModeList::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (!cm)
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Mode"] = Anope::printf("%c%c", ml->set ? '+' : '-', cm->mchar);
- entry["Param"] = ml->param;
- entry["Creator"] = ml->setter;
- entry["Created"] = Anope::strftime(ml->created, NULL, true);
- list.AddEntry(entry);
- }
-
- source.Reply(_("Mode locks for %s:"), ci->name.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else
- this->OnSyntaxError(source, subcommand);
- }
-
- void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- User *u = source.GetUser();
-
- bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/administration");
- bool can_override = source.HasPriv("chanserv/administration");
-
- spacesepstream sep(params.size() > 3 ? params[3] : "");
- Anope::string modes = params[2], param;
-
- bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/administration");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2] << (params.size() > 3 ? " " + params[3] : "");
-
- int adding = -1;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- case '*':
- if (adding == -1 || !has_access)
- break;
- for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j)
- {
- ChannelMode *cm = ModeManager::GetChannelModes()[j];
-
- if (!u || cm->CanSet(u) || can_override)
- {
- if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM))
- {
- if (adding)
- ci->c->SetMode(NULL, cm);
- else
- ci->c->RemoveMode(NULL, cm);
- }
- }
- }
- break;
- default:
- if (adding == -1)
- break;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm || (u && !cm->CanSet(u) && !can_override))
- continue;
- switch (cm->type)
- {
- case MODE_REGULAR:
- if (!has_access)
- break;
- if (adding)
- ci->c->SetMode(NULL, cm);
- else
- ci->c->RemoveMode(NULL, cm);
- break;
- case MODE_PARAM:
- if (!has_access)
- break;
- if (adding && !sep.GetToken(param))
- break;
- if (adding)
- ci->c->SetMode(NULL, cm, param);
- else
- ci->c->RemoveMode(NULL, cm);
- break;
- case MODE_STATUS:
- {
- if (!sep.GetToken(param))
- param = source.GetNick();
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (param.find_first_of("*?") != Anope::string::npos)
- {
- if (!this->CanSet(source, ci, cm, false) && !can_override)
- {
- source.Reply(_("You do not have access to set mode %c."), cm->mchar);
- break;
- }
-
- for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- AccessGroup targ_access = ci->AccessFor(uc->user);
-
- if (uc->user->IsProtected() || (ci->HasExt("PEACE") && targ_access >= u_access && !can_override))
- {
- source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
- continue;
- }
-
- if (Anope::Match(uc->user->GetMask(), param))
- {
- if (adding)
- ci->c->SetMode(NULL, cm, uc->user->GetUID());
- else
- ci->c->RemoveMode(NULL, cm, uc->user->GetUID());
- }
- }
- }
- else
- {
- User *target = User::Find(param, true);
- if (target == NULL)
- {
- source.Reply(NICK_X_NOT_IN_USE, param.c_str());
- break;
- }
-
- if (!this->CanSet(source, ci, cm, source.GetUser() == target) && !can_override)
- {
- source.Reply(_("You do not have access to set mode %c."), cm->mchar);
- break;
- }
-
- if (source.GetUser() != target)
- {
- AccessGroup targ_access = ci->AccessFor(target);
- if (ci->HasExt("PEACE") && targ_access >= u_access && !can_override)
- {
- source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
- break;
- }
- else if (target->IsProtected())
- {
- source.Reply(ACCESS_DENIED);
- break;
- }
- }
-
- if (adding)
- ci->c->SetMode(NULL, cm, target->GetUID());
- else
- ci->c->RemoveMode(NULL, cm, target->GetUID());
- }
- break;
- }
- case MODE_LIST:
- if (!has_access)
- break;
- if (!sep.GetToken(param))
- break;
- if (adding)
- {
- if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
- ci->c->SetMode(NULL, cm, param);
- }
- else
- {
- std::vector<Anope::string> v = ci->c->GetModeList(cm->name);
- for (unsigned j = 0; j < v.size(); ++j)
- if (Anope::Match(v[j], param))
- ci->c->RemoveMode(NULL, cm, v[j]);
- }
- }
- }
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- std::vector<Anope::string> new_params;
- new_params.push_back(params[0]);
- new_params.push_back("SET");
- new_params.push_back("-*");
- this->DoSet(source, ci, new_params);
- return;
- }
-
- ChannelMode *cm;
- if (param.length() == 1)
- cm = ModeManager::FindChannelModeByChar(param[0]);
- else
- {
- cm = ModeManager::FindChannelModeByName(param.upper());
- if (!cm)
- cm = ModeManager::FindChannelModeByName(param.substr(0, param.length() - 1).upper());
- }
-
- if (!cm)
- {
- source.Reply(_("There is no such mode %s."), param.c_str());
- return;
- }
-
- if (cm->type != MODE_STATUS && cm->type != MODE_LIST)
- {
- source.Reply(_("Mode %s is not a status or list mode."), param.c_str());
- return;
- }
-
- std::vector<Anope::string> new_params;
- new_params.push_back(params[0]);
- new_params.push_back("SET");
- new_params.push_back("-" + stringify(cm->mchar));
- new_params.push_back("*");
- this->DoSet(source, ci, new_params);
- }
-
- public:
- CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 2, 4)
- {
- this->SetDesc(_("Control modes and mode locks on a channel"));
- this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|SET|LIST} [\037what\037]"));
- this->SetSyntax(_("\037channel\037 SET \037modes\037"));
- this->SetSyntax(_("\037channel\037 CLEAR [\037what\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcommand = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!ci)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (subcommand.equals_ci("LOCK") && params.size() > 2)
- {
- if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- this->DoLock(source, ci, params);
- }
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
- else if (subcommand.equals_ci("SET") && params.size() > 2)
- this->DoSet(source, ci, params);
- else if (subcommand.equals_ci("CLEAR"))
- {
- if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- this->DoClear(source, ci, params);
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Mainly controls mode locks and mode access (which is different from channel access)\n"
- "on a channel.\n"
- " \n"
- "The \002%s LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n"
- "If a mode is locked on or off, services will not allow that mode to be changed. The \002SET\002\n"
- "command will clear all existing mode locks and set the new one given, while \002ADD\002 and \002DEL\002\n"
- "modify the existing mode lock.\n"
- "Example:\n"
- " \002MODE #channel LOCK ADD +bmnt *!*@*aol*\002\n"
- " \n"
- "The \002%s SET\002 command allows you to set modes through services. Wildcards * and ? may\n"
- "be given as parameters for list and status modes.\n"
- "Example:\n"
- " \002MODE #channel SET +v *\002\n"
- " Sets voice status to all users in the channel.\n"
- " \n"
- " \002MODE #channel SET -b ~c:*\n"
- " Clears all extended bans that start with ~c:\n"
- " \n"
- "The \002%s CLEAR\002 command is an easy way to clear modes on a channel. \037what\037 may be\n"
- "any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If \037what\037\n"
- "is not given then all basic modes are removed."),
- source.command.upper().c_str(), source.command.upper().c_str(), source.command.upper().c_str());
- return true;
- }
-};
-
-static Anope::map<std::pair<bool, Anope::string> > modes;
-
-class CommandCSModes : public Command
-{
- public:
- CommandCSModes(Module *creator) : Command(creator, "chanserv/modes", 1, 2)
- {
- this->SetSyntax(_("\037channel\037 [\037user\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser(),
- *targ = params.size() > 1 ? User::Find(params[1], true) : u;
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!targ)
- {
- if (params.size() > 1)
- source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
- return;
- }
-
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
- else if (!ci->c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci), targ_access = ci->AccessFor(targ);
- const std::pair<bool, Anope::string> &m = modes[source.command];
-
- bool can_override = source.HasPriv("chanserv/administration");
- bool override = false;
-
- if (m.second.empty())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (u == targ ? !u_access.HasPriv(m.second + "ME") : !u_access.HasPriv(m.second))
- {
- if (!can_override)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (!override && !m.first && u != targ && (targ->IsProtected() || (ci->HasExt("PEACE") && targ_access >= u_access)))
- {
- if (!can_override)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (!ci->c->FindUser(targ))
- {
- source.Reply(NICK_X_NOT_ON_CHAN, targ->nick.c_str(), ci->name.c_str());
- return;
- }
-
- if (m.first)
- ci->c->SetMode(NULL, m.second, targ->GetUID());
- else
- ci->c->RemoveMode(NULL, m.second, targ->GetUID());
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "on " << targ->nick;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- const std::pair<bool, Anope::string> &m = modes[source.command];
- if (!m.second.empty())
- {
- if (m.first)
- return Anope::printf(Language::Translate(source.GetAccount(), _("Gives you or the specified nick %s status on a channel")), m.second.c_str());
- else
- return Anope::printf(Language::Translate(source.GetAccount(), _("Removes %s status from you or the specified nick on a channel")), m.second.c_str());
- }
- else
- return "";
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- const std::pair<bool, Anope::string> &m = modes[source.command];
- if (m.second.empty())
- return false;
-
- this->SendSyntax(source);
- source.Reply(" ");
- if (m.first)
- source.Reply(_("Gives %s status to the selected nick on a channel. If \037nick\037 is\n"
- "not given, it will %s you."),
- m.second.upper().c_str(), m.second.lower().c_str());
- else
- source.Reply(_("Removes %s status from the selected nick on a channel. If \037nick\037 is\n"
- "not given, it will de%s you."),
- m.second.upper().c_str(), m.second.lower().c_str());
- source.Reply(" ");
- source.Reply(_("You must have the %s(ME) privilege on the channel to use this command."), m.second.upper().c_str());
-
- return true;
- }
-};
-
-class CSMode : public Module
-{
- CommandCSMode commandcsmode;
- CommandCSModes commandcsmodes;
- ExtensibleItem<ModeLocksImpl> modelocks;
- Serialize::Type modelocks_type;
-
- public:
- CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsmode(this), commandcsmodes(this),
- modelocks(this, "modelocks"),
- modelocks_type("ModeLock", ModeLockImpl::Unserialize)
- {
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- modes.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- const Anope::string &cname = block->Get<const Anope::string>("name"),
- &cmd = block->Get<const Anope::string>("command");
-
- if (cname.empty() || cmd != "chanserv/modes")
- continue;
-
- const Anope::string &set = block->Get<const Anope::string>("set"),
- &unset = block->Get<const Anope::string>("unset");
-
- if (set.empty() && unset.empty())
- continue;
-
- modes[cname] = std::make_pair(!set.empty(), !set.empty() ? set : unset);
- }
- }
-
- void OnCheckModes(Reference<Channel> &c) anope_override
- {
- if (!c || !c->ci)
- return;
-
- ModeLocks *locks = modelocks.Get(c->ci);
- if (locks)
- for (ModeLocks::ModeList::const_iterator it = locks->GetMLock().begin(), it_end = locks->GetMLock().end(); it != it_end; ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (!cm)
- continue;
-
- if (cm->type == MODE_REGULAR)
- {
- if (!c->HasMode(cm->name) && ml->set)
- c->SetMode(NULL, cm, "", false);
- else if (c->HasMode(cm->name) && !ml->set)
- c->RemoveMode(NULL, cm, "", false);
- }
- else if (cm->type == MODE_PARAM)
- {
- /* If the channel doesn't have the mode, or it does and it isn't set correctly */
- if (ml->set)
- {
- Anope::string param;
- c->GetParam(cm->name, param);
-
- if (!c->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param)))
- c->SetMode(NULL, cm, ml->param, false);
- }
- else
- {
- if (c->HasMode(cm->name))
- c->RemoveMode(NULL, cm, "", false);
- }
-
- }
- else if (cm->type == MODE_LIST || cm->type == MODE_STATUS)
- {
- if (ml->set)
- c->SetMode(NULL, cm, ml->param, false);
- else
- c->RemoveMode(NULL, cm, ml->param, false);
- }
- }
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- ModeLocks *ml = modelocks.Require(ci);
- Anope::string mlock;
- spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("mlock", "+nt"));
- if (sep.GetToken(mlock))
- {
- bool add = true;
- for (unsigned i = 0; i < mlock.length(); ++i)
- {
- if (mlock[i] == '+')
- {
- add = true;
- continue;
- }
-
- if (mlock[i] == '-')
- {
- add = false;
- continue;
- }
-
- ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]);
- if (!cm)
- continue;
-
- Anope::string param;
- if (cm->type == MODE_PARAM)
- {
- ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
- if (add || !cmp->minus_no_arg)
- {
- sep.GetToken(param);
- if (param.empty() || !cmp->IsValid(param))
- continue;
- }
- }
- else if (cm->type != MODE_REGULAR)
- {
- sep.GetToken(param);
- if (param.empty())
- continue;
- }
-
- ml->SetMLock(cm, add, param);
- }
- }
- ml->Check();
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- if (!show_hidden)
- return;
-
- ModeLocks *ml = modelocks.Get(ci);
- if (ml)
- info[_("Mode lock")] = ml->GetMLockAsString(true);
- }
-};
-
-MODULE_INIT(CSMode)
diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp
deleted file mode 100644
index 8b73c9f06..000000000
--- a/modules/commands/cs_register.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSRegister : public Command
-{
- public:
- CommandCSRegister(Module *creator) : Command(creator, "chanserv/register", 1, 2)
- {
- this->SetDesc(_("Register a channel"));
- this->SetSyntax(_("\037channel\037 [\037description\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &chdesc = params.size() > 1 ? params[1] : "";
- unsigned maxregistered = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
-
- User *u = source.GetUser();
- NickCore *nc = source.nc;
- Channel *c = Channel::Find(params[0]);
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (Anope::ReadOnly)
- source.Reply(_("Sorry, channel registration is temporarily disabled."));
- else if (nc->HasExt("UNCONFIRMED"))
- source.Reply(_("You must confirm your account before you can register a channel."));
- else if (chan[0] == '&')
- source.Reply(_("Local channels cannot be registered."));
- else if (chan[0] != '#')
- source.Reply(CHAN_SYMBOL_REQUIRED);
- else if (!IRCD->IsChannelValid(chan))
- source.Reply(CHAN_X_INVALID, chan.c_str());
- else if (!c && u)
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- else if (ci)
- source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
- else if (c && u && !c->HasUserStatus(u, "OP"))
- source.Reply(_("You must be a channel operator to register the channel."));
- else if (maxregistered && nc->channelcount >= maxregistered && !source.HasPriv("chanserv/no-register-limit"))
- source.Reply(nc->channelcount > maxregistered ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, maxregistered);
- else
- {
- ci = new ChannelInfo(chan);
- ci->SetFounder(nc);
- ci->desc = chdesc;
-
- if (c && !c->topic.empty())
- {
- ci->last_topic = c->topic;
- ci->last_topic_setter = c->topic_setter;
- ci->last_topic_time = c->topic_time;
- }
- else
- ci->last_topic_setter = source.service->nick;
-
- Log(LOG_COMMAND, source, this, ci);
- source.Reply(_("Channel \002%s\002 registered under your account: %s"), chan.c_str(), nc->display.c_str());
-
- FOREACH_MOD(OnChanRegistered, (ci));
-
- /* Implement new mode lock */
- if (c)
- {
- c->CheckModes();
- if (u)
- c->SetCorrectModes(u, true);
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Registers a channel in the %s database. In order\n"
- "to use this command, you must first be a channel operator\n"
- "on the channel you're trying to register.\n"
- "The description, which is optional, is a\n"
- "general description of the channel's purpose.\n"
- " \n"
- "When you register a channel, you are recorded as the\n"
- "\"founder\" of the channel. The channel founder is allowed\n"
- "to change all of the channel settings for the channel;\n"
- "%s will also automatically give the founder\n"
- "channel-operator privileges when s/he enters the channel."),
- source.service->nick.c_str(), source.service->nick.c_str());
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("chanserv/access", bi, cmd))
- source.Reply(_(" \n"
- "See the \002%s\002 command (\002%s%s HELP ACCESS\002) for\n"
- "information on giving a subset of these privileges to\n"
- "other channel users.\n"), cmd.c_str(), Config->StrictPrivmsg.c_str(), bi->nick.c_str());
- source.Reply(_(" \n"
- "NOTICE: In order to register a channel, you must have\n"
- "first registered your nickname."));
- return true;
- }
-};
-
-
-class CSRegister : public Module
-{
- CommandCSRegister commandcsregister;
-
- public:
- CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsregister(this)
- {
- }
-};
-
-MODULE_INIT(CSRegister)
diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp
deleted file mode 100644
index 80bc8e548..000000000
--- a/modules/commands/cs_seen.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/* cs_seen: provides a seen command by tracking all users
- *
- * (C) 2003-2016 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"
-
-enum TypeInfo
-{
- NEW, NICK_TO, NICK_FROM, JOIN, PART, QUIT, KICK
-};
-
-static bool simple;
-struct SeenInfo;
-static SeenInfo *FindInfo(const Anope::string &nick);
-typedef Anope::hash_map<SeenInfo *> database_map;
-database_map database;
-
-struct SeenInfo : Serializable
-{
- Anope::string nick;
- Anope::string vhost;
- TypeInfo type;
- Anope::string nick2; // for nickchanges and kicks
- Anope::string channel; // for join/part/kick
- Anope::string message; // for part/kick/quit
- time_t last; // the time when the user was last seen
-
- SeenInfo() : Serializable("SeenInfo")
- {
- }
-
- ~SeenInfo()
- {
- database_map::iterator iter = database.find(nick);
- if (iter != database.end() && iter->second == this)
- database.erase(iter);
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["nick"] << nick;
- data["vhost"] << vhost;
- data["type"] << type;
- data["nick2"] << nick2;
- data["channel"] << channel;
- data["message"] << message;
- data.SetType("last", Serialize::Data::DT_INT); data["last"] << last;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snick;
-
- data["nick"] >> snick;
-
- SeenInfo *s;
- if (obj)
- s = anope_dynamic_static_cast<SeenInfo *>(obj);
- else
- {
- SeenInfo* &info = database[snick];
- if (!info)
- info = new SeenInfo();
- s = info;
- }
-
- s->nick = snick;
- data["vhost"] >> s->vhost;
- unsigned int n;
- data["type"] >> n;
- s->type = static_cast<TypeInfo>(n);
- data["nick2"] >> s->nick2;
- data["channel"] >> s->channel;
- data["message"] >> s->message;
- data["last"] >> s->last;
-
- if (!obj)
- database[s->nick] = s;
- return s;
- }
-};
-
-static SeenInfo *FindInfo(const Anope::string &nick)
-{
- database_map::iterator iter = database.find(nick);
- if (iter != database.end())
- return iter->second;
- return NULL;
-}
-
-static bool ShouldHide(const Anope::string &channel, User *u)
-{
- Channel *targetchan = Channel::Find(channel);
- const ChannelInfo *targetchan_ci = targetchan ? *targetchan->ci : ChannelInfo::Find(channel);
-
- if (targetchan && targetchan->HasMode("SECRET"))
- return true;
- else if (targetchan_ci && targetchan_ci->HasExt("CS_PRIVATE"))
- return true;
- else if (u && u->HasMode("PRIV"))
- return true;
- return false;
-}
-
-class CommandOSSeen : public Command
-{
- public:
- CommandOSSeen(Module *creator) : Command(creator, "operserv/seen", 1, 2)
- {
- this->SetDesc(_("Statistics and maintenance for seen data"));
- this->SetSyntax("STATS");
- this->SetSyntax(_("CLEAR \037time\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params[0].equals_ci("STATS"))
- {
- size_t mem_counter;
- mem_counter = sizeof(database_map);
- for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end; ++it)
- {
- mem_counter += (5 * sizeof(Anope::string)) + sizeof(TypeInfo) + sizeof(time_t);
- mem_counter += it->first.capacity();
- mem_counter += it->second->vhost.capacity();
- mem_counter += it->second->nick2.capacity();
- mem_counter += it->second->channel.capacity();
- mem_counter += it->second->message.capacity();
- }
- source.Reply(_("%lu nicks are stored in the database, using %.2Lf kB of memory."), database.size(), static_cast<long double>(mem_counter) / 1024);
- }
- else if (params[0].equals_ci("CLEAR"))
- {
- time_t time = 0;
- if ((params.size() < 2) || (0 >= (time = Anope::DoTime(params[1]))))
- {
- this->OnSyntaxError(source, params[0]);
- return;
- }
- time = Anope::CurTime - time;
- database_map::iterator buf;
- size_t counter = 0;
- for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
- {
- buf = it;
- ++it;
- if (time < buf->second->last)
- {
- Log(LOG_DEBUG) << buf->first << " was last seen " << Anope::strftime(buf->second->last) << ", deleting entry";
- delete buf->second;
- counter++;
- }
- }
- Log(LOG_ADMIN, source, this) << "CLEAR and removed " << counter << " nicks that were added after " << Anope::strftime(time, NULL, true);
- source.Reply(_("Database cleared, removed %lu nicks that were added after %s."), counter, Anope::strftime(time, source.nc, true).c_str());
- }
- else
- this->SendSyntax(source);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("The \002STATS\002 command prints out statistics about stored nicks and memory usage."));
- source.Reply(_("The \002CLEAR\002 command lets you clean the database by removing all entries from the\n"
- "database that were added within \037time\037.\n"
- " \n"
- "Example:\n"
- " %s CLEAR 30m\n"
- " Will remove all entries that were added within the last 30 minutes."), source.command.c_str());
- return true;
- }
-};
-
-class CommandSeen : public Command
-{
- void SimpleSeen(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (!source.c || !source.c->ci)
- {
- if (source.IsOper())
- source.Reply("Seen in simple mode is designed as a fantasy command only!");
- return;
- }
-
- BotInfo *bi = BotInfo::Find(params[0], true);
- if (bi)
- {
- if (bi == source.c->ci->bi)
- source.Reply(_("You found me, %s!"), source.GetNick().c_str());
- else
- source.Reply(_("%s is a network service."), bi->nick.c_str());
- return;
- }
-
- NickAlias *na = NickAlias::Find(params[0]);
- if (!na)
- {
- source.Reply(_("I don't know who %s is."), params[0].c_str());
- return;
- }
-
- if (source.GetAccount() == na->nc)
- {
- source.Reply(_("Looking for yourself, eh %s?"), source.GetNick().c_str());
- return;
- }
-
- User *target = User::Find(params[0], true);
-
- if (target && source.c->FindUser(target))
- {
- source.Reply(_("%s is on the channel right now!"), target->nick.c_str());
- return;
- }
-
- for (Channel::ChanUserList::const_iterator it = source.c->users.begin(), it_end = source.c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *u = uc->user;
-
- if (u->Account() == na->nc)
- {
- source.Reply(_("%s is on the channel right now (as %s)!"), params[0].c_str(), u->nick.c_str());
- return;
- }
- }
-
- AccessGroup ag = source.c->ci->AccessFor(na->nc);
- time_t last = 0;
- for (unsigned int i = 0; i < ag.paths.size(); ++i)
- {
- ChanAccess::Path &p = ag.paths[i];
-
- if (p.empty())
- continue;
-
- ChanAccess *a = p[p.size() - 1];
-
- if (a->GetAccount() == na->nc && a->last_seen > last)
- last = a->last_seen;
- }
-
- if (last > Anope::CurTime || !last)
- source.Reply(_("I've never seen %s on this channel."), na->nick.c_str());
- else
- source.Reply(_("%s was last seen here %s ago."), na->nick.c_str(), Anope::Duration(Anope::CurTime - last, source.GetAccount()).c_str());
- }
-
- public:
- CommandSeen(Module *creator) : Command(creator, "chanserv/seen", 1, 2)
- {
- this->SetDesc(_("Tells you about the last time a user was seen"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &target = params[0];
-
- if (simple)
- return this->SimpleSeen(source, params);
-
- if (target.length() > Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"))
- {
- source.Reply(_("Nick too long, max length is %u characters."), Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"));
- return;
- }
-
- if (BotInfo::Find(target, true) != NULL)
- {
- source.Reply(_("%s is a client on services."), target.c_str());
- return;
- }
-
- if (target.equals_ci(source.GetNick()))
- {
- source.Reply(_("You might see yourself in the mirror, %s."), source.GetNick().c_str());
- return;
- }
-
- SeenInfo *info = FindInfo(target);
- if (!info)
- {
- source.Reply(_("Sorry, I have not seen %s."), target.c_str());
- return;
- }
-
- User *u2 = User::Find(target, true);
- Anope::string onlinestatus;
- if (u2)
- onlinestatus = ".";
- else
- onlinestatus = Anope::printf(_(" but %s mysteriously dematerialized."), target.c_str());
-
- Anope::string timebuf = Anope::Duration(Anope::CurTime - info->last, source.nc);
- Anope::string timebuf2 = Anope::strftime(info->last, source.nc, true);
-
- if (info->type == NEW)
- {
- source.Reply(_("%s (%s) was last seen connecting %s ago (%s)%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), timebuf2.c_str(), onlinestatus.c_str());
- }
- else if (info->type == NICK_TO)
- {
- u2 = User::Find(info->nick2, true);
- if (u2)
- onlinestatus = Anope::printf( _(". %s is still online."), u2->nick.c_str());
- else
- onlinestatus = Anope::printf(_(", but %s mysteriously dematerialized."), info->nick2.c_str());
-
- source.Reply(_("%s (%s) was last seen changing nick to %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->nick2.c_str(), timebuf.c_str(), onlinestatus.c_str());
- }
- else if (info->type == NICK_FROM)
- {
- source.Reply(_("%s (%s) was last seen changing nick from %s to %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->nick2.c_str(), target.c_str(), timebuf.c_str(), onlinestatus.c_str());
- }
- else if (info->type == JOIN)
- {
- if (ShouldHide(info->channel, u2))
- source.Reply(_("%s (%s) was last seen joining a secret channel %s ago%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), onlinestatus.c_str());
- else
- source.Reply(_("%s (%s) was last seen joining %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->channel.c_str(), timebuf.c_str(), onlinestatus.c_str());
- }
- else if (info->type == PART)
- {
- if (ShouldHide(info->channel, u2))
- source.Reply(_("%s (%s) was last seen parting a secret channel %s ago%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), onlinestatus.c_str());
- else
- source.Reply(_("%s (%s) was last seen parting %s %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->channel.c_str(), timebuf.c_str(), onlinestatus.c_str());
- }
- else if (info->type == QUIT)
- {
- source.Reply(_("%s (%s) was last seen quitting (%s) %s ago (%s)."),
- target.c_str(), info->vhost.c_str(), info->message.c_str(), timebuf.c_str(), timebuf2.c_str());
- }
- else if (info->type == KICK)
- {
- if (ShouldHide(info->channel, u2))
- source.Reply(_("%s (%s) was kicked from a secret channel %s ago%s"),
- target.c_str(), info->vhost.c_str(), timebuf.c_str(), onlinestatus.c_str());
- else
- source.Reply(_("%s (%s) was kicked from %s (\"%s\") %s ago%s"),
- target.c_str(), info->vhost.c_str(), info->channel.c_str(), info->message.c_str(), timebuf.c_str(), onlinestatus.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Checks for the last time \037nick\037 was seen joining, leaving,\n"
- "or changing nick on the network and tells you when and, depending\n"
- "on channel or user settings, where it was."));
- return true;
- }
-};
-
-class CSSeen : public Module
-{
- Serialize::Type seeninfo_type;
- CommandSeen commandseen;
- CommandOSSeen commandosseen;
- public:
- CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), seeninfo_type("SeenInfo", SeenInfo::Unserialize), commandseen(this), commandosseen(this)
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- simple = conf->GetModule(this)->Get<bool>("simple");
- }
-
- void OnExpireTick() anope_override
- {
- size_t previous_size = database.size();
- time_t purgetime = Config->GetModule(this)->Get<time_t>("purgetime");
- if (!purgetime)
- purgetime = Anope::DoTime("30d");
- for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
- {
- database_map::iterator cur = it;
- ++it;
-
- if ((Anope::CurTime - cur->second->last) > purgetime)
- {
- Log(LOG_DEBUG) << cur->first << " was last seen " << Anope::strftime(cur->second->last) << ", purging entries";
- delete cur->second;
- }
- }
- Log(LOG_DEBUG) << "cs_seen: Purged database, checked " << previous_size << " nicks and removed " << (previous_size - database.size()) << " old entries.";
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (!u->Quitting())
- UpdateUser(u, NEW, u->nick, "", "", "");
- }
-
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
- {
- UpdateUser(u, NICK_TO, oldnick, u->nick, "", "");
- UpdateUser(u, NICK_FROM, u->nick, oldnick, "", "");
- }
-
- void OnUserQuit(User *u, const Anope::string &msg) anope_override
- {
- UpdateUser(u, QUIT, u->nick, "", "", msg);
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- UpdateUser(u, JOIN, u->nick, "", c->name, "");
- }
-
- void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) anope_override
- {
- UpdateUser(u, PART, u->nick, "", channel, msg);
- }
-
- void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &msg) anope_override
- {
- UpdateUser(cu->user, KICK, cu->user->nick, source.GetSource(), cu->chan->name, msg);
- }
-
- private:
- void UpdateUser(const User *u, const TypeInfo Type, const Anope::string &nick, const Anope::string &nick2, const Anope::string &channel, const Anope::string &message)
- {
- if (simple || !u->server->IsSynced())
- return;
-
- SeenInfo* &info = database[nick];
- if (!info)
- info = new SeenInfo();
- info->nick = nick;
- info->vhost = u->GetVIdent() + "@" + u->GetDisplayedHost();
- info->type = Type;
- info->last = Anope::CurTime;
- info->nick2 = nick2;
- info->channel = channel;
- info->message = message;
- }
-};
-
-MODULE_INIT(CSSeen)
diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp
deleted file mode 100644
index fb58f9efd..000000000
--- a/modules/commands/cs_set.cpp
+++ /dev/null
@@ -1,1356 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/cs_mode.h"
-
-class CommandCSSet : public Command
-{
- public:
- CommandCSSet(Module *creator) : Command(creator, "chanserv/set", 2, 3)
- {
- this->SetDesc(_("Set channel options and information"));
- this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows the channel founder to set various channel options\n"
- "and other information.\n"
- " \n"
- "Available options:"));
- Anope::string this_name = source.command;
- bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
- hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> c("Command", info.name);
-
- // XXX dup
- if (!c)
- continue;
- else if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
- continue;
- else if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- source.command = it->first;
- c->OnServHelp(source);
- }
- }
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
- "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
- return true;
- }
-};
-
-class CommandCSSetAutoOp : public Command
-{
- public:
- CommandCSSetAutoOp(Module *creator, const Anope::string &cname = "chanserv/set/autoop") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Should services automatically give status to users"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable autoop";
- ci->Shrink<bool>("NOAUTOOP");
- source.Reply(_("Services will now automatically give modes to users in \002%s\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable autoop";
- ci->Extend<bool>("NOAUTOOP");
- source.Reply(_("Services will no longer automatically give modes to users in \002%s\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "AUTOOP");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables %s's autoop feature for a\n"
- "channel. When disabled, users who join the channel will\n"
- "not automatically gain any status from %s."), source.service->nick.c_str(),
- source.service->nick.c_str(), this->name.c_str());
- return true;
- }
-};
-
-class CommandCSSetBanType : public Command
-{
- public:
- CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Set how Services make bans on the channel"));
- this->SetSyntax(_("\037channel\037 \037bantype\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- try
- {
- int16_t new_type = convertTo<int16_t>(params[1]);
- if (new_type < 0 || new_type > 3)
- throw ConvertException("Invalid range");
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the ban type to " << new_type;
- ci->bantype = new_type;
- source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype);
- }
- catch (const ConvertException &)
- {
- source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the ban type that will be used by services whenever\n"
- "they need to ban someone from your channel.\n"
- " \n"
- "Bantype is a number between 0 and 3 that means:\n"
- " \n"
- "0: ban in the form *!user@host\n"
- "1: ban in the form *!*user@host\n"
- "2: ban in the form *!*@host\n"
- "3: ban in the form *!*user@*.domain"), this->name.c_str());
- return true;
- }
-};
-
-class CommandCSSetDescription : public Command
-{
- public:
- CommandCSSetDescription(Module *creator, const Anope::string &cname = "chanserv/set/description") : Command(creator, cname, 1, 2)
- {
- this->SetDesc(_("Set the channel description"));
- this->SetSyntax(_("\037channel\037 [\037description\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &param = params.size() > 1 ? params[1] : "";
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!param.empty())
- {
- ci->desc = param;
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the description to " << ci->desc;
- source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str());
- }
- else
- {
- ci->desc.clear();
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset the description";
- source.Reply(_("Description of %s unset."), ci->name.c_str());
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the description for the channel, which shows up with\n"
- "the \002LIST\002 and \002INFO\002 commands."), this->name.c_str());
- return true;
- }
-};
-
-class CommandCSSetFounder : public Command
-{
- public:
- CommandCSSetFounder(Module *creator, const Anope::string &cname = "chanserv/set/founder") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Set the founder of a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(params[1]);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str());
- return;
- }
-
- NickCore *nc = na->nc;
- unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
- if (max_reg && nc->channelcount >= max_reg && !source.HasPriv("chanserv/no-register-limit"))
- {
- source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
- return;
- }
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << " to " << nc->display;
-
- ci->SetFounder(nc);
-
- source.Reply(_("Founder of \002%s\002 changed to \002%s\002."), ci->name.c_str(), na->nick.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the founder of a channel. The new nickname must\n"
- "be a registered one."), this->name.c_str());
- return true;
- }
-};
-
-class CommandCSSetKeepModes : public Command
-{
- public:
- CommandCSSetKeepModes(Module *creator, const Anope::string &cname = "chanserv/set/keepmodes") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Retain modes when channel is not in use"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keep modes";
- ci->Extend<bool>("CS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002on\002."), ci->name.c_str());
- if (ci->c)
- ci->last_modes = ci->c->GetModes();
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keep modes";
- ci->Shrink<bool>("CS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002off\002."), ci->name.c_str());
- ci->last_modes.clear();
- }
- else
- this->OnSyntaxError(source, "KEEPMODES");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables keepmodes for the given channel. If keep\n"
- "modes is enabled, services will remember modes set on the channel\n"
- "and attempt to re-set them the next time the channel is created."));
- return true;
- }
-};
-
-class CommandCSSetPeace : public Command
-{
- public:
- CommandCSSetPeace(Module *creator, const Anope::string &cname = "chanserv/set/peace") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Regulate the use of critical commands"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable peace";
- ci->Extend<bool>("PEACE");
- source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable peace";
- ci->Shrink<bool>("PEACE");
- source.Reply(_("Peace option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "PEACE");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002peace\002 option for a channel.\n"
- "When \002peace\002 is set, a user won't be able to kick,\n"
- "ban or remove a channel status of a user that has\n"
- "a level superior or equal to his via %s commands."), source.service->nick.c_str());
- return true;
- }
-};
-
-inline static Anope::string BotModes()
-{
- return Config->GetModule("botserv")->Get<Anope::string>("botmodes",
- Config->GetModule("chanserv")->Get<Anope::string>("botmodes", "o")
- );
-}
-
-class CommandCSSetPersist : public Command
-{
- public:
- CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Set the channel as permanent"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
-
- if (params[1].equals_ci("ON"))
- {
- if (!ci->HasExt("PERSIST"))
- {
- ci->Extend<bool>("PERSIST");
-
- /* Channel doesn't exist, create it */
- if (!ci->c)
- {
- bool created;
- Channel *c = Channel::FindOrCreate(ci->name, created);
- if (ci->bi)
- {
- ChannelStatus status(BotModes());
- ci->bi->Join(c, &status);
- }
- if (created)
- c->Sync();
- }
-
- /* Set the perm mode */
- if (cm)
- {
- if (ci->c && !ci->c->HasMode("PERM"))
- ci->c->SetMode(NULL, cm);
- /* Add it to the channels mlock */
- ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
- if (ml)
- ml->SetMLock(cm, true, "", source.GetNick());
- }
- /* No botserv bot, no channel mode, give them ChanServ.
- * Yes, this works fine with no BotServ.
- */
- else if (!ci->bi)
- {
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- if (!ChanServ)
- {
- source.Reply(_("ChanServ is required to enable persist on this network."));
- return;
- }
-
- ChanServ->Assign(NULL, ci);
- if (!ci->c->FindUser(ChanServ))
- {
- ChannelStatus status(BotModes());
- ChanServ->Join(ci->c, &status);
- }
- }
- }
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable persist";
- source.Reply(_("Channel \002%s\002 is now persistent."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- if (ci->HasExt("PERSIST"))
- {
- ci->Shrink<bool>("PERSIST");
-
- BotInfo *ChanServ = Config->GetClient("ChanServ"),
- *BotServ = Config->GetClient("BotServ");
-
- /* Unset perm mode */
- if (cm)
- {
- if (ci->c && ci->c->HasMode("PERM"))
- ci->c->RemoveMode(NULL, cm);
- /* Remove from mlock */
- ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
- if (ml)
- ml->RemoveMLock(cm, true);
- }
- /* No channel mode, no BotServ, but using ChanServ as the botserv bot
- * which was assigned when persist was set on
- */
- else if (!cm && !BotServ && ci->bi)
- {
- if (!ChanServ)
- {
- source.Reply(_("ChanServ is required to enable persist on this network."));
- return;
- }
-
- /* Unassign bot */
- ChanServ->UnAssign(NULL, ci);
- }
- }
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable persist";
- source.Reply(_("Channel \002%s\002 is no longer persistent."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "PERSIST");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- BotInfo *BotServ = Config->GetClient("BotServ");
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the persistent channel setting.\n"
- "When persistent is set, the service bot will remain\n"
- "in the channel when it has emptied of users.\n"
- " \n"
- "If your IRCd does not have a permanent (persistent) channel\n"
- "mode you must have a service bot in your channel to\n"
- "set persist on, and it can not be unassigned while persist\n"
- "is on.\n"
- " \n"
- "If this network does not have %s enabled and does\n"
- "not have a permanent channel mode, %s will\n"
- "join your channel when you set persist on (and leave when\n"
- "it has been set off).\n"
- " \n"
- "If your IRCd has a permanent (persistent) channel mode\n"
- "and it is set or unset (for any reason, including MODE LOCK),\n"
- "persist is automatically set and unset for the channel as well.\n"
- "Additionally, services will set or unset this mode when you\n"
- "set persist on or off."), BotServ ? BotServ->nick.c_str() : "BotServ",
- ChanServ ? ChanServ->nick.c_str() : "ChanServ");
- return true;
- }
-};
-
-class CommandCSSetRestricted : public Command
-{
- public:
- CommandCSSetRestricted(Module *creator, const Anope::string &cname = "chanserv/set/restricted") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Restrict access to the channel"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable restricted";
- ci->Extend<bool>("RESTRICTED");
- source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable restricted";
- ci->Shrink<bool>("RESTRICTED");
- source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "RESTRICTED");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002restricted access\002 option for a\n"
- "channel. When \002restricted access\002 is set, users not on the access list will\n"
- "instead be kicked and banned from the channel."));
- return true;
- }
-};
-
-class CommandCSSetSecure : public Command
-{
- public:
- CommandCSSetSecure(Module *creator, const Anope::string &cname = "chanserv/set/secure") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Activate security features"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure";
- ci->Extend<bool>("CS_SECURE");
- source.Reply(_("Secure option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure";
- ci->Shrink<bool>("CS_SECURE");
- source.Reply(_("Secure option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "SECURE");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables security features for a\n"
- "channel. When \002SECURE\002 is set, only users who have\n"
- "identified to services, and are not only recognized, will be\n"
- "given access to channels from account-based access entries."));
- return true;
- }
-};
-
-class CommandCSSetSecureFounder : public Command
-{
- public:
- CommandCSSetSecureFounder(Module *creator, const Anope::string &cname = "chanserv/set/securefounder") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Stricter control of channel founder status"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure founder";
- ci->Extend<bool>("SECUREFOUNDER");
- source.Reply(_("Secure founder option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure founder";
- ci->Shrink<bool>("SECUREFOUNDER");
- source.Reply(_("Secure founder option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "SECUREFOUNDER");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002secure founder\002 option for a channel.\n"
- "When \002secure founder\002 is set, only the real founder will be\n"
- "able to drop the channel, change its founder and its successor,\n"
- "and not those who have founder level access through\n"
- "the access/qop command."));
- return true;
- }
-};
-
-class CommandCSSetSecureOps : public Command
-{
- public:
- CommandCSSetSecureOps(Module *creator, const Anope::string &cname = "chanserv/set/secureops") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Stricter control of chanop status"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable secure ops";
- ci->Extend<bool>("SECUREOPS");
- source.Reply(_("Secure ops option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable secure ops";
- ci->Shrink<bool>("SECUREOPS");
- source.Reply(_("Secure ops option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "SECUREOPS");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002secure ops\002 option for a channel.\n"
- "When \002secure ops\002 is set, users who are not on the access list\n"
- "will not be allowed channel operator status."));
- return true;
- }
-};
-
-class CommandCSSetSignKick : public Command
-{
- public:
- CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Sign kicks that are done with the KICK command"));
- this->SetSyntax(_("\037channel\037 {ON | LEVEL | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- ci->Extend<bool>("SIGNKICK");
- ci->Shrink<bool>("SIGNKICK_LEVEL");
- source.Reply(_("Signed kick option for %s is now \002on\002."), ci->name.c_str());
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick";
- }
- else if (params[1].equals_ci("LEVEL"))
- {
- ci->Extend<bool>("SIGNKICK_LEVEL");
- ci->Shrink<bool>("SIGNKICK");
- source.Reply(_("Signed kick option for %s is now \002on\002, but depends of the\n"
- "level of the user that is using the command."), ci->name.c_str());
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable sign kick level";
- }
- else if (params[1].equals_ci("OFF"))
- {
- ci->Shrink<bool>("SIGNKICK");
- ci->Shrink<bool>("SIGNKICK_LEVEL");
- source.Reply(_("Signed kick option for %s is now \002off\002."), ci->name.c_str());
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable sign kick";
- }
- else
- this->OnSyntaxError(source, "SIGNKICK");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables signed kicks for a\n"
- "channel. When \002SIGNKICK\002 is set, kicks issued with\n"
- "the \002KICK\002 command will have the nick that used the\n"
- "command in their reason.\n"
- " \n"
- "If you use \002LEVEL\002, those who have a level that is superior\n"
- "or equal to the SIGNKICK level on the channel won't have their\n"
- "kicks signed."));
- return true;
- }
-};
-
-class CommandCSSetSuccessor : public Command
-{
- public:
- CommandCSSetSuccessor(Module *creator, const Anope::string &cname = "chanserv/set/successor") : Command(creator, cname, 1, 2)
- {
- this->SetDesc(_("Set the successor for a channel"));
- this->SetSyntax(_("\037channel\037 \037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &param = params.size() > 1 ? params[1] : "";
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- NickCore *nc;
-
- if (!param.empty())
- {
- const NickAlias *na = NickAlias::Find(param);
-
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, param.c_str());
- return;
- }
- if (na->nc == ci->GetFounder())
- {
- source.Reply(_("%s cannot be the successor on channel %s as they are the founder."), na->nick.c_str(), ci->name.c_str());
- return;
- }
- nc = na->nc;
- }
- else
- nc = NULL;
-
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change the successor from " << (ci->GetSuccessor() ? ci->GetSuccessor()->display : "(none)") << " to " << (nc ? nc->display : "(none)");
-
- ci->SetSuccessor(nc);
-
- if (nc)
- source.Reply(_("Successor for \002%s\002 changed to \002%s\002."), ci->name.c_str(), nc->display.c_str());
- else
- source.Reply(_("Successor for \002%s\002 unset."), ci->name.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the successor of a channel. If the founder's\n"
- "nickname expires or is dropped while the channel is still\n"
- "registered, the successor will become the new founder of the\n"
- "channel. The new nickname must be a registered one."));
- unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
- if (max_reg)
- source.Reply(_("However, if the successor already has too many\n"
- "channels registered (%d), the channel will be dropped\n"
- "instead, just as if no successor had been set."), max_reg);
- return true;
- }
-};
-
-class CommandCSSetNoexpire : public Command
-{
- public:
- CommandCSSetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2)
- {
- this->SetDesc(_("Prevent the channel from expiring"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (source.permission.empty() && !source.AccessFor(ci).HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(LOG_ADMIN, source, this, ci) << "to enable noexpire";
- ci->Extend<bool>("CS_NO_EXPIRE");
- source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(LOG_ADMIN, source, this, ci) << "to disable noexpire";
- ci->Shrink<bool>("CS_NO_EXPIRE");
- source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "NOEXPIRE");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether the given channel will expire. Setting this\n"
- "to ON prevents the channel from expiring."));
- return true;
- }
-};
-
-class CSSet : public Module
-{
- SerializableExtensibleItem<bool> noautoop, peace, securefounder,
- restricted, secure, secureops, signkick, signkick_level, noexpire;
-
- struct KeepModes : SerializableExtensibleItem<bool>
- {
- KeepModes(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleSerialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- const ChannelInfo *ci = anope_dynamic_static_cast<const ChannelInfo *>(s);
- Anope::string modes;
- for (Channel::ModeList::const_iterator it = ci->last_modes.begin(); it != ci->last_modes.end(); ++it)
- {
- if (!modes.empty())
- modes += " ";
- modes += it->first;
- if (!it->second.empty())
- modes += "," + it->second;
- }
- data["last_modes"] << modes;
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "ChannelInfo")
- return;
-
- ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
- Anope::string modes;
- data["last_modes"] >> modes;
- for (spacesepstream sep(modes); sep.GetToken(modes);)
- {
- size_t c = modes.find(',');
- if (c == Anope::string::npos)
- ci->last_modes.insert(std::make_pair(modes, ""));
- else
- ci->last_modes.insert(std::make_pair(modes.substr(0, c), modes.substr(c + 1)));
- }
- }
- } keep_modes;
-
- struct Persist : SerializableExtensibleItem<bool>
- {
- Persist(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "ChannelInfo" || !this->HasExt(e))
- return;
-
- ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
- if (ci->c)
- return;
-
- bool created;
- Channel *c = Channel::FindOrCreate(ci->name, created);
-
- ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
- if (cm)
- {
- c->SetMode(NULL, cm);
- }
- /* on startup we might not know mode availibity here */
- else if (Me && Me->IsSynced())
- {
- if (!ci->bi)
- {
- BotInfo *ChanServ = Config->GetClient("ChanServ");
- if (ChanServ)
- ChanServ->Assign(NULL, ci);
- }
-
- if (ci->bi && !c->FindUser(ci->bi))
- {
- ChannelStatus status(BotModes());
- ci->bi->Join(c, &status);
- }
- }
-
- if (created)
- c->Sync();
- }
- } persist;
-
- CommandCSSet commandcsset;
- CommandCSSetAutoOp commandcssetautoop;
- CommandCSSetBanType commandcssetbantype;
- CommandCSSetDescription commandcssetdescription;
- CommandCSSetFounder commandcssetfounder;
- CommandCSSetKeepModes commandcssetkeepmodes;
- CommandCSSetPeace commandcssetpeace;
- CommandCSSetPersist commandcssetpersist;
- CommandCSSetRestricted commandcssetrestricted;
- CommandCSSetSecure commandcssetsecure;
- CommandCSSetSecureFounder commandcssetsecurefounder;
- CommandCSSetSecureOps commandcssetsecureops;
- CommandCSSetSignKick commandcssetsignkick;
- CommandCSSetSuccessor commandcssetsuccessor;
- CommandCSSetNoexpire commandcssetnoexpire;
-
- ExtensibleRef<bool> inhabit;
-
- bool persist_lower_ts;
-
- public:
- CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- noautoop(this, "NOAUTOOP"), peace(this, "PEACE"),
- securefounder(this, "SECUREFOUNDER"), restricted(this, "RESTRICTED"),
- secure(this, "CS_SECURE"), secureops(this, "SECUREOPS"), signkick(this, "SIGNKICK"),
- signkick_level(this, "SIGNKICK_LEVEL"), noexpire(this, "CS_NO_EXPIRE"),
- keep_modes(this, "CS_KEEP_MODES"), persist(this, "PERSIST"),
-
- commandcsset(this), commandcssetautoop(this), commandcssetbantype(this),
- commandcssetdescription(this), commandcssetfounder(this), commandcssetkeepmodes(this),
- commandcssetpeace(this), commandcssetpersist(this), commandcssetrestricted(this),
- commandcssetsecure(this), commandcssetsecurefounder(this), commandcssetsecureops(this), commandcssetsignkick(this),
- commandcssetsuccessor(this), commandcssetnoexpire(this),
-
- inhabit("inhabit")
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- persist_lower_ts = conf->GetModule(this)->Get<bool>("persist_lower_ts");
- }
-
- void OnCreateChan(ChannelInfo *ci) anope_override
- {
- ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2");
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- if (c->ci && keep_modes.HasExt(c->ci))
- {
- Channel::ModeList ml = c->ci->last_modes;
- for (Channel::ModeList::iterator it = ml.begin(); it != ml.end(); ++it)
- c->SetMode(c->ci->WhoSends(), it->first, it->second);
- }
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT"))
- return EVENT_CONTINUE;
-
- if (c->ci->AccessFor(u).empty() && (!c->ci->GetFounder() || u->Account() != c->ci->GetFounder()))
- return EVENT_STOP;
-
- return EVENT_CONTINUE;
- }
-
- void OnDelChan(ChannelInfo *ci) anope_override
- {
- if (ci->c && persist.HasExt(ci))
- ci->c->RemoveMode(ci->WhoSends(), "PERM", "", false);
- persist.Unset(ci);
- }
-
- EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (c->ci)
- {
- /* Channel mode +P or so was set, mark this channel as persistent */
- if (mode->name == "PERM")
- persist.Set(c->ci, true);
-
- if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
- c->ci->last_modes = c->GetModes();
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (mode->name == "PERM")
- {
- if (c->ci)
- persist.Unset(c->ci);
- }
-
- if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
- c->ci->last_modes = c->GetModes();
-
- return EVENT_CONTINUE;
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->time_registered)
- {
- Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered;
- c->creation_time = c->ci->time_registered;
- IRCD->SendChannel(c);
- c->Reset();
- }
- }
-
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
- {
- if (chan->ci)
- {
- if (noautoop.HasExt(chan->ci))
- give_modes = false;
- if (secureops.HasExt(chan->ci))
- // This overrides what chanserv does because it is loaded after chanserv
- take_modes = true;
- }
- }
-
- void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
- {
- if (noexpire.HasExt(ci))
- expire = false;
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- if (peace.HasExt(ci))
- info.AddOption(_("Peace"));
- if (restricted.HasExt(ci))
- info.AddOption(_("Restricted access"));
- if (secure.HasExt(ci))
- info.AddOption(_("Security"));
- if (securefounder.HasExt(ci))
- info.AddOption(_("Secure founder"));
- if (secureops.HasExt(ci))
- info.AddOption(_("Secure ops"));
- if (signkick.HasExt(ci) || signkick_level.HasExt(ci))
- info.AddOption(_("Signed kicks"));
- if (persist.HasExt(ci))
- info.AddOption(_("Persistent"));
- if (noexpire.HasExt(ci))
- info.AddOption(_("No expire"));
- if (keep_modes.HasExt(ci))
- info.AddOption(_("Keep modes"));
- if (noautoop.HasExt(ci))
- info.AddOption(_("No auto-op"));
- }
-};
-
-MODULE_INIT(CSSet)
diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp
deleted file mode 100644
index 038bd7cb5..000000000
--- a/modules/commands/cs_set_misc.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 "modules/set_misc.h"
-
-static Module *me;
-
-static Anope::map<Anope::string> descriptions;
-
-struct CSMiscData;
-static Anope::map<ExtensibleItem<CSMiscData> *> items;
-
-static ExtensibleItem<CSMiscData> *GetItem(const Anope::string &name)
-{
- ExtensibleItem<CSMiscData>* &it = items[name];
- if (!it)
- try
- {
- it = new ExtensibleItem<CSMiscData>(me, name);
- }
- catch (const ModuleException &) { }
- return it;
-}
-
-struct CSMiscData : MiscData, Serializable
-{
- CSMiscData(Extensible *obj) : Serializable("CSMiscData") { }
-
- CSMiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : Serializable("CSMiscData")
- {
- object = c->name;
- name = n;
- data = d;
- }
-
- void Serialize(Serialize::Data &sdata) const anope_override
- {
- sdata["ci"] << this->object;
- sdata["name"] << this->name;
- sdata["data"] << this->data;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string sci, sname, sdata;
-
- data["ci"] >> sci;
- data["name"] >> sname;
- data["data"] >> sdata;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (ci == NULL)
- return NULL;
-
- CSMiscData *d = NULL;
- if (obj)
- {
- d = anope_dynamic_static_cast<CSMiscData *>(obj);
- d->object = ci->name;
- data["name"] >> d->name;
- data["data"] >> d->data;
- }
- else
- {
- ExtensibleItem<CSMiscData> *item = GetItem(sname);
- if (item)
- d = item->Set(ci, CSMiscData(ci, sname, sdata));
- }
-
- return d;
- }
-};
-
-static Anope::string GetAttribute(const Anope::string &command)
-{
- size_t sp = command.rfind(' ');
- if (sp != Anope::string::npos)
- return command.substr(sp + 1);
- return command;
-}
-
-class CommandCSSetMisc : public Command
-{
- public:
- CommandCSSetMisc(Module *creator, const Anope::string &cname = "chanserv/set/misc") : Command(creator, cname, 1, 2)
- {
- this->SetSyntax(_("\037channel\037 [\037parameters\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &param = params.size() > 1 ? params[1] : "";
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Anope::string scommand = GetAttribute(source.command);
- Anope::string key = "cs_set_misc:" + scommand;
- ExtensibleItem<CSMiscData> *item = GetItem(key);
- if (item == NULL)
- return;
-
- if (!param.empty())
- {
- item->Set(ci, CSMiscData(ci, key, param));
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change it to " << param;
- source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), ci->name.c_str(), params[1].c_str());
- }
- else
- {
- item->Unset(ci);
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset it";
- source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str());
- }
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (descriptions.count(source.command))
- {
- this->SetDesc(descriptions[source.command]);
- Command::OnServHelp(source);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (descriptions.count(source.command))
- {
- source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
- return true;
- }
- return false;
- }
-};
-
-class CSSetMisc : public Module
-{
- CommandCSSetMisc commandcssetmisc;
- Serialize::Type csmiscdata_type;
-
- public:
- CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcssetmisc(this), csmiscdata_type("CSMiscData", CSMiscData::Unserialize)
- {
- me = this;
- }
-
- ~CSSetMisc()
- {
- for (Anope::map<ExtensibleItem<CSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- delete it->second;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- descriptions.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- if (block->Get<const Anope::string>("command") != "chanserv/set/misc")
- continue;
-
- Anope::string cname = block->Get<const Anope::string>("name");
- Anope::string desc = block->Get<const Anope::string>("misc_description");
-
- if (cname.empty() || desc.empty())
- continue;
-
- descriptions[cname] = desc;
- }
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool) anope_override
- {
- for (Anope::map<ExtensibleItem<CSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- {
- ExtensibleItem<CSMiscData> *e = it->second;
- MiscData *data = e->Get(ci);
-
- if (data != NULL)
- info[e->name.substr(12).replace_all_cs("_", " ")] = data->data;
- }
- }
-};
-
-MODULE_INIT(CSSetMisc)
diff --git a/modules/commands/cs_status.cpp b/modules/commands/cs_status.cpp
deleted file mode 100644
index b984d5952..000000000
--- a/modules/commands/cs_status.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSStatus : public Command
-{
-public:
- CommandCSStatus(Module *creator) : Command(creator, "chanserv/status", 1, 2)
- {
- this->SetDesc(_("Find a user's status on a channel"));
- this->SetSyntax(_("\037channel\037 [\037user\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &channel = params[0];
-
- ChannelInfo *ci = ChannelInfo::Find(channel);
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- else if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && !source.HasPriv("chanserv/auspex"))
- source.Reply(ACCESS_DENIED);
- else
- {
- Anope::string nick = source.GetNick();
- if (params.size() > 1)
- nick = params[1];
-
- AccessGroup ag;
- User *u = User::Find(nick, true);
- NickAlias *na = NULL;
- if (u != NULL)
- ag = ci->AccessFor(u);
- else
- {
- na = NickAlias::Find(nick);
- if (na != NULL)
- ag = ci->AccessFor(na->nc);
- }
-
- if (ag.super_admin)
- source.Reply(_("\002%s\002 is a super administrator."), nick.c_str());
- else if (ag.founder)
- source.Reply(_("\002%s\002 is the founder of \002%s\002."), nick.c_str(), ci->name.c_str());
- else if (ag.empty())
- source.Reply(_("\002%s\002 has no access on \002%s\002."), nick.c_str(), ci->name.c_str());
- else
- {
- source.Reply(_("Access for \002%s\002 on \002%s\002:"), nick.c_str(), ci->name.c_str());
-
- for (unsigned i = 0; i < ag.paths.size(); ++i)
- {
- ChanAccess::Path &p = ag.paths[i];
-
- if (p.empty())
- continue;
-
- if (p.size() == 1)
- {
- ChanAccess *acc = p[0];
-
- source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->Mask().c_str(), acc->AccessSerialize().c_str());
- }
- else
- {
- ChanAccess *first = p[0];
- ChanAccess *acc = p[p.size() - 1];
-
- source.Reply(_("\002%s\002 matches access entry %s (from entry %s), which has privilege %s."), nick.c_str(), acc->Mask().c_str(), first->Mask().c_str(), acc->AccessSerialize().c_str());
- }
- }
- }
-
- for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
- {
- AutoKick *autokick = ci->GetAkick(j);
-
- if (autokick->nc)
- {
- if (na && *autokick->nc == na->nc)
- source.Reply(_("\002%s\002 is on the auto kick list of \002%s\002 (%s)."), na->nc->display.c_str(), ci->name.c_str(), autokick->reason.c_str());
- }
- else if (u != NULL)
- {
- Entry akick_mask("", autokick->mask);
- if (akick_mask.Matches(u))
- source.Reply(_("\002%s\002 matches auto kick entry %s on \002%s\002 (%s)."), u->nick.c_str(), autokick->mask.c_str(), ci->name.c_str(), autokick->reason.c_str());
- }
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command tells you what a users access is on a channel\n"
- "and what access entries, if any, they match. Additionally it\n"
- "will tell you of any auto kick entries they match. Usage of\n"
- "this command is limited to users who have the ability to modify\n"
- "access entries on the channel."));
- return true;
- }
-};
-
-class CSStatus : public Module
-{
- CommandCSStatus commandcsstatus;
-
- public:
- CSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsstatus(this)
- {
- }
-};
-
-MODULE_INIT(CSStatus)
diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp
deleted file mode 100644
index 6bab44207..000000000
--- a/modules/commands/cs_suspend.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/suspend.h"
-
-struct CSSuspendInfo : SuspendInfo, Serializable
-{
- CSSuspendInfo(Extensible *) : Serializable("CSSuspendInfo") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["chan"] << what;
- data["by"] << by;
- data["reason"] << reason;
- data["time"] << when;
- data["expires"] << expires;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string schan;
- data["chan"] >> schan;
-
- CSSuspendInfo *si;
- if (obj)
- si = anope_dynamic_static_cast<CSSuspendInfo *>(obj);
- else
- {
- ChannelInfo *ci = ChannelInfo::Find(schan);
- if (!ci)
- return NULL;
- si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
- data["chan"] >> si->what;
- }
-
- data["by"] >> si->by;
- data["reason"] >> si->reason;
- data["time"] >> si->when;
- data["expires"] >> si->expires;
- return si;
- }
-};
-
-class CommandCSSuspend : public Command
-{
- public:
- CommandCSSuspend(Module *creator) : Command(creator, "chanserv/suspend", 2, 3)
- {
- this->SetDesc(_("Prevent a channel from being used preserving channel data and settings"));
- this->SetSyntax(_("\037channel\037 [+\037expiry\037] [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- Anope::string expiry = params[1];
- Anope::string reason = params.size() > 2 ? params[2] : "";
- time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("expire");
-
- if (!expiry.empty() && expiry[0] != '+')
- {
- reason = expiry + " " + reason;
- reason.trim();
- expiry.clear();
- }
- else
- {
- expiry_secs = Anope::DoTime(expiry);
- if (expiry_secs == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- ChannelInfo *ci = ChannelInfo::Find(chan);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
-
- if (ci->HasExt("CS_SUSPENDED"))
- {
- source.Reply(_("\002%s\002 is already suspended."), ci->name.c_str());
- return;
- }
-
- CSSuspendInfo *si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
- si->what = ci->name;
- si->by = source.GetNick();
- si->reason = reason;
- si->when = Anope::CurTime;
- si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
-
- if (ci->c)
- {
- std::vector<User *> users;
-
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
- if (!user->HasMode("OPER") && user->server != Me)
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- ci->c->Kick(NULL, users[i], "%s", !reason.empty() ? reason.c_str() : Language::Translate(users[i], _("This channel has been suspended.")));
- }
-
- Log(LOG_ADMIN, source, this, ci) << "(" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
- source.Reply(_("Channel \002%s\002 is now suspended."), ci->name.c_str());
-
- FOREACH_MOD(OnChanSuspend, (ci));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Disallows anyone from using the given channel.\n"
- "May be cancelled by using the \002UNSUSPEND\002\n"
- "command to preserve all previous channel data/settings.\n"
- "If an expiry is given the channel will be unsuspended after\n"
- "that period of time, else the default expiry from the\n"
- "configuration is used.\n"
- " \n"
- "Reason may be required on certain networks."));
- return true;
- }
-};
-
-class CommandCSUnSuspend : public Command
-{
- public:
- CommandCSUnSuspend(Module *creator) : Command(creator, "chanserv/unsuspend", 1, 1)
- {
- this->SetDesc(_("Releases a suspended channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- /* Only UNSUSPEND already suspended channels */
- CSSuspendInfo *si = ci->GetExt<CSSuspendInfo>("CS_SUSPENDED");
- if (!si)
- {
- source.Reply(_("Channel \002%s\002 isn't suspended."), ci->name.c_str());
- return;
- }
-
- Log(LOG_ADMIN, source, this, ci) << "which was suspended by " << si->by << " for: " << (!si->reason.empty() ? si->reason : "No reason");
-
- ci->Shrink<CSSuspendInfo>("CS_SUSPENDED");
-
- source.Reply(_("Channel \002%s\002 is now released."), ci->name.c_str());
-
- FOREACH_MOD(OnChanUnsuspend, (ci));
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Releases a suspended channel. All data and settings\n"
- "are preserved from before the suspension."));
- return true;
- }
-};
-
-class CSSuspend : public Module
-{
- CommandCSSuspend commandcssuspend;
- CommandCSUnSuspend commandcsunsuspend;
- ExtensibleItem<CSSuspendInfo> suspend;
- Serialize::Type suspend_type;
- std::vector<Anope::string> show;
-
- struct trim
- {
- Anope::string operator()(Anope::string s) const
- {
- return s.trim();
- }
- };
-
- bool Show(CommandSource &source, const Anope::string &what) const
- {
- return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
- }
-
- public:
- CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcssuspend(this), commandcsunsuspend(this), suspend(this, "CS_SUSPENDED"),
- suspend_type("CSSuspendInfo", CSSuspendInfo::Unserialize)
- {
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- CSSuspendInfo *si = suspend.Get(ci);
- if (!si)
- return;
-
- if (show_hidden || Show(source, "suspended"))
- info[_("Suspended")] = _("This channel is \002suspended\002.");
- if (!si->by.empty() && (show_hidden || Show(source, "by")))
- info[_("Suspended by")] = si->by;
- if (!si->reason.empty() && (show_hidden || Show(source, "reason")))
- info[_("Suspend reason")] = si->reason;
- if (si->when && (show_hidden || Show(source, "on")))
- info[_("Suspended on")] = Anope::strftime(si->when, source.GetAccount());
- if (si->expires && (show_hidden || Show(source, "expires")))
- info[_("Suspension expires")] = Anope::strftime(si->expires, source.GetAccount());
- }
-
- void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
- {
- CSSuspendInfo *si = suspend.Get(ci);
- if (!si)
- return;
-
- expire = false;
-
- if (!si->expires)
- return;
-
- if (si->expires < Anope::CurTime)
- {
- ci->last_used = Anope::CurTime;
- suspend.Unset(ci);
-
- Log(this) << "Expiring suspend for " << ci->name;
- }
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- if (u->HasMode("OPER") || !c->ci || !suspend.HasExt(c->ci))
- return EVENT_CONTINUE;
-
- reason = Language::Translate(u, _("This channel may not be used."));
- return EVENT_STOP;
- }
-
- EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) anope_override
- {
- CSSuspendInfo *si = suspend.Get(ci);
- if (si && !source.HasCommand("chanserv/drop"))
- {
- source.Reply(CHAN_X_SUSPENDED, ci->name.c_str());
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(CSSuspend)
diff --git a/modules/commands/cs_sync.cpp b/modules/commands/cs_sync.cpp
deleted file mode 100644
index a60e24cab..000000000
--- a/modules/commands/cs_sync.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * (C) 2003-2016 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"
-
-class CommandCSSync : public Command
-{
- public:
- CommandCSSync(Module *creator) : Command(creator, "chanserv/sync", 1, 1)
- {
- this->SetDesc(_("Sync users channel modes"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (ci->c == NULL)
- source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
- else if (!source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- {
- bool override = !source.AccessFor(ci).HasPriv("ACCESS_CHANGE") && source.HasPriv("chanserv/administration");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
-
- for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- ci->c->SetCorrectModes(it->second->user, true);
-
- source.Reply(_("All user modes on \002%s\002 have been synced."), ci->name.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &params) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Syncs all modes set on users on the channel with the modes\n"
- "they should have based on their access."));
- return true;
- }
-};
-
-class CSSync : public Module
-{
- CommandCSSync commandcssync;
- public:
- CSSync(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcssync(this)
- {
-
- }
-};
-
-MODULE_INIT(CSSync)
diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp
deleted file mode 100644
index 2db37a456..000000000
--- a/modules/commands/cs_topic.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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 "modules/cs_mode.h"
-
-class CommandCSSetKeepTopic : public Command
-{
- public:
- CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2)
- {
- this->SetDesc(_("Retain topic when channel is not in use"));
- this->SetSyntax(_("\037channel\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (params[1].equals_ci("ON"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable keeptopic";
- ci->Extend<bool>("KEEPTOPIC");
- source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str());
- }
- else if (params[1].equals_ci("OFF"))
- {
- Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable keeptopic";
- ci->Shrink<bool>("KEEPTOPIC");
- source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, "KEEPTOPIC");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables the \002topic retention\002 option for a\n"
- "channel. When \002%s\002 is set, the topic for the\n"
- "channel will be remembered by %s even after the\n"
- "last user leaves the channel, and will be restored the\n"
- "next time the channel is created."), source.command.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandCSTopic : public Command
-{
- ExtensibleRef<bool> topiclock;
-
- void Lock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, "topiclock on"));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- topiclock->Set(ci, true);
- source.Reply(_("Topic lock option for %s is now \002on\002."), ci->name.c_str());
- }
-
- void Unlock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, "topiclock off"));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- topiclock->Unset(ci);
- source.Reply(_("Topic lock option for %s is now \002off\002."), ci->name.c_str());
- }
-
- void Set(CommandSource &source, ChannelInfo *ci, const Anope::string &topic)
- {
- bool has_topiclock = topiclock->HasExt(ci);
- topiclock->Unset(ci);
- ci->c->ChangeTopic(source.GetNick(), topic, Anope::CurTime);
- if (has_topiclock)
- topiclock->Set(ci);
-
- bool override = !source.AccessFor(ci).HasPriv("TOPIC");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << (!topic.empty() ? "to change the topic to: " : "to unset the topic") << (!topic.empty() ? topic : "");
- }
-
- void Append(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &topic = params[2];
-
- Anope::string new_topic;
- if (!ci->c->topic.empty())
- {
- new_topic = ci->c->topic + " " + topic;
- ci->last_topic.clear();
- }
- else
- new_topic = topic;
-
- this->Set(source, ci, new_topic);
- }
-
- public:
- CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 2, 3),
- topiclock("TOPICLOCK")
- {
- this->SetDesc(_("Manipulate the topic of the specified channel"));
- this->SetSyntax(_("\037channel\037 [SET] [\037topic\037]"));
- this->SetSyntax(_("\037channel\037 APPEND \037topic\037"));
- this->SetSyntax(_("\037channel\037 [UNLOCK|LOCK]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcmd = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (!source.AccessFor(ci).HasPriv("TOPIC") && !source.HasCommand("chanserv/topic"))
- source.Reply(ACCESS_DENIED);
- else if (subcmd.equals_ci("LOCK"))
- this->Lock(source, ci, params);
- else if (subcmd.equals_ci("UNLOCK"))
- this->Unlock(source, ci, params);
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- else if (subcmd.equals_ci("APPEND") && params.size() > 2)
- this->Append(source, ci, params);
- else
- {
- Anope::string topic;
- if (subcmd.equals_ci("SET"))
- {
- topic = params.size() > 2 ? params[2] : "";
- }
- else
- {
- topic = subcmd;
- if (params.size() > 2)
- topic += " " + params[2];
- }
- this->Set(source, ci, topic);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows manipulating the topic of the specified channel.\n"
- "The \002SET\002 command changes the topic of the channel to the given topic\n"
- "or unsets the topic if no topic is given. The \002APPEND\002 command appends\n"
- "the given topic to the existing topic.\n"
- " \n"
- "\002LOCK\002 and \002UNLOCK\002 may be used to enable and disable topic lock. When\n"
- "topic lock is set, the channel topic will be unchangeable by users who do not have\n"
- "the \002TOPIC\002 privilege."));
- return true;
- }
-};
-
-class CSTopic : public Module
-{
- CommandCSTopic commandcstopic;
- CommandCSSetKeepTopic commandcssetkeeptopic;
-
- SerializableExtensibleItem<bool> topiclock, keeptopic;
-
- public:
- CSTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcstopic(this), commandcssetkeeptopic(this), topiclock(this, "TOPICLOCK"), keeptopic(this, "KEEPTOPIC")
- {
-
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- if (c->ci)
- {
- /* Update channel topic */
- if ((topiclock.HasExt(c->ci) || keeptopic.HasExt(c->ci)) && c->ci->last_topic != c->topic)
- {
- c->ChangeTopic(!c->ci->last_topic_setter.empty() ? c->ci->last_topic_setter : c->ci->WhoSends()->nick, c->ci->last_topic, c->ci->last_topic_time ? c->ci->last_topic_time : Anope::CurTime);
- }
- }
- }
-
- void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
- {
- if (!c->ci)
- return;
-
- /* We only compare the topics here, not the time or setter. This is because some (old) IRCds do not
- * allow us to set the topic as someone else, meaning we have to bump the TS and change the setter to us.
- * This desyncs what is really set with what we have stored, and we end up resetting the topic often when
- * it is not required
- */
- if (topiclock.HasExt(c->ci) && c->ci->last_topic != c->topic && (!source || !c->ci->AccessFor(source).HasPriv("TOPIC")))
- {
- c->ChangeTopic(c->ci->last_topic_setter, c->ci->last_topic, c->ci->last_topic_time);
- }
- else
- {
- c->ci->last_topic = c->topic;
- c->ci->last_topic_setter = c->topic_setter;
- c->ci->last_topic_time = c->topic_ts;
- }
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
- {
- if (keeptopic.HasExt(ci))
- info.AddOption(_("Topic retention"));
- if (topiclock.HasExt(ci))
- info.AddOption(_("Topic lock"));
-
- ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
- const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL;
- if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode("SECRET")))))
- {
- info[_("Last topic")] = ci->last_topic;
- info[_("Topic set by")] = ci->last_topic_setter;
- }
- }
-};
-
-MODULE_INIT(CSTopic)
diff --git a/modules/commands/cs_unban.cpp b/modules/commands/cs_unban.cpp
deleted file mode 100644
index 64ecc7151..000000000
--- a/modules/commands/cs_unban.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSUnban : public Command
-{
- public:
- CommandCSUnban(Module *creator) : Command(creator, "chanserv/unban", 0, 2)
- {
- this->SetDesc(_("Remove all bans preventing a user from entering a channel"));
- this->SetSyntax(_("\037channel\037 [\037nick\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelMode *cm = ModeManager::FindChannelModeByName("BAN");
- if (!cm)
- return;
-
- std::vector<ChannelMode *> modes = cm->listeners;
- modes.push_back(cm);
-
- if (params.empty())
- {
- if (!source.GetUser())
- return;
-
- std::deque<ChannelInfo *> queue;
- source.GetAccount()->GetChannelReferences(queue);
-
- unsigned count = 0;
- for (unsigned i = 0; i < queue.size(); ++i)
- {
- ChannelInfo *ci = queue[i];
-
- if (!ci->c || !source.AccessFor(ci).HasPriv("UNBAN"))
- continue;
-
- for (unsigned j = 0; j < modes.size(); ++j)
- if (ci->c->Unban(source.GetUser(), modes[j]->name, true))
- ++count;
- }
-
- Log(LOG_COMMAND, source, this, NULL) << "on all channels";
- source.Reply(_("You have been unbanned from %d channels."), count);
-
- return;
- }
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (ci->c == NULL)
- {
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("UNBAN") && !source.HasPriv("chanserv/kick"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- User *u2 = source.GetUser();
- if (params.size() > 1)
- u2 = User::Find(params[1], true);
-
- if (!u2)
- {
- source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("UNBAN") && source.HasPriv("chanserv/kick");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to unban " << u2->nick;
-
- for (unsigned i = 0; i < modes.size(); ++i)
- ci->c->Unban(u2, modes[i]->name, source.GetUser() == u2);
- if (u2 == source.GetUser())
- source.Reply(_("You have been unbanned from \002%s\002."), ci->c->name.c_str());
- else
- source.Reply(_("\002%s\002 has been unbanned from \002%s\002."), u2->nick.c_str(), ci->c->name.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells %s to remove all bans preventing you or the given\n"
- "user from entering the given channel. If no channel is\n"
- "given, all bans affecting you in channels you have access\n"
- "in are removed.\n"
- " \n"
- "By default, limited to AOPs or those with level 5 access and above\n"
- "on the channel."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CSUnban : public Module
-{
- CommandCSUnban commandcsunban;
-
- public:
- CSUnban(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsunban(this)
- {
-
- }
-};
-
-MODULE_INIT(CSUnban)
diff --git a/modules/commands/cs_updown.cpp b/modules/commands/cs_updown.cpp
deleted file mode 100644
index ab3ab60ce..000000000
--- a/modules/commands/cs_updown.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandCSUp : public Command
-{
- void SetModes(User *u, Channel *c)
- {
- if (!c->ci)
- return;
-
- /* whether or not we are giving modes */
- bool giving = true;
- /* whether or not we have given a mode */
- bool given = false;
- AccessGroup u_access = c->ci->AccessFor(u);
-
- for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i)
- {
- ChannelModeStatus *cm = ModeManager::GetStatusChannelModesByRank()[i];
- bool has_priv = u_access.HasPriv("AUTO" + cm->name) || u_access.HasPriv(cm->name);
-
- if (has_priv)
- {
- /* Always give op. If we have already given one mode, don't give more until it has a symbol */
- if (cm->name == "OP" || !given || (giving && cm->symbol))
- {
- c->SetMode(NULL, cm, u->GetUID(), false);
- /* Now if this contains a symbol don't give any more modes, to prevent setting +qaohv etc on users */
- giving = !cm->symbol;
- given = true;
- }
- }
- }
- }
- public:
- CommandCSUp(Module *creator) : Command(creator, "chanserv/up", 0, 2)
- {
- this->SetDesc(_("Updates a selected nicks status on a channel"));
- this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.empty())
- {
- if (!source.GetUser())
- return;
- for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
- {
- Channel *c = it->second->chan;
- SetModes(source.GetUser(), c);
- }
- Log(LOG_COMMAND, source, this, NULL) << "on all channels to update their status modes";
- }
- else
- {
- const Anope::string &channel = params[0];
- const Anope::string &nick = params.size() > 1 ? params[1] : source.GetNick();
-
- Channel *c = Channel::Find(channel);
-
- if (c == NULL)
- {
- source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
- return;
- }
- else if (!c->ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- return;
- }
-
- User *u = User::Find(nick, true);
- User *srcu = source.GetUser();
- bool override = false;
-
- if (u == NULL)
- {
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- return;
- }
- else if (srcu && !srcu->FindChannel(c))
- {
- source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str());
- return;
- }
- else if (!u->FindChannel(c))
- {
- source.Reply(NICK_X_NOT_ON_CHAN, nick.c_str(), channel.c_str());
- return;
- }
- else if (source.GetUser() && u != source.GetUser() && c->ci->HasExt("PEACE"))
- {
- if (c->ci->AccessFor(u) >= c->ci->AccessFor(source.GetUser()))
- {
- if (source.HasPriv("chanserv/administration"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- }
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, c->ci) << "to update the status modes of " << u->nick;
- SetModes(u, c);
- }
-
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Updates a selected nicks status modes on a channel. If \037nick\037 is\n"
- "omitted then your status is updated. If \037channel\037 is omitted then\n"
- "your channel status is updated on every channel you are in."));
- return true;
- }
-};
-
-class CommandCSDown : public Command
-{
- void RemoveAll(User *u, Channel *c)
- {
- ChanUserContainer *cu = c->FindUser(u);
- if (cu != NULL)
- for (size_t i = cu->status.Modes().length(); i > 0;)
- c->RemoveMode(NULL, ModeManager::FindChannelModeByChar(cu->status.Modes()[--i]), u->GetUID());
- }
-
- public:
- CommandCSDown(Module *creator) : Command(creator, "chanserv/down", 0, 2)
- {
- this->SetDesc(_("Removes a selected nicks status from a channel"));
- this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.empty())
- {
- if (!source.GetUser())
- return;
- for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
- {
- Channel *c = it->second->chan;
- RemoveAll(source.GetUser(), c);
- }
- Log(LOG_COMMAND, source, this, NULL) << "on all channels to remove their status modes";
- }
- else
- {
- const Anope::string &channel = params[0];
- const Anope::string &nick = params.size() > 1 ? params[1] : source.GetNick();
-
- Channel *c = Channel::Find(channel);
-
- if (c == NULL)
- {
- source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
- return;
- }
- else if (!c->ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
- return;
- }
-
- User *u = User::Find(nick, true);
- User *srcu = source.GetUser();
- bool override = false;
-
- if (u == NULL)
- {
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- return;
- }
- else if (srcu && !srcu->FindChannel(c))
- {
- source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str());
- return;
- }
- else if (!u->FindChannel(c))
- {
- source.Reply(NICK_X_NOT_ON_CHAN, nick.c_str(), channel.c_str());
- return;
- }
- else if (source.GetUser() && u != source.GetUser() && c->ci->HasExt("PEACE"))
- {
- if (c->ci->AccessFor(u) >= c->ci->AccessFor(source.GetUser()))
- {
- if (source.HasPriv("chanserv/administration"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
- }
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, c->ci) << "to remove the status modes from " << u->nick;
- RemoveAll(u, c);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Removes a selected nicks status modes on a channel. If \037nick\037 is\n"
- "omitted then your status is removed. If \037channel\037 is omitted then\n"
- "your channel status is removed on every channel you are in."));
- return true;
- }
-};
-
-class CSUpDown : public Module
-{
- CommandCSUp commandcsup;
- CommandCSDown commandcsdown;
-
- public:
- CSUpDown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsup(this), commandcsdown(this)
- {
-
- }
-};
-
-MODULE_INIT(CSUpDown)
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
deleted file mode 100644
index 3a6c4d484..000000000
--- a/modules/commands/cs_xop.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- std::vector<Anope::string> order;
- std::map<Anope::string, std::vector<Anope::string> > permissions;
-}
-
-class XOPChanAccess : public ChanAccess
-{
- public:
- Anope::string type;
-
- XOPChanAccess(AccessProvider *p) : ChanAccess(p)
- {
- }
-
- bool HasPriv(const Anope::string &priv) const anope_override
- {
- for (std::vector<Anope::string>::iterator it = std::find(order.begin(), order.end(), this->type); it != order.end(); ++it)
- {
- const std::vector<Anope::string> &privs = permissions[*it];
- if (std::find(privs.begin(), privs.end(), priv) != privs.end())
- return true;
- }
- return false;
- }
-
- Anope::string AccessSerialize() const
- {
- return this->type;
- }
-
- void AccessUnserialize(const Anope::string &data) anope_override
- {
- this->type = data;
- }
-
- static Anope::string DetermineLevel(const ChanAccess *access)
- {
- if (access->provider->name == "access/xop")
- {
- const XOPChanAccess *xaccess = anope_dynamic_static_cast<const XOPChanAccess *>(access);
- return xaccess->type;
- }
- else
- {
- std::map<Anope::string, int> count;
-
- for (std::map<Anope::string, std::vector<Anope::string> >::const_iterator it = permissions.begin(), it_end = permissions.end(); it != it_end; ++it)
- {
- int &c = count[it->first];
- const std::vector<Anope::string> &perms = it->second;
- for (unsigned i = 0; i < perms.size(); ++i)
- if (access->HasPriv(perms[i]))
- ++c;
- }
-
- Anope::string max;
- int maxn = 0;
- for (std::map<Anope::string, int>::iterator it = count.begin(), it_end = count.end(); it != it_end; ++it)
- if (it->second > maxn)
- {
- maxn = it->second;
- max = it->first;
- }
-
- return max;
- }
- }
-};
-
-class XOPAccessProvider : public AccessProvider
-{
- public:
- XOPAccessProvider(Module *o) : AccessProvider(o, "access/xop")
- {
- }
-
- ChanAccess *Create() anope_override
- {
- return new XOPChanAccess(this);
- }
-};
-
-class CommandCSXOP : public Command
-{
- private:
- void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- Anope::string mask = params.size() > 2 ? params[2] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
- return;
- }
-
- XOPChanAccess tmp_access(NULL);
- tmp_access.ci = ci;
- tmp_access.type = source.command.upper();
-
- AccessGroup access = source.AccessFor(ci);
- const ChanAccess *highest = access.Highest();
- bool override = false;
- const NickAlias *na = NULL;
-
- std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
- access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
-
- if (!access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- if (IRCD->IsChannelValid(mask))
- {
- if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- ChannelInfo *targ_ci = ChannelInfo::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->name;
- }
- else
- {
- na = NickAlias::Find(mask);
- if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
- {
- source.Reply(_("Masks and unregistered users may not be on access lists."));
- return;
- }
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- if (na)
- mask = na->nick;
- }
-
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- const ChanAccess *a = ci->GetAccess(i);
-
- if ((na && na->nc == a->GetAccount()) || mask.equals_ci(a->Mask()))
- {
- if ((!highest || *a >= *highest) && !access.founder && !source.HasPriv("chanserv/access/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- delete ci->EraseAccess(i);
- break;
- }
- }
-
- unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
- if (access_max && ci->GetDeepAccessCount() >= access_max)
- {
- source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
- return;
- }
-
- ServiceReference<AccessProvider> provider("AccessProvider", "access/xop");
- if (!provider)
- return;
- XOPChanAccess *acc = anope_dynamic_static_cast<XOPChanAccess *>(provider->Create());
- acc->SetMask(mask, ci);
- acc->creator = source.GetNick();
- acc->type = source.command.upper();
- acc->last_seen = 0;
- acc->created = Anope::CurTime;
- ci->AddAccess(acc);
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask;
-
- FOREACH_MOD(OnAccessAdd, (ci, source, acc));
- source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask().c_str(), ci->name.c_str(), source.command.c_str());
- }
-
- void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- NickCore *nc = source.nc;
- Anope::string mask = params.size() > 2 ? params[2] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
- return;
- }
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
- return;
- }
-
- XOPChanAccess tmp_access(NULL);
- tmp_access.ci = ci;
- tmp_access.type = source.command.upper();
-
- AccessGroup access = source.AccessFor(ci);
- const ChanAccess *highest = access.Highest();
- bool override = false;
-
- if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask))
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
- return;
- }
- }
-
- std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
- access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
-
- if (!mask.equals_ci(nc->display) && !access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
- {
- if (source.HasPriv("chanserv/access/modify"))
- override = true;
- else
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class XOPDelCallback : public NumberList
- {
- CommandSource &source;
- ChannelInfo *ci;
- Command *c;
- unsigned deleted;
- Anope::string nicks;
- bool override;
- public:
- XOPDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, bool _override, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), deleted(0), override(_override)
- {
- }
-
- ~XOPDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on %s %s list."), ci->name.c_str(), source.command.c_str());
- else
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << nicks;
-
- if (deleted == 1)
- source.Reply(_("Deleted one entry from %s %s list."), ci->name.c_str(), source.command.c_str());
- else
- source.Reply(_("Deleted %d entries from %s %s list."), deleted, ci->name.c_str(), source.command.c_str());
- }
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > ci->GetAccessCount())
- return;
-
- ChanAccess *caccess = ci->GetAccess(number - 1);
-
- if (caccess->provider->name != "access/xop" || this->source.command.upper() != caccess->AccessSerialize())
- return;
-
- ++deleted;
- if (!nicks.empty())
- nicks += ", " + caccess->Mask();
- else
- nicks = caccess->Mask();
-
- ci->EraseAccess(number - 1);
- FOREACH_MOD(OnAccessDel, (ci, source, caccess));
- delete caccess;
- }
- }
- delcallback(source, ci, this, override, mask);
- delcallback.Process();
- }
- else
- {
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- ChanAccess *a = ci->GetAccess(i);
-
- if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
- continue;
-
- if (a->Mask().equals_ci(mask))
- {
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->Mask();
-
- source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->name.c_str(), source.command.c_str());
-
- ci->EraseAccess(i);
- FOREACH_MOD(OnAccessDel, (ci, source, a));
- delete a;
-
- return;
- }
- }
-
- source.Reply(_("\002%s\002 not found on %s %s list."), mask.c_str(), ci->name.c_str(), source.command.c_str());
- }
- }
-
- void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
-
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
-
- AccessGroup access = source.AccessFor(ci);
-
- if (!access.HasPriv("ACCESS_LIST") && !source.HasPriv("chanserv/access/list"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask"));
-
- if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class XOPListCallback : public NumberList
- {
- ListFormatter &list;
- ChannelInfo *ci;
- CommandSource &source;
- public:
- XOPListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist, CommandSource &src) : NumberList(numlist, false), list(_list), ci(_ci), source(src)
- {
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > ci->GetAccessCount())
- return;
-
- const ChanAccess *a = ci->GetAccess(Number - 1);
-
- if (a->provider->name != "access/xop" || this->source.command.upper() != a->AccessSerialize())
- return;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(Number);
- entry["Mask"] = a->Mask();
- this->list.AddEntry(entry);
- }
- } nl_list(list, ci, nick, source);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
- {
- const ChanAccess *a = ci->GetAccess(i);
-
- if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
- continue;
- else if (!nick.empty() && !Anope::Match(a->Mask(), nick))
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = a->Mask();
- list.AddEntry(entry);
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
- else
- {
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("%s list for %s"), source.command.c_str(), ci->name.c_str());
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
- return;
- }
-
- if (!ci->GetAccessCount())
- {
- source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
- return;
- }
-
- if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("chanserv/access/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
-
- for (unsigned i = ci->GetAccessCount(); i > 0; --i)
- {
- const ChanAccess *access = ci->GetAccess(i - 1);
-
- if (access->provider->name != "access/xop" || source.command.upper() != access->AccessSerialize())
- continue;
-
- delete ci->EraseAccess(i - 1);
- }
-
- FOREACH_MOD(OnAccessClear, (ci, source));
-
- source.Reply(_("Channel %s %s list has been cleared."), ci->name.c_str(), source.command.c_str());
- }
-
- public:
- CommandCSXOP(Module *modname) : Command(modname, "chanserv/xop", 2, 4)
- {
- this->SetSyntax(_("\037channel\037 ADD \037mask\037"));
- this->SetSyntax(_("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("\037channel\037 CLEAR"));
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Modify the list of %s users")), source.command.upper().c_str());
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- const Anope::string &cmd = params[1];
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, ci, params);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, ci, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, ci, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source, ci);
- else
- this->OnSyntaxError(source, "");
- }
-
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- const Anope::string &cmd = source.command.upper();
-
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Maintains the \002%s list\002 for a channel. Users who match an access entry\n"
- "on the %s list receive the following privileges:\n"
- " "), cmd.c_str(), cmd.c_str());
-
- Anope::string buf;
- for (unsigned i = 0; i < permissions[cmd].size(); ++i)
- {
- buf += ", " + permissions[cmd][i];
- if (buf.length() > 75)
- {
- source.Reply(" %s\n", buf.substr(2).c_str());
- buf.clear();
- }
- }
- if (!buf.empty())
- {
- source.Reply(" %s\n", buf.substr(2).c_str());
- buf.clear();
- }
-
- source.Reply(_(" \n"
- "The \002%s ADD\002 command adds the given nickname to the\n"
- "%s list.\n"
- " \n"
- "The \002%s DEL\002 command removes the given nick from the\n"
- "%s list. If a list of entry numbers is given, those\n"
- "entries are deleted. (See the example for LIST below.)\n"
- " \n"
- "The \002%s LIST\002 command displays the %s list. If\n"
- "a wildcard mask is given, only those entries matching the\n"
- "mask are displayed. If a list of entry numbers is given,\n"
- "only those entries are shown; for example:\n"
- " \002%s #channel LIST 2-5,7-9\002\n"
- " Lists %s entries numbered 2 through 5 and\n"
- " 7 through 9.\n"
- " \n"
- "The \002%s CLEAR\002 command clears all entries of the\n"
- "%s list."), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(),
- cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str());
- BotInfo *access_bi, *flags_bi;
- Anope::string access_cmd, flags_cmd;
- Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
- Command::FindCommandFromService("chanserv/flags", flags_bi, access_cmd);
- if (!access_cmd.empty() || !flags_cmd.empty())
- {
- source.Reply(_("Alternative methods of modifying channel access lists are\n"
- "available. "));
- if (!access_cmd.empty())
- source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
- "about the access list."), Config->StrictPrivmsg.c_str(), access_bi->nick.c_str(), access_cmd.c_str());
- if (!flags_cmd.empty())
- source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
- "about the flags system."), Config->StrictPrivmsg.c_str(), flags_bi->nick.c_str(), flags_cmd.c_str());
- }
- return true;
- }
-};
-
-class CSXOP : public Module
-{
- XOPAccessProvider accessprovider;
- CommandCSXOP commandcsxop;
-
- public:
- CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- accessprovider(this), commandcsxop(this)
- {
- this->SetPermanent(true);
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- order.clear();
- permissions.clear();
-
- for (int i = 0; i < conf->CountBlock("privilege"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("privilege", i);
- const Anope::string &pname = block->Get<const Anope::string>("name");
-
- Privilege *p = PrivilegeManager::FindPrivilege(pname);
- if (p == NULL)
- continue;
-
- const Anope::string &xop = block->Get<const Anope::string>("xop");
- if (pname.empty() || xop.empty())
- continue;
-
- permissions[xop].push_back(pname);
- }
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
- const Anope::string &cname = block->Get<const Anope::string>("name"),
- &cserv = block->Get<const Anope::string>("command");
- if (cname.empty() || cserv != "chanserv/xop")
- continue;
-
- order.push_back(cname);
- }
- }
-};
-
-MODULE_INIT(CSXOP)
diff --git a/modules/commands/gl_global.cpp b/modules/commands/gl_global.cpp
deleted file mode 100644
index dcc7c4780..000000000
--- a/modules/commands/gl_global.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Global core functions
- *
- * (C) 2003-2016 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"
-
-class CommandGLGlobal : public Command
-{
- ServiceReference<GlobalService> GService;
-
- public:
- CommandGLGlobal(Module *creator) : Command(creator, "global/global", 1, 1), GService("GlobalService", "Global")
- {
- this->SetDesc(_("Send a message to all users"));
- this->SetSyntax(_("\037message\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &msg = params[0];
-
- if (!GService)
- source.Reply("No global reference, is global loaded?");
- else
- {
- Log(LOG_ADMIN, source, this);
- GService->SendGlobal(NULL, source.GetNick(), msg);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Administrators to send messages to all users on the\n"
- "network. The message will be sent from the nick \002%s\002."), source.service->nick.c_str());
- return true;
- }
-};
-
-class GLGlobal : public Module
-{
- CommandGLGlobal commandglglobal;
-
- public:
- GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandglglobal(this)
- {
-
- }
-};
-
-MODULE_INIT(GLGlobal)
diff --git a/modules/commands/greet.cpp b/modules/commands/greet.cpp
deleted file mode 100644
index 0f61a1a6e..000000000
--- a/modules/commands/greet.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- *
- * (C) 2003-2016 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"
-
-class CommandBSSetGreet : public Command
-{
- public:
- CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2)
- {
- this->SetDesc(_("Enable greet messages"));
- this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
- const Anope::string &value = params[1];
-
- if (ci == NULL)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (value.equals_ci("ON"))
- {
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets";
-
- ci->Extend<bool>("BS_GREET");
- source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str());
- }
- else if (value.equals_ci("OFF"))
- {
- bool override = !source.AccessFor(ci).HasPriv("SET");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets";
-
- ci->Shrink<bool>("BS_GREET");
- source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
- }
- else
- this->OnSyntaxError(source, source.command);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_(" \n"
- "Enables or disables \002greet\002 mode on a channel.\n"
- "When it is enabled, the bot will display greet\n"
- "messages of users joining the channel, provided\n"
- "they have enough access to the channel."));
- return true;
- }
-};
-
-class CommandNSSetGreet : public Command
-{
- public:
- CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Associate a greet message with your nickname"));
- this->SetSyntax(_("\037message\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (!param.empty())
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the greet of " << nc->display;
- nc->Extend<Anope::string>("greet", param);
- source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str());
- }
- else
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the greet of " << nc->display;
- nc->Shrink<Anope::string>("greet");
- source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str());
- }
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params.size() > 0 ? params[0] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the given message the greet of your nickname, that\n"
- "will be displayed when joining a channel that has GREET\n"
- "option enabled, provided that you have the necessary\n"
- "access on it."));
- return true;
- }
-};
-
-class CommandNSSASetGreet : public CommandNSSetGreet
-{
- public:
- CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037message\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params.size() > 1 ? params[1] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Makes the given message the greet of the nickname, that\n"
- "will be displayed when joining a channel that has GREET\n"
- "option enabled, provided that the user has the necessary\n"
- "access on it."));
- return true;
- }
-};
-
-class Greet : public Module
-{
- /* channel setting for whether or not greet should be shown */
- SerializableExtensibleItem<bool> bs_greet;
- /* user greets */
- SerializableExtensibleItem<Anope::string> ns_greet;
-
- CommandBSSetGreet commandbssetgreet;
- CommandNSSetGreet commandnssetgreet;
- CommandNSSASetGreet commandnssasetgreet;
-
- public:
- Greet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- bs_greet(this, "BS_GREET"),
- ns_greet(this, "greet"),
- commandbssetgreet(this),
- commandnssetgreet(this), commandnssasetgreet(this)
- {
- }
-
- void OnJoinChannel(User *user, Channel *c) anope_override
- {
- /* Only display the greet if the main uplink we're connected
- * to has synced, or we'll get greet-floods when the net
- * recovers from a netsplit. -GD
- */
- if (!c->ci || !c->ci->bi || !user->server->IsSynced() || !user->Account())
- return;
-
- Anope::string *greet = ns_greet.Get(user->Account());
- if (bs_greet.HasExt(c->ci) && greet != NULL && !greet->empty() && c->FindUser(c->ci->bi) && c->ci->AccessFor(user).HasPriv("GREET"))
- {
- IRCD->SendPrivmsg(*c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), greet->c_str());
- c->ci->bi->lastmsg = Anope::CurTime;
- }
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- Anope::string *greet = ns_greet.Get(na->nc);
- if (greet != NULL)
- info[_("Greet")] = *greet;
- }
-
- void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override
- {
- if (bs_greet.HasExt(ci))
- info.AddOption(_("Greet"));
- }
-};
-
-MODULE_INIT(Greet)
diff --git a/modules/commands/help.cpp b/modules/commands/help.cpp
deleted file mode 100644
index f6e459bde..000000000
--- a/modules/commands/help.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHelp : public Command
-{
- static const unsigned help_wrap_len = 40;
-
- static CommandGroup *FindGroup(const Anope::string &name)
- {
- for (unsigned i = 0; i < Config->CommandGroups.size(); ++i)
- {
- CommandGroup &gr = Config->CommandGroups[i];
- if (gr.name == name)
- return &gr;
- }
-
- return NULL;
- }
-
- public:
- CommandHelp(Module *creator) : Command(creator, "generic/help", 0)
- {
- this->SetDesc(_("Displays this list and give information about commands"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnPreHelp, MOD_RESULT, (source, params));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Anope::string source_command = source.command;
- const BotInfo *bi = source.service;
- const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands;
- bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
- hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
-
- if (params.empty() || params[0].equals_ci("ALL"))
- {
- bool all = !params.empty() && params[0].equals_ci("ALL");
- typedef std::map<CommandGroup *, std::list<Anope::string> > GroupInfo;
- GroupInfo groups;
-
- if (all)
- source.Reply(_("All available commands for \002%s\002:"), source.service->nick.c_str());
-
- for (CommandInfo::map::const_iterator it = map.begin(), it_end = map.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (info.hide)
- continue;
-
- // Smaller command exists
- Anope::string cmd;
- spacesepstream(c_name).GetToken(cmd, 0);
- if (cmd != it->first && map.count(cmd))
- continue;
-
- ServiceReference<Command> c("Command", info.name);
- if (!c)
- continue;
-
- if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
- continue;
-
- if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- if (!info.group.empty() && !all)
- {
- CommandGroup *gr = FindGroup(info.group);
- if (gr != NULL)
- {
- groups[gr].push_back(c_name);
- continue;
- }
- }
-
- source.command = c_name;
- c->OnServHelp(source);
-
- }
-
- for (GroupInfo::iterator it = groups.begin(), it_end = groups.end(); it != it_end; ++it)
- {
- CommandGroup *gr = it->first;
-
- source.Reply(" ");
- source.Reply("%s", gr->description.c_str());
-
- Anope::string buf;
- for (std::list<Anope::string>::iterator it2 = it->second.begin(), it2_end = it->second.end(); it2 != it2_end; ++it2)
- {
- const Anope::string &c_name = *it2;
-
- buf += ", " + c_name;
-
- if (buf.length() > help_wrap_len)
- {
- source.Reply(" %s", buf.substr(2).c_str());
- buf.clear();
- }
- }
- if (buf.length() > 2)
- {
- source.Reply(" %s", buf.substr(2).c_str());
- buf.clear();
- }
- }
- if (!groups.empty())
- {
- source.Reply(" ");
- source.Reply(_("Use the \002%s ALL\002 command to list all commands and their descriptions."), source_command.c_str());
- }
- }
- else
- {
- bool helped = false;
- for (unsigned max = params.size(); max > 0; --max)
- {
- Anope::string full_command;
- for (unsigned i = 0; i < max; ++i)
- full_command += " " + params[i];
- full_command.erase(full_command.begin());
-
- CommandInfo::map::const_iterator it = map.find(full_command);
- if (it == map.end())
- continue;
-
- const CommandInfo &info = it->second;
-
- ServiceReference<Command> c("Command", info.name);
- if (!c)
- continue;
-
- if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- // Allow unregistered users to see help for commands that they explicitly request help for
-
- const Anope::string &subcommand = params.size() > max ? params[max] : "";
- source.command = full_command;
- if (!c->OnHelp(source, subcommand))
- continue;
-
- helped = true;
-
- /* Inform the user what permission is required to use the command */
- if (!info.permission.empty())
- {
- source.Reply(" ");
- source.Reply(_("Access to this command requires the permission \002%s\002 to be present in your opertype."), info.permission.c_str());
- }
- if (!c->AllowUnregistered() && !source.nc)
- {
- if (info.permission.empty())
- source.Reply(" ");
- source.Reply( _("You need to be identified to use this command."));
- }
- /* User doesn't have the proper permission to use this command */
- else if (!info.permission.empty() && !source.HasCommand(info.permission))
- {
- source.Reply(_("You cannot use this command."));
- }
-
- break;
- }
-
- if (helped == false)
- source.Reply(_("No help available for \002%s\002."), params[0].c_str());
- }
-
- FOREACH_MOD(OnPostHelp, (source, params));
-
- return;
- }
-};
-
-class Help : public Module
-{
- CommandHelp commandhelp;
-
- public:
- Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhelp(this)
- {
-
- }
-};
-
-MODULE_INIT(Help)
diff --git a/modules/commands/hs_del.cpp b/modules/commands/hs_del.cpp
deleted file mode 100644
index 02b2a1324..000000000
--- a/modules/commands/hs_del.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHSDel : public Command
-{
- public:
- CommandHSDel(Module *creator) : Command(creator, "hostserv/del", 1, 1)
- {
- this->SetDesc(_("Delete the vhost of another user"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
- NickAlias *na = NickAlias::Find(nick);
- if (na)
- {
- Log(LOG_ADMIN, source, this) << "for user " << na->nick;
- FOREACH_MOD(OnDeleteVhost, (na));
- na->RemoveVhost();
- source.Reply(_("Vhost for \002%s\002 removed."), nick.c_str());
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Deletes the vhost assigned to the given nick from the\n"
- "database."));
- return true;
- }
-};
-
-class CommandHSDelAll : public Command
-{
- public:
- CommandHSDelAll(Module *creator) : Command(creator, "hostserv/delall", 1, 1)
- {
- this->SetDesc(_("Deletes the vhost for all nicks in a group"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
- NickAlias *na = NickAlias::Find(nick);
- if (na)
- {
- FOREACH_MOD(OnDeleteVhost, (na));
- const NickCore *nc = na->nc;
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- na = nc->aliases->at(i);
- na->RemoveVhost();
- }
- Log(LOG_ADMIN, source, this) << "for all nicks in group " << nc->display;
- source.Reply(_("vhosts for group \002%s\002 have been removed."), nc->display.c_str());
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Deletes the vhost for all nicks in the same group as\n"
- "that of the given nick."));
- return true;
- }
-};
-
-class HSDel : public Module
-{
- CommandHSDel commandhsdel;
- CommandHSDelAll commandhsdelall;
-
- public:
- HSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsdel(this), commandhsdelall(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSDel)
diff --git a/modules/commands/hs_group.cpp b/modules/commands/hs_group.cpp
deleted file mode 100644
index e6211b118..000000000
--- a/modules/commands/hs_group.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHSGroup : public Command
-{
- bool setting;
-
- public:
- void Sync(const NickAlias *na)
- {
- if (setting)
- return;
-
- if (!na || !na->HasVhost())
- return;
-
- setting = true;
- for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
- {
- NickAlias *nick = na->nc->aliases->at(i);
- if (nick)
- {
- nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
- FOREACH_MOD(OnSetVhost, (nick));
- }
- }
- setting = false;
- }
-
- CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0), setting(false)
- {
- this->SetDesc(_("Syncs the vhost for all nicks in a group"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- NickAlias *na = NickAlias::Find(source.GetNick());
- if (na && source.GetAccount() == na->nc && na->HasVhost())
- {
- this->Sync(na);
- if (!na->GetVhostIdent().empty())
- source.Reply(_("All vhosts in the group \002%s\002 have been set to \002%s\002@\002%s\002."), source.nc->display.c_str(), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
- else
- source.Reply(_("All vhosts in the group \002%s\002 have been set to \002%s\002."), source.nc->display.c_str(), na->GetVhostHost().c_str());
- }
- else
- source.Reply(HOST_NOT_ASSIGNED);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command allows users to set the vhost of their\n"
- "CURRENT nick to be the vhost for all nicks in the same\n"
- "group."));
- return true;
- }
-};
-
-class HSGroup : public Module
-{
- CommandHSGroup commandhsgroup;
- bool syncongroup;
- bool synconset;
-
- public:
- HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsgroup(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-
- void OnSetVhost(NickAlias *na) anope_override
- {
- if (!synconset)
- return;
-
- commandhsgroup.Sync(na);
- }
-
- void OnNickGroup(User *u, NickAlias *na) anope_override
- {
- if (!syncongroup)
- return;
-
- commandhsgroup.Sync(na);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- syncongroup = block->Get<bool>("syncongroup");
- synconset = block->Get<bool>("synconset");
- }
-};
-
-MODULE_INIT(HSGroup)
diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp
deleted file mode 100644
index a5258b04c..000000000
--- a/modules/commands/hs_list.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHSList : public Command
-{
- public:
- CommandHSList(Module *creator) : Command(creator, "hostserv/list", 0, 1)
- {
- this->SetDesc(_("Displays one or more vhost entries"));
- this->SetSyntax(_("[\037key\037|\037#X-Y\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &key = !params.empty() ? params[0] : "";
- int from = 0, to = 0, counter = 1;
-
- /**
- * Do a check for a range here, then in the next loop
- * we'll only display what has been requested..
- **/
- if (!key.empty() && key[0] == '#')
- {
- size_t tmp = key.find('-');
- if (tmp == Anope::string::npos || tmp == key.length() || tmp == 1)
- {
- source.Reply(LIST_INCORRECT_RANGE);
- return;
- }
- for (unsigned i = 1, end = key.length(); i < end; ++i)
- {
- if (!isdigit(key[i]) && i != tmp)
- {
- source.Reply(LIST_INCORRECT_RANGE);
- return;
- }
- try
- {
- from = convertTo<int>(key.substr(1, tmp - 1));
- to = convertTo<int>(key.substr(tmp + 1));
- }
- catch (const ConvertException &) { }
- }
- }
-
- unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Nick")).AddColumn(_("Vhost")).AddColumn(_("Creator")).AddColumn(_("Created"));
-
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- {
- const NickAlias *na = it->second;
-
- if (!na->HasVhost())
- continue;
-
- if (!key.empty() && key[0] != '#')
- {
- if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < listmax)
- {
- ++display_counter;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(display_counter);
- entry["Nick"] = na->nick;
- if (!na->GetVhostIdent().empty())
- entry["Vhost"] = na->GetVhostIdent() + "@" + na->GetVhostHost();
- else
- entry["Vhost"] = na->GetVhostHost();
- entry["Creator"] = na->GetVhostCreator();
- entry["Created"] = Anope::strftime(na->GetVhostCreated(), NULL, true);
- list.AddEntry(entry);
- }
- }
- else
- {
- /**
- * List the host if its in the display range, and not more
- * than NSListMax records have been displayed...
- **/
- if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax)
- {
- ++display_counter;
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(display_counter);
- entry["Nick"] = na->nick;
- if (!na->GetVhostIdent().empty())
- entry["Vhost"] = na->GetVhostIdent() + "@" + na->GetVhostHost();
- else
- entry["Vhost"] = na->GetVhostHost();
- entry["Creator"] = na->GetVhostCreator();
- entry["Created"] = Anope::strftime(na->GetVhostCreated(), NULL, true);
- list.AddEntry(entry);
- }
- }
- ++counter;
- }
-
- if (!display_counter)
- {
- source.Reply(_("No records to display."));
- return;
- }
-
- if (!key.empty())
- source.Reply(_("Displayed records matching key \002%s\002 (count: \002%d\002)."), key.c_str(), display_counter);
- else
- {
- if (from)
- source.Reply(_("Displayed records from \002%d\002 to \002%d\002."), from, to);
- else
- source.Reply(_("Displayed all records (count: \002%d\002)."), display_counter);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command lists registered vhosts to the operator.\n"
- "If a \037key\037 is specified, only entries whose nick or vhost match\n"
- "the pattern given in \037key\037 are displayed e.g. Rob* for all\n"
- "entries beginning with \"Rob\"\n"
- "If a \037#X-Y\037 style is used, only entries between the range of \002X\002\n"
- "and \002Y\002 will be displayed, e.g. \002#1-3\002 will display the first 3\n"
- "nick/vhost entries."));
- return true;
- }
-};
-
-class HSList : public Module
-{
- CommandHSList commandhslist;
-
- public:
- HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhslist(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSList)
diff --git a/modules/commands/hs_off.cpp b/modules/commands/hs_off.cpp
deleted file mode 100644
index 75c8cf62a..000000000
--- a/modules/commands/hs_off.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHSOff : public Command
-{
- public:
- CommandHSOff(Module *creator) : Command(creator, "hostserv/off", 0, 0)
- {
- this->SetDesc(_("Deactivates your assigned vhost"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- const NickAlias *na = NickAlias::Find(u->nick);
- if (!na || na->nc != u->Account() || !na->HasVhost())
- na = NickAlias::Find(u->Account()->display);
-
- if (!na || !na->HasVhost())
- source.Reply(HOST_NOT_ASSIGNED);
- else
- {
- u->vhost.clear();
- IRCD->SendVhostDel(u);
- u->UpdateHost();
- Log(LOG_COMMAND, source, this) << "to disable their vhost";
- source.Reply(_("Your vhost was removed and the normal cloaking restored."));
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Deactivates the vhost currently assigned to the nick in use.\n"
- "When you use this command any user who performs a /whois\n"
- "on you will see your real host/IP address."));
- return true;
- }
-};
-
-class HSOff : public Module
-{
- CommandHSOff commandhsoff;
-
- public:
- HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsoff(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSOff)
diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp
deleted file mode 100644
index 5aa20380c..000000000
--- a/modules/commands/hs_on.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHSOn : public Command
-{
- public:
- CommandHSOn(Module *creator) : Command(creator, "hostserv/on", 0, 0)
- {
- this->SetDesc(_("Activates your assigned vhost"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!IRCD->CanSetVHost)
- return; // HostServ wouldn't even be loaded at this point
-
- User *u = source.GetUser();
- const NickAlias *na = NickAlias::Find(u->nick);
- if (!na || na->nc != u->Account() || !na->HasVhost())
- na = NickAlias::Find(u->Account()->display);
- if (na && u->Account() == na->nc && na->HasVhost())
- {
- if (!na->GetVhostIdent().empty())
- source.Reply(_("Your vhost of \002%s\002@\002%s\002 is now activated."), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str());
- else
- source.Reply(_("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str());
- Log(LOG_COMMAND, source, this) << "to enable their vhost of " << (!na->GetVhostIdent().empty() ? na->GetVhostIdent() + "@" : "") << na->GetVhostHost();
- IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
- u->vhost = na->GetVhostHost();
- if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
- u->SetVIdent(na->GetVhostIdent());
- u->UpdateHost();
- }
- else
- source.Reply(HOST_NOT_ASSIGNED);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Activates the vhost currently assigned to the nick in use.\n"
- "When you use this command any user who performs a /whois\n"
- "on you will see the vhost instead of your real host/IP address."));
- return true;
- }
-};
-
-class HSOn : public Module
-{
- CommandHSOn commandhson;
-
- public:
- HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhson(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSOn)
diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp
deleted file mode 100644
index 12979e804..000000000
--- a/modules/commands/hs_request.cpp
+++ /dev/null
@@ -1,394 +0,0 @@
-/* hs_request.c - Add request and activate functionality to HostServ
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Based on the original module by Rob <rob@anope.org>
- * Included in the Anope module pack since Anope 1.7.11
- * Anope Coder: GeniusDex <geniusdex@anope.org>
- *
- * Please read COPYING and README for further details.
- *
- * Send bug reports to the Anope Coder instead of the module
- * author, because any changes since the inclusion into anope
- * are not supported by the original author.
- */
-
-#include "module.h"
-
-static ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-
-static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
-
-struct HostRequest : Serializable
-{
- Anope::string nick;
- Anope::string ident;
- Anope::string host;
- time_t time;
-
- HostRequest(Extensible *) : Serializable("HostRequest") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["nick"] << this->nick;
- data["ident"] << this->ident;
- data["host"] << this->host;
- data.SetType("time", Serialize::Data::DT_INT); data["time"] << this->time;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snick;
- data["nick"] >> snick;
-
- NickAlias *na = NickAlias::Find(snick);
- if (na == NULL)
- return NULL;
-
- HostRequest *req;
- if (obj)
- req = anope_dynamic_static_cast<HostRequest *>(obj);
- else
- req = na->Extend<HostRequest>("hostrequest");
- if (req)
- {
- req->nick = na->nick;
- data["ident"] >> req->ident;
- data["host"] >> req->host;
- data["time"] >> req->time;
- }
-
- return req;
- }
-};
-
-class CommandHSRequest : public Command
-{
- bool isvalidchar(char c)
- {
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-')
- return true;
- return false;
- }
-
- public:
- CommandHSRequest(Module *creator) : Command(creator, "hostserv/request", 1, 1)
- {
- this->SetDesc(_("Request a vHost for your nick"));
- this->SetSyntax(_("vhost"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(source.GetNick());
- if (!na || na->nc != source.GetAccount())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (source.GetAccount()->HasExt("UNCONFIRMED"))
- {
- source.Reply(_("You must confirm your account before you may request a vhost."));
- return;
- }
-
- Anope::string rawhostmask = params[0];
-
- Anope::string user, host;
- size_t a = rawhostmask.find('@');
-
- if (a == Anope::string::npos)
- host = rawhostmask;
- else
- {
- user = rawhostmask.substr(0, a);
- host = rawhostmask.substr(a + 1);
- }
-
- if (host.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- if (!user.empty())
- {
- if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
- {
- source.Reply(HOST_SET_IDENTTOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("userlen"));
- return;
- }
- else if (!IRCD->CanSetVIdent)
- {
- source.Reply(HOST_NO_VIDENT);
- return;
- }
- for (Anope::string::iterator s = user.begin(), s_end = user.end(); s != s_end; ++s)
- if (!isvalidchar(*s))
- {
- source.Reply(HOST_SET_IDENT_ERROR);
- return;
- }
- }
-
- if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
- {
- source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(HOST_SET_ERROR);
- return;
- }
-
- time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
- if (Config->GetModule(this->owner)->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime)
- {
- source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay);
- u->lastmemosend = Anope::CurTime;
- return;
- }
-
- HostRequest req(na);
- req.nick = source.GetNick();
- req.ident = user;
- req.host = host;
- req.time = Anope::CurTime;
- na->Extend<HostRequest>("hostrequest", req);
-
- source.Reply(_("Your vHost has been requested."));
- req_send_memos(owner, source, user, host);
- Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Request the given vHost to be activated for your nick by the\n"
- "network administrators. Please be patient while your request\n"
- "is being considered."));
- return true;
- }
-};
-
-class CommandHSActivate : public Command
-{
- public:
- CommandHSActivate(Module *creator) : Command(creator, "hostserv/activate", 1, 1)
- {
- this->SetDesc(_("Approve the requested vHost of a user"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
-
- NickAlias *na = NickAlias::Find(nick);
- HostRequest *req = na ? na->GetExt<HostRequest>("hostrequest") : NULL;
- if (req)
- {
- na->SetVhost(req->ident, req->host, source.GetNick(), req->time);
- FOREACH_MOD(OnSetVhost, (na));
-
- if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
- memoserv->Send(source.service->nick, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
-
- source.Reply(_("vHost for %s has been activated."), na->nick.c_str());
- Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host;
- na->Shrink<HostRequest>("hostrequest");
- }
- else
- source.Reply(_("No request for nick %s found."), nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Activate the requested vHost for the given nick."));
- if (Config->GetModule(this->owner)->Get<bool>("memouser"))
- source.Reply(_("A memo informing the user will also be sent."));
-
- return true;
- }
-};
-
-class CommandHSReject : public Command
-{
- public:
- CommandHSReject(Module *creator) : Command(creator, "hostserv/reject", 1, 2)
- {
- this->SetDesc(_("Reject the requested vHost of a user"));
- this->SetSyntax(_("\037nick\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
- const Anope::string &reason = params.size() > 1 ? params[1] : "";
-
- NickAlias *na = NickAlias::Find(nick);
- HostRequest *req = na ? na->GetExt<HostRequest>("hostrequest") : NULL;
- if (req)
- {
- na->Shrink<HostRequest>("hostrequest");
-
- if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
- {
- Anope::string message;
- if (!reason.empty())
- message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
- else
- message = _("[auto memo] Your requested vHost has been rejected.");
-
- memoserv->Send(source.service->nick, nick, Language::Translate(source.GetAccount(), message.c_str()), true);
- }
-
- source.Reply(_("vHost for %s has been rejected."), nick.c_str());
- Log(LOG_COMMAND, source, this) << "to reject vhost for " << nick << " (" << (!reason.empty() ? reason : "no reason") << ")";
- }
- else
- source.Reply(_("No request for nick %s found."), nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Reject the requested vHost for the given nick."));
- if (Config->GetModule(this->owner)->Get<bool>("memouser"))
- source.Reply(_("A memo informing the user will also be sent, which includes the reason for the rejection if supplied."));
-
- return true;
- }
-};
-
-class CommandHSWaiting : public Command
-{
- public:
- CommandHSWaiting(Module *creator) : Command(creator, "hostserv/waiting", 0, 0)
- {
- this->SetDesc(_("Retrieves the vhost requests"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- unsigned counter = 0;
- unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax");
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Number")).AddColumn(_("Nick")).AddColumn(_("Vhost")).AddColumn(_("Created"));
-
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- {
- const NickAlias *na = it->second;
- HostRequest *hr = na->GetExt<HostRequest>("hostrequest");
- if (!hr)
- continue;
-
- if (!listmax || display_counter < listmax)
- {
- ++display_counter;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(display_counter);
- entry["Nick"] = it->first;
- if (!hr->ident.empty())
- entry["Vhost"] = hr->ident + "@" + hr->host;
- else
- entry["Vhost"] = hr->host;
- entry["Created"] = Anope::strftime(hr->time, NULL, true);
- list.AddEntry(entry);
- }
- ++counter;
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("Displayed \002%d\002 records (\002%d\002 total)."), display_counter, counter);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command retrieves the vhost requests."));
-
- return true;
- }
-};
-
-class HSRequest : public Module
-{
- CommandHSRequest commandhsrequest;
- CommandHSActivate commandhsactive;
- CommandHSReject commandhsreject;
- CommandHSWaiting commandhswaiting;
- ExtensibleItem<HostRequest> hostrequest;
- Serialize::Type request_type;
-
- public:
- HSRequest(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandhsrequest(this), commandhsactive(this),
- commandhsreject(this), commandhswaiting(this), hostrequest(this, "hostrequest"), request_type("HostRequest", HostRequest::Unserialize)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
-{
- Anope::string host;
- std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end;
-
- if (!vIdent.empty())
- host = vIdent + "@" + vHost;
- else
- host = vHost;
-
- if (Config->GetModule(me)->Get<bool>("memooper") && memoserv)
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- const NickAlias *na = NickAlias::Find(o->name);
- if (!na)
- continue;
-
- Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str());
-
- memoserv->Send(source.service->nick, na->nick, message, true);
- }
-}
-
-MODULE_INIT(HSRequest)
diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp
deleted file mode 100644
index 4c736a77d..000000000
--- a/modules/commands/hs_set.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/* HostServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandHSSet : public Command
-{
- public:
- CommandHSSet(Module *creator) : Command(creator, "hostserv/set", 2, 2)
- {
- this->SetDesc(_("Set the vhost of another user"));
- this->SetSyntax(_("\037nick\037 \037hostmask\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nick = params[0];
-
- NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- Anope::string rawhostmask = params[1];
-
- Anope::string user, host;
- size_t a = rawhostmask.find('@');
-
- if (a == Anope::string::npos)
- host = rawhostmask;
- else
- {
- user = rawhostmask.substr(0, a);
- host = rawhostmask.substr(a + 1);
- }
-
- if (host.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- if (!user.empty())
- {
- if (!IRCD->CanSetVIdent)
- {
- source.Reply(HOST_NO_VIDENT);
- return;
- }
- else if (!IRCD->IsIdentValid(user))
- {
- source.Reply(HOST_SET_IDENT_ERROR);
- return;
- }
- }
-
- if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
- {
- source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(HOST_SET_ERROR);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
-
- na->SetVhost(user, host, source.GetNick());
- FOREACH_MOD(OnSetVhost, (na));
- if (!user.empty())
- source.Reply(_("VHost for \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
- else
- source.Reply(_("VHost for \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the vhost for the given nick to that of the given\n"
- "hostmask. If your IRCD supports vIdents, then using\n"
- "SET <nick> <ident>@<hostmask> set idents for users as\n"
- "well as vhosts."));
- return true;
- }
-};
-
-class CommandHSSetAll : public Command
-{
- void Sync(const NickAlias *na)
- {
- if (!na || !na->HasVhost())
- return;
-
- for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
- {
- NickAlias *nick = na->nc->aliases->at(i);
- if (nick)
- nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
- }
- }
-
- public:
- CommandHSSetAll(Module *creator) : Command(creator, "hostserv/setall", 2, 2)
- {
- this->SetDesc(_("Set the vhost for all nicks in a group"));
- this->SetSyntax(_("\037nick\037 \037hostmask\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- Anope::string nick = params[0];
-
- NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- Anope::string rawhostmask = params[1];
-
- Anope::string user, host;
- size_t a = rawhostmask.find('@');
-
- if (a == Anope::string::npos)
- host = rawhostmask;
- else
- {
- user = rawhostmask.substr(0, a);
- host = rawhostmask.substr(a + 1);
- }
-
- if (host.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- if (!user.empty())
- {
- if (!IRCD->CanSetVIdent)
- {
- source.Reply(HOST_NO_VIDENT);
- return;
- }
- else if (!IRCD->IsIdentValid(user))
- {
- source.Reply(HOST_SET_IDENT_ERROR);
- return;
- }
- }
-
- if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
- {
- source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
- return;
- }
-
- if (!IRCD->IsHostValid(host))
- {
- source.Reply(HOST_SET_ERROR);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "to set the vhost of " << na->nick << " to " << (!user.empty() ? user + "@" : "") << host;
-
- na->SetVhost(user, host, source.GetNick());
- this->Sync(na);
- FOREACH_MOD(OnSetVhost, (na));
- if (!user.empty())
- source.Reply(_("VHost for group \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), user.c_str(), host.c_str());
- else
- source.Reply(_("VHost for group \002%s\002 set to \002%s\002."), nick.c_str(), host.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets the vhost for all nicks in the same group as that\n"
- "of the given nick. If your IRCD supports vIdents, then\n"
- "using SETALL <nick> <ident>@<hostmask> will set idents\n"
- "for users as well as vhosts.\n"
- "* NOTE, this will not update the vhost for any nicks\n"
- "added to the group after this command was used."));
- return true;
- }
-};
-
-class HSSet : public Module
-{
- CommandHSSet commandhsset;
- CommandHSSetAll commandhssetall;
-
- public:
- HSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhsset(this), commandhssetall(this)
- {
- if (!IRCD || !IRCD->CanSetVHost)
- throw ModuleException("Your IRCd does not support vhosts");
- }
-};
-
-MODULE_INIT(HSSet)
diff --git a/modules/commands/ms_cancel.cpp b/modules/commands/ms_cancel.cpp
deleted file mode 100644
index 9e6f0ce63..000000000
--- a/modules/commands/ms_cancel.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandMSCancel : public Command
-{
- public:
- CommandMSCancel(Module *creator) : Command(creator, "memoserv/cancel", 1, 1)
- {
- this->SetDesc(_("Cancel the last memo you sent"));
- this->SetSyntax(_("{\037nick\037 | \037channel\037}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const Anope::string &nname = params[0];
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(nname, ischan);
-
- if (mi == NULL)
- source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), nname.c_str());
- else
- {
- ChannelInfo *ci = NULL;
- NickAlias *na = NULL;
- if (ischan)
- ci = ChannelInfo::Find(nname);
- else
- na = NickAlias::Find(nname);
- for (int i = mi->memos->size() - 1; i >= 0; --i)
- if (mi->GetMemo(i)->unread && source.nc->display.equals_ci(mi->GetMemo(i)->sender))
- {
- FOREACH_MOD(OnMemoDel, (ischan ? ci->name : na->nc->display, mi, mi->GetMemo(i)));
- mi->Del(i);
- source.Reply(_("Last memo to \002%s\002 has been cancelled."), nname.c_str());
- return;
- }
-
- source.Reply(_("No memo was cancelable."));
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Cancels the last memo you sent to the given nick or channel,\n"
- "provided it has not been read at the time you use the command."));
- return true;
- }
-};
-
-class MSCancel : public Module
-{
- CommandMSCancel commandmscancel;
-
- public:
- MSCancel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmscancel(this)
- {
- }
-};
-
-MODULE_INIT(MSCancel)
diff --git a/modules/commands/ms_check.cpp b/modules/commands/ms_check.cpp
deleted file mode 100644
index 707da95cd..000000000
--- a/modules/commands/ms_check.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandMSCheck : public Command
-{
- public:
- CommandMSCheck(Module *creator) : Command(creator, "memoserv/check", 1, 1)
- {
- this->SetDesc(_("Checks if last memo to a nick was read"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &recipient = params[0];
-
- bool found = false;
-
- const NickAlias *na = NickAlias::Find(recipient);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, recipient.c_str());
- return;
- }
-
- MemoInfo *mi = &na->nc->memos;
-
- /* Okay, I know this looks strange but we want to get the LAST memo, so we
- have to loop backwards */
-
- for (unsigned i = mi->memos->size(); i > 0; --i)
- {
- Memo *m = mi->GetMemo(i - 1);
- NickAlias *na2 = NickAlias::Find(m->sender);
-
- if (na2 != NULL && na2->nc == source.GetAccount())
- {
- found = true; /* Yes, we've found the memo */
-
- if (m->unread)
- source.Reply(_("The last memo you sent to %s (sent on %s) has not yet been read."), na->nick.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
- else
- source.Reply(_("The last memo you sent to %s (sent on %s) has been read."), na->nick.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
- break;
- }
- }
-
- if (!found)
- source.Reply(_("Nick %s doesn't have a memo from you."), na->nick.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Checks whether the _last_ memo you sent to \037nick\037 has been read\n"
- "or not. Note that this only works with nicks, not with channels."));
- return true;
- }
-};
-
-class MSCheck : public Module
-{
- CommandMSCheck commandmscheck;
-
- public:
- MSCheck(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmscheck(this)
- {
-
- }
-};
-
-MODULE_INIT(MSCheck)
diff --git a/modules/commands/ms_del.cpp b/modules/commands/ms_del.cpp
deleted file mode 100644
index bc496d72e..000000000
--- a/modules/commands/ms_del.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class MemoDelCallback : public NumberList
-{
- CommandSource &source;
- ChannelInfo *ci;
- MemoInfo *mi;
- public:
- MemoDelCallback(CommandSource &_source, ChannelInfo *_ci, MemoInfo *_mi, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), mi(_mi)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > mi->memos->size())
- return;
-
- FOREACH_MOD(OnMemoDel, (ci ? ci->name : source.nc->display, mi, mi->GetMemo(number - 1)));
-
- mi->Del(number - 1);
- source.Reply(_("Memo %d has been deleted."), number);
- }
-};
-
-class CommandMSDel : public Command
-{
- public:
- CommandMSDel(Module *creator) : Command(creator, "memoserv/del", 0, 2)
- {
- this->SetDesc(_("Delete a memo or memos"));
- this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | ALL}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- MemoInfo *mi;
- ChannelInfo *ci = NULL;
- Anope::string numstr = !params.empty() ? params[0] : "", chan;
-
- if (!numstr.empty() && numstr[0] == '#')
- {
- chan = numstr;
- numstr = params.size() > 1 ? params[1] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- else
- mi = &source.nc->memos;
- if (numstr.empty() || (!isdigit(numstr[0]) && !numstr.equals_ci("ALL") && !numstr.equals_ci("LAST")))
- this->OnSyntaxError(source, numstr);
- else if (mi->memos->empty())
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_MEMOS);
- }
- else
- {
- if (isdigit(numstr[0]))
- {
- MemoDelCallback list(source, ci, mi, numstr);
- list.Process();
- }
- else if (numstr.equals_ci("LAST"))
- {
- /* Delete last memo. */
- FOREACH_MOD(OnMemoDel, (ci ? ci->name : source.nc->display, mi, mi->GetMemo(mi->memos->size() - 1)));
- mi->Del(mi->memos->size() - 1);
- source.Reply(_("Memo %d has been deleted."), mi->memos->size() + 1);
- }
- else
- {
- /* Delete all memos. */
- for (unsigned i = mi->memos->size(); i > 0; --i)
- {
- FOREACH_MOD(OnMemoDel, (ci ? ci->name : source.nc->display, mi, mi->GetMemo(i)));
- mi->Del(i - 1);
- }
- if (!chan.empty())
- source.Reply(_("All memos for channel %s have been deleted."), chan.c_str());
- else
- source.Reply(_("All of your memos have been deleted."));
- }
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Deletes the specified memo or memos. You can supply\n"
- "multiple memo numbers or ranges of numbers instead of a\n"
- "single number, as in the second example below.\n"
- " \n"
- "If \002LAST\002 is given, the last memo will be deleted.\n"
- "If \002ALL\002 is given, deletes all of your memos.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002DEL 1\002\n"
- " Deletes your first memo.\n"
- " \n"
- " \002DEL 2-5,7-9\002\n"
- " Deletes memos numbered 2 through 5 and 7 through 9."));
- return true;
- }
-};
-
-class MSDel : public Module
-{
- CommandMSDel commandmsdel;
-
- public:
- MSDel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsdel(this)
- {
-
- }
-};
-
-MODULE_INIT(MSDel)
diff --git a/modules/commands/ms_ignore.cpp b/modules/commands/ms_ignore.cpp
deleted file mode 100644
index 6a2fa01cf..000000000
--- a/modules/commands/ms_ignore.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandMSIgnore : public Command
-{
- public:
- CommandMSIgnore(Module *creator) : Command(creator, "memoserv/ignore", 1, 3)
- {
- this->SetDesc(_("Manage the memo ignore list"));
- this->SetSyntax(_("[\037channel\037] ADD \037entry\037"));
- this->SetSyntax(_("[\037channel\037] DEL \037entry\037"));
- this->SetSyntax(_("[\037channel\037] LIST"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- Anope::string channel = params[0];
- Anope::string command = (params.size() > 1 ? params[1] : "");
- Anope::string param = (params.size() > 2 ? params[2] : "");
-
- if (channel[0] != '#')
- {
- param = command;
- command = channel;
- channel = source.GetNick();
- }
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(channel, ischan);
- ChannelInfo *ci = ChannelInfo::Find(channel);
- if (!mi)
- source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), channel.c_str());
- else if (ischan && !source.AccessFor(ci).HasPriv("MEMO"))
- source.Reply(ACCESS_DENIED);
- else if (command.equals_ci("ADD") && !param.empty())
- {
- if (mi->ignores.size() >= Config->GetModule(this->owner)->Get<unsigned>("max", "32"))
- {
- source.Reply(_("Sorry, the memo ignore list for \002%s\002 is full."), channel.c_str());
- return;
- }
-
- if (std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str()) == mi->ignores.end())
- {
- mi->ignores.push_back(param.ci_str());
- source.Reply(_("\002%s\002 added to ignore list."), param.c_str());
- }
- else
- source.Reply(_("\002%s\002 is already on the ignore list."), param.c_str());
- }
- else if (command.equals_ci("DEL") && !param.empty())
- {
- std::vector<Anope::string>::iterator it = std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str());
-
- if (it != mi->ignores.end())
- {
- mi->ignores.erase(it);
- source.Reply(_("\002%s\002 removed from the ignore list."), param.c_str());
- }
- else
- source.Reply(_("\002%s\002 is not on the ignore list."), param.c_str());
- }
- else if (command.equals_ci("LIST"))
- {
- if (mi->ignores.empty())
- source.Reply(_("Memo ignore list is empty."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mask"));
- for (unsigned i = 0; i < mi->ignores.size(); ++i)
- {
- ListFormatter::ListEntry entry;
- entry["Mask"] = mi->ignores[i];
- list.AddEntry(entry);
- }
-
- source.Reply(_("Ignore list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to ignore users by nick or host from memoing\n"
- "you or a channel. If someone on the memo ignore list tries\n"
- "to memo you or a channel, they will not be told that you have\n"
- "them ignored."));
- return true;
- }
-};
-
-class MSIgnore : public Module
-{
- CommandMSIgnore commandmsignore;
-
- public:
- MSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsignore(this)
- {
- }
-};
-
-MODULE_INIT(MSIgnore)
diff --git a/modules/commands/ms_info.cpp b/modules/commands/ms_info.cpp
deleted file mode 100644
index 8f99557bf..000000000
--- a/modules/commands/ms_info.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandMSInfo : public Command
-{
- public:
- CommandMSInfo(Module *creator) : Command(creator, "memoserv/info", 0, 1)
- {
- this->SetDesc(_("Displays information about your memos"));
- this->SetSyntax(_("[\037nick\037 | \037channel\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- NickCore *nc = source.nc;
- const MemoInfo *mi;
- const NickAlias *na = NULL;
- ChannelInfo *ci = NULL;
- const Anope::string &nname = !params.empty() ? params[0] : "";
- bool hardmax;
-
- if (!nname.empty() && nname[0] != '#' && source.HasPriv("memoserv/info"))
- {
- na = NickAlias::Find(nname);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nname.c_str());
- return;
- }
- mi = &na->nc->memos;
- hardmax = na->nc->HasExt("MEMO_HARDMAX");
- }
- else if (!nname.empty() && nname[0] == '#')
- {
- ci = ChannelInfo::Find(nname);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, nname.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- hardmax = ci->HasExt("MEMO_HARDMAX");
- }
- else if (!nname.empty()) /* It's not a chan and we aren't services admin */
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- {
- mi = &nc->memos;
- hardmax = nc->HasExt("MEMO_HARDMAX");
- }
-
- if (!nname.empty() && (ci || na->nc != nc))
- {
- if (mi->memos->empty())
- source.Reply(_("%s currently has no memos."), nname.c_str());
- else if (mi->memos->size() == 1)
- {
- if (mi->GetMemo(0)->unread)
- source.Reply(_("%s currently has \0021\002 memo, and it has not yet been read."), nname.c_str());
- else
- source.Reply(_("%s currently has \0021\002 memo."), nname.c_str());
- }
- else
- {
- unsigned count = 0, i, end;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- ++count;
- if (count == mi->memos->size())
- source.Reply(_("%s currently has \002%d\002 memos; all of them are unread."), nname.c_str(), count);
- else if (!count)
- source.Reply(_("%s currently has \002%d\002 memos."), nname.c_str(), mi->memos->size());
- else if (count == 1)
- source.Reply(_("%s currently has \002%d\002 memos, of which \0021\002 is unread."), nname.c_str(), mi->memos->size());
- else
- source.Reply(_("%s currently has \002%d\002 memos, of which \002%d\002 are unread."), nname.c_str(), mi->memos->size(), count);
- }
- if (!mi->memomax)
- {
- if (hardmax)
- source.Reply(_("%s's memo limit is \002%d\002, and may not be changed."), nname.c_str(), mi->memomax);
- else
- source.Reply(_("%s's memo limit is \002%d\002."), nname.c_str(), mi->memomax);
- }
- else if (mi->memomax > 0)
- {
- if (hardmax)
- source.Reply(_("%s's memo limit is \002%d\002, and may not be changed."), nname.c_str(), mi->memomax);
- else
- source.Reply(_("%s's memo limit is \002%d\002."), nname.c_str(), mi->memomax);
- }
- else
- source.Reply(_("%s has no memo limit."), nname.c_str());
-
- /* I ripped this code out of ircservices 4.4.5, since I didn't want
- to rewrite the whole thing (it pisses me off). */
- if (na)
- {
- if (na->nc->HasExt("MEMO_RECEIVE") && na->nc->HasExt("MEMO_SIGNON"))
- source.Reply(_("%s is notified of new memos at logon and when they arrive."), nname.c_str());
- else if (na->nc->HasExt("MEMO_RECEIVE"))
- source.Reply(_("%s is notified when new memos arrive."), nname.c_str());
- else if (na->nc->HasExt("MEMO_SIGNON"))
- source.Reply(_("%s is notified of news memos at logon."), nname.c_str());
- else
- source.Reply(_("%s is not notified of new memos."), nname.c_str());
- }
- }
- else /* !nname || (!ci || na->nc == nc) */
- {
- if (mi->memos->empty())
- source.Reply(_("You currently have no memos."));
- else if (mi->memos->size() == 1)
- {
- if (mi->GetMemo(0)->unread)
- source.Reply(_("You currently have \0021\002 memo, and it has not yet been read."));
- else
- source.Reply(_("You currently have \0021\002 memo."));
- }
- else
- {
- unsigned count = 0, i, end;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- ++count;
- if (count == mi->memos->size())
- source.Reply(_("You currently have \002%d\002 memos; all of them are unread."), count);
- else if (!count)
- source.Reply(_("You currently have \002%d\002 memos."), mi->memos->size());
- else if (count == 1)
- source.Reply(_("You currently have \002%d\002 memos, of which \0021\002 is unread."), mi->memos->size());
- else
- source.Reply(_("You currently have \002%d\002 memos, of which \002%d\002 are unread."), mi->memos->size(), count);
- }
-
- if (!mi->memomax)
- {
- if (!source.IsServicesOper() && hardmax)
- source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos. You cannot change this limit."));
- else
- source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos."));
- }
- else if (mi->memomax > 0)
- {
- if (!source.IsServicesOper() && hardmax)
- source.Reply(_("Your memo limit is \002%d\002, and may not be changed."), mi->memomax);
- else
- source.Reply(_("Your memo limit is \002%d\002."), mi->memomax);
- }
- else
- source.Reply(_("You have no limit on the number of memos you may keep."));
-
- bool memo_mail = nc->HasExt("MEMO_MAIL");
- if (nc->HasExt("MEMO_RECEIVE") && nc->HasExt("MEMO_SIGNON"))
- {
- if (memo_mail)
- source.Reply(_("You will be notified of new memos at logon and when they arrive, and by mail when they arrive."));
- else
- source.Reply(_("You will be notified of new memos at logon and when they arrive."));
- }
- else if (nc->HasExt("MEMO_RECEIVE"))
- {
- if (memo_mail)
- source.Reply(_("You will be notified by message and by mail when new memos arrive."));
- else
- source.Reply(_("You will be notified when new memos arrive."));
- }
- else if (nc->HasExt("MEMO_SIGNON"))
- {
- if (memo_mail)
- source.Reply(_("You will be notified of new memos at logon, and by mail when they arrive."));
- else
- source.Reply(_("You will be notified of new memos at logon."));
- }
- else
- {
- source.Reply(_("You will not be notified of new memos."));
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Without a parameter, displays information on the number of\n"
- "memos you have, how many of them are unread, and how many\n"
- "total memos you can receive.\n"
- " \n"
- "With a channel parameter, displays the same information for\n"
- "the given channel.\n"
- " \n"
- "With a nickname parameter, displays the same information\n"
- "for the given nickname. This is limited to \002Services\002\n"
- "\002Operators\002."));
-
- return true;
- }
-};
-
-class MSInfo : public Module
-{
- CommandMSInfo commandmsinfo;
-
- public:
- MSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsinfo(this)
- {
-
- }
-};
-
-MODULE_INIT(MSInfo)
diff --git a/modules/commands/ms_list.cpp b/modules/commands/ms_list.cpp
deleted file mode 100644
index c386be81d..000000000
--- a/modules/commands/ms_list.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandMSList : public Command
-{
- public:
- CommandMSList(Module *creator) : Command(creator, "memoserv/list", 0, 2)
- {
- this->SetDesc(_("List your memos"));
- this->SetSyntax(_("[\037channel\037] [\037list\037 | NEW]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- Anope::string param = !params.empty() ? params[0] : "", chan;
- ChannelInfo *ci = NULL;
- const MemoInfo *mi;
-
- if (!param.empty() && param[0] == '#')
- {
- chan = param;
- param = params.size() > 1 ? params[1] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- else
- mi = &source.nc->memos;
-
- if (!param.empty() && !isdigit(param[0]) && !param.equals_ci("NEW"))
- this->OnSyntaxError(source, param);
- else if (!mi->memos->size())
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_MEMOS);
- }
- else
- {
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Number")).AddColumn(_("Sender")).AddColumn(_("Date/Time"));
-
- if (!param.empty() && isdigit(param[0]))
- {
- class MemoListCallback : public NumberList
- {
- ListFormatter &list;
- CommandSource &source;
- const MemoInfo *mi;
- public:
- MemoListCallback(ListFormatter &_list, CommandSource &_source, const MemoInfo *_mi, const Anope::string &numlist) : NumberList(numlist, false), list(_list), source(_source), mi(_mi)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > mi->memos->size())
- return;
-
- const Memo *m = mi->GetMemo(number - 1);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = (m->unread ? "* " : " ") + stringify(number);
- entry["Sender"] = m->sender;
- entry["Date/Time"] = Anope::strftime(m->time, source.GetAccount());
- this->list.AddEntry(entry);
- }
- }
- mlc(list, source, mi, param);
- mlc.Process();
- }
- else
- {
- if (!param.empty())
- {
- unsigned i, end;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- break;
- if (i == end)
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_NEW_MEMOS);
- return;
- }
- }
-
- for (unsigned i = 0, end = mi->memos->size(); i < end; ++i)
- {
- if (!param.empty() && !mi->GetMemo(i)->unread)
- continue;
-
- const Memo *m = mi->GetMemo(i);
-
- ListFormatter::ListEntry entry;
- entry["Number"] = (m->unread ? "* " : " ") + stringify(i + 1);
- entry["Sender"] = m->sender;
- entry["Date/Time"] = Anope::strftime(m->time, source.GetAccount());
- list.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- source.Reply(_("Memos for %s:"), ci ? ci->name.c_str() : source.GetNick().c_str());
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists any memos you currently have. With \002NEW\002, lists only\n"
- "new (unread) memos. Unread memos are marked with a \"*\"\n"
- "to the left of the memo number. You can also specify a list\n"
- "of numbers, as in the example below:\n"
- " \002LIST 2-5,7-9\002\n"
- " Lists memos numbered 2 through 5 and 7 through 9."));
- return true;
- }
-};
-
-class MSList : public Module
-{
- CommandMSList commandmslist;
-
- public:
- MSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmslist(this)
- {
-
- }
-};
-
-MODULE_INIT(MSList)
diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp
deleted file mode 100644
index 96103d30b..000000000
--- a/modules/commands/ms_read.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ");
-
-static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ)
-{
- /* Only send receipt if memos are allowed */
- if (MemoServService && !Anope::ReadOnly)
- {
- /* Get nick alias for sender */
- const NickAlias *na = NickAlias::Find(m->sender);
-
- if (!na)
- return;
-
- /* Get nick core for sender */
- const NickCore *nc = na->nc;
-
- if (!nc)
- return;
-
- /* Text of the memo varies if the recipient was a
- nick or channel */
- Anope::string text = Anope::printf(Language::Translate(na->nc, _("\002[auto-memo]\002 The memo you sent to %s has been viewed.")), targ.c_str());
-
- /* Send notification */
- MemoServService->Send(source.GetNick(), m->sender, text, true);
-
- /* Notify recipient of the memo that a notification has
- been sent to the sender */
- source.Reply(_("A notification memo has been sent to %s informing him/her you have\n"
- "read his/her memo."), nc->display.c_str());
- }
-
- /* Remove receipt flag from the original memo */
- m->receipt = false;
-}
-
-class MemoListCallback : public NumberList
-{
- CommandSource &source;
- MemoInfo *mi;
- const ChannelInfo *ci;
- bool found;
- public:
- MemoListCallback(CommandSource &_source, MemoInfo *_mi, const ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), mi(_mi), ci(_ci)
- {
- found = false;
- }
-
- ~MemoListCallback()
- {
- if (!found)
- source.Reply(_("No memos to display."));
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > mi->memos->size())
- return;
-
- MemoListCallback::DoRead(source, mi, ci, number - 1);
- found = true;
- }
-
- static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index)
- {
- Memo *m = mi->GetMemo(index);
- if (!m)
- return;
-
- if (ci)
- source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
- else
- source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str());
-
- BotInfo *bi;
- Anope::string cmd;
- if (Command::FindCommandFromService("memoserv/del", bi, cmd))
- {
- if (ci)
- source.Reply(_("To delete, type: \002%s%s %s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), ci->name.c_str(), index + 1);
- else
- source.Reply(_("To delete, type: \002%s%s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), index + 1);
- }
-
- source.Reply("%s", m->text.c_str());
- m->unread = false;
-
- /* Check if a receipt notification was requested */
- if (m->receipt)
- rsend_notify(source, mi, m, ci ? ci->name : source.GetNick());
- }
-};
-
-class CommandMSRead : public Command
-{
- public:
- CommandMSRead(Module *creator) : Command(creator, "memoserv/read", 1, 2)
- {
- this->SetDesc(_("Read a memo or memos"));
- this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | NEW}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- MemoInfo *mi;
- ChannelInfo *ci = NULL;
- Anope::string numstr = params[0], chan;
-
- if (!numstr.empty() && numstr[0] == '#')
- {
- chan = numstr;
- numstr = params.size() > 1 ? params[1] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- else
- mi = &source.nc->memos;
-
- if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && numstr.find_first_not_of("0123456789.,-") != Anope::string::npos))
- this->OnSyntaxError(source, numstr);
- else if (mi->memos->empty())
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_MEMOS);
- }
- else
- {
- int i, end;
-
- if (numstr.equals_ci("NEW"))
- {
- int readcount = 0;
- for (i = 0, end = mi->memos->size(); i < end; ++i)
- if (mi->GetMemo(i)->unread)
- {
- MemoListCallback::DoRead(source, mi, ci, i);
- ++readcount;
- }
- if (!readcount)
- {
- if (!chan.empty())
- source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str());
- else
- source.Reply(MEMO_HAVE_NO_NEW_MEMOS);
- }
- }
- else if (numstr.equals_ci("LAST"))
- {
- for (i = 0, end = mi->memos->size() - 1; i < end; ++i);
- MemoListCallback::DoRead(source, mi, ci, i);
- }
- else /* number[s] */
- {
- MemoListCallback list(source, mi, ci, numstr);
- list.Process();
- }
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends you the text of the memos specified. If LAST is\n"
- "given, sends you the memo you most recently received. If\n"
- "NEW is given, sends you all of your new memos. Otherwise,\n"
- "sends you memo number \037num\037. You can also give a list of\n"
- "numbers, as in this example:\n"
- " \n"
- " \002READ 2-5,7-9\002\n"
- " Displays memos numbered 2 through 5 and 7 through 9."));
- return true;
- }
-};
-
-class MSRead : public Module
-{
- CommandMSRead commandmsread;
-
- public:
- MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsread(this)
- {
-
- }
-};
-
-MODULE_INIT(MSRead)
diff --git a/modules/commands/ms_rsend.cpp b/modules/commands/ms_rsend.cpp
deleted file mode 100644
index b7744131a..000000000
--- a/modules/commands/ms_rsend.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSRSend : public Command
-{
- public:
- CommandMSRSend(Module *creator) : Command(creator, "memoserv/rsend", 2, 2)
- {
- this->SetDesc(_("Sends a memo and requests a read receipt"));
- this->SetSyntax(_("{\037nick\037 | \037channel\037} \037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- if (Anope::ReadOnly && !source.IsOper())
- {
- source.Reply(MEMO_SEND_DISABLED);
- return;
- }
-
- const Anope::string &nick = params[0];
- const Anope::string &text = params[1];
- const NickAlias *na = NULL;
-
- /* prevent user from rsend to themselves */
- if ((na = NickAlias::Find(nick)) && na->nc == source.GetAccount())
- {
- source.Reply(_("You can not request a receipt when sending a memo to yourself."));
- return;
- }
-
- if (Config->GetModule(this->owner)->Get<bool>("operonly") && !source.IsServicesOper())
- source.Reply(ACCESS_DENIED);
- else
- {
- MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text);
- if (result == MemoServService::MEMO_INVALID_TARGET)
- source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
- else if (result == MemoServService::MEMO_TOO_FAST)
- source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str());
- else if (result == MemoServService::MEMO_TARGET_FULL)
- source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str());
- else
- {
- source.Reply(_("Memo sent to \002%s\002."), nick.c_str());
-
- bool ischan;
- MemoInfo *mi = MemoInfo::GetMemoInfo(nick, ischan);
- if (mi == NULL)
- throw CoreException("NULL mi in ms_rsend");
- Memo *m = (mi->memos->size() ? mi->GetMemo(mi->memos->size() - 1) : NULL);
- if (m != NULL)
- m->receipt = true;
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends the named \037nick\037 or \037channel\037 a memo containing\n"
- "\037memo-text\037. When sending to a nickname, the recipient will\n"
- "receive a notice that he/she has a new memo. The target\n"
- "nickname/channel must be registered.\n"
- "Once the memo is read by its recipient, an automatic notification\n"
- "memo will be sent to the sender informing him/her that the memo\n"
- "has been read."));
- return true;
- }
-};
-
-class MSRSend : public Module
-{
- CommandMSRSend commandmsrsend;
-
- public:
- MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsrsend(this)
- {
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSRSend)
diff --git a/modules/commands/ms_send.cpp b/modules/commands/ms_send.cpp
deleted file mode 100644
index b028706d3..000000000
--- a/modules/commands/ms_send.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSSend : public Command
-{
- public:
- CommandMSSend(Module *creator) : Command(creator, "memoserv/send", 2, 2)
- {
- this->SetDesc(_("Send a memo to a nick or channel"));
- this->SetSyntax(_("{\037nick\037 | \037channel\037} \037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- const Anope::string &nick = params[0];
- const Anope::string &text = params[1];
-
- if (Anope::ReadOnly && !source.IsOper())
- {
- source.Reply(MEMO_SEND_DISABLED);
- return;
- }
-
- if (source.GetAccount()->HasExt("UNCONFIRMED"))
- {
- source.Reply(_("You must confirm your account before you may send a memo."));
- return;
- }
-
- MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text);
- if (result == MemoServService::MEMO_SUCCESS)
- {
- source.Reply(_("Memo sent to \002%s\002."), nick.c_str());
- Log(LOG_COMMAND, source, this) << "to send a memo to " << nick;
- }
- else if (result == MemoServService::MEMO_INVALID_TARGET)
- source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
- else if (result == MemoServService::MEMO_TOO_FAST)
- source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str());
- else if (result == MemoServService::MEMO_TARGET_FULL)
- source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends the named \037nick\037 or \037channel\037 a memo containing\n"
- "\037memo-text\037. When sending to a nickname, the recipient will\n"
- "receive a notice that he/she has a new memo. The target\n"
- "nickname/channel must be registered."));
- return true;
- }
-};
-
-class MSSend : public Module
-{
- CommandMSSend commandmssend;
-
- public:
- MSSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmssend(this)
- {
-
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSSend)
diff --git a/modules/commands/ms_sendall.cpp b/modules/commands/ms_sendall.cpp
deleted file mode 100644
index 4cc0f350c..000000000
--- a/modules/commands/ms_sendall.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSSendAll : public Command
-{
- public:
- CommandMSSendAll(Module *creator) : Command(creator, "memoserv/sendall", 1, 1)
- {
- this->SetDesc(_("Send a memo to all registered users"));
- this->SetSyntax(_("\037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- const Anope::string &text = params[0];
-
- Log(LOG_ADMIN, source, this) << "to send " << text;
-
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (nc != source.nc)
- memoserv->Send(source.GetNick(), nc->display, text);
- }
-
- source.Reply(_("A massmemo has been sent to all registered users."));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends all registered users a memo containing \037memo-text\037."));
- return true;
- }
-};
-
-class MSSendAll : public Module
-{
- CommandMSSendAll commandmssendall;
-
- public:
- MSSendAll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmssendall(this)
- {
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSSendAll)
diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp
deleted file mode 100644
index d407132c7..000000000
--- a/modules/commands/ms_set.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandMSSet : public Command
-{
- private:
- void DoNotify(CommandSource &source, const std::vector<Anope::string> &params, MemoInfo *mi)
- {
- const Anope::string &param = params[1];
- NickCore *nc = source.nc;
- BotInfo *MemoServ = Config->GetClient("MemoServ");
-
- if (!MemoServ)
- return;
-
- if (param.equals_ci("ON"))
- {
- nc->Extend<bool>("MEMO_SIGNON");
- nc->Extend<bool>("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str());
- }
- else if (param.equals_ci("LOGON"))
- {
- nc->Extend<bool>("MEMO_SIGNON");
- nc->Shrink<bool>("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str());
- }
- else if (param.equals_ci("NEW"))
- {
- nc->Shrink<bool>("MEMO_SIGNON");
- nc->Extend<bool>("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str());
- }
- else if (param.equals_ci("MAIL"))
- {
- if (!nc->email.empty())
- {
- nc->Extend<bool>("MEMO_MAIL");
- source.Reply(_("You will now be informed about new memos via email."));
- }
- else
- source.Reply(_("There's no email address set for your nick."));
- }
- else if (param.equals_ci("NOMAIL"))
- {
- nc->Shrink<bool>("MEMO_MAIL");
- source.Reply(_("You will no longer be informed via email."));
- }
- else if (param.equals_ci("OFF"))
- {
- nc->Shrink<bool>("MEMO_SIGNON");
- nc->Shrink<bool>("MEMO_RECEIVE");
- nc->Shrink<bool>("MEMO_MAIL");
- source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- void DoLimit(CommandSource &source, const std::vector<Anope::string> &params, MemoInfo *mi)
- {
-
- Anope::string p1 = params[1];
- Anope::string p2 = params.size() > 2 ? params[2] : "";
- Anope::string p3 = params.size() > 3 ? params[3] : "";
- Anope::string user, chan;
- int16_t limit;
- NickCore *nc = source.nc;
- ChannelInfo *ci = NULL;
- bool is_servadmin = source.HasPriv("memoserv/set-limit");
-
- if (p1[0] == '#')
- {
- chan = p1;
- p1 = p2;
- p2 = p3;
- p3 = params.size() > 4 ? params[4] : "";
-
- ci = ChannelInfo::Find(chan);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- return;
- }
- else if (!is_servadmin && !source.AccessFor(ci).HasPriv("MEMO"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- mi = &ci->memos;
- }
- if (is_servadmin)
- {
- if (!p2.empty() && !p2.equals_ci("HARD") && chan.empty())
- {
- const NickAlias *na;
- if (!(na = NickAlias::Find(p1)))
- {
- source.Reply(NICK_X_NOT_REGISTERED, p1.c_str());
- return;
- }
- user = p1;
- mi = &na->nc->memos;
- nc = na->nc;
- p1 = p2;
- p2 = p3;
- }
- else if (p1.empty() || (!p1.is_pos_number_only() && !p1.equals_ci("NONE")) || (!p2.empty() && !p2.equals_ci("HARD")))
- {
- this->OnSyntaxError(source, "");
- return;
- }
- if (!chan.empty())
- {
- if (!p2.empty())
- ci->Extend<bool>("MEMO_HARDMAX");
- else
- ci->Shrink<bool>("MEMO_HARDMAX");
- }
- else
- {
- if (!p2.empty())
- nc->Extend<bool>("MEMO_HARDMAX");
- else
- nc->Shrink<bool>("MEMO_HARDMAX");
- }
- limit = -1;
- try
- {
- limit = convertTo<int16_t>(p1);
- }
- catch (const ConvertException &) { }
- }
- else
- {
- if (p1.empty() || !p2.empty() || !isdigit(p1[0]))
- {
- this->OnSyntaxError(source, "");
- return;
- }
- if (!chan.empty() && ci->HasExt("MEMO_HARDMAX"))
- {
- source.Reply(_("The memo limit for %s may not be changed."), chan.c_str());
- return;
- }
- else if (chan.empty() && nc->HasExt("MEMO_HARDMAX"))
- {
- source.Reply(_("You are not permitted to change your memo limit."));
- return;
- }
- int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
- limit = -1;
- try
- {
- limit = convertTo<int16_t>(p1);
- }
- catch (const ConvertException &) { }
- /* The first character is a digit, but we could still go negative
- * from overflow... watch out! */
- if (limit < 0 || (max_memos > 0 && limit > max_memos))
- {
- if (!chan.empty())
- source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), max_memos);
- else
- source.Reply(_("You cannot set your memo limit higher than %d."), max_memos);
- return;
- }
- }
- mi->memomax = limit;
- if (limit > 0)
- {
- if (chan.empty() && nc == source.nc)
- source.Reply(_("Your memo limit has been set to \002%d\002."), limit);
- else
- source.Reply(_("Memo limit for %s set to \002%d\002."), !chan.empty() ? chan.c_str() : user.c_str(), limit);
- }
- else if (!limit)
- {
- if (chan.empty() && nc == source.nc)
- source.Reply(_("You will no longer be able to receive memos."));
- else
- source.Reply(_("Memo limit for %s set to \0020\002."), !chan.empty() ? chan.c_str() : user.c_str());
- }
- else
- {
- if (chan.empty() && nc == source.nc)
- source.Reply(_("Your memo limit has been disabled."));
- else
- source.Reply(_("Memo limit \002disabled\002 for %s."), !chan.empty() ? chan.c_str() : user.c_str());
- }
- return;
- }
- public:
- CommandMSSet(Module *creator) : Command(creator, "memoserv/set", 2, 5)
- {
- this->SetDesc(_("Set options related to memos"));
- this->SetSyntax(_("\037option\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- MemoInfo *mi = &source.nc->memos;
-
- if (Anope::ReadOnly)
- source.Reply(_("Sorry, memo option setting is temporarily disabled."));
- else if (cmd.equals_ci("NOTIFY"))
- return this->DoNotify(source, params, mi);
- else if (cmd.equals_ci("LIMIT"))
- return this->DoLimit(source, params, mi);
- else
- {
- this->OnSyntaxError(source, "");
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (subcommand.empty())
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various memo options. \037option\037 can be one of:\n"
- " \n"
- " NOTIFY Changes when you will be notified about\n"
- " new memos (only for nicknames)\n"
- " LIMIT Sets the maximum number of memos you can\n"
- " receive\n"
- " \n"
- "Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
- }
- else if (subcommand.equals_ci("NOTIFY"))
- source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
- " \n"
- "Changes when you will be notified about new memos:\n"
- " \n"
- " ON You will be notified of memos when you log on,\n"
- " when you unset /AWAY, and when they are sent\n"
- " to you.\n"
- " LOGON You will only be notified of memos when you log\n"
- " on or when you unset /AWAY.\n"
- " NEW You will only be notified of memos when they\n"
- " are sent to you.\n"
- " MAIL You will be notified of memos by email as well as\n"
- " any other settings you have.\n"
- " NOMAIL You will not be notified of memos by email.\n"
- " OFF You will not receive any notification of memos.\n"
- " \n"
- "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined."));
- else if (subcommand.equals_ci("LIMIT"))
- {
- int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
- if (source.IsServicesOper())
- source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
- " \n"
- "Sets the maximum number of memos a user or channel is\n"
- "allowed to have. Setting the limit to 0 prevents the user\n"
- "from receiving any memos; setting it to \002NONE\002 allows the\n"
- "user to receive and keep as many memos as they want. If\n"
- "you do not give a nickname or channel, your own limit is\n"
- "set.\n"
- " \n"
- "Adding \002HARD\002 prevents the user from changing the limit. Not\n"
- "adding \002HARD\002 has the opposite effect, allowing the user to\n"
- "change the limit (even if a previous limit was set with\n"
- "\002HARD\002).\n"
- " \n"
- "This use of the \002SET LIMIT\002 command is limited to \002Services\002\n"
- "\002Operators\002. Other users may only enter a limit for themselves\n"
- "or a channel on which they have such privileges, may not\n"
- "remove their limit, may not set a limit above %d, and may\n"
- "not set a hard limit."), max_memos);
- else
- source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n"
- " \n"
- "Sets the maximum number of memos you (or the given channel)\n"
- "are allowed to have. If you set this to 0, no one will be\n"
- "able to send any memos to you. However, you cannot set\n"
- "this any higher than %d."), max_memos);
- }
- else
- return false;
-
- return true;
- }
-};
-
-class MSSet : public Module
-{
- CommandMSSet commandmsset;
- SerializableExtensibleItem<bool> memo_signon, memo_receive, memo_mail, memo_hardmax;
-
- public:
- MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsset(this), memo_signon(this, "MEMO_SIGNON"), memo_receive(this, "MEMO_RECEIVE"), memo_mail(this, "MEMO_MAIL"),
- memo_hardmax(this, "MEMO_HARDMAX")
- {
-
- }
-};
-
-MODULE_INIT(MSSet)
diff --git a/modules/commands/ms_staff.cpp b/modules/commands/ms_staff.cpp
deleted file mode 100644
index b3554fab8..000000000
--- a/modules/commands/ms_staff.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* MemoServ core functions
- *
- * (C) 2003-2016 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"
-
-namespace
-{
- ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-}
-
-class CommandMSStaff : public Command
-{
- public:
- CommandMSStaff(Module *creator) : Command(creator, "memoserv/staff", 1, 1)
- {
- this->SetDesc(_("Send a memo to all opers/admins"));
- this->SetSyntax(_("\037memo-text\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!memoserv)
- return;
-
- const Anope::string &text = params[0];
-
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (source.nc != nc && nc->IsServicesOper())
- memoserv->Send(source.GetNick(), nc->display, text, true);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends all services staff a memo containing \037memo-text\037."));
-
- return true;
- }
-};
-
-class MSStaff : public Module
-{
- CommandMSStaff commandmsstaff;
-
- public:
- MSStaff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandmsstaff(this)
- {
- if (!memoserv)
- throw ModuleException("No MemoServ!");
- }
-};
-
-MODULE_INIT(MSStaff)
diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp
deleted file mode 100644
index e54252c65..000000000
--- a/modules/commands/ns_access.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSAccess : public Command
-{
- private:
- void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask)
- {
- if (mask.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax", "32"))
- {
- source.Reply(_("Sorry, the maximum of %d access entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
- return;
- }
-
- if (nc->FindAccess(mask))
- {
- source.Reply(_("Mask \002%s\002 already present on %s's access list."), mask.c_str(), nc->display.c_str());
- return;
- }
-
- nc->AddAccess(mask);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD mask " << mask << " to " << nc->display;
- source.Reply(_("\002%s\002 added to %s's access list."), mask.c_str(), nc->display.c_str());
-
- return;
- }
-
- void DoDel(CommandSource &source, NickCore *nc, const Anope::string &mask)
- {
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (!nc->FindAccess(mask))
- {
- source.Reply(_("\002%s\002 not found on %s's access list."), mask.c_str(), nc->display.c_str());
- return;
- }
-
- nc->EraseAccess(mask);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE mask " << mask << " from " << nc->display;
- source.Reply(_("\002%s\002 deleted from %s's access list."), mask.c_str(), nc->display.c_str());
-
- return;
- }
-
- void DoList(CommandSource &source, NickCore *nc, const Anope::string &mask)
- {
- unsigned i, end;
-
- if (nc->access.empty())
- {
- source.Reply(_("%s's access list is empty."), nc->display.c_str());
- return;
- }
-
- source.Reply(_("Access list for %s:"), nc->display.c_str());
- for (i = 0, end = nc->access.size(); i < end; ++i)
- {
- Anope::string access = nc->GetAccess(i);
- if (!mask.empty() && !Anope::Match(access, mask))
- continue;
- source.Reply(" %s", access.c_str());
- }
-
- return;
- }
- public:
- CommandNSAccess(Module *creator) : Command(creator, "nickserv/access", 1, 3)
- {
- this->SetDesc(_("Modify the list of authorized addresses"));
- this->SetSyntax(_("ADD [\037nickname\037] \037mask\037"));
- this->SetSyntax(_("DEL [\037nickname\037] \037mask\037"));
- this->SetSyntax(_("LIST [\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- Anope::string nick, mask;
-
- if (cmd.equals_ci("LIST"))
- nick = params.size() > 1 ? params[1] : "";
- else
- {
- nick = params.size() == 3 ? params[1] : "";
- mask = params.size() > 1 ? params[params.size() - 1] : "";
- }
-
- NickCore *nc;
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.HasPriv("nickserv/access"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
- {
- source.Reply(_("You may view but not modify the access list of other Services Operators."));
- return;
- }
-
- nc = na->nc;
- }
- else
- nc = source.nc;
-
- if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos))
- {
- source.Reply(BAD_USERHOST_MASK);
- source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
- }
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, nc, mask);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, nc, mask);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, nc, mask);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Modifies or displays the access list for your nick. This\n"
- "is the list of addresses which will be automatically\n"
- "recognized by %s as allowed to use the nick. If\n"
- "you want to use the nick from a different address, you\n"
- "need to send an \002IDENTIFY\002 command to make %s\n"
- "recognize you. Services Operators may provide a nick\n"
- "to modify other users' access lists.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002ACCESS ADD anyone@*.bepeg.com\002\n"
- " Allows access to user \002anyone\002 from any machine in\n"
- " the \002bepeg.com\002 domain.\n"
- " \n"
- " \002ACCESS DEL anyone@*.bepeg.com\002\n"
- " Reverses the previous command.\n"
- " \n"
- " \002ACCESS LIST\002\n"
- " Displays the current access list."), source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class NSAccess : public Module
-{
- CommandNSAccess commandnsaccess;
-
- public:
- NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsaccess(this)
- {
- }
-
- void OnNickRegister(User *u, NickAlias *na, const Anope::string &) anope_override
- {
- if (u && Config->GetModule(this)->Get<bool>("addaccessonreg"))
- na->nc->AddAccess(u->Mask());
- }
-};
-
-MODULE_INIT(NSAccess)
diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp
deleted file mode 100644
index b62029fad..000000000
--- a/modules/commands/ns_ajoin.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-struct AJoinEntry;
-
-struct AJoinList : Serialize::Checker<std::vector<AJoinEntry *> >
-{
- AJoinList(Extensible *) : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
- ~AJoinList();
-};
-
-struct AJoinEntry : Serializable
-{
- Serialize::Reference<NickCore> owner;
- Anope::string channel;
- Anope::string key;
-
- AJoinEntry(Extensible *) : Serializable("AJoinEntry") { }
-
- ~AJoinEntry()
- {
- AJoinList *channels = owner->GetExt<AJoinList>("ajoinlist");
- if (channels)
- {
- std::vector<AJoinEntry *>::iterator it = std::find((*channels)->begin(), (*channels)->end(), this);
- if (it != (*channels)->end())
- (*channels)->erase(it);
- }
- }
-
- void Serialize(Serialize::Data &sd) const anope_override
- {
- if (!this->owner)
- return;
-
- sd["owner"] << this->owner->display;
- sd["channel"] << this->channel;
- sd["key"] << this->key;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &sd)
- {
- Anope::string sowner;
-
- sd["owner"] >> sowner;
-
- NickCore *nc = NickCore::Find(sowner);
- if (nc == NULL)
- return NULL;
-
- AJoinEntry *aj;
- if (obj)
- aj = anope_dynamic_static_cast<AJoinEntry *>(obj);
- else
- {
- aj = new AJoinEntry(nc);
- aj->owner = nc;
- }
-
- sd["channel"] >> aj->channel;
- sd["key"] >> aj->key;
-
- if (!obj)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
- (*channels)->push_back(aj);
- }
-
- return aj;
- }
-};
-
-AJoinList::~AJoinList()
-{
- for (unsigned i = 0; i < (*this)->size(); ++i)
- delete (*this)->at(i);
-}
-
-class CommandNSAJoin : public Command
-{
- void DoList(CommandSource &source, NickCore *nc)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
-
- if ((*channels)->empty())
- source.Reply(_("%s's auto join list is empty."), nc->display.c_str());
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Key"));
- for (unsigned i = 0; i < (*channels)->size(); ++i)
- {
- AJoinEntry *aj = (*channels)->at(i);
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Channel"] = aj->channel;
- entry["Key"] = aj->key;
- list.AddEntry(entry);
- }
-
- source.Reply(_("%s's auto join list:"), nc->display.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chans, const Anope::string &keys)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
-
- Anope::string addedchans;
- Anope::string alreadyadded;
- Anope::string invalidkey;
- commasepstream ksep(keys, true);
- commasepstream csep(chans);
- for (Anope::string chan, key; csep.GetToken(chan);)
- {
- ksep.GetToken(key);
-
- unsigned i = 0;
- for (; i < (*channels)->size(); ++i)
- if ((*channels)->at(i)->channel.equals_ci(chan))
- break;
-
- if ((*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax"))
- {
- source.Reply(_("Sorry, the maximum of %d auto join entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("ajoinmax"));
- return;
- }
- else if (i != (*channels)->size())
- alreadyadded += chan + ", ";
- else if (IRCD->IsChannelValid(chan) == false)
- source.Reply(CHAN_X_INVALID, chan.c_str());
- else
- {
- Channel *c = Channel::Find(chan);
- Anope::string k;
- if (c && c->GetParam("KEY", k) && key != k)
- {
- invalidkey += chan + ", ";
- continue;
- }
-
- AJoinEntry *entry = new AJoinEntry(nc);
- entry->owner = nc;
- entry->channel = chan;
- entry->key = key;
- (*channels)->push_back(entry);
- addedchans += chan + ", ";
- }
- }
-
- if (!alreadyadded.empty())
- {
- alreadyadded = alreadyadded.substr(0, alreadyadded.length() - 2);
- source.Reply(_("%s is already on %s's auto join list."), alreadyadded.c_str(), nc->display.c_str());
- }
-
- if (!invalidkey.empty())
- {
- invalidkey = invalidkey.substr(0, invalidkey.length() - 2);
- source.Reply(_("%s had an invalid key specified, and was thus ignored."), invalidkey.c_str());
- }
-
- if (addedchans.empty())
- return;
-
- addedchans = addedchans.substr(0, addedchans.length() - 2);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << addedchans << " to " << nc->display;
- source.Reply(_("%s added to %s's auto join list."), addedchans.c_str(), nc->display.c_str());
- }
-
- void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chans)
- {
- AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
- Anope::string delchans;
- Anope::string notfoundchans;
- commasepstream sep(chans);
-
- for (Anope::string chan; sep.GetToken(chan);)
- {
- unsigned i = 0;
- for (; i < (*channels)->size(); ++i)
- if ((*channels)->at(i)->channel.equals_ci(chan))
- break;
-
- if (i == (*channels)->size())
- notfoundchans += chan + ", ";
- else
- {
- delete (*channels)->at(i);
- delchans += chan + ", ";
- }
- }
-
- if (!notfoundchans.empty())
- {
- notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2);
- source.Reply(_("%s was not found on %s's auto join list."), notfoundchans.c_str(), nc->display.c_str());
- }
-
- if (delchans.empty())
- return;
-
- delchans = delchans.substr(0, delchans.length() - 2);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->display;
- source.Reply(_("%s was removed from %s's auto join list."), delchans.c_str(), nc->display.c_str());
-
- if ((*channels)->empty())
- nc->Shrink<AJoinList>("ajoinlist");
- }
-
- public:
- CommandNSAJoin(Module *creator) : Command(creator, "nickserv/ajoin", 1, 4)
- {
- this->SetDesc(_("Manage your auto join list"));
- this->SetSyntax(_("ADD [\037nickname\037] \037channel\037 [\037key\037]"));
- this->SetSyntax(_("DEL [\037nickname\037] \037channel\037"));
- this->SetSyntax(_("LIST [\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- Anope::string nick, param, param2;
-
- if (cmd.equals_ci("LIST"))
- nick = params.size() > 1 ? params[1] : "";
- else
- nick = (params.size() > 2 && IRCD->IsChannelValid(params[2])) ? params[1] : "";
-
- NickCore *nc;
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.HasCommand("nickserv/ajoin"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- nc = na->nc;
- param = params.size() > 2 ? params[2] : "";
- param2 = params.size() > 3 ? params[3] : "";
- }
- else
- {
- nc = source.nc;
- param = params.size() > 1 ? params[1] : "";
- param2 = params.size() > 2 ? params[2] : "";
- }
-
- if (cmd.equals_ci("LIST"))
- return this->DoList(source, nc);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
- else if (param.empty())
- this->OnSyntaxError(source, "");
- else if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, nc, param, param2);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, nc, param);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command manages your auto join list. When you identify\n"
- "you will automatically join the channels on your auto join list.\n"
- "Services Operators may provide a nick to modify other users'\n"
- "auto join lists."));
- return true;
- }
-};
-
-class NSAJoin : public Module
-{
- CommandNSAJoin commandnsajoin;
- ExtensibleItem<AJoinList> ajoinlist;
- Serialize::Type ajoinentry_type;
-
- public:
- NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsajoin(this), ajoinlist(this, "ajoinlist"),
- ajoinentry_type("AJoinEntry", AJoinEntry::Unserialize)
- {
-
- if (!IRCD || !IRCD->CanSVSJoin)
- throw ModuleException("Your IRCd does not support SVSJOIN");
-
- }
-
- void OnUserLogin(User *u) anope_override
- {
- BotInfo *NickServ = Config->GetClient("NickServ");
- if (!NickServ)
- return;
-
- AJoinList *channels = u->Account()->GetExt<AJoinList>("ajoinlist");
- if (channels == NULL)
- return;
-
- /* Set +r now, so we can ajoin users into +R channels */
- ModeManager::ProcessModes();
-
- for (unsigned i = 0; i < (*channels)->size(); ++i)
- {
- AJoinEntry *entry = (*channels)->at(i);
- Channel *c = Channel::Find(entry->channel);
- ChannelInfo *ci;
-
- if (c)
- ci = c->ci;
- else
- ci = ChannelInfo::Find(entry->channel);
-
- bool need_invite = false;
- Anope::string key = entry->key;
- AccessGroup u_access;
-
- if (ci != NULL)
- {
- if (ci->HasExt("CS_SUSPENDED"))
- continue;
- u_access = ci->AccessFor(u);
- }
- if (c != NULL)
- {
- if (c->FindUser(u) != NULL)
- continue;
- else if (c->HasMode("OPERONLY") && !u->HasMode("OPER"))
- continue;
- else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN"))
- continue;
- else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExt("ssl")))
- continue;
- else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false)
- need_invite = true;
- else if (c->HasMode("INVITE") && c->MatchesList(u, "INVITEOVERRIDE") == false)
- need_invite = true;
-
- if (c->HasMode("KEY"))
- {
- Anope::string k;
- if (c->GetParam("KEY", k))
- {
- if (u_access.HasPriv("GETKEY"))
- key = k;
- else if (key != k)
- need_invite = true;
- }
- }
- if (c->HasMode("LIMIT"))
- {
- Anope::string l;
- if (c->GetParam("LIMIT", l))
- {
- try
- {
- unsigned limit = convertTo<unsigned>(l);
- if (c->users.size() >= limit)
- need_invite = true;
- }
- catch (const ConvertException &) { }
- }
- }
- }
-
- if (need_invite && c != NULL)
- {
- if (!u_access.HasPriv("INVITE"))
- continue;
- IRCD->SendInvite(NickServ, c, u);
- }
-
- IRCD->SendSVSJoin(NickServ, u, entry->channel, key);
- }
- }
-};
-
-MODULE_INIT(NSAJoin)
diff --git a/modules/commands/ns_alist.cpp b/modules/commands/ns_alist.cpp
deleted file mode 100644
index 5f5efc7ea..000000000
--- a/modules/commands/ns_alist.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSAList : public Command
-{
- static bool ChannelSort(ChannelInfo *ci1, ChannelInfo *ci2)
- {
- return ci::less()(ci1->name, ci2->name);
- }
-
- public:
- CommandNSAList(Module *creator) : Command(creator, "nickserv/alist", 0, 2)
- {
- this->SetDesc(_("List channels you have access on"));
- this->SetSyntax(_("[\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string nick = source.GetNick();
- NickCore *nc = source.nc;
-
- if (params.size() && source.HasPriv("nickserv/alist"))
- {
- nick = params[0];
- const NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- nc = na->nc;
- }
-
- ListFormatter list(source.GetAccount());
- int chan_count = 0;
-
- list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Access")).AddColumn(_("Description"));
-
- std::deque<ChannelInfo *> queue;
- nc->GetChannelReferences(queue);
- std::sort(queue.begin(), queue.end(), ChannelSort);
-
- for (unsigned i = 0; i < queue.size(); ++i)
- {
- ChannelInfo *ci = queue[i];
- ListFormatter::ListEntry entry;
-
- if (ci->GetFounder() == nc)
- {
- ++chan_count;
- entry["Number"] = stringify(chan_count);
- entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
- entry["Access"] = Language::Translate(source.GetAccount(), _("Founder"));
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- continue;
- }
-
- if (ci->GetSuccessor() == nc)
- {
- ++chan_count;
- entry["Number"] = stringify(chan_count);
- entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
- entry["Access"] = Language::Translate(source.GetAccount(), _("Successor"));
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- continue;
- }
-
- AccessGroup access = ci->AccessFor(nc, false);
- if (access.empty())
- continue;
-
- ++chan_count;
-
- entry["Number"] = stringify(chan_count);
- entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
- for (unsigned j = 0; j < access.paths.size(); ++j)
- {
- ChanAccess::Path &p = access.paths[j];
-
- // not interested in indirect access
- if (p.size() != 1)
- continue;
-
- ChanAccess *a = p[0];
- entry["Access"] = entry["Access"] + ", " + a->AccessSerialize();
- }
- entry["Access"] = entry["Access"].substr(2);
- entry["Description"] = ci->desc;
- list.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- if (!chan_count)
- {
- source.Reply(_("\002%s\002 has no access in any channels."), nc->display.c_str());
- }
- else
- {
- source.Reply(_("Channels that \002%s\002 has access on:"), nc->display.c_str());
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of list - %d channels shown."), chan_count);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all channels you have access on.\n"
- " \n"
- "Channels that have the \037NOEXPIRE\037 option set will be\n"
- "prefixed by an exclamation mark. The nickname parameter is\n"
- "limited to Services Operators"));
-
- return true;
- }
-};
-
-class NSAList : public Module
-{
- CommandNSAList commandnsalist;
-
- public:
- NSAList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsalist(this)
- {
-
- }
-};
-
-MODULE_INIT(NSAList)
diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp
deleted file mode 100644
index 6fa5decab..000000000
--- a/modules/commands/ns_cert.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 "modules/ns_cert.h"
-
-static Anope::hash_map<NickCore *> certmap;
-
-struct CertServiceImpl : CertService
-{
- CertServiceImpl(Module *o) : CertService(o) { }
-
- NickCore* FindAccountFromCert(const Anope::string &cert) anope_override
- {
- Anope::hash_map<NickCore *>::iterator it = certmap.find(cert);
- if (it != certmap.end())
- return it->second;
- return NULL;
- }
-};
-
-struct NSCertListImpl : NSCertList
-{
- Serialize::Reference<NickCore> nc;
- std::vector<Anope::string> certs;
-
- public:
- NSCertListImpl(Extensible *obj) : nc(anope_dynamic_static_cast<NickCore *>(obj)) { }
-
- ~NSCertListImpl()
- {
- ClearCert();
- }
-
- /** Add an entry to the nick's certificate list
- *
- * @param entry The fingerprint to add to the cert list
- *
- * Adds a new entry into the cert list.
- */
- void AddCert(const Anope::string &entry) anope_override
- {
- this->certs.push_back(entry);
- certmap[entry] = nc;
- FOREACH_MOD(OnNickAddCert, (this->nc, entry));
- }
-
- /** Get an entry from the nick's cert list by index
- *
- * @param entry Index in the certificaate list vector to retrieve
- * @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
- *
- * Retrieves an entry from the certificate list corresponding to the given index.
- */
- Anope::string GetCert(unsigned entry) const anope_override
- {
- if (entry >= this->certs.size())
- return "";
- return this->certs[entry];
- }
-
- unsigned GetCertCount() const anope_override
- {
- return this->certs.size();
- }
-
- /** Find an entry in the nick's cert list
- *
- * @param entry The fingerprint to search for
- * @return True if the fingerprint is found in the cert list, false otherwise
- *
- * Search for an fingerprint within the cert list.
- */
- bool FindCert(const Anope::string &entry) const anope_override
- {
- return std::find(this->certs.begin(), this->certs.end(), entry) != this->certs.end();
- }
-
- /** Erase a fingerprint from the nick's certificate list
- *
- * @param entry The fingerprint to remove
- *
- * Removes the specified fingerprint from the cert list.
- */
- void EraseCert(const Anope::string &entry) anope_override
- {
- std::vector<Anope::string>::iterator it = std::find(this->certs.begin(), this->certs.end(), entry);
- if (it != this->certs.end())
- {
- FOREACH_MOD(OnNickEraseCert, (this->nc, entry));
- certmap.erase(entry);
- this->certs.erase(it);
- }
- }
-
- /** Clears the entire nick's cert list
- *
- * Deletes all the memory allocated in the certificate list vector and then clears the vector.
- */
- void ClearCert() anope_override
- {
- FOREACH_MOD(OnNickClearCert, (this->nc));
- for (unsigned i = 0; i < certs.size(); ++i)
- certmap.erase(certs[i]);
- this->certs.clear();
- }
-
- void Check() anope_override
- {
- if (this->certs.empty())
- nc->Shrink<NSCertList>("certificates");
- }
-
- struct ExtensibleItem : ::ExtensibleItem<NSCertListImpl>
- {
- ExtensibleItem(Module *m, const Anope::string &ename) : ::ExtensibleItem<NSCertListImpl>(m, ename) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- const NickCore *n = anope_dynamic_static_cast<const NickCore *>(e);
- NSCertList *c = this->Get(n);
- if (c == NULL || !c->GetCertCount())
- return;
-
- for (unsigned i = 0; i < c->GetCertCount(); ++i)
- data["cert"] << c->GetCert(i) << " ";
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- NickCore *n = anope_dynamic_static_cast<NickCore *>(e);
- NSCertListImpl *c = this->Require(n);
-
- Anope::string buf;
- data["cert"] >> buf;
- spacesepstream sep(buf);
- for (unsigned i = 0; i < c->certs.size(); ++i)
- certmap.erase(c->certs[i]);
- c->certs.clear();
- while (sep.GetToken(buf))
- {
- c->certs.push_back(buf);
- certmap[buf] = n;
- }
- }
- };
-};
-
-class CommandNSCert : public Command
-{
- private:
- void DoAdd(CommandSource &source, NickCore *nc, Anope::string certfp)
- {
- NSCertList *cl = nc->Require<NSCertList>("certificates");
- unsigned max = Config->GetModule(this->owner)->Get<unsigned>("max", "5");
-
- if (cl->GetCertCount() >= max)
- {
- source.Reply(_("Sorry, the maximum of %d certificate entries has been reached."), max);
- return;
- }
-
- if (source.GetAccount() == nc)
- {
- User *u = source.GetUser();
-
- if (!u || u->fingerprint.empty())
- {
- source.Reply(_("You are not using a client certificate."));
- return;
- }
-
- certfp = u->fingerprint;
- }
-
- if (cl->FindCert(certfp))
- {
- source.Reply(_("Fingerprint \002%s\002 already present on %s's certificate list."), certfp.c_str(), nc->display.c_str());
- return;
- }
-
- if (certmap.find(certfp) != certmap.end())
- {
- source.Reply(_("Fingerprint \002%s\002 is already in use."), certfp.c_str());
- return;
- }
-
- cl->AddCert(certfp);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD certificate fingerprint " << certfp << " to " << nc->display;
- source.Reply(_("\002%s\002 added to %s's certificate list."), certfp.c_str(), nc->display.c_str());
- }
-
- void DoDel(CommandSource &source, NickCore *nc, Anope::string certfp)
- {
- NSCertList *cl = nc->Require<NSCertList>("certificates");
-
- if (certfp.empty())
- {
- User *u = source.GetUser();
- if (u)
- certfp = u->fingerprint;
- }
-
- if (certfp.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (!cl->FindCert(certfp))
- {
- source.Reply(_("\002%s\002 not found on %s's certificate list."), certfp.c_str(), nc->display.c_str());
- return;
- }
-
- cl->EraseCert(certfp);
- cl->Check();
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE certificate fingerprint " << certfp << " from " << nc->display;
- source.Reply(_("\002%s\002 deleted from %s's certificate list."), certfp.c_str(), nc->display.c_str());
- }
-
- void DoList(CommandSource &source, const NickCore *nc)
- {
- NSCertList *cl = nc->GetExt<NSCertList>("certificates");
-
- if (!cl || !cl->GetCertCount())
- {
- source.Reply(_("%s's certificate list is empty."), nc->display.c_str());
- return;
- }
-
- source.Reply(_("Certificate list for %s:"), nc->display.c_str());
- for (unsigned i = 0; i < cl->GetCertCount(); ++i)
- {
- Anope::string fingerprint = cl->GetCert(i);
- source.Reply(" %s", fingerprint.c_str());
- }
- }
-
- public:
- CommandNSCert(Module *creator) : Command(creator, "nickserv/cert", 1, 3)
- {
- this->SetDesc(_("Modify the nickname client certificate list"));
- this->SetSyntax(_("ADD [\037nickname\037] [\037fingerprint\037]"));
- this->SetSyntax(_("DEL [\037nickname\037] \037fingerprint\037"));
- this->SetSyntax(_("LIST [\037nickname\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- Anope::string nick, certfp;
-
- if (cmd.equals_ci("LIST"))
- nick = params.size() > 1 ? params[1] : "";
- else
- {
- nick = params.size() == 3 ? params[1] : "";
- certfp = params.size() > 1 ? params[params.size() - 1] : "";
- }
-
- NickCore *nc;
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.HasPriv("nickserv/access"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
- {
- source.Reply(_("You may view but not modify the certificate list of other Services Operators."));
- return;
- }
-
- nc = na->nc;
- }
- else
- nc = source.nc;
-
- if (cmd.equals_ci("LIST"))
- return this->DoList(source, nc);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
- else if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, nc, certfp);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, nc, certfp);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Modifies or displays the certificate list for your nick.\n"
- "If you connect to IRC and provide a client certificate with a\n"
- "matching fingerprint in the cert list, you will be\n"
- "automatically identified to services. Services Operators\n"
- "may provide a nick to modify other users' certificate lists.\n"
- " \n"));
- source.Reply(_("Examples:\n"
- " \n"
- " \002CERT ADD\002\n"
- " Adds your current fingerprint to the certificate list and\n"
- " automatically identifies you when you connect to IRC\n"
- " using this fingerprint.\n"
- " \n"
- " \002CERT DEL <fingerprint>\002\n"
- " Removes the fingerprint <fingerprint> from your certificate list.\n"
- " \n"
- " \002CERT LIST\002\n"
- " Displays the current certificate list."));
- return true;
- }
-};
-
-class NSCert : public Module
-{
- CommandNSCert commandnscert;
- NSCertListImpl::ExtensibleItem certs;
- CertServiceImpl cs;
-
- public:
- NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnscert(this), certs(this, "certificates"), cs(this)
- {
- if (!IRCD || !IRCD->CanCertFP)
- throw ModuleException("Your IRCd does not support ssl client certificates");
- }
-
- void OnFingerprint(User *u) anope_override
- {
- BotInfo *NickServ = Config->GetClient("NickServ");
- if (!NickServ || u->IsIdentified())
- return;
-
- NickCore *nc = cs.FindAccountFromCert(u->fingerprint);
- if (!nc || nc->HasExt("NS_SUSPENDED"))
- return;
-
- unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
- if (maxlogins && nc->users.size() >= maxlogins)
- {
- u->SendMessage(NickServ, _("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), nc->display.c_str(), maxlogins);
- return;
- }
-
- NickAlias *na = NickAlias::Find(u->nick);
- if (na && na->nc == nc)
- u->Identify(na);
- else
- u->Login(nc);
-
- u->SendMessage(NickServ, _("SSL certificate fingerprint accepted, you are now identified to \002%s\002."), nc->display.c_str());
- Log(NickServ) << u->GetMask() << " automatically identified for account " << nc->display << " via SSL certificate fingerprint";
- }
-
- EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
- {
- NSCertList *cl = certs.Get(na->nc);
- if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint))
- {
- BotInfo *NickServ = Config->GetClient("NickServ");
-
- unsigned int maxlogins = Config->GetModule("ns_identify")->Get<unsigned int>("maxlogins");
- if (maxlogins && na->nc->users.size() >= maxlogins)
- {
- u->SendMessage(NickServ, _("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), na->nc->display.c_str(), maxlogins);
- return EVENT_CONTINUE;
- }
-
- u->Identify(na);
-
- u->SendMessage(NickServ, _("SSL certificate fingerprint accepted, you are now identified."));
- Log(NickServ) << u->GetMask() << " automatically identified for account " << na->nc->display << " via SSL certificate fingerprint";
- return EVENT_ALLOW;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(NSCert)
diff --git a/modules/commands/ns_drop.cpp b/modules/commands/ns_drop.cpp
deleted file mode 100644
index df632fd24..000000000
--- a/modules/commands/ns_drop.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSDrop : public Command
-{
- public:
- CommandNSDrop(Module *creator) : Command(creator, "nickserv/drop", 1, 1)
- {
- this->SetSyntax(_("\037nickname\037"));
- this->SetDesc(_("Cancel the registration of a nickname"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
-
- if (Anope::ReadOnly && !source.HasPriv("nickserv/drop"))
- {
- source.Reply(_("Sorry, nickname de-registration is temporarily disabled."));
- return;
- }
-
- NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- bool is_mine = source.GetAccount() == na->nc;
-
- if (!is_mine && !source.HasPriv("nickserv/drop"))
- source.Reply(ACCESS_DENIED);
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && !is_mine && na->nc->IsServicesOper())
- source.Reply(_("You may not drop other Services Operators' nicknames."));
- else
- {
- FOREACH_MOD(OnNickDrop, (source, na));
-
- Log(!is_mine ? LOG_ADMIN : LOG_COMMAND, source, this) << "to drop nickname " << na->nick << " (group: " << na->nc->display << ") (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")";
- delete na;
-
- source.Reply(_("Nickname \002%s\002 has been dropped."), nick.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Drops the given nick from the database. Once your nickname\n"
- "is dropped you may lose all of your access and channels that\n"
- "you may own. Any other user will be able to gain control of\n"
- "this nick."));
- if (!source.HasPriv("nickserv/drop"))
- source.Reply(_("You may drop any nick within your group."));
- else
- source.Reply(_("As a Services Operator, you may drop any nick."));
-
- return true;
- }
-};
-
-class NSDrop : public Module
-{
- CommandNSDrop commandnsdrop;
-
- public:
- NSDrop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsdrop(this)
- {
-
- }
-};
-
-MODULE_INIT(NSDrop)
diff --git a/modules/commands/ns_getemail.cpp b/modules/commands/ns_getemail.cpp
deleted file mode 100644
index 0e782938f..000000000
--- a/modules/commands/ns_getemail.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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.
- *
- * A simple call to check for all emails that a user may have registered
- * with. It returns the nicks that match the email you provide. Wild
- * Cards are not excepted. Must use user@email-host.
- */
-
-#include "module.h"
-
-class CommandNSGetEMail : public Command
-{
- public:
- CommandNSGetEMail(Module *creator) : Command(creator, "nickserv/getemail", 1, 1)
- {
- this->SetDesc(_("Matches and returns all users that registered using given email"));
- this->SetSyntax(_("\037email\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &email = params[0];
- int j = 0;
-
- Log(LOG_ADMIN, source, this) << "on " << email;
-
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (!nc->email.empty() && Anope::Match(nc->email, email))
- {
- ++j;
- source.Reply(_("Email matched: \002%s\002 (\002%s\002) to \002%s\002."), nc->display.c_str(), nc->email.c_str(), email.c_str());
- }
- }
-
- if (j <= 0)
- {
- source.Reply(_("No registrations matching \002%s\002 were found."), email.c_str());
- return;
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns the matching accounts that used given email."));
- return true;
- }
-};
-
-class NSGetEMail : public Module
-{
- CommandNSGetEMail commandnsgetemail;
- public:
- NSGetEMail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsgetemail(this)
- {
-
- }
-};
-
-MODULE_INIT(NSGetEMail)
diff --git a/modules/commands/ns_getpass.cpp b/modules/commands/ns_getpass.cpp
deleted file mode 100644
index ae32fc2ef..000000000
--- a/modules/commands/ns_getpass.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSGetPass : public Command
-{
- public:
- CommandNSGetPass(Module *creator) : Command(creator, "nickserv/getpass", 1, 1)
- {
- this->SetDesc(_("Retrieve the password for a nickname"));
- this->SetSyntax(_("\037nickname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- Anope::string tmp_pass;
- const NickAlias *na;
-
- if (!(na = NickAlias::Find(nick)))
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
- source.Reply(_("You may not get the password of other Services Operators."));
- else
- {
- if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1)
- {
- Log(LOG_ADMIN, source, this) << "for " << nick;
- source.Reply(_("Password for %s is \002%s\002."), nick.c_str(), tmp_pass.c_str());
- }
- else
- source.Reply(_("GETPASS command unavailable because encryption is in use."));
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns the password for the given nickname. \002Note\002 that\n"
- "whenever this command is used, a message including the\n"
- "person who issued the command and the nickname it was used\n"
- "on will be logged and sent out as a WALLOPS/GLOBOPS."));
- return true;
- }
-};
-
-class NSGetPass : public Module
-{
- CommandNSGetPass commandnsgetpass;
-
- public:
- NSGetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsgetpass(this)
- {
-
- Anope::string tmp_pass = "plain:tmp";
- if (!Anope::Decrypt(tmp_pass, tmp_pass))
- throw ModuleException("Incompatible with the encryption module being used");
-
- }
-};
-
-MODULE_INIT(NSGetPass)
diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp
deleted file mode 100644
index 63d0dff10..000000000
--- a/modules/commands/ns_group.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 "modules/ns_cert.h"
-
-class NSGroupRequest : public IdentifyRequest
-{
- CommandSource source;
- Command *cmd;
- Anope::string nick;
- Reference<NickAlias> target;
-
- public:
- NSGroupRequest(Module *o, CommandSource &src, Command *c, const Anope::string &n, NickAlias *targ, const Anope::string &pass) : IdentifyRequest(o, targ->nc->display, pass), source(src), cmd(c), nick(n), target(targ) { }
-
- void OnSuccess() anope_override
- {
- if (!source.GetUser() || source.GetUser()->nick != nick || !target || !target->nc)
- return;
-
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(nick);
- /* If the nick is already registered, drop it. */
- if (na)
- {
- FOREACH_MOD(OnChangeCoreDisplay, (na->nc, u->nick));
- delete na;
- }
-
- na = new NickAlias(nick, target->nc);
-
- Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
- na->last_usermask = last_usermask;
- na->last_realname = u->realname;
- na->time_registered = na->last_seen = Anope::CurTime;
-
- u->Login(target->nc);
- FOREACH_MOD(OnNickGroup, (u, target));
-
- Log(LOG_COMMAND, source, cmd) << "to make " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")";
- source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str());
-
- u->lastnickreg = Anope::CurTime;
-
- }
-
- void OnFail() anope_override
- {
- if (!source.GetUser())
- return;
-
- Log(LOG_COMMAND, source, cmd) << "and failed to group to " << target->nick;
- if (NickAlias::Find(GetAccount()) != NULL)
- {
- source.Reply(PASSWORD_INCORRECT);
- source.GetUser()->BadPassword();
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- }
-};
-
-class CommandNSGroup : public Command
-{
- public:
- CommandNSGroup(Module *creator) : Command(creator, "nickserv/group", 0, 2)
- {
- this->SetDesc(_("Join a group"));
- this->SetSyntax(_("\037[target]\037 \037[password]\037"));
- this->AllowUnregistered(true);
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- Anope::string nick;
- if (params.empty())
- {
- NickCore* core = u->Account();
- if (core)
- nick = core->display;
- }
- else
- nick = params[0];
-
- if (nick.empty())
- {
- this->SendSyntax(source);
- return;
- }
-
- const Anope::string &pass = params.size() > 1 ? params[1] : "";
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, nickname grouping is temporarily disabled."));
- return;
- }
-
- if (!IRCD->IsNickValid(u->nick))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- if (!u->HasMode("OPER") && u->nick.find_ci(o->name) != Anope::string::npos)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
- return;
- }
- }
-
- NickAlias *target, *na = NickAlias::Find(u->nick);
- const Anope::string &guestnick = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
- time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
- unsigned maxaliases = Config->GetModule(this->owner)->Get<unsigned>("maxaliases");
- if (!(target = NickAlias::Find(nick)))
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- else if (Anope::CurTime < u->lastnickreg + reg_delay)
- source.Reply(_("Please wait %d seconds before using the GROUP command again."), (reg_delay + u->lastnickreg) - Anope::CurTime);
- else if (target->nc->HasExt("NS_SUSPENDED"))
- {
- Log(LOG_COMMAND, source, this) << "and tried to group to SUSPENDED nick " << target->nick;
- source.Reply(NICK_X_SUSPENDED, target->nick.c_str());
- }
- else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange"))
- source.Reply(_("Your nick is already registered."));
- else if (na && *target->nc == *na->nc)
- source.Reply(_("You are already a member of the group of \002%s\002."), target->nick.c_str());
- else if (na && na->nc != u->Account())
- source.Reply(NICK_IDENTIFY_REQUIRED);
- else if (maxaliases && target->nc->aliases->size() >= maxaliases && !target->nc->IsServicesOper())
- source.Reply(_("There are too many nicks in your group."));
- else if (u->nick.length() <= guestnick.length() + 7 &&
- u->nick.length() >= guestnick.length() + 1 &&
- !u->nick.find_ci(guestnick) && !u->nick.substr(guestnick.length()).find_first_not_of("1234567890"))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
- }
- else
- {
- bool ok = false;
- if (!na && u->Account() == target->nc)
- ok = true;
-
- NSCertList *cl = target->nc->GetExt<NSCertList>("certificates");
- if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint))
- ok = true;
-
- if (ok == false && !pass.empty())
- {
- NSGroupRequest *req = new NSGroupRequest(owner, source, this, u->nick, target, pass);
- FOREACH_MOD(OnCheckAuthentication, (source.GetUser(), req));
- req->Dispatch();
- }
- else
- {
- NSGroupRequest req(owner, source, this, u->nick, target, pass);
-
- if (ok)
- req.OnSuccess();
- else
- req.OnFail();
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command makes your nickname join the \037target\037 nickname's\n"
- "group. \037password\037 is the password of the target nickname.\n"
- " \n"
- "Joining a group will allow you to share your configuration,\n"
- "memos, and channel privileges with all the nicknames in the\n"
- "group, and much more!\n"
- " \n"
- "A group exists as long as it is useful. This means that even\n"
- "if a nick of the group is dropped, you won't lose the\n"
- "shared things described above, as long as there is at\n"
- "least one nick remaining in the group.\n"
- " \n"
- "You may be able to use this command even if you have not registered\n"
- "your nick yet. If your nick is already registered, you'll\n"
- "need to identify yourself before using this command.\n"
- " \n"
- "It is recommended to use this command with a non-registered\n"
- "nick because it will be registered automatically when\n"
- "using this command. You may use it with a registered nick (to\n"
- "change your group) only if your network administrators allowed\n"
- "it.\n"
- " \n"
- "You can only be in one group at a time. Group merging is\n"
- "not possible.\n"
- " \n"
- "\037Note\037: all the nicknames of a group have the same password."));
- return true;
- }
-};
-
-class CommandNSUngroup : public Command
-{
- public:
- CommandNSUngroup(Module *creator) : Command(creator, "nickserv/ungroup", 0, 1)
- {
- this->SetDesc(_("Remove a nick from a group"));
- this->SetSyntax(_("[\037nick\037]"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- Anope::string nick = !params.empty() ? params[0] : "";
- NickAlias *na = NickAlias::Find(!nick.empty() ? nick : u->nick);
-
- if (u->Account()->aliases->size() == 1)
- source.Reply(_("Your nick is not grouped to anything, you can't ungroup it."));
- else if (!na)
- source.Reply(NICK_X_NOT_REGISTERED, !nick.empty() ? nick.c_str() : u->nick.c_str());
- else if (na->nc != u->Account())
- source.Reply(_("Nick %s is not in your group."), na->nick.c_str());
- else
- {
- NickCore *oldcore = na->nc;
-
- std::vector<NickAlias *>::iterator it = std::find(oldcore->aliases->begin(), oldcore->aliases->end(), na);
- if (it != oldcore->aliases->end())
- oldcore->aliases->erase(it);
-
- if (na->nick.equals_ci(oldcore->display))
- oldcore->SetDisplay(oldcore->aliases->front());
-
- NickCore *nc = new NickCore(na->nick);
- na->nc = nc;
- nc->aliases->push_back(na);
-
- nc->pass = oldcore->pass;
- if (!oldcore->email.empty())
- nc->email = oldcore->email;
- nc->language = oldcore->language;
-
- source.Reply(_("Nick %s has been ungrouped from %s."), na->nick.c_str(), oldcore->display.c_str());
-
- User *user = User::Find(na->nick, true);
- if (user)
- /* The user on the nick who was ungrouped may be identified to the old group, set -r */
- user->RemoveMode(source.service, "REGISTERED");
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command ungroups your nick, or if given, the specificed nick,\n"
- "from the group it is in. The ungrouped nick keeps its registration\n"
- "time, password, email, greet, language, and url. Everything else\n"
- "is reset. You may not ungroup yourself if there is only one nick in\n"
- "your group."));
- return true;
- }
-};
-
-class CommandNSGList : public Command
-{
- public:
- CommandNSGList(Module *creator) : Command(creator, "nickserv/glist", 0, 1)
- {
- this->SetDesc(_("Lists all nicknames in your group"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = !params.empty() ? params[0] : "";
- const NickCore *nc;
-
- if (!nick.empty())
- {
- const NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc != source.GetAccount() && !source.IsServicesOper())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- nc = na->nc;
- }
- else
- nc = source.GetAccount();
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Nick")).AddColumn(_("Expires"));
- time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire", "21d"),
- unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- const NickAlias *na2 = nc->aliases->at(i);
-
- Anope::string expires;
- if (na2->HasExt("NS_NO_EXPIRE"))
- expires = NO_EXPIRE;
- else if (!nickserv_expire || Anope::NoExpire)
- ;
- else if (na2->nc->HasExt("UNCONFIRMED") && unconfirmed_expire)
- expires = Anope::strftime(na2->time_registered + unconfirmed_expire, source.GetAccount());
- else
- expires = Anope::strftime(na2->last_seen + nickserv_expire, source.GetAccount());
-
- ListFormatter::ListEntry entry;
- entry["Nick"] = na2->nick;
- entry["Expires"] = expires;
- list.AddEntry(entry);
- }
-
- source.Reply(!nick.empty() ? _("List of nicknames in the group of \002%s\002:") : _("List of nicknames in your group:"), nc->display.c_str());
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("%d nickname(s) in the group."), nc->aliases->size());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (source.IsServicesOper())
- source.Reply(_("Syntax: \002%s [\037nickname\037]\002\n"
- " \n"
- "Without a parameter, lists all nicknames that are in\n"
- "your group.\n"
- " \n"
- "With a parameter, lists all nicknames that are in the\n"
- "group of the given nick.\n"
- "Specifying a nick is limited to \002Services Operators\002."),
- source.command.c_str());
- else
- source.Reply(_("Syntax: \002%s\002\n"
- " \n"
- "Lists all nicks in your group."), source.command.c_str());
-
- return true;
- }
-};
-
-class NSGroup : public Module
-{
- CommandNSGroup commandnsgroup;
- CommandNSUngroup commandnsungroup;
- CommandNSGList commandnsglist;
-
- public:
- NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsgroup(this), commandnsungroup(this), commandnsglist(this)
- {
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
- }
-};
-
-MODULE_INIT(NSGroup)
diff --git a/modules/commands/ns_identify.cpp b/modules/commands/ns_identify.cpp
deleted file mode 100644
index a188b2ee8..000000000
--- a/modules/commands/ns_identify.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class NSIdentifyRequest : public IdentifyRequest
-{
- CommandSource source;
- Command *cmd;
-
- public:
- NSIdentifyRequest(Module *o, CommandSource &s, Command *c, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(o, acc, pass), source(s), cmd(c) { }
-
- void OnSuccess() anope_override
- {
- if (!source.GetUser())
- return;
-
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(GetAccount());
-
- if (!na)
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- else
- {
- if (u->IsIdentified())
- Log(LOG_COMMAND, source, cmd) << "to log out of account " << u->Account()->display;
-
- Log(LOG_COMMAND, source, cmd) << "and identified for account " << na->nc->display;
- source.Reply(_("Password accepted - you are now recognized."));
- u->Identify(na);
- }
- }
-
- void OnFail() anope_override
- {
- if (source.GetUser())
- {
- bool accountexists = NickAlias::Find(GetAccount()) != NULL;
- Log(LOG_COMMAND, source, cmd) << "and failed to identify to" << (accountexists ? " " : " nonexistent ") << "account " << GetAccount();
- if (accountexists)
- {
- source.Reply(PASSWORD_INCORRECT);
- source.GetUser()->BadPassword();
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- }
- }
-};
-
-class CommandNSIdentify : public Command
-{
- public:
- CommandNSIdentify(Module *creator) : Command(creator, "nickserv/identify", 1, 2)
- {
- this->SetDesc(_("Identify yourself with your password"));
- this->SetSyntax(_("[\037account\037] \037password\037"));
- this->AllowUnregistered(true);
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
-
- const Anope::string &nick = params.size() == 2 ? params[0] : u->nick;
- Anope::string pass = params[params.size() - 1];
-
- NickAlias *na = NickAlias::Find(nick);
- if (na && na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(NICK_X_SUSPENDED, na->nick.c_str());
- return;
- }
-
- if (u->Account() && na && u->Account() == na->nc)
- {
- source.Reply(_("You are already identified."));
- return;
- }
-
- unsigned int maxlogins = Config->GetModule(this->owner)->Get<unsigned int>("maxlogins");
- if (na && maxlogins && na->nc->users.size() >= maxlogins)
- {
- source.Reply(_("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), na->nc->display.c_str(), maxlogins);
- return;
- }
-
- NSIdentifyRequest *req = new NSIdentifyRequest(owner, source, this, na ? na->nc->display : nick, pass);
- FOREACH_MOD(OnCheckAuthentication, (u, req));
- req->Dispatch();
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells %s that you are really the owner of this\n"
- "nick. Many commands require you to authenticate yourself\n"
- "with this command before you use them. The password\n"
- "should be the same one you sent with the \002REGISTER\002\n"
- "command."), source.service->nick.c_str());
- return true;
- }
-};
-
-class NSIdentify : public Module
-{
- CommandNSIdentify commandnsidentify;
-
- public:
- NSIdentify(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsidentify(this)
- {
-
- }
-};
-
-MODULE_INIT(NSIdentify)
diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp
deleted file mode 100644
index a1cdfc897..000000000
--- a/modules/commands/ns_info.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSInfo : public Command
-{
- public:
- CommandNSInfo(Module *creator) : Command(creator, "nickserv/info", 0, 2)
- {
- this->SetDesc(_("Displays information about a given nickname"));
- this->SetSyntax(_("[\037nickname\037]"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &nick = params.size() ? params[0] : (source.nc ? source.nc->display : source.GetNick());
- NickAlias *na = NickAlias::Find(nick);
- bool has_auspex = source.HasPriv("nickserv/auspex");
-
- if (!na)
- {
- if (BotInfo::Find(nick, true))
- source.Reply(_("Nick \002%s\002 is part of this Network's Services."), nick.c_str());
- else
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- }
- else
- {
- bool nick_online = false, show_hidden = false;
-
- /* Is the real owner of the nick we're looking up online? -TheShadow */
- User *u2 = User::Find(na->nick, true);
- if (u2 && u2->Account() == na->nc)
- {
- nick_online = true;
- na->last_seen = Anope::CurTime;
- }
-
- if (has_auspex || na->nc == source.GetAccount())
- show_hidden = true;
-
- source.Reply(_("%s is %s"), na->nick.c_str(), na->last_realname.c_str());
-
- if (na->nc->HasExt("UNCONFIRMED"))
- source.Reply(_("%s is an unconfirmed nickname."), na->nick.c_str());
-
- if (na->nc->IsServicesOper() && (show_hidden || !na->nc->HasExt("HIDE_STATUS")))
- source.Reply(_("%s is a Services Operator of type %s."), na->nick.c_str(), na->nc->o->ot->GetName().c_str());
-
- InfoFormatter info(source.nc);
-
- if (nick_online)
- {
- bool shown = false;
- if (show_hidden && !na->last_realhost.empty())
- {
- info[_("Online from")] = na->last_realhost;
- shown = true;
- }
- if ((show_hidden || !na->nc->HasExt("HIDE_MASK")) && (!shown || na->last_usermask != na->last_realhost))
- info[_("Online from")] = na->last_usermask;
- else
- source.Reply(_("%s is currently online."), na->nick.c_str());
- }
- else
- {
- Anope::string shown;
- if (show_hidden || !na->nc->HasExt("HIDE_MASK"))
- {
- info[_("Last seen address")] = na->last_usermask;
- shown = na->last_usermask;
- }
-
- if (show_hidden && !na->last_realhost.empty() && na->last_realhost != shown)
- info[_("Last seen address")] = na->last_realhost;
- }
-
- info[_("Registered")] = Anope::strftime(na->time_registered, source.GetAccount());
-
- if (!nick_online)
- info[_("Last seen")] = Anope::strftime(na->last_seen, source.GetAccount());
-
- if (!na->last_quit.empty() && (show_hidden || !na->nc->HasExt("HIDE_QUIT")))
- info[_("Last quit message")] = na->last_quit;
-
- if (!na->nc->email.empty() && (show_hidden || !na->nc->HasExt("HIDE_EMAIL")))
- info[_("Email address")] = na->nc->email;
-
- if (show_hidden)
- {
- if (na->HasVhost())
- {
- if (IRCD->CanSetVIdent && !na->GetVhostIdent().empty())
- info[_("VHost")] = na->GetVhostIdent() + "@" + na->GetVhostHost();
- else
- info[_("VHost")] = na->GetVhostHost();
- }
- }
-
- FOREACH_MOD(OnNickInfo, (source, na, info, show_hidden));
-
- std::vector<Anope::string> replies;
- info.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Displays information about the given nickname, such as\n"
- "the nick's owner, last seen address and time, and nick\n"
- "options. If no nick is given, and you are identified,\n"
- "your account name is used, else your current nickname is\n"
- "used."));
-
- return true;
- }
-};
-
-
-class CommandNSSetHide : public Command
-{
- public:
- CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Hide certain pieces of nickname information"));
- this->SetSyntax("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param, const Anope::string &arg)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Anope::string onmsg, offmsg, flag;
-
- if (param.equals_ci("EMAIL"))
- {
- flag = "HIDE_EMAIL";
- onmsg = _("The E-mail address of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The E-mail address of \002%s\002 will now be shown in %s INFO displays.");
- }
- else if (param.equals_ci("USERMASK"))
- {
- flag = "HIDE_MASK";
- onmsg = _("The last seen user@host mask of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The last seen user@host mask of \002%s\002 will now be shown in %s INFO displays.");
- }
- else if (param.equals_ci("STATUS"))
- {
- flag = "HIDE_STATUS";
- onmsg = _("The services access status of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The services access status of \002%s\002 will now be shown in %s INFO displays.");
- }
- else if (param.equals_ci("QUIT"))
- {
- flag = "HIDE_QUIT";
- onmsg = _("The last quit message of \002%s\002 will now be hidden from %s INFO displays.");
- offmsg = _("The last quit message of \002%s\002 will now be shown in %s INFO displays.");
- }
- else
- {
- this->OnSyntaxError(source, "HIDE");
- return;
- }
-
- if (arg.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param.upper() << " to " << arg.upper() << " for " << nc->display;
- nc->Extend<bool>(flag);
- source.Reply(onmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
- }
- else if (arg.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param.upper() << " to " << arg.upper() << " for " << nc->display;
- nc->Shrink<bool>(flag);
- source.Reply(offmsg.c_str(), nc->display.c_str(), source.service->nick.c_str());
- }
- else
- this->OnSyntaxError(source, "HIDE");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to prevent certain pieces of information from\n"
- "being displayed when someone does a %s \002INFO\002 on your\n"
- "nick. You can hide your E-mail address (\002EMAIL\002), last seen\n"
- "user@host mask (\002USERMASK\002), your services access status\n"
- "(\002STATUS\002) and last quit message (\002QUIT\002).\n"
- "The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetHide : public CommandNSSetHide
-{
- public:
- CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3)
- {
- this->SetSyntax(_("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->ClearSyntax();
- this->Run(source, params[0], params[1], params[2]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to prevent certain pieces of information from\n"
- "being displayed when someone does a %s \002INFO\002 on the\n"
- "nick. You can hide the E-mail address (\002EMAIL\002), last seen\n"
- "user@host mask (\002USERMASK\002), the services access status\n"
- "(\002STATUS\002) and last quit message (\002QUIT\002).\n"
- "The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), source.service->nick.c_str());
- return true;
- }
-};
-
-class NSInfo : public Module
-{
- CommandNSInfo commandnsinfo;
-
- CommandNSSetHide commandnssethide;
- CommandNSSASetHide commandnssasethide;
-
- SerializableExtensibleItem<bool> hide_email, hide_usermask, hide_status, hide_quit;
-
- public:
- NSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsinfo(this), commandnssethide(this), commandnssasethide(this),
- hide_email(this, "HIDE_EMAIL"), hide_usermask(this, "HIDE_MASK"), hide_status(this, "HIDE_STATUS"),
- hide_quit(this, "HIDE_QUIT")
- {
-
- }
-};
-
-MODULE_INIT(NSInfo)
diff --git a/modules/commands/ns_list.cpp b/modules/commands/ns_list.cpp
deleted file mode 100644
index 43e8d3f13..000000000
--- a/modules/commands/ns_list.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSList : public Command
-{
- public:
- CommandNSList(Module *creator) : Command(creator, "nickserv/list", 1, 2)
- {
- this->SetDesc(_("List all registered nicknames that match a given pattern"));
- this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- Anope::string pattern = params[0];
- const NickCore *mync;
- unsigned nnicks;
- bool is_servadmin = source.HasCommand("nickserv/list");
- int count = 0, from = 0, to = 0;
- bool suspended, nsnoexpire, unconfirmed;
- unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
-
- suspended = nsnoexpire = unconfirmed = false;
-
- if (pattern[0] == '#')
- {
- Anope::string n1, n2;
- sepstream(pattern.substr(1), '-').GetToken(n1, 0);
- sepstream(pattern, '-').GetToken(n2, 1);
- try
- {
- from = convertTo<int>(n1);
- to = convertTo<int>(n2);
- }
- catch (const ConvertException &)
- {
- source.Reply(LIST_INCORRECT_RANGE);
- return;
- }
-
- pattern = "*";
- }
-
- nnicks = 0;
-
- if (is_servadmin && params.size() > 1)
- {
- Anope::string keyword;
- spacesepstream keywords(params[1]);
- while (keywords.GetToken(keyword))
- {
- if (keyword.equals_ci("NOEXPIRE"))
- nsnoexpire = true;
- if (keyword.equals_ci("SUSPENDED"))
- suspended = true;
- if (keyword.equals_ci("UNCONFIRMED"))
- unconfirmed = true;
- }
- }
-
- mync = source.nc;
- ListFormatter list(source.GetAccount());
-
- list.AddColumn(_("Nick")).AddColumn(_("Last usermask"));
-
- Anope::map<NickAlias *> ordered_map;
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
- ordered_map[it->first] = it->second;
-
- for (Anope::map<NickAlias *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
- {
- const NickAlias *na = it->second;
-
- /* Don't show private nicks to non-services admins. */
- if (na->nc->HasExt("NS_PRIVATE") && !is_servadmin && na->nc != mync)
- continue;
- else if (nsnoexpire && !na->HasExt("NS_NO_EXPIRE"))
- continue;
- else if (suspended && !na->nc->HasExt("NS_SUSPENDED"))
- continue;
- else if (unconfirmed && !na->nc->HasExt("UNCONFIRMED"))
- continue;
-
- /* We no longer compare the pattern against the output buffer.
- * Instead we build a nice nick!user@host buffer to compare.
- * The output is then generated separately. -TheShadow */
- Anope::string buf = Anope::printf("%s!%s", na->nick.c_str(), !na->last_usermask.empty() ? na->last_usermask.c_str() : "*@*");
- if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern, false, true))
- {
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax)
- {
- bool isnoexpire = false;
- if (is_servadmin && na->HasExt("NS_NO_EXPIRE"))
- isnoexpire = true;
-
- ListFormatter::ListEntry entry;
- entry["Nick"] = (isnoexpire ? "!" : "") + na->nick;
- if (na->nc->HasExt("HIDE_MASK") && !is_servadmin && na->nc != mync)
- entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Hostname hidden]"));
- else if (na->nc->HasExt("NS_SUSPENDED"))
- entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
- else if (na->nc->HasExt("UNCONFIRMED"))
- entry["Last usermask"] = Language::Translate(source.GetAccount(), _("[Unconfirmed]"));
- else
- entry["Last usermask"] = na->last_usermask;
- list.AddEntry(entry);
- }
- ++count;
- }
- }
-
- source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks);
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all registered nicknames which match the given\n"
- "pattern, in \037nick!user@host\037 format. Nicks with the \002PRIVATE\002\n"
- "option set will only be displayed to Services Operators with the\n"
- "proper access. Nicks with the \002NOEXPIRE\002 option set will have\n"
- "a \002!\002 prefixed to the nickname for Services Operators to see.\n"
- " \n"
- "Note that a preceding '#' specifies a range.\n"
- " \n"
- "If the SUSPENDED, UNCONFIRMED or NOEXPIRE options are given, only\n"
- "nicks which, respectively, are SUSPENDED, UNCONFIRMED or have the\n"
- "NOEXPIRE flag set will be displayed. If multiple options are\n"
- "given, all nicks matching at least one option will be displayed.\n"
- "Note that these options are limited to \037Services Operators\037.\n"
- " \n"
- "Examples:\n"
- " \n"
- " \002LIST *!joeuser@foo.com\002\n"
- " Lists all registered nicks owned by joeuser@foo.com.\n"
- " \n"
- " \002LIST *Bot*!*@*\002\n"
- " Lists all registered nicks with \002Bot\002 in their\n"
- " names (case insensitive).\n"
- " \n"
- " \002LIST * NOEXPIRE\002\n"
- " Lists all registered nicks which have been set to not expire.\n"
- " \n"
- " \002LIST #51-100\002\n"
- " Lists all registered nicks within the given range (51-100)."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-
-class CommandNSSetPrivate : public Command
-{
- public:
- CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Prevent the nickname from appearing in the LIST command"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable private for " << nc->display;
- nc->Extend<bool>("NS_PRIVATE");
- source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable private for " << nc->display;
- nc->Shrink<bool>("NS_PRIVATE");
- source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "PRIVATE");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's privacy option on or off for your nick.\n"
- "With \002PRIVATE\002 set, your nickname will not appear in\n"
- "nickname lists generated with %s's \002LIST\002 command.\n"
- "(However, anyone who knows your nickname can still get\n"
- "information on it using the \002INFO\002 command.)"),
- source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetPrivate : public CommandNSSetPrivate
-{
- public:
- CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's privacy option on or off for the nick.\n"
- "With \002PRIVATE\002 set, the nickname will not appear in\n"
- "nickname lists generated with %s's \002LIST\002 command.\n"
- "(However, anyone who knows the nickname can still get\n"
- "information on it using the \002INFO\002 command.)"),
- source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-
-class NSList : public Module
-{
- CommandNSList commandnslist;
-
- CommandNSSetPrivate commandnssetprivate;
- CommandNSSASetPrivate commandnssasetprivate;
-
- SerializableExtensibleItem<bool> priv;
-
- public:
- NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnslist(this), commandnssetprivate(this), commandnssasetprivate(this),
- priv(this, "NS_PRIVATE")
- {
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_all) anope_override
- {
- if (!show_all)
- return;
-
- if (priv.HasExt(na->nc))
- info.AddOption(_("Private"));
- }
-};
-
-MODULE_INIT(NSList)
diff --git a/modules/commands/ns_logout.cpp b/modules/commands/ns_logout.cpp
deleted file mode 100644
index 7567626e0..000000000
--- a/modules/commands/ns_logout.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<NickServService> NickServService("NickServService", "NickServ");
-
-class CommandNSLogout : public Command
-{
- public:
- CommandNSLogout(Module *creator) : Command(creator, "nickserv/logout", 0, 2)
- {
- this->SetDesc(_("Reverses the effect of the IDENTIFY command"));
- this->SetSyntax(_("[\037nickname\037 [REVALIDATE]]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &nick = !params.empty() ? params[0] : "";
- const Anope::string &param = params.size() > 1 ? params[1] : "";
-
- User *u2;
- if (!source.IsServicesOper() && !nick.empty())
- this->OnSyntaxError(source, "");
- else if (!(u2 = (!nick.empty() ? User::Find(nick, true) : source.GetUser())))
- source.Reply(NICK_X_NOT_IN_USE, !nick.empty() ? nick.c_str() : source.GetNick().c_str());
- else if (!nick.empty() && u2->IsServicesOper())
- source.Reply(_("You can't logout %s, they are a Services Operator."), nick.c_str());
- else
- {
- if (!nick.empty() && !param.empty() && param.equals_ci("REVALIDATE") && NickServService)
- NickServService->Validate(u2);
-
- u2->super_admin = false; /* Don't let people logout and remain a SuperAdmin */
- Log(LOG_COMMAND, source, this) << "to logout " << u2->nick;
-
- /* Remove founder status from this user in all channels */
- if (!nick.empty())
- source.Reply(_("Nick %s has been logged out."), nick.c_str());
- else
- source.Reply(_("Your nick has been logged out."));
-
- IRCD->SendLogout(u2);
- u2->RemoveMode(source.service, "REGISTERED");
- u2->Logout();
-
- /* Send out an event */
- FOREACH_MOD(OnNickLogout, (u2));
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Without a parameter, reverses the effect of the \002IDENTIFY\002\n"
- "command, i.e. make you not recognized as the real owner of the nick\n"
- "anymore. Note, however, that you won't be asked to reidentify\n"
- "yourself.\n"
- " \n"
- "With a parameter, does the same for the given nick. If you\n"
- "specify \002REVALIDATE\002 as well, Services will ask the given nick\n"
- "to re-identify. This is limited to \002Services Operators\002."));
-
- return true;
- }
-};
-
-class NSLogout : public Module
-{
- CommandNSLogout commandnslogout;
-
- public:
- NSLogout(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnslogout(this)
- {
-
- }
-};
-
-MODULE_INIT(NSLogout)
diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp
deleted file mode 100644
index f41a8d782..000000000
--- a/modules/commands/ns_recover.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 "modules/ns_cert.h"
-
-static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
-
-typedef std::map<Anope::string, ChannelStatus> NSRecoverInfo;
-
-class NSRecoverSvsnick
-{
- public:
- Reference<User> from;
- Anope::string to;
-};
-
-class NSRecoverRequest : public IdentifyRequest
-{
- CommandSource source;
- Command *cmd;
- Anope::string user;
-
- public:
- NSRecoverRequest(Module *o, CommandSource &src, Command *c, const Anope::string &nick, const Anope::string &pass) : IdentifyRequest(o, nick, pass), source(src), cmd(c), user(nick) { }
-
- void OnSuccess() anope_override
- {
- User *u = User::Find(user, true);
- if (!source.GetUser() || !source.service)
- return;
-
- NickAlias *na = NickAlias::Find(user);
- if (!na)
- return;
-
- Log(LOG_COMMAND, source, cmd) << "for " << na->nick;
-
- /* Nick is being held by us, release it */
- if (na->HasExt("HELD"))
- {
- nickserv->Release(na);
- source.Reply(_("Service's hold on \002%s\002 has been released."), na->nick.c_str());
- }
- else if (!u)
- {
- source.Reply(_("No one is using your nick, and services are not holding it."));
- }
- // If the user being recovered is identified for the account of the nick then the user is the
- // same person that is executing the command, so kill them off (old GHOST command).
- else if (u->Account() == na->nc)
- {
- if (!source.GetAccount() && na->nc->HasExt("NS_SECURE"))
- {
- source.GetUser()->Login(u->Account());
- Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display;
- }
-
- if (Config->GetModule("ns_recover")->Get<bool>("restoreonrecover"))
- {
- if (!u->chans.empty())
- {
- NSRecoverInfo *ei = source.GetUser()->Extend<NSRecoverInfo>("recover");
- for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
- (*ei)[it->first->name] = it->second->status;
- }
- }
-
- u->SendMessage(source.service, _("This nickname has been recovered by %s. If you did not do\n"
- "this then %s may have your password, and you should change it."),
- source.GetNick().c_str(), source.GetNick().c_str());
-
- Anope::string buf = source.command.upper() + " command used by " + source.GetNick();
- u->Kill(*source.service, buf);
-
- source.Reply(_("Ghost with your nick has been killed."));
-
- if (IRCD->CanSVSNick)
- IRCD->SendForceNickChange(source.GetUser(), GetAccount(), Anope::CurTime);
- }
- /* User is not identified or not identified to the same account as the person using this command */
- else
- {
- if (!source.GetAccount() && na->nc->HasExt("NS_SECURE"))
- {
- source.GetUser()->Login(na->nc); // Identify the user using the command if they arent identified
- Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->nick << " (" << na->nc->display << ")";
- source.Reply(_("You have been logged in as \002%s\002."), na->nc->display.c_str());
- }
-
- u->SendMessage(source.service, _("This nickname has been recovered by %s."), source.GetNick().c_str());
-
- if (IRCD->CanSVSNick)
- {
- NSRecoverSvsnick *svs = u->Extend<NSRecoverSvsnick>("svsnick");
- svs->from = source.GetUser();
- svs->to = u->nick;
- }
-
- if (nickserv)
- nickserv->Collide(u, na);
-
- if (IRCD->CanSVSNick)
- {
- /* If we can svsnick then release our hold and svsnick the user using the command */
- if (nickserv)
- nickserv->Release(na);
-
- source.Reply(_("You have regained control of \002%s\002."), u->nick.c_str());
- }
- else
- {
- source.Reply(_("The user with your nick has been removed. Use this command again\n"
- "to release services's hold on your nick."));
- }
- }
- }
-
- void OnFail() anope_override
- {
- if (NickAlias::Find(GetAccount()) != NULL)
- {
- source.Reply(ACCESS_DENIED);
- if (!GetPassword().empty())
- {
- Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount();
- if (source.GetUser())
- source.GetUser()->BadPassword();
- }
- }
- else
- source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str());
- }
-};
-
-class CommandNSRecover : public Command
-{
- public:
- CommandNSRecover(Module *creator) : Command(creator, "nickserv/recover", 1, 2)
- {
- this->SetDesc(_("Regains control of your nick"));
- this->SetSyntax(_("\037nickname\037 [\037password\037]"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- const Anope::string &pass = params.size() > 1 ? params[1] : "";
-
- User *user = User::Find(nick, true);
-
- if (user && source.GetUser() == user)
- {
- source.Reply(_("You can't %s yourself!"), source.command.lower().c_str());
- return;
- }
-
- const NickAlias *na = NickAlias::Find(nick);
-
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
- else if (na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(NICK_X_SUSPENDED, na->nick.c_str());
- return;
- }
-
- bool ok = false;
- if (source.GetAccount() == na->nc)
- ok = true;
- else if (!na->nc->HasExt("NS_SECURE") && source.GetUser() && na->nc->IsOnAccess(source.GetUser()))
- ok = true;
-
- NSCertList *cl = na->nc->GetExt<NSCertList>("certificates");
- if (source.GetUser() && !source.GetUser()->fingerprint.empty() && cl && cl->FindCert(source.GetUser()->fingerprint))
- ok = true;
-
- if (ok == false && !pass.empty())
- {
- NSRecoverRequest *req = new NSRecoverRequest(owner, source, this, na->nick, pass);
- FOREACH_MOD(OnCheckAuthentication, (source.GetUser(), req));
- req->Dispatch();
- }
- else
- {
- NSRecoverRequest req(owner, source, this, na->nick, pass);
-
- if (ok)
- req.OnSuccess();
- else
- req.OnFail();
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Recovers your nick from another user or from services.\n"
- "If services are currently holding your nick, the hold\n"
- "will be released. If another user is holding your nick\n"
- "and is identified they will be killed (similar to the old\n"
- "GHOST command). If they are not identified they will be\n"
- "forced off of the nick."));
- return true;
- }
-};
-
-class NSRecover : public Module
-{
- CommandNSRecover commandnsrecover;
- PrimitiveExtensibleItem<NSRecoverInfo> recover;
- PrimitiveExtensibleItem<NSRecoverSvsnick> svsnick;
-
- public:
- NSRecover(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsrecover(this), recover(this, "recover"), svsnick(this, "svsnick")
- {
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
-
- }
-
- void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
- {
- if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
- {
- NSRecoverInfo *ei = recover.Get(u);
- BotInfo *NickServ = Config->GetClient("NickServ");
-
- if (ei != NULL && NickServ != NULL)
- for (NSRecoverInfo::iterator it = ei->begin(), it_end = ei->end(); it != it_end;)
- {
- Channel *c = Channel::Find(it->first);
- const Anope::string &cname = it->first;
- ++it;
-
- /* User might already be on the channel */
- if (u->FindChannel(c))
- this->OnJoinChannel(u, c);
- else if (IRCD->CanSVSJoin)
- IRCD->SendSVSJoin(NickServ, u, cname, "");
- }
- }
-
- NSRecoverSvsnick *svs = svsnick.Get(u);
- if (svs)
- {
- if (svs->from)
- {
- // svsnick from to to
- IRCD->SendForceNickChange(svs->from, svs->to, Anope::CurTime);
- }
-
- svsnick.Unset(u);
- }
- }
-
- void OnJoinChannel(User *u, Channel *c) anope_override
- {
- if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
- {
- NSRecoverInfo *ei = recover.Get(u);
-
- if (ei != NULL)
- {
- NSRecoverInfo::iterator it = ei->find(c->name);
- if (it != ei->end())
- {
- for (size_t i = 0; i < it->second.Modes().length(); ++i)
- c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(it->second.Modes()[i]), u->GetUID());
-
- ei->erase(it);
- if (ei->empty())
- recover.Unset(u);
- }
- }
- }
- }
-};
-
-MODULE_INIT(NSRecover)
diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp
deleted file mode 100644
index ce5dbc997..000000000
--- a/modules/commands/ns_register.cpp
+++ /dev/null
@@ -1,429 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-static bool SendRegmail(User *u, const NickAlias *na, BotInfo *bi);
-
-class CommandNSConfirm : public Command
-{
- public:
- CommandNSConfirm(Module *creator) : Command(creator, "nickserv/confirm", 1, 2)
- {
- this->SetDesc(_("Confirm a passcode"));
- this->SetSyntax(_("\037passcode\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &passcode = params[0];
-
- if (source.nc && !source.nc->HasExt("UNCONFIRMED") && source.HasPriv("nickserv/confirm"))
- {
- NickAlias *na = NickAlias::Find(passcode);
- if (na == NULL)
- source.Reply(NICK_X_NOT_REGISTERED, passcode.c_str());
- else if (na->nc->HasExt("UNCONFIRMED") == false)
- source.Reply(_("Nick \002%s\002 is already confirmed."), na->nick.c_str());
- else
- {
- na->nc->Shrink<bool>("UNCONFIRMED");
- FOREACH_MOD(OnNickConfirm, (source.GetUser(), na->nc));
- Log(LOG_ADMIN, source, this) << "to confirm nick " << na->nick << " (" << na->nc->display << ")";
- source.Reply(_("Nick \002%s\002 has been confirmed."), na->nick.c_str());
-
- /* Login the users online already */
- for (std::list<User *>::iterator it = na->nc->users.begin(); it != na->nc->users.end(); ++it)
- {
- User *u = *it;
-
- IRCD->SendLogin(u, na);
-
- NickAlias *u_na = NickAlias::Find(u->nick);
-
- /* Set +r if they're on a nick in the group */
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && u_na && *u_na->nc == *na->nc)
- u->SetMode(source.service, "REGISTERED");
- }
- }
- }
- else if (source.nc)
- {
- Anope::string *code = source.nc->GetExt<Anope::string>("passcode");
- if (code != NULL && *code == passcode)
- {
- NickCore *nc = source.nc;
- nc->Shrink<Anope::string>("passcode");
- Log(LOG_COMMAND, source, this) << "to confirm their email";
- source.Reply(_("Your email address of \002%s\002 has been confirmed."), source.nc->email.c_str());
- nc->Shrink<bool>("UNCONFIRMED");
- FOREACH_MOD(OnNickConfirm, (source.GetUser(), nc));
-
- if (source.GetUser())
- {
- NickAlias *na = NickAlias::Find(source.GetNick());
- if (na)
- {
- IRCD->SendLogin(source.GetUser(), na);
- if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && na->nc == source.GetAccount() && !na->nc->HasExt("UNCONFIRMED"))
- source.GetUser()->SetMode(source.service, "REGISTERED");
- }
- }
- }
- else
- source.Reply(_("Invalid passcode."));
- }
- else
- source.Reply(_("Invalid passcode."));
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command is used by several commands as a way to confirm\n"
- "changes made to your account.\n"
- " \n"
- "This is most commonly used to confirm your email address once\n"
- "you register or change it.\n"
- " \n"
- "This is also used after the RESETPASS command has been used to\n"
- "force identify you to your nick so you may change your password."));
- if (source.HasPriv("nickserv/confirm"))
- source.Reply(_("Additionally, Services Operators with the \037nickserv/confirm\037 permission can\n"
- "replace \037passcode\037 with a users nick to force validate them."));
- return true;
- }
-
- void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- source.Reply(NICK_CONFIRM_INVALID);
- }
-};
-
-class CommandNSRegister : public Command
-{
- public:
- CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2)
- {
- this->SetDesc(_("Register a nickname"));
- if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
- this->SetSyntax(_("\037password\037 \037email\037"));
- else
- this->SetSyntax(_("\037password\037 \037[email]\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- Anope::string u_nick = source.GetNick();
- size_t nicklen = u_nick.length();
- Anope::string pass = params[0];
- Anope::string email = params.size() > 1 ? params[1] : "";
- const Anope::string &nsregister = Config->GetModule(this->owner)->Get<const Anope::string>("registration");
-
- if (Anope::ReadOnly)
- {
- source.Reply(_("Sorry, nickname registration is temporarily disabled."));
- return;
- }
-
- if (nsregister.equals_ci("disable"))
- {
- source.Reply(_("Registration is currently disabled."));
- return;
- }
-
- time_t nickregdelay = Config->GetModule(this->owner)->Get<time_t>("nickregdelay");
- time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
- if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay)
- {
- source.Reply(_("You must have been using this nick for at least %d seconds to register."), nickregdelay);
- return;
- }
-
- /* Prevent "Guest" nicks from being registered. -TheShadow */
-
- /* Guest nick can now have a series of between 1 and 7 digits.
- * --lara
- */
- const Anope::string &guestnick = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
- if (nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !u_nick.find_ci(guestnick) && u_nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
-
- if (!IRCD->IsNickValid(u_nick))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
-
- if (BotInfo::Find(u_nick, true))
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
- for (unsigned i = 0; i < Oper::opers.size(); ++i)
- {
- Oper *o = Oper::opers[i];
-
- if (!source.IsOper() && u_nick.find_ci(o->name) != Anope::string::npos)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
- return;
- }
- }
-
- unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
-
- if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty())
- this->OnSyntaxError(source, "");
- else if (u && Anope::CurTime < u->lastnickreg + reg_delay)
- source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + reg_delay) - Anope::CurTime);
- else if (NickAlias::Find(u_nick) != NULL)
- source.Reply(NICK_ALREADY_REGISTERED, u_nick.c_str());
- else if (pass.equals_ci(u_nick) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && pass.length() < 5))
- source.Reply(MORE_OBSCURE_PASSWORD);
- else if (pass.length() > passlen)
- source.Reply(PASSWORD_TOO_LONG, passlen);
- else if (!email.empty() && !Mail::Validate(email))
- source.Reply(MAIL_X_INVALID, email.c_str());
- else
- {
- NickCore *nc = new NickCore(u_nick);
- NickAlias *na = new NickAlias(u_nick, nc);
- Anope::Encrypt(pass, nc->pass);
- if (!email.empty())
- nc->email = email;
-
- if (u)
- {
- na->last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
- na->last_realname = u->realname;
- }
- else
- na->last_realname = source.GetNick();
-
- Log(LOG_COMMAND, source, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")";
-
- if (na->nc->GetAccessCount())
- source.Reply(_("Nickname \002%s\002 registered under your user@host-mask: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str());
- else
- source.Reply(_("Nickname \002%s\002 registered."), u_nick.c_str());
-
- Anope::string tmp_pass;
- if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1)
- source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str());
-
- if (nsregister.equals_ci("admin"))
- {
- nc->Extend<bool>("UNCONFIRMED");
- // User::Identify() called below will notify the user that their registration is pending
- }
- else if (nsregister.equals_ci("mail"))
- {
- if (!email.empty())
- {
- nc->Extend<bool>("UNCONFIRMED");
- SendRegmail(NULL, na, source.service);
- }
- }
-
- FOREACH_MOD(OnNickRegister, (source.GetUser(), na, pass));
-
- if (u)
- {
- u->Identify(na);
- u->lastnickreg = Anope::CurTime;
- }
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Registers your nickname in the %s database. Once\n"
- "your nick is registered, you can use the \002SET\002 and \002ACCESS\002\n"
- "commands to configure your nick's settings as you like\n"
- "them. Make sure you remember the password you use when\n"
- "registering - you'll need it to make changes to your nick\n"
- "later. (Note that \002case matters!\002 \037ANOPE\037, \037Anope\037, and\n"
- "\037anope\037 are all different passwords!)\n"
- " \n"
- "Guidelines on choosing passwords:\n"
- " \n"
- "Passwords should not be easily guessable. For example,\n"
- "using your real name as a password is a bad idea. Using\n"
- "your nickname as a password is a much worse idea ;) and,\n"
- "in fact, %s will not allow it. Also, short\n"
- "passwords are vulnerable to trial-and-error searches, so\n"
- "you should choose a password at least 5 characters long.\n"
- "Finally, the space character cannot be used in passwords."),
- source.service->nick.c_str(), source.service->nick.c_str());
-
- if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
- {
- source.Reply(" ");
- source.Reply(_("The \037email\037 parameter is optional and will set the email\n"
- "for your nick immediately.\n"
- "Your privacy is respected; this e-mail won't be given to\n"
- "any third-party person. You may also wish to \002SET HIDE\002 it\n"
- "after registering if it isn't the default setting already."));
- }
-
- source.Reply(" ");
- source.Reply(_("This command also creates a new group for your nickname,\n"
- "that will allow you to register other nicks later sharing\n"
- "the same configuration, the same set of memos and the\n"
- "same channel privileges."));
- return true;
- }
-};
-
-class CommandNSResend : public Command
-{
- public:
- CommandNSResend(Module *creator) : Command(creator, "nickserv/resend", 0, 0)
- {
- this->SetDesc(_("Resend registration confirmation email"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(source.GetNick());
-
- if (na == NULL)
- source.Reply(NICK_NOT_REGISTERED);
- else if (na->nc != source.GetAccount() || !source.nc->HasExt("UNCONFIRMED"))
- source.Reply(_("Your account is already confirmed."));
- else
- {
- if (Anope::CurTime < source.nc->lastmail + Config->GetModule(this->owner)->Get<time_t>("resenddelay"))
- source.Reply(_("Cannot send mail now; please retry a little later."));
- else if (SendRegmail(source.GetUser(), na, source.service))
- {
- na->nc->lastmail = Anope::CurTime;
- source.Reply(_("Your passcode has been re-sent to %s."), na->nc->email.c_str());
- Log(LOG_COMMAND, source, this) << "to resend registration verification code";
- }
- else
- Log(this->owner) << "Unable to resend registration verification code for " << source.GetNick();
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (!Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail"))
- return false;
-
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command will resend you the registration confirmation email."));
- return true;
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (Config->GetModule(this->owner)->Get<const Anope::string>("registration").equals_ci("mail"))
- Command::OnServHelp(source);
- }
-};
-
-class NSRegister : public Module
-{
- CommandNSRegister commandnsregister;
- CommandNSConfirm commandnsconfirm;
- CommandNSResend commandnsrsend;
-
- SerializableExtensibleItem<bool> unconfirmed;
- SerializableExtensibleItem<Anope::string> passcode;
-
- public:
- NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsregister(this), commandnsconfirm(this), commandnsrsend(this), unconfirmed(this, "UNCONFIRMED"),
- passcode(this, "passcode")
- {
- if (Config->GetModule(this)->Get<const Anope::string>("registration").equals_ci("disable"))
- throw ModuleException("Module " + this->name + " will not load with registration disabled.");
- }
-
- void OnNickIdentify(User *u) anope_override
- {
- BotInfo *NickServ;
- if (unconfirmed.HasExt(u->Account()) && (NickServ = Config->GetClient("NickServ")))
- {
- const Anope::string &nsregister = Config->GetModule(this)->Get<const Anope::string>("registration");
- if (nsregister.equals_ci("admin"))
- u->SendMessage(NickServ, _("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
- else
- u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you."));
- const NickAlias *this_na = NickAlias::Find(u->Account()->display);
- time_t time_registered = Anope::CurTime - this_na->time_registered;
- time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
- if (unconfirmed_expire > time_registered)
- u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s."), Anope::Duration(unconfirmed_expire - time_registered, u->Account()).c_str());
- }
- }
-
- void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
- {
- if (unconfirmed.HasExt(na->nc))
- {
- time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
- if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire)
- expire = true;
- }
- }
-};
-
-static bool SendRegmail(User *u, const NickAlias *na, BotInfo *bi)
-{
- NickCore *nc = na->nc;
-
- Anope::string *code = na->nc->GetExt<Anope::string>("passcode");
- if (code == NULL)
- {
- code = na->nc->Extend<Anope::string>("passcode");
- *code = Anope::Random(9);
- }
-
- Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_subject").c_str()),
- message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("registration_message").c_str());
-
- subject = subject.replace_all_cs("%n", na->nick);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- subject = subject.replace_all_cs("%c", *code);
-
- message = message.replace_all_cs("%n", na->nick);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- message = message.replace_all_cs("%c", *code);
-
- return Mail::Send(u, nc, bi, subject, message);
-}
-
-MODULE_INIT(NSRegister)
diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp
deleted file mode 100644
index b1f835a01..000000000
--- a/modules/commands/ns_resetpass.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-static bool SendResetEmail(User *u, const NickAlias *na, BotInfo *bi);
-
-class CommandNSResetPass : public Command
-{
- public:
- CommandNSResetPass(Module *creator) : Command(creator, "nickserv/resetpass", 2, 2)
- {
- this->SetDesc(_("Helps you reset lost passwords"));
- this->SetSyntax(_("\037nickname\037 \037email\037"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const NickAlias *na;
-
- if (!(na = NickAlias::Find(params[0])))
- source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
- else if (!na->nc->email.equals_ci(params[1]))
- source.Reply(_("Incorrect email address."));
- else
- {
- if (SendResetEmail(source.GetUser(), na, source.service))
- {
- Log(LOG_COMMAND, source, this) << "for " << na->nick << " (group: " << na->nc->display << ")";
- source.Reply(_("Password reset email for \002%s\002 has been sent."), na->nick.c_str());
- }
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sends a passcode to the nickname with instructions on how to\n"
- "reset their password. Email must be the email address associated\n"
- "to the nickname."));
- return true;
- }
-};
-
-struct ResetInfo
-{
- Anope::string code;
- time_t time;
-};
-
-class NSResetPass : public Module
-{
- CommandNSResetPass commandnsresetpass;
- PrimitiveExtensibleItem<ResetInfo> reset;
-
- public:
- NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsresetpass(this), reset(this, "reset")
- {
- if (!Config->GetBlock("mail")->Get<bool>("usemail"))
- throw ModuleException("Not using mail.");
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- if (command->name == "nickserv/confirm" && params.size() > 1)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return EVENT_STOP;
- }
-
- NickAlias *na = NickAlias::Find(params[0]);
-
- ResetInfo *ri = na ? reset.Get(na->nc) : NULL;
- if (na && ri)
- {
- NickCore *nc = na->nc;
- const Anope::string &passcode = params[1];
- if (ri->time < Anope::CurTime - 3600)
- {
- reset.Unset(nc);
- source.Reply(_("Your password reset request has expired."));
- }
- else if (passcode.equals_cs(ri->code))
- {
- reset.Unset(nc);
- nc->Shrink<bool>("UNCONFIRMED");
-
- Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify as " << na->nick;
-
- if (source.GetUser())
- {
- source.GetUser()->Identify(na);
- source.Reply(_("You are now identified for your nick. Change your password now."));
- }
- }
- else
- return EVENT_CONTINUE;
-
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-static bool SendResetEmail(User *u, const NickAlias *na, BotInfo *bi)
-{
- Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_subject").c_str()),
- message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const Anope::string>("reset_message").c_str()),
- passcode = Anope::Random(20);
-
- subject = subject.replace_all_cs("%n", na->nick);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- subject = subject.replace_all_cs("%c", passcode);
-
- message = message.replace_all_cs("%n", na->nick);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- message = message.replace_all_cs("%c", passcode);
-
- ResetInfo *ri = na->nc->Extend<ResetInfo>("reset");
- ri->code = passcode;
- ri->time = Anope::CurTime;
-
- return Mail::Send(u, na->nc, bi, subject, message);
-}
-
-MODULE_INIT(NSResetPass)
diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp
deleted file mode 100644
index f9351424e..000000000
--- a/modules/commands/ns_set.cpp
+++ /dev/null
@@ -1,1341 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSSet : public Command
-{
- public:
- CommandNSSet(Module *creator) : Command(creator, "nickserv/set", 1, 3)
- {
- this->SetDesc(_("Set options, including kill protection"));
- this->SetSyntax(_("\037option\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various nickname options. \037option\037 can be one of:"));
-
- Anope::string this_name = source.command;
- bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
- hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> c("Command", info.name);
- // XXX dup
- if (!c)
- continue;
- else if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
- continue;
- else if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
- continue;
-
- source.command = c_name;
- c->OnServHelp(source);
- }
- }
-
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
-
- return true;
- }
-};
-
-class CommandNSSASet : public Command
-{
- public:
- CommandNSSASet(Module *creator) : Command(creator, "nickserv/saset", 2, 4)
- {
- this->SetDesc(_("Set SET-options on another nickname"));
- this->SetSyntax(_("\037option\037 \037nickname\037 \037parameters\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various nickname options. \037option\037 can be one of:"));
-
- Anope::string this_name = source.command;
- for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it)
- {
- const Anope::string &c_name = it->first;
- const CommandInfo &info = it->second;
-
- if (c_name.find_ci(this_name + " ") == 0)
- {
- ServiceReference<Command> command("Command", info.name);
- if (command)
- {
- source.command = c_name;
- command->OnServHelp(source);
- }
- }
- }
-
- source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option. The options will be set on the given\n"
- "\037nickname\037."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
- return true;
- }
-};
-
-class CommandNSSetPassword : public Command
-{
- public:
- CommandNSSetPassword(Module *creator) : Command(creator, "nickserv/set/password", 1)
- {
- this->SetDesc(_("Set your nickname password"));
- this->SetSyntax(_("\037new-password\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &param = params[0];
- unsigned len = param.length();
-
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (source.GetNick().equals_ci(param) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
- {
- source.Reply(MORE_OBSCURE_PASSWORD);
- return;
- }
-
- unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
- if (len > passlen)
- {
- source.Reply(PASSWORD_TOO_LONG, passlen);
- return;
- }
-
- Log(LOG_COMMAND, source, this) << "to change their password";
-
- Anope::Encrypt(param, source.nc->pass);
- Anope::string tmp_pass;
- if (Anope::Decrypt(source.nc->pass, tmp_pass) == 1)
- source.Reply(_("Password for \002%s\002 changed to \002%s\002."), source.nc->display.c_str(), tmp_pass.c_str());
- else
- source.Reply(_("Password for \002%s\002 changed."), source.nc->display.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the password used to identify you as the nick's\n"
- "owner."));
- return true;
- }
-};
-
-class CommandNSSASetPassword : public Command
-{
- public:
- CommandNSSASetPassword(Module *creator) : Command(creator, "nickserv/saset/password", 2, 2)
- {
- this->SetDesc(_("Set the nickname password"));
- this->SetSyntax(_("\037nickname\037 \037new-password\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *setter_na = NickAlias::Find(params[0]);
- if (setter_na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
- NickCore *nc = setter_na->nc;
-
- size_t len = params[1].length();
-
- if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
- {
- source.Reply(_("You may not change the password of other Services Operators."));
- return;
- }
-
- if (nc->display.equals_ci(params[1]) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
- {
- source.Reply(MORE_OBSCURE_PASSWORD);
- return;
- }
-
- unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
- if (len > passlen)
- {
- source.Reply(PASSWORD_TOO_LONG, passlen);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "to change the password of " << nc->display;
-
- Anope::Encrypt(params[1], nc->pass);
- Anope::string tmp_pass;
- if (Anope::Decrypt(nc->pass, tmp_pass) == 1)
- source.Reply(_("Password for \002%s\002 changed to \002%s\002."), nc->display.c_str(), tmp_pass.c_str());
- else
- source.Reply(_("Password for \002%s\002 changed."), nc->display.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the password used to identify as the nick's owner."));
- return true;
- }
-};
-
-class CommandNSSetAutoOp : public Command
-{
- public:
- CommandNSSetAutoOp(Module *creator, const Anope::string &sname = "nickserv/set/autoop", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Sets whether services should set channel status modes on you automatically."));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable autoop for " << na->nc->display;
- nc->Extend<bool>("AUTOOP");
- source.Reply(_("Services will from now on set status modes on %s in channels."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable autoop for " << na->nc->display;
- nc->Shrink<bool>("AUTOOP");
- source.Reply(_("Services will no longer set status modes on %s in channels."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "AUTOOP");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- BotInfo *bi = Config->GetClient("ChanServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether you will be given your channel status modes automatically.\n"
- "Set to \002ON\002 to allow %s to set status modes on you automatically\n"
- "when entering channels. Note that depending on channel settings some modes\n"
- "may not get set automatically."), bi ? bi->nick.c_str() : "ChanServ");
- return true;
- }
-};
-
-class CommandNSSASetAutoOp : public CommandNSSetAutoOp
-{
- public:
- CommandNSSASetAutoOp(Module *creator) : CommandNSSetAutoOp(creator, "nickserv/saset/autoop", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- BotInfo *bi = Config->GetClient("ChanServ");
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether the given nickname will be given its status modes\n"
- "in channels automatically. Set to \002ON\002 to allow %s\n"
- "to set status modes on the given nickname automatically when it\n"
- "is entering channels. Note that depending on channel settings\n"
- "some modes may not get set automatically."), bi ? bi->nick.c_str() : "ChanServ");
- return true;
- }
-};
-
-class CommandNSSetDisplay : public Command
-{
- public:
- CommandNSSetDisplay(Module *creator, const Anope::string &sname = "nickserv/set/display", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Set the display of your group in Services"));
- this->SetSyntax(_("\037new-display\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param);
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- {
- source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
- return;
- }
- if (user_na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- else if (!na || *na->nc != *user_na->nc)
- {
- source.Reply(_("The new display MUST be a nickname of the nickname group %s."), user_na->nc->display.c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, user_na->nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Log(user_na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the display of " << user_na->nc->display << " to " << na->nick;
-
- user_na->nc->SetDisplay(na);
-
- /* Send updated account name */
- for (std::list<User *>::iterator it = user_na->nc->users.begin(); it != user_na->nc->users.end(); ++it)
- {
- User *u = *it;
- IRCD->SendLogin(u, user_na);
- }
-
- source.Reply(NICK_SET_DISPLAY_CHANGED, user_na->nc->display.c_str());
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the display used to refer to your nickname group in\n"
- "Services. The new display MUST be a nick of your group."));
- return true;
- }
-};
-
-class CommandNSSASetDisplay : public CommandNSSetDisplay
-{
- public:
- CommandNSSASetDisplay(Module *creator) : CommandNSSetDisplay(creator, "nickserv/saset/display", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037new-display\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the display used to refer to the nickname group in\n"
- "Services. The new display MUST be a nick of the group."));
- return true;
- }
-};
-
-class CommandNSSetEmail : public Command
-{
- static bool SendConfirmMail(User *u, BotInfo *bi, const Anope::string &new_email)
- {
- Anope::string code = Anope::Random(9);
-
- std::pair<Anope::string, Anope::string> *n = u->Account()->Extend<std::pair<Anope::string, Anope::string> >("ns_set_email");
- n->first = new_email;
- n->second = code;
-
- Anope::string subject = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_subject"),
- message = Config->GetBlock("mail")->Get<const Anope::string>("emailchange_message");
-
- subject = subject.replace_all_cs("%e", u->Account()->email);
- subject = subject.replace_all_cs("%E", new_email);
- subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- subject = subject.replace_all_cs("%c", code);
-
- message = message.replace_all_cs("%e", u->Account()->email);
- message = message.replace_all_cs("%E", new_email);
- message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
- message = message.replace_all_cs("%c", code);
-
- Anope::string old = u->Account()->email;
- u->Account()->email = new_email;
- bool b = Mail::Send(u, u->Account(), bi, subject, message);
- u->Account()->email = old;
- return b;
- }
-
- public:
- CommandNSSetEmail(Module *creator, const Anope::string &cname = "nickserv/set/email", size_t min = 0) : Command(creator, cname, min, min + 1)
- {
- this->SetDesc(_("Associate an E-mail address with your nickname"));
- this->SetSyntax(_("\037address\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- if (nc->HasExt("UNCONFIRMED"))
- {
- source.Reply(_("You may not change the email of an unconfirmed account."));
- return;
- }
-
- if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
- {
- source.Reply(_("You cannot unset the e-mail on this network."));
- return;
- }
- else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
- {
- source.Reply(_("You may not change the e-mail of other Services Operators."));
- return;
- }
- else if (!param.empty() && !Mail::Validate(param))
- {
- source.Reply(MAIL_X_INVALID, param.c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (!param.empty() && Config->GetModule("nickserv")->Get<bool>("confirmemailchanges") && !source.IsServicesOper())
- {
- if (SendConfirmMail(source.GetUser(), source.service, param))
- source.Reply(_("A confirmation e-mail has been sent to \002%s\002. Follow the instructions in it to change your e-mail address."), param.c_str());
- }
- else
- {
- if (!param.empty())
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the email of " << nc->display << " to " << param;
- nc->email = param;
- source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str());
- }
- else
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to unset the email of " << nc->display;
- nc->email.clear();
- source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str());
- }
- }
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params.size() ? params[0] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Associates the given E-mail address with your nickname.\n"
- "This address will be displayed whenever someone requests\n"
- "information on the nickname with the \002INFO\002 command."));
- return true;
- }
-};
-
-class CommandNSSASetEmail : public CommandNSSetEmail
-{
- public:
- CommandNSSASetEmail(Module *creator) : CommandNSSetEmail(creator, "nickserv/saset/email", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037address\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params.size() > 1 ? params[1] : "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Associates the given E-mail address with the nickname."));
- return true;
- }
-};
-
-class CommandNSSetKeepModes : public Command
-{
- public:
- CommandNSSetKeepModes(Module *creator, const Anope::string &sname = "nickserv/set/keepmodes", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Enable or disable keep modes"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable keepmodes for " << nc->display;
- nc->Extend<bool>("NS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002on\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable keepmodes for " << nc->display;
- nc->Shrink<bool>("NS_KEEP_MODES");
- source.Reply(_("Keep modes for %s is now \002off\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables keepmodes for your nick. If keep\n"
- "modes is enabled, services will remember your usermodes\n"
- "and attempt to re-set them the next time you authenticate."));
- return true;
- }
-};
-
-class CommandNSSASetKeepModes : public CommandNSSetKeepModes
-{
- public:
- CommandNSSASetKeepModes(Module *creator) : CommandNSSetKeepModes(creator, "nickserv/saset/keepmodes", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Enables or disables keepmodes for the given nick. If keep\n"
- "modes is enabled, services will remember users' usermodes\n"
- "and attempt to re-set them the next time they authenticate."));
- return true;
- }
-};
-
-class CommandNSSetKill : public Command
-{
- public:
- CommandNSSetKill(Module *creator, const Anope::string &sname = "nickserv/set/kill", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Turn protection on or off"));
- this->SetSyntax("{ON | QUICK | IMMED | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
- {
- source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- nc->Extend<bool>("KILLPROTECT");
- nc->Shrink<bool>("KILL_QUICK");
- nc->Shrink<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill on for " << nc->display;
- source.Reply(_("Protection is now \002on\002 for \002%s\002."), nc->display.c_str());
- }
- else if (param.equals_ci("QUICK"))
- {
- nc->Extend<bool>("KILLPROTECT");
- nc->Extend<bool>("KILL_QUICK");
- nc->Shrink<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill quick for " << nc->display;
- source.Reply(_("Protection is now \002on\002 for \002%s\002, with a reduced delay."), nc->display.c_str());
- }
- else if (param.equals_ci("IMMED"))
- {
- if (Config->GetModule(this->owner)->Get<bool>("allowkillimmed"))
- {
- nc->Extend<bool>("KILLPROTECT");
- nc->Shrink<bool>("KILL_QUICK");
- nc->Extend<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to set kill immed for " << nc->display;
- source.Reply(_("Protection is now \002on\002 for \002%s\002, with no delay."), nc->display.c_str());
- }
- else
- source.Reply(_("The \002IMMED\002 option is not available on this network."));
- }
- else if (param.equals_ci("OFF"))
- {
- nc->Shrink<bool>("KILLPROTECT");
- nc->Shrink<bool>("KILL_QUICK");
- nc->Shrink<bool>("KILL_IMMED");
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable kill for " << nc->display;
- source.Reply(_("Protection is now \002off\002 for \002%s\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "KILL");
-
- return;
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns the automatic protection option for your nick\n"
- "on or off. With protection on, if another user\n"
- "tries to take your nick, they will be given one minute to\n"
- "change to another nick, after which %s will forcibly change\n"
- "their nick.\n"
- " \n"
- "If you select \002QUICK\002, the user will be given only 20 seconds\n"
- "to change nicks instead of the usual 60. If you select\n"
- "\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n"
- "warned first or given a chance to change their nick; please\n"
- "do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetKill : public CommandNSSetKill
-{
- public:
- CommandNSSASetKill(Module *creator) : CommandNSSetKill(creator, "nickserv/saset/kill", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | QUICK | IMMED | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns the automatic protection option for the nick\n"
- "on or off. With protection on, if another user\n"
- "tries to take the nick, they will be given one minute to\n"
- "change to another nick, after which %s will forcibly change\n"
- "their nick.\n"
- " \n"
- "If you select \002QUICK\002, the user will be given only 20 seconds\n"
- "to change nicks instead of the usual 60. If you select\n"
- "\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n"
- "warned first or given a chance to change their nick; please\n"
- "do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSetLanguage : public Command
-{
- public:
- CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Set the language Services will use when messaging you"));
- this->SetSyntax(_("\037language\037"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param != "en_US")
- for (unsigned j = 0; j < Language::Languages.size(); ++j)
- {
- if (Language::Languages[j] == param)
- break;
- else if (j + 1 == Language::Languages.size())
- {
- this->OnSyntaxError(source, "");
- return;
- }
- }
-
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the language of " << nc->display << " to " << param;
-
- nc->language = param;
- if (source.GetAccount() == nc)
- source.Reply(_("Language changed to \002English\002."));
- else
- source.Reply(_("Language for \002%s\002 changed to \002%s\002."), nc->display.c_str(), Language::Translate(param.c_str(), _("English")));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &param) anope_override
- {
- this->Run(source, source.nc->display, param[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the language Services uses when sending messages to\n"
- "you (for example, when responding to a command you send).\n"
- "\037language\037 should be chosen from the following list of\n"
- "supported languages:"));
-
- source.Reply(" en_US (English)");
- for (unsigned j = 0; j < Language::Languages.size(); ++j)
- {
- const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English"));
- if (langname == "English")
- continue;
- source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str());
- }
-
- return true;
- }
-};
-
-class CommandNSSASetLanguage : public CommandNSSetLanguage
-{
- public:
- CommandNSSASetLanguage(Module *creator) : CommandNSSetLanguage(creator, "nickserv/saset/language", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 \037language\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Changes the language Services uses when sending messages to\n"
- "the given user (for example, when responding to a command they send).\n"
- "\037language\037 should be chosen from the following list of\n"
- "supported languages:"));
- source.Reply(" en (English)");
- for (unsigned j = 0; j < Language::Languages.size(); ++j)
- {
- const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English"));
- if (langname == "English")
- continue;
- source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str());
- }
- return true;
- }
-};
-
-class CommandNSSetMessage : public Command
-{
- public:
- CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Change the communication method of Services"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
- {
- source.Reply(_("You cannot %s on this network."), source.command.c_str());
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->display;
- nc->Extend<bool>("MSG");
- source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->display;
- nc->Shrink<bool>("MSG");
- source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "MSG");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- Anope::string cmd = source.command;
- size_t i = cmd.find_last_of(' ');
- if (i != Anope::string::npos)
- cmd = cmd.substr(i + 1);
-
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to choose the way Services are communicating with\n"
- "you. With \002%s\002 set, Services will use messages, else they'll\n"
- "use notices."), cmd.upper().c_str());
- return true;
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
- Command::OnServHelp(source);
- }
-};
-
-class CommandNSSASetMessage : public CommandNSSetMessage
-{
- public:
- CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to choose the way Services are communicating with\n"
- "the given user. With \002MSG\002 set, Services will use messages,\n"
- "else they'll use notices."));
- return true;
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-};
-
-class CommandNSSetSecure : public Command
-{
- public:
- CommandNSSetSecure(Module *creator, const Anope::string &sname = "nickserv/set/secure", size_t min = 1) : Command(creator, sname, min, min + 1)
- {
- this->SetDesc(_("Turn nickname security on or off"));
- this->SetSyntax("{ON | OFF}");
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- if (param.equals_ci("ON"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable secure for " << nc->display;
- nc->Extend<bool>("NS_SECURE");
- source.Reply(_("Secure option is now \002on\002 for \002%s\002."), nc->display.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable secure for " << nc->display;
- nc->Shrink<bool>("NS_SECURE");
- source.Reply(_("Secure option is now \002off\002 for \002%s\002."), nc->display.c_str());
- }
- else
- this->OnSyntaxError(source, "SECURE");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, params[0]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's security features on or off for your\n"
- "nick. With \002SECURE\002 set, you must enter your password\n"
- "before you will be recognized as the owner of the nick,\n"
- "regardless of whether your address is on the access\n"
- "list. However, if you are on the access list, %s\n"
- "will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetSecure : public CommandNSSetSecure
-{
- public:
- CommandNSSASetSecure(Module *creator) : CommandNSSetSecure(creator, "nickserv/saset/secure", 2)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params[1]);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Turns %s's security features on or off for your\n"
- "nick. With \002SECURE\002 set, you must enter your password\n"
- "before you will be recognized as the owner of the nick,\n"
- "regardless of whether your address is on the access\n"
- "list. However, if you are on the access list, %s\n"
- "will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), source.service->nick.c_str(), source.service->nick.c_str());
- return true;
- }
-};
-
-class CommandNSSASetNoexpire : public Command
-{
- public:
- CommandNSSASetNoexpire(Module *creator) : Command(creator, "nickserv/saset/noexpire", 1, 2)
- {
- this->SetDesc(_("Prevent the nickname from expiring"));
- this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- NickAlias *na = NickAlias::Find(params[0]);
- if (na == NULL)
- {
- source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
-
- Anope::string param = params.size() > 1 ? params[1] : "";
-
- if (param.equals_ci("ON"))
- {
- Log(LOG_ADMIN, source, this) << "to enable noexpire for " << na->nick << " (" << na->nc->display << ")";
- na->Extend<bool>("NS_NO_EXPIRE");
- source.Reply(_("Nick %s \002will not\002 expire."), na->nick.c_str());
- }
- else if (param.equals_ci("OFF"))
- {
- Log(LOG_ADMIN, source, this) << "to disable noexpire for " << na->nick << " (" << na->nc->display << ")";
- na->Shrink<bool>("NS_NO_EXPIRE");
- source.Reply(_("Nick %s \002will\002 expire."), na->nick.c_str());
- }
- else
- this->OnSyntaxError(source, "NOEXPIRE");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets whether the given nickname will expire. Setting this\n"
- "to \002ON\002 prevents the nickname from expiring."));
- return true;
- }
-};
-
-class NSSet : public Module
-{
- CommandNSSet commandnsset;
- CommandNSSASet commandnssaset;
-
- CommandNSSetAutoOp commandnssetautoop;
- CommandNSSASetAutoOp commandnssasetautoop;
-
- CommandNSSetDisplay commandnssetdisplay;
- CommandNSSASetDisplay commandnssasetdisplay;
-
- CommandNSSetEmail commandnssetemail;
- CommandNSSASetEmail commandnssasetemail;
-
- CommandNSSetKeepModes commandnssetkeepmodes;
- CommandNSSASetKeepModes commandnssasetkeepmodes;
-
- CommandNSSetKill commandnssetkill;
- CommandNSSASetKill commandnssasetkill;
-
- CommandNSSetLanguage commandnssetlanguage;
- CommandNSSASetLanguage commandnssasetlanguage;
-
- CommandNSSetMessage commandnssetmessage;
- CommandNSSASetMessage commandnssasetmessage;
-
- CommandNSSetPassword commandnssetpassword;
- CommandNSSASetPassword commandnssasetpassword;
-
- CommandNSSetSecure commandnssetsecure;
- CommandNSSASetSecure commandnssasetsecure;
-
- CommandNSSASetNoexpire commandnssasetnoexpire;
-
- SerializableExtensibleItem<bool> autoop, killprotect, kill_quick, kill_immed,
- message, secure, noexpire;
-
- struct KeepModes : SerializableExtensibleItem<bool>
- {
- KeepModes(Module *m, const Anope::string &n) : SerializableExtensibleItem<bool>(m, n) { }
-
- void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleSerialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- const NickCore *nc = anope_dynamic_static_cast<const NickCore *>(s);
- Anope::string modes;
- for (User::ModeList::const_iterator it = nc->last_modes.begin(); it != nc->last_modes.end(); ++it)
- {
- if (!modes.empty())
- modes += " ";
- modes += it->first;
- if (!it->second.empty())
- modes += "," + it->second;
- }
- data["last_modes"] << modes;
- }
-
- void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override
- {
- SerializableExtensibleItem<bool>::ExtensibleUnserialize(e, s, data);
-
- if (s->GetSerializableType()->GetName() != "NickCore")
- return;
-
- NickCore *nc = anope_dynamic_static_cast<NickCore *>(s);
- Anope::string modes;
- data["last_modes"] >> modes;
- for (spacesepstream sep(modes); sep.GetToken(modes);)
- {
- size_t c = modes.find(',');
- if (c == Anope::string::npos)
- nc->last_modes.insert(std::make_pair(modes, ""));
- else
- nc->last_modes.insert(std::make_pair(modes.substr(0, c), modes.substr(c + 1)));
- }
- }
- } keep_modes;
-
- /* email, passcode */
- PrimitiveExtensibleItem<std::pair<Anope::string, Anope::string > > ns_set_email;
-
- public:
- NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsset(this), commandnssaset(this),
- commandnssetautoop(this), commandnssasetautoop(this),
- commandnssetdisplay(this), commandnssasetdisplay(this),
- commandnssetemail(this), commandnssasetemail(this),
- commandnssetkeepmodes(this), commandnssasetkeepmodes(this),
- commandnssetkill(this), commandnssasetkill(this),
- commandnssetlanguage(this), commandnssasetlanguage(this),
- commandnssetmessage(this), commandnssasetmessage(this),
- commandnssetpassword(this), commandnssasetpassword(this),
- commandnssetsecure(this), commandnssasetsecure(this),
- commandnssasetnoexpire(this),
-
- autoop(this, "AUTOOP"),
- killprotect(this, "KILLPROTECT"), kill_quick(this, "KILL_QUICK"),
- kill_immed(this, "KILL_IMMED"), message(this, "MSG"),
- secure(this, "NS_SECURE"), noexpire(this, "NS_NO_EXPIRE"),
-
- keep_modes(this, "NS_KEEP_MODES"), ns_set_email(this, "ns_set_email")
- {
-
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- NickCore *uac = source.nc;
-
- if (command->name == "nickserv/confirm" && !params.empty() && uac)
- {
- std::pair<Anope::string, Anope::string> *n = ns_set_email.Get(uac);
- if (n)
- {
- if (params[0] == n->second)
- {
- uac->email = n->first;
- Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->email;
- source.Reply(_("Your email address has been changed to \002%s\002."), uac->email.c_str());
- ns_set_email.Unset(uac);
- return EVENT_STOP;
- }
- }
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
- {
- if (chan->ci)
- {
- /* Only give modes if autoop is set */
- give_modes &= !user->Account() || autoop.HasExt(user->Account());
- }
- }
-
- void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
- {
- if (noexpire.HasExt(na))
- expire = false;
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- if (!show_hidden)
- return;
-
- if (kill_immed.HasExt(na->nc))
- info.AddOption(_("Immediate protection"));
- else if (kill_quick.HasExt(na->nc))
- info.AddOption(_("Quick protection"));
- else if (killprotect.HasExt(na->nc))
- info.AddOption(_("Protection"));
- if (secure.HasExt(na->nc))
- info.AddOption(_("Security"));
- if (message.HasExt(na->nc))
- info.AddOption(_("Message mode"));
- if (autoop.HasExt(na->nc))
- info.AddOption(_("Auto-op"));
- if (noexpire.HasExt(na))
- info.AddOption(_("No expire"));
- if (keep_modes.HasExt(na->nc))
- info.AddOption(_("Keep modes"));
- }
-
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (u->Account() && setter.GetUser() == u)
- u->Account()->last_modes = u->GetModeList();
- }
-
- void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (u->Account() && setter.GetUser() == u)
- u->Account()->last_modes = u->GetModeList();
- }
-
- void OnUserLogin(User *u) anope_override
- {
- if (keep_modes.HasExt(u->Account()))
- {
- User::ModeList modes = u->Account()->last_modes;
- for (User::ModeList::iterator it = modes.begin(); it != modes.end(); ++it)
- {
- UserMode *um = ModeManager::FindUserModeByName(it->first);
- /* if the null user can set the mode, then it's probably safe */
- if (um && um->CanSet(NULL))
- u->SetMode(NULL, it->first, it->second);
- }
- }
- }
-};
-
-MODULE_INIT(NSSet)
diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp
deleted file mode 100644
index c145e386c..000000000
--- a/modules/commands/ns_set_misc.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- *
- * (C) 2003-2016 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 "modules/set_misc.h"
-
-static Module *me;
-
-static Anope::map<Anope::string> descriptions;
-
-struct NSMiscData;
-static Anope::map<ExtensibleItem<NSMiscData> *> items;
-
-static ExtensibleItem<NSMiscData> *GetItem(const Anope::string &name)
-{
- ExtensibleItem<NSMiscData>* &it = items[name];
- if (!it)
- try
- {
- it = new ExtensibleItem<NSMiscData>(me, name);
- }
- catch (const ModuleException &) { }
- return it;
-}
-
-struct NSMiscData : MiscData, Serializable
-{
- NSMiscData(Extensible *) : Serializable("NSMiscData") { }
-
- NSMiscData(NickCore *ncore, const Anope::string &n, const Anope::string &d) : Serializable("NSMiscData")
- {
- object = ncore->display;
- name = n;
- data = d;
- }
-
- void Serialize(Serialize::Data &sdata) const anope_override
- {
- sdata["nc"] << this->object;
- sdata["name"] << this->name;
- sdata["data"] << this->data;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snc, sname, sdata;
-
- data["nc"] >> snc;
- data["name"] >> sname;
- data["data"] >> sdata;
-
- NickCore *nc = NickCore::Find(snc);
- if (nc == NULL)
- return NULL;
-
- NSMiscData *d = NULL;
- if (obj)
- {
- d = anope_dynamic_static_cast<NSMiscData *>(obj);
- d->object = nc->display;
- data["name"] >> d->name;
- data["data"] >> d->data;
- }
- else
- {
- ExtensibleItem<NSMiscData> *item = GetItem(sname);
- if (item)
- d = item->Set(nc, NSMiscData(nc, sname, sdata));
- }
-
- return d;
- }
-};
-
-static Anope::string GetAttribute(const Anope::string &command)
-{
- size_t sp = command.rfind(' ');
- if (sp != Anope::string::npos)
- return command.substr(sp + 1);
- return command;
-}
-
-class CommandNSSetMisc : public Command
-{
- public:
- CommandNSSetMisc(Module *creator, const Anope::string &cname = "nickserv/set/misc", size_t min = 0) : Command(creator, cname, min, min + 1)
- {
- this->SetSyntax(_("[\037parameter\037]"));
- }
-
- void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
- {
- if (Anope::ReadOnly)
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(user);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
- return;
- }
- NickCore *nc = na->nc;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Anope::string scommand = GetAttribute(source.command);
- Anope::string key = "ns_set_misc:" + scommand;
- ExtensibleItem<NSMiscData> *item = GetItem(key);
- if (item == NULL)
- return;
-
- if (!param.empty())
- {
- item->Set(nc, NSMiscData(nc, key, param));
- source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), nc->display.c_str(), param.c_str());
- }
- else
- {
- item->Unset(nc);
- source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), nc->display.c_str());
- }
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, source.nc->display, !params.empty() ? params[0] : "");
- }
-
- void OnServHelp(CommandSource &source) anope_override
- {
- if (descriptions.count(source.command))
- {
- this->SetDesc(descriptions[source.command]);
- Command::OnServHelp(source);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (descriptions.count(source.command))
- {
- source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
- return true;
- }
- return false;
- }
-};
-
-class CommandNSSASetMisc : public CommandNSSetMisc
-{
- public:
- CommandNSSASetMisc(Module *creator) : CommandNSSetMisc(creator, "nickserv/saset/misc", 1)
- {
- this->ClearSyntax();
- this->SetSyntax(_("\037nickname\037 [\037parameter\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- this->Run(source, params[0], params.size() > 1 ? params[1] : "");
- }
-};
-
-class NSSetMisc : public Module
-{
- CommandNSSetMisc commandnssetmisc;
- CommandNSSASetMisc commandnssasetmisc;
- Serialize::Type nsmiscdata_type;
-
- public:
- NSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnssetmisc(this), commandnssasetmisc(this), nsmiscdata_type("NSMiscData", NSMiscData::Unserialize)
- {
- me = this;
- }
-
- ~NSSetMisc()
- {
- for (Anope::map<ExtensibleItem<NSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- delete it->second;
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- descriptions.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- const Anope::string &cmd = block->Get<const Anope::string>("command");
-
- if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc")
- continue;
-
- Anope::string cname = block->Get<const Anope::string>("name");
- Anope::string desc = block->Get<const Anope::string>("misc_description");
-
- if (cname.empty() || desc.empty())
- continue;
-
- descriptions[cname] = desc;
- }
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool) anope_override
- {
- for (Anope::map<ExtensibleItem<NSMiscData> *>::iterator it = items.begin(); it != items.end(); ++it)
- {
- ExtensibleItem<NSMiscData> *e = it->second;
- NSMiscData *data = e->Get(na->nc);
-
- if (data != NULL)
- info[e->name.substr(12).replace_all_cs("_", " ")] = data->data;
- }
- }
-};
-
-MODULE_INIT(NSSetMisc)
diff --git a/modules/commands/ns_status.cpp b/modules/commands/ns_status.cpp
deleted file mode 100644
index b06e51ec4..000000000
--- a/modules/commands/ns_status.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSStatus : public Command
-{
- public:
- CommandNSStatus(Module *creator) : Command(creator, "nickserv/status", 0, 16)
- {
- this->SetDesc(_("Returns the owner status of the given nickname"));
- this->SetSyntax(_("[\037nickname\037]"));
- this->AllowUnregistered(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = !params.empty() ? params[0] : source.GetNick();
- const NickAlias *na = NickAlias::Find(nick);
- spacesepstream sep(nick);
- Anope::string nickbuf;
-
- while (sep.GetToken(nickbuf))
- {
- User *u2 = User::Find(nickbuf, true);
- if (!u2) /* Nick is not online */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 0, "");
- else if (u2->IsIdentified() && na && na->nc == u2->Account()) /* Nick is identified */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 3, u2->Account()->display.c_str());
- else if (u2->IsRecognized()) /* Nick is recognised, but NOT identified */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 2, u2->Account() ? u2->Account()->display.c_str() : "");
- else if (!na) /* Nick is online, but NOT a registered */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 0, "");
- else
- /* Nick is not identified for the nick, but they could be logged into an account,
- * so we tell the user about it
- */
- source.Reply("STATUS %s %d %s", nickbuf.c_str(), 1, u2->Account() ? u2->Account()->display.c_str() : "");
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Returns whether the user using the given nickname is\n"
- "recognized as the owner of the nickname. The response has\n"
- "this format:\n"
- " \n"
- " \037nickname\037 \037status-code\037 \037account\037\n"
- " \n"
- "where \037nickname\037 is the nickname sent with the command,\n"
- "\037status-code\037 is one of the following, and \037account\037\n"
- "is the account they are logged in as.\n"
- " \n"
- " 0 - no such user online \002or\002 nickname not registered\n"
- " 1 - user not recognized as nickname's owner\n"
- " 2 - user recognized as owner via access list only\n"
- " 3 - user recognized as owner via password identification\n"
- " \n"
- "If no nickname is given, your status will be returned."));
- return true;
- }
-};
-
-class NSStatus : public Module
-{
- CommandNSStatus commandnsstatus;
-
- public:
- NSStatus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsstatus(this)
- {
-
- }
-};
-
-MODULE_INIT(NSStatus)
diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp
deleted file mode 100644
index 76b79d1d1..000000000
--- a/modules/commands/ns_suspend.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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 "modules/suspend.h"
-
-static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
-
-struct NSSuspendInfo : SuspendInfo, Serializable
-{
- NSSuspendInfo(Extensible *) : Serializable("NSSuspendInfo") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["nick"] << what;
- data["by"] << by;
- data["reason"] << reason;
- data["time"] << when;
- data["expires"] << expires;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string snick;
- data["nick"] >> snick;
-
- NSSuspendInfo *si;
- if (obj)
- si = anope_dynamic_static_cast<NSSuspendInfo *>(obj);
- else
- {
- NickAlias *na = NickAlias::Find(snick);
- if (!na)
- return NULL;
- si = na->nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
- data["nick"] >> si->what;
- }
-
- data["by"] >> si->by;
- data["reason"] >> si->reason;
- data["time"] >> si->when;
- data["expires"] >> si->expires;
- return si;
- }
-};
-
-class CommandNSSuspend : public Command
-{
- public:
- CommandNSSuspend(Module *creator) : Command(creator, "nickserv/suspend", 2, 3)
- {
- this->SetDesc(_("Suspend a given nick"));
- this->SetSyntax(_("\037nickname\037 [+\037expiry\037] [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
-
- const Anope::string &nick = params[0];
- Anope::string expiry = params[1];
- Anope::string reason = params.size() > 2 ? params[2] : "";
- time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire");
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- if (expiry[0] != '+')
- {
- reason = expiry + " " + reason;
- reason.trim();
- expiry.clear();
- }
- else
- {
- expiry_secs = Anope::DoTime(expiry);
- if (expiry_secs == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- }
-
- NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
- {
- source.Reply(_("You may not suspend other Services Operators' nicknames."));
- return;
- }
-
- if (na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(_("\002%s\002 is already suspended."), na->nc->display.c_str());
- return;
- }
-
- NickCore *nc = na->nc;
-
- NSSuspendInfo *si = nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
- si->what = nc->display;
- si->by = source.GetNick();
- si->reason = reason;
- si->when = Anope::CurTime;
- si->expires = expiry_secs ? expiry_secs + Anope::CurTime : 0;
-
- for (unsigned i = 0; i < nc->aliases->size(); ++i)
- {
- NickAlias *na2 = nc->aliases->at(i);
-
- if (na2 && *na2->nc == *na->nc)
- {
- na2->last_quit = reason;
-
- User *u2 = User::Find(na2->nick, true);
- if (u2)
- {
- u2->Logout();
- if (nickserv)
- nickserv->Collide(u2, na2);
- }
- }
- }
-
- Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires on " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
- source.Reply(_("Nick %s is now suspended."), nick.c_str());
-
- FOREACH_MOD(OnNickSuspend, (na));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Suspends a registered nickname, which prevents it from being used\n"
- "while keeping all the data for that nick. If an expiry is given\n"
- "the nick will be unsuspended after that period of time, else the\n"
- "default expiry from the configuration is used."));
- return true;
- }
-};
-
-class CommandNSUnSuspend : public Command
-{
- public:
- CommandNSUnSuspend(Module *creator) : Command(creator, "nickserv/unsuspend", 1, 1)
- {
- this->SetDesc(_("Unsuspend a given nick"));
- this->SetSyntax(_("\037nickname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- NickAlias *na = NickAlias::Find(nick);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- return;
- }
-
- if (!na->nc->HasExt("NS_SUSPENDED"))
- {
- source.Reply(_("Nick %s is not suspended."), na->nick.c_str());
- return;
- }
-
- NSSuspendInfo *si = na->nc->GetExt<NSSuspendInfo>("NS_SUSPENDED");
-
- Log(LOG_ADMIN, source, this) << "for " << na->nick << " which was suspended by " << (!si->by.empty() ? si->by : "(none)") << " for: " << (!si->reason.empty() ? si->reason : "No reason");
-
- na->nc->Shrink<NSSuspendInfo>("NS_SUSPENDED");
-
- source.Reply(_("Nick %s is now released."), nick.c_str());
-
- FOREACH_MOD(OnNickUnsuspended, (na));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Unsuspends a nickname which allows it to be used again."));
- return true;
- }
-};
-
-class NSSuspend : public Module
-{
- CommandNSSuspend commandnssuspend;
- CommandNSUnSuspend commandnsunsuspend;
- ExtensibleItem<NSSuspendInfo> suspend;
- Serialize::Type suspend_type;
- std::vector<Anope::string> show;
-
- struct trim
- {
- Anope::string operator()(Anope::string s) const
- {
- return s.trim();
- }
- };
-
- bool Show(CommandSource &source, const Anope::string &what) const
- {
- return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
- }
-
- public:
- NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnssuspend(this), commandnsunsuspend(this), suspend(this, "NS_SUSPENDED"),
- suspend_type("NSSuspendInfo", NSSuspendInfo::Unserialize)
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Anope::string s = conf->GetModule(this)->Get<Anope::string>("show");
- commasepstream(s).GetTokens(show);
- std::transform(show.begin(), show.end(), show.begin(), trim());
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- NSSuspendInfo *s = suspend.Get(na->nc);
- if (!s)
- return;
-
- if (show_hidden || Show(source, "suspended"))
- info[_("Suspended")] = _("This nickname is \002suspended\002.");
- if (!s->by.empty() && (show_hidden || Show(source, "by")))
- info[_("Suspended by")] = s->by;
- if (!s->reason.empty() && (show_hidden || Show(source, "reason")))
- info[_("Suspend reason")] = s->reason;
- if (s->when && (show_hidden || Show(source, "on")))
- info[_("Suspended on")] = Anope::strftime(s->when, source.GetAccount());
- if (s->expires && (show_hidden || Show(source, "expires")))
- info[_("Suspension expires")] = Anope::strftime(s->expires, source.GetAccount());
- }
-
- void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
- {
- NSSuspendInfo *s = suspend.Get(na->nc);
- if (!s)
- return;
-
- expire = false;
-
- if (!s->expires)
- return;
-
- if (s->expires < Anope::CurTime)
- {
- na->last_seen = Anope::CurTime;
- suspend.Unset(na->nc);
-
- Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
- }
- }
-
- EventReturn OnNickValidate(User *u, NickAlias *na) anope_override
- {
- NSSuspendInfo *s = suspend.Get(na->nc);
- if (!s)
- return EVENT_CONTINUE;
-
- u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str());
- return EVENT_STOP;
- }
-};
-
-MODULE_INIT(NSSuspend)
diff --git a/modules/commands/ns_update.cpp b/modules/commands/ns_update.cpp
deleted file mode 100644
index fcbe02f21..000000000
--- a/modules/commands/ns_update.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandNSUpdate : public Command
-{
- public:
- CommandNSUpdate(Module *creator) : Command(creator, "nickserv/update", 0, 0)
- {
- this->SetDesc(_("Updates your current status, i.e. it checks for new memos"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- NickAlias *na = NickAlias::Find(u->nick);
-
- if (na && na->nc == source.GetAccount())
- {
- na->last_realname = u->realname;
- na->last_seen = Anope::CurTime;
- }
-
- FOREACH_MOD(OnNickUpdate, (u));
-
- source.Reply(_("Status updated (memos, vhost, chmodes, flags)."));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Updates your current status, i.e. it checks for new memos,\n"
- "sets needed channel modes and updates your vhost and\n"
- "your userflags (lastseentime, etc)."));
- return true;
- }
-};
-
-class NSUpdate : public Module
-{
- CommandNSUpdate commandnsupdate;
-
- public:
- NSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandnsupdate(this)
- {
-
- }
-};
-
-MODULE_INIT(NSUpdate)
diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp
deleted file mode 100644
index 08bbc79ac..000000000
--- a/modules/commands/os_akill.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline");
-
-class AkillDelCallback : public NumberList
-{
- CommandSource &source;
- unsigned deleted;
- Command *cmd;
- public:
- AkillDelCallback(CommandSource &_source, const Anope::string &numlist, Command *c) : NumberList(numlist, true), source(_source), deleted(0), cmd(c)
- {
- }
-
- ~AkillDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on the AKILL list."));
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from the AKILL list."));
- else
- source.Reply(_("Deleted %d entries from the AKILL list."), deleted);
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- XLine *x = akills->GetEntry(number - 1);
-
- if (!x)
- return;
-
- Log(LOG_ADMIN, source, cmd) << "to remove " << x->mask << " from the list";
-
- ++deleted;
- DoDel(source, x);
- }
-
- static void DoDel(CommandSource &source, XLine *x)
- {
- akills->DelXLine(x);
- }
-};
-
-class CommandOSAKill : public Command
-{
- private:
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string expiry, mask;
-
- if (params.size() < 2)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- spacesepstream sep(params[1]);
- sep.GetToken(mask);
-
- if (mask[0] == '+')
- {
- expiry = mask;
- sep.GetToken(mask);
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (sep.StreamEnd())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string reason;
- if (mask.find('#') != Anope::string::npos)
- {
- Anope::string remaining = sep.GetRemaining();
-
- size_t co = remaining[0] == ':' ? 0 : remaining.rfind(" :");
- if (co == Anope::string::npos)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (co != 0)
- ++co;
-
- reason = remaining.substr(co + 1);
- mask += " " + remaining.substr(0, co);
- mask.trim();
- }
- else
- reason = sep.GetRemaining();
-
- if (mask[0] == '/' && mask[mask.length() - 1] == '/')
- {
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
-
- if (regexengine.empty())
- {
- source.Reply(_("Regex is disabled."));
- return;
- }
-
- ServiceReference<RegexProvider> provider("Regex", regexengine);
- if (!provider)
- {
- source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
- return;
- }
-
- try
- {
- Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- delete provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- source.Reply("%s", ex.GetReason().c_str());
- return;
- }
- }
-
- User *targ = User::Find(mask, true);
- if (targ)
- mask = "*@" + targ->host;
-
- if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
- reason = "[" + source.GetNick() + "] " + reason;
-
- if (mask.find_first_not_of("/~@.*?") == Anope::string::npos)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- return;
- }
- else if (mask.find('@') == Anope::string::npos)
- {
- source.Reply(BAD_USERHOST_MASK);
- return;
- }
-
- XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- x->id = XLineManager::GenerateUID();
-
- unsigned int affected = 0;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (akills->Check(it->second, x))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- Log(LOG_ADMIN, source, this) << "tried to akill " << percent << "% of the network (" << affected << " users)";
- delete x;
- return;
- }
-
- if (!akills->CanAdd(source, mask, expires, reason))
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, akills));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return;
- }
-
- akills->AddXLine(x);
- if (Config->GetModule("operserv")->Get<bool>("akillonadd"))
- akills->Send(NULL, x);
-
- source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str());
-
- Log(LOG_ADMIN, source, this) << "on " << mask << " (" << x->reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (akills->GetList().empty())
- {
- source.Reply(_("AKILL list is empty."));
- return;
- }
-
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- AkillDelCallback list(source, mask, this);
- list.Process();
- }
- else
- {
- XLine *x = akills->HasEntry(mask);
-
- if (!x)
- {
- source.Reply(_("\002%s\002 not found on the AKILL list."), mask.c_str());
- return;
- }
-
- do
- {
- FOREACH_MOD(OnDelXLine, (source, x, akills));
-
- Log(LOG_ADMIN, source, this) << "to remove " << x->mask << " from the list";
- source.Reply(_("\002%s\002 deleted from the AKILL list."), x->mask.c_str());
- AkillDelCallback::DoDel(source, x);
- }
- while ((x = akills->HasEntry(mask)));
-
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
-
- void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class ListCallback : public NumberList
- {
- CommandSource &source;
- ListFormatter &list;
- public:
- ListCallback(CommandSource &_source, ListFormatter &_list, const Anope::string &numstr) : NumberList(numstr, false), source(_source), list(_list)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- const XLine *x = akills->GetEntry(number - 1);
-
- if (!x)
- return;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- entry["Mask"] = x->mask;
- entry["Creator"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- this->list.AddEntry(entry);
- }
- }
- nl_list(source, list, mask);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = akills->GetCount(); i < end; ++i)
- {
- const XLine *x = akills->GetEntry(i);
-
- if (mask.empty() || mask.equals_ci(x->mask) || mask == x->id || Anope::Match(x->mask, mask, false, true))
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = x->mask;
- entry["Creator"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- list.AddEntry(entry);
- }
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on the AKILL list."));
- else
- {
- source.Reply(_("Current AKILL list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of AKILL list."));
- }
- }
-
- void DoList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (akills->GetList().empty())
- {
- source.Reply(_("AKILL list is empty."));
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void DoView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (akills->GetList().empty())
- {
- source.Reply(_("AKILL list is empty."));
- return;
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Expires"));
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- list.AddColumn(_("ID"));
- list.AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void DoClear(CommandSource &source)
- {
-
- for (unsigned i = akills->GetCount(); i > 0; --i)
- {
- XLine *x = akills->GetEntry(i - 1);
- FOREACH_MOD(OnDelXLine, (source, x, akills));
- akills->DelXLine(x);
- }
-
- Log(LOG_ADMIN, source, this) << "to CLEAR the list";
- source.Reply(_("The AKILL list has been cleared."));
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- public:
- CommandOSAKill(Module *creator) : Command(creator, "operserv/akill", 1, 2)
- {
- this->SetDesc(_("Manipulate the AKILL list"));
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax("CLEAR");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (!akills)
- return;
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->DoView(source, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the AKILL list. If\n"
- "a user matching an AKILL mask attempts to connect, Services\n"
- "will issue a KILL for that user and, on supported server\n"
- "types, will instruct all servers to add a ban for the mask\n"
- "which the user matched.\n"
- " \n"
- "\002AKILL ADD\002 adds the given mask to the AKILL\n"
- "list for the given reason, which \002must\002 be given.\n"
- "Mask should be in the format of nick!user@host#real name,\n"
- "though all that is required is user@host. If a real name is specified,\n"
- "the reason must be prepended with a :.\n"
- "\037expiry\037 is specified as an integer followed by one of \037d\037\n"
- "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n"
- "\0371h30m\037) are not permitted. If a unit specifier is not\n"
- "included, the default is days (so \037+30\037 by itself means 30\n"
- "days). To add an AKILL which does not expire, use \037+0\037. If the\n"
- "usermask to be added starts with a \037+\037, an expiry time must\n"
- "be given, even if it is the same as the default. The\n"
- "current AKILL default expiry time can be found with the\n"
- "\002STATS AKILL\002 command."));
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), regexengine.c_str());
- }
- source.Reply(_(
- " \n"
- "The \002AKILL DEL\002 command removes the given mask from the\n"
- "AKILL list if it is present. If a list of entry numbers is\n"
- "given, those entries are deleted. (See the example for LIST\n"
- "below.)\n"
- " \n"
- "The \002AKILL LIST\002 command displays the AKILL list.\n"
- "If a wildcard mask is given, only those entries matching the\n"
- "mask are displayed. If a list of entry numbers is given,\n"
- "only those entries are shown; for example:\n"
- " \002AKILL LIST 2-5,7-9\002\n"
- " Lists AKILL entries numbered 2 through 5 and 7\n"
- " through 9.\n"
- " \n"
- "\002AKILL VIEW\002 is a more verbose version of \002AKILL LIST\002, and\n"
- "will show who added an AKILL, the date it was added, and when\n"
- "it expires, as well as the user@host/ip mask and reason.\n"
- " \n"
- "\002AKILL CLEAR\002 clears all entries of the AKILL list."));
- return true;
- }
-};
-
-class OSAKill : public Module
-{
- CommandOSAKill commandosakill;
-
- public:
- OSAKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosakill(this)
- {
-
- }
-};
-
-MODULE_INIT(OSAKill)
diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp
deleted file mode 100644
index 56b5f6b33..000000000
--- a/modules/commands/os_chankill.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline");
-
-class CommandOSChanKill : public Command
-{
- public:
- CommandOSChanKill(Module *creator) : Command(creator, "operserv/chankill", 2, 3)
- {
- this->SetDesc(_("AKILL all users on a specific channel"));
- this->SetSyntax(_("[+\037expiry\037] \037channel\037 \037reason\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!akills)
- return;
-
- Anope::string expiry, channel;
- unsigned last_param = 1;
- Channel *c;
-
- channel = params[0];
- if (!channel.empty() && channel[0] == '+')
- {
- expiry = channel;
- channel = params[1];
- last_param = 2;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- Anope::string reason = params[last_param];
- if (params.size() > last_param + 1)
- reason += params[last_param + 1];
- if (!reason.empty())
- {
- Anope::string realreason;
- if (Config->GetModule("operserv")->Get<bool>("addakiller") && !source.GetNick().empty())
- realreason = "[" + source.GetNick() + "] " + reason;
- else
- realreason = reason;
-
- if ((c = Channel::Find(channel)))
- {
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
-
- if (uc->user->server == Me || uc->user->HasMode("OPER"))
- continue;
-
- Anope::string akillmask = "*@" + uc->user->host;
- if (akills->HasEntry(akillmask))
- continue;
-
- XLine *x = new XLine(akillmask, source.GetNick(), expires, realreason, XLineManager::GenerateUID());
- akills->AddXLine(x);
- akills->OnMatch(uc->user, x);
- }
-
- Log(LOG_ADMIN, source, this) << "on " << c->name << " (" << realreason << ")";
- }
- else
- source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Puts an AKILL for every nick on the specified channel. It\n"
- "uses the entire real ident@host for every nick, and\n"
- "then enforces the AKILL."));
- return true;
- }
-};
-
-class OSChanKill : public Module
-{
- CommandOSChanKill commandoschankill;
-
- public:
- OSChanKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoschankill(this)
- {
-
- }
-};
-
-MODULE_INIT(OSChanKill)
diff --git a/modules/commands/os_config.cpp b/modules/commands/os_config.cpp
deleted file mode 100644
index a2e4f3272..000000000
--- a/modules/commands/os_config.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSConfig : public Command
-{
- public:
- CommandOSConfig(Module *creator) : Command(creator, "operserv/config", 1, 4)
- {
- this->SetDesc(_("View and change configuration file settings"));
- this->SetSyntax(_("{\037MODIFY\037|\037VIEW\037} [\037block name\037 \037item name\037 \037item value\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &what = params[0];
-
- if (what.equals_ci("MODIFY") && params.size() > 3)
- {
- if (!source.HasPriv("operserv/config"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Configuration::Block *block = Config->GetBlock(params[1]);
- if (!block)
- block = Config->GetModule(params[1]);
-
- if (!block)
- {
- source.Reply(_("There is no such configuration block %s."), params[1].c_str());
- return;
- }
-
- block->Set(params[2], params[3]);
-
- Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3];
- source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str());
- }
- else if (what.equals_ci("VIEW"))
- {
- /* Blocks we should show */
- const Anope::string show_blocks[] = { "serverinfo", "networkinfo", "options", "" };
-
- Log(LOG_ADMIN, source, this) << "VIEW";
-
- for (unsigned i = 0; !show_blocks[i].empty(); ++i)
- {
- Configuration::Block *block = Config->GetBlock(show_blocks[i]);
- const Configuration::Block::item_map *items = block->GetItems();
-
- if (!items)
- continue;
-
- ListFormatter lflist(source.GetAccount());
- lflist.AddColumn(_("Name")).AddColumn(_("Value"));
-
- for (Configuration::Block::item_map::const_iterator it = items->begin(), it_end = items->end(); it != it_end; ++it)
- {
- ListFormatter::ListEntry entry;
- entry["Name"] = it->first;
- entry["Value"] = it->second;
- lflist.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- lflist.Process(replies);
-
- source.Reply(_("%s settings:"), block->GetName().c_str());
-
- for (unsigned j = 0; j < replies.size(); ++j)
- source.Reply(replies[j]);
-
- source.Reply(" ");
- }
-
- ListFormatter lflist(source.GetAccount());
- lflist.AddColumn(_("Module Name")).AddColumn(_("Name")).AddColumn(_("Value"));
-
- for (int i = 0; i < Config->CountBlock("module"); ++i)
- {
- Configuration::Block *block = Config->GetBlock("module", i);
- const Configuration::Block::item_map *items = block->GetItems();
-
- if (!items || items->size() <= 1)
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Module Name"] = block->Get<Anope::string>("name");
-
- for (Configuration::Block::item_map::const_iterator it = items->begin(), it_end = items->end(); it != it_end; ++it)
- {
- entry["Name"] = it->first;
- entry["Value"] = it->second;
- lflist.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- lflist.Process(replies);
-
- source.Reply(_("Module settings:"));
-
- for (unsigned j = 0; j < replies.size(); ++j)
- source.Reply(replies[j]);
-
- source.Reply(_("End of configuration."));
- }
- else
- this->OnSyntaxError(source, what);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to change and view configuration settings.\n"
- "Settings changed by this command are temporary and will not be reflected\n"
- "back into the configuration file, and will be lost if Anope is shut down,\n"
- "restarted, or the configuration is reloaded.\n"
- " \n"
- "Example:\n"
- " \002MODIFY nickserv forcemail no\002"));
- return true;
- }
-};
-
-class OSConfig : public Module
-{
- CommandOSConfig commandosconfig;
-
- public:
- OSConfig(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosconfig(this)
- {
-
- }
-};
-
-MODULE_INIT(OSConfig)
diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp
deleted file mode 100644
index fbccf2aae..000000000
--- a/modules/commands/os_defcon.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 "modules/os_session.h"
-
-enum DefconLevel
-{
- DEFCON_NO_NEW_CHANNELS,
- DEFCON_NO_NEW_NICKS,
- DEFCON_NO_MLOCK_CHANGE,
- DEFCON_FORCE_CHAN_MODES,
- DEFCON_REDUCE_SESSION,
- DEFCON_NO_NEW_CLIENTS,
- DEFCON_OPER_ONLY,
- DEFCON_SILENT_OPER_ONLY,
- DEFCON_AKILL_NEW_CLIENTS,
- DEFCON_NO_NEW_MEMOS
-};
-
-bool DefConModesSet = false;
-
-struct DefconConfig
-{
- std::vector<std::bitset<32> > DefCon;
- std::set<Anope::string> DefConModesOn, DefConModesOff;
- std::map<Anope::string, Anope::string> DefConModesOnParams;
-
- int defaultlevel, sessionlimit;
- Anope::string chanmodes, message, offmessage, akillreason;
- std::vector<Anope::string> defcons;
- time_t akillexpire, timeout;
- bool globalondefcon;
-
- unsigned max_session_kill;
- time_t session_autokill_expiry;
- Anope::string sle_reason, sle_detailsloc;
-
- DefconConfig()
- {
- this->DefCon.resize(6);
- this->defcons.resize(5);
- }
-
- bool Check(DefconLevel level)
- {
- return this->Check(this->defaultlevel, level);
- }
-
- bool Check(int dlevel, DefconLevel level)
- {
- return this->DefCon[dlevel].test(level);
- }
-
- void Add(int dlevel, DefconLevel level)
- {
- this->DefCon[dlevel][level] = true;
- }
-
- void Del(int dlevel, DefconLevel level)
- {
- this->DefCon[dlevel][level] = false;
- }
-
- bool SetDefConParam(const Anope::string &name, const Anope::string &buf)
- {
- return DefConModesOnParams.insert(std::make_pair(name, buf)).second;
- }
-
- void UnsetDefConParam(const Anope::string &name)
- {
- DefConModesOnParams.erase(name);
- }
-
- bool GetDefConParam(const Anope::string &name, Anope::string &buf)
- {
- std::map<Anope::string, Anope::string>::iterator it = DefConModesOnParams.find(name);
-
- buf.clear();
-
- if (it != DefConModesOnParams.end())
- {
- buf = it->second;
- return true;
- }
-
- return false;
- }
-};
-
-static DefconConfig DConfig;
-
-static void runDefCon();
-static Anope::string defconReverseModes(const Anope::string &modes);
-
-static ServiceReference<GlobalService> GlobalService("GlobalService", "Global");
-
-static Timer *timeout;
-
-class DefConTimeout : public Timer
-{
- int level;
-
- public:
- DefConTimeout(Module *mod, int newlevel) : Timer(mod, DConfig.timeout), level(newlevel)
- {
- timeout = this;
- }
-
- ~DefConTimeout()
- {
- timeout = NULL;
- }
-
- void Tick(time_t) anope_override
- {
- if (DConfig.defaultlevel != level)
- {
- DConfig.defaultlevel = level;
- FOREACH_MOD(OnDefconLevel, (level));
- Log(Config->GetClient("OperServ"), "operserv/defcon") << "Defcon level timeout, returning to level " << level;
-
- if (DConfig.globalondefcon)
- {
- if (!DConfig.offmessage.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.offmessage);
- else
- GlobalService->SendGlobal(NULL, "", Anope::printf(Language::Translate(_("The Defcon level is now at: \002%d\002")), DConfig.defaultlevel));
-
- if (!DConfig.message.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.message);
- }
-
- runDefCon();
- }
- }
-};
-
-class CommandOSDefcon : public Command
-{
- void SendLevels(CommandSource &source)
- {
- if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
- source.Reply(_("* No new channel registrations"));
- if (DConfig.Check(DEFCON_NO_NEW_NICKS))
- source.Reply(_("* No new nick registrations"));
- if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
- source.Reply(_("* No mode lock changes"));
- if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && !DConfig.chanmodes.empty())
- source.Reply(_("* Force channel modes (%s) to be set on all channels"), DConfig.chanmodes.c_str());
- if (DConfig.Check(DEFCON_REDUCE_SESSION))
- source.Reply(_("* Use the reduced session limit of %d"), DConfig.sessionlimit);
- if (DConfig.Check(DEFCON_NO_NEW_CLIENTS))
- source.Reply(_("* Kill any new clients connecting"));
- if (DConfig.Check(DEFCON_OPER_ONLY))
- source.Reply(_("* Ignore non-opers with a message"));
- if (DConfig.Check(DEFCON_SILENT_OPER_ONLY))
- source.Reply(_("* Silently ignore non-opers"));
- if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
- source.Reply(_("* AKILL any new clients connecting"));
- if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
- source.Reply(_("* No new memos sent"));
- }
-
- public:
- CommandOSDefcon(Module *creator) : Command(creator, "operserv/defcon", 1, 1)
- {
- this->SetDesc(_("Manipulate the DefCon system"));
- this->SetSyntax(_("[\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &lvl = params[0];
-
- if (lvl.empty())
- {
- source.Reply(_("Services are now at DEFCON \002%d\002."), DConfig.defaultlevel);
- this->SendLevels(source);
- return;
- }
-
- int newLevel = 0;
- try
- {
- newLevel = convertTo<int>(lvl);
- }
- catch (const ConvertException &) { }
-
- if (newLevel < 1 || newLevel > 5)
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- DConfig.defaultlevel = newLevel;
-
- FOREACH_MOD(OnDefconLevel, (newLevel));
-
- delete timeout;
-
- if (DConfig.timeout)
- timeout = new DefConTimeout(this->module, 5);
-
- source.Reply(_("Services are now at DEFCON \002%d\002."), DConfig.defaultlevel);
- this->SendLevels(source);
- Log(LOG_ADMIN, source, this) << "to change defcon level to " << newLevel;
-
- /* Global notice the user what is happening. Also any Message that
- the Admin would like to add. Set in config file. */
- if (DConfig.globalondefcon)
- {
- if (DConfig.defaultlevel == 5 && !DConfig.offmessage.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.offmessage);
- else if (DConfig.defaultlevel != 5)
- {
- GlobalService->SendGlobal(NULL, "", Anope::printf(_("The Defcon level is now at: \002%d\002"), DConfig.defaultlevel));
- if (!DConfig.message.empty())
- GlobalService->SendGlobal(NULL, "", DConfig.message);
- }
- }
-
- /* Run any defcon functions, e.g. FORCE CHAN MODE */
- runDefCon();
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("The defcon system can be used to implement a pre-defined\n"
- "set of restrictions to services useful during an attempted\n"
- "attack on the network."));
- return true;
- }
-};
-
-class OSDefcon : public Module
-{
- ServiceReference<SessionService> session_service;
- ServiceReference<XLineManager> akills;
- CommandOSDefcon commandosdefcon;
-
- void ParseModeString()
- {
- int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
- unsigned char mode;
- ChannelMode *cm;
- ChannelModeParam *cmp;
- Anope::string modes, param;
-
- spacesepstream ss(DConfig.chanmodes);
-
- DConfig.DefConModesOn.clear();
- DConfig.DefConModesOff.clear();
- ss.GetToken(modes);
-
- /* Loop while there are modes to set */
- for (unsigned i = 0, end = modes.length(); i < end; ++i)
- {
- mode = modes[i];
-
- switch (mode)
- {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- default:
- if (add < 0)
- continue;
- }
-
- if ((cm = ModeManager::FindChannelModeByChar(mode)))
- {
- if (cm->type == MODE_STATUS || cm->type == MODE_LIST)
- {
- Log(this) << "DefConChanModes mode character '" << mode << "' cannot be locked";
- continue;
- }
- else if (add)
- {
- DConfig.DefConModesOn.insert(cm->name);
- DConfig.DefConModesOff.erase(cm->name);
-
- if (cm->type == MODE_PARAM)
- {
- cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
-
- if (!ss.GetToken(param))
- {
- Log(this) << "DefConChanModes mode character '" << mode << "' has no parameter while one is expected";
- continue;
- }
-
- if (!cmp->IsValid(param))
- continue;
-
- DConfig.SetDefConParam(cmp->name, param);
- }
- }
- else if (DConfig.DefConModesOn.count(cm->name))
- {
- DConfig.DefConModesOn.erase(cm->name);
-
- if (cm->type == MODE_PARAM)
- DConfig.UnsetDefConParam(cm->name);
- }
- }
- }
-
- /* We can't mlock +L if +l is not mlocked as well. */
- if ((cm = ModeManager::FindChannelModeByName("REDIRECT")) && DConfig.DefConModesOn.count(cm->name) && !DConfig.DefConModesOn.count("LIMIT"))
- {
- DConfig.DefConModesOn.erase("REDIRECT");
-
- Log(this) << "DefConChanModes must lock mode +l as well to lock mode +L";
- }
- }
-
- public:
- OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), session_service("SessionService", "session"), akills("XLineManager", "xlinemanager/sgline"), commandosdefcon(this)
- {
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- DefconConfig dconfig;
-
- dconfig.defaultlevel = block->Get<int>("defaultlevel");
- dconfig.defcons[4] = block->Get<const Anope::string>("level4");
- dconfig.defcons[3] = block->Get<const Anope::string>("level3");
- dconfig.defcons[2] = block->Get<const Anope::string>("level2");
- dconfig.defcons[1] = block->Get<const Anope::string>("level1");
- dconfig.sessionlimit = block->Get<int>("sessionlimit");
- dconfig.akillreason = block->Get<const Anope::string>("akillreason");
- dconfig.akillexpire = block->Get<time_t>("akillexpire");
- dconfig.chanmodes = block->Get<const Anope::string>("chanmodes");
- dconfig.timeout = block->Get<time_t>("timeout");
- dconfig.globalondefcon = block->Get<bool>("globalondefcon");
- dconfig.message = block->Get<const Anope::string>("message");
- dconfig.offmessage = block->Get<const Anope::string>("offmessage");
-
- block = conf->GetModule("os_session");
-
- dconfig.max_session_kill = block->Get<int>("maxsessionkill");
- dconfig.session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
- dconfig.sle_reason = block->Get<const Anope::string>("sessionlimitexceeded");
- dconfig.sle_detailsloc = block->Get<const Anope::string>("sessionlimitdetailsloc");
-
- if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5)
- throw ConfigException("The value for <defcon:defaultlevel> must be between 1 and 5");
- else if (dconfig.akillexpire <= 0)
- throw ConfigException("The value for <defcon:akillexpire> must be greater than zero!");
-
- for (unsigned level = 1; level < 5; ++level)
- {
- spacesepstream operations(dconfig.defcons[level]);
- Anope::string operation;
- while (operations.GetToken(operation))
- {
- if (operation.equals_ci("nonewchannels"))
- dconfig.Add(level, DEFCON_NO_NEW_CHANNELS);
- else if (operation.equals_ci("nonewnicks"))
- dconfig.Add(level, DEFCON_NO_NEW_NICKS);
- else if (operation.equals_ci("nomlockchanges"))
- dconfig.Add(level, DEFCON_NO_MLOCK_CHANGE);
- else if (operation.equals_ci("forcechanmodes"))
- dconfig.Add(level, DEFCON_FORCE_CHAN_MODES);
- else if (operation.equals_ci("reducedsessions"))
- dconfig.Add(level, DEFCON_REDUCE_SESSION);
- else if (operation.equals_ci("nonewclients"))
- dconfig.Add(level, DEFCON_NO_NEW_CLIENTS);
- else if (operation.equals_ci("operonly"))
- dconfig.Add(level, DEFCON_OPER_ONLY);
- else if (operation.equals_ci("silentoperonly"))
- dconfig.Add(level, DEFCON_SILENT_OPER_ONLY);
- else if (operation.equals_ci("akillnewclients"))
- dconfig.Add(level, DEFCON_AKILL_NEW_CLIENTS);
- else if (operation.equals_ci("nonewmemos"))
- dconfig.Add(level, DEFCON_NO_NEW_MEMOS);
- }
-
- if (dconfig.Check(level, DEFCON_REDUCE_SESSION) && dconfig.sessionlimit <= 0)
- throw ConfigException("The value for <defcon:sessionlimit> must be greater than zero!");
- else if (dconfig.Check(level, DEFCON_AKILL_NEW_CLIENTS) && dconfig.akillreason.empty())
- throw ConfigException("The value for <defcon:akillreason> must not be empty!");
- else if (dconfig.Check(level, DEFCON_FORCE_CHAN_MODES) && dconfig.chanmodes.empty())
- throw ConfigException("The value for <defcon:chanmodes> must not be empty!");
- }
-
- DConfig = dconfig;
- this->ParseModeString();
- }
-
- EventReturn OnChannelModeSet(Channel *c, MessageSource &source, ChannelMode *mode, const Anope::string &param) anope_override
- {
- if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && DConfig.DefConModesOff.count(mode->name) && source.GetUser() && !source.GetBot())
- {
- c->RemoveMode(Config->GetClient("OperServ"), mode, param);
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &source, ChannelMode *mode, const Anope::string &) anope_override
- {
- if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && DConfig.DefConModesOn.count(mode->name) && source.GetUser() && !source.GetBot())
- {
- Anope::string param;
-
- if (DConfig.GetDefConParam(mode->name, param))
- c->SetMode(Config->GetClient("OperServ"), mode, param);
- else
- c->SetMode(Config->GetClient("OperServ"), mode);
-
- return EVENT_STOP;
-
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- if (DConfig.Check(DEFCON_OPER_ONLY) && !source.IsOper())
- {
- source.Reply(_("Services are in DefCon mode, please try again later."));
- return EVENT_STOP;
- }
- else if (DConfig.Check(DEFCON_SILENT_OPER_ONLY) && !source.IsOper())
- {
- return EVENT_STOP;
- }
- else if (command->name == "nickserv/register" || command->name == "nickserv/group")
- {
- if (DConfig.Check(DEFCON_NO_NEW_NICKS))
- {
- source.Reply(_("Services are in DefCon mode, please try again later."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "chanserv/mode" && params.size() > 1 && params[1].equals_ci("LOCK"))
- {
- if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
- {
- source.Reply(_("Services are in DefCon mode, please try again later."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "chanserv/register")
- {
- if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
- {
- source.Reply(_("Services are in DefCon mode, please try again later."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "memoserv/send")
- {
- if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
- {
- source.Reply(_("Services are in DefCon mode, please try again later."));
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (exempt || u->Quitting() || !u->server->IsSynced() || u->server->IsULined())
- return;
-
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills)
- {
- Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
- XLine x("*@" + u->host, OperServ ? OperServ->nick : "defcon", Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID());
- akills->Send(NULL, &x);
- }
-
- if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
- {
- u->Kill(OperServ, DConfig.akillreason);
- return;
- }
-
- if (DConfig.sessionlimit <= 0 || !session_service)
- return;
-
- Session *session = session_service->FindSession(u->ip.addr());
- Exception *exception = session_service->FindException(u);
-
- if (DConfig.Check(DEFCON_REDUCE_SESSION) && !exception)
- {
- if (session && session->count > static_cast<unsigned>(DConfig.sessionlimit))
- {
- if (!DConfig.sle_reason.empty())
- {
- Anope::string message = DConfig.sle_reason.replace_all_cs("%IP%", u->ip.addr());
- u->SendMessage(OperServ, message);
- }
- if (!DConfig.sle_detailsloc.empty())
- u->SendMessage(OperServ, DConfig.sle_detailsloc);
-
- ++session->hits;
- if (akills && DConfig.max_session_kill && session->hits >= DConfig.max_session_kill)
- {
- XLine x("*@" + session->addr.mask(), OperServ ? OperServ->nick : "", Anope::CurTime + DConfig.session_autokill_expiry, "Defcon session limit exceeded", XLineManager::GenerateUID());
- akills->Send(NULL, &x);
- Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \002*@" << session->addr.mask() << "\002 due to excessive connections";
- }
- else
- {
- u->Kill(OperServ, "Defcon session limit exceeded");
- }
- }
- }
- }
-
- void OnChannelModeAdd(ChannelMode *cm) anope_override
- {
- if (DConfig.chanmodes.find(cm->mchar) != Anope::string::npos)
- this->ParseModeString();
- }
-
- void OnChannelSync(Channel *c) anope_override
- {
- if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
- c->SetModes(Config->GetClient("OperServ"), false, "%s", DConfig.chanmodes.c_str());
- }
-};
-
-static void runDefCon()
-{
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
- {
- if (!DConfig.chanmodes.empty() && !DefConModesSet)
- {
- if (DConfig.chanmodes[0] == '+' || DConfig.chanmodes[0] == '-')
- {
- Log(OperServ, "operserv/defcon") << "DEFCON: setting " << DConfig.chanmodes << " on all channels";
- DefConModesSet = true;
- for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
- it->second->SetModes(OperServ, false, "%s", DConfig.chanmodes.c_str());
- }
- }
- }
- else
- {
- if (!DConfig.chanmodes.empty() && DefConModesSet)
- {
- if (DConfig.chanmodes[0] == '+' || DConfig.chanmodes[0] == '-')
- {
- DefConModesSet = false;
- Anope::string newmodes = defconReverseModes(DConfig.chanmodes);
- if (!newmodes.empty())
- {
- Log(OperServ, "operserv/defcon") << "DEFCON: setting " << newmodes << " on all channels";
- for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
- it->second->SetModes(OperServ, true, "%s", newmodes.c_str());
- }
- }
- }
- }
-}
-
-static Anope::string defconReverseModes(const Anope::string &modes)
-{
- if (modes.empty())
- return "";
- Anope::string newmodes;
- for (unsigned i = 0, end = modes.length(); i < end; ++i)
- {
- if (modes[i] == '+')
- newmodes += '-';
- else if (modes[i] == '-')
- newmodes += '+';
- else
- newmodes += modes[i];
- }
- return newmodes;
-}
-
-MODULE_INIT(OSDefcon)
diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp
deleted file mode 100644
index 687f44f4a..000000000
--- a/modules/commands/os_dns.cpp
+++ /dev/null
@@ -1,949 +0,0 @@
-/*
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-#include "modules/dns.h"
-
-static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager");
-
-struct DNSZone;
-class DNSServer;
-
-static Serialize::Checker<std::vector<DNSZone *> > zones("DNSZone");
-static Serialize::Checker<std::vector<DNSServer *> > dns_servers("DNSServer");
-
-static std::map<Anope::string, std::list<time_t> > server_quit_times;
-
-struct DNSZone : Serializable
-{
- Anope::string name;
- std::set<Anope::string, ci::less> servers;
-
- DNSZone(const Anope::string &n) : Serializable("DNSZone"), name(n)
- {
- zones->push_back(this);
- }
-
- ~DNSZone()
- {
- std::vector<DNSZone *>::iterator it = std::find(zones->begin(), zones->end(), this);
- if (it != zones->end())
- zones->erase(it);
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["name"] << name;
- unsigned count = 0;
- for (std::set<Anope::string, ci::less>::iterator it = servers.begin(), it_end = servers.end(); it != it_end; ++it)
- data["server" + stringify(count++)] << *it;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- DNSZone *zone;
- Anope::string zone_name;
-
- data["name"] >> zone_name;
-
- if (obj)
- {
- zone = anope_dynamic_static_cast<DNSZone *>(obj);
- data["name"] >> zone->name;
- }
- else
- zone = new DNSZone(zone_name);
-
- zone->servers.clear();
- for (unsigned count = 0; true; ++count)
- {
- Anope::string server_str;
- data["server" + stringify(count)] >> server_str;
- if (server_str.empty())
- break;
- zone->servers.insert(server_str);
- }
-
- return zone;
- }
-
- static DNSZone *Find(const Anope::string &name)
- {
- for (unsigned i = 0; i < zones->size(); ++i)
- if (zones->at(i)->name.equals_ci(name))
- {
- DNSZone *z = zones->at(i);
- z->QueueUpdate();
- return z;
- }
- return NULL;
- }
-};
-
-class DNSServer : public Serializable
-{
- Anope::string server_name;
- std::vector<Anope::string> ips;
- unsigned limit;
- /* wants to be in the pool */
- bool pooled;
- /* is actually in the pool */
- bool active;
-
- public:
- std::set<Anope::string, ci::less> zones;
- time_t repool;
-
- DNSServer(const Anope::string &sn) : Serializable("DNSServer"), server_name(sn), limit(0), pooled(false), active(false), repool(0)
- {
- dns_servers->push_back(this);
- }
-
- ~DNSServer()
- {
- std::vector<DNSServer *>::iterator it = std::find(dns_servers->begin(), dns_servers->end(), this);
- if (it != dns_servers->end())
- dns_servers->erase(it);
- }
-
- const Anope::string &GetName() const { return server_name; }
- std::vector<Anope::string> &GetIPs() { return ips; }
- unsigned GetLimit() const { return limit; }
- void SetLimit(unsigned l) { limit = l; }
-
- bool Pooled() const { return pooled; }
- void Pool(bool p)
- {
- if (!p)
- this->SetActive(p);
- pooled = p;
- }
-
- bool Active() const { return pooled && active; }
- void SetActive(bool p)
- {
- if (p)
- this->Pool(p);
- active = p;
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it)
- dnsmanager->Notify(*it);
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["server_name"] << server_name;
- for (unsigned i = 0; i < ips.size(); ++i)
- data["ip" + stringify(i)] << ips[i];
- data["limit"] << limit;
- data["pooled"] << pooled;
- unsigned count = 0;
- for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it)
- data["zone" + stringify(count++)] << *it;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- DNSServer *req;
- Anope::string server_name;
-
- data["server_name"] >> server_name;
-
- if (obj)
- {
- req = anope_dynamic_static_cast<DNSServer *>(obj);
- req->server_name = server_name;
- }
- else
- req = new DNSServer(server_name);
-
- for (unsigned i = 0; true; ++i)
- {
- Anope::string ip_str;
- data["ip" + stringify(i)] >> ip_str;
- if (ip_str.empty())
- break;
- req->ips.push_back(ip_str);
- }
-
- data["limit"] >> req->limit;
- data["pooled"] >> req->pooled;
-
- req->zones.clear();
- for (unsigned i = 0; true; ++i)
- {
- Anope::string zone_str;
- data["zone" + stringify(i)] >> zone_str;
- if (zone_str.empty())
- break;
- req->zones.insert(zone_str);
- }
-
- return req;
- }
-
- static DNSServer *Find(const Anope::string &s)
- {
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- if (dns_servers->at(i)->GetName().equals_ci(s))
- {
- DNSServer *serv = dns_servers->at(i);
- serv->QueueUpdate();
- return serv;
- }
- return NULL;
- }
-};
-
-class CommandOSDNS : public Command
-{
- void DisplayPoolState(CommandSource &source)
- {
- if (dns_servers->empty())
- {
- source.Reply(_("There are no configured servers."));
- return;
- }
-
- ListFormatter lf(source.GetAccount());
- lf.AddColumn(_("Server")).AddColumn(_("IP")).AddColumn(_("Limit")).AddColumn(_("State"));
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- {
- DNSServer *s = dns_servers->at(i);
- Server *srv = Server::Find(s->GetName(), true);
-
- ListFormatter::ListEntry entry;
- entry["Server"] = s->GetName();
- entry["Limit"] = s->GetLimit() ? stringify(s->GetLimit()) : Language::Translate(source.GetAccount(), _("None"));
-
- Anope::string ip_str;
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- ip_str += s->GetIPs()[j] + " ";
- ip_str.trim();
- if (ip_str.empty())
- ip_str = "None";
- entry["IP"] = ip_str;
-
- if (s->Active())
- entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Active"));
- else if (s->Pooled())
- entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Not Active"));
- else
- entry["State"] = Language::Translate(source.GetAccount(), _("Unpooled"));
-
- if (!srv)
- entry["State"] += Anope::string(" ") + Language::Translate(source.GetAccount(), _("(Split)"));
-
- lf.AddEntry(entry);
- }
-
- std::vector<Anope::string> replies;
- lf.Process(replies);
-
- if (!zones->empty())
- {
- ListFormatter lf2(source.GetAccount());
- lf2.AddColumn(_("Zone")).AddColumn(_("Servers"));
-
- for (unsigned i = 0; i < zones->size(); ++i)
- {
- const DNSZone *z = zones->at(i);
-
- ListFormatter::ListEntry entry;
- entry["Zone"] = z->name;
-
- Anope::string server_str;
- for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it)
- server_str += *it + " ";
- server_str.trim();
-
- if (server_str.empty())
- server_str = "None";
-
- entry["Servers"] = server_str;
-
- lf2.AddEntry(entry);
- }
-
- lf2.Process(replies);
- }
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- void AddZone(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &zone = params[1];
-
- if (DNSZone::Find(zone))
- {
- source.Reply(_("Zone %s already exists."), zone.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add zone " << zone;
-
- new DNSZone(zone);
- source.Reply(_("Added zone %s."), zone.c_str());
- }
-
- void DelZone(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &zone = params[1];
-
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to delete zone " << z->name;
-
- for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it)
- {
- DNSServer *s = DNSServer::Find(*it);
- if (s)
- s->zones.erase(z->name);
- }
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(z->name);
- }
-
- source.Reply(_("Zone %s removed."), z->name.c_str());
- delete z;
- }
-
- void AddServer(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
- const Anope::string &zone = params.size() > 2 ? params[2] : "";
-
- if (s)
- {
- if (zone.empty())
- {
- source.Reply(_("Server %s already exists."), s->GetName().c_str());
- }
- else
- {
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- return;
- }
- else if (z->servers.count(s->GetName()))
- {
- source.Reply(_("Server %s is already in zone %s."), s->GetName().c_str(), z->name.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- z->servers.insert(s->GetName());
- s->zones.insert(zone);
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(zone);
- }
-
- Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << z->name;
-
- source.Reply(_("Server %s added to zone %s."), s->GetName().c_str(), z->name.c_str());
- }
-
- return;
- }
-
- Server *serv = Server::Find(params[1], true);
- if (!serv || serv == Me || serv->IsJuped())
- {
- source.Reply(_("Server %s is not linked to the network."), params[1].c_str());
- return;
- }
-
- s = new DNSServer(params[1]);
- if (zone.empty())
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add server " << s->GetName();
- source.Reply(_("Added server %s."), s->GetName().c_str());
- }
- else
- {
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- delete s;
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << zone;
-
- z->servers.insert(s->GetName());
- s->zones.insert(z->name);
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(z->name);
- }
- }
- }
-
- void DelServer(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
- const Anope::string &zone = params.size() > 2 ? params[2] : "";
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
- else if (!zone.empty())
- {
- DNSZone *z = DNSZone::Find(zone);
- if (!z)
- {
- source.Reply(_("Zone %s does not exist."), zone.c_str());
- return;
- }
- else if (!z->servers.count(s->GetName()))
- {
- source.Reply(_("Server %s is not in zone %s."), s->GetName().c_str(), z->name.c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to remove server " << s->GetName() << " from zone " << z->name;
-
- if (dnsmanager)
- {
- dnsmanager->UpdateSerial();
- dnsmanager->Notify(z->name);
- }
-
- z->servers.erase(s->GetName());
- s->zones.erase(z->name);
- source.Reply(_("Removed server %s from zone %s."), s->GetName().c_str(), z->name.c_str());
- return;
- }
- else if (Server::Find(s->GetName(), true))
- {
- source.Reply(_("Server %s must be quit before it can be deleted."), s->GetName().c_str());
- return;
- }
-
- for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it)
- {
- DNSZone *z = DNSZone::Find(*it);
- if (z)
- z->servers.erase(s->GetName());
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- if (dnsmanager)
- dnsmanager->UpdateSerial();
-
- Log(LOG_ADMIN, source, this) << "to delete server " << s->GetName();
- source.Reply(_("Removed server %s."), s->GetName().c_str());
- delete s;
- }
-
- void AddIP(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
-
- for (unsigned i = 0; i < s->GetIPs().size(); ++i)
- if (params[2].equals_ci(s->GetIPs()[i]))
- {
- source.Reply(_("IP %s already exists for %s."), s->GetIPs()[i].c_str(), s->GetName().c_str());
- return;
- }
-
- sockaddrs addr(params[2]);
- if (!addr.valid())
- {
- source.Reply(_("%s is not a valid IP address."), params[2].c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- s->GetIPs().push_back(params[2]);
- source.Reply(_("Added IP %s to %s."), params[2].c_str(), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to add IP " << params[2] << " to " << s->GetName();
-
- if (s->Active() && dnsmanager)
- {
- dnsmanager->UpdateSerial();
- for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it)
- dnsmanager->Notify(*it);
- }
- }
-
- void DelIP(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- for (unsigned i = 0; i < s->GetIPs().size(); ++i)
- if (params[2].equals_ci(s->GetIPs()[i]))
- {
- s->GetIPs().erase(s->GetIPs().begin() + i);
- source.Reply(_("Removed IP %s from %s."), params[2].c_str(), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to remove IP " << params[2] << " from " << s->GetName();
-
- if (s->GetIPs().empty())
- {
- s->repool = 0;
- s->Pool(false);
- }
-
- if (s->Active() && dnsmanager)
- {
- dnsmanager->UpdateSerial();
- for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it)
- dnsmanager->Notify(*it);
- }
-
- return;
- }
-
- source.Reply(_("IP %s does not exist for %s."), params[2].c_str(), s->GetName().c_str());
- }
-
- void OnSet(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- if (params[2].equals_ci("LIMIT"))
- {
- try
- {
- unsigned l = convertTo<unsigned>(params[3]);
- s->SetLimit(l);
- if (l)
- source.Reply(_("User limit for %s set to %d."), s->GetName().c_str(), l);
- else
- source.Reply(_("User limit for %s removed."), s->GetName().c_str());
- }
- catch (const ConvertException &ex)
- {
- source.Reply(_("Invalid value for LIMIT. Must be numerical."));
- }
- }
- else
- source.Reply(_("Unknown SET option."));
- }
-
- void OnPool(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
- else if (!Server::Find(s->GetName(), true))
- {
- source.Reply(_("Server %s is not currently linked."), s->GetName().c_str());
- return;
- }
- else if (s->Pooled())
- {
- source.Reply(_("Server %s is already pooled."), s->GetName().c_str());
- return;
- }
- else if (s->GetIPs().empty())
- {
- source.Reply(_("Server %s has no configured IPs."), s->GetName().c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- s->SetActive(true);
-
- source.Reply(_("Pooled %s."), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to pool " << s->GetName();
- }
-
-
- void OnDepool(CommandSource &source, const std::vector<Anope::string> &params)
- {
- DNSServer *s = DNSServer::Find(params[1]);
-
- if (!s)
- {
- source.Reply(_("Server %s does not exist."), params[1].c_str());
- return;
- }
- else if (!s->Pooled())
- {
- source.Reply(_("Server %s is not pooled."), s->GetName().c_str());
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- s->Pool(false);
-
- source.Reply(_("Depooled %s."), s->GetName().c_str());
- Log(LOG_ADMIN, source, this) << "to depool " << s->GetName();
- }
-
- public:
- CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 4)
- {
- this->SetDesc(_("Manage DNS zones for this network"));
- this->SetSyntax(_("ADDZONE \037zone.name\037"));
- this->SetSyntax(_("DELZONE \037zone.name\037"));
- this->SetSyntax(_("ADDSERVER \037server.name\037 [\037zone.name\037]"));
- this->SetSyntax(_("DELSERVER \037server.name\037 [\037zone.name\037]"));
- this->SetSyntax(_("ADDIP \037server.name\037 \037ip\037"));
- this->SetSyntax(_("DELIP \037server.name\037 \037ip\037"));
- this->SetSyntax(_("SET \037server.name\037 \037option\037 \037value\037"));
- this->SetSyntax(_("POOL \037server.name\037"));
- this->SetSyntax(_("DEPOOL \037server.name\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.empty())
- this->DisplayPoolState(source);
- else if (params[0].equals_ci("ADDZONE") && params.size() > 1)
- this->AddZone(source, params);
- else if (params[0].equals_ci("DELZONE") && params.size() > 1)
- this->DelZone(source, params);
- else if (params[0].equals_ci("ADDSERVER") && params.size() > 1)
- this->AddServer(source, params);
- else if (params[0].equals_ci("DELSERVER") && params.size() > 1)
- this->DelServer(source, params);
- else if (params[0].equals_ci("ADDIP") && params.size() > 2)
- this->AddIP(source, params);
- else if (params[0].equals_ci("DELIP") && params.size() > 2)
- this->DelIP(source, params);
- else if (params[0].equals_ci("SET") && params.size() > 3)
- this->OnSet(source, params);
- else if (params[0].equals_ci("POOL") && params.size() > 1)
- this->OnPool(source, params);
- else if (params[0].equals_ci("DEPOOL") && params.size() > 1)
- this->OnDepool(source, params);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command allows managing DNS zones used for controlling what servers users\n"
- "are directed to when connecting. Omitting all parameters prints out the status of\n"
- "the DNS zone.\n"
- " \n"
- "\002ADDZONE\002 adds a zone, eg us.yournetwork.tld. Servers can then be added to this\n"
- "zone with the \002ADDSERVER\002 command.\n"
- " \n"
- "The \002ADDSERVER\002 command adds a server to the given zone. When a query is done, the\n"
- "zone in question is served if it exists, else all servers in all zones are served.\n"
- "A server may be in more than one zone.\n"
- " \n"
- "The \002ADDIP\002 command associates an IP with a server.\n"
- " \n"
- "The \002POOL\002 and \002DEPOOL\002 commands actually add and remove servers to their given zones."));
- return true;
- }
-};
-
-class ModuleDNS : public Module
-{
- Serialize::Type zone_type, dns_type;
- CommandOSDNS commandosdns;
-
- time_t ttl;
- int user_drop_mark;
- time_t user_drop_time;
- time_t user_drop_readd_time;
- bool remove_split_servers;
- bool readd_connected_servers;
-
- time_t last_warn;
-
- public:
- ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR),
- zone_type("DNSZone", DNSZone::Unserialize), dns_type("DNSServer", DNSServer::Unserialize), commandosdns(this),
- last_warn(0)
- {
-
-
- for (unsigned j = 0; j < dns_servers->size(); ++j)
- {
- DNSServer *s = dns_servers->at(j);
- if (s->Pooled() && Server::Find(s->GetName(), true))
- s->SetActive(true);
- }
- }
-
- ~ModuleDNS()
- {
- for (unsigned i = zones->size(); i > 0; --i)
- delete zones->at(i - 1);
- for (unsigned i = dns_servers->size(); i > 0; --i)
- delete dns_servers->at(i - 1);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = conf->GetModule(this);
- this->ttl = block->Get<time_t>("ttl");
- this->user_drop_mark = block->Get<int>("user_drop_mark");
- this->user_drop_time = block->Get<time_t>("user_drop_time");
- this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time");
- this->remove_split_servers = block->Get<bool>("remove_split_servers");
- this->readd_connected_servers = block->Get<bool>("readd_connected_servers");
- }
-
- void OnNewServer(Server *s) anope_override
- {
- if (s == Me || s->IsJuped())
- return;
- if (!Me->IsSynced() || this->readd_connected_servers)
- {
- DNSServer *dns = DNSServer::Find(s->GetName());
- if (dns && dns->Pooled() && !dns->Active() && !dns->GetIPs().empty())
- {
- dns->SetActive(true);
- Log(this) << "Pooling server " << s->GetName();
- }
- }
- }
-
- void OnServerQuit(Server *s) anope_override
- {
- DNSServer *dns = DNSServer::Find(s->GetName());
- if (remove_split_servers && dns && dns->Pooled() && dns->Active())
- {
- if (readd_connected_servers)
- dns->SetActive(false); // Will be reactivated when it comes back
- else
- dns->Pool(false); // Otherwise permanently pull this
- Log(this) << "Depooling delinked server " << s->GetName();
- }
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (!u->Quitting() && u->server)
- {
- DNSServer *s = DNSServer::Find(u->server->GetName());
- /* Check for user limit reached */
- if (s && s->Pooled() && s->Active() && s->GetLimit() && u->server->users >= s->GetLimit())
- {
- Log(this) << "Depooling full server " << s->GetName() << ": " << u->server->users << " users";
- s->SetActive(false);
- }
- }
- }
-
- void OnPreUserLogoff(User *u) anope_override
- {
- if (u && u->server)
- {
- DNSServer *s = DNSServer::Find(u->server->GetName());
- if (!s || !s->Pooled())
- return;
-
- /* Check for dropping under userlimit */
- if (s->GetLimit() && !s->Active() && s->GetLimit() > u->server->users)
- {
- Log(this) << "Pooling server " << s->GetName();
- s->SetActive(true);
- }
-
- if (this->user_drop_mark > 0)
- {
- std::list<time_t>& times = server_quit_times[u->server->GetName()];
- times.push_back(Anope::CurTime);
- if (times.size() > static_cast<unsigned>(this->user_drop_mark))
- times.pop_front();
-
- if (times.size() == static_cast<unsigned>(this->user_drop_mark))
- {
- time_t diff = Anope::CurTime - *times.begin();
-
- /* Check for very fast user drops */
- if (s->Active() && diff <= this->user_drop_time)
- {
- Log(this) << "Depooling server " << s->GetName() << ": dropped " << this->user_drop_mark << " users in " << diff << " seconds";
- s->repool = Anope::CurTime + this->user_drop_readd_time;
- s->SetActive(false);
- }
- /* Check for needing to re-pool a server that dropped users */
- else if (!s->Active() && s->repool && s->repool <= Anope::CurTime)
- {
- s->SetActive(true);
- s->repool = 0;
- Log(this) << "Pooling server " << s->GetName();
- }
- }
- }
- }
- }
-
- void OnDnsRequest(DNS::Query &req, DNS::Query *packet) anope_override
- {
- if (req.questions.empty())
- return;
- /* Currently we reply to any QR for A/AAAA */
- const DNS::Question& q = req.questions[0];
- if (q.type != DNS::QUERY_A && q.type != DNS::QUERY_AAAA && q.type != DNS::QUERY_AXFR && q.type != DNS::QUERY_ANY)
- return;
-
- DNSZone *zone = DNSZone::Find(q.name);
- size_t answer_size = packet->answers.size();
- if (zone)
- {
- for (std::set<Anope::string, ci::less>::iterator it = zone->servers.begin(), it_end = zone->servers.end(); it != it_end; ++it)
- {
- DNSServer *s = DNSServer::Find(*it);
- if (!s || !s->Active())
- continue;
-
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- {
- DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
-
- if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
- {
- DNS::ResourceRecord rr(q.name, q_type);
- rr.ttl = this->ttl;
- rr.rdata = s->GetIPs()[j];
- packet->answers.push_back(rr);
- }
- }
- }
- }
-
- if (packet->answers.size() == answer_size)
- {
- /* Default zone */
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- {
- DNSServer *s = dns_servers->at(i);
- if (!s->Active())
- continue;
-
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- {
- DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
-
- if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
- {
- DNS::ResourceRecord rr(q.name, q_type);
- rr.ttl = this->ttl;
- rr.rdata = s->GetIPs()[j];
- packet->answers.push_back(rr);
- }
- }
- }
- }
-
- if (packet->answers.size() == answer_size)
- {
- if (last_warn + 60 < Anope::CurTime)
- {
- last_warn = Anope::CurTime;
- Log(this) << "Warning! There are no pooled servers!";
- }
-
- /* Something messed up, just return them all and hope one is available */
- for (unsigned i = 0; i < dns_servers->size(); ++i)
- {
- DNSServer *s = dns_servers->at(i);
-
- for (unsigned j = 0; j < s->GetIPs().size(); ++j)
- {
- DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A;
-
- if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type)
- {
- DNS::ResourceRecord rr(q.name, q_type);
- rr.ttl = this->ttl;
- rr.rdata = s->GetIPs()[j];
- packet->answers.push_back(rr);
- }
- }
- }
-
- if (packet->answers.size() == answer_size)
- {
- Log(this) << "Error! There are no servers with any IPs of type " << q.type;
- /* Send back an empty answer anyway */
- }
- }
- }
-};
-
-MODULE_INIT(ModuleDNS)
diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp
deleted file mode 100644
index 8c723b337..000000000
--- a/modules/commands/os_forbid.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 "modules/os_forbid.h"
-
-static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
-
-struct ForbidDataImpl : ForbidData, Serializable
-{
- ForbidDataImpl() : Serializable("ForbidData") { }
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-void ForbidDataImpl::Serialize(Serialize::Data &data) const
-{
- data["mask"] << this->mask;
- data["creator"] << this->creator;
- data["reason"] << this->reason;
- data["created"] << this->created;
- data["expires"] << this->expires;
- data["type"] << this->type;
-}
-
-Serializable* ForbidDataImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- if (!forbid_service)
- return NULL;
-
- ForbidDataImpl *fb;
- if (obj)
- fb = anope_dynamic_static_cast<ForbidDataImpl *>(obj);
- else
- fb = new ForbidDataImpl();
-
- data["mask"] >> fb->mask;
- data["creator"] >> fb->creator;
- data["reason"] >> fb->reason;
- data["created"] >> fb->created;
- data["expires"] >> fb->expires;
- unsigned int t;
- data["type"] >> t;
- fb->type = static_cast<ForbidType>(t);
-
- if (t > FT_SIZE - 1)
- return NULL;
-
- if (!obj)
- forbid_service->AddForbid(fb);
- return fb;
-}
-
-class MyForbidService : public ForbidService
-{
- Serialize::Checker<std::vector<ForbidData *>[FT_SIZE - 1]> forbid_data;
-
- inline std::vector<ForbidData *>& forbids(unsigned t) { return (*this->forbid_data)[t - 1]; }
-
- public:
- MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { }
-
- ~MyForbidService()
- {
- std::vector<ForbidData *> f = GetForbids();
- for (unsigned i = 0; i < f.size(); ++i)
- delete f[i];
- }
-
- void AddForbid(ForbidData *d) anope_override
- {
- this->forbids(d->type).push_back(d);
- }
-
- void RemoveForbid(ForbidData *d) anope_override
- {
- std::vector<ForbidData *>::iterator it = std::find(this->forbids(d->type).begin(), this->forbids(d->type).end(), d);
- if (it != this->forbids(d->type).end())
- this->forbids(d->type).erase(it);
- delete d;
- }
-
- ForbidData *CreateForbid() anope_override
- {
- return new ForbidDataImpl();
- }
-
- ForbidData *FindForbid(const Anope::string &mask, ForbidType ftype) anope_override
- {
- for (unsigned i = this->forbids(ftype).size(); i > 0; --i)
- {
- ForbidData *d = this->forbids(ftype)[i - 1];
-
- if (Anope::Match(mask, d->mask, false, true))
- return d;
- }
- return NULL;
- }
-
- std::vector<ForbidData *> GetForbids() anope_override
- {
- std::vector<ForbidData *> f;
- for (unsigned j = FT_NICK; j < FT_SIZE; ++j)
- for (unsigned i = this->forbids(j).size(); i > 0; --i)
- {
- ForbidData *d = this->forbids(j).at(i - 1);
-
- if (d->expires && !Anope::NoExpire && Anope::CurTime >= d->expires)
- {
- Anope::string ftype = "none";
- if (d->type == FT_NICK)
- ftype = "nick";
- else if (d->type == FT_CHAN)
- ftype = "chan";
- else if (d->type == FT_EMAIL)
- ftype = "email";
-
- Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << d->mask << " type " << ftype;
- this->forbids(j).erase(this->forbids(j).begin() + i - 1);
- delete d;
- }
- else
- f.push_back(d);
- }
-
- return f;
- }
-};
-
-class CommandOSForbid : public Command
-{
- ServiceReference<ForbidService> fs;
- public:
- CommandOSForbid(Module *creator) : Command(creator, "operserv/forbid", 1, 5), fs("ForbidService", "forbid")
- {
- this->SetDesc(_("Forbid usage of nicknames, channels, and emails"));
- this->SetSyntax(_("ADD {NICK|CHAN|EMAIL|REGISTER} [+\037expiry\037] \037entry\037 \037reason\037"));
- this->SetSyntax(_("DEL {NICK|CHAN|EMAIL|REGISTER} \037entry\037"));
- this->SetSyntax("LIST [NICK|CHAN|EMAIL|REGISTER]");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!this->fs)
- return;
-
- const Anope::string &command = params[0];
- const Anope::string &subcommand = params.size() > 1 ? params[1] : "";
-
- ForbidType ftype = FT_SIZE;
- if (subcommand.equals_ci("NICK"))
- ftype = FT_NICK;
- else if (subcommand.equals_ci("CHAN"))
- ftype = FT_CHAN;
- else if (subcommand.equals_ci("EMAIL"))
- ftype = FT_EMAIL;
- else if (subcommand.equals_ci("REGISTER"))
- ftype = FT_REGISTER;
-
- if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE)
- {
- const Anope::string &expiry = params[2][0] == '+' ? params[2] : "";
- const Anope::string &entry = !expiry.empty() ? params[3] : params[2];
- Anope::string reason;
- if (expiry.empty())
- reason = params[3] + " ";
- if (params.size() > 4)
- reason += params[4];
- reason.trim();
-
- if (entry.replace_all_cs("?*", "").empty())
- {
- source.Reply(_("The mask must contain at least one non wildcard character."));
- return;
- }
-
- time_t expiryt = 0;
-
- if (!expiry.empty())
- {
- expiryt = Anope::DoTime(expiry);
- if (expiryt == -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expiryt)
- expiryt += Anope::CurTime;
- }
-
- NickAlias *target = NickAlias::Find(entry);
- if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->nc->IsServicesOper())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- ForbidData *d = this->fs->FindForbid(entry, ftype);
- bool created = false;
- if (d == NULL)
- {
- d = new ForbidDataImpl();
- created = true;
- }
-
- d->mask = entry;
- d->creator = source.GetNick();
- d->reason = reason;
- d->created = Anope::CurTime;
- d->expires = expiryt;
- d->type = ftype;
- if (created)
- this->fs->AddForbid(d);
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand;
- source.Reply(_("Added a forbid on %s of type %s to expire on %s."), entry.c_str(), subcommand.lower().c_str(), d->expires ? Anope::strftime(d->expires, source.GetAccount()).c_str() : "never");
-
- /* apply forbid */
- switch (ftype)
- {
- case FT_NICK:
- {
- int na_matches = 0;
-
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- module->OnUserNickChange(it->second, "");
-
- for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end;)
- {
- NickAlias *na = it->second;
- ++it;
-
- d = this->fs->FindForbid(na->nick, FT_NICK);
- if (d == NULL)
- continue;
-
- ++na_matches;
-
- delete na;
- }
-
- source.Reply(_("\002%d\002 nickname(s) dropped."), na_matches);
- break;
- }
- case FT_CHAN:
- {
- int chan_matches = 0, ci_matches = 0;
-
- for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
- {
- Channel *c = it->second;
- ++it;
-
- d = this->fs->FindForbid(c->name, FT_CHAN);
- if (d == NULL)
- continue;
-
- ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (IRCD->CanSQLineChannel && OperServ)
- {
- time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
- XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason);
- IRCD->SendSQLine(NULL, &x);
- }
- else if (chanserv)
- {
- chanserv->Hold(c);
- }
-
- ++chan_matches;
-
- for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;)
- {
- User *u = cit->first;
- ++cit;
-
- if (u->server == Me || u->HasMode("OPER"))
- continue;
-
- reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: %s")), d->reason.c_str());
-
- c->Kick(source.service, u, "%s", reason.c_str());
- }
- }
-
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(); it != RegisteredChannelList->end();)
- {
- ChannelInfo *ci = it->second;
- ++it;
-
- d = this->fs->FindForbid(ci->name, FT_CHAN);
- if (d == NULL)
- continue;
-
- ++ci_matches;
-
- delete ci;
- }
-
- source.Reply(_("\002%d\002 channel(s) cleared, and \002%d\002 channel(s) dropped."), chan_matches, ci_matches);
-
- break;
- }
- default:
- break;
- }
-
- }
- else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE)
- {
- const Anope::string &entry = params[2];
-
- ForbidData *d = this->fs->FindForbid(entry, ftype);
- if (d != NULL)
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to remove forbid on " << d->mask << " of type " << subcommand;
- source.Reply(_("%s deleted from the %s forbid list."), d->mask.c_str(), subcommand.c_str());
- this->fs->RemoveForbid(d);
- }
- else
- source.Reply(_("Forbid on %s was not found."), entry.c_str());
- }
- else if (command.equals_ci("LIST"))
- {
- const std::vector<ForbidData *> &forbids = this->fs->GetForbids();
- if (forbids.empty())
- source.Reply(_("Forbid list is empty."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mask")).AddColumn(_("Type")).AddColumn(_("Creator")).AddColumn(_("Expires")).AddColumn(_("Reason"));
-
- unsigned shown = 0;
- for (unsigned i = 0; i < forbids.size(); ++i)
- {
- ForbidData *d = forbids[i];
-
- if (ftype != FT_SIZE && ftype != d->type)
- continue;
-
- Anope::string stype;
- if (d->type == FT_NICK)
- stype = "NICK";
- else if (d->type == FT_CHAN)
- stype = "CHAN";
- else if (d->type == FT_EMAIL)
- stype = "EMAIL";
- else if (d->type == FT_REGISTER)
- stype = "REGISTER";
- else
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Mask"] = d->mask;
- entry["Type"] = stype;
- entry["Creator"] = d->creator;
- entry["Expires"] = d->expires ? Anope::strftime(d->expires, NULL, true).c_str() : Language::Translate(source.GetAccount(), _("Never"));
- entry["Reason"] = d->reason;
- list.AddEntry(entry);
- ++shown;
- }
-
- if (!shown)
- {
- source.Reply(_("There are no forbids of type %s."), subcommand.upper().c_str());
- }
- else
- {
- source.Reply(_("Forbid list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- if (shown >= forbids.size())
- source.Reply(_("End of forbid list."));
- else
- source.Reply(_("End of forbid list - %d/%d entries shown."), shown, forbids.size());
- }
- }
- }
- else
- this->OnSyntaxError(source, command);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels,\n"
- "and email addresses. Wildcards are accepted for all entries."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-class OSForbid : public Module
-{
- MyForbidService forbidService;
- Serialize::Type forbiddata_type;
- CommandOSForbid commandosforbid;
-
- public:
- OSForbid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- forbidService(this), forbiddata_type("ForbidData", ForbidDataImpl::Unserialize), commandosforbid(this)
- {
-
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (u->Quitting() || exempt)
- return;
-
- this->OnUserNickChange(u, "");
- }
-
- void OnUserNickChange(User *u, const Anope::string &) anope_override
- {
- if (u->HasMode("OPER"))
- return;
-
- ForbidData *d = this->forbidService.FindForbid(u->nick, FT_NICK);
- if (d != NULL)
- {
- BotInfo *bi = Config->GetClient("NickServ");
- if (!bi)
- bi = Config->GetClient("OperServ");
- if (bi)
- u->SendMessage(bi, _("This nickname has been forbidden: %s"), d->reason.c_str());
- if (nickserv)
- nickserv->Collide(u, NULL);
- }
- }
-
- EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
- {
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (u->HasMode("OPER") || !OperServ)
- return EVENT_CONTINUE;
-
- ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN);
- if (d != NULL)
- {
- ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
- if (IRCD->CanSQLineChannel)
- {
- time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
- XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason);
- IRCD->SendSQLine(NULL, &x);
- }
- else if (chanserv)
- {
- chanserv->Hold(c);
- }
-
- reason = Anope::printf(Language::Translate(u, _("This channel has been forbidden: %s")), d->reason.c_str());
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
- {
- if (command->name == "nickserv/info" && params.size() > 0)
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_NICK);
- if (d != NULL)
- {
- if (source.IsOper())
- source.Reply(_("Nick \002%s\002 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str());
- else
- source.Reply(_("Nick \002%s\002 is forbidden."), params[0].c_str());
- return EVENT_STOP;
- }
- }
- else if (command->name == "chanserv/info" && params.size() > 0)
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_CHAN);
- if (d != NULL)
- {
- if (source.IsOper())
- source.Reply(_("Channel \002%s\002 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str());
- else
- source.Reply(_("Channel \002%s\002 is forbidden."), params[0].c_str());
- return EVENT_STOP;
- }
- }
- else if (source.IsOper())
- return EVENT_CONTINUE;
- else if (command->name == "nickserv/register" && params.size() > 1)
- {
- ForbidData *d = this->forbidService.FindForbid(source.GetNick(), FT_REGISTER);
- if (d != NULL)
- {
- source.Reply(NICK_CANNOT_BE_REGISTERED, source.GetNick().c_str());
- return EVENT_STOP;
- }
-
- d = this->forbidService.FindForbid(params[1], FT_EMAIL);
- if (d != NULL)
- {
- source.Reply(_("Your email address is not allowed, choose a different one."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "nickserv/set/email" && params.size() > 0)
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_EMAIL);
- if (d != NULL)
- {
- source.Reply(_("Your email address is not allowed, choose a different one."));
- return EVENT_STOP;
- }
- }
- else if (command->name == "chanserv/register" && !params.empty())
- {
- ForbidData *d = this->forbidService.FindForbid(params[0], FT_REGISTER);
- if (d != NULL)
- {
- source.Reply(CHAN_X_INVALID, params[0].c_str());
- return EVENT_STOP;
- }
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(OSForbid)
diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp
deleted file mode 100644
index 2f4fca3e2..000000000
--- a/modules/commands/os_ignore.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 "modules/os_ignore.h"
-
-struct IgnoreDataImpl : IgnoreData, Serializable
-{
- IgnoreDataImpl() : Serializable("IgnoreData") { }
- ~IgnoreDataImpl();
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-IgnoreDataImpl::~IgnoreDataImpl()
-{
- if (ignore_service)
- ignore_service->DelIgnore(this);
-}
-
-void IgnoreDataImpl::Serialize(Serialize::Data &data) const
-{
- data["mask"] << this->mask;
- data["creator"] << this->creator;
- data["reason"] << this->reason;
- data["time"] << this->time;
-}
-
-Serializable* IgnoreDataImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- if (!ignore_service)
- return NULL;
-
- IgnoreDataImpl *ign;
- if (obj)
- ign = anope_dynamic_static_cast<IgnoreDataImpl *>(obj);
- else
- {
- ign = new IgnoreDataImpl();
- ignore_service->AddIgnore(ign);
- }
-
- data["mask"] >> ign->mask;
- data["creator"] >> ign->creator;
- data["reason"] >> ign->reason;
- data["time"] >> ign->time;
-
- return ign;
-}
-
-
-class OSIgnoreService : public IgnoreService
-{
- Serialize::Checker<std::vector<IgnoreData *> > ignores;
-
- public:
- OSIgnoreService(Module *o) : IgnoreService(o), ignores("IgnoreData") { }
-
- void AddIgnore(IgnoreData *ign) anope_override
- {
- ignores->push_back(ign);
- }
-
- void DelIgnore(IgnoreData *ign) anope_override
- {
- std::vector<IgnoreData *>::iterator it = std::find(ignores->begin(), ignores->end(), ign);
- if (it != ignores->end())
- ignores->erase(it);
- }
-
- void ClearIgnores() anope_override
- {
- for (unsigned i = ignores->size(); i > 0; --i)
- {
- IgnoreData *ign = ignores->at(i - 1);
- delete ign;
- }
- }
-
- IgnoreData *Create() anope_override
- {
- return new IgnoreDataImpl();
- }
-
- IgnoreData *Find(const Anope::string &mask) anope_override
- {
- User *u = User::Find(mask, true);
- std::vector<IgnoreData *>::iterator ign = this->ignores->begin(), ign_end = this->ignores->end();
-
- if (u)
- {
- for (; ign != ign_end; ++ign)
- {
- Entry ignore_mask("", (*ign)->mask);
- if (ignore_mask.Matches(u, true))
- break;
- }
- }
- else
- {
- size_t user, host;
- Anope::string tmp;
- /* We didn't get a user.. generate a valid mask. */
- if ((host = mask.find('@')) != Anope::string::npos)
- {
- if ((user = mask.find('!')) != Anope::string::npos)
- {
- /* this should never happen */
- if (user > host)
- return NULL;
- tmp = mask;
- }
- else
- /* We have user@host. Add nick wildcard. */
- tmp = "*!" + mask;
- }
- /* We only got a nick.. */
- else
- tmp = mask + "!*@*";
-
- for (; ign != ign_end; ++ign)
- if (Anope::Match(tmp, (*ign)->mask, false, true))
- break;
- }
-
- /* Check whether the entry has timed out */
- if (ign != ign_end)
- {
- IgnoreData *id = *ign;
-
- if (id->time && !Anope::NoExpire && id->time <= Anope::CurTime)
- {
- Log(LOG_NORMAL, "expire/ignore", Config->GetClient("OperServ")) << "Expiring ignore entry " << id->mask;
- delete id;
- }
- else
- return id;
- }
-
- return NULL;
- }
-
- std::vector<IgnoreData *> &GetIgnores() anope_override
- {
- return *ignores;
- }
-};
-
-class CommandOSIgnore : public Command
-{
- private:
- Anope::string RealMask(const Anope::string &mask)
- {
- /* If it s an existing user, we ignore the hostmask. */
- User *u = User::Find(mask, true);
- if (u)
- return "*!*@" + u->host;
-
- size_t host = mask.find('@');
- /* Determine whether we get a nick or a mask. */
- if (host != Anope::string::npos)
- {
- size_t user = mask.find('!');
- /* Check whether we have a nick too.. */
- if (user != Anope::string::npos)
- {
- if (user > host)
- /* this should never happen */
- return "";
- else
- return mask;
- }
- else
- /* We have user@host. Add nick wildcard. */
- return "*!" + mask;
- }
-
- /* We only got a nick.. */
- return mask + "!*@*";
- }
-
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (!ignore_service)
- return;
-
- const Anope::string &time = params.size() > 1 ? params[1] : "";
- const Anope::string &nick = params.size() > 2 ? params[2] : "";
- const Anope::string &reason = params.size() > 3 ? params[3] : "";
-
- if (time.empty() || nick.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
- else
- {
- time_t t = Anope::DoTime(time);
-
- if (t <= -1)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
-
- Anope::string mask = RealMask(nick);
- if (mask.empty())
- {
- source.Reply(BAD_USERHOST_MASK);
- return;
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- IgnoreData *ign = new IgnoreDataImpl();
- ign->mask = mask;
- ign->creator = source.GetNick();
- ign->reason = reason;
- ign->time = t ? Anope::CurTime + t : 0;
-
- ignore_service->AddIgnore(ign);
- if (!t)
- {
- source.Reply(_("\002%s\002 will now permanently be ignored."), mask.c_str());
- Log(LOG_ADMIN, source, this) << "to add a permanent ignore for " << mask;
- }
- else
- {
- source.Reply(_("\002%s\002 will now be ignored for \002%s\002."), mask.c_str(), Anope::Duration(t, source.GetAccount()).c_str());
- Log(LOG_ADMIN, source, this) << "to add an ignore on " << mask << " for " << Anope::Duration(t);
- }
- }
- }
-
- void DoList(CommandSource &source)
- {
- if (!ignore_service)
- return;
-
- std::vector<IgnoreData *> &ignores = ignore_service->GetIgnores();
- for (unsigned i = ignores.size(); i > 0; --i)
- {
- IgnoreData *id = ignores[i - 1];
-
- if (id->time && !Anope::NoExpire && id->time <= Anope::CurTime)
- {
- Log(LOG_NORMAL, "expire/ignore", Config->GetClient("OperServ")) << "Expiring ignore entry " << id->mask;
- delete id;
- }
- }
-
- if (ignores.empty())
- source.Reply(_("Ignore list is empty."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Reason")).AddColumn(_("Expires"));
-
- for (unsigned i = ignores.size(); i > 0; --i)
- {
- const IgnoreData *ignore = ignores[i - 1];
-
- ListFormatter::ListEntry entry;
- entry["Mask"] = ignore->mask;
- entry["Creator"] = ignore->creator;
- entry["Reason"] = ignore->reason;
- entry["Expires"] = Anope::Expires(ignore->time, source.GetAccount());
- list.AddEntry(entry);
- }
-
- source.Reply(_("Services ignore list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- if (!ignore_service)
- return;
-
- const Anope::string nick = params.size() > 1 ? params[1] : "";
- if (nick.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- Anope::string mask = RealMask(nick);
- if (mask.empty())
- {
- source.Reply(BAD_USERHOST_MASK);
- return;
- }
-
- IgnoreData *ign = ignore_service->Find(mask);
- if (ign)
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "to remove an ignore on " << mask;
- source.Reply(_("\002%s\002 will no longer be ignored."), mask.c_str());
- delete ign;
- }
- else
- source.Reply(_("\002%s\002 not found on ignore list."), mask.c_str());
- }
-
- void DoClear(CommandSource &source)
- {
- if (!ignore_service)
- return;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- ignore_service->ClearIgnores();
- Log(LOG_ADMIN, source, this) << "to CLEAR the list";
- source.Reply(_("Ignore list has been cleared."));
-
- return;
- }
-
- public:
- CommandOSIgnore(Module *creator) : Command(creator, "operserv/ignore", 1, 4)
- {
- this->SetDesc(_("Modify the Services ignore list"));
- this->SetSyntax(_("ADD \037expiry\037 {\037nick\037|\037mask\037} [\037reason\037]"));
- this->SetSyntax(_("DEL {\037nick\037|\037mask\037}"));
- this->SetSyntax("LIST");
- this->SetSyntax("CLEAR");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->DoClear(source);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to make Services ignore a nick or mask\n"
- "for a certain time or until the next restart. The default\n"
- "time format is seconds. You can specify it by using units.\n"
- "Valid units are: \037s\037 for seconds, \037m\037 for minutes,\n"
- "\037h\037 for hours and \037d\037 for days.\n"
- "Combinations of these units are not permitted.\n"
- "To make Services permanently ignore the user, type 0 as time.\n"
- "When adding a \037mask\037, it should be in the format nick!user@host,\n"
- "everything else will be considered a nick. Wildcards are permitted.\n"
- " \n"
- "Ignores will not be enforced on IRC Operators."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-class OSIgnore : public Module
-{
- Serialize::Type ignoredata_type;
- OSIgnoreService osignoreservice;
- CommandOSIgnore commandosignore;
-
- public:
- OSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- ignoredata_type("IgnoreData", IgnoreDataImpl::Unserialize), osignoreservice(this), commandosignore(this)
- {
-
- }
-
- EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
- {
- if (!u->HasMode("OPER") && this->osignoreservice.Find(u->nick))
- return EVENT_STOP;
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(OSIgnore)
diff --git a/modules/commands/os_info.cpp b/modules/commands/os_info.cpp
deleted file mode 100644
index 0965d5ea7..000000000
--- a/modules/commands/os_info.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "module.h"
-
-struct OperInfo : Serializable
-{
- Anope::string target;
- Anope::string info;
- Anope::string adder;
- time_t created;
-
- OperInfo() : Serializable("OperInfo"), created(0) { }
- OperInfo(const Anope::string &t, const Anope::string &i, const Anope::string &a, time_t c) :
- Serializable("OperInfo"), target(t), info(i), adder(a), created(c) { }
-
- ~OperInfo();
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["target"] << target;
- data["info"] << info;
- data["adder"] << adder;
- data["created"] << created;
- }
-
- static Serializable *Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct OperInfos : Serialize::Checker<std::vector<OperInfo *> >
-{
- OperInfos(Extensible *) : Serialize::Checker<std::vector<OperInfo *> >("OperInfo") { }
-
- ~OperInfos()
- {
- for (unsigned i = (*this)->size(); i > 0; --i)
- delete (*this)->at(i - 1);
- }
-
- static Extensible *Find(const Anope::string &target)
- {
- NickAlias *na = NickAlias::Find(target);
- if (na)
- return na->nc;
- return ChannelInfo::Find(target);
- }
-};
-
-OperInfo::~OperInfo()
-{
- Extensible *e = OperInfos::Find(target);
- if (e)
- {
- OperInfos *op = e->GetExt<OperInfos>("operinfo");
- if (op)
- {
- std::vector<OperInfo *>::iterator it = std::find((*op)->begin(), (*op)->end(), this);
- if (it != (*op)->end())
- (*op)->erase(it);
- }
- }
-}
-
-Serializable *OperInfo::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string starget;
- data["target"] >> starget;
-
- Extensible *e = OperInfos::Find(starget);
- if (!e)
- return NULL;
-
- OperInfos *oi = e->Require<OperInfos>("operinfo");
- OperInfo *o;
- if (obj)
- o = anope_dynamic_static_cast<OperInfo *>(obj);
- else
- {
- o = new OperInfo();
- o->target = starget;
- }
- data["info"] >> o->info;
- data["adder"] >> o->adder;
- data["created"] >> o->created;
-
- if (!obj)
- (*oi)->push_back(o);
- return o;
-}
-
-class CommandOSInfo : public Command
-{
- public:
- CommandOSInfo(Module *creator) : Command(creator, "operserv/info", 2, 3)
- {
- this->SetDesc(_("Associate oper info with a nick or channel"));
- this->SetSyntax(_("ADD \037target\037 \037info\037"));
- this->SetSyntax(_("DEL \037target\037 \037info\037"));
- this->SetSyntax(_("CLEAR \037target\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0], target = params[1], info = params.size() > 2 ? params[2] : "";
-
- Extensible *e;
- if (IRCD->IsChannelValid(target))
- {
- ChannelInfo *ci = ChannelInfo::Find(target);
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
- return;
- }
-
- e = ci;
- }
- else
- {
- NickAlias *na = NickAlias::Find(target);
- if (!na)
- {
- source.Reply(NICK_X_NOT_REGISTERED, target.c_str());
- return;
- }
-
- e = na->nc;
- }
-
- if (cmd.equals_ci("ADD"))
- {
- if (info.empty())
- {
- this->OnSyntaxError(source, cmd);
- return;
- }
-
- OperInfos *oi = e->Require<OperInfos>("operinfo");
-
- if ((*oi)->size() >= Config->GetModule(this->module)->Get<unsigned>("max", "10"))
- {
- source.Reply(_("The oper info list for \002%s\002 is full."), target.c_str());
- return;
- }
-
- for (unsigned i = 0; i < (*oi)->size(); ++i)
- {
- OperInfo *o = (*oi)->at(i);
-
- if (o->info.equals_ci(info))
- {
- source.Reply(_("The oper info already exists on \002%s\002."), target.c_str());
- return;
- }
- }
-
- (*oi)->push_back(new OperInfo(target, info, source.GetNick(), Anope::CurTime));
-
- source.Reply(_("Added info to \002%s\002."), target.c_str());
- Log(LOG_ADMIN, source, this) << "to add information to " << target;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- else if (cmd.equals_ci("DEL"))
- {
- if (info.empty())
- {
- this->OnSyntaxError(source, cmd);
- return;
- }
-
- OperInfos *oi = e->GetExt<OperInfos>("operinfo");
-
- if (!oi)
- {
- source.Reply(_("Oper info list for \002%s\002 is empty."), target.c_str());
- return;
- }
-
- bool found = false;
- for (unsigned i = (*oi)->size(); i > 0; --i)
- {
- OperInfo *o = (*oi)->at(i - 1);
-
- if (o->info.equals_ci(info))
- {
- delete o;
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- source.Reply(_("No such info \"%s\" on \002%s\002."), info.c_str(), target.c_str());
- }
- else
- {
- if ((*oi)->empty())
- e->Shrink<OperInfos>("operinfo");
-
- source.Reply(_("Deleted info from \002%s\002."), target.c_str());
- Log(LOG_ADMIN, source, this) << "to remove information from " << target;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- }
- else if (cmd.equals_ci("CLEAR"))
- {
- OperInfos *oi = e->GetExt<OperInfos>("operinfo");
-
- if (!oi)
- {
- source.Reply(_("Oper info list for \002%s\002 is empty."), target.c_str());
- return;
- }
-
- e->Shrink<OperInfos>("operinfo");
-
- source.Reply(_("Cleared info from \002%s\002."), target.c_str());
- Log(LOG_ADMIN, source, this) << "to clear information for " << target;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- else
- {
- this->OnSyntaxError(source, cmd);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Add or delete oper information for a given nick or channel.\n"
- "This will show to opers in the respective info command for\n"
- "the nick or channel."));
- return true;
- }
-};
-
-class OSInfo : public Module
-{
- CommandOSInfo commandosinfo;
- ExtensibleItem<OperInfos> oinfo;
- Serialize::Type oinfo_type;
-
- void OnInfo(CommandSource &source, Extensible *e, InfoFormatter &info)
- {
- if (!source.IsOper())
- return;
-
- OperInfos *oi = oinfo.Get(e);
- if (!oi)
- return;
-
- for (unsigned i = 0; i < (*oi)->size(); ++i)
- {
- OperInfo *o = (*oi)->at(i);
- info[_("Oper Info")] = Anope::printf(_("(by %s on %s) %s"), o->adder.c_str(), Anope::strftime(o->created, source.GetAccount(), true).c_str(), o->info.c_str());
- }
- }
-
- public:
- OSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosinfo(this), oinfo(this, "operinfo"), oinfo_type("OperInfo", OperInfo::Unserialize)
- {
-
- }
-
- void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override
- {
- OnInfo(source, na->nc, info);
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- OnInfo(source, ci, info);
- }
-};
-
-MODULE_INIT(OSInfo)
diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp
deleted file mode 100644
index c586feee3..000000000
--- a/modules/commands/os_jupe.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSJupe : public Command
-{
- public:
- CommandOSJupe(Module *creator) : Command(creator, "operserv/jupe", 1, 2)
- {
- this->SetDesc(_("\"Jupiter\" a server"));
- this->SetSyntax(_("\037server\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &jserver = params[0];
- const Anope::string &reason = params.size() > 1 ? params[1] : "";
- Server *server = Server::Find(jserver, true);
-
- if (!IRCD->IsHostValid(jserver) || jserver.find('.') == Anope::string::npos)
- source.Reply(_("Please use a valid server name when juping."));
- else if (server == Me || server == Servers::GetUplink())
- source.Reply(_("You can not jupe your Services' pseudoserver or your uplink server."));
- else if (server && server->IsJuped())
- source.Reply(_("You can not jupe an already juped server."));
- else
- {
- Anope::string rbuf = "Juped by " + source.GetNick() + (!reason.empty() ? ": " + reason : "");
- /* Generate the new sid before quitting the old server, so they can't collide */
- Anope::string sid = IRCD->SID_Retrieve();
- if (server)
- {
- IRCD->SendSquit(server, rbuf);
- server->Delete(rbuf);
- }
- Server *juped_server = new Server(Me, jserver, 1, rbuf, sid, true);
- IRCD->SendServer(juped_server);
-
- Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")";
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Tells Services to jupiter a server -- that is, to create\n"
- "a fake \"server\" connected to Services which prevents\n"
- "the real server of that name from connecting. The jupe\n"
- "may be removed using a standard \002SQUIT\002. If a reason is\n"
- "given, it is placed in the server information field;\n"
- "otherwise, the server information field will contain the\n"
- "text \"Juped by <nick>\", showing the nickname of the\n"
- "person who jupitered the server."));
- return true;
- }
-};
-
-class OSJupe : public Module
-{
- CommandOSJupe commandosjupe;
-
- public:
- OSJupe(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosjupe(this)
- {
-
- }
-};
-
-MODULE_INIT(OSJupe)
diff --git a/modules/commands/os_kick.cpp b/modules/commands/os_kick.cpp
deleted file mode 100644
index 5a3584240..000000000
--- a/modules/commands/os_kick.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSKick : public Command
-{
- public:
- CommandOSKick(Module *creator) : Command(creator, "operserv/kick", 3, 3)
- {
- this->SetDesc(_("Kick a user from a channel"));
- this->SetSyntax(_("\037channel\037 \037user\037 \037reason\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &chan = params[0];
- const Anope::string &nick = params[1];
- const Anope::string &s = params[2];
- Channel *c;
- User *u2;
-
- if (!(c = Channel::Find(chan)))
- {
- source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
- return;
- }
-
- if (c->bouncy_modes)
- {
- source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
- return;
- }
-
- if (!(u2 = User::Find(nick, true)))
- {
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- return;
- }
-
- if (!c->Kick(source.service, u2, "%s (%s)", source.GetNick().c_str(), s.c_str()))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- Log(LOG_ADMIN, source, this) << "on " << u2->nick << " in " << c->name << " (" << s << ")";
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows staff to kick a user from any channel.\n"
- "Parameters are the same as for the standard /KICK\n"
- "command. The kick message will have the nickname of the\n"
- "IRCop sending the KICK command prepended; for example:\n"
- " \n"
- "*** SpamMan has been kicked off channel #my_channel by %s (Alcan (Flood))"), source.service->nick.c_str());
- return true;
- }
-};
-
-class OSKick : public Module
-{
- CommandOSKick commandoskick;
-
- public:
- OSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoskick(this)
- {
-
- }
-};
-
-MODULE_INIT(OSKick)
diff --git a/modules/commands/os_kill.cpp b/modules/commands/os_kill.cpp
deleted file mode 100644
index 12fcda99e..000000000
--- a/modules/commands/os_kill.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSKill : public Command
-{
- public:
- CommandOSKill(Module *creator) : Command(creator, "operserv/kill", 1, 2)
- {
- this->SetDesc(_("Kill a user"));
- this->SetSyntax(_("\037user\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- Anope::string reason = params.size() > 1 ? params[1] : "";
-
- User *u2 = User::Find(nick, true);
- if (u2 == NULL)
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- else if (u2->IsProtected() || u2->server == Me)
- source.Reply(ACCESS_DENIED);
- else
- {
- if (reason.empty())
- reason = "No reason specified";
- if (Config->GetModule("operserv")->Get<bool>("addakiller"))
- reason = "(" + source.GetNick() + ") " + reason;
- Log(LOG_ADMIN, source, this) << "on " << u2->nick << " for " << reason;
- u2->Kill(*source.service, reason);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to kill a user from the network.\n"
- "Parameters are the same as for the standard /KILL\n"
- "command."));
- return true;
- }
-};
-
-class OSKill : public Module
-{
- CommandOSKill commandoskill;
-
- public:
- OSKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoskill(this)
- {
-
- }
-};
-
-MODULE_INIT(OSKill)
diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp
deleted file mode 100644
index 27e02cb0a..000000000
--- a/modules/commands/os_list.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSChanList : public Command
-{
- public:
- CommandOSChanList(Module *creator) : Command(creator, "operserv/chanlist", 0, 2)
- {
- this->SetDesc(_("Lists all channel records"));
- this->SetSyntax(_("[{\037pattern\037 | \037nick\037} [\037SECRET\037]]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &pattern = !params.empty() ? params[0] : "";
- const Anope::string &opt = params.size() > 1 ? params[1] : "";
- std::set<Anope::string> modes;
- User *u2;
-
- if (!pattern.empty())
- Log(LOG_ADMIN, source, this) << "for " << pattern;
- else
- Log(LOG_ADMIN, source, this);
-
- if (!opt.empty() && opt.equals_ci("SECRET"))
- {
- modes.insert("SECRET");
- modes.insert("PRIVATE");
- }
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Users")).AddColumn(_("Modes")).AddColumn(_("Topic"));
-
- if (!pattern.empty() && (u2 = User::Find(pattern, true)))
- {
- source.Reply(_("\002%s\002 channel list:"), u2->nick.c_str());
-
- for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit)
- {
- ChanUserContainer *cc = uit->second;
-
- if (!modes.empty())
- for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
- if (!cc->chan->HasMode(*it))
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Name"] = cc->chan->name;
- entry["Users"] = stringify(cc->chan->users.size());
- entry["Modes"] = cc->chan->GetModes(true, true);
- entry["Topic"] = cc->chan->topic;
- list.AddEntry(entry);
- }
- }
- else
- {
- source.Reply(_("Channel list:"));
-
- for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
- {
- Channel *c = cit->second;
-
- if (!pattern.empty() && !Anope::Match(c->name, pattern, false, true))
- continue;
- if (!modes.empty())
- for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
- if (!c->HasMode(*it))
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Name"] = c->name;
- entry["Users"] = stringify(c->users.size());
- entry["Modes"] = c->GetModes(true, true);
- entry["Topic"] = c->topic;
- list.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of channel list."));
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all channels currently in use on the IRC network, whether they\n"
- "are registered or not.\n"
- " \n"
- "If \002pattern\002 is given, lists only channels that match it. If a nickname\n"
- "is given, lists only the channels the user using it is on. If SECRET is\n"
- "specified, lists only channels matching \002pattern\002 that have the +s or\n"
- "+p mode."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-class CommandOSUserList : public Command
-{
- public:
- CommandOSUserList(Module *creator) : Command(creator, "operserv/userlist", 0, 2)
- {
- this->SetDesc(_("Lists all user records"));
- this->SetSyntax(_("[{\037pattern\037 | \037channel\037} [\037INVISIBLE\037]]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &pattern = !params.empty() ? params[0] : "";
- const Anope::string &opt = params.size() > 1 ? params[1] : "";
- Channel *c;
- std::set<Anope::string> modes;
-
- if (!pattern.empty())
- Log(LOG_ADMIN, source, this) << "for " << pattern;
- else
- Log(LOG_ADMIN, source, this);
-
- if (!opt.empty() && opt.equals_ci("INVISIBLE"))
- modes.insert("INVIS");
-
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Name")).AddColumn(_("Mask"));
-
- if (!pattern.empty() && (c = Channel::Find(pattern)))
- {
- source.Reply(_("\002%s\002 users list:"), pattern.c_str());
-
- for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit)
- {
- ChanUserContainer *uc = cuit->second;
-
- if (!modes.empty())
- for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
- if (!uc->user->HasMode(*it))
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Name"] = uc->user->nick;
- entry["Mask"] = uc->user->GetIdent() + "@" + uc->user->GetDisplayedHost();
- list.AddEntry(entry);
- }
- }
- else
- {
- /* Historically this has been ordered, so... */
- Anope::map<User *> ordered_map;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- ordered_map[it->first] = it->second;
-
- source.Reply(_("Users list:"));
-
- for (Anope::map<User *>::const_iterator it = ordered_map.begin(); it != ordered_map.end(); ++it)
- {
- User *u2 = it->second;
-
- if (!pattern.empty())
- {
- Anope::string mask = u2->nick + "!" + u2->GetIdent() + "@" + u2->GetDisplayedHost(), mask2 = u2->nick + "!" + u2->GetIdent() + "@" + u2->host, mask3 = u2->nick + "!" + u2->GetIdent() + "@" + u2->ip.addr();
- if (!Anope::Match(mask, pattern) && !Anope::Match(mask2, pattern) && !Anope::Match(mask3, pattern))
- continue;
- if (!modes.empty())
- for (std::set<Anope::string>::iterator mit = modes.begin(), mit_end = modes.end(); mit != mit_end; ++mit)
- if (!u2->HasMode(*mit))
- continue;
- }
-
- ListFormatter::ListEntry entry;
- entry["Name"] = u2->nick;
- entry["Mask"] = u2->GetIdent() + "@" + u2->GetDisplayedHost();
- list.AddEntry(entry);
- }
- }
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of users list."));
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists all users currently online on the IRC network, whether their\n"
- "nick is registered or not.\n"
- " \n"
- "If \002pattern\002 is given, lists only users that match it (it must be in\n"
- "the format nick!user@host). If \002channel\002 is given, lists only users\n"
- "that are on the given channel. If INVISIBLE is specified, only users\n"
- "with the +i flag will be listed."));
-
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), regexengine.c_str());
- }
-
- return true;
- }
-};
-
-class OSList : public Module
-{
- CommandOSChanList commandoschanlist;
- CommandOSUserList commandosuserlist;
-
- public:
- OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoschanlist(this), commandosuserlist(this)
- {
-
- }
-};
-
-MODULE_INIT(OSList)
diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp
deleted file mode 100644
index b18ffc633..000000000
--- a/modules/commands/os_login.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSLogin : public Command
-{
- public:
- CommandOSLogin(Module *creator) : Command(creator, "operserv/login", 1, 1)
- {
- this->SetSyntax(_("\037password\037"));
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &password = params[0];
-
- User *u = source.GetUser();
- Oper *o = source.nc->o;
- if (o == NULL)
- source.Reply(_("No oper block for your nick."));
- else if (o->password.empty())
- source.Reply(_("Your oper block doesn't require logging in."));
- else if (u->HasExt("os_login"))
- source.Reply(_("You are already identified."));
- else if (o->password != password)
- {
- source.Reply(PASSWORD_INCORRECT);
- u->BadPassword();
- }
- else
- {
- Log(LOG_ADMIN, source, this) << "and successfully identified to " << source.service->nick;
- u->Extend<bool>("os_login");
- source.Reply(_("Password accepted."));
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Logs you in to %s so you gain Services Operator privileges.\n"
- "This command may be unnecessary if your oper block is\n"
- "configured without a password."), source.service->nick.c_str());
- return true;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Login to %s")), source.service->nick.c_str());
- }
-};
-
-class CommandOSLogout : public Command
-{
- public:
- CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0)
- {
- this->RequireUser(true);
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser();
- Oper *o = source.nc->o;
- if (o == NULL)
- source.Reply(_("No oper block for your nick."));
- else if (o->password.empty())
- source.Reply(_("Your oper block doesn't require logging in."));
- else if (!u->HasExt("os_login"))
- source.Reply(_("You are not identified."));
- else
- {
- Log(LOG_ADMIN, source, this);
- u->Shrink<bool>("os_login");
- source.Reply(_("You have been logged out."));
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Logs you out from %s so you lose Services Operator privileges.\n"
- "This command is only useful if your oper block is configured\n"
- "with a password."), source.service->nick.c_str());
- return true;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Logout from %s")), source.service->nick.c_str());
- }
-};
-
-class OSLogin : public Module
-{
- CommandOSLogin commandoslogin;
- CommandOSLogout commandoslogout;
- ExtensibleItem<bool> os_login;
-
- public:
- OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoslogin(this), commandoslogout(this), os_login(this, "os_login")
- {
-
- }
-
- EventReturn IsServicesOper(User *u) anope_override
- {
- if (!u->Account()->o->password.empty())
- {
- if (os_login.HasExt(u))
- return EVENT_ALLOW;
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-};
-
-MODULE_INIT(OSLogin)
diff --git a/modules/commands/os_logsearch.cpp b/modules/commands/os_logsearch.cpp
deleted file mode 100644
index f8ee99d4e..000000000
--- a/modules/commands/os_logsearch.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSLogSearch : public Command
-{
- static inline Anope::string CreateLogName(const Anope::string &file, time_t t = Anope::CurTime)
- {
- char timestamp[32];
-
- tm *tm = localtime(&t);
-
- strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
-
- return Anope::LogDir + "/" + file + "." + timestamp;
- }
-
- public:
- CommandOSLogSearch(Module *creator) : Command(creator, "operserv/logsearch", 1, 3)
- {
- this->SetDesc(_("Searches logs for a matching pattern"));
- this->SetSyntax(_("[+\037days\037d] [+\037limit\037l] \037pattern\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- int days = 7, replies = 50;
-
- unsigned i;
- for (i = 0; i < params.size() && params[i][0] == '+'; ++i)
- {
- switch (params[i][params[i].length() - 1])
- {
- case 'd':
- if (params[i].length() > 2)
- {
- Anope::string dur = params[i].substr(1, params[i].length() - 2);
- try
- {
- days = convertTo<int>(dur);
- if (days <= 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("Invalid duration %s, using %d days."), dur.c_str(), days);
- }
- }
- break;
- case 'l':
- if (params[i].length() > 2)
- {
- Anope::string dur = params[i].substr(1, params[i].length() - 2);
- try
- {
- replies = convertTo<int>(dur);
- if (replies <= 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
- {
- source.Reply(_("Invalid limit %s, using %d."), dur.c_str(), replies);
- }
- }
- break;
- default:
- source.Reply(_("Unknown parameter: %s"), params[i].c_str());
- }
- }
-
- if (i >= params.size())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
- Anope::string search_string = params[i++];
- for (; i < params.size(); ++i)
- search_string += " " + params[i];
-
- Log(LOG_ADMIN, source, this) << "for " << search_string;
-
- const Anope::string &logfile_name = Config->GetModule(this->owner)->Get<const Anope::string>("logname");
- std::list<Anope::string> matches;
- for (int d = days - 1; d >= 0; --d)
- {
- Anope::string lf_name = CreateLogName(logfile_name, Anope::CurTime - (d * 86400));
- Log(LOG_DEBUG) << "Searching " << lf_name;
- std::fstream fd(lf_name.c_str(), std::ios_base::in);
- if (!fd.is_open())
- continue;
-
- for (Anope::string buf, token; std::getline(fd, buf.str());)
- if (Anope::Match(buf, "*" + search_string + "*"))
- matches.push_back(buf);
-
- fd.close();
- }
-
- unsigned found = matches.size();
- if (!found)
- {
- source.Reply(_("No matches for \002%s\002 found."), search_string.c_str());
- return;
- }
-
- while (matches.size() > static_cast<unsigned>(replies))
- matches.pop_front();
-
- source.Reply(_("Matches for \002%s\002:"), search_string.c_str());
- unsigned count = 0;
- for (std::list<Anope::string>::iterator it = matches.begin(), it_end = matches.end(); it != it_end; ++it)
- source.Reply("#%d: %s", ++count, it->c_str());
- source.Reply(_("Showed %d/%d matches for \002%s\002."), matches.size(), found, search_string.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command searches the Services logfiles for messages\n"
- "that match the given pattern. The day and limit argument\n"
- "may be used to specify how many days of logs to search\n"
- "and the number of replies to limit to. By default this\n"
- "command searches one week of logs, and limits replies\n"
- "to 50.\n"
- " \n"
- "For example:\n"
- " \002LOGSEARCH +21d +500l Anope\002\n"
- " Searches the last 21 days worth of logs for messages\n"
- " containing Anope and lists the most recent 500 of them."));
- return true;
- }
-};
-
-class OSLogSearch : public Module
-{
- CommandOSLogSearch commandoslogsearch;
-
- public:
- OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandoslogsearch(this)
- {
- }
-};
-
-MODULE_INIT(OSLogSearch)
diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp
deleted file mode 100644
index 378f6b082..000000000
--- a/modules/commands/os_mode.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSMode : public Command
-{
- public:
- CommandOSMode(Module *creator) : Command(creator, "operserv/mode", 2, 3)
- {
- this->SetDesc(_("Change channel modes"));
- this->SetSyntax(_("\037channel\037 \037modes\037"));
- this->SetSyntax(_("\037channel\037 CLEAR [ALL]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &target = params[0];
- const Anope::string &modes = params[1];
-
- Reference<Channel> c = Channel::Find(target);
- if (!c)
- source.Reply(CHAN_X_NOT_IN_USE, target.c_str());
- else if (c->bouncy_modes)
- source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
- else if (modes.equals_ci("CLEAR"))
- {
- bool all = params.size() > 2 && params[2].equals_ci("ALL");
-
- const Channel::ModeList chmodes = c->GetModes();
- for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end && c; ++it)
- c->RemoveMode(c->ci->WhoSends(), it->first, it->second, false);
-
- if (!c)
- {
- source.Reply(_("Modes cleared on %s and the channel destroyed."), target.c_str());
- return;
- }
-
- if (all)
- {
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
-
- if (uc->user->HasMode("OPER"))
- continue;
-
- for (size_t i = uc->status.Modes().length(); i > 0; --i)
- c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i - 1]), uc->user->GetUID(), false);
- }
-
- source.Reply(_("All modes cleared on %s."), c->name.c_str());
- }
- else
- source.Reply(_("Non-status modes cleared on %s."), c->name.c_str());
- }
- else
- {
- spacesepstream sep(modes + (params.size() > 2 ? " " + params[2] : ""));
- Anope::string mode;
- int add = 1;
- Anope::string log_modes, log_params;
-
- sep.GetToken(mode);
- for (unsigned i = 0; i < mode.length() && c; ++i)
- {
- char ch = mode[i];
-
- if (ch == '+')
- {
- add = 1;
- log_modes += "+";
- continue;
- }
- else if (ch == '-')
- {
- add = 0;
- log_modes += "-";
- continue;
- }
-
- ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
- if (!cm)
- continue;
-
- Anope::string param, param_log;
- if (cm->type != MODE_REGULAR)
- {
- if (cm->type == MODE_PARAM && !add && anope_dynamic_static_cast<ChannelModeParam *>(cm)->minus_no_arg)
- ;
- else if (!sep.GetToken(param))
- continue;
-
- param_log = param;
-
- if (cm->type == MODE_STATUS)
- {
- User *targ = User::Find(param, true);
- if (targ == NULL || c->FindUser(targ) == NULL)
- continue;
- param = targ->GetUID();
- }
- }
-
- log_modes += cm->mchar;
- if (!param.empty())
- log_params += " " + param_log;
-
- if (add)
- c->SetMode(source.service, cm, param, false);
- else
- c->RemoveMode(source.service, cm, param, false);
- }
-
- if (!log_modes.replace_all_cs("+", "").replace_all_cs("-", "").empty())
- Log(LOG_ADMIN, source, this) << log_modes << log_params << " on " << (c ? c->name : target);
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to change modes for any channel.\n"
- "Parameters are the same as for the standard /MODE command.\n"
- "Alternatively, CLEAR may be given to clear all modes on the channel.\n"
- "If CLEAR ALL is given then all modes, including user status, is removed."));
- return true;
- }
-};
-
-class CommandOSUMode : public Command
-{
- public:
- CommandOSUMode(Module *creator) : Command(creator, "operserv/umode", 2, 2)
- {
- this->SetDesc(_("Change user modes"));
- this->SetSyntax(_("\037user\037 \037modes\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &target = params[0];
- const Anope::string &modes = params[1];
-
- User *u2 = User::Find(target, true);
- if (!u2)
- source.Reply(NICK_X_NOT_IN_USE, target.c_str());
- else
- {
- u2->SetModes(source.service, "%s", modes.c_str());
- source.Reply(_("Changed usermodes of \002%s\002 to %s."), u2->nick.c_str(), modes.c_str());
-
- u2->SendMessage(source.service, _("\002%s\002 changed your usermodes to %s."), source.GetNick().c_str(), modes.c_str());
-
- Log(LOG_ADMIN, source, this) << modes << " on " << target;
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to change modes for any user.\n"
- "Parameters are the same as for the standard /MODE command."));
- return true;
- }
-};
-
-class OSMode : public Module
-{
- CommandOSMode commandosmode;
- CommandOSUMode commandosumode;
-
- public:
- OSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosmode(this), commandosumode(this)
- {
-
- }
-};
-
-MODULE_INIT(OSMode)
diff --git a/modules/commands/os_modinfo.cpp b/modules/commands/os_modinfo.cpp
deleted file mode 100644
index b1f0c7470..000000000
--- a/modules/commands/os_modinfo.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSModInfo : public Command
-{
- public:
- CommandOSModInfo(Module *creator) : Command(creator, "operserv/modinfo", 1, 1)
- {
- this->SetDesc(_("Info about a loaded module"));
- this->SetSyntax(_("\037modname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &file = params[0];
-
- Log(LOG_ADMIN, source, this) << "on " << file;
-
- Module *m = ModuleManager::FindModule(file);
- if (m)
- {
- source.Reply(_("Module: \002%s\002 Version: \002%s\002 Author: \002%s\002 Loaded: \002%s\002"), m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "Unknown", Anope::strftime(m->created, source.GetAccount()).c_str());
- if (Anope::Debug)
- source.Reply(_(" Loaded at: %p"), m->handle);
-
- std::vector<Anope::string> servicekeys = Service::GetServiceKeys("Command");
- for (unsigned i = 0; i < servicekeys.size(); ++i)
- {
- ServiceReference<Command> c("Command", servicekeys[i]);
- if (!c || c->owner != m)
- continue;
-
- source.Reply(_(" Providing service: \002%s\002"), c->name.c_str());
-
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
- {
- const BotInfo *bi = it->second;
-
- for (CommandInfo::map::const_iterator cit = bi->commands.begin(), cit_end = bi->commands.end(); cit != cit_end; ++cit)
- {
- const Anope::string &c_name = cit->first;
- const CommandInfo &info = cit->second;
- if (info.name != c->name)
- continue;
- source.Reply(_(" Command \002%s\002 on \002%s\002 is linked to \002%s\002"), c_name.c_str(), bi->nick.c_str(), c->name.c_str());
- }
- }
- }
- }
- else
- source.Reply(_("No information about module \002%s\002 is available."), file.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command lists information about the specified loaded module."));
- return true;
- }
-};
-
-class CommandOSModList : public Command
-{
- public:
- CommandOSModList(Module *creator) : Command(creator, "operserv/modlist", 0, 1)
- {
- this->SetDesc(_("List loaded modules"));
- this->SetSyntax("[all|third|vendor|extra|database|encryption|pseudoclient|protocol]");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &param = !params.empty() ? params[0] : "";
-
- if (!param.empty())
- Log(LOG_ADMIN, source, this) << "for " << param;
- else
- Log(LOG_ADMIN, source, this);
-
- bool third = false, vendor = false, extra = false, database = false, encryption = false, pseudoclient = false, protocol = false;
-
- if (param.equals_ci("all"))
- third = vendor = extra = database = encryption = pseudoclient = protocol = true;
- else if (param.equals_ci("third"))
- third = true;
- else if (param.equals_ci("vendor"))
- vendor = true;
- else if (param.equals_ci("extra"))
- extra = true;
- else if (param.equals_ci("database"))
- database = true;
- else if (param.equals_ci("encryption"))
- encryption = true;
- else if (param.equals_ci("pseudoclient"))
- pseudoclient = true;
- else if (param.equals_ci("protocol"))
- protocol = true;
- else
- third = extra = database = encryption = protocol = true;
-
- Module *protomod = ModuleManager::FindFirstOf(PROTOCOL);
-
- source.Reply(_("Current module list:"));
-
- int count = 0;
- for (std::list<Module *>::iterator it = ModuleManager::Modules.begin(), it_end = ModuleManager::Modules.end(); it != it_end; ++it)
- {
- Module *m = *it;
-
- bool show = false;
- Anope::string mtype;
-
- if (m->type & PROTOCOL)
- {
- show |= protocol;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Protocol";
- }
- if (m->type & PSEUDOCLIENT)
- {
- show |= pseudoclient;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Pseudoclient";
- }
- if (m->type & ENCRYPTION)
- {
- show |= encryption;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Encryption";
- }
- if (m->type & DATABASE)
- {
- show |= database;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Database";
- }
- if (m->type & EXTRA)
- {
- show |= extra;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Extra";
- }
- if (m->type & VENDOR)
- {
- show |= vendor;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Vendor";
- }
- if (m->type & THIRD)
- {
- show |= third;
- if (!mtype.empty())
- mtype += ", ";
- mtype += "Third";
- }
-
- if (!show)
- continue;
- else if (m->type & PROTOCOL && param.empty() && m != protomod)
- continue;
-
- ++count;
-
- source.Reply(_("Module: \002%s\002 [%s] [%s]"), m->name.c_str(), m->version.c_str(), mtype.c_str());
- }
-
- if (!count)
- source.Reply(_("No modules currently loaded matching that criteria."));
- else
- source.Reply(_("%d modules loaded."), count);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Lists currently loaded modules."));
- return true;
- }
-};
-
-class OSModInfo : public Module
-{
- CommandOSModInfo commandosmodinfo;
- CommandOSModList commandosmodlist;
-
- public:
- OSModInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosmodinfo(this), commandosmodlist(this)
- {
-
- }
-};
-
-MODULE_INIT(OSModInfo)
diff --git a/modules/commands/os_module.cpp b/modules/commands/os_module.cpp
deleted file mode 100644
index f271ed2c9..000000000
--- a/modules/commands/os_module.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSModLoad : public Command
-{
- public:
- CommandOSModLoad(Module *creator) : Command(creator, "operserv/modload", 1, 1)
- {
- this->SetDesc(_("Load a module"));
- this->SetSyntax(_("\037modname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &mname = params[0];
-
- ModuleReturn status = ModuleManager::LoadModule(mname, source.GetUser());
- if (status == MOD_ERR_OK)
- {
- Log(LOG_ADMIN, source, this) << "to load module " << mname;
- source.Reply(_("Module \002%s\002 loaded."), mname.c_str());
- }
- else if (status == MOD_ERR_EXISTS)
- source.Reply(_("Module \002%s\002 is already loaded."), mname.c_str());
- else
- source.Reply(_("Unable to load module \002%s\002."), mname.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command loads the module named \037modname\037 from the modules\n"
- "directory."));
- return true;
- }
-};
-
-class CommandOSModReLoad : public Command
-{
- public:
- CommandOSModReLoad(Module *creator) : Command(creator, "operserv/modreload", 1, 1)
- {
- this->SetDesc(_("Reload a module"));
- this->SetSyntax(_("\037modname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &mname = params[0];
-
- Module *m = ModuleManager::FindModule(mname);
- if (!m)
- {
- source.Reply(_("Module \002%s\002 isn't loaded."), mname.c_str());
- return;
- }
-
- if (!m->handle || m->GetPermanent())
- {
- source.Reply(_("Unable to remove module \002%s\002."), m->name.c_str());
- return;
- }
-
- Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
- if (m->type == PROTOCOL && m != protocol)
- {
- source.Reply(_("You can not reload this module directly, instead reload %s."), protocol ? protocol->name.c_str() : "(unknown)");
- return;
- }
-
- /* Unrecoverable */
- bool fatal = m->type == PROTOCOL;
- ModuleReturn status = ModuleManager::UnloadModule(m, source.GetUser());
-
- if (status != MOD_ERR_OK)
- {
- source.Reply(_("Unable to remove module \002%s\002."), mname.c_str());
- return;
- }
-
- status = ModuleManager::LoadModule(mname, source.GetUser());
- if (status == MOD_ERR_OK)
- {
- Log(LOG_ADMIN, source, this) << "to reload module " << mname;
- source.Reply(_("Module \002%s\002 reloaded."), mname.c_str());
- }
- else
- {
- if (fatal)
- {
- Anope::QuitReason = "Unable to reload module " + mname;
- Anope::Quitting = true;
- }
- else
- source.Reply(_("Unable to load module \002%s\002."), mname.c_str());
- }
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command reloads the module named \037modname\037."));
- return true;
- }
-};
-
-class CommandOSModUnLoad : public Command
-{
- public:
- CommandOSModUnLoad(Module *creator) : Command(creator, "operserv/modunload", 1, 1)
- {
- this->SetDesc(_("Un-Load a module"));
- this->SetSyntax(_("\037modname\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &mname = params[0];
-
- Module *m = ModuleManager::FindModule(mname);
- if (!m)
- {
- source.Reply(_("Module \002%s\002 isn't loaded."), mname.c_str());
- return;
- }
-
- if (!m->handle || m->GetPermanent() || m->type == PROTOCOL)
- {
- source.Reply(_("Unable to remove module \002%s\002."), m->name.c_str());
- return;
- }
-
- Log(this->owner) << "Trying to unload module [" << mname << "]";
-
- ModuleReturn status = ModuleManager::UnloadModule(m, source.GetUser());
-
- if (status == MOD_ERR_OK)
- {
- Log(LOG_ADMIN, source, this) << "to unload module " << mname;
- source.Reply(_("Module \002%s\002 unloaded."), mname.c_str());
- }
- else
- source.Reply(_("Unable to remove module \002%s\002."), mname.c_str());
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("This command unloads the module named \037modname\037."));
- return true;
- }
-};
-
-class OSModule : public Module
-{
- CommandOSModLoad commandosmodload;
- CommandOSModReLoad commandosmodreload;
- CommandOSModUnLoad commandosmodunload;
-
- public:
- OSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosmodload(this), commandosmodreload(this), commandosmodunload(this)
- {
- this->SetPermanent(true);
-
- }
-};
-
-MODULE_INIT(OSModule)
diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp
deleted file mode 100644
index a35a74584..000000000
--- a/modules/commands/os_news.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 "modules/os_news.h"
-
-/* List of messages for each news type. This simplifies message sending. */
-
-enum
-{
- MSG_SYNTAX,
- MSG_LIST_HEADER,
- MSG_LIST_NONE,
- MSG_ADDED,
- MSG_DEL_NOT_FOUND,
- MSG_DELETED,
- MSG_DEL_NONE,
- MSG_DELETED_ALL
-};
-
-struct NewsMessages msgarray[] = {
- {NEWS_LOGON, "LOGON",
- {_("LOGONNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
- _("Logon news items:"),
- _("There is no logon news."),
- _("Added new logon news item."),
- _("Logon news item #%s not found!"),
- _("Logon news item #%d deleted."),
- _("No logon news items to delete!"),
- _("All logon news items deleted.")}
- },
- {NEWS_OPER, "OPER",
- {_("OPERNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
- _("Oper news items:"),
- _("There is no oper news."),
- _("Added new oper news item."),
- _("Oper news item #%s not found!"),
- _("Oper news item #%d deleted."),
- _("No oper news items to delete!"),
- _("All oper news items deleted.")}
- },
- {NEWS_RANDOM, "RANDOM",
- {_("RANDOMNEWS {ADD|DEL|LIST} [\037text\037|\037num\037]\002"),
- _("Random news items:"),
- _("There is no random news."),
- _("Added new random news item."),
- _("Random news item #%s not found!"),
- _("Random news item #%d deleted."),
- _("No random news items to delete!"),
- _("All random news items deleted.")}
- }
-};
-
-struct MyNewsItem : NewsItem
-{
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["type"] << this->type;
- data["text"] << this->text;
- data["who"] << this->who;
- data["time"] << this->time;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- if (!news_service)
- return NULL;
-
- NewsItem *ni;
- if (obj)
- ni = anope_dynamic_static_cast<NewsItem *>(obj);
- else
- ni = new MyNewsItem();
-
- unsigned int t;
- data["type"] >> t;
- ni->type = static_cast<NewsType>(t);
- data["text"] >> ni->text;
- data["who"] >> ni->who;
- data["time"] >> ni->time;
-
- if (!obj)
- news_service->AddNewsItem(ni);
- return ni;
- }
-};
-
-class MyNewsService : public NewsService
-{
- std::vector<NewsItem *> newsItems[3];
- public:
- MyNewsService(Module *m) : NewsService(m) { }
-
- ~MyNewsService()
- {
- for (unsigned i = 0; i < 3; ++i)
- for (unsigned j = 0; j < newsItems[i].size(); ++j)
- delete newsItems[i][j];
- }
-
- NewsItem *CreateNewsItem() anope_override
- {
- return new MyNewsItem();
- }
-
- void AddNewsItem(NewsItem *n)
- {
- this->newsItems[n->type].push_back(n);
- }
-
- void DelNewsItem(NewsItem *n)
- {
- std::vector<NewsItem *> &list = this->GetNewsList(n->type);
- std::vector<NewsItem *>::iterator it = std::find(list.begin(), list.end(), n);
- if (it != list.end())
- list.erase(it);
- delete n;
- }
-
- std::vector<NewsItem *> &GetNewsList(NewsType t)
- {
- return this->newsItems[t];
- }
-};
-
-#define lenof(a) (sizeof(a) / sizeof(*(a)))
-static const char **findmsgs(NewsType type)
-{
- for (unsigned i = 0; i < lenof(msgarray); ++i)
- if (msgarray[i].type == type)
- return msgarray[i].msgs;
- return NULL;
-}
-
-class NewsBase : public Command
-{
- ServiceReference<NewsService> ns;
-
- protected:
- void DoList(CommandSource &source, NewsType ntype, const char **msgs)
- {
- std::vector<NewsItem *> &list = this->ns->GetNewsList(ntype);
- if (list.empty())
- source.Reply(msgs[MSG_LIST_NONE]);
- else
- {
- ListFormatter lflist(source.GetAccount());
- lflist.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Text"));
-
- for (unsigned i = 0, end = list.size(); i < end; ++i)
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Creator"] = list[i]->who;
- entry["Created"] = Anope::strftime(list[i]->time, NULL, true);
- entry["Text"] = list[i]->text;
- lflist.AddEntry(entry);
- }
-
- source.Reply(msgs[MSG_LIST_HEADER]);
-
- std::vector<Anope::string> replies;
- lflist.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
-
- source.Reply(_("End of news list."));
- }
-
- return;
- }
-
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype, const char **msgs)
- {
- const Anope::string text = params.size() > 1 ? params[1] : "";
-
- if (text.empty())
- this->OnSyntaxError(source, "ADD");
- else
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- NewsItem *news = new MyNewsItem();
- news->type = ntype;
- news->text = text;
- news->time = Anope::CurTime;
- news->who = source.GetNick();
-
- this->ns->AddNewsItem(news);
-
- source.Reply(msgs[MSG_ADDED]);
- Log(LOG_ADMIN, source, this) << "to add a news item";
- }
-
- return;
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype, const char **msgs)
- {
- const Anope::string &text = params.size() > 1 ? params[1] : "";
-
- if (text.empty())
- this->OnSyntaxError(source, "DEL");
- else
- {
- std::vector<NewsItem *> &list = this->ns->GetNewsList(ntype);
- if (list.empty())
- source.Reply(msgs[MSG_LIST_NONE]);
- else
- {
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- if (!text.equals_ci("ALL"))
- {
- try
- {
- unsigned num = convertTo<unsigned>(text);
- if (num > 0 && num <= list.size())
- {
- this->ns->DelNewsItem(list[num - 1]);
- source.Reply(msgs[MSG_DELETED], num);
- Log(LOG_ADMIN, source, this) << "to delete a news item";
- return;
- }
- }
- catch (const ConvertException &) { }
-
- source.Reply(msgs[MSG_DEL_NOT_FOUND], text.c_str());
- }
- else
- {
- for (unsigned i = list.size(); i > 0; --i)
- this->ns->DelNewsItem(list[i - 1]);
- source.Reply(msgs[MSG_DELETED_ALL]);
- Log(LOG_ADMIN, source, this) << "to delete all news items";
- }
- }
- }
-
- return;
- }
-
- void DoNews(CommandSource &source, const std::vector<Anope::string> &params, NewsType ntype)
- {
- if (!this->ns)
- return;
-
- const Anope::string &cmd = params[0];
-
- const char **msgs = findmsgs(ntype);
- if (!msgs)
- throw CoreException("news: Invalid type to do_news()");
-
- if (cmd.equals_ci("LIST"))
- return this->DoList(source, ntype, msgs);
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params, ntype, msgs);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params, ntype, msgs);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
- public:
- NewsBase(Module *creator, const Anope::string &newstype) : Command(creator, newstype, 1, 2), ns("NewsService", "news")
- {
- this->SetSyntax(_("ADD \037text\037"));
- this->SetSyntax(_("DEL {\037num\037 | ALL}"));
- this->SetSyntax("LIST");
- }
-
- virtual ~NewsBase()
- {
- }
-
- virtual void Execute(CommandSource &source, const std::vector<Anope::string> &params) = 0;
-
- virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) = 0;
-};
-
-class CommandOSLogonNews : public NewsBase
-{
- public:
- CommandOSLogonNews(Module *creator) : NewsBase(creator, "operserv/logonnews")
- {
- this->SetDesc(_("Define messages to be shown to users at logon"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- return this->DoNews(source, params, NEWS_LOGON);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Edits or displays the list of logon news messages. When a\n"
- "user connects to the network, these messages will be sent\n"
- "to them. However, no more than \002%d\002 messages will be\n"
- "sent in order to avoid flooding the user. If there are\n"
- "more news messages, only the most recent will be sent."),
- Config->GetModule(this->owner)->Get<unsigned>("newscount", "3"));
- return true;
- }
-};
-
-class CommandOSOperNews : public NewsBase
-{
- public:
- CommandOSOperNews(Module *creator) : NewsBase(creator, "operserv/opernews")
- {
- this->SetDesc(_("Define messages to be shown to users who oper"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- return this->DoNews(source, params, NEWS_OPER);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Edits or displays the list of oper news messages. When a\n"
- "user opers up (with the /OPER command), these messages will\n"
- "be sent to them. However, no more than \002%d\002 messages will\n"
- "be sent in order to avoid flooding the user. If there are\n"
- "more news messages, only the most recent will be sent."),
- Config->GetModule(this->owner)->Get<unsigned>("newscount", "3"));
- return true;
- }
-};
-
-class CommandOSRandomNews : public NewsBase
-{
- public:
- CommandOSRandomNews(Module *creator) : NewsBase(creator, "operserv/randomnews")
- {
- this->SetDesc(_("Define messages to be randomly shown to users at logon"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- return this->DoNews(source, params, NEWS_RANDOM);
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Edits or displays the list of random news messages. When a\n"
- "user connects to the network, one (and only one) of the\n"
- "random news will be randomly chosen and sent to them."));
- return true;
- }
-};
-
-static unsigned cur_rand_news = 0;
-
-class OSNews : public Module
-{
- MyNewsService newsservice;
- Serialize::Type newsitem_type;
-
- CommandOSLogonNews commandoslogonnews;
- CommandOSOperNews commandosopernews;
- CommandOSRandomNews commandosrandomnews;
-
- Anope::string oper_announcer, announcer;
- unsigned news_count;
-
- void DisplayNews(User *u, NewsType Type)
- {
- std::vector<NewsItem *> &newsList = this->newsservice.GetNewsList(Type);
- if (newsList.empty())
- return;
-
- BotInfo *bi = NULL;
- if (Type == NEWS_OPER)
- bi = BotInfo::Find(Config->GetModule(this)->Get<const Anope::string>("oper_announcer", "OperServ"), true);
- else
- bi = BotInfo::Find(Config->GetModule(this)->Get<const Anope::string>("announcer", "Global"), true);
- if (bi == NULL)
- return;
-
- Anope::string msg;
- if (Type == NEWS_LOGON)
- msg = _("[\002Logon News\002 - %s] %s");
- else if (Type == NEWS_OPER)
- msg = _("[\002Oper News\002 - %s] %s");
- else if (Type == NEWS_RANDOM)
- msg = _("[\002Random News\002 - %s] %s");
-
- int start = 0;
-
- if (Type != NEWS_RANDOM)
- {
- start = newsList.size() - news_count;
- if (start < 0)
- start = 0;
- }
-
- for (unsigned i = start, end = newsList.size(); i < end; ++i)
- {
- if (Type == NEWS_RANDOM && i != cur_rand_news)
- continue;
-
- u->SendMessage(bi, msg.c_str(), Anope::strftime(newsList[i]->time, u->Account(), true).c_str(), newsList[i]->text.c_str());
-
- if (Type == NEWS_RANDOM)
- {
- ++cur_rand_news;
- break;
- }
- }
-
- /* Reset to head of list to get first random news value */
- if (Type == NEWS_RANDOM && cur_rand_news >= newsList.size())
- cur_rand_news = 0;
- }
-
- public:
- OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- newsservice(this), newsitem_type("NewsItem", MyNewsItem::Unserialize),
- commandoslogonnews(this), commandosopernews(this), commandosrandomnews(this)
- {
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- oper_announcer = conf->GetModule(this)->Get<const Anope::string>("oper_announcer", "OperServ");
- announcer = conf->GetModule(this)->Get<const Anope::string>("announcer", "Global");
- news_count = conf->GetModule(this)->Get<unsigned>("newscount", "3");
- }
-
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
- {
- if (mname == "OPER")
- DisplayNews(u, NEWS_OPER);
- }
-
- void OnUserConnect(User *user, bool &) anope_override
- {
- if (user->Quitting() || !user->server->IsSynced())
- return;
-
- DisplayNews(user, NEWS_LOGON);
- DisplayNews(user, NEWS_RANDOM);
- }
-};
-
-MODULE_INIT(OSNews)
diff --git a/modules/commands/os_noop.cpp b/modules/commands/os_noop.cpp
deleted file mode 100644
index c0beb678a..000000000
--- a/modules/commands/os_noop.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSNOOP : public Command
-{
- public:
- CommandOSNOOP(Module *creator) : Command(creator, "operserv/noop", 2, 2)
- {
- this->SetDesc(_("Remove all operators from a server remotely"));
- this->SetSyntax(_("SET \037server\037"));
- this->SetSyntax(_("REVOKE \037server\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
- const Anope::string &server = params[1];
-
- Server *s = Server::Find(server, true);
- if (s == NULL)
- source.Reply(_("Server %s does not exist."), server.c_str());
- else if (s == Me || s->IsJuped())
- source.Reply(_("You can not NOOP Services."));
- else if (cmd.equals_ci("SET"))
- {
- /* Remove the O:lines */
- IRCD->SendSVSNOOP(s, true);
- s->Extend<Anope::string>("noop", source.GetNick());
-
- Log(LOG_ADMIN, source, this) << "SET on " << s->GetName();
- source.Reply(_("All operators from \002%s\002 have been removed."), s->GetName().c_str());
-
- Anope::string reason = "NOOP command used by " + source.GetNick();
- /* Kill all the IRCops of the server */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u2 = it->second;
-
- if (u2->server == s && u2->HasMode("OPER"))
- u2->Kill(*source.service, reason);
- }
- }
- else if (cmd.equals_ci("REVOKE"))
- {
- s->Shrink<Anope::string>("noop");
- IRCD->SendSVSNOOP(s, false);
- Log(LOG_ADMIN, source, this) << "REVOKE on " << s->GetName();
- source.Reply(_("All O:lines of \002%s\002 have been reset."), s->GetName().c_str());
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("\002SET\002 kills all operators from the given\n"
- "\002server\002 and prevents operators from opering\n"
- "up on the given server. \002REVOKE\002 removes this\n"
- "restriction."));
- return true;
- }
-};
-
-class OSNOOP : public Module
-{
- CommandOSNOOP commandosnoop;
- PrimitiveExtensibleItem<Anope::string> noop;
-
- public:
- OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosnoop(this), noop(this, "noop")
- {
-
- }
-
- void OnUserModeSet(const MessageSource &, User *u, const Anope::string &mname) anope_override
- {
- Anope::string *setter;
- if (mname == "OPER" && (setter = noop.Get(u->server)))
- {
- Anope::string reason = "NOOP command used by " + *setter;
- BotInfo *OperServ = Config->GetClient("OperServ");
- u->Kill(OperServ, reason);
- }
- }
-};
-
-MODULE_INIT(OSNOOP)
diff --git a/modules/commands/os_oline.cpp b/modules/commands/os_oline.cpp
deleted file mode 100644
index 5270d3f78..000000000
--- a/modules/commands/os_oline.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSOLine : public Command
-{
- public:
- CommandOSOLine(Module *creator) : Command(creator, "operserv/oline", 2, 2)
- {
- this->SetDesc(_("Give Operflags to a certain user"));
- this->SetSyntax(_("\037nick\037 \037flags\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- const Anope::string &flag = params[1];
- User *u2 = NULL;
-
- /* let's check whether the user is online */
- if (!(u2 = User::Find(nick, true)))
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- else if (u2 && flag[0] == '+')
- {
- IRCD->SendSVSO(source.service, nick, flag);
- u2->SetMode(source.service, "OPER");
- u2->SendMessage(source.service, _("You are now an IRC Operator."));
- source.Reply(_("Operflags \002%s\002 have been added for \002%s\002."), flag.c_str(), nick.c_str());
- Log(LOG_ADMIN, source, this) << "for " << nick;
- }
- else if (u2 && flag[0] == '-')
- {
- IRCD->SendSVSO(source.service, nick, flag);
- source.Reply(_("Operflags \002%s\002 have been removed from \002%s\002."), flag.c_str(), nick.c_str());
- Log(LOG_ADMIN, source, this) << "for " << nick;
- }
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to give Operflags to any user.\n"
- "Flags have to be prefixed with a \"+\" or a \"-\". To\n"
- "remove all flags simply type a \"-\" instead of any flags."));
- return true;
- }
-};
-
-class OSOLine : public Module
-{
- CommandOSOLine commandosoline;
-
- public:
- OSOLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosoline(this)
- {
-
- if (!IRCD || !IRCD->CanSVSO)
- throw ModuleException("Your IRCd does not support OMODE.");
-
- }
-};
-
-MODULE_INIT(OSOLine)
diff --git a/modules/commands/os_oper.cpp b/modules/commands/os_oper.cpp
deleted file mode 100644
index f5ac80160..000000000
--- a/modules/commands/os_oper.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-struct MyOper : Oper, Serializable
-{
- MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["name"] << this->name;
- data["type"] << this->ot->GetName();
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- Anope::string stype, sname;
-
- data["type"] >> stype;
- data["name"] >> sname;
-
- OperType *ot = OperType::Find(stype);
- if (ot == NULL)
- return NULL;
- NickCore *nc = NickCore::Find(sname);
- if (nc == NULL)
- return NULL;
-
- MyOper *myo;
- if (obj)
- myo = anope_dynamic_static_cast<MyOper *>(obj);
- else
- myo = new MyOper(nc->display, ot);
- nc->o = myo;
- Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
- return myo;
- }
-};
-
-class CommandOSOper : public Command
-{
- bool HasPrivs(CommandSource &source, OperType *ot) const
- {
- std::list<Anope::string> commands = ot->GetCommands(), privs = ot->GetPrivs();
-
- for (std::list<Anope::string>::iterator it = commands.begin(); it != commands.end(); ++it)
- if (!source.HasCommand(*it))
- return false;
-
- for (std::list<Anope::string>::iterator it = privs.begin(); it != privs.end(); ++it)
- if (!source.HasPriv(*it))
- return false;
-
- return true;
- }
-
- public:
- CommandOSOper(Module *creator) : Command(creator, "operserv/oper", 1, 3)
- {
- this->SetDesc(_("View and change Services Operators"));
- this->SetSyntax(_("ADD \037oper\037 \037type\037"));
- this->SetSyntax(_("DEL \037oper\037"));
- this->SetSyntax(_("INFO [\037type\037]"));
- this->SetSyntax("LIST");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcommand = params[0];
-
- if (subcommand.equals_ci("ADD") && params.size() > 2)
- {
- const Anope::string &oper = params[1];
- const Anope::string &otype = params[2];
-
- if (!source.HasPriv("operserv/oper/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(oper);
- if (na == NULL)
- source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
- else if (na->nc->o)
- source.Reply(_("Nick \002%s\002 is already an operator."), na->nick.c_str());
- else
- {
- OperType *ot = OperType::Find(otype);
- if (ot == NULL)
- {
- source.Reply(_("Oper type \002%s\002 has not been configured."), otype.c_str());
- return;
- }
-
- if (!HasPrivs(source, ot))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- na->nc->o = new MyOper(na->nc->display, ot);
- na->nc->o->require_oper = true;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "ADD " << na->nick << " as type " << ot->GetName();
- source.Reply("%s (%s) added to the \002%s\002 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str());
- }
- }
- else if (subcommand.equals_ci("DEL") && params.size() > 1)
- {
- const Anope::string &oper = params[1];
-
- if (!source.HasPriv("operserv/oper/modify"))
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- const NickAlias *na = NickAlias::Find(oper);
- if (na == NULL)
- source.Reply(NICK_X_NOT_REGISTERED, oper.c_str());
- else if (!na->nc || !na->nc->o)
- source.Reply(_("Nick \002%s\002 is not a Services Operator."), oper.c_str());
- else if (!HasPrivs(source, na->nc->o->ot))
- source.Reply(ACCESS_DENIED);
- else if (std::find(Config->Opers.begin(), Config->Opers.end(), na->nc->o) != Config->Opers.end())
- source.Reply(_("Oper \002%s\002 is configured in the configuration file(s) and can not be removed by this command."), na->nc->display.c_str());
- else
- {
- delete na->nc->o;
- na->nc->o = NULL;
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- Log(LOG_ADMIN, source, this) << "DEL " << na->nick;
- source.Reply(_("Oper privileges removed from %s (%s)."), na->nick.c_str(), na->nc->display.c_str());
- }
- }
- else if (subcommand.equals_ci("LIST"))
- {
- source.Reply(_("Name Type"));
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- const NickCore *nc = it->second;
-
- if (!nc->o)
- continue;
-
- source.Reply(_("%-8s %s"), nc->o->name.c_str(), nc->o->ot->GetName().c_str());
- if (std::find(Config->Opers.begin(), Config->Opers.end(), nc->o) != Config->Opers.end())
- source.Reply(_(" This oper is configured in the configuration file."));
- for (std::list<User *>::const_iterator uit = nc->users.begin(); uit != nc->users.end(); ++uit)
- {
- User *u = *uit;
- source.Reply(_(" %s is online using this oper block."), u->nick.c_str());
- }
- }
- }
- else if (subcommand.equals_ci("INFO"))
- {
- if (params.size() < 2)
- {
- source.Reply(_("Available opertypes:"));
- for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
- {
- OperType *ot = Config->MyOperTypes[i];
- source.Reply("%s", ot->GetName().c_str());
- }
- return;
- }
-
- Anope::string fulltype = params[1];
- if (params.size() > 2)
- fulltype += " " + params[2];
- OperType *ot = OperType::Find(fulltype);
- if (ot == NULL)
- source.Reply(_("Oper type \002%s\002 has not been configured."), fulltype.c_str());
- else
- {
- if (ot->GetCommands().empty())
- source.Reply(_("Opertype \002%s\002 has no allowed commands."), ot->GetName().c_str());
- else
- {
- source.Reply(_("Available commands for \002%s\002:"), ot->GetName().c_str());
- Anope::string buf;
- std::list<Anope::string> cmds = ot->GetCommands();
- for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it)
- {
- buf += *it + " ";
- if (buf.length() > 400)
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (!buf.empty())
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (ot->GetPrivs().empty())
- source.Reply(_("Opertype \002%s\002 has no allowed privileges."), ot->GetName().c_str());
- else
- {
- source.Reply(_("Available privileges for \002%s\002:"), ot->GetName().c_str());
- Anope::string buf;
- std::list<Anope::string> privs = ot->GetPrivs();
- for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it)
- {
- buf += *it + " ";
- if (buf.length() > 400)
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (!buf.empty())
- {
- source.Reply("%s", buf.c_str());
- buf.clear();
- }
- }
- if (!ot->modes.empty())
- source.Reply(_("Opertype \002%s\002 receives modes \002%s\002 once identified."), ot->GetName().c_str(), ot->modes.c_str());
- }
- }
- else
- this->OnSyntaxError(source, subcommand);
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows you to change and view Services Operators.\n"
- "Note that operators removed by this command but are still set in\n"
- "the configuration file are not permanently affected by this."));
- return true;
- }
-};
-
-class OSOper : public Module
-{
- Serialize::Type myoper_type;
- CommandOSOper commandosoper;
-
- public:
- OSOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- myoper_type("Oper", MyOper::Unserialize), commandosoper(this)
- {
- }
-
- ~OSOper()
- {
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
- {
- NickCore *nc = it->second;
-
- if (nc->o && dynamic_cast<MyOper *>(nc->o))
- {
- delete nc->o;
- nc->o = NULL;
- }
- }
- }
-
- void OnDelCore(NickCore *nc) anope_override
- {
- if (nc->o && dynamic_cast<MyOper *>(nc->o))
- {
- delete nc->o;
- nc->o = NULL;
- }
- }
-};
-
-MODULE_INIT(OSOper)
diff --git a/modules/commands/os_reload.cpp b/modules/commands/os_reload.cpp
deleted file mode 100644
index 1ab3c3c87..000000000
--- a/modules/commands/os_reload.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSReload : public Command
-{
- public:
- CommandOSReload(Module *creator) : Command(creator, "operserv/reload", 0, 0)
- {
- this->SetDesc(_("Reload services' configuration file"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- try
- {
- Log(LOG_ADMIN, source, this);
-
- Configuration::Conf *new_config = new Configuration::Conf();
- Configuration::Conf *old = Config;
- Config = new_config;
- Config->Post(old);
- delete old;
-
- source.Reply(_("Services' configuration has been reloaded."));
- }
- catch (const ConfigException &ex)
- {
- Log(this->owner) << "Error reloading configuration file: " << ex.GetReason();
- source.Reply(_("Error reloading configuration file: %s"), ex.GetReason().c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to reload the configuration file. Note that\n"
- "some directives still need the restart of the Services to\n"
- "take effect (such as Services' nicknames, activation of the\n"
- "session limitation, etc.)."));
- return true;
- }
-};
-
-class OSReload : public Module
-{
- CommandOSReload commandosreload;
-
- public:
- OSReload(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosreload(this)
- {
-
- }
-};
-
-MODULE_INIT(OSReload)
diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp
deleted file mode 100644
index e8f1e241a..000000000
--- a/modules/commands/os_session.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 "modules/os_session.h"
-
-namespace
-{
- /* The default session limit */
- unsigned session_limit;
- /* How many times to kill before adding an AKILL */
- unsigned max_session_kill;
- /* How long session akills should last */
- time_t session_autokill_expiry;
- /* Reason to use for session kills */
- Anope::string sle_reason;
- /* Optional second reason */
- Anope::string sle_detailsloc;
-
- /* Max limit that can be used for exceptions */
- unsigned max_exception_limit;
- /* How long before exceptions expire by default */
- time_t exception_expiry;
-
- /* Number of bits to use when comparing session IPs */
- unsigned ipv4_cidr;
- unsigned ipv6_cidr;
-}
-
-class MySessionService : public SessionService
-{
- SessionMap Sessions;
- Serialize::Checker<ExceptionVector> Exceptions;
- public:
- MySessionService(Module *m) : SessionService(m), Exceptions("Exception") { }
-
- Exception *CreateException() anope_override
- {
- return new Exception();
- }
-
- void AddException(Exception *e) anope_override
- {
- this->Exceptions->push_back(e);
- }
-
- void DelException(Exception *e) anope_override
- {
- ExceptionVector::iterator it = std::find(this->Exceptions->begin(), this->Exceptions->end(), e);
- if (it != this->Exceptions->end())
- this->Exceptions->erase(it);
- }
-
- Exception *FindException(User *u) anope_override
- {
- for (std::vector<Exception *>::const_iterator it = this->Exceptions->begin(), it_end = this->Exceptions->end(); it != it_end; ++it)
- {
- Exception *e = *it;
- if (Anope::Match(u->host, e->mask) || Anope::Match(u->ip.addr(), e->mask))
- return e;
-
- if (cidr(e->mask).match(u->ip))
- return e;
- }
- return NULL;
- }
-
- Exception *FindException(const Anope::string &host) anope_override
- {
- for (std::vector<Exception *>::const_iterator it = this->Exceptions->begin(), it_end = this->Exceptions->end(); it != it_end; ++it)
- {
- Exception *e = *it;
- if (Anope::Match(host, e->mask))
- return e;
-
- if (cidr(e->mask).match(sockaddrs(host)))
- return e;
- }
-
- return NULL;
- }
-
- ExceptionVector &GetExceptions() anope_override
- {
- return this->Exceptions;
- }
-
- void DelSession(Session *s)
- {
- this->Sessions.erase(s->addr);
- }
-
- Session *FindSession(const Anope::string &ip) anope_override
- {
- cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
- if (!c.valid())
- return NULL;
- SessionMap::iterator it = this->Sessions.find(c);
- if (it != this->Sessions.end())
- return it->second;
- return NULL;
- }
-
- SessionMap::iterator FindSessionIterator(const sockaddrs &ip)
- {
- cidr c(ip, ip.ipv6() ? ipv6_cidr : ipv4_cidr);
- if (!c.valid())
- return this->Sessions.end();
- return this->Sessions.find(c);
- }
-
- Session* &FindOrCreateSession(const cidr &ip)
- {
- return this->Sessions[ip];
- }
-
- SessionMap &GetSessions() anope_override
- {
- return this->Sessions;
- }
-};
-
-class ExceptionDelCallback : public NumberList
-{
- protected:
- CommandSource &source;
- unsigned deleted;
- Command *cmd;
- public:
- ExceptionDelCallback(CommandSource &_source, const Anope::string &numlist, Command *c) : NumberList(numlist, true), source(_source), deleted(0), cmd(c)
- {
- }
-
- ~ExceptionDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on session-limit exception list."));
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from session-limit exception list."));
- else
- source.Reply(_("Deleted %d entries from session-limit exception list."), deleted);
- }
-
- virtual void HandleNumber(unsigned number) anope_override
- {
- if (!number || number > session_service->GetExceptions().size())
- return;
-
- Log(LOG_ADMIN, source, cmd) << "to remove the session limit exception for " << session_service->GetExceptions()[number - 1]->mask;
-
- ++deleted;
- DoDel(source, number - 1);
- }
-
- static void DoDel(CommandSource &source, unsigned index)
- {
- Exception *e = session_service->GetExceptions()[index];
- FOREACH_MOD(OnExceptionDel, (source, e));
-
- session_service->DelException(e);
- delete e;
- }
-};
-
-class CommandOSSession : public Command
-{
- private:
- void DoList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string param = params[1];
-
- unsigned mincount = 0;
- try
- {
- mincount = convertTo<unsigned>(param);
- }
- catch (const ConvertException &) { }
-
- if (mincount <= 1)
- source.Reply(_("Invalid threshold value. It must be a valid integer greater than 1."));
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Session")).AddColumn(_("Host"));
-
- for (SessionService::SessionMap::iterator it = session_service->GetSessions().begin(), it_end = session_service->GetSessions().end(); it != it_end; ++it)
- {
- Session *session = it->second;
-
- if (session->count >= mincount)
- {
- ListFormatter::ListEntry entry;
- entry["Session"] = stringify(session->count);
- entry["Host"] = session->addr.mask();
- list.AddEntry(entry);
- }
- }
-
- source.Reply(_("Hosts with at least \002%d\002 sessions:"), mincount);
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
-
- return;
- }
-
- void DoView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string param = params[1];
- Session *session = session_service->FindSession(param);
-
- Exception *exception = session_service->FindException(param);
- Anope::string entry = "no entry";
- unsigned limit = session_limit;
- if (exception)
- {
- if (!exception->limit)
- limit = 0;
- else if (exception->limit > limit)
- limit = exception->limit;
- entry = exception->mask;
- }
-
- if (!session)
- source.Reply(_("\002%s\002 not found on session list, but has a limit of \002%d\002 because it matches entry: \002%s\002."), param.c_str(), limit, entry.c_str());
- else
- source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002 because it matches entry: \002%s\002."), session->addr.mask().c_str(), session->count, limit, entry.c_str());
- }
- public:
- CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2)
- {
- this->SetDesc(_("View the list of host sessions"));
- this->SetSyntax(_("LIST \037threshold\037"));
- this->SetSyntax(_("VIEW \037host\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- Log(LOG_ADMIN, source, this) << cmd << " " << params[1];
-
- if (!session_limit)
- source.Reply(_("Session limiting is disabled."));
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->DoView(source, params);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to view the session list.\n"
- " \n"
- "\002SESSION LIST\002 lists hosts with at least \037threshold\037 sessions.\n"
- "The threshold must be a number greater than 1. This is to\n"
- "prevent accidental listing of the large number of single\n"
- "session hosts.\n"
- " \n"
- "\002SESSION VIEW\002 displays detailed information about a specific\n"
- "host - including the current session count and session limit.\n"
- "The \037host\037 value may not include wildcards.\n"
- " \n"
- "See the \002EXCEPTION\002 help for more information about session\n"
- "limiting and how to set session limits specific to certain\n"
- "hosts and groups thereof."));
- return true;
- }
-};
-
-class CommandOSException : public Command
-{
- private:
- void DoAdd(CommandSource &source, const std::vector<Anope::string> &params)
- {
- Anope::string mask, expiry, limitstr;
- unsigned last_param = 3;
-
- mask = params.size() > 1 ? params[1] : "";
- if (!mask.empty() && mask[0] == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2] : "";
- last_param = 4;
- }
-
- limitstr = params.size() > last_param - 1 ? params[last_param - 1] : "";
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string reason = params[last_param];
- if (last_param == 3 && params.size() > 4)
- reason += " " + params[4];
- if (reason.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : exception_expiry;
- if (expires < 0)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- unsigned limit = -1;
- try
- {
- limit = convertTo<unsigned>(limitstr);
- }
- catch (const ConvertException &) { }
-
- if (limit > max_exception_limit)
- {
- source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), max_exception_limit);
- return;
- }
- else
- {
- if (mask.find('!') != Anope::string::npos || mask.find('@') != Anope::string::npos)
- {
- source.Reply(_("Invalid hostmask. Only real hostmasks are valid, as exceptions are not matched against nicks or usernames."));
- return;
- }
-
- for (std::vector<Exception *>::iterator it = session_service->GetExceptions().begin(), it_end = session_service->GetExceptions().end(); it != it_end; ++it)
- {
- Exception *e = *it;
- if (e->mask.equals_ci(mask))
- {
- if (e->limit != limit)
- {
- e->limit = limit;
- source.Reply(_("Exception for \002%s\002 has been updated to %d."), mask.c_str(), e->limit);
- }
- else
- source.Reply(_("\002%s\002 already exists on the EXCEPTION list."), mask.c_str());
- return;
- }
- }
-
- Exception *exception = new Exception();
- exception->mask = mask;
- exception->limit = limit;
- exception->reason = reason;
- exception->time = Anope::CurTime;
- exception->who = source.GetNick();
- exception->expires = expires;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnExceptionAdd, MOD_RESULT, (exception));
- if (MOD_RESULT == EVENT_STOP)
- delete exception;
- else
- {
- Log(LOG_ADMIN, source, this) << "to set the session limit for " << mask << " to " << limit;
- session_service->AddException(exception);
- source.Reply(_("Session limit for \002%s\002 set to \002%d\002."), mask.c_str(), limit);
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
- }
-
- return;
- }
-
- void DoDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- ExceptionDelCallback list(source, mask, this);
- list.Process();
- }
- else
- {
- unsigned i = 0, end = session_service->GetExceptions().size();
- for (; i < end; ++i)
- if (mask.equals_ci(session_service->GetExceptions()[i]->mask))
- {
- Log(LOG_ADMIN, source, this) << "to remove the session limit exception for " << mask;
- ExceptionDelCallback::DoDel(source, i);
- source.Reply(_("\002%s\002 deleted from session-limit exception list."), mask.c_str());
- break;
- }
- if (i == end)
- source.Reply(_("\002%s\002 not found on session-limit exception list."), mask.c_str());
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
-
- void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (session_service->GetExceptions().empty())
- {
- source.Reply(_("The session exception list is empty."));
- return;
- }
-
- if (!mask.empty() && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class ExceptionListCallback : public NumberList
- {
- CommandSource &source;
- ListFormatter &list;
- public:
- ExceptionListCallback(CommandSource &_source, ListFormatter &_list, const Anope::string &numlist) : NumberList(numlist, false), source(_source), list(_list)
- {
- }
-
- void HandleNumber(unsigned Number) anope_override
- {
- if (!Number || Number > session_service->GetExceptions().size())
- return;
-
- Exception *e = session_service->GetExceptions()[Number - 1];
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(Number);
- entry["Mask"] = e->mask;
- entry["By"] = e->who;
- entry["Created"] = Anope::strftime(e->time, NULL, true);
- entry["Expires"] = Anope::Expires(e->expires, source.GetAccount());
- entry["Limit"] = stringify(e->limit);
- entry["Reason"] = e->reason;
- this->list.AddEntry(entry);
- }
- }
- nl_list(source, list, mask);
- nl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = session_service->GetExceptions().size(); i < end; ++i)
- {
- Exception *e = session_service->GetExceptions()[i];
- if (mask.empty() || Anope::Match(e->mask, mask))
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = e->mask;
- entry["By"] = e->who;
- entry["Created"] = Anope::strftime(e->time, NULL, true);
- entry["Expires"] = Anope::Expires(e->expires, source.GetAccount());
- entry["Limit"] = stringify(e->limit);
- entry["Reason"] = e->reason;
- list.AddEntry(entry);
- }
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on session-limit exception list."));
- else
- {
- source.Reply(_("Current Session Limit Exception list:"));
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void DoList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Limit")).AddColumn(_("Mask"));
-
- this->ProcessList(source, params, list);
- }
-
- void DoView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Created")).AddColumn(_("Expires")).AddColumn(_("Limit")).AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- public:
- CommandOSException(Module *creator) : Command(creator, "operserv/exception", 1, 5)
- {
- this->SetDesc(_("Modify the session-limit exception list"));
- this->SetSyntax(_("ADD [\037+expiry\037] \037mask\037 \037limit\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (!session_limit)
- source.Reply(_("Session limiting is disabled."));
- else if (cmd.equals_ci("ADD"))
- return this->DoAdd(source, params);
- else if (cmd.equals_ci("DEL"))
- return this->DoDel(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->DoList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->DoView(source, params);
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the list of hosts that\n"
- "have specific session limits - allowing certain machines,\n"
- "such as shell servers, to carry more than the default number\n"
- "of clients at a time. Once a host reaches its session limit,\n"
- "all clients attempting to connect from that host will be\n"
- "killed. Before the user is killed, they are notified, of a\n"
- "source of help regarding session limiting. The content of\n"
- "this notice is a config setting."));
- source.Reply(" ");
- source.Reply(_("\002EXCEPTION ADD\002 adds the given host mask to the exception list.\n"
- "Note that \002nick!user@host\002 and \002user@host\002 masks are invalid!\n"
- "Only real host masks, such as \002box.host.dom\002 and \002*.host.dom\002,\n"
- "are allowed because sessions limiting does not take nick or\n"
- "user names into account. \037limit\037 must be a number greater than\n"
- "or equal to zero. This determines how many sessions this host\n"
- "may carry at a time. A value of zero means the host has an\n"
- "unlimited session limit. See the \002AKILL\002 help for details about\n"
- "the format of the optional \037expiry\037 parameter.\n"
- " \n"
- "\002EXCEPTION DEL\002 removes the given mask from the exception list.\n"
- " \n"
- "\002EXCEPTION LIST\002 and \002EXCEPTION VIEW\002 show all current\n"
- "sessions if the optional mask is given, the list is limited\n"
- "to those sessions matching the mask. The difference is that\n"
- "\002EXCEPTION VIEW\002 is more verbose, displaying the name of the\n"
- "person who added the exception, its session limit, reason,\n"
- "host mask and the expiry date and time.\n"
- " \n"
- "Note that a connecting client will \"use\" the first exception\n"
- "their host matches."));
- return true;
- }
-};
-
-class OSSession : public Module
-{
- Serialize::Type exception_type;
- MySessionService ss;
- CommandOSSession commandossession;
- CommandOSException commandosexception;
- ServiceReference<XLineManager> akills;
-
- public:
- OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- exception_type("Exception", Exception::Unserialize), ss(this), commandossession(this), commandosexception(this), akills("XLineManager", "xlinemanager/sgline")
- {
- this->SetPermanent(true);
- }
-
- void Prioritize() anope_override
- {
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- Configuration::Block *block = Config->GetModule(this);
-
- session_limit = block->Get<int>("defaultsessionlimit");
- max_session_kill = block->Get<int>("maxsessionkill");
- session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
- sle_reason = block->Get<const Anope::string>("sessionlimitexceeded");
- sle_detailsloc = block->Get<const Anope::string>("sessionlimitdetailsloc");
-
- max_exception_limit = block->Get<int>("maxsessionlimit");
- exception_expiry = block->Get<time_t>("exceptionexpiry");
-
- ipv4_cidr = block->Get<unsigned>("session_ipv4_cidr", "32");
- ipv6_cidr = block->Get<unsigned>("session_ipv6_cidr", "128");
-
- if (ipv4_cidr > 32 || ipv6_cidr > 128)
- throw ConfigException(this->name + ": session CIDR value out of range");
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined())
- return;
-
- cidr u_ip(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr);
- if (!u_ip.valid())
- return;
-
- Session* &session = this->ss.FindOrCreateSession(u_ip);
-
- if (session)
- {
- bool kill = false;
- if (session->count >= session_limit)
- {
- kill = true;
- Exception *exception = this->ss.FindException(u);
- if (exception)
- {
- kill = false;
- if (exception->limit && session->count >= exception->limit)
- kill = true;
- }
- }
-
- /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
- * decremented in do_quit, which caused problems and fixed here
- *
- * Now, we create the user struture before calling this to fix some user tracking issues,
- * so we must increment this here no matter what because it will either be
- * decremented when the user is killed or quits - Adam
- */
- ++session->count;
-
- if (kill && !exempt)
- {
- BotInfo *OperServ = Config->GetClient("OperServ");
- if (OperServ)
- {
- if (!sle_reason.empty())
- {
- Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip.addr());
- u->SendMessage(OperServ, message);
- }
- if (!sle_detailsloc.empty())
- u->SendMessage(OperServ, sle_detailsloc);
- }
-
- ++session->hits;
-
- const Anope::string &akillmask = "*@" + session->addr.mask();
- if (max_session_kill && session->hits >= max_session_kill && akills && !akills->HasEntry(akillmask))
- {
- XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID());
- akills->AddXLine(x);
- akills->Send(NULL, x);
- Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
- }
- else
- {
- u->Kill(OperServ, "Session limit exceeded");
- }
- }
- }
- else
- {
- session = new Session(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr);
- }
- }
-
- void OnUserQuit(User *u, const Anope::string &msg) anope_override
- {
- if (!session_limit || !u->server || u->server->IsULined())
- return;
-
- SessionService::SessionMap &sessions = this->ss.GetSessions();
- SessionService::SessionMap::iterator sit = this->ss.FindSessionIterator(u->ip);
-
- if (sit == sessions.end())
- return;
-
- Session *session = sit->second;
-
- if (session->count > 1)
- {
- --session->count;
- return;
- }
-
- delete session;
- sessions.erase(sit);
- }
-
- void OnExpireTick() anope_override
- {
- if (Anope::NoExpire)
- return;
- for (unsigned i = this->ss.GetExceptions().size(); i > 0; --i)
- {
- Exception *e = this->ss.GetExceptions()[i - 1];
-
- if (!e->expires || e->expires > Anope::CurTime)
- continue;
- BotInfo *OperServ = Config->GetClient("OperServ");
- Log(OperServ, "expire/exception") << "Session exception for " << e->mask << " has expired.";
- this->ss.DelException(e);
- delete e;
- }
- }
-};
-
-MODULE_INIT(OSSession)
diff --git a/modules/commands/os_set.cpp b/modules/commands/os_set.cpp
deleted file mode 100644
index 5aca2f370..000000000
--- a/modules/commands/os_set.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSSet : public Command
-{
- private:
- void DoList(CommandSource &source)
- {
- Log(LOG_ADMIN, source, this) << "LIST";
-
- Anope::string index;
-
- index = Anope::ReadOnly ? _("%s is enabled") : _("%s is disabled");
- source.Reply(index.c_str(), "READONLY");
- index = Anope::Debug ? _("%s is enabled") : _("%s is disabled");
- source.Reply(index.c_str(), "DEBUG");
- index = Anope::NoExpire ? _("%s is enabled") : _("%s is disabled");
- source.Reply(index.c_str(), "NOEXPIRE");
-
- return;
- }
-
- void DoSetReadOnly(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &setting = params.size() > 1 ? params[1] : "";
-
- if (setting.empty())
- {
- this->OnSyntaxError(source, "READONLY");
- return;
- }
-
- if (setting.equals_ci("ON"))
- {
- Anope::ReadOnly = true;
- Log(LOG_ADMIN, source, this) << "READONLY ON";
- source.Reply(_("Services are now in \002read-only\002 mode."));
- }
- else if (setting.equals_ci("OFF"))
- {
- Anope::ReadOnly = false;
- Log(LOG_ADMIN, source, this) << "READONLY OFF";
- source.Reply(_("Services are now in \002read-write\002 mode."));
- }
- else
- source.Reply(_("Setting for READONLY must be \002ON\002 or \002OFF\002."));
-
- return;
- }
-
- void DoSetSuperAdmin(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &setting = params.size() > 1 ? params[1] : "";
-
- if (!source.GetUser())
- return;
-
- if (setting.empty())
- {
- this->OnSyntaxError(source, "SUPERADMIN");
- return;
- }
-
- /**
- * Allow the user to turn super admin on/off
- *
- * Rob
- **/
- bool super_admin = Config->GetModule(this->owner)->Get<bool>("superadmin");
- if (!super_admin)
- source.Reply(_("Super admin can not be set because it is not enabled in the configuration."));
- else if (setting.equals_ci("ON"))
- {
- source.GetUser()->super_admin = true;
- source.Reply(_("You are now a super admin."));
- Log(LOG_ADMIN, source, this) << "SUPERADMIN ON";
- }
- else if (setting.equals_ci("OFF"))
- {
- source.GetUser()->super_admin = false;
- source.Reply(_("You are no longer a super admin."));
- Log(LOG_ADMIN, source, this) << "SUPERADMIN OFF";
- }
- else
- source.Reply(_("Setting for super admin must be \002ON\002 or \002OFF\002."));
-
- return;
- }
-
- void DoSetDebug(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &setting = params.size() > 1 ? params[1] : "";
-
- if (setting.empty())
- {
- this->OnSyntaxError(source, "DEBUG");
- return;
- }
-
- if (setting.equals_ci("ON"))
- {
- Anope::Debug = 1;
- Log(LOG_ADMIN, source, this) << "DEBUG ON";
- source.Reply(_("Services are now in \002debug\002 mode."));
- }
- else if (setting.equals_ci("OFF") || setting == "0")
- {
- Log(LOG_ADMIN, source, this) << "DEBUG OFF";
- Anope::Debug = 0;
- source.Reply(_("Services are now in \002non-debug\002 mode."));
- }
- else
- {
- try
- {
- Anope::Debug = convertTo<int>(setting);
- Log(LOG_ADMIN, source, this) << "DEBUG " << Anope::Debug;
- source.Reply(_("Services are now in \002debug\002 mode (level %d)."), Anope::Debug);
- return;
- }
- catch (const ConvertException &) { }
-
- source.Reply(_("Setting for DEBUG must be \002ON\002, \002OFF\002, or a positive number."));
- }
-
- return;
- }
-
- void DoSetNoExpire(CommandSource &source, const std::vector<Anope::string> &params)
- {
- const Anope::string &setting = params.size() > 1 ? params[1] : "";
-
- if (setting.empty())
- {
- this->OnSyntaxError(source, "NOEXPIRE");
- return;
- }
-
- if (setting.equals_ci("ON"))
- {
- Anope::NoExpire = true;
- Log(LOG_ADMIN, source, this) << "NOEXPIRE ON";
- source.Reply(_("Services are now in \002no expire\002 mode."));
- }
- else if (setting.equals_ci("OFF"))
- {
- Anope::NoExpire = false;
- Log(LOG_ADMIN, source, this) << "NOEXPIRE OFF";
- source.Reply(_("Services are now in \002expire\002 mode."));
- }
- else
- source.Reply(_("Setting for NOEXPIRE must be \002ON\002 or \002OFF\002."));
-
- return;
- }
- public:
- CommandOSSet(Module *creator) : Command(creator, "operserv/set", 1, 2)
- {
- this->SetDesc(_("Set various global Services options"));
- this->SetSyntax(_("\037option\037 \037setting\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &option = params[0];
-
- if (option.equals_ci("LIST"))
- return this->DoList(source);
- else if (option.equals_ci("READONLY"))
- return this->DoSetReadOnly(source, params);
- else if (option.equals_ci("DEBUG"))
- return this->DoSetDebug(source, params);
- else if (option.equals_ci("NOEXPIRE"))
- return this->DoSetNoExpire(source, params);
- else if (option.equals_ci("SUPERADMIN"))
- return this->DoSetSuperAdmin(source, params);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- if (subcommand.empty())
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Sets various global Services options. Option names\n"
- "currently defined are:\n"
- " READONLY Set read-only or read-write mode\n"
- " DEBUG Activate or deactivate debug mode\n"
- " NOEXPIRE Activate or deactivate no expire mode\n"
- " SUPERADMIN Activate or deactivate super admin mode\n"
- " LIST List the options"));
- }
- else if (subcommand.equals_ci("LIST"))
- source.Reply(_("Syntax: \002LIST\002\n"
- " \n"
- "Display the various %s settings."), source.service->nick.c_str());
- else if (subcommand.equals_ci("READONLY"))
- source.Reply(_("Syntax: \002READONLY {ON | OFF}\002\n"
- " \n"
- "Sets read-only mode on or off. In read-only mode, normal\n"
- "users will not be allowed to modify any Services data,\n"
- "including channel and nickname access lists, etc. IRCops\n"
- "with sufficient Services privileges will be able to modify\n"
- "Services' AKILL, SQLINE, SNLINE and ignore lists, drop,\n"
- "suspend or forbid nicknames and channels, and manage news,\n"
- "oper info and DNS, but any such changes will not be saved\n"
- "unless read-only mode is deactivated before Services are\n"
- "terminated or restarted.\n"
- " \n"
- "This option is equivalent to the command-line option\n"
- "\002--readonly\002."));
- else if (subcommand.equals_ci("DEBUG"))
- source.Reply(_("Syntax: \002DEBUG {ON | OFF}\002\n"
- " \n"
- "Sets debug mode on or off.\n"
- " \n"
- "This option is equivalent to the command-line option\n"
- "\002--debug\002."));
- else if (subcommand.equals_ci("NOEXPIRE"))
- source.Reply(_("Syntax: \002NOEXPIRE {ON | OFF}\002\n"
- " \n"
- "Sets no expire mode on or off. In no expire mode, nicks,\n"
- "channels, akills and exceptions won't expire until the\n"
- "option is unset.\n"
- " \n"
- "This option is equivalent to the command-line option\n"
- "\002--noexpire\002."));
- else if (subcommand.equals_ci("SUPERADMIN"))
- source.Reply(_("Syntax: \002SUPERADMIN {ON | OFF}\002\n"
- " \n"
- "Setting this will grant you extra privileges such as the\n"
- "ability to be \"founder\" on all channel's etc...\n"
- " \n"
- "This option is \002not\002 persistent, and should only be used when\n"
- "needed, and set back to OFF when no longer needed."));
- else
- return false;
- return true;
- }
-};
-
-class OSSet : public Module
-{
- CommandOSSet commandosset;
-
- public:
- OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosset(this)
- {
- }
-};
-
-MODULE_INIT(OSSet)
diff --git a/modules/commands/os_shutdown.cpp b/modules/commands/os_shutdown.cpp
deleted file mode 100644
index 1142edbc0..000000000
--- a/modules/commands/os_shutdown.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSQuit : public Command
-{
- public:
- CommandOSQuit(Module *creator) : Command(creator, "operserv/quit", 0, 0)
- {
- this->SetDesc(_("Terminate Services WITHOUT saving"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Log(LOG_ADMIN, source, this);
- Anope::QuitReason = source.command + " command received from " + source.GetNick();
- Anope::Quitting = true;
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to do an immediate shutdown; databases are\n"
- "\002not\002 saved. This command should not be used unless\n"
- "damage to the in-memory copies of the databases is feared\n"
- "and they should not be saved."));
- return true;
- }
-};
-
-class CommandOSRestart : public Command
-{
- public:
- CommandOSRestart(Module *creator) : Command(creator, "operserv/restart", 0, 0)
- {
- this->SetDesc(_("Save databases and restart Services"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Log(LOG_ADMIN, source, this);
- Anope::QuitReason = source.command + " command received from " + source.GetNick();
- Anope::Quitting = Anope::Restarting = true;
- Anope::SaveDatabases();
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(_("Causes Services to save all databases and then restart\n"
- "(i.e. exit and immediately re-run the executable)."));
- return true;
- }
-};
-
-class CommandOSShutdown : public Command
-{
- public:
- CommandOSShutdown(Module *creator) : Command(creator, "operserv/shutdown", 0, 0)
- {
- this->SetDesc(_("Terminate services with save"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Log(LOG_ADMIN, source, this);
- Anope::QuitReason = source.command + " command received from " + source.GetNick();
- Anope::Quitting = true;
- Anope::SaveDatabases();
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to save all databases and then shut down."));
- return true;
- }
-};
-
-class OSShutdown : public Module
-{
- CommandOSQuit commandosquit;
- CommandOSRestart commandosrestart;
- CommandOSShutdown commandosshutdown;
-
- public:
- OSShutdown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosquit(this), commandosrestart(this), commandosshutdown(this)
- {
-
- }
-};
-
-MODULE_INIT(OSShutdown)
diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp
deleted file mode 100644
index 306100cea..000000000
--- a/modules/commands/os_stats.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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 "modules/os_session.h"
-
-struct Stats : Serializable
-{
- static Stats *me;
-
- Stats() : Serializable("Stats")
- {
- me = this;
- }
-
- void Serialize(Serialize::Data &data) const anope_override
- {
- data["maxusercnt"] << MaxUserCount;
- data["maxusertime"] << MaxUserTime;
- }
-
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
- {
- data["maxusercnt"] >> MaxUserCount;
- data["maxusertime"] >> MaxUserTime;
- return me;
- }
-};
-
-Stats *Stats::me;
-
-/**
- * Count servers connected to server s
- * @param s The server to start counting from
- * @return Amount of servers connected to server s
- **/
-static int stats_count_servers(Server *s)
-{
- if (!s)
- return 0;
-
- int count = 1;
-
- if (!s->GetLinks().empty())
- for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
- count += stats_count_servers(s->GetLinks()[i]);
-
- return count;
-}
-
-class CommandOSStats : public Command
-{
- ServiceReference<XLineManager> akills, snlines, sqlines;
- private:
- void DoStatsAkill(CommandSource &source)
- {
- int timeout;
- if (akills)
- {
- /* AKILLs */
- source.Reply(_("Current number of AKILLs: \002%d\002"), akills->GetCount());
- timeout = Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d") + 59;
- if (timeout >= 172800)
- source.Reply(_("Default AKILL expiry time: \002%d days\002"), timeout / 86400);
- else if (timeout >= 86400)
- source.Reply(_("Default AKILL expiry time: \0021 day\002"));
- else if (timeout >= 7200)
- source.Reply(_("Default AKILL expiry time: \002%d hours\002"), timeout / 3600);
- else if (timeout >= 3600)
- source.Reply(_("Default AKILL expiry time: \0021 hour\002"));
- else if (timeout >= 120)
- source.Reply(_("Default AKILL expiry time: \002%d minutes\002"), timeout / 60);
- else if (timeout >= 60)
- source.Reply(_("Default AKILL expiry time: \0021 minute\002"));
- else
- source.Reply(_("Default AKILL expiry time: \002No expiration\002"));
- }
- if (snlines)
- {
- /* SNLINEs */
- source.Reply(_("Current number of SNLINEs: \002%d\002"), snlines->GetCount());
- timeout = Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d") + 59;
- if (timeout >= 172800)
- source.Reply(_("Default SNLINE expiry time: \002%d days\002"), timeout / 86400);
- else if (timeout >= 86400)
- source.Reply(_("Default SNLINE expiry time: \0021 day\002"));
- else if (timeout >= 7200)
- source.Reply(_("Default SNLINE expiry time: \002%d hours\002"), timeout / 3600);
- else if (timeout >= 3600)
- source.Reply(_("Default SNLINE expiry time: \0021 hour\002"));
- else if (timeout >= 120)
- source.Reply(_("Default SNLINE expiry time: \002%d minutes\002"), timeout / 60);
- else if (timeout >= 60)
- source.Reply(_("Default SNLINE expiry time: \0021 minute\002"));
- else
- source.Reply(_("Default SNLINE expiry time: \002No expiration\002"));
- }
- if (sqlines)
- {
- /* SQLINEs */
- source.Reply(_("Current number of SQLINEs: \002%d\002"), sqlines->GetCount());
- timeout = Config->GetModule("operserv")->Get<time_t>("sglineexpiry", "30d") + 59;
- if (timeout >= 172800)
- source.Reply(_("Default SQLINE expiry time: \002%d days\002"), timeout / 86400);
- else if (timeout >= 86400)
- source.Reply(_("Default SQLINE expiry time: \0021 day\002"));
- else if (timeout >= 7200)
- source.Reply(_("Default SQLINE expiry time: \002%d hours\002"), timeout / 3600);
- else if (timeout >= 3600)
- source.Reply(_("Default SQLINE expiry time: \0021 hour\002"));
- else if (timeout >= 120)
- source.Reply(_("Default SQLINE expiry time: \002%d minutes\002"), timeout / 60);
- else if (timeout >= 60)
- source.Reply(_("Default SQLINE expiry time: \0021 minute\002"));
- else
- source.Reply(_("Default SQLINE expiry time: \002No expiration\002"));
- }
- }
-
- void DoStatsReset(CommandSource &source)
- {
- MaxUserCount = UserListByNick.size();
- source.Reply(_("Statistics reset."));
- return;
- }
-
- void DoStatsUptime(CommandSource &source)
- {
- time_t uptime = Anope::CurTime - Anope::StartTime;
- source.Reply(_("Current users: \002%d\002 (\002%d\002 ops)"), UserListByNick.size(), OperCount);
- source.Reply(_("Maximum users: \002%d\002 (%s)"), MaxUserCount, Anope::strftime(MaxUserTime, source.GetAccount()).c_str());
- source.Reply(_("Services up %s."), Anope::Duration(uptime, source.GetAccount()).c_str());
-
- return;
- }
-
- void DoStatsUplink(CommandSource &source)
- {
- Anope::string buf;
- for (std::set<Anope::string>::iterator it = Servers::Capab.begin(); it != Servers::Capab.end(); ++it)
- buf += " " + *it;
- if (!buf.empty())
- buf.erase(buf.begin());
-
- source.Reply(_("Uplink server: %s"), Me->GetLinks().front()->GetName().c_str());
- source.Reply(_("Uplink capab: %s"), buf.c_str());
- source.Reply(_("Servers found: %d"), stats_count_servers(Me->GetLinks().front()));
- return;
- }
-
- template<typename T> void GetHashStats(const T& map, size_t& entries, size_t& buckets, size_t& max_chain)
- {
- entries = map.size(), buckets = map.bucket_count(), max_chain = 0;
- for (size_t i = 0; i < buckets; ++i)
- if (map.bucket_size(i) > max_chain)
- max_chain = map.bucket_size(i);
- }
-
- void DoStatsHash(CommandSource &source)
- {
- size_t entries, buckets, max_chain;
-
- GetHashStats(UserListByNick, entries, buckets, max_chain);
- source.Reply(_("Users (nick): %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- if (!UserListByUID.empty())
- {
- GetHashStats(UserListByUID, entries, buckets, max_chain);
- source.Reply(_("Users (uid): %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
- }
-
- GetHashStats(ChannelList, entries, buckets, max_chain);
- source.Reply(_("Channels: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- GetHashStats(*RegisteredChannelList, entries, buckets, max_chain);
- source.Reply(_("Registered channels: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- GetHashStats(*NickAliasList, entries, buckets, max_chain);
- source.Reply(_("Registered nicknames: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- GetHashStats(*NickCoreList, entries, buckets, max_chain);
- source.Reply(_("Registered nick groups: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
-
- if (session_service)
- {
- GetHashStats(session_service->GetSessions(), entries, buckets, max_chain);
- source.Reply(_("Sessions: %lu entries, %lu buckets, longest chain is %d"), entries, buckets, max_chain);
- }
- }
-
- public:
- CommandOSStats(Module *creator) : Command(creator, "operserv/stats", 0, 1),
- akills("XLineManager", "xlinemanager/sgline"), snlines("XLineManager", "xlinemanager/snline"), sqlines("XLineManager", "xlinemanager/sqline")
- {
- this->SetDesc(_("Show status of Services and network"));
- this->SetSyntax("[AKILL | HASH | UPLINK | UPTIME | ALL | RESET]");
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Anope::string extra = !params.empty() ? params[0] : "";
-
- Log(LOG_ADMIN, source, this) << extra;
-
- if (extra.equals_ci("RESET"))
- return this->DoStatsReset(source);
-
- if (extra.equals_ci("ALL") || extra.equals_ci("AKILL"))
- this->DoStatsAkill(source);
-
- if (extra.equals_ci("ALL") || extra.equals_ci("HASH"))
- this->DoStatsHash(source);
-
- if (extra.equals_ci("ALL") || extra.equals_ci("UPLINK"))
- this->DoStatsUplink(source);
-
- if (extra.empty() || extra.equals_ci("ALL") || extra.equals_ci("UPTIME"))
- this->DoStatsUptime(source);
-
- if (!extra.empty() && !extra.equals_ci("ALL") && !extra.equals_ci("AKILL") && !extra.equals_ci("HASH") && !extra.equals_ci("UPLINK") && !extra.equals_ci("UPTIME"))
- source.Reply(_("Unknown STATS option: \002%s\002"), extra.c_str());
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Without any option, shows the current number of users online,\n"
- "and the highest number of users online since Services was\n"
- "started, and the length of time Services has been running.\n"
- " \n"
- "With the \002AKILL\002 option, displays the current size of the\n"
- "AKILL list and the current default expiry time.\n"
- " \n"
- "The \002RESET\002 option currently resets the maximum user count\n"
- "to the number of users currently present on the network.\n"
- " \n"
- "The \002UPLINK\002 option displays information about the current\n"
- "server Anope uses as an uplink to the network.\n"
- " \n"
- "The \002HASH\002 option displays information about the hash maps.\n"
- " \n"
- "The \002ALL\002 option displays all of the above statistics."));
- return true;
- }
-};
-
-class OSStats : public Module
-{
- CommandOSStats commandosstats;
- Serialize::Type stats_type;
- Stats stats_saver;
-
- public:
- OSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosstats(this), stats_type("Stats", Stats::Unserialize)
- {
-
- }
-
- void OnUserConnect(User *u, bool &exempt) anope_override
- {
- if (UserListByNick.size() == MaxUserCount && Anope::CurTime == MaxUserTime)
- stats_saver.QueueUpdate();
- }
-};
-
-MODULE_INIT(OSStats)
diff --git a/modules/commands/os_svs.cpp b/modules/commands/os_svs.cpp
deleted file mode 100644
index 769adb338..000000000
--- a/modules/commands/os_svs.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSSVSNick : public Command
-{
- public:
- CommandOSSVSNick(Module *creator) : Command(creator, "operserv/svsnick", 2, 2)
- {
- this->SetDesc(_("Forcefully change a user's nickname"));
- this->SetSyntax(_("\037nick\037 \037newnick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &nick = params[0];
- Anope::string newnick = params[1];
- User *u2;
-
- if (!IRCD->CanSVSNick)
- {
- source.Reply(_("Your IRCd does not support SVSNICK."));
- return;
- }
-
- /* Truncate long nicknames to nicklen characters */
- unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
- if (newnick.length() > nicklen)
- {
- source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), nicklen, newnick.c_str());
- newnick = params[1].substr(0, nicklen);
- }
-
- /* Check for valid characters */
- if (!IRCD->IsNickValid(newnick))
- {
- source.Reply(_("Nick \002%s\002 is an illegal nickname and cannot be used."), newnick.c_str());
- return;
- }
-
- /* Check for a nick in use or a forbidden/suspended nick */
- if (!(u2 = User::Find(nick, true)))
- source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
- else if (!nick.equals_ci(newnick) && User::Find(newnick))
- source.Reply(_("Nick \002%s\002 is currently in use."), newnick.c_str());
- else
- {
- source.Reply(_("The nick \002%s\002 is now being changed to \002%s\002."), nick.c_str(), newnick.c_str());
- Log(LOG_ADMIN, source, this) << "to change " << nick << " to " << newnick;
- IRCD->SendForceNickChange(u2, newnick, Anope::CurTime);
- }
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forcefully changes a user's nickname from \037nick\037 to \037newnick\037."));
- return true;
- }
-};
-
-class CommandOSSVSJoin : public Command
-{
- public:
- CommandOSSVSJoin(Module *creator) : Command(creator, "operserv/svsjoin", 2, 2)
- {
- this->SetDesc(_("Forcefully join a user to a channel"));
- this->SetSyntax(_("\037nick\037 \037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!IRCD->CanSVSJoin)
- {
- source.Reply(_("Your IRCd does not support SVSJOIN."));
- return;
- }
-
- User *target = User::Find(params[0], true);
- Channel *c = Channel::Find(params[1]);
- if (target == NULL)
- source.Reply(NICK_X_NOT_IN_USE, params[0].c_str());
- else if (source.GetUser() != target && (target->IsProtected() || target->server == Me))
- source.Reply(ACCESS_DENIED);
- else if (!IRCD->IsChannelValid(params[1]))
- source.Reply(CHAN_X_INVALID, params[1].c_str());
- else if (c && c->FindUser(target))
- source.Reply(_("\002%s\002 is already in \002%s\002."), target->nick.c_str(), c->name.c_str());
- else
- {
- IRCD->SendSVSJoin(*source.service, target, params[1], "");
- Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to join " << params[1];
- source.Reply(_("\002%s\002 has been joined to \002%s\002."), target->nick.c_str(), params[1].c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forcefully join a user to a channel."));
- return true;
- }
-};
-
-class CommandOSSVSPart : public Command
-{
- public:
- CommandOSSVSPart(Module *creator) : Command(creator, "operserv/svspart", 2, 3)
- {
- this->SetDesc(_("Forcefully part a user from a channel"));
- this->SetSyntax(_("\037nick\037 \037channel\037 [\037reason\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!IRCD->CanSVSJoin)
- {
- source.Reply(_("Your IRCd does not support SVSPART."));
- return;
- }
-
- User *target = User::Find(params[0], true);
- Channel *c = Channel::Find(params[1]);
- const Anope::string &reason = params.size() > 2 ? params[2] : "";
- if (target == NULL)
- source.Reply(NICK_X_NOT_IN_USE, params[0].c_str());
- else if (source.GetUser() != target && (target->IsProtected() || target->server == Me))
- source.Reply(ACCESS_DENIED);
- else if (!c)
- source.Reply(CHAN_X_NOT_IN_USE, params[1].c_str());
- else if (!c->FindUser(target))
- source.Reply(_("\002%s\002 is not in \002%s\002."), target->nick.c_str(), c->name.c_str());
- else
- {
- IRCD->SendSVSPart(*source.service, target, params[1], reason);
- if (!reason.empty())
- Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name << " with reason " << reason;
- else
- Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name;
- source.Reply(_("\002%s\002 has been parted from \002%s\002."), target->nick.c_str(), c->name.c_str());
- }
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Forcefully part a user from a channel."));
- return true;
- }
-};
-
-class OSSVS : public Module
-{
- CommandOSSVSNick commandossvsnick;
- CommandOSSVSJoin commandossvsjoin;
- CommandOSSVSPart commandossvspart;
-
- public:
- OSSVS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandossvsnick(this), commandossvsjoin(this), commandossvspart(this)
- {
- }
-};
-
-MODULE_INIT(OSSVS)
diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp
deleted file mode 100644
index 0de21ce02..000000000
--- a/modules/commands/os_sxline.cpp
+++ /dev/null
@@ -1,732 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class SXLineDelCallback : public NumberList
-{
- XLineManager *xlm;
- Command *command;
- CommandSource &source;
- unsigned deleted;
- public:
- SXLineDelCallback(XLineManager *x, Command *c, CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, true), xlm(x), command(c), source(_source), deleted(0)
- {
- }
-
- ~SXLineDelCallback()
- {
- if (!deleted)
- source.Reply(_("No matching entries on the %s list."), source.command.c_str());
- else if (deleted == 1)
- source.Reply(_("Deleted 1 entry from the %s list."), source.command.c_str());
- else
- source.Reply(_("Deleted %d entries from the %s list."), deleted, source.command.c_str());
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- XLine *x = this->xlm->GetEntry(number - 1);
-
- if (!x)
- return;
-
- Log(LOG_ADMIN, source, command) << "to remove " << x->mask << " from the list";
-
- ++deleted;
- DoDel(this->xlm, source, x);
- }
-
- static void DoDel(XLineManager *xlm, CommandSource &source, XLine *x)
- {
- xlm->DelXLine(x);
- }
-};
-
-class CommandOSSXLineBase : public Command
-{
- private:
- virtual XLineManager* xlm() = 0;
-
- virtual void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) = 0;
-
- void OnDel(CommandSource &source, const std::vector<Anope::string> &params)
- {
-
- if (!this->xlm() || this->xlm()->GetList().empty())
- {
- source.Reply(_("%s list is empty."), source.command.c_str());
- return;
- }
-
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (mask.empty())
- {
- this->OnSyntaxError(source, "DEL");
- return;
- }
-
- if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- SXLineDelCallback list(this->xlm(), this, source, mask);
- list.Process();
- }
- else
- {
- XLine *x = this->xlm()->HasEntry(mask);
-
- if (!x)
- {
- source.Reply(_("\002%s\002 not found on the %s list."), mask.c_str(), source.command.c_str());
- return;
- }
-
- FOREACH_MOD(OnDelXLine, (source, x, this->xlm()));
-
- SXLineDelCallback::DoDel(this->xlm(), source, x);
- source.Reply(_("\002%s\002 deleted from the %s list."), mask.c_str(), source.command.c_str());
- Log(LOG_ADMIN, source, this) << "to remove " << mask << " from the list";
- }
-
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
-
- void ProcessList(CommandSource &source, const std::vector<Anope::string> &params, ListFormatter &list)
- {
- if (!this->xlm() || this->xlm()->GetList().empty())
- {
- source.Reply(_("%s list is empty."), source.command.c_str());
- return;
- }
-
- const Anope::string &mask = params.size() > 1 ? params[1] : "";
-
- if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
- {
- class SXLineListCallback : public NumberList
- {
- XLineManager *xlm;
- CommandSource &source;
- ListFormatter &list;
- public:
- SXLineListCallback(XLineManager *x, CommandSource &_source, ListFormatter &_list, const Anope::string &numlist) : NumberList(numlist, false), xlm(x), source(_source), list(_list)
- {
- }
-
- void HandleNumber(unsigned number) anope_override
- {
- if (!number)
- return;
-
- const XLine *x = this->xlm->GetEntry(number - 1);
-
- if (!x)
- return;
-
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(number);
- entry["Mask"] = x->mask;
- entry["By"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- list.AddEntry(entry);
- }
- }
- sl_list(this->xlm(), source, list, mask);
- sl_list.Process();
- }
- else
- {
- for (unsigned i = 0, end = this->xlm()->GetCount(); i < end; ++i)
- {
- const XLine *x = this->xlm()->GetEntry(i);
-
- if (mask.empty() || mask.equals_ci(x->mask) || mask == x->id || Anope::Match(x->mask, mask, false, true))
- {
- ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
- entry["Mask"] = x->mask;
- entry["By"] = x->by;
- entry["Created"] = Anope::strftime(x->created, NULL, true);
- entry["Expires"] = Anope::Expires(x->expires, source.nc);
- entry["ID"] = x->id;
- entry["Reason"] = x->reason;
- list.AddEntry(entry);
- }
- }
- }
-
- if (list.IsEmpty())
- source.Reply(_("No matching entries on the %s list."), source.command.c_str());
- else
- {
- source.Reply(_("Current %s list:"), source.command.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
-
- void OnList(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void OnView(CommandSource &source, const std::vector<Anope::string> &params)
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("By")).AddColumn(_("Created")).AddColumn(_("Expires"));
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- list.AddColumn(_("ID"));
- list.AddColumn(_("Reason"));
-
- this->ProcessList(source, params, list);
- }
-
- void OnClear(CommandSource &source)
- {
- FOREACH_MOD(OnDelXLine, (source, NULL, this->xlm()));
-
- for (unsigned i = this->xlm()->GetCount(); i > 0; --i)
- {
- XLine *x = this->xlm()->GetEntry(i - 1);
- this->xlm()->DelXLine(x);
- }
-
- Log(LOG_ADMIN, source, this) << "to CLEAR the list";
- source.Reply(_("The %s list has been cleared."), source.command.c_str());
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
-
- return;
- }
- public:
- CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 4)
- {
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- return Anope::printf(Language::Translate(source.GetAccount(), _("Manipulate the %s list")), source.command.upper().c_str());
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &cmd = params[0];
-
- if (cmd.equals_ci("ADD"))
- return this->OnAdd(source, params);
- else if (cmd.equals_ci("DEL"))
- return this->OnDel(source, params);
- else if (cmd.equals_ci("LIST"))
- return this->OnList(source, params);
- else if (cmd.equals_ci("VIEW"))
- return this->OnView(source, params);
- else if (cmd.equals_ci("CLEAR"))
- return this->OnClear(source);
- else
- this->OnSyntaxError(source, "");
-
- return;
- }
-
- virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand) = 0;
-};
-
-class CommandOSSNLine : public CommandOSSXLineBase
-{
- XLineManager *xlm()
- {
- return this->snlines;
- }
-
- void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!this->xlm())
- return;
-
- unsigned last_param = 2;
- Anope::string param, expiry;
-
- param = params.size() > 1 ? params[1] : "";
- if (!param.empty() && param[0] == '+')
- {
- expiry = param;
- param = params.size() > 2 ? params[2] : "";
- last_param = 3;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d");
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (param.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string rest = param;
- if (params.size() > last_param)
- rest += " " + params[last_param];
-
- if (rest.find(':') == Anope::string::npos)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- sepstream sep(rest, ':');
- Anope::string mask;
- sep.GetToken(mask);
- Anope::string reason = sep.GetRemaining();
-
- if (mask.empty() || reason.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (mask[0] == '/' && mask[mask.length() - 1] == '/')
- {
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
-
- if (regexengine.empty())
- {
- source.Reply(_("Regex is disabled."));
- return;
- }
-
- ServiceReference<RegexProvider> provider("Regex", regexengine);
- if (!provider)
- {
- source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
- return;
- }
-
- try
- {
- Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- delete provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- source.Reply("%s", ex.GetReason().c_str());
- return;
- }
- }
-
- /* Clean up the last character of the mask if it is a space
- * See bug #761
- */
- unsigned masklen = mask.length();
- if (mask[masklen - 1] == ' ')
- mask.erase(masklen - 1);
-
- if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
- reason = "[" + source.GetNick() + "] " + reason;
-
- if (mask.find_first_not_of("/.*?") == Anope::string::npos)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- return;
- }
-
- XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- x->id = XLineManager::GenerateUID();
-
- unsigned int affected = 0;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (this->xlm()->Check(it->second, x))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- Log(LOG_ADMIN, source, this) << "tried to " << source.command << " " << percent << "% of the network (" << affected << " users)";
- delete x;
- return;
- }
-
- if (!this->xlm()->CanAdd(source, mask, expires, reason))
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, this->xlm()));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return;
- }
-
- this->xlm()->AddXLine(x);
-
- if (Config->GetModule("operserv")->Get<bool>("killonsnline", "yes"))
- {
- Anope::string rreason = "G-Lined: " + reason;
-
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *user = it->second;
-
- if (!user->HasMode("OPER") && user->server != Me && this->xlm()->Check(user, x))
- user->Kill(Me, rreason);
- }
-
- this->xlm()->Send(NULL, x);
- }
-
- source.Reply(_("\002%s\002 added to the %s list."), mask.c_str(), source.command.c_str());
- Log(LOG_ADMIN, source, this) << "on " << mask << " (" << reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
-
- ServiceReference<XLineManager> snlines;
- public:
- CommandOSSNLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/snline"), snlines("XLineManager", "xlinemanager/snline")
- {
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax("CLEAR");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the SNLINE list. If\n"
- "a user with a realname matching an SNLINE mask attempts to\n"
- "connect, Services will not allow it to pursue his IRC\n"
- "session."));
- source.Reply(_(" \n"
- "\002SNLINE ADD\002 adds the given realname mask to the SNLINE\n"
- "list for the given reason (which \002must\002 be given).\n"
- "\037expiry\037 is specified as an integer followed by one of \037d\037\n"
- "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n"
- "\0371h30m\037) are not permitted. If a unit specifier is not\n"
- "included, the default is days (so \037+30\037 by itself means 30\n"
- "days). To add an SNLINE which does not expire, use \037+0\037. If the\n"
- "realname mask to be added starts with a \037+\037, an expiry time must\n"
- "be given, even if it is the same as the default. The\n"
- "current SNLINE default expiry time can be found with the\n"
- "\002STATS AKILL\002 command.\n"
- " \n"
- "\002Note\002: because the realname mask may contain spaces, the\n"
- "separator between it and the reason is a colon."));
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), regexengine.c_str());
- }
- source.Reply(_(" \n"
- "The \002SNLINE DEL\002 command removes the given mask from the\n"
- "SNLINE list if it is present. If a list of entry numbers is\n"
- "given, those entries are deleted. (See the example for LIST\n"
- "below.)\n"
- " \n"
- "The \002SNLINE LIST\002 command displays the SNLINE list.\n"
- "If a wildcard mask is given, only those entries matching the\n"
- "mask are displayed. If a list of entry numbers is given,\n"
- "only those entries are shown; for example:\n"
- " \002SNLINE LIST 2-5,7-9\002\n"
- " Lists SNLINE entries numbered 2 through 5 and 7\n"
- " through 9.\n"
- " \n"
- "\002SNLINE VIEW\002 is a more verbose version of \002SNLINE LIST\002, and\n"
- "will show who added an SNLINE, the date it was added, and when\n"
- "it expires, as well as the realname mask and reason.\n"
- " \n"
- "\002SNLINE CLEAR\002 clears all entries of the SNLINE list."));
- return true;
- }
-};
-
-class CommandOSSQLine : public CommandOSSXLineBase
-{
- XLineManager *xlm()
- {
- return this->sqlines;
- }
-
- void OnAdd(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- if (!this->xlm())
- return;
-
- unsigned last_param = 2;
- Anope::string expiry, mask;
-
- mask = params.size() > 1 ? params[1] : "";
- if (!mask.empty() && mask[0] == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2] : "";
- last_param = 3;
- }
-
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d");
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- source.Reply(BAD_EXPIRY_TIME);
- return;
- }
- else if (expires > 0)
- expires += Anope::CurTime;
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- Anope::string reason = params[last_param];
- if (last_param == 2 && params.size() > 3)
- reason += " " + params[3];
-
- if (mask.empty() || reason.empty())
- {
- this->OnSyntaxError(source, "ADD");
- return;
- }
-
- if (mask[0] == '/' && mask[mask.length() - 1] == '/')
- {
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
-
- if (regexengine.empty())
- {
- source.Reply(_("Regex is disabled."));
- return;
- }
-
- ServiceReference<RegexProvider> provider("Regex", regexengine);
- if (!provider)
- {
- source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
- return;
- }
-
- try
- {
- Anope::string stripped_mask = mask.substr(1, mask.length() - 2);
- delete provider->Compile(stripped_mask);
- }
- catch (const RegexException &ex)
- {
- source.Reply("%s", ex.GetReason().c_str());
- return;
- }
- }
-
- if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
- reason = "[" + source.GetNick() + "] " + reason;
-
- if (mask.find_first_not_of("./?*") == Anope::string::npos)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- return;
- }
-
- XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->GetModule("operserv")->Get<bool>("akillids"))
- x->id = XLineManager::GenerateUID();
-
- unsigned int affected = 0;
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (this->xlm()->Check(it->second, x))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
- source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str());
- Log(LOG_ADMIN, source, this) << "tried to SQLine " << percent << "% of the network (" << affected << " users)";
- delete x;
- return;
- }
-
- if (!this->sqlines->CanAdd(source, mask, expires, reason))
- return;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, this->xlm()));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return;
- }
-
- this->xlm()->AddXLine(x);
-
- if (Config->GetModule("operserv")->Get<bool>("killonsqline", "yes"))
- {
- Anope::string rreason = "Q-Lined: " + reason;
-
- if (mask[0] == '#')
- {
- for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
- {
- Channel *c = cit->second;
-
- if (!Anope::Match(c->name, mask, false, true))
- continue;
-
- std::vector<User *> users;
- for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
- {
- ChanUserContainer *uc = it->second;
- User *user = uc->user;
-
- if (!user->HasMode("OPER") && user->server != Me)
- users.push_back(user);
- }
-
- for (unsigned i = 0; i < users.size(); ++i)
- c->Kick(NULL, users[i], "%s", reason.c_str());
- }
- }
- else
- {
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *user = it->second;
-
- if (!user->HasMode("OPER") && user->server != Me && this->xlm()->Check(user, x))
- user->Kill(Me, rreason);
- }
- }
-
- this->xlm()->Send(NULL, x);
- }
-
- source.Reply(_("\002%s\002 added to the %s list."), mask.c_str(), source.command.c_str());
- Log(LOG_ADMIN, source, this) << "on " << mask << " (" << reason << "), expires in " << (expires ? Anope::Duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (Anope::ReadOnly)
- source.Reply(READ_ONLY_MODE);
- }
-
- ServiceReference<XLineManager> sqlines;
- public:
- CommandOSSQLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/sqline"), sqlines("XLineManager", "xlinemanager/sqline")
- {
- this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037"));
- this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}"));
- this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]"));
- this->SetSyntax("CLEAR");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Allows Services Operators to manipulate the SQLINE list. If\n"
- "a user with a nick matching an SQLINE mask attempts to\n"
- "connect, Services will not allow it to pursue his IRC\n"
- "session.\n"
- "If the first character of the mask is #, services will\n"
- "prevent the use of matching channels. If the mask is a\n"
- "regular expression, the expression will be matched against\n"
- "channels too."));
- source.Reply(_(" \n"
- "\002SQLINE ADD\002 adds the given (nick's) mask to the SQLINE\n"
- "list for the given reason (which \002must\002 be given).\n"
- "\037expiry\037 is specified as an integer followed by one of \037d\037\n"
- "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n"
- "\0371h30m\037) are not permitted. If a unit specifier is not\n"
- "included, the default is days (so \037+30\037 by itself means 30\n"
- "days). To add an SQLINE which does not expire, use \037+0\037.\n"
- "If the mask to be added starts with a \037+\037, an expiry time\n"
- "must be given, even if it is the same as the default. The\n"
- "current SQLINE default expiry time can be found with the\n"
- "\002STATS AKILL\002 command."));
- const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
- if (!regexengine.empty())
- {
- source.Reply(" ");
- source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), regexengine.c_str());
- }
- source.Reply(_(" \n"
- "The \002SQLINE DEL\002 command removes the given mask from the\n"
- "SQLINE list if it is present. If a list of entry numbers is\n"
- "given, those entries are deleted. (See the example for LIST\n"
- "below.)\n"
- " \n"
- "The \002SQLINE LIST\002 command displays the SQLINE list.\n"
- "If a wildcard mask is given, only those entries matching the\n"
- "mask are displayed. If a list of entry numbers is given,\n"
- "only those entries are shown; for example:\n"
- " \002SQLINE LIST 2-5,7-9\002\n"
- " Lists SQLINE entries numbered 2 through 5 and 7\n"
- " through 9.\n"
- " \n"
- "\002SQLINE VIEW\002 is a more verbose version of \002SQLINE LIST\002, and\n"
- "will show who added an SQLINE, the date it was added, and when\n"
- "it expires, as well as the mask and reason.\n"
- " \n"
- "\002SQLINE CLEAR\002 clears all entries of the SQLINE list."));
- return true;
- }
-};
-
-class OSSXLine : public Module
-{
- CommandOSSNLine commandossnline;
- CommandOSSQLine commandossqline;
-
- public:
- OSSXLine(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandossnline(this), commandossqline(this)
- {
- }
-};
-
-MODULE_INIT(OSSXLine)
diff --git a/modules/commands/os_update.cpp b/modules/commands/os_update.cpp
deleted file mode 100644
index 5fac1b063..000000000
--- a/modules/commands/os_update.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2016 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"
-
-class CommandOSUpdate : public Command
-{
- public:
- CommandOSUpdate(Module *creator) : Command(creator, "operserv/update", 0, 0)
- {
- this->SetDesc(_("Force the Services databases to be updated immediately"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- Log(LOG_ADMIN, source, this);
- source.Reply(_("Updating databases."));
- Anope::SaveDatabases();
- return;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Causes Services to update all database files as soon as you\n"
- "send the command."));
- return true;
- }
-};
-
-class OSUpdate : public Module
-{
- CommandOSUpdate commandosupdate;
-
- public:
- OSUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandosupdate(this)
- {
-
- }
-};
-
-MODULE_INIT(OSUpdate)