diff options
-rw-r--r-- | data/example.conf | 33 | ||||
-rw-r--r-- | include/extern.h | 8 | ||||
-rw-r--r-- | include/sockets.h | 2 | ||||
-rw-r--r-- | include/users.h | 13 | ||||
-rw-r--r-- | modules/extra/m_xmlrpc.cpp | 270 | ||||
-rw-r--r-- | modules/extra/m_xmlrpc_main.cpp | 284 | ||||
-rw-r--r-- | modules/extra/xmlrpc.h | 75 | ||||
-rw-r--r-- | src/language.cpp | 6 | ||||
-rw-r--r-- | src/misc.cpp | 4 | ||||
-rw-r--r-- | src/users.cpp | 15 |
10 files changed, 683 insertions, 27 deletions
diff --git a/data/example.conf b/data/example.conf index 0b0c1abcd..e573cbaac 100644 --- a/data/example.conf +++ b/data/example.conf @@ -1805,3 +1805,36 @@ blacklist reason = "You have a host listed in the DroneBL. For more information, visit http://dronebl.org/lookup.do?ip=%i" } +/* + * m_xmlrpc + * + * Allows remote applications (websites) to execute queries in real time to retrieve data from Anope. + * By itself this module does nothing, but allows other modules (m_xmlrpc_main) to receive and send XMLRPC queries. + */ +#module { name = "m_xmlrpc" } +m_xmlrpc +{ + /* IP to listen on */ + bindip = "127.0.0.1" + /* Port to listen on */ + port = 16673 + /* Enable for IPv6 */ + ipv6 = no + /* If enabled, requires m_ssl is loaded */ + ssl = no + /* IPs allowed to connect (separate with spaces), this should be secured. We also recommend you firewall this + * with an outside program to ensure security. + */ + allowed = "127.0.0.1" + /* An optional username and password, if supplied clients using XMLRPC must authenticate first using it */ + username = "anope" + password = "mypass" +} + +/* + * m_xmlrpc_main + * + * Main XMLRPC function, adds many core methods that may be required for XMLRPC to work right (such as login). + */ +#module { name = "m_xmlrpc_main" } + diff --git a/include/extern.h b/include/extern.h index c1d01d79f..02b5d91f8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -157,8 +157,8 @@ E std::vector<Anope::string> languages; E void InitLanguages(); E const Anope::string GetString(const Anope::string &language, LanguageString string); E const Anope::string GetString(LanguageString string); -E const Anope::string GetString(const NickCore *nc, LanguageString string); -E const Anope::string GetString(const User *u, LanguageString string); +E const Anope::string GetString(NickCore *nc, LanguageString string); +E const Anope::string GetString(User *u, LanguageString string); E const Anope::string GetString(const char *domain, Anope::string language, const Anope::string &string); E Anope::string language_strings[LANG_STRING_COUNT]; E void SyntaxError(BotInfo *bi, User *u, const Anope::string &command, LanguageString message); @@ -239,8 +239,8 @@ E const char *merge_args(int argc, char **argv); E const char *merge_args(int argc, const char **argv); E time_t dotime(const Anope::string &s); -E Anope::string duration(const NickCore *nc, time_t seconds); -E Anope::string expire_left(const NickCore *nc, time_t expires); +E Anope::string duration(NickCore *nc, time_t seconds); +E Anope::string expire_left(NickCore *nc, time_t expires); E Anope::string do_strftime(const time_t &t); E bool doValidHost(const Anope::string &host, int type); diff --git a/include/sockets.h b/include/sockets.h index 2f1b3c8d7..a24e346d7 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -330,11 +330,11 @@ class CoreExport ConnectionSocket : public BufferedSocket class ClientSocket : public BufferedSocket { + public: /* Listen socket this connection came from */ ListenSocket *LS; /* Clients address */ sockaddrs clientaddr; - public: /** Constructor * @param ls Listen socket this connection is from diff --git a/include/users.h b/include/users.h index 889eca357..776ce450c 100644 --- a/include/users.h +++ b/include/users.h @@ -90,7 +90,7 @@ class CoreExport User : public Extensible /** Update the nickname of a user record accordingly, should be * called from ircd protocol. */ - virtual void SetNewNick(const Anope::string &newnick); + void SetNewNick(const Anope::string &newnick); /** Update the displayed (vhost) of a user record. * This is used (if set) instead of real host. @@ -155,15 +155,15 @@ class CoreExport User : public Extensible * @param fmt Format of the Message * @param ... any number of parameters */ - virtual void SendMessage(const Anope::string &source, const char *fmt, ...) const; - virtual void SendMessage(const Anope::string &source, const Anope::string &msg) const; + void SendMessage(const Anope::string &source, const char *fmt, ...); + virtual void SendMessage(const Anope::string &source, const Anope::string &msg); /** Send a language string message to a user * @param source Sender * @param message The message num * @param ... parameters */ - void SendMessage(BotInfo *source, LanguageString message, ...) const; + void SendMessage(BotInfo *source, LanguageString message, ...); /** Collide a nick * See the comment in users.cpp @@ -184,19 +184,18 @@ class CoreExport User : public Extensible * @return The account or NULL */ virtual NickCore *Account(); - virtual const NickCore *Account() const; /** Check if the user is identified for their nick * @param CheckNick True to check if the user is identified to the nickname they are on too * @return true or false */ - virtual bool IsIdentified(bool CheckNick = false) const; + virtual bool IsIdentified(bool CheckNick = false); /** Check if the user is recognized for their nick (on the nicks access list) * @param CheckSecure Only returns true if the user has secure off * @return true or false */ - virtual bool IsRecognized(bool CheckSecure = false) const; + virtual bool IsRecognized(bool CheckSecure = false); /** Update the last usermask stored for a user, and check to see if they are recognized */ diff --git a/modules/extra/m_xmlrpc.cpp b/modules/extra/m_xmlrpc.cpp new file mode 100644 index 000000000..f71a260d0 --- /dev/null +++ b/modules/extra/m_xmlrpc.cpp @@ -0,0 +1,270 @@ +#include "module.h" +#include "ssl.h" +#include "xmlrpc.h" + +class MyXMLRPCClientSocket : public XMLRPCClientSocket +{ + public: + MyXMLRPCClientSocket(XMLRPCListenSocket *ls, int fd, const sockaddrs &addr) : XMLRPCClientSocket(ls, fd, addr) + { + if (ls->username.empty() && ls->password.empty()) + this->logged_in = true; + } + + bool Read(const Anope::string &message) + { + this->query += message; + Log(LOG_DEBUG) << "m_xmlrpc: " << message; + + if (message.find("</methodCall>") != Anope::string::npos) + { + this->HandleMessage(); + this->query.clear(); + } + return true; + } + + bool GetData(Anope::string &tag, Anope::string &data) + { + if (this->query.empty()) + return false; + + Anope::string prev, cur; + bool istag; + + do + { + prev = cur; + cur.clear(); + + int len = 0; + istag = false; + + if (this->query[0] == '<') + { + len = this->query.find_first_of('>'); + istag = true; + } + else if (this->query[0] != '>') + { + len = this->query.find_first_of('<'); + } + + if (len) + { + if (istag) + { + cur = this->query.substr(1, len - 1); + this->query.erase(0, len + 1); + while (!this->query.empty() && this->query[0] == ' ') + this->query.erase(this->query.begin()); + } + else + { + cur = this->query.substr(0,len); + this->query.erase(0, len); + } + } + } + while (istag && !this->query.empty()); + + tag = prev; + data = cur; + return !istag && !data.empty(); + } + + void HandleMessage(); +}; + +class MyXMLRPCListenSocket : public XMLRPCListenSocket +{ + public: + MyXMLRPCListenSocket(const Anope::string &bindip, int port, bool ipv6, const Anope::string &u, const Anope::string &p, const std::vector<Anope::string> &a) : XMLRPCListenSocket(bindip, port, ipv6, u, p, a) { } + + ClientSocket *OnAccept(int fd, const sockaddrs &addr) + { + MyXMLRPCClientSocket *socket = new MyXMLRPCClientSocket(this, fd, addr); + if (std::find(this->allowed.begin(), this->allowed.end(), addr.addr()) != this->allowed.end()) + Log() << "m_xmlrpc: Accepted connection " << fd << " from " << addr.addr(); + else + { + Log() << "m_xmlrpc: Dropping disallowed connection " << fd << " from " << addr.addr(); + socket->SetFlag(SF_DEAD); + } + return socket; + } +}; + +class MyXMLRPCServiceInterface : public XMLRPCServiceInterface +{ + std::deque<XMLRPCEvent *> events; + + public: + MyXMLRPCServiceInterface(Module *creator, const Anope::string &sname) : XMLRPCServiceInterface(creator, sname) { } + + void Register(XMLRPCEvent *event) + { + this->events.push_back(event); + } + + void Unregister(XMLRPCEvent *event) + { + std::deque<XMLRPCEvent *>::iterator it = std::find(this->events.begin(), this->events.end(), event); + + if (it != this->events.end()) + this->events.erase(it); + } + + void Reply(XMLRPCClientSocket *source, XMLRPCRequest *request) + { + if (!request->id.empty()) + request->reply("id", request->id); + + Anope::string reply = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<methodCall>\n<methodName>" + request->name + "</methodName>\n<params>\n<param>\n<value>\n<struct>\n"; + for (std::map<Anope::string, Anope::string>::const_iterator it = request->get_replies().begin(); it != request->get_replies().end(); ++it) + { + reply += "<member>\n<name>" + it->first + "</name>\n<value>\n<string>" + this->Sanitize(it->second) + "</string>\n</value>\n</member>\n"; + } + reply += "</struct>\n</value>\n</param>\n</params>\n</methodCall>"; + + source->Write(reply); + } + + Anope::string Sanitize(const Anope::string &string) + { + static struct special_chars + { + Anope::string character; + Anope::string replace; + + special_chars(const Anope::string &c, const Anope::string &r) : character(c), replace(r) { } + } + special[] = { + special_chars("&", "&"), + special_chars("\"", """), + special_chars("<", "<"), + special_chars(">", "&qt;"), + special_chars("'", "'"), + special_chars("\n", "
"), + special_chars("\002", ""), // bold + special_chars("\003", ""), // color + special_chars("\35", ""), // italics + special_chars("\031", ""), // underline + special_chars("\26", ""), // reverses + special_chars("", "") + }; + + Anope::string ret = string; + for (int i = 0; special[i].character.empty() == false; ++i) + ret = ret.replace_all_cs(special[i].character, special[i].replace); + return ret; + } + + void RunXMLRPC(XMLRPCClientSocket *source, XMLRPCRequest *request) + { + for (unsigned i = 0; i < this->events.size(); ++i) + { + XMLRPCEvent *e = this->events[i]; + + e->Run(this, source, request); + if (!request->get_replies().empty()) + this->Reply(source, request); + } + } +}; + +class ModuleXMLRPC; +static ModuleXMLRPC *me; +class ModuleXMLRPC : public Module +{ + std::vector<MyXMLRPCListenSocket *> listen_sockets; + service_reference<SSLService> sslref; + + public: + MyXMLRPCServiceInterface xmlrpcinterface; + + ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), sslref("ssl"), xmlrpcinterface(this, "xmlrpc") + { + me = this; + + OnReload(false); + + ModuleManager::RegisterService(&this->xmlrpcinterface); + + Implementation i[] = { I_OnReload }; + ModuleManager::Attach(i, this, 1); + } + + ~ModuleXMLRPC() + { + for (unsigned i = 0; i < this->listen_sockets.size(); ++i) + delete this->listen_sockets[i]; + this->listen_sockets.clear(); + } + + void OnReload(bool) + { + ConfigReader config; + + for (unsigned i = 0; i < this->listen_sockets.size(); ++i) + delete this->listen_sockets[i]; + this->listen_sockets.clear(); + + for (int i = 0; i < config.Enumerate("m_xmlrpc"); ++i) + { + Anope::string bindip = config.ReadValue("m_xmlrpc", "bindip", "0.0.0.0", i); + int port = config.ReadInteger("m_xmlrpc", "port", 0, i); + bool ipv6 = config.ReadFlag("m_xmlrpc", "ipv6", "no", i); + bool ssl = config.ReadFlag("m_xmlrpc", "ssl", "no", i); + Anope::string allowed = config.ReadValue("m_xmlrpc", "allowed", "127.0.0.1", i); + Anope::string username = config.ReadValue("m_xmlrpc", "username", "", i); + Anope::string password = config.ReadValue("m_xmlrpc", "password", "", i); + std::vector<Anope::string> allowed_vector = BuildStringVector(allowed, ' '); + + if (bindip.empty() || port < 1) + continue; + + if (ssl && !sslref) + { + Log() << "m_xmlrpc: Could not enable SSL, is m_ssl loaded?"; + ssl = false; + } + + try + { + MyXMLRPCListenSocket *xmls = new MyXMLRPCListenSocket(bindip, port, ipv6, username, password, allowed_vector); + if (ssl) + { + sslref->Init(xmls); + } + this->listen_sockets.push_back(xmls); + } + catch (const SocketException &ex) + { + Log() << "m_xmlrpc " << ex.GetReason(); + } + } + } +}; + +void MyXMLRPCClientSocket::HandleMessage() +{ + Anope::string name, data; + XMLRPCRequest request; + + while (this->GetData(name, data)) + { + if (name == "methodName") + request.name = data; + else if (name == "id") + request.id = data; + else if (name == "string") + request.data.push_back(data); + } + + if (request.name == "login" || this->logged_in) + me->xmlrpcinterface.RunXMLRPC(this, &request); +} + +MODULE_INIT(ModuleXMLRPC) + diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp new file mode 100644 index 000000000..a3062b7ad --- /dev/null +++ b/modules/extra/m_xmlrpc_main.cpp @@ -0,0 +1,284 @@ +#include "module.h" +#include "xmlrpc.h" + +class XMLRPCUser : public User +{ + Anope::string out; + dynamic_reference<NickAlias> na; + + public: + XMLRPCUser(const Anope::string &nnick) : User(nnick, Config->ServiceUser, Config->ServiceHost, ""), na(findnick(nick)) + { + this->realname = "XMLRPC User"; + this->server = Me; + } + + void SendMessage(const Anope::string &source, const Anope::string &msg) + { + this->out += msg + "\n"; + } + + NickCore *Account() + { + return (na ? na->nc : NULL); + } + + bool IsIdentified(bool CheckNick = false) + { + return na; + } + + bool IsRecognized(bool CheckSecure = false) + { + return na; + } + + const Anope::string &GetOut() + { + return this->out; + } +}; + +class MyXMLRPCEvent : public XMLRPCEvent +{ + public: + void Run(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + if (request->name == "login") + this->DoLogin(iface, source, request); + else if (request->name == "command") + this->DoCommand(iface, source, request); + else if (request->name == "checkAuthentication") + this->DoCheckAuthentication(iface, source, request); + else if (request->name == "stats") + this->DoStats(iface, source, request); + else if (request->name == "channel") + this->DoChannel(iface, source, request); + else if (request->name == "user") + this->DoUser(iface, source, request); + } + + void DoCommand(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + Anope::string service = request->data.size() > 0 ? request->data[0] : ""; + Anope::string user = request->data.size() > 1 ? request->data[1] : ""; + Anope::string command = request->data.size() > 2 ? request->data[2] : ""; + + if (service.empty() || user.empty() || command.empty()) + request->reply("error", "Invalid parameters"); + else + { + BotInfo *bi = findbot(service); + if (!bi) + request->reply("error", "Invalid service"); + else + { + request->reply("result", "Success"); + + dynamic_reference<User> u = finduser(user); + bool created = false; + if (!u) + { + u = new XMLRPCUser(user); + created = true; + request->reply("online", "no"); + } + else + request->reply("online", "yes"); + + mod_run_cmd(bi, *u, command); + + if (created && u) + { + XMLRPCUser *myu = debug_cast<XMLRPCUser *>(*u); + if (!myu->GetOut().empty()) + request->reply("return", iface->Sanitize(myu->GetOut())); + delete *u; + } + } + } + } + + void DoLogin(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + if (source->logged_in) + request->reply("result", "Logged in"); + else + { + XMLRPCListenSocket *ls = static_cast<XMLRPCListenSocket *>(source->LS); + + if (ls->username.empty() && ls->password.empty()) + request->reply("result", "Logged in"); + else if (request->data.size() > 1 && request->data[0] == ls->username && request->data[1] == ls->password) + request->reply("result", "Logged in"); + else + request->reply("error", "Invalid credentials"); + } + } + + void DoCheckAuthentication(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + Anope::string username = request->data.size() > 0 ? request->data[0] : ""; + Anope::string password = request->data.size() > 1 ? request->data[1] : ""; + + if (username.empty() || password.empty()) + request->reply("error", "Invalid parameters"); + else + { + NickAlias *na = findnick(username); + + if (!na) + request->reply("error", "Invalid account"); + else if (enc_check_password(password, na->nc->pass) == 1) + { + request->reply("result", "Success"); + request->reply("account", na->nc->display); + } + else + request->reply("error", "Invalid password"); + } + } + + void DoStats(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + if (SGLine) + request->reply("sglinecount", stringify(SGLine->GetCount())); + if (SQLine) + request->reply("sqlinecount", stringify(SQLine->GetCount())); + if (SNLine) + request->reply("snlinecount", stringify(SNLine->GetCount())); + if (SZLine) + request->reply("szlinecount", stringify(SZLine->GetCount())); + request->reply("uptime", stringify(Anope::CurTime - start_time)); + request->reply("uplinkname", Me->GetLinks().front()->GetName()); + { + Anope::string buf; + for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j) + if (Capab.HasFlag(Capab_Info[j].Flag)) + buf += " " + Capab_Info[j].Token; + request->reply("uplinkcapab", buf); + } + request->reply("usercount", stringify(usercnt)); + request->reply("maxusercount", stringify(maxusercnt)); + request->reply("channelcount", stringify(ChannelList.size())); + } + + void DoChannel(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + if (request->data.empty()) + return; + + Channel *c = findchan(request->data[0]); + + request->reply("name", iface->Sanitize(c ? c->name : request->data[0])); + + if (c) + { + request->reply("bancount", stringify((c && c->bans ? c->bans->count : 0))); + if (c->bans && c->bans->count) + { + int i = 0; + for (Entry *entry = c->bans->entries; entry; entry = entry->next, ++i) + request->reply("ban" + stringify(i), iface->Sanitize(entry->mask)); + } + request->reply("exceptcount", stringify((c && c->excepts ? c->excepts->count : 0))); + if (c->excepts && c->excepts->count) + { + int i = 0; + for (Entry *entry = c->excepts->entries; entry; entry = entry->next, ++i) + request->reply("except" + stringify(i), iface->Sanitize(entry->mask)); + } + request->reply("invitecount", stringify((c && c->invites ? c->invites->count : 0))); + if (c->invites && c->invites->count) + { + int i = 0; + for (Entry *entry = c->invites->entries; entry; entry = entry->next, ++i) + request->reply("invite" + stringify(i), iface->Sanitize(entry->mask)); + } + + Anope::string users; + for (CUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) + { + UserContainer *uc = *it; + users += uc->Status->BuildModePrefixList() + uc->user->nick + " "; + } + if (!users.empty()) + { + users.erase(users.length() - 1); + request->reply("users", iface->Sanitize(users)); + } + + if (!c->topic.empty()) + request->reply("topic", iface->Sanitize(c->topic)); + + if (!c->topic_setter.empty()) + request->reply("topicsetter", iface->Sanitize(c->topic_setter)); + + request->reply("topictime", stringify(c->topic_time)); + } + } + + void DoUser(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) + { + if (request->data.empty()) + return; + + User *u = finduser(request->data[0]); + + request->reply("nick", iface->Sanitize(u ? u->nick : request->data[0])); + + if (u) + { + request->reply("ident", iface->Sanitize(u->GetIdent())); + request->reply("vident", iface->Sanitize(u->GetVIdent())); + request->reply("host", iface->Sanitize(u->host)); + if (!u->vhost.empty()) + request->reply("vhost", iface->Sanitize(u->vhost)); + if (!u->chost.empty()) + request->reply("chost", iface->Sanitize(u->chost)); + if (u->ip()) + request->reply("ip", u->ip.addr()); + request->reply("timestamp", stringify(u->timestamp)); + request->reply("signon", stringify(u->my_signon)); + if (u->Account()) + request->reply("account", iface->Sanitize(u->Account()->display)); + + Anope::string channels; + for (UChannelList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it) + { + ChannelContainer *cc = *it; + channels += cc->Status->BuildModePrefixList() + cc->chan->name + " "; + } + if (!channels.empty()) + { + channels.erase(channels.length() - 1); + request->reply("channels", channels); + } + } + } +}; + +class ModuleXMLRPCMain : public Module +{ + service_reference<XMLRPCServiceInterface> xmlrpc; + + MyXMLRPCEvent stats; + + public: + ModuleXMLRPCMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), xmlrpc("xmlrpc") + { + if (!xmlrpc) + throw ModuleException("Unable to find xmlrpc reference, is m_xmlrpc loaded?"); + + xmlrpc->Register(&stats); + } + + ~ModuleXMLRPCMain() + { + if (xmlrpc) + xmlrpc->Unregister(&stats); + } +}; + +MODULE_INIT(ModuleXMLRPCMain) + diff --git a/modules/extra/xmlrpc.h b/modules/extra/xmlrpc.h new file mode 100644 index 000000000..004d6aef5 --- /dev/null +++ b/modules/extra/xmlrpc.h @@ -0,0 +1,75 @@ + +class XMLRPCClientSocket; +class XMLRPCListenSocket; +class XMLRPCServiceInterface; + +class XMLRPCClientSocket : public ClientSocket +{ + protected: + Anope::string query; + + public: + bool logged_in; + + XMLRPCClientSocket(ListenSocket *ls, int fd, const sockaddrs &addr) : ClientSocket(ls, fd, addr), logged_in(false) { } + + virtual ~XMLRPCClientSocket() { } + + virtual bool Read(const Anope::string &message) = 0; + + virtual bool GetData(Anope::string &tag, Anope::string &data) = 0; + + virtual void HandleMessage() = 0; +}; + +class XMLRPCListenSocket : public ListenSocket +{ + protected: + std::vector<Anope::string> allowed; + + public: + Anope::string username; + Anope::string password; + + XMLRPCListenSocket(const Anope::string &bindip, int port, bool ipv6, const Anope::string &u, const Anope::string &p, const std::vector<Anope::string> &a) : ListenSocket(bindip, port, ipv6), allowed(a), username(u), password(p) { } + + virtual ~XMLRPCListenSocket() { } + + virtual ClientSocket *OnAccept(int fd, const sockaddrs &addr) = 0; +}; + +class XMLRPCRequest +{ + std::map<Anope::string, Anope::string> replies; + + public: + Anope::string name; + Anope::string id; + std::deque<Anope::string> data; + + inline void reply(const Anope::string &dname, const Anope::string &ddata) { this->replies.insert(std::make_pair(dname, ddata)); } + inline const std::map<Anope::string, Anope::string> &get_replies() { return this->replies; } +}; + +class XMLRPCEvent +{ + public: + virtual void Run(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) = 0; +}; + +class XMLRPCServiceInterface : public Service +{ + public: + XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, sname) { } + + virtual void Register(XMLRPCEvent *event) = 0; + + virtual void Unregister(XMLRPCEvent *event) = 0; + + virtual void Reply(XMLRPCClientSocket *source, XMLRPCRequest *request) = 0; + + virtual Anope::string Sanitize(const Anope::string &string) = 0; + + virtual void RunXMLRPC(XMLRPCClientSocket *source, XMLRPCRequest *request) = 0; +}; + diff --git a/src/language.cpp b/src/language.cpp index ce53c0fe6..7636b563b 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -48,16 +48,16 @@ const Anope::string GetString(LanguageString string) return GetString("anope", "", language_strings[string]); } -const Anope::string GetString(const NickCore *nc, LanguageString string) +const Anope::string GetString(NickCore *nc, LanguageString string) { return GetString(nc ? nc->language : "", string); } -const Anope::string GetString(const User *u, LanguageString string) +const Anope::string GetString(User *u, LanguageString string) { if (!u) return GetString(string); - const NickCore *nc = u->Account(); + NickCore *nc = u->Account(); NickAlias *na = NULL; if (!nc) na = findnick(u->nick); diff --git a/src/misc.cpp b/src/misc.cpp index 9bb323b3d..3db15962b 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -304,7 +304,7 @@ time_t dotime(const Anope::string &s) * @param seconds time in seconds * @return buffer */ -Anope::string duration(const NickCore *nc, time_t seconds) +Anope::string duration(NickCore *nc, time_t seconds) { /* We first calculate everything */ int days = seconds / 86400; @@ -365,7 +365,7 @@ Anope::string do_strftime(const time_t &t) * @param seconds time in seconds * @return buffer */ -Anope::string expire_left(const NickCore *nc, time_t expires) +Anope::string expire_left(NickCore *nc, time_t expires) { if (!expires) return GetString(nc, NO_EXPIRE); diff --git a/src/users.cpp b/src/users.cpp index 9aa67b174..c38aee472 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -216,7 +216,7 @@ User::~User() Log(LOG_DEBUG_2) << "User::~User() done"; } -void User::SendMessage(const Anope::string &source, const char *fmt, ...) const +void User::SendMessage(const Anope::string &source, const char *fmt, ...) { va_list args; char buf[BUFSIZE] = ""; @@ -232,7 +232,7 @@ void User::SendMessage(const Anope::string &source, const char *fmt, ...) const } } -void User::SendMessage(const Anope::string &source, const Anope::string &msg) const +void User::SendMessage(const Anope::string &source, const Anope::string &msg) { /* Send privmsg instead of notice if: * - UsePrivmsg is enabled @@ -245,7 +245,7 @@ void User::SendMessage(const Anope::string &source, const Anope::string &msg) co ircdproto->SendNotice(findbot(source), this->nick, "%s", msg.c_str()); } -void User::SendMessage(BotInfo *source, LanguageString message, ...) const +void User::SendMessage(BotInfo *source, LanguageString message, ...) { if (!source) { @@ -385,16 +385,11 @@ NickCore *User::Account() return this->nc; } -const NickCore *User::Account() const -{ - return this->nc; -} - /** Check if the user is identified for their nick * @param CheckNick True to check if the user is identified to the nickname they are on too * @return true or false */ -bool User::IsIdentified(bool CheckNick) const +bool User::IsIdentified(bool CheckNick) { if (CheckNick && this->nc) { @@ -413,7 +408,7 @@ bool User::IsIdentified(bool CheckNick) const * @param CheckSecure Only returns true if the user has secure off * @return true or false */ -bool User::IsRecognized(bool CheckSecure) const +bool User::IsRecognized(bool CheckSecure) { if (CheckSecure && OnAccess) { |