anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

os_list.cpp (8305B)

      1 /* OperServ core functions
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #include "module.h"
     13 
     14 class CommandOSChanList : public Command
     15 {
     16  public:
     17 	CommandOSChanList(Module *creator) : Command(creator, "operserv/chanlist", 0, 2)
     18 	{
     19 		this->SetDesc(_("Lists all channel records"));
     20 		this->SetSyntax(_("[{\037pattern\037 | \037nick\037} [\037SECRET\037]]"));
     21 	}
     22 
     23 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
     24 	{
     25 		const Anope::string &pattern = !params.empty() ? params[0] : "";
     26 		const Anope::string &opt = params.size() > 1 ? params[1] : "";
     27 		std::set<Anope::string> modes;
     28 		User *u2;
     29 		unsigned int count = 0;
     30 
     31 		if (!pattern.empty())
     32 			Log(LOG_ADMIN, source, this) << "for " << pattern;
     33 		else
     34 			Log(LOG_ADMIN, source, this);
     35 
     36 		if (!opt.empty() && opt.equals_ci("SECRET"))
     37 		{
     38 			modes.insert("SECRET");
     39 			modes.insert("PRIVATE");
     40 		}
     41 
     42 		ListFormatter list(source.GetAccount());
     43 		list.AddColumn(_("Name")).AddColumn(_("Users")).AddColumn(_("Modes")).AddColumn(_("Topic"));
     44 
     45 		if (!pattern.empty() && (u2 = User::Find(pattern, true)))
     46 		{
     47 			source.Reply(_("\002%s\002 channel list:"), u2->nick.c_str());
     48 
     49 			for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit)
     50 			{
     51 				ChanUserContainer *cc = uit->second;
     52 
     53 				if (!modes.empty())
     54 					for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
     55 						if (!cc->chan->HasMode(*it))
     56 							continue;
     57 
     58 				ListFormatter::ListEntry entry;
     59 				entry["Name"] = cc->chan->name;
     60 				entry["Users"] = stringify(cc->chan->users.size());
     61 				entry["Modes"] = cc->chan->GetModes(true, true);
     62 				entry["Topic"] = cc->chan->topic;
     63 				list.AddEntry(entry);
     64 
     65 				++count;
     66 			}
     67 		}
     68 		else
     69 		{
     70 			source.Reply(_("Channel list:"));
     71 
     72 			for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
     73 			{
     74 				Channel *c = cit->second;
     75 
     76 				if (!pattern.empty() && !Anope::Match(c->name, pattern, false, true))
     77 					continue;
     78 				if (!modes.empty())
     79 					for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
     80 						if (!c->HasMode(*it))
     81 							continue;
     82 
     83 				ListFormatter::ListEntry entry;
     84 				entry["Name"] = c->name;
     85 				entry["Users"] = stringify(c->users.size());
     86 				entry["Modes"] = c->GetModes(true, true);
     87 				entry["Topic"] = c->topic;
     88 				list.AddEntry(entry);
     89 
     90 				++count;
     91 			}
     92 		}
     93 
     94 		std::vector<Anope::string> replies;
     95 		list.Process(replies);
     96 
     97 		for (unsigned i = 0; i < replies.size(); ++i)
     98 			source.Reply(replies[i]);
     99 
    100 		source.Reply(_("End of channel list. \002%u\002 channels shown."), count);
    101 	}
    102 
    103 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    104 	{
    105 		this->SendSyntax(source);
    106 		source.Reply(" ");
    107 		source.Reply(_("Lists all channels currently in use on the IRC network, whether they\n"
    108 				"are registered or not.\n"
    109 				" \n"
    110 				"If \002pattern\002 is given, lists only channels that match it. If a nickname\n"
    111 				"is given, lists only the channels the user using it is on. If SECRET is\n"
    112 				"specified, lists only channels matching \002pattern\002 that have the +s or\n"
    113 				"+p mode."));
    114 
    115 		const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
    116 		if (!regexengine.empty())
    117 		{
    118 			source.Reply(" ");
    119 			source.Reply(_("Regex matches are also supported using the %s engine.\n"
    120 					"Enclose your pattern in // if this is desired."), regexengine.c_str());
    121 		}
    122 
    123 		return true;
    124 	}
    125 };
    126 
    127 class CommandOSUserList : public Command
    128 {
    129  public:
    130 	CommandOSUserList(Module *creator) : Command(creator, "operserv/userlist", 0, 2)
    131 	{
    132 		this->SetDesc(_("Lists all user records"));
    133 		this->SetSyntax(_("[{\037pattern\037 | \037channel\037} [\037INVISIBLE\037]]"));
    134 	}
    135 
    136 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
    137 	{
    138 		const Anope::string &pattern = !params.empty() ? params[0] : "";
    139 		const Anope::string &opt = params.size() > 1 ? params[1] : "";
    140 		Channel *c;
    141 		std::set<Anope::string> modes;
    142 		unsigned int count = 0;
    143 
    144 		if (!pattern.empty())
    145 			Log(LOG_ADMIN, source, this) << "for " << pattern;
    146 		else
    147 			Log(LOG_ADMIN, source, this);
    148 
    149 		if (!opt.empty() && opt.equals_ci("INVISIBLE"))
    150 			modes.insert("INVIS");
    151 
    152 		ListFormatter list(source.GetAccount());
    153 		list.AddColumn(_("Name")).AddColumn(_("Mask")).AddColumn(_("Realname"));
    154 
    155 		if (!pattern.empty() && (c = Channel::Find(pattern)))
    156 		{
    157 			source.Reply(_("\002%s\002 users list:"), pattern.c_str());
    158 
    159 			for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit)
    160 			{
    161 				ChanUserContainer *uc = cuit->second;
    162 
    163 				if (!modes.empty())
    164 					for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
    165 						if (!uc->user->HasMode(*it))
    166 							continue;
    167 
    168 				ListFormatter::ListEntry entry;
    169 				entry["Name"] = uc->user->nick;
    170 				entry["Mask"] = uc->user->GetIdent() + "@" + uc->user->GetDisplayedHost();
    171 				entry["Realname"] = uc->user->realname;
    172 				list.AddEntry(entry);
    173 
    174 				++count;
    175 			}
    176 		}
    177 		else
    178 		{
    179 			/* Historically this has been ordered, so... */
    180 			Anope::map<User *> ordered_map;
    181 			for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
    182 				ordered_map[it->first] = it->second;
    183 
    184 			source.Reply(_("Users list:"));
    185 
    186 			for (Anope::map<User *>::const_iterator it = ordered_map.begin(); it != ordered_map.end(); ++it)
    187 			{
    188 				User *u2 = it->second;
    189 
    190 				if (!pattern.empty())
    191 				{
    192 					/* check displayed host, host, and ip */
    193 					Anope::string masks[] = {
    194 						u2->nick + "!" + u2->GetIdent() + "@" + u2->GetDisplayedHost(),
    195 						u2->nick + "!" + u2->GetIdent() + "@" + u2->host,
    196 						u2->nick + "!" + u2->GetIdent() + "@" + u2->ip.addr()
    197 					};
    198 
    199 					bool match = false;
    200 					for (unsigned int i = 0; i < sizeof(masks) / sizeof(*masks); ++i)
    201 					{
    202 						/* Check mask with realname included, too */
    203 						if (Anope::Match(masks[i], pattern, false, true) || Anope::Match(masks[i] + "#" + u2->realname, pattern, false, true))
    204 						{
    205 							match = true;
    206 							break;
    207 						}
    208 					}
    209 
    210 					if (!match)
    211 						continue;
    212 
    213 					if (!modes.empty())
    214 						for (std::set<Anope::string>::iterator mit = modes.begin(), mit_end = modes.end(); mit != mit_end; ++mit)
    215 							if (!u2->HasMode(*mit))
    216 								continue;
    217 				}
    218 
    219 				ListFormatter::ListEntry entry;
    220 				entry["Name"] = u2->nick;
    221 				entry["Mask"] = u2->GetIdent() + "@" + u2->GetDisplayedHost();
    222 				entry["Realname"] = u2->realname;
    223 				list.AddEntry(entry);
    224 
    225 				++count;
    226 			}
    227 		}
    228 
    229 		std::vector<Anope::string> replies;
    230 		list.Process(replies);
    231 
    232 		for (unsigned i = 0; i < replies.size(); ++i)
    233 			source.Reply(replies[i]);
    234 
    235 		source.Reply(_("End of users list. \002%u\002 users shown."), count);
    236 		return;
    237 	}
    238 
    239 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    240 	{
    241 		this->SendSyntax(source);
    242 		source.Reply(" ");
    243 		source.Reply(_("Lists all users currently online on the IRC network, whether their\n"
    244 				"nick is registered or not.\n"
    245 				" \n"
    246 				"If \002pattern\002 is given, lists only users that match it (it must be in\n"
    247 				"the format nick!user@host[#realname]). If \002channel\002 is given, lists\n"
    248 				"only users that are on the given channel. If INVISIBLE is specified, only users\n"
    249 				"with the +i flag will be listed."));
    250 
    251 		const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
    252 		if (!regexengine.empty())
    253 		{
    254 			source.Reply(" ");
    255 			source.Reply(_("Regex matches are also supported using the %s engine.\n"
    256 					"Enclose your pattern in // if this is desired."), regexengine.c_str());
    257 		}
    258 
    259 		return true;
    260 	}
    261 };
    262 
    263 class OSList : public Module
    264 {
    265 	CommandOSChanList commandoschanlist;
    266 	CommandOSUserList commandosuserlist;
    267 
    268  public:
    269 	OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
    270 		commandoschanlist(this), commandosuserlist(this)
    271 	{
    272 
    273 	}
    274 };
    275 
    276 MODULE_INIT(OSList)