summaryrefslogtreecommitdiff
path: root/modules/operserv/list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/operserv/list.cpp')
-rw-r--r--modules/operserv/list.cpp246
1 files changed, 246 insertions, 0 deletions
diff --git a/modules/operserv/list.cpp b/modules/operserv/list.cpp
new file mode 100644
index 000000000..00b7bf746
--- /dev/null
+++ b/modules/operserv/list.cpp
@@ -0,0 +1,246 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2003-2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#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) 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(_("Channel list for \002{0}\002:"), u2->nick);
+
+ 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) override
+ {
+ source.Reply(_("Lists all channels currently in use on the IRC network, whether they are registered or not.\n"
+ "\n"
+ "If \002pattern\002 is given, lists only channels that match it. If a nicknam is given, lists only the channels the user using it is on."
+ " If SECRET is specified, lists only channels matching \002pattern\002 that have the +s or +p mode."));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<Anope::string>("regexengine");
+ if (!regexengine.empty())
+ {
+ source.Reply(" ");
+ source.Reply(_("Regex matches are also supported using the {0} engine. Enclose your pattern in // if this is desired."), regexengine);
+ }
+
+ 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) 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(_("User list for \002{0}\002:"), pattern);
+
+ 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) override
+ {
+ this->SendSyntax(source);
+ source.Reply(" ");
+ source.Reply(_("Lists all users currently online on the IRC network, whether their nickname is registered or not.\n"
+ "\n"
+ "If \002pattern\002 is given, lists only users that match it (it must be in the format nick!user@host)."
+ " If \002channel\002 is given, lists only users that are on the given channel. If INVISIBLE is specified, only users with the +i flag will be listed."));
+
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<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)