Anope IRC Services  Version 2.0
cs_list.cpp
Go to the documentation of this file.
1 /* ChanServ core functions
2  *
3  * (C) 2003-2014 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 #include "modules/cs_mode.h"
14 
15 class CommandCSList : public Command
16 {
17  public:
18  CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
19  {
20  this->SetDesc(_("Lists all registered channels matching the given pattern"));
21  this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]"));
22  }
23 
24  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
25  {
26  Anope::string pattern = params[0];
27  unsigned nchans;
28  bool is_servadmin = source.HasCommand("chanserv/list");
29  int count = 0, from = 0, to = 0;
30  bool suspended = false, channoexpire = false;
31 
32  if (pattern[0] == '#')
33  {
34  Anope::string n1, n2;
35  sepstream(pattern.substr(1), '-').GetToken(n1, 0);
36  sepstream(pattern, '-').GetToken(n2, 1);
37 
38  try
39  {
40  from = convertTo<int>(n1);
41  to = convertTo<int>(n2);
42  }
43  catch (const ConvertException &)
44  {
45  source.Reply(LIST_INCORRECT_RANGE);
46  source.Reply(_("To search for channels starting with #, search for the channel\n"
47  "name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
48  return;
49  }
50 
51  pattern = "*";
52  }
53 
54  nchans = 0;
55 
56  if (is_servadmin && params.size() > 1)
57  {
58  Anope::string keyword;
59  spacesepstream keywords(params[1]);
60  while (keywords.GetToken(keyword))
61  {
62  if (keyword.equals_ci("SUSPENDED"))
63  suspended = true;
64  if (keyword.equals_ci("NOEXPIRE"))
65  channoexpire = true;
66  }
67  }
68 
69  Anope::string spattern = "#" + pattern;
70  unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax", "50");
71 
72  source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
73 
74  ListFormatter list(source.GetAccount());
75  list.AddColumn(_("Name")).AddColumn(_("Description"));
76 
77  Anope::map<ChannelInfo *> ordered_map;
78  for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
79  ordered_map[it->first] = it->second;
80 
81  for (Anope::map<ChannelInfo *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it)
82  {
83  const ChannelInfo *ci = it->second;
84 
85  if (!is_servadmin)
86  {
87  if (ci->HasExt("CS_PRIVATE") || ci->HasExt("CS_SUSPENDED"))
88  continue;
89  if (ci->c && ci->c->HasMode("SECRET"))
90  continue;
91 
92  ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
93  const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL;
94  if (secret && secret->set)
95  continue;
96  }
97 
98  if (suspended && !ci->HasExt("CS_SUSPENDED"))
99  continue;
100 
101  if (channoexpire && !ci->HasExt("CS_NO_EXPIRE"))
102  continue;
103 
104  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))
105  {
106  if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax)
107  {
108  bool isnoexpire = false;
109  if (is_servadmin && (ci->HasExt("CS_NO_EXPIRE")))
110  isnoexpire = true;
111 
113  entry["Name"] = (isnoexpire ? "!" : "") + ci->name;
114  if (ci->HasExt("CS_SUSPENDED"))
115  entry["Description"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
116  else
117  entry["Description"] = ci->desc;
118  list.AddEntry(entry);
119  }
120  ++count;
121  }
122  }
123 
124  std::vector<Anope::string> replies;
125  list.Process(replies);
126 
127  for (unsigned i = 0; i < replies.size(); ++i)
128  source.Reply(replies[i]);
129 
130  source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans);
131  }
132 
133  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
134  {
135  this->SendSyntax(source);
136  source.Reply(" ");
137  source.Reply(_("Lists all registered channels matching the given pattern.\n"
138  "Channels with the \002PRIVATE\002 option set will only be\n"
139  "displayed to Services Operators with the proper access.\n"
140  "Channels with the \002NOEXPIRE\002 option set will have\n"
141  "a \002!\002 prefixed to the channel for Services Operators to see.\n"
142  " \n"
143  "Note that a preceding '#' specifies a range, channel names\n"
144  "are to be written without '#'.\n"
145  " \n"
146  "If the SUSPENDED or NOEXPIRE options are given, only channels\n"
147  "which, respectively, are SUSPENDED or have the NOEXPIRE\n"
148  "flag set will be displayed. If multiple options are given,\n"
149  "all channels matching at least one option will be displayed.\n"
150  "Note that these options are limited to \037Services Operators\037.\n"
151  " \n"
152  "Examples:\n"
153  " \n"
154  " \002LIST *anope*\002\n"
155  " Lists all registered channels with \002anope\002 in their\n"
156  " names (case insensitive).\n"
157  " \n"
158  " \002LIST * NOEXPIRE\002\n"
159  " Lists all registered channels which have been set to not expire.\n"
160  " \n"
161  " \002LIST #51-100\002\n"
162  " Lists all registered channels within the given range (51-100)."));
163 
164  if (!Config->GetBlock("options")->Get<const Anope::string>("regexengine").empty())
165  {
166  source.Reply(" ");
167  source.Reply(_("Regex matches are also supported using the %s engine.\n"
168  "Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<const Anope::string>("regexengine").c_str());
169  }
170 
171  return true;
172  }
173 };
174 
176 {
177  public:
178  CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2)
179  {
180  this->SetDesc(_("Hide channel from the LIST command"));
181  this->SetSyntax(_("\037channel\037 {ON | OFF}"));
182  }
183 
184  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
185  {
186  if (Anope::ReadOnly)
187  {
188  source.Reply(READ_ONLY_MODE);
189  return;
190  }
191 
192  ChannelInfo *ci = ChannelInfo::Find(params[0]);
193  if (ci == NULL)
194  {
195  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
196  return;
197  }
198 
199  EventReturn MOD_RESULT;
200  FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1]));
201  if (MOD_RESULT == EVENT_STOP)
202  return;
203 
204  if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
205  {
206  source.Reply(ACCESS_DENIED);
207  return;
208  }
209 
210  if (params[1].equals_ci("ON"))
211  {
212  Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable private";
213  ci->Extend<bool>("CS_PRIVATE");
214  source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str());
215  }
216  else if (params[1].equals_ci("OFF"))
217  {
218  Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable private";
219  ci->Shrink<bool>("CS_PRIVATE");
220  source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str());
221  }
222  else
223  this->OnSyntaxError(source, "PRIVATE");
224 
225  return;
226  }
227 
229  {
230  this->SendSyntax(source);
231  source.Reply(" ");
232  source.Reply(_("Enables or disables the \002private\002 option for a channel."));
233 
234  BotInfo *bi;
235  Anope::string cmd;
236  if (Command::FindCommandFromService("chanserv/list", bi, cmd))
237  source.Reply(_("When \002private\002 is set, the channel will not appear in\n"
238  "%s's %s command."), bi->nick.c_str(), cmd.c_str());
239  return true;
240  }
241 };
242 
243 class CSList : public Module
244 {
247 
249 
250  public:
251  CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
252  commandcslist(this), commandcssetprivate(this), priv(this, "CS_PRIVATE")
253  {
254  }
255 
256  void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
257  {
258  if (!show_all)
259  return;
260 
261  if (priv.HasExt(ci))
262  info.AddOption(_("Private"));
263  }
264 };
265 
Definition: bots.h:24
CoreExport bool ReadOnly
Definition: main.cpp:28
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
Definition: cs_list.cpp:228
Definition: hashcomp.h:84
Anope::string name
Definition: regchannel.h:63
Anope::string desc
Definition: regchannel.h:64
#define ACCESS_DENIED
Definition: language.h:73
CSList(const Anope::string &modname, const Anope::string &creator)
Definition: cs_list.cpp:251
static bool FindCommandFromService(const Anope::string &command_service, BotInfo *&bi, Anope::string &name)
Definition: command.cpp:287
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
CommandCSSetPrivate commandcssetprivate
Definition: cs_list.cpp:246
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: cs_list.cpp:184
#define READ_ONLY_MODE
Definition: language.h:71
#define FOREACH_RESULT(ename, ret, args)
Definition: modules.h:95
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
CommandCSList commandcslist
Definition: cs_list.cpp:245
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
std::map< Anope::string, Anope::string > ListEntry
Definition: lists.h:68
Definition: Config.cs:26
Channel * c
Definition: regchannel.h:79
void Shrink(const Anope::string &name)
Definition: extensible.h:253
CoreExport bool Match(const string &str, const string &mask, bool case_sensitive=false, bool use_regex=false)
Definition: misc.cpp:407
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
void Reply(const char *message,...)
Definition: command.cpp:96
CoreExport Serialize::Checker< registered_channel_map > RegisteredChannelList
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: cs_list.cpp:24
virtual const ModeList & GetMLock() const =0
#define anope_override
Definition: services.h:56
void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override
Definition: cs_list.cpp:256
#define LIST_INCORRECT_RANGE
Definition: language.h:90
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
CoreExport const char * Translate(const char *string)
Definition: language.cpp:59
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
size_t HasMode(const Anope::string &name, const Anope::string &param="")
Definition: channels.cpp:201
Anope::string last_topic
Definition: regchannel.h:69
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
Anope::string nick
Definition: users.h:62
CommandCSSetPrivate(Module *creator, const Anope::string &cname="chanserv/set/private")
Definition: cs_list.cpp:178
SerializableExtensibleItem< bool > priv
Definition: cs_list.cpp:248
bool GetToken(Anope::string &token)
Definition: hashcomp.cpp:99
void SendSyntax(CommandSource &)
Definition: command.cpp:145
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
T * GetExt(const Anope::string &name) const
Definition: extensible.h:213
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: cs_list.cpp:133
bool HasExt(const Extensible *obj) const
Definition: extensible.h:111
#define _(x)
Definition: services.h:50
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31
ListFormatter & AddColumn(const Anope::string &name)
Definition: misc.cpp:128
CommandCSList(Module *creator)
Definition: cs_list.cpp:18
Module * owner
Definition: service.h:84