summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/dynref.h36
-rw-r--r--include/event.h146
-rw-r--r--include/modules.h36
-rw-r--r--include/modules/account.h27
-rw-r--r--include/modules/cap.h21
-rw-r--r--include/modules/httpd.h29
-rw-r--r--include/modules/sasl.h12
-rw-r--r--include/modules/spanningtree.h29
-rw-r--r--src/modules.cpp26
-rw-r--r--src/modules/m_cap.cpp9
-rw-r--r--src/modules/m_httpd.cpp24
-rw-r--r--src/modules/m_httpd_acl.cpp26
-rw-r--r--src/modules/m_httpd_config.cpp16
-rw-r--r--src/modules/m_httpd_stats.cpp16
-rw-r--r--src/modules/m_ircv3.cpp60
-rw-r--r--src/modules/m_namesx.cpp5
-rw-r--r--src/modules/m_sasl.cpp11
-rw-r--r--src/modules/m_services_account.cpp13
-rw-r--r--src/modules/m_spanningtree/main.cpp1
-rw-r--r--src/modules/m_spanningtree/main.h7
-rw-r--r--src/modules/m_spanningtree/treeserver.cpp4
-rw-r--r--src/modules/m_starttls.cpp5
-rw-r--r--src/modules/m_uhnames.cpp5
23 files changed, 380 insertions, 184 deletions
diff --git a/include/dynref.h b/include/dynref.h
index a3d2f9966..6e2e17423 100644
--- a/include/dynref.h
+++ b/include/dynref.h
@@ -24,8 +24,18 @@
class CoreExport dynamic_reference_base : public interfacebase, public insp::intrusive_list_node<dynamic_reference_base>
{
+ public:
+ class CaptureHook
+ {
+ public:
+ /** Called when the target of the dynamic_reference has been acquired
+ */
+ virtual void OnCapture() = 0;
+ };
+
private:
std::string name;
+ CaptureHook* hook;
void resolve();
protected:
ServiceProvider* value;
@@ -35,6 +45,12 @@ class CoreExport dynamic_reference_base : public interfacebase, public insp::int
~dynamic_reference_base();
inline const std::string& GetProvider() { return name; }
void SetProvider(const std::string& newname);
+
+ /** Set handler to call when the target object becomes available
+ * @param h Handler to call
+ */
+ void SetCaptureHook(CaptureHook* h) { hook = h; }
+
void check();
operator bool() { return (value != NULL); }
static void reset_all();
@@ -63,6 +79,16 @@ class dynamic_reference : public dynamic_reference_base
{
return operator->();
}
+
+ const T* operator->() const
+ {
+ return static_cast<T*>(value);
+ }
+
+ const T* operator*() const
+ {
+ return operator->();
+ }
};
template<typename T>
@@ -81,6 +107,16 @@ class dynamic_reference_nocheck : public dynamic_reference_base
{
return operator->();
}
+
+ const T* operator->() const
+ {
+ return static_cast<T*>(value);
+ }
+
+ const T* operator*() const
+ {
+ return operator->();
+ }
};
class ModeHandler;
diff --git a/include/event.h b/include/event.h
new file mode 100644
index 000000000..c9bad7d04
--- /dev/null
+++ b/include/event.h
@@ -0,0 +1,146 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+namespace Events
+{
+ class ModuleEventListener;
+ class ModuleEventProvider;
+}
+
+/** Provider of one or more cross-module events.
+ * Modules who wish to provide events for other modules create instances of this class and use
+ * one of the macros below to fire the event, passing the instance of the event provider class
+ * to the macro.
+ * Event providers are identified using a unique identifier string.
+ */
+class Events::ModuleEventProvider : public ServiceProvider, private dynamic_reference_base::CaptureHook
+{
+ public:
+ typedef std::vector<ModuleEventListener*> SubscriberList;
+
+ /** Constructor
+ * @param mod Module providing the event(s)
+ * @param eventid Identifier of the event or event group provided, must be unique
+ */
+ ModuleEventProvider(Module* mod, const std::string& eventid)
+ : ServiceProvider(mod, eventid, SERVICE_DATA)
+ , prov(mod, eventid)
+ {
+ prov.SetCaptureHook(this);
+ }
+
+ /** Get list of objects subscribed to this event
+ * @return List of subscribed objects
+ */
+ const SubscriberList& GetSubscribers() const { return prov->subscribers; }
+
+ friend class ModuleEventListener;
+
+ private:
+ void OnCapture() CXX11_OVERRIDE
+ {
+ // If someone else holds the list from now on, clear mine. See below for more info.
+ if (*prov != this)
+ subscribers.clear();
+ }
+
+ /** Reference to the active provider for this event. In case multiple event providers
+ * exist for the same event, only one of them contains the list of subscribers.
+ * To handle the case when we are not the ones with the list, we get it from the provider
+ * where the dynref points to.
+ */
+ dynamic_reference_nocheck<ModuleEventProvider> prov;
+
+ /** List of objects subscribed to the event(s) provided by us, or empty if multiple providers
+ * exist with the same name and we are not the ones holding the list.
+ */
+ SubscriberList subscribers;
+};
+
+/** Base class for abstract classes describing cross-module events.
+ * Subscribers should NOT inherit directly from this class.
+ */
+class Events::ModuleEventListener : private dynamic_reference_base::CaptureHook
+{
+ /** Reference to the provider, can be NULL if none of the provider modules are loaded
+ */
+ dynamic_reference_nocheck<ModuleEventProvider> prov;
+
+ /** Called by the dynref when the event provider becomes available
+ */
+ void OnCapture() CXX11_OVERRIDE
+ {
+ prov->subscribers.push_back(this);
+ }
+
+ public:
+ /** Constructor
+ * @param mod Module subscribing
+ * @param eventid Identifier of the event to subscribe to
+ */
+ ModuleEventListener(Module* mod, const std::string& eventid)
+ : prov(mod, eventid)
+ {
+ prov.SetCaptureHook(this);
+ // If the dynamic_reference resolved at construction our capture handler wasn't called
+ if (prov)
+ ModuleEventListener::OnCapture();
+ }
+
+ ~ModuleEventListener()
+ {
+ if (prov)
+ stdalgo::erase(prov->subscribers, this);
+ }
+};
+
+/**
+ * Run the given hook provided by a module
+ *
+ * FOREACH_MOD_CUSTOM(accountevprov, AccountEventListener, OnAccountChange, MOD_RESULT, (user, newaccount))
+ */
+#define FOREACH_MOD_CUSTOM(prov, listenerclass, func, params) do { \
+ const Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
+ for (Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
+ { \
+ listenerclass* _t = static_cast<listenerclass*>(*_i); \
+ _t->func params ; \
+ } \
+} while (0);
+
+/**
+ * Run the given hook provided by a module until some module returns MOD_RES_ALLOW or MOD_RES_DENY.
+ * If no module does that, result is set to MOD_RES_PASSTHRU.
+ *
+ * Example: ModResult MOD_RESULT;
+ * FIRST_MOD_RESULT_CUSTOM(httpevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (request));
+ */
+#define FIRST_MOD_RESULT_CUSTOM(prov, listenerclass, func, result, params) do { \
+ result = MOD_RES_PASSTHRU; \
+ const Events::ModuleEventProvider::SubscriberList& _handlers = (prov).GetSubscribers(); \
+ for (Events::ModuleEventProvider::SubscriberList::const_iterator _i = _handlers.begin(); _i != _handlers.end(); ++_i) \
+ { \
+ listenerclass* _t = static_cast<listenerclass*>(*_i); \
+ result = _t->func params ; \
+ if (result != MOD_RES_PASSTHRU) \
+ break; \
+ } \
+} while (0);
diff --git a/include/modules.h b/include/modules.h
index 5a4090dfb..d034ebac2 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -206,34 +206,6 @@ class CoreExport Version
virtual ~Version() {}
};
-/** The Event class is a unicast message directed at all modules.
- * When the class is properly instantiated it may be sent to all modules
- * using the Send() method, which will trigger the OnEvent method in
- * all modules passing the object as its parameter.
- */
-class CoreExport Event : public classbase
-{
- public:
- /** This is a pointer to the sender of the message, which can be used to
- * directly trigger events, or to create a reply.
- */
- ModuleRef source;
- /** The event identifier.
- * This is arbitary text which should be used to distinguish
- * one type of event from another.
- */
- const std::string id;
-
- /** Create a new Event
- */
- Event(Module* src, const std::string &eventid);
- /** Send the Event.
- * The return result of an Event::Send() will always be NULL as
- * no replies are expected.
- */
- void Send();
-};
-
class CoreExport DataProvider : public ServiceProvider
{
public:
@@ -260,7 +232,7 @@ enum Implementation
I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
I_OnStats, I_OnChangeLocalUserHost, I_OnPreTopicChange,
- I_OnPostTopicChange, I_OnEvent, I_OnPostConnect,
+ I_OnPostTopicChange, I_OnPostConnect,
I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
@@ -952,12 +924,6 @@ class CoreExport Module : public classbase, public usecountbase
*/
virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
- /** Called whenever an Event class is sent to all modules by another module.
- * You should *always* check the value of Event::id to determine the event type.
- * @param event The Event class being received
- */
- virtual void OnEvent(Event& event);
-
/** Called whenever a password check is to be made. Replaces the old OldOperCompare API.
* The password field (from the config file) is in 'password' and is to be compared against
* 'input'. This method allows for encryption of passwords (oper, connect:allow, die/restart, etc).
diff --git a/include/modules/account.h b/include/modules/account.h
index c00b044e4..0368127a6 100644
--- a/include/modules/account.h
+++ b/include/modules/account.h
@@ -22,16 +22,7 @@
#include <map>
#include <string>
-class AccountEvent : public Event
-{
- public:
- User* const user;
- const std::string account;
- AccountEvent(Module* me, User* u, const std::string& name)
- : Event(me, "account_login"), user(u), account(name)
- {
- }
-};
+#include "event.h"
typedef StringExtItem AccountExtItem;
@@ -39,3 +30,19 @@ inline AccountExtItem* GetAccountExtItem()
{
return static_cast<AccountExtItem*>(ServerInstance->Extensions.GetItem("accountname"));
}
+
+class AccountEventListener : public Events::ModuleEventListener
+{
+ public:
+ AccountEventListener(Module* mod)
+ : ModuleEventListener(mod, "event/account")
+ {
+ }
+
+ /** Called when a user logs in or logs out
+ * @param user User logging in or out
+ * @param newaccount New account name of the user or empty string if the user
+ * logged out
+ */
+ virtual void OnAccountChange(User* user, const std::string& newaccount) = 0;
+};
diff --git a/include/modules/cap.h b/include/modules/cap.h
index cc1cb8d8c..7aa60cd21 100644
--- a/include/modules/cap.h
+++ b/include/modules/cap.h
@@ -20,7 +20,9 @@
#pragma once
-class CapEvent : public Event
+#include "event.h"
+
+class CapEvent
{
public:
enum CapEventType
@@ -35,23 +37,27 @@ class CapEvent : public Event
std::vector<std::string> wanted;
std::vector<std::string> ack;
User* user;
- CapEvent(Module* sender, User* u, CapEventType capevtype) : Event(sender, "cap_request"), type(capevtype), user(u) {}
+ CapEvent(Module* sender, User* u, CapEventType capevtype) : type(capevtype), user(u) {}
};
-class GenericCap
+class GenericCap : public Events::ModuleEventListener
{
+ bool active;
+
public:
LocalIntExt ext;
const std::string cap;
GenericCap(Module* parent, const std::string& Cap)
- : ext("cap_" + Cap, ExtensionItem::EXT_USER, parent)
+ : Events::ModuleEventListener(parent, "event/cap")
+ , active(true)
+ , ext("cap_" + Cap, ExtensionItem::EXT_USER, parent)
, cap(Cap)
{
}
- void HandleEvent(Event& ev)
+ void OnCapEvent(CapEvent& ev) CXX11_OVERRIDE
{
- if (ev.id != "cap_request")
+ if (!active)
return;
CapEvent *data = static_cast<CapEvent*>(&ev);
@@ -87,4 +93,7 @@ class GenericCap
ext.set(data->user, 0);
}
}
+
+ void SetActive(bool newstate) { active = newstate; }
+ bool IsActive() const { return active; }
};
diff --git a/include/modules/httpd.h b/include/modules/httpd.h
index 86234d53f..b4b88bed5 100644
--- a/include/modules/httpd.h
+++ b/include/modules/httpd.h
@@ -24,6 +24,7 @@
#pragma once
#include "base.h"
+#include "event.h"
#include <string>
#include <sstream>
@@ -107,7 +108,7 @@ class HttpServerSocket;
/** This class represents a HTTP request.
*/
-class HTTPRequest : public Event
+class HTTPRequest
{
protected:
std::string type;
@@ -134,9 +135,9 @@ class HTTPRequest : public Event
* @param ip The IP address making the web request.
* @param pdata The post data (content after headers) received with the request, up to Content-Length in size
*/
- HTTPRequest(Module* me, const std::string &eventid, const std::string &request_type, const std::string &uri,
+ HTTPRequest(const std::string& request_type, const std::string& uri,
HTTPHeaders* hdr, HttpServerSocket* socket, const std::string &ip, const std::string &pdata)
- : Event(me, eventid), type(request_type), document(uri), ipaddr(ip), postdata(pdata), headers(hdr), sock(socket)
+ : type(request_type), document(uri), ipaddr(ip), postdata(pdata), headers(hdr), sock(socket)
{
}
@@ -237,3 +238,25 @@ class HTTPdAPI : public dynamic_reference<HTTPdAPIBase>
{
}
};
+
+class HTTPACLEventListener : public Events::ModuleEventListener
+{
+ public:
+ HTTPACLEventListener(Module* mod)
+ : ModuleEventListener(mod, "event/http-acl")
+ {
+ }
+
+ virtual ModResult OnHTTPACLCheck(HTTPRequest& req) = 0;
+};
+
+class HTTPRequestEventListener : public Events::ModuleEventListener
+{
+ public:
+ HTTPRequestEventListener(Module* mod)
+ : ModuleEventListener(mod, "event/http-request")
+ {
+ }
+
+ virtual ModResult OnHTTPRequest(HTTPRequest& req) = 0;
+};
diff --git a/include/modules/sasl.h b/include/modules/sasl.h
index 321711a68..0a7b19a70 100644
--- a/include/modules/sasl.h
+++ b/include/modules/sasl.h
@@ -19,13 +19,15 @@
#pragma once
-class SASLFallback : public Event
+#include "event.h"
+
+class SASLEventListener : public Events::ModuleEventListener
{
public:
- const parameterlist& params;
- SASLFallback(Module* me, const parameterlist& p)
- : Event(me, "sasl_fallback"), params(p)
+ SASLEventListener(Module* mod)
+ : ModuleEventListener(mod, "event/sasl")
{
- Send();
}
+
+ virtual void OnSASLAuth(const parameterlist& params) = 0;
};
diff --git a/include/modules/spanningtree.h b/include/modules/spanningtree.h
index 99f4f9fc4..0f51c35db 100644
--- a/include/modules/spanningtree.h
+++ b/include/modules/spanningtree.h
@@ -19,22 +19,23 @@
#pragma once
-struct AddServerEvent : public Event
-{
- const std::string servername;
- AddServerEvent(Module* me, const std::string& name)
- : Event(me, "new_server"), servername(name)
- {
- Send();
- }
-};
+#include "event.h"
-struct DelServerEvent : public Event
+class SpanningTreeEventListener : public Events::ModuleEventListener
{
- const std::string servername;
- DelServerEvent(Module* me, const std::string& name)
- : Event(me, "lost_server"), servername(name)
+ public:
+ SpanningTreeEventListener(Module* mod)
+ : ModuleEventListener(mod, "event/spanningtree")
{
- Send();
}
+
+ /** Fired when a server finishes burst
+ * @param server Server that recently linked and finished burst
+ */
+ virtual void OnServerLink(const std::string& server) { }
+
+ /** Fired when a server splits
+ * @param server Server that split
+ */
+ virtual void OnServerSplit(const std::string& server) { }
};
diff --git a/src/modules.cpp b/src/modules.cpp
index d7aa534ab..1c33785b0 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -52,13 +52,6 @@ Version::Version(const std::string &desc, int flags, const std::string& linkdata
{
}
-Event::Event(Module* src, const std::string &eventid) : source(src), id(eventid) { }
-
-void Event::Send()
-{
- FOREACH_MOD(OnEvent, (*this));
-}
-
// These declarations define the behavours of the base class Module (which does nothing at all)
Module::Module() { }
@@ -119,7 +112,6 @@ ModResult Module::OnStats(char, User*, string_list&) { DetachEvent(I_OnStats); r
ModResult Module::OnChangeLocalUserHost(LocalUser*, const std::string&) { DetachEvent(I_OnChangeLocalUserHost); return MOD_RES_PASSTHRU; }
ModResult Module::OnChangeLocalUserGECOS(LocalUser*, const std::string&) { DetachEvent(I_OnChangeLocalUserGECOS); return MOD_RES_PASSTHRU; }
ModResult Module::OnPreTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPreTopicChange); return MOD_RES_PASSTHRU; }
-void Module::OnEvent(Event&) { DetachEvent(I_OnEvent); }
ModResult Module::OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype) { DetachEvent(I_OnPassCompare); return MOD_RES_PASSTHRU; }
void Module::OnPostConnect(User*) { DetachEvent(I_OnPostConnect); }
void Module::OnUserMessage(User*, void*, int, const std::string&, char, const CUList&, MessageType) { DetachEvent(I_OnUserMessage); }
@@ -655,7 +647,7 @@ ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string&
}
dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name)
- : name(Name), value(NULL), creator(Creator)
+ : name(Name), hook(NULL), value(NULL), creator(Creator)
{
if (!dynrefs)
dynrefs = new insp::intrusive_list<dynamic_reference_base>;
@@ -684,9 +676,19 @@ void dynamic_reference_base::SetProvider(const std::string& newname)
void dynamic_reference_base::resolve()
{
- std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules->DataProviders.find(name);
- if (i != ServerInstance->Modules->DataProviders.end())
- value = static_cast<DataProvider*>(i->second);
+ // Because find() may return any element with a matching key in case count(key) > 1 use lower_bound()
+ // to ensure a dynref with the same name as another one resolves to the same object
+ std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name);
+ if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name))
+ {
+ ServiceProvider* newvalue = i->second;
+ if (value != newvalue)
+ {
+ value = newvalue;
+ if (hook)
+ hook->OnCapture();
+ }
+ }
else
value = NULL;
}
diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp
index db5d85f0f..2c2178a18 100644
--- a/src/modules/m_cap.cpp
+++ b/src/modules/m_cap.cpp
@@ -39,9 +39,12 @@ CAP END
*/
class CommandCAP : public Command
{
+ Events::ModuleEventProvider capevprov;
+
public:
LocalIntExt reghold;
CommandCAP (Module* mod) : Command(mod, "CAP", 1),
+ capevprov(mod, "event/cap"),
reghold("CAP_REGHOLD", ExtensionItem::EXT_USER, mod)
{
works_before_reg = true;
@@ -70,7 +73,7 @@ class CommandCAP : public Command
}
reghold.set(user, 1);
- Data.Send();
+ FOREACH_MOD_CUSTOM(capevprov, GenericCap, OnCapEvent, (Data));
if (Data.ack.size() > 0)
{
@@ -93,7 +96,7 @@ class CommandCAP : public Command
CapEvent Data(creator, user, subcommand == "LS" ? CapEvent::CAPEVENT_LS : CapEvent::CAPEVENT_LIST);
reghold.set(user, 1);
- Data.Send();
+ FOREACH_MOD_CUSTOM(capevprov, GenericCap, OnCapEvent, (Data));
std::string Result = irc::stringjoiner(Data.wanted);
user->WriteCommand("CAP", subcommand + " :" + Result);
@@ -103,7 +106,7 @@ class CommandCAP : public Command
CapEvent Data(creator, user, CapEvent::CAPEVENT_CLEAR);
reghold.set(user, 1);
- Data.Send();
+ FOREACH_MOD_CUSTOM(capevprov, GenericCap, OnCapEvent, (Data));
std::string Result = irc::stringjoiner(Data.ack);
user->WriteCommand("CAP", "ACK :" + Result);
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp
index bbd9f1275..e09ca3fa2 100644
--- a/src/modules/m_httpd.cpp
+++ b/src/modules/m_httpd.cpp
@@ -29,8 +29,9 @@
class ModuleHttpServer;
static ModuleHttpServer* HttpModule;
-static bool claimed;
static insp::intrusive_list<HttpServerSocket> sockets;
+static Events::ModuleEventProvider* aclevprov;
+static Events::ModuleEventProvider* reqevprov;
/** HTTP socket states
*/
@@ -322,14 +323,14 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
{
InternalState = HTTP_SERVE_SEND_DATA;
- claimed = false;
- HTTPRequest acl((Module*)HttpModule, "httpd_acl", request_type, uri, &headers, this, ip, postdata);
- acl.Send();
- if (!claimed)
+ ModResult MOD_RESULT;
+ HTTPRequest acl(request_type, uri, &headers, this, ip, postdata);
+ FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl));
+ if (MOD_RESULT != MOD_RES_DENY)
{
- HTTPRequest url((Module*)HttpModule, "httpd_url", request_type, uri, &headers, this, ip, postdata);
- url.Send();
- if (!claimed)
+ HTTPRequest url(request_type, uri, &headers, this, ip, postdata);
+ FIRST_MOD_RESULT_CUSTOM(*reqevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (url));
+ if (MOD_RESULT == MOD_RES_PASSTHRU)
{
SendHTTPError(404);
}
@@ -363,7 +364,6 @@ class HTTPdAPIImpl : public HTTPdAPIBase
void SendResponse(HTTPDocumentResponse& resp) CXX11_OVERRIDE
{
- claimed = true;
resp.src.sock->Page(resp.document, resp.responsecode, &resp.headers);
}
};
@@ -372,11 +372,17 @@ class ModuleHttpServer : public Module
{
HTTPdAPIImpl APIImpl;
unsigned int timeoutsec;
+ Events::ModuleEventProvider acleventprov;
+ Events::ModuleEventProvider reqeventprov;
public:
ModuleHttpServer()
: APIImpl(this)
+ , acleventprov(this, "event/http-acl")
+ , reqeventprov(this, "event/http-request")
{
+ aclevprov = &acleventprov;
+ reqevprov = &reqeventprov;
}
void init() CXX11_OVERRIDE
diff --git a/src/modules/m_httpd_acl.cpp b/src/modules/m_httpd_acl.cpp
index 58bbbde2a..866fa0e86 100644
--- a/src/modules/m_httpd_acl.cpp
+++ b/src/modules/m_httpd_acl.cpp
@@ -36,7 +36,7 @@ class HTTPACL
blacklist(set_blacklist) { }
};
-class ModuleHTTPAccessList : public Module
+class ModuleHTTPAccessList : public Module, public HTTPACLEventListener
{
std::string stylesheet;
std::vector<HTTPACL> acl_list;
@@ -44,7 +44,8 @@ class ModuleHTTPAccessList : public Module
public:
ModuleHTTPAccessList()
- : API(this)
+ : HTTPACLEventListener(this)
+ , API(this)
{
}
@@ -104,12 +105,10 @@ class ModuleHTTPAccessList : public Module
API->SendResponse(response);
}
- void OnEvent(Event& event) CXX11_OVERRIDE
+ bool IsAccessAllowed(HTTPRequest* http)
{
- if (event.id == "httpd_acl")
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd acl event");
- HTTPRequest* http = (HTTPRequest*)&event;
for (std::vector<HTTPACL>::const_iterator this_acl = acl_list.begin(); this_acl != acl_list.end(); ++this_acl)
{
@@ -128,7 +127,7 @@ class ModuleHTTPAccessList : public Module
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Denying access to blacklisted resource %s (matched by pattern %s) from ip %s (matched by entry %s)",
http->GetURI().c_str(), this_acl->path.c_str(), http->GetIP().c_str(), entry.c_str());
BlockAccess(http, 403);
- return;
+ return false;
}
}
}
@@ -150,7 +149,7 @@ class ModuleHTTPAccessList : public Module
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Denying access to whitelisted resource %s (matched by pattern %s) from ip %s (Not in whitelist)",
http->GetURI().c_str(), this_acl->path.c_str(), http->GetIP().c_str());
BlockAccess(http, 403);
- return;
+ return false;
}
}
if (!this_acl->password.empty() && !this_acl->username.empty())
@@ -186,7 +185,7 @@ class ModuleHTTPAccessList : public Module
if (user == this_acl->username && pass == this_acl->password)
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP authorization: password and username match");
- return;
+ return true;
}
else
/* Invalid password */
@@ -205,13 +204,22 @@ class ModuleHTTPAccessList : public Module
/* No password given at all, access denied */
BlockAccess(http, 401, "WWW-Authenticate", "Basic realm=\"Restricted Object\"");
}
+ return false;
}
/* A path may only match one ACL (the first it finds in the config file) */
- return;
+ break;
}
}
}
+ return true;
+ }
+
+ ModResult OnHTTPACLCheck(HTTPRequest& req) CXX11_OVERRIDE
+ {
+ if (IsAccessAllowed(&req))
+ return MOD_RES_PASSTHRU;
+ return MOD_RES_DENY;
}
Version GetVersion() CXX11_OVERRIDE
diff --git a/src/modules/m_httpd_config.cpp b/src/modules/m_httpd_config.cpp
index 3c4680799..6fd7f4050 100644
--- a/src/modules/m_httpd_config.cpp
+++ b/src/modules/m_httpd_config.cpp
@@ -21,13 +21,14 @@
#include "inspircd.h"
#include "modules/httpd.h"
-class ModuleHttpConfig : public Module
+class ModuleHttpConfig : public Module, public HTTPRequestEventListener
{
HTTPdAPI API;
public:
ModuleHttpConfig()
- : API(this)
+ : HTTPRequestEventListener(this)
+ , API(this)
{
}
@@ -65,14 +66,12 @@ class ModuleHttpConfig : public Module
return ret;
}
- void OnEvent(Event& event) CXX11_OVERRIDE
+ ModResult HandleRequest(HTTPRequest* http)
{
std::stringstream data("");
- if (event.id == "httpd_url")
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd event");
- HTTPRequest* http = (HTTPRequest*)&event;
if ((http->GetURI() == "/config") || (http->GetURI() == "/config/"))
{
@@ -96,8 +95,15 @@ class ModuleHttpConfig : public Module
response.headers.SetHeader("X-Powered-By", MODNAME);
response.headers.SetHeader("Content-Type", "text/html");
API->SendResponse(response);
+ return MOD_RES_DENY; // Handled
}
}
+ return MOD_RES_PASSTHRU;
+ }
+
+ ModResult OnHTTPRequest(HTTPRequest& req) CXX11_OVERRIDE
+ {
+ return HandleRequest(&req);
}
Version GetVersion() CXX11_OVERRIDE
diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp
index 35a4b0fb2..ad0b4bb72 100644
--- a/src/modules/m_httpd_stats.cpp
+++ b/src/modules/m_httpd_stats.cpp
@@ -25,14 +25,15 @@
#include "modules/httpd.h"
#include "xline.h"
-class ModuleHttpStats : public Module
+class ModuleHttpStats : public Module, public HTTPRequestEventListener
{
static const insp::flat_map<char, char const*>& entities;
HTTPdAPI API;
public:
ModuleHttpStats()
- : API(this)
+ : HTTPRequestEventListener(this)
+ , API(this)
{
}
@@ -87,14 +88,12 @@ class ModuleHttpStats : public Module
data << "</metadata>";
}
- void OnEvent(Event& event) CXX11_OVERRIDE
+ ModResult HandleRequest(HTTPRequest* http)
{
std::stringstream data("");
- if (event.id == "httpd_url")
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd event");
- HTTPRequest* http = (HTTPRequest*)&event;
if ((http->GetURI() == "/stats") || (http->GetURI() == "/stats/"))
{
@@ -225,8 +224,15 @@ class ModuleHttpStats : public Module
response.headers.SetHeader("X-Powered-By", MODNAME);
response.headers.SetHeader("Content-Type", "text/xml");
API->SendResponse(response);
+ return MOD_RES_DENY; // Handled
}
}
+ return MOD_RES_PASSTHRU;
+ }
+
+ ModResult OnHTTPRequest(HTTPRequest& req) CXX11_OVERRIDE
+ {
+ return HandleRequest(&req);
}
Version GetVersion() CXX11_OVERRIDE
diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp
index b1c04cdf5..caee0d329 100644
--- a/src/modules/m_ircv3.cpp
+++ b/src/modules/m_ircv3.cpp
@@ -40,19 +40,18 @@ class WriteNeighboursWithExt : public User::ForEachNeighborHandler
}
};
-class ModuleIRCv3 : public Module
+class ModuleIRCv3 : public Module, public AccountEventListener
{
GenericCap cap_accountnotify;
GenericCap cap_awaynotify;
GenericCap cap_extendedjoin;
- bool accountnotify;
- bool awaynotify;
- bool extendedjoin;
CUList last_excepts;
public:
- ModuleIRCv3() : cap_accountnotify(this, "account-notify"),
+ ModuleIRCv3()
+ : AccountEventListener(this)
+ , cap_accountnotify(this, "account-notify"),
cap_awaynotify(this, "away-notify"),
cap_extendedjoin(this, "extended-join")
{
@@ -61,47 +60,32 @@ class ModuleIRCv3 : public Module
void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
{
ConfigTag* conf = ServerInstance->Config->ConfValue("ircv3");
- accountnotify = conf->getBool("accountnotify", true);
- awaynotify = conf->getBool("awaynotify", true);
- extendedjoin = conf->getBool("extendedjoin", true);
+ cap_accountnotify.SetActive(conf->getBool("accountnotify", true));
+ cap_awaynotify.SetActive(conf->getBool("awaynotify", true));
+ cap_extendedjoin.SetActive(conf->getBool("extendedjoin", true));
}
- void OnEvent(Event& ev) CXX11_OVERRIDE
+ void OnAccountChange(User* user, const std::string& newaccount) CXX11_OVERRIDE
{
- if (awaynotify)
- cap_awaynotify.HandleEvent(ev);
- if (extendedjoin)
- cap_extendedjoin.HandleEvent(ev);
-
- if (accountnotify)
- {
- cap_accountnotify.HandleEvent(ev);
-
- if (ev.id == "account_login")
- {
- AccountEvent* ae = static_cast<AccountEvent*>(&ev);
-
- // :nick!user@host ACCOUNT account
- // or
- // :nick!user@host ACCOUNT *
- std::string line = ":" + ae->user->GetFullHost() + " ACCOUNT ";
- if (ae->account.empty())
- line += "*";
- else
- line += std::string(ae->account);
-
- WriteNeighboursWithExt(ae->user, line, cap_accountnotify.ext);
- }
- }
+ // :nick!user@host ACCOUNT account
+ // or
+ // :nick!user@host ACCOUNT *
+ std::string line = ":" + user->GetFullHost() + " ACCOUNT ";
+ if (newaccount.empty())
+ line += "*";
+ else
+ line += newaccount;
+
+ WriteNeighboursWithExt(user, line, cap_accountnotify.ext);
}
void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts) CXX11_OVERRIDE
{
// Remember who is not going to see the JOIN because of other modules
- if ((awaynotify) && (memb->user->IsAway()))
+ if ((cap_awaynotify.IsActive()) && (memb->user->IsAway()))
last_excepts = excepts;
- if (!extendedjoin)
+ if (!cap_extendedjoin.IsActive())
return;
/*
@@ -170,7 +154,7 @@ class ModuleIRCv3 : public Module
ModResult OnSetAway(User* user, const std::string &awaymsg) CXX11_OVERRIDE
{
- if (awaynotify)
+ if (cap_awaynotify.IsActive())
{
// Going away: n!u@h AWAY :reason
// Back from away: n!u@h AWAY
@@ -185,7 +169,7 @@ class ModuleIRCv3 : public Module
void OnPostJoin(Membership *memb) CXX11_OVERRIDE
{
- if ((!awaynotify) || (!memb->user->IsAway()))
+ if ((!cap_awaynotify.IsActive()) || (!memb->user->IsAway()))
return;
std::string line = ":" + memb->user->GetFullHost() + " AWAY :" + memb->user->awaymsg;
diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp
index f211b01d8..c701f16bf 100644
--- a/src/modules/m_namesx.cpp
+++ b/src/modules/m_namesx.cpp
@@ -94,11 +94,6 @@ class ModuleNamesX : public Module
line.erase(pos, 1);
line.insert(pos, prefixes);
}
-
- void OnEvent(Event& ev) CXX11_OVERRIDE
- {
- cap.HandleEvent(ev);
- }
};
MODULE_INIT(ModuleNamesX)
diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp
index 0a2c840bd..c96b87034 100644
--- a/src/modules/m_sasl.cpp
+++ b/src/modules/m_sasl.cpp
@@ -28,12 +28,13 @@ enum SaslState { SASL_INIT, SASL_COMM, SASL_DONE };
enum SaslResult { SASL_OK, SASL_FAIL, SASL_ABORT };
static std::string sasl_target = "*";
+static Events::ModuleEventProvider* saslevprov;
static void SendSASL(const parameterlist& params)
{
if (!ServerInstance->PI->SendEncapsulatedData(sasl_target, "SASL", params))
{
- SASLFallback(NULL, params);
+ FOREACH_MOD_CUSTOM(*saslevprov, SASLEventListener, OnSASLAuth, (params));
}
}
@@ -246,6 +247,7 @@ class ModuleSASL : public Module
GenericCap cap;
CommandAuthenticate auth;
CommandSASL sasl;
+ Events::ModuleEventProvider sasleventprov;
public:
ModuleSASL()
@@ -253,7 +255,9 @@ class ModuleSASL : public Module
, cap(this, "sasl")
, auth(this, authExt, cap)
, sasl(this, authExt)
+ , sasleventprov(this, "event/sasl")
{
+ saslevprov = &sasleventprov;
}
void init() CXX11_OVERRIDE
@@ -283,11 +287,6 @@ class ModuleSASL : public Module
{
return Version("Provides support for IRC Authentication Layer (aka: atheme SASL) via AUTHENTICATE.",VF_VENDOR);
}
-
- void OnEvent(Event &ev) CXX11_OVERRIDE
- {
- cap.HandleEvent(ev);
- }
};
MODULE_INIT(ModuleSASL)
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index aac0b9ce0..26a53b4d7 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -104,9 +104,12 @@ class AChannel_M : public SimpleChannelModeHandler
class AccountExtItemImpl : public AccountExtItem
{
+ Events::ModuleEventProvider eventprov;
+
public:
AccountExtItemImpl(Module* mod)
: AccountExtItem("accountname", ExtensionItem::EXT_USER, mod)
+ , eventprov(mod, "event/account")
{
}
@@ -123,14 +126,10 @@ class AccountExtItemImpl : public AccountExtItem
user->WriteNumeric(900, "%s %s :You are now logged in as %s",
user->GetFullHost().c_str(), value.c_str(), value.c_str());
}
-
- AccountEvent(creator, user, value).Send();
- }
- else
- {
- // Logged out
- AccountEvent(creator, user, "").Send();
}
+ // If value is empty then logged out
+
+ FOREACH_MOD_CUSTOM(eventprov, AccountEventListener, OnAccountChange, (user, value));
}
};
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 31d822789..e5e6e522b 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -39,6 +39,7 @@ ModuleSpanningTree::ModuleSpanningTree()
: rconnect(this), rsquit(this), map(this)
, commands(NULL)
, currmembid(0)
+ , eventprov(this, "event/spanningtree")
, DNS(this, "DNS")
, loopCall(false)
{
diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h
index 13c743f73..9fde32cad 100644
--- a/src/modules/m_spanningtree/main.h
+++ b/src/modules/m_spanningtree/main.h
@@ -24,6 +24,7 @@
#pragma once
#include "inspircd.h"
+#include "event.h"
#include "modules/dns.h"
#include "servercommand.h"
#include "commands.h"
@@ -72,6 +73,10 @@ class ModuleSpanningTree : public Module
*/
SpanningTreeProtocolInterface protocolinterface;
+ /** Event provider for our events
+ */
+ Events::ModuleEventProvider eventprov;
+
public:
dynamic_reference<DNS::Manager> DNS;
@@ -135,6 +140,8 @@ class ModuleSpanningTree : public Module
*/
static std::string TimeToStr(time_t secs);
+ const Events::ModuleEventProvider& GetEventProvider() const { return eventprov; }
+
/**
** *** MODULE EVENTS ***
**/
diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp
index e004f897e..6ebce07f9 100644
--- a/src/modules/m_spanningtree/treeserver.cpp
+++ b/src/modules/m_spanningtree/treeserver.cpp
@@ -151,7 +151,7 @@ void TreeServer::FinishBurst()
unsigned long bursttime = ts - this->StartBurst;
ServerInstance->SNO->WriteToSnoMask(Parent == Utils->TreeRoot ? 'l' : 'L', "Received end of netburst from \2%s\2 (burst time: %lu %s)",
GetName().c_str(), (bursttime > 10000 ? bursttime / 1000 : bursttime), (bursttime > 10000 ? "secs" : "msecs"));
- AddServerEvent(Utils->Creator, GetName());
+ FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerLink, (GetName()));
StartBurst = 0;
FinishBurstInternal();
@@ -159,7 +159,7 @@ void TreeServer::FinishBurst()
void TreeServer::SQuitChild(TreeServer* server, const std::string& reason)
{
- DelServerEvent(Utils->Creator, server->GetName());
+ FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerSplit, (server->GetName()));
stdalgo::erase(Children, server);
if (IsRoot())
diff --git a/src/modules/m_starttls.cpp b/src/modules/m_starttls.cpp
index d591eed55..b05302fa9 100644
--- a/src/modules/m_starttls.cpp
+++ b/src/modules/m_starttls.cpp
@@ -102,11 +102,6 @@ class ModuleStartTLS : public Module
ssl.SetProvider("ssl/" + newprovider);
}
- void OnEvent(Event& ev) CXX11_OVERRIDE
- {
- tls.HandleEvent(ev);
- }
-
void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
{
tokens["STARTTLS"];
diff --git a/src/modules/m_uhnames.cpp b/src/modules/m_uhnames.cpp
index 0a171c4dc..90bac54f5 100644
--- a/src/modules/m_uhnames.cpp
+++ b/src/modules/m_uhnames.cpp
@@ -66,11 +66,6 @@ class ModuleUHNames : public Module
return MOD_RES_PASSTHRU;
}
-
- void OnEvent(Event& ev) CXX11_OVERRIDE
- {
- cap.HandleEvent(ev);
- }
};
MODULE_INIT(ModuleUHNames)