Anope IRC Services  Version 2.0
cs_clone.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/bs_badwords.h"
14 
15 class CommandCSClone : public Command
16 {
17 public:
18  CommandCSClone(Module *creator) : Command(creator, "chanserv/clone", 2, 3)
19  {
20  this->SetDesc(_("Copy all settings from one channel to another"));
21  this->SetSyntax(_("\037channel\037 \037target\037 [\037what\037]"));
22  }
23 
24  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
25  {
26  const Anope::string &channel = params[0];
27  const Anope::string &target = params[1];
28  Anope::string what = params.size() > 2 ? params[2] : "";
29 
30  if (Anope::ReadOnly)
31  {
32  source.Reply(READ_ONLY_MODE);
33  return;
34  }
35 
36  User *u = source.GetUser();
37  ChannelInfo *ci = ChannelInfo::Find(params[0]);
38  bool override = false;
39 
40  if (ci == NULL)
41  {
42  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
43  return;
44  }
45 
46  ChannelInfo *target_ci = ChannelInfo::Find(target);
47  if (!target_ci)
48  {
49  source.Reply(CHAN_X_NOT_REGISTERED, target.c_str());
50  return;
51  }
52 
53  if (ci == target_ci)
54  {
55  source.Reply(_("Cannot clone channel \002%s\002 to itself!"), target.c_str());
56  return;
57  }
58 
59  if (!source.IsFounder(ci) || !source.IsFounder(target_ci))
60  {
61  if (!source.HasPriv("chanserv/administration"))
62  {
63  source.Reply(ACCESS_DENIED);
64  return;
65  }
66  else
67  override = true;
68  }
69 
70  if (what.equals_ci("ALL"))
71  what.clear();
72 
73  if (what.empty())
74  {
75  delete target_ci;
76  target_ci = new ChannelInfo(*ci);
77  target_ci->name = target;
78  (*RegisteredChannelList)[target_ci->name] = target_ci;
79  target_ci->c = Channel::Find(target_ci->name);
80 
81  target_ci->bi = NULL;
82  if (ci->bi)
83  ci->bi->Assign(u, target_ci);
84 
85  if (target_ci->c)
86  {
87  target_ci->c->ci = target_ci;
88 
89  target_ci->c->CheckModes();
90 
91  target_ci->c->SetCorrectModes(u, true);
92  }
93 
94  if (target_ci->c && !target_ci->c->topic.empty())
95  {
96  target_ci->last_topic = target_ci->c->topic;
97  target_ci->last_topic_setter = target_ci->c->topic_setter;
98  target_ci->last_topic_time = target_ci->c->topic_time;
99  }
100  else
101  target_ci->last_topic_setter = source.service->nick;
102 
103  FOREACH_MOD(OnChanRegistered, (target_ci));
104 
105  source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str());
106  }
107  else if (what.equals_ci("ACCESS"))
108  {
109  std::set<Anope::string> masks;
110  unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
111  unsigned count = 0;
112 
113  for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i)
114  masks.insert(target_ci->GetAccess(i)->Mask());
115 
116  for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
117  {
118  const ChanAccess *taccess = ci->GetAccess(i);
119  AccessProvider *provider = taccess->provider;
120 
121  if (access_max && target_ci->GetDeepAccessCount() >= access_max)
122  break;
123 
124  if (masks.count(taccess->Mask()))
125  continue;
126  masks.insert(taccess->Mask());
127 
128  ChanAccess *newaccess = provider->Create();
129  newaccess->SetMask(taccess->Mask(), target_ci);
130  newaccess->creator = taccess->creator;
131  newaccess->last_seen = taccess->last_seen;
132  newaccess->created = taccess->created;
133  newaccess->AccessUnserialize(taccess->AccessSerialize());
134 
135  target_ci->AddAccess(newaccess);
136 
137  ++count;
138  }
139 
140  source.Reply(_("%d access entries from \002%s\002 have been cloned to \002%s\002."), count, channel.c_str(), target.c_str());
141  }
142  else if (what.equals_ci("AKICK"))
143  {
144  target_ci->ClearAkick();
145  for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
146  {
147  const AutoKick *akick = ci->GetAkick(i);
148  if (akick->nc)
149  target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
150  else
151  target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
152  }
153 
154  source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str());
155  }
156  else if (what.equals_ci("BADWORDS"))
157  {
158  BadWords *target_badwords = target_ci->Require<BadWords>("badwords"),
159  *badwords = ci->Require<BadWords>("badwords");
160 
161  if (!target_badwords || !badwords)
162  {
163  source.Reply(ACCESS_DENIED); // BotServ doesn't exist/badwords isn't loaded
164  return;
165  }
166 
167  target_badwords->ClearBadWords();
168 
169  for (unsigned i = 0; i < badwords->GetBadWordCount(); ++i)
170  {
171  const BadWord *bw = badwords->GetBadWord(i);
172  target_badwords->AddBadWord(bw->word, bw->type);
173  }
174 
175  badwords->Check();
176  target_badwords->Check();
177 
178  source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str());
179  }
180  else
181  {
182  this->OnSyntaxError(source, "");
183  return;
184  }
185 
186  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->name;
187  }
188 
189  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
190  {
191  this->SendSyntax(source);
192  source.Reply(" ");
193  source.Reply(_("Copies all settings, access, akicks, etc from \002channel\002 to the\n"
194  "\002target\002 channel. If \037what\037 is \002ACCESS\002, \002AKICK\002, or \002BADWORDS\002\n"
195  "then only the respective settings are cloned.\n"
196  "You must be the founder of \037channel\037 and \037target\037."));
197  return true;
198  }
199 };
200 
201 class CSClone : public Module
202 {
204 
205  public:
206  CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsclone(this)
207  {
208 
209  }
210 };
211 
CoreExport bool ReadOnly
Definition: main.cpp:28
CommandCSClone commandcsclone
Definition: cs_clone.cpp:203
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: cs_clone.cpp:24
Definition: hashcomp.h:84
unsigned GetAkickCount() const
Definition: regchannel.cpp:562
void clear()
Definition: anope.h:187
CSClone(const Anope::string &modname, const Anope::string &creator)
Definition: cs_clone.cpp:206
Anope::string name
Definition: regchannel.h:63
#define ACCESS_DENIED
Definition: language.h:73
time_t last_topic_time
Definition: regchannel.h:71
Definition: users.h:34
Anope::string topic_setter
Definition: channels.h:61
Anope::string creator
Definition: access.h:93
virtual Anope::string AccessSerialize() const =0
unsigned GetDeepAccessCount() const
Definition: regchannel.cpp:479
time_t created
Definition: access.h:95
#define READ_ONLY_MODE
Definition: language.h:71
BadWordType type
Definition: bs_badwords.h:33
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
Serialize::Reference< ChannelInfo > ci
Definition: channels.h:46
Anope::string word
Definition: bs_badwords.h:32
T * Require(const Anope::string &name)
Definition: extensible.h:244
virtual void AccessUnserialize(const Anope::string &data)=0
Anope::string topic
Definition: channels.h:59
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
void CheckModes()
Definition: channels.cpp:105
virtual void Check()=0
Definition: Config.cs:26
Channel * c
Definition: regchannel.h:79
time_t last_seen
Definition: access.h:94
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
Anope::string reason
Definition: regchannel.h:35
time_t last_used
Definition: regchannel.h:38
const Anope::string & Mask() const
Definition: access.cpp:196
virtual ChanAccess * Create()=0
unsigned GetAccessCount() const
Definition: regchannel.cpp:474
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
void AddAccess(ChanAccess *access)
Definition: regchannel.cpp:398
Anope::string last_topic_setter
Definition: regchannel.h:70
void SetCorrectModes(User *u, bool give_modes)
Definition: channels.cpp:816
time_t topic_time
Definition: channels.h:68
Anope::string creator
Definition: regchannel.h:36
AccessProvider * provider
Definition: access.h:90
#define MODULE_INIT(x)
Definition: modules.h:45
CommandCSClone(Module *creator)
Definition: cs_clone.cpp:18
AutoKick * GetAkick(unsigned index) const
Definition: regchannel.cpp:552
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
Anope::string last_topic
Definition: regchannel.h:69
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
virtual void ClearBadWords()=0
Anope::string mask
Definition: regchannel.h:32
Serialize::Reference< NickCore > nc
Definition: regchannel.h:33
static Channel * Find(const Anope::string &name)
Definition: channels.cpp:920
void SendSyntax(CommandSource &)
Definition: command.cpp:145
virtual BadWord * AddBadWord(const Anope::string &word, BadWordType type)=0
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
void SetMask(const Anope::string &mask, ChannelInfo *ci)
Definition: access.cpp:165
AutoKick * AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t=Anope::CurTime, time_t lu=0)
Definition: regchannel.cpp:519
Serialize::Reference< BotInfo > bi
Definition: regchannel.h:82
time_t addtime
Definition: regchannel.h:37
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: cs_clone.cpp:189
#define _(x)
Definition: services.h:50
ChanAccess * GetAccess(unsigned index) const
Definition: regchannel.cpp:403
void ClearAkick()
Definition: regchannel.cpp:575