Anope IRC Services  Version 2.0
m_xmlrpc_main.cpp
Go to the documentation of this file.
1 #include "module.h"
2 #include "modules/xmlrpc.h"
3 
4 static Module *me;
5 
7 {
9  HTTPReply repl; /* Request holds a reference to the HTTPReply, because we might exist long enough to invalidate it
10  we'll copy it here then reset the reference before we use it */
13 
14  public:
15  XMLRPCIdentifyRequest(Module *m, XMLRPCRequest& req, HTTPClient *c, XMLRPCServiceInterface* iface, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), request(req), repl(request.r), client(c), xinterface(iface) { }
16 
18  {
19  if (!xinterface || !client)
20  return;
21 
22  request.r = this->repl;
23 
24  request.reply("result", "Success");
25  request.reply("account", GetAccount());
26 
27  xinterface->Reply(request);
28  client->SendReply(&request.r);
29  }
30 
32  {
33  if (!xinterface || !client)
34  return;
35 
36  request.r = this->repl;
37 
38  request.reply("error", "Invalid password");
39 
40  xinterface->Reply(request);
41  client->SendReply(&request.r);
42  }
43 };
44 
45 class MyXMLRPCEvent : public XMLRPCEvent
46 {
47  public:
49  {
50  if (request.name == "command")
51  this->DoCommand(iface, client, request);
52  else if (request.name == "checkAuthentication")
53  return this->DoCheckAuthentication(iface, client, request);
54  else if (request.name == "stats")
55  this->DoStats(iface, client, request);
56  else if (request.name == "channel")
57  this->DoChannel(iface, client, request);
58  else if (request.name == "user")
59  this->DoUser(iface, client, request);
60  else if (request.name == "opers")
61  this->DoOperType(iface, client, request);
62 
63  return true;
64  }
65 
66  private:
67  void DoCommand(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
68  {
69  Anope::string service = request.data.size() > 0 ? request.data[0] : "";
70  Anope::string user = request.data.size() > 1 ? request.data[1] : "";
71  Anope::string command = request.data.size() > 2 ? request.data[2] : "";
72 
73  if (service.empty() || user.empty() || command.empty())
74  request.reply("error", "Invalid parameters");
75  else
76  {
77  BotInfo *bi = BotInfo::Find(service, true);
78  if (!bi)
79  request.reply("error", "Invalid service");
80  else
81  {
82  request.reply("result", "Success");
83 
84  NickAlias *na = NickAlias::Find(user);
85 
86  Anope::string out;
87 
88  struct XMLRPCommandReply : CommandReply
89  {
90  Anope::string &str;
91 
92  XMLRPCommandReply(Anope::string &s) : str(s) { }
93 
94  void SendMessage(BotInfo *, const Anope::string &msg) anope_override
95  {
96  str += msg + "\n";
97  };
98  }
99  reply(out);
100 
101  CommandSource source(user, NULL, na ? *na->nc : NULL, &reply, bi);
102  Command::Run(source, command);
103 
104  if (!out.empty())
105  request.reply("return", iface->Sanitize(out));
106  }
107  }
108  }
109 
111  {
112  Anope::string username = request.data.size() > 0 ? request.data[0] : "";
113  Anope::string password = request.data.size() > 1 ? request.data[1] : "";
114 
115  if (username.empty() || password.empty())
116  request.reply("error", "Invalid parameters");
117  else
118  {
119  XMLRPCIdentifyRequest *req = new XMLRPCIdentifyRequest(me, request, client, iface, username, password);
120  FOREACH_MOD(OnCheckAuthentication, (NULL, req));
121  req->Dispatch();
122  return false;
123  }
124 
125  return true;
126  }
127 
128  void DoStats(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
129  {
130  request.reply("uptime", stringify(Anope::CurTime - Anope::StartTime));
131  request.reply("uplinkname", Me->GetLinks().front()->GetName());
132  {
133  Anope::string buf;
134  for (std::set<Anope::string>::iterator it = Servers::Capab.begin(); it != Servers::Capab.end(); ++it)
135  buf += " " + *it;
136  if (!buf.empty())
137  buf.erase(buf.begin());
138  request.reply("uplinkcapab", buf);
139  }
140  request.reply("usercount", stringify(UserListByNick.size()));
141  request.reply("maxusercount", stringify(MaxUserCount));
142  request.reply("channelcount", stringify(ChannelList.size()));
143  }
144 
146  {
147  if (request.data.empty())
148  return;
149 
150  Channel *c = Channel::Find(request.data[0]);
151 
152  request.reply("name", iface->Sanitize(c ? c->name : request.data[0]));
153 
154  if (c)
155  {
156  request.reply("bancount", stringify(c->HasMode("BAN")));
157  int count = 0;
158  std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = c->GetModeList("BAN");
159  for (; its.first != its.second; ++its.first)
160  request.reply("ban" + stringify(++count), iface->Sanitize(its.first->second));
161 
162  request.reply("exceptcount", stringify(c->HasMode("EXCEPT")));
163  count = 0;
164  its = c->GetModeList("EXCEPT");
165  for (; its.first != its.second; ++its.first)
166  request.reply("except" + stringify(++count), iface->Sanitize(its.first->second));
167 
168  request.reply("invitecount", stringify(c->HasMode("INVITEOVERRIDE")));
169  count = 0;
170  its = c->GetModeList("INVITEOVERRIDE");
171  for (; its.first != its.second; ++its.first)
172  request.reply("invite" + stringify(++count), iface->Sanitize(its.first->second));
173 
174  Anope::string users;
175  for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it)
176  {
177  ChanUserContainer *uc = it->second;
178  users += uc->status.BuildModePrefixList() + uc->user->nick + " ";
179  }
180  if (!users.empty())
181  {
182  users.erase(users.length() - 1);
183  request.reply("users", iface->Sanitize(users));
184  }
185 
186  if (!c->topic.empty())
187  request.reply("topic", iface->Sanitize(c->topic));
188 
189  if (!c->topic_setter.empty())
190  request.reply("topicsetter", iface->Sanitize(c->topic_setter));
191 
192  request.reply("topictime", stringify(c->topic_time));
193  request.reply("topicts", stringify(c->topic_ts));
194  }
195  }
196 
197  void DoUser(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
198  {
199  if (request.data.empty())
200  return;
201 
202  User *u = User::Find(request.data[0]);
203 
204  request.reply("nick", iface->Sanitize(u ? u->nick : request.data[0]));
205 
206  if (u)
207  {
208  request.reply("ident", iface->Sanitize(u->GetIdent()));
209  request.reply("vident", iface->Sanitize(u->GetVIdent()));
210  request.reply("host", iface->Sanitize(u->host));
211  if (!u->vhost.empty())
212  request.reply("vhost", iface->Sanitize(u->vhost));
213  if (!u->chost.empty())
214  request.reply("chost", iface->Sanitize(u->chost));
215  request.reply("ip", u->ip.addr());
216  request.reply("timestamp", stringify(u->timestamp));
217  request.reply("signon", stringify(u->signon));
218  if (u->Account())
219  {
220  request.reply("account", iface->Sanitize(u->Account()->display));
221  if (u->Account()->o)
222  request.reply("opertype", iface->Sanitize(u->Account()->o->ot->GetName()));
223  }
224 
225  Anope::string channels;
226  for (User::ChanUserList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it)
227  {
228  ChanUserContainer *cc = it->second;
229  channels += cc->status.BuildModePrefixList() + cc->chan->name + " ";
230  }
231  if (!channels.empty())
232  {
233  channels.erase(channels.length() - 1);
234  request.reply("channels", channels);
235  }
236  }
237  }
238 
240  {
241  for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
242  {
243  OperType *ot = Config->MyOperTypes[i];
244  Anope::string perms;
245  for (std::list<Anope::string>::const_iterator it2 = ot->GetPrivs().begin(), it2_end = ot->GetPrivs().end(); it2 != it2_end; ++it2)
246  perms += " " + *it2;
247  for (std::list<Anope::string>::const_iterator it2 = ot->GetCommands().begin(), it2_end = ot->GetCommands().end(); it2 != it2_end; ++it2)
248  perms += " " + *it2;
249  request.reply(ot->GetName(), perms);
250  }
251  }
252 };
253 
254 class ModuleXMLRPCMain : public Module
255 {
257 
259 
260  public:
261  ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), xmlrpc("XMLRPCServiceInterface", "xmlrpc")
262  {
263  me = this;
264 
265  if (!xmlrpc)
266  throw ModuleException("Unable to find xmlrpc reference, is m_xmlrpc loaded?");
267 
268  xmlrpc->Register(&stats);
269  }
270 
272  {
273  if (xmlrpc)
274  xmlrpc->Unregister(&stats);
275  }
276 };
277 
279 
Serialize::Reference< NickCore > nc
Definition: account.h:47
Definition: bots.h:24
static Module * me
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
const Anope::string & GetIdent() const
Definition: users.cpp:264
ServiceReference< XMLRPCServiceInterface > xmlrpc
time_t signon
Definition: users.h:79
CoreExport time_t StartTime
Definition: main.cpp:40
CoreExport std::set< Anope::string > Capab
Definition: servers.cpp:29
void OnSuccess() anope_override
Anope::string addr() const
Definition: sockets.cpp:73
ChanUserList chans
Definition: users.h:87
const Anope::string & GetName() const
Definition: opertype.cpp:113
void Dispatch()
Definition: account.cpp:57
Definition: users.h:34
Anope::string topic_setter
Definition: channels.h:61
void DoStats(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
CoreExport unsigned MaxUserCount
Definition: users.cpp:31
virtual void SendReply(HTTPReply *)=0
ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator)
time_t topic_ts
Definition: channels.h:66
Reference< HTTPClient > client
Anope::string name
Definition: channels.h:44
CoreExport time_t CurTime
Definition: main.cpp:41
Anope::string topic
Definition: channels.h:59
void DoChannel(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
void DoOperType(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
iterator erase(const iterator &i)
Definition: anope.h:155
std::pair< ModeList::iterator, ModeList::iterator > GetModeList(const Anope::string &name)
Definition: channels.cpp:243
Channel * chan
Definition: channels.h:26
void DoUser(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
time_t timestamp
Definition: users.h:81
size_type length() const
Definition: anope.h:131
void reply(const Anope::string &dname, const Anope::string &ddata)
Definition: xmlrpc.h:14
void OnFail() anope_override
Definition: Config.cs:26
OperType * ot
Definition: opertype.h:23
const std::list< Anope::string > GetPrivs() const
Definition: opertype.cpp:137
virtual Anope::string Sanitize(const Anope::string &string)=0
Anope::string display
Definition: account.h:113
Oper * o
Definition: account.h:131
const Anope::string & GetVIdent() const
Definition: users.cpp:247
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) anope_override
const std::list< Anope::string > GetCommands() const
Definition: opertype.cpp:124
static void Run(CommandSource &source, const Anope::string &message)
Definition: command.cpp:199
Anope::string host
Definition: users.h:65
sockaddrs ip
Definition: users.h:75
XMLRPCIdentifyRequest(Module *m, XMLRPCRequest &req, HTTPClient *c, XMLRPCServiceInterface *iface, const Anope::string &acc, const Anope::string &pass)
XMLRPCRequest request
time_t topic_time
Definition: channels.h:68
#define MODULE_INIT(x)
Definition: modules.h:45
virtual void Reply(XMLRPCRequest &request)=0
CoreExport channel_map ChannelList
Definition: channels.cpp:29
ChanUserList users
Definition: channels.h:56
const std::vector< Server * > & GetLinks() const
Definition: servers.cpp:216
size_t HasMode(const Anope::string &name, const Anope::string &param="")
Definition: channels.cpp:201
ChannelStatus status
Definition: channels.h:28
Anope::string stringify(const T &x)
Definition: anope.h:710
Anope::string nick
Definition: users.h:62
Reference< XMLRPCServiceInterface > xinterface
HTTPReply & r
Definition: xmlrpc.h:11
static User * Find(const Anope::string &name, bool nick_only=false)
Definition: users.cpp:815
Anope::string chost
Definition: users.h:69
NickCore * Account() const
Definition: users.cpp:422
static Channel * Find(const Anope::string &name)
Definition: channels.cpp:920
CoreExport Server * Me
Definition: servers.cpp:24
CoreExport user_map UserListByNick
Definition: users.cpp:28
std::deque< Anope::string > data
Definition: xmlrpc.h:10
bool DoCheckAuthentication(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
iterator begin()
Definition: anope.h:282
static BotInfo * Find(const Anope::string &nick, bool nick_only=false)
Definition: bots.cpp:249
Anope::string vhost
Definition: users.h:67
void DoCommand(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
Definition: modules.h:163
Anope::string BuildModePrefixList() const
Definition: modes.cpp:101
MyXMLRPCEvent stats
const Anope::string & GetAccount() const
Definition: account.h:250