summaryrefslogtreecommitdiff
path: root/include/modules
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-05-05 03:30:08 -0400
committerAdam <Adam@anope.org>2013-05-05 03:30:08 -0400
commit57c2b65f08c9c0658003a74a32c6506829e12b0b (patch)
tree49883b790ed9f7cd395e0c6f2f62cc946d743635 /include/modules
parenta118946e657b8a137502ff60c1f21c608cb44495 (diff)
Move module header files to include/modules to fix naming conflicts with system headers
Diffstat (limited to 'include/modules')
-rw-r--r--include/modules/chanserv.h18
-rw-r--r--include/modules/dns.h177
-rw-r--r--include/modules/global.h20
-rw-r--r--include/modules/httpd.h226
-rw-r--r--include/modules/ldap.h173
-rw-r--r--include/modules/memoserv.h34
-rw-r--r--include/modules/nickserv.h16
-rw-r--r--include/modules/os_forbid.h82
-rw-r--r--include/modules/os_ignore.h79
-rw-r--r--include/modules/os_news.h76
-rw-r--r--include/modules/os_session.h85
-rw-r--r--include/modules/sql.h216
-rw-r--r--include/modules/ssl.h9
-rw-r--r--include/modules/xmlrpc.h40
14 files changed, 1251 insertions, 0 deletions
diff --git a/include/modules/chanserv.h b/include/modules/chanserv.h
new file mode 100644
index 000000000..e1c3849fd
--- /dev/null
+++ b/include/modules/chanserv.h
@@ -0,0 +1,18 @@
+#ifndef CHANSERV_H
+#define CHANSERV_H
+
+class ChanServService : public Service
+{
+ public:
+ ChanServService(Module *m) : Service(m, "ChanServService", "ChanServ")
+ {
+ }
+
+ /* Have ChanServ hold the channel, that is, join and set +nsti and wait
+ * for a few minutes so no one can join or rejoin.
+ */
+ virtual void Hold(Channel *c) = 0;
+};
+
+#endif // CHANSERV_H
+
diff --git a/include/modules/dns.h b/include/modules/dns.h
new file mode 100644
index 000000000..99b84098f
--- /dev/null
+++ b/include/modules/dns.h
@@ -0,0 +1,177 @@
+/*
+ *
+ * (C) 2003-2013 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ */
+
+#ifndef DNS_H
+#define DNS_H
+
+namespace DNS
+{
+ /** Valid query types
+ */
+ enum QueryType
+ {
+ /* Nothing */
+ QUERY_NONE,
+ /* A simple A lookup */
+ QUERY_A = 1,
+ /* An authoritative name server */
+ QUERY_NS = 2,
+ /* A CNAME lookup */
+ QUERY_CNAME = 5,
+ /* Start of a zone of authority */
+ QUERY_SOA = 6,
+ /* Reverse DNS lookup */
+ QUERY_PTR = 12,
+ /* IPv6 AAAA lookup */
+ QUERY_AAAA = 28,
+ /* Zone transfer */
+ QUERY_AXFR = 252
+ };
+
+ /** Flags that can be AND'd into DNSPacket::flags to receive certain values
+ */
+ enum
+ {
+ QUERYFLAGS_QR = 0x8000,
+ QUERYFLAGS_OPCODE = 0x7800,
+ QUERYFLAGS_AA = 0x400,
+ QUERYFLAGS_TC = 0x200,
+ QUERYFLAGS_RD = 0x100,
+ QUERYFLAGS_RA = 0x80,
+ QUERYFLAGS_Z = 0x70,
+ QUERYFLAGS_RCODE = 0xF
+ };
+
+ enum Error
+ {
+ ERROR_NONE,
+ ERROR_UNKNOWN,
+ ERROR_UNLOADED,
+ ERROR_TIMEDOUT,
+ ERROR_NOT_AN_ANSWER,
+ ERROR_NONSTANDARD_QUERY,
+ ERROR_FORMAT_ERROR,
+ ERROR_SERVER_FAILURE,
+ ERROR_DOMAIN_NOT_FOUND,
+ ERROR_NOT_IMPLEMENTED,
+ ERROR_REFUSED,
+ ERROR_NO_RECORDS,
+ ERROR_INVALIDTYPE
+ };
+
+ struct Question
+ {
+ Anope::string name;
+ QueryType type;
+ unsigned short qclass;
+
+ Question() : type(QUERY_NONE), qclass(0) { }
+ Question(const Anope::string &n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { }
+ inline bool operator==(const Question & other) const { return name == other.name && type == other.type && qclass == other.qclass; }
+
+ struct hash
+ {
+ size_t operator()(const Question &q) const
+ {
+ return Anope::hash_ci()(q.name);
+ }
+ };
+ };
+
+ struct ResourceRecord : Question
+ {
+ unsigned int ttl;
+ Anope::string rdata;
+ time_t created;
+
+ ResourceRecord(const Anope::string &n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(Anope::CurTime) { }
+ ResourceRecord(const Question &q) : Question(q), ttl(0), created(Anope::CurTime) { }
+ };
+
+ struct Query
+ {
+ std::vector<Question> questions;
+ std::vector<ResourceRecord> answers, authorities, additional;
+ Error error;
+
+ Query() : error(ERROR_NONE) { }
+ Query(const Question &q) : error(ERROR_NONE) { questions.push_back(q); }
+ };
+
+ class ReplySocket;
+ class Request;
+
+ /** DNS manager
+ */
+ class Manager : public Service
+ {
+ public:
+ Manager(Module *creator) : Service(creator, "DNS::Manager", "dns/manager") { }
+ virtual ~Manager() { }
+
+ virtual void Process(Request *req) = 0;
+ virtual void RemoveRequest(Request *req) = 0;
+
+ virtual bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from) = 0;
+
+ virtual void UpdateSerial() = 0;
+ virtual uint32_t GetSerial() const = 0;
+ };
+
+ /** A DNS query.
+ */
+ class Request : public Timer, public Question
+ {
+ Manager *manager;
+ public:
+ /* Use result cache if available */
+ bool use_cache;
+ /* Request id */
+ unsigned short id;
+ /* Creator of this request */
+ Module *creator;
+
+ Request(Manager *mgr, Module *c, const Anope::string &addr, QueryType qt, bool cache = false) : Timer(0), Question(addr, qt), manager(mgr),
+ use_cache(cache), id(0), creator(c) { }
+
+ virtual ~Request()
+ {
+ manager->RemoveRequest(this);
+ }
+
+ /** Called when this request succeeds
+ * @param r The query sent back from the nameserver
+ */
+ virtual void OnLookupComplete(const Query *r) = 0;
+
+ /** Called when this request fails or times out.
+ * @param r The query sent back from the nameserver, check the error code.
+ */
+ virtual void OnError(const Query *r) { }
+
+ /** Used to time out the query, xalls OnError and lets the TimerManager
+ * delete this request.
+ */
+ void Tick(time_t) anope_override
+ {
+ Log(LOG_DEBUG_2) << "Resolver: timeout for query " << this->name;
+ Query rr(*this);
+ rr.error = ERROR_TIMEDOUT;
+ this->OnError(&rr);
+ }
+ };
+
+} // namespace DNS
+
+#endif // DNS_H
+
+
diff --git a/include/modules/global.h b/include/modules/global.h
new file mode 100644
index 000000000..52afc4a23
--- /dev/null
+++ b/include/modules/global.h
@@ -0,0 +1,20 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+class GlobalService : public Service
+{
+ public:
+ GlobalService(Module *m) : Service(m, "GlobalService", "Global")
+ {
+ }
+
+ /** Send out a global message to all users
+ * @param sender Our client which should send the global
+ * @param source The sender of the global
+ * @param message The message
+ */
+ virtual void SendGlobal(const BotInfo *sender, const Anope::string &source, const Anope::string &message) = 0;
+};
+
+#endif // GLOBAL_H
+
diff --git a/include/modules/httpd.h b/include/modules/httpd.h
new file mode 100644
index 000000000..6127a51e0
--- /dev/null
+++ b/include/modules/httpd.h
@@ -0,0 +1,226 @@
+#ifndef ANOPE_HTTPD_H
+#define ANOPE_HTTPD_H
+
+enum HTTPError
+{
+ HTTP_ERROR_OK = 200,
+ HTTP_FOUND = 302,
+ HTTP_BAD_REQUEST = 400,
+ HTTP_PAGE_NOT_FOUND = 404,
+ HTTP_NOT_SUPPORTED = 505
+};
+
+/* A message to someone */
+struct HTTPReply
+{
+ HTTPError error;
+ Anope::string content_type;
+ std::map<Anope::string, Anope::string> headers;
+ typedef std::list<std::pair<Anope::string, Anope::string> > cookie;
+ std::vector<cookie> cookies;
+
+ HTTPReply() : error(HTTP_ERROR_OK), length(0) { }
+
+ HTTPReply(const HTTPReply& other) : error(other.error), length(other.length)
+ {
+ content_type = other.content_type;
+ headers = other.headers;
+ cookies = other.cookies;
+
+ for (unsigned i = 0; i < other.out.size(); ++i)
+ out.push_back(new Data(other.out[i]->buf, other.out[i]->len));
+ }
+
+ ~HTTPReply()
+ {
+ for (unsigned i = 0; i < out.size(); ++i)
+ delete out[i];
+ out.clear();
+ }
+
+ struct Data
+ {
+ char *buf;
+ size_t len;
+
+ Data(const char *b, size_t l)
+ {
+ this->buf = new char[l];
+ memcpy(this->buf, b, l);
+ this->len = l;
+ }
+
+ ~Data()
+ {
+ delete [] buf;
+ }
+ };
+
+ std::deque<Data *> out;
+ size_t length;
+
+ void Write(const Anope::string &message)
+ {
+ this->out.push_back(new Data(message.c_str(), message.length()));
+ this->length += message.length();
+ }
+
+ void Write(const char *b, size_t l)
+ {
+ this->out.push_back(new Data(b, l));
+ this->length += l;
+ }
+};
+
+/* A message from soneone */
+struct HTTPMessage
+{
+ std::map<Anope::string, Anope::string> headers;
+ std::map<Anope::string, Anope::string> cookies;
+ std::map<Anope::string, Anope::string> get_data;
+ std::map<Anope::string, Anope::string> post_data;
+ Anope::string content;
+};
+
+class HTTPClient;
+class HTTPProvider;
+
+class HTTPPage : public Base
+{
+ Anope::string url;
+ Anope::string content_type;
+
+ public:
+ HTTPPage(const Anope::string &u, const Anope::string &ct = "text/html") : url(u), content_type(ct) { }
+
+ const Anope::string &GetURL() const { return this->url; }
+
+ const Anope::string &GetContentType() const { return this->content_type; }
+
+ /** Called when this page is requested
+ * @param The server this page is on
+ * @param The page name
+ * @param The client requesting the page
+ * @param The HTTP header sent from the client to request the page
+ * @param The HTTP header that will be sent back to the client
+ */
+ virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0;
+};
+
+class HTTPClient : public ClientSocket, public BinarySocket, public Base
+{
+ protected:
+ void WriteClient(const Anope::string &message)
+ {
+ BinarySocket::Write(message + "\r\n");
+ }
+
+ public:
+ HTTPClient(ListenSocket *l, int f, const sockaddrs &a) : ClientSocket(l, a), BinarySocket() { }
+
+ virtual const Anope::string GetIP()
+ {
+ return this->clientaddr.addr();
+ }
+
+ virtual void SendError(HTTPError err, const Anope::string &msg) = 0;
+ virtual void SendReply(HTTPReply *) = 0;
+};
+
+class HTTPProvider : public ListenSocket, public Service
+{
+ Anope::string ip;
+ unsigned short port;
+ public:
+ Anope::string ext_ip;
+ std::vector<Anope::string> ext_headers;
+
+ HTTPProvider(Module *c, const Anope::string &n, const Anope::string &i, const unsigned short p) : ListenSocket(i, p, i.find(':') != Anope::string::npos), Service(c, "HTTPProvider", n), ip(i), port(p) { }
+
+ const Anope::string &GetIP() const
+ {
+ return this->ip;
+ }
+
+ unsigned short GetPort() const
+ {
+ return this->port;
+ }
+
+ virtual bool RegisterPage(HTTPPage *page) = 0;
+ virtual void UnregisterPage(HTTPPage *page) = 0;
+ virtual HTTPPage* FindPage(const Anope::string &name) = 0;
+};
+
+namespace HTTPUtils
+{
+ inline Anope::string URLDecode(const Anope::string &url)
+ {
+ Anope::string decoded;
+
+ for (unsigned i = 0; i < url.length(); ++i)
+ {
+ const char& c = url[i];
+
+ if (c == '%' && i + 2 < url.length())
+ {
+ Anope::string dest;
+ Anope::Unhex(url.substr(i + 1, 2), dest);
+ decoded += dest;
+ i += 2;
+ }
+ else if (c == '+')
+ decoded += ' ';
+ else
+ decoded += c;
+ }
+
+ return decoded;
+ }
+
+ inline Anope::string URLEncode(const Anope::string &url)
+ {
+ Anope::string encoded;
+
+ for (unsigned i = 0; i < url.length(); ++i)
+ {
+ const char& c = url[i];
+
+ if (isalnum(c) || c == '.' || c == '-' || c == '*' || c == '_')
+ encoded += c;
+ else if (c == ' ')
+ encoded += '+';
+ else
+ encoded += "%" + Anope::Hex(c);
+ }
+
+ return encoded;
+ }
+
+ inline Anope::string Escape(const Anope::string &src)
+ {
+ Anope::string dst;
+
+ for (unsigned i = 0; i < src.length(); ++i)
+ {
+ switch (src[i])
+ {
+ case '<':
+ dst += "&lt;";
+ break;
+ case '>':
+ dst += "&gt;";
+ break;
+ case '"':
+ dst += "&quot;";
+ break;
+ default:
+ dst += src[i];
+ }
+ }
+
+ return dst;
+ }
+}
+
+#endif // ANOPE_HTTPD_H
diff --git a/include/modules/ldap.h b/include/modules/ldap.h
new file mode 100644
index 000000000..65be27687
--- /dev/null
+++ b/include/modules/ldap.h
@@ -0,0 +1,173 @@
+#ifndef ANOPE_LDAP_H
+#define ANOPE_LDAP_H
+
+typedef int LDAPQuery;
+
+class LDAPException : public ModuleException
+{
+ public:
+ LDAPException(const Anope::string &reason) : ModuleException(reason) { }
+
+ virtual ~LDAPException() throw() { }
+};
+
+struct LDAPModification
+{
+ enum LDAPOperation
+ {
+ LDAP_ADD,
+ LDAP_DEL,
+ LDAP_REPLACE
+ };
+
+ LDAPOperation op;
+ Anope::string name;
+ std::vector<Anope::string> values;
+};
+typedef std::vector<LDAPModification> LDAPMods;
+
+struct LDAPAttributes : public std::map<Anope::string, std::vector<Anope::string> >
+{
+ size_t size(const Anope::string &attr) const
+ {
+ const std::vector<Anope::string>& array = this->getArray(attr);
+ return array.size();
+ }
+
+ const std::vector<Anope::string> keys() const
+ {
+ std::vector<Anope::string> k;
+ for (const_iterator it = this->begin(), it_end = this->end(); it != it_end; ++it)
+ k.push_back(it->first);
+ return k;
+ }
+
+ const Anope::string &get(const Anope::string &attr) const
+ {
+ const std::vector<Anope::string>& array = this->getArray(attr);
+ if (array.empty())
+ throw LDAPException("Empty attribute " + attr + " in LDAPResult::get");
+ return array[0];
+ }
+
+ const std::vector<Anope::string>& getArray(const Anope::string &attr) const
+ {
+ const_iterator it = this->find(attr);
+ if (it == this->end())
+ throw LDAPException("Unknown attribute " + attr + " in LDAPResult::getArray");
+ return it->second;
+ }
+};
+
+struct LDAPResult
+{
+ std::vector<LDAPAttributes> messages;
+ Anope::string error;
+
+ enum QueryType
+ {
+ QUERY_UNKNOWN,
+ QUERY_BIND,
+ QUERY_SEARCH,
+ QUERY_ADD,
+ QUERY_DELETE,
+ QUERY_MODIFY
+ };
+
+ QueryType type;
+ LDAPQuery id;
+
+ LDAPResult()
+ {
+ this->type = QUERY_UNKNOWN;
+ this->id = -1;
+ }
+
+ size_t size() const
+ {
+ return this->messages.size();
+ }
+
+ bool empty() const
+ {
+ return this->messages.empty();
+ }
+
+ const LDAPAttributes &get(size_t sz) const
+ {
+ if (sz >= this->messages.size())
+ throw LDAPException("Index out of range");
+ return this->messages[sz];
+ }
+
+ const Anope::string &getError() const
+ {
+ return this->error;
+ }
+};
+
+class LDAPInterface
+{
+ public:
+ Module *owner;
+
+ LDAPInterface(Module *m) : owner(m) { }
+ virtual ~LDAPInterface() { }
+
+ virtual void OnResult(const LDAPResult &r) = 0;
+ virtual void OnError(const LDAPResult &err) = 0;
+ virtual void OnDelete() { }
+};
+
+class LDAPProvider : public Service
+{
+ public:
+ LDAPProvider(Module *c, const Anope::string &n) : Service(c, "LDAPProvider", n) { }
+
+ /** Attempt to bind to the LDAP server as an admin
+ * @param i The LDAPInterface the result is sent to
+ * @return The query ID
+ */
+ virtual LDAPQuery BindAsAdmin(LDAPInterface *i) = 0;
+
+ /** Bind to LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param who The binddn
+ * @param pass The password
+ * @return The query ID
+ */
+ virtual LDAPQuery Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) = 0;
+
+ /** Search ldap for the specified filter
+ * @param i The LDAPInterface the result is sent to
+ * @param base The base DN to search
+ * @param filter The filter to apply
+ * @return The query ID
+ */
+ virtual LDAPQuery Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) = 0;
+
+ /** Add an entry to LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param dn The dn of the entry to add
+ * @param attributes The attributes
+ * @return The query ID
+ */
+ virtual LDAPQuery Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) = 0;
+
+ /** Delete an entry from LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param dn The dn of the entry to delete
+ * @return The query ID
+ */
+ virtual LDAPQuery Del(LDAPInterface *i, const Anope::string &dn) = 0;
+
+ /** Modify an existing entry in LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param base The base DN to modify
+ * @param attributes The attributes to modify
+ * @return The query ID
+ */
+ virtual LDAPQuery Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) = 0;
+};
+
+#endif // ANOPE_LDAP_H
diff --git a/include/modules/memoserv.h b/include/modules/memoserv.h
new file mode 100644
index 000000000..d35d3f8a0
--- /dev/null
+++ b/include/modules/memoserv.h
@@ -0,0 +1,34 @@
+#ifndef MEMOSERV_H
+#define MEMOSERV_H
+
+class MemoServService : public Service
+{
+ public:
+ enum MemoResult
+ {
+ MEMO_SUCCESS,
+ MEMO_INVALID_TARGET,
+ MEMO_TOO_FAST,
+ MEMO_TARGET_FULL
+ };
+
+ MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ")
+ {
+ }
+
+ /** Sends a memo.
+ * @param source The source of the memo, can be anythin.
+ * @param target The target of the memo, nick or channel.
+ * @param message Memo text
+ * @param force true to force the memo, restrictions/delays etc are not checked
+ */
+ virtual MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force = false) = 0;
+
+ /** Check for new memos and notify the user if there are any
+ * @param u The user
+ */
+ virtual void Check(User *u) = 0;
+};
+
+#endif // MEMOSERV_H
+
diff --git a/include/modules/nickserv.h b/include/modules/nickserv.h
new file mode 100644
index 000000000..b20d6ebd1
--- /dev/null
+++ b/include/modules/nickserv.h
@@ -0,0 +1,16 @@
+#ifndef NICKSERV_H
+#define NICKSERV_H
+
+class NickServService : public Service
+{
+ public:
+ NickServService(Module *m) : Service(m, "NickServService", "NickServ")
+ {
+ }
+
+ virtual void Validate(User *u) = 0;
+ virtual void Login(User *u, NickAlias *na) = 0;
+};
+
+#endif // NICKSERV_H
+
diff --git a/include/modules/os_forbid.h b/include/modules/os_forbid.h
new file mode 100644
index 000000000..3f1fe9a7f
--- /dev/null
+++ b/include/modules/os_forbid.h
@@ -0,0 +1,82 @@
+#ifndef OS_FORBID_H
+#define OS_FORBID_H
+
+enum ForbidType
+{
+ FT_NICK = 1,
+ FT_CHAN,
+ FT_EMAIL,
+ FT_REGISTER,
+ FT_SIZE
+};
+
+struct ForbidData : Serializable
+{
+ Anope::string mask;
+ Anope::string creator;
+ Anope::string reason;
+ time_t created;
+ time_t expires;
+ ForbidType type;
+
+ ForbidData() : Serializable("ForbidData") { }
+ void Serialize(Serialize::Data &data) const anope_override;
+ static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
+};
+
+class ForbidService : public Service
+{
+ public:
+ ForbidService(Module *m) : Service(m, "ForbidService", "forbid") { }
+
+ virtual void AddForbid(ForbidData *d) = 0;
+
+ virtual void RemoveForbid(ForbidData *d) = 0;
+
+ virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0;
+
+ virtual std::vector<ForbidData *> GetForbids() = 0;
+};
+
+static ServiceReference<ForbidService> forbid_service("ForbidService", "forbid");
+
+void ForbidData::Serialize(Serialize::Data &data) const
+{
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["reason"] << this->reason;
+ data["created"] << this->created;
+ data["expires"] << this->expires;
+ data["type"] << this->type;
+}
+
+Serializable* ForbidData::Unserialize(Serializable *obj, Serialize::Data &data)
+{
+ if (!forbid_service)
+ return NULL;
+
+ ForbidData *fb;
+ if (obj)
+ fb = anope_dynamic_static_cast<ForbidData *>(obj);
+ else
+ fb = new ForbidData;
+
+ data["mask"] >> fb->mask;
+ data["creator"] >> fb->creator;
+ data["reason"] >> fb->reason;
+ data["created"] >> fb->created;
+ data["expires"] >> fb->expires;
+ unsigned int t;
+ data["type"] >> t;
+ fb->type = static_cast<ForbidType>(t);
+
+ if (t > FT_SIZE - 1)
+ return NULL;
+
+ if (!obj)
+ forbid_service->AddForbid(fb);
+ return fb;
+}
+
+#endif
+
diff --git a/include/modules/os_ignore.h b/include/modules/os_ignore.h
new file mode 100644
index 000000000..6c3e237ab
--- /dev/null
+++ b/include/modules/os_ignore.h
@@ -0,0 +1,79 @@
+/* OperServ ignore interface
+ *
+ * (C) 2003-2013 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+
+struct IgnoreData : Serializable
+{
+ Anope::string mask;
+ Anope::string creator;
+ Anope::string reason;
+ time_t time; /* When do we stop ignoring them? */
+
+ IgnoreData() : Serializable("IgnoreData") { }
+ void Serialize(Serialize::Data &data) const anope_override;
+ static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
+};
+
+class IgnoreService : public Service
+{
+ protected:
+ std::list<IgnoreData> ignores;
+
+ IgnoreService(Module *c) : Service(c, "IgnoreService", "ignore") { }
+
+ public:
+ virtual IgnoreData* AddIgnore(const Anope::string &mask, const Anope::string &creator, const Anope::string &reason, time_t delta = Anope::CurTime) = 0;
+
+ virtual bool DelIgnore(const Anope::string &mask) = 0;
+
+ inline void ClearIgnores() { this->ignores.clear(); }
+
+ virtual IgnoreData *Find(const Anope::string &mask) = 0;
+
+ inline std::list<IgnoreData> &GetIgnores() { return this->ignores; }
+};
+
+static ServiceReference<IgnoreService> ignore_service("IgnoreService", "ignore");
+
+void IgnoreData::Serialize(Serialize::Data &data) const
+{
+ data["mask"] << this->mask;
+ data["creator"] << this->creator;
+ data["reason"] << this->reason;
+ data["time"] << this->time;
+}
+
+Serializable* IgnoreData::Unserialize(Serializable *obj, Serialize::Data &data)
+{
+ if (!ignore_service)
+ return NULL;
+
+ if (obj)
+ {
+ IgnoreData *ign = anope_dynamic_static_cast<IgnoreData *>(obj);
+ data["mask"] >> ign->mask;
+ data["creator"] >> ign->creator;
+ data["reason"] >> ign->reason;
+ data["time"] >> ign->time;
+ return ign;
+ }
+
+ Anope::string smask, screator, sreason;
+ time_t t;
+
+ data["mask"] >> smask;
+ data["creator"] >> screator;
+ data["reason"] >> sreason;
+ data["time"] >> t;
+
+ return ignore_service->AddIgnore(smask, screator, sreason, t);
+}
+
diff --git a/include/modules/os_news.h b/include/modules/os_news.h
new file mode 100644
index 000000000..b1e717455
--- /dev/null
+++ b/include/modules/os_news.h
@@ -0,0 +1,76 @@
+#ifndef OS_NEWS
+#define OS_NEWS
+
+enum NewsType
+{
+ NEWS_LOGON,
+ NEWS_RANDOM,
+ NEWS_OPER
+};
+
+struct NewsMessages
+{
+ NewsType type;
+ Anope::string name;
+ const char *msgs[10];
+};
+
+struct NewsItem : Serializable
+{
+ NewsType type;
+ Anope::string text;
+ Anope::string who;
+ time_t time;
+
+ NewsItem() : Serializable("NewsItem") { }
+ void Serialize(Serialize::Data &data) const anope_override;
+ static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
+};
+
+class NewsService : public Service
+{
+ public:
+ NewsService(Module *m) : Service(m, "NewsService", "news") { }
+
+ virtual void AddNewsItem(NewsItem *n) = 0;
+
+ virtual void DelNewsItem(NewsItem *n) = 0;
+
+ virtual std::vector<NewsItem *> &GetNewsList(NewsType t) = 0;
+};
+
+static ServiceReference<NewsService> news_service("NewsService", "news");
+
+void NewsItem::Serialize(Serialize::Data &data) const
+{
+ data["type"] << this->type;
+ data["text"] << this->text;
+ data["who"] << this->who;
+ data["time"] << this->time;
+}
+
+Serializable* NewsItem::Unserialize(Serializable *obj, Serialize::Data &data)
+{
+ if (!news_service)
+ return NULL;
+
+ NewsItem *ni;
+ if (obj)
+ ni = anope_dynamic_static_cast<NewsItem *>(obj);
+ else
+ ni = new NewsItem();
+
+ unsigned int t;
+ data["type"] >> t;
+ ni->type = static_cast<NewsType>(t);
+ data["text"] >> ni->text;
+ data["who"] >> ni->who;
+ data["time"] >> ni->time;
+
+ if (!obj)
+ news_service->AddNewsItem(ni);
+ return ni;
+}
+
+#endif // OS_NEWS
+
diff --git a/include/modules/os_session.h b/include/modules/os_session.h
new file mode 100644
index 000000000..f3077d0ac
--- /dev/null
+++ b/include/modules/os_session.h
@@ -0,0 +1,85 @@
+#ifndef OS_SESSION_H
+#define OS_SESSION_H
+
+struct Session
+{
+ cidr addr; /* A cidr (sockaddrs + len) representing this session */
+ unsigned count; /* Number of clients with this host */
+ unsigned hits; /* Number of subsequent kills for a host */
+
+ Session(const Anope::string &ip, int len) : addr(ip, len), count(1), hits(0) { }
+};
+
+struct Exception : Serializable
+{
+ Anope::string mask; /* Hosts to which this exception applies */
+ unsigned limit; /* Session limit for exception */
+ Anope::string who; /* Nick of person who added the exception */
+ Anope::string reason; /* Reason for exception's addition */
+ time_t time; /* When this exception was added */
+ time_t expires; /* Time when it expires. 0 == no expiry */
+
+ Exception() : Serializable("Exception") { }
+ void Serialize(Serialize::Data &data) const anope_override;
+ static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
+};
+
+class SessionService : public Service
+{
+ public:
+ typedef std::tr1::unordered_map<cidr, Session *, cidr::hash> SessionMap;
+ typedef std::vector<Exception *> ExceptionVector;
+
+ SessionService(Module *m) : Service(m, "SessionService", "session") { }
+
+ virtual void AddException(Exception *e) = 0;
+
+ virtual void DelException(Exception *e) = 0;
+
+ virtual Exception *FindException(User *u) = 0;
+
+ virtual Exception *FindException(const Anope::string &host) = 0;
+
+ virtual ExceptionVector &GetExceptions() = 0;
+
+ virtual Session *FindSession(const Anope::string &ip) = 0;
+
+ virtual SessionMap &GetSessions() = 0;
+};
+
+static ServiceReference<SessionService> session_service("SessionService", "session");
+
+void Exception::Serialize(Serialize::Data &data) const
+{
+ data["mask"] << this->mask;
+ data["limit"] << this->limit;
+ data["who"] << this->who;
+ data["reason"] << this->reason;
+ data["time"] << this->time;
+ data["expires"] << this->expires;
+}
+
+Serializable* Exception::Unserialize(Serializable *obj, Serialize::Data &data)
+{
+ if (!session_service)
+ return NULL;
+
+ Exception *ex;
+ if (obj)
+ ex = anope_dynamic_static_cast<Exception *>(obj);
+ else
+ ex = new Exception;
+ data["mask"] >> ex->mask;
+ data["limit"] >> ex->limit;
+ data["who"] >> ex->who;
+ data["reason"] >> ex->reason;
+ data["time"] >> ex->time;
+ data["expires"] >> ex->expires;
+
+ if (!obj)
+ session_service->AddException(ex);
+ return ex;
+}
+
+#endif
+
diff --git a/include/modules/sql.h b/include/modules/sql.h
new file mode 100644
index 000000000..1c8fdd3aa
--- /dev/null
+++ b/include/modules/sql.h
@@ -0,0 +1,216 @@
+/*
+ * (C) 2003-2013 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+namespace SQL
+{
+
+ class Data : public Serialize::Data
+ {
+ public:
+ typedef std::map<Anope::string, std::stringstream *> Map;
+ Map data;
+ std::map<Anope::string, Type> types;
+
+ ~Data()
+ {
+ Clear();
+ }
+
+ std::iostream& operator[](const Anope::string &key) anope_override
+ {
+ std::stringstream *&ss = data[key];
+ if (!ss)
+ ss = new std::stringstream();
+ return *ss;
+ }
+
+ std::set<Anope::string> KeySet() const anope_override
+ {
+ std::set<Anope::string> keys;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ keys.insert(it->first);
+ return keys;
+ }
+
+ size_t Hash() const anope_override
+ {
+ size_t hash = 0;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ if (!it->second->str().empty())
+ hash ^= Anope::hash_cs()(it->second->str());
+ return hash;
+ }
+
+ std::map<Anope::string, std::iostream *> GetData() const
+ {
+ std::map<Anope::string, std::iostream *> d;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ d[it->first] = it->second;
+ return d;
+ }
+
+ void Clear()
+ {
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ delete it->second;
+ this->data.clear();
+ }
+
+ void SetType(const Anope::string &key, Type t) anope_override
+ {
+ this->types[key] = t;
+ }
+
+ Type GetType(const Anope::string &key) const anope_override
+ {
+ std::map<Anope::string, Type>::const_iterator it = this->types.find(key);
+ if (it != this->types.end())
+ return it->second;
+ return DT_TEXT;
+ }
+ };
+
+ /** A SQL exception, can be thrown at various points
+ */
+ class Exception : public ModuleException
+ {
+ public:
+ Exception(const Anope::string &reason) : ModuleException(reason) { }
+
+ virtual ~Exception() throw() { }
+ };
+
+ /** A SQL query
+ */
+
+ struct QueryData
+ {
+ Anope::string data;
+ bool escape;
+ };
+
+ struct Query
+ {
+ Anope::string query;
+ std::map<Anope::string, QueryData> parameters;
+
+ Query() { }
+ Query(const Anope::string &q) : query(q) { }
+
+ Query& operator=(const Anope::string &q)
+ {
+ this->query = q;
+ this->parameters.clear();
+ return *this;
+ }
+
+ bool operator==(const Query &other) const
+ {
+ return this->query == other.query;
+ }
+
+ inline bool operator!=(const Query &other) const
+ {
+ return !(*this == other);
+ }
+
+ template<typename T> void SetValue(const Anope::string &key, const T& value, bool escape = true)
+ {
+ try
+ {
+ Anope::string string_value = stringify(value);
+ this->parameters[key].data = string_value;
+ this->parameters[key].escape = escape;
+ }
+ catch (const ConvertException &ex) { }
+ }
+ };
+
+ /** A result from a SQL query
+ */
+ class Result
+ {
+ protected:
+ /* Rows, column, item */
+ std::vector<std::map<Anope::string, Anope::string> > entries;
+ Query query;
+ Anope::string error;
+ public:
+ unsigned int id;
+ Anope::string finished_query;
+
+ Result() : id(0) { }
+ Result(unsigned int i, const Query &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { }
+
+ inline operator bool() const { return this->error.empty(); }
+
+ inline const unsigned int GetID() const { return this->id; }
+ inline const Query &GetQuery() const { return this->query; }
+ inline const Anope::string &GetError() const { return this->error; }
+
+ int Rows() const { return this->entries.size(); }
+
+ const std::map<Anope::string, Anope::string> &Row(size_t index) const
+ {
+ try
+ {
+ return this->entries.at(index);
+ }
+ catch (const std::out_of_range &)
+ {
+ throw Exception("Out of bounds access to SQLResult");
+ }
+ }
+
+ const Anope::string Get(size_t index, const Anope::string &col) const
+ {
+ const std::map<Anope::string, Anope::string> rows = this->Row(index);
+
+ std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col);
+ if (it == rows.end())
+ throw Exception("Unknown column name in SQLResult: " + col);
+
+ return it->second;
+ }
+ };
+
+ /* An interface used by modules to retrieve the results
+ */
+ class Interface
+ {
+ public:
+ Module *owner;
+
+ Interface(Module *m) : owner(m) { }
+ virtual ~Interface() { }
+
+ virtual void OnResult(const Result &r) = 0;
+ virtual void OnError(const Result &r) = 0;
+ };
+
+ /** Class providing the SQL service, modules call this to execute queries
+ */
+ class Provider : public Service
+ {
+ public:
+ Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { }
+
+ virtual void Run(Interface *i, const Query &query) = 0;
+
+ virtual Result RunQuery(const Query &query) = 0;
+
+ virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0;
+
+ virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0;
+
+ virtual Query GetTables(const Anope::string &prefix) = 0;
+
+ virtual Anope::string FromUnixtime(time_t) = 0;
+ };
+
+}
+
diff --git a/include/modules/ssl.h b/include/modules/ssl.h
new file mode 100644
index 000000000..6eb97582c
--- /dev/null
+++ b/include/modules/ssl.h
@@ -0,0 +1,9 @@
+
+class SSLService : public Service
+{
+ public:
+ SSLService(Module *o, const Anope::string &n) : Service(o, "SSLService", n) { }
+
+ virtual void Init(Socket *s) = 0;
+};
+
diff --git a/include/modules/xmlrpc.h b/include/modules/xmlrpc.h
new file mode 100644
index 000000000..d5a5ea4a7
--- /dev/null
+++ b/include/modules/xmlrpc.h
@@ -0,0 +1,40 @@
+#include "httpd.h"
+
+class XMLRPCRequest
+{
+ std::map<Anope::string, Anope::string> replies;
+
+ public:
+ Anope::string name;
+ Anope::string id;
+ std::deque<Anope::string> data;
+ HTTPReply& r;
+
+ XMLRPCRequest(HTTPReply &_r) : r(_r) { }
+ 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 XMLRPCServiceInterface;
+
+class XMLRPCEvent
+{
+ public:
+ virtual ~XMLRPCEvent() { }
+ virtual bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) = 0;
+};
+
+class XMLRPCServiceInterface : public Service
+{
+ public:
+ XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, "XMLRPCServiceInterface", sname) { }
+
+ virtual void Register(XMLRPCEvent *event) = 0;
+
+ virtual void Unregister(XMLRPCEvent *event) = 0;
+
+ virtual Anope::string Sanitize(const Anope::string &string) = 0;
+
+ virtual void Reply(XMLRPCRequest &request) = 0;
+};
+