1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2020 Matt Schatz <genius3000@g3k.solutions>
5  *   Copyright (C) 2019 iwalkalone <iwalkalone69@gmail.com>
6  *   Copyright (C) 2013 Adam <Adam@anope.org>
7  *   Copyright (C) 2012-2016, 2018 Attila Molnar <attilamolnar@hush.com>
8  *   Copyright (C) 2012-2013, 2017-2021 Sadie Powell <sadie@witchery.services>
9  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
10  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
11  *   Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
12  *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
13  *   Copyright (C) 2007-2009 Robin Burchell <robin+git@viroteck.net>
14  *   Copyright (C) 2007 Oliver Lupton <om@inspircd.org>
15  *   Copyright (C) 2006-2007 Dennis Friis <peavey@inspircd.org>
16  *   Copyright (C) 2006 John Brooks <special@inspircd.org>
17  *   Copyright (C) 2003-2008, 2010 Craig Edwards <brain@inspircd.org>
18  *
19  * This file is part of InspIRCd.  InspIRCd is free software: you can
20  * redistribute it and/or modify it under the terms of the GNU General Public
21  * License as published by the Free Software Foundation, version 2.
22  *
23  * This program is distributed in the hope that it will be useful, but WITHOUT
24  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
26  * details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
30  */
31 
32 
33 #pragma once
34 
35 #include "moduledefs.h"
36 #include "dynamic.h"
37 #include "base.h"
38 #include "ctables.h"
39 #include "inspsocket.h"
40 #include "mode.h"
41 
42 /** Used to specify the behaviour of a module. */
43 enum ModuleFlags
44 {
45 	/** The module has no special attributes. */
46 	VF_NONE = 0,
47 
48 	/** The module is a coremod and can be assumed to be loaded on all servers. */
49 	VF_CORE = 1,
50 
51 	/* The module is included with InspIRCd. */
52 	VF_VENDOR = 2,
53 
54 	/** The module MUST be loaded on all servers on a network to link. */
55 	VF_COMMON = 4,
56 
57 	/** The module SHOULD be loaded on all servers on a network for consistency. */
58 	VF_OPTCOMMON = 8
59 };
60 
61 /** The event was explicitly allowed. */
62 #define MOD_RES_ALLOW (ModResult(1))
63 
64 /** The event was not explicitly allowed or denied. */
65 #define MOD_RES_PASSTHRU (ModResult(0))
66 
67 /** The event was explicitly denied. */
68 #define MOD_RES_DENY (ModResult(-1))
69 
70 /** Represents the result of a module event. */
71 class ModResult
72 {
73  private:
74 	/** The underlying result value. */
75 	char result;
76 
77  public:
78 	/** Creates a new instance of the ModResult class which defaults to MOD_RES_PASSTHRU. */
ModResult()79 	ModResult()
80 		: result(0)
81 	{
82 	}
83 
84 	/** Creates a new instance of the ModResult class with the specified value. */
ModResult(char res)85 	explicit ModResult(char res)
86 		: result(res)
87 	{
88 	}
89 
90 	/** Determines whether this ModResult has.the same value as \p res */
91 	inline bool operator==(const ModResult& res) const
92 	{
93 		return result == res.result;
94 	}
95 
96 	/** Determines whether this ModResult has.a different value to \p res */
97 	inline bool operator!=(const ModResult& res) const
98 	{
99 		return result != res.result;
100 	}
101 
102 	/** Determines whether a non-MOD_RES_PASSTHRU result has been set. */
103 	inline bool operator!() const
104 	{
105 		return !result;
106 	}
107 
108 	/** Checks whether the result is an MOD_RES_ALLOW or MOD_RES_PASSTHRU when the default is to allow. */
check(bool def)109 	inline bool check(bool def) const
110 	{
111 		return (result == 1 || (result == 0 && def));
112 	}
113 
114 	/* Merges two results preferring MOD_RES_ALLOW to MOD_RES_DENY. */
115 	inline ModResult operator+(const ModResult& res) const
116 	{
117 		// If the results are identical or the other result is MOD_RES_PASSTHRU
118 		// then return this result.
119 		if (result == res.result || res.result == 0)
120 			return *this;
121 
122 		// If this result is MOD_RES_PASSTHRU then return the other result.
123 		if (result == 0)
124 			return res;
125 
126 		// Otherwise, they are different, and neither is MOD_RES_PASSTHRU.
127 		return MOD_RES_ALLOW;
128 	}
129 };
130 
131 /**
132  * This #define allows us to call a method in all
133  * loaded modules in a readable simple way, e.g.:
134  * 'FOREACH_MOD(OnConnect,(user));'
135  */
136 #define FOREACH_MOD(y,x) do { \
137 	const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
138 	for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
139 	{ \
140 		_next = _i+1; \
141 		try \
142 		{ \
143 			if (!(*_i)->dying) \
144 				(*_i)->y x ; \
145 		} \
146 		catch (CoreException& modexcept) \
147 		{ \
148 			ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
149 		} \
150 	} \
151 } while (0);
152 
153 /**
154  * Custom module result handling loop. This is a paired macro, and should only
155  * be used with while_each_hook.
156  *
157  * See src/channels.cpp for an example of use.
158  */
159 #define DO_EACH_HOOK(n,v,args) \
160 do { \
161 	const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
162 	for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
163 	{ \
164 		_next = _i+1; \
165 		try \
166 		{ \
167 			if (!(*_i)->dying) \
168 				v = (*_i)->n args;
169 
170 #define WHILE_EACH_HOOK(n) \
171 		} \
172 		catch (CoreException& except_ ## n) \
173 		{ \
174 			ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
175 		} \
176 	} \
177 } while(0)
178 
179 /**
180  * Module result iterator
181  * Runs the given hook until some module returns a useful result.
182  *
183  * Example: ModResult result;
184  * FIRST_MOD_RESULT(OnUserPreNick, result, (user, newnick))
185  */
186 #define FIRST_MOD_RESULT(n,v,args) do { \
187 	v = MOD_RES_PASSTHRU; \
188 	DO_EACH_HOOK(n,v,args) \
189 	{ \
190 		if (v != MOD_RES_PASSTHRU) \
191 			break; \
192 	} \
193 	WHILE_EACH_HOOK(n); \
194 } while (0)
195 
196 /** Holds a module's Version information.
197  * The members (set by the constructor only) indicate details as to the version number
198  * of a module. A class of type Version is returned by the GetVersion method of the Module class.
199  */
200 class CoreExport Version
201 {
202  public:
203 	/** Module description
204 	 */
205 	const std::string description;
206 
207 	/** Flags
208 	 */
209 	const int Flags;
210 
211 	/** Server linking description string */
212 	const std::string link_data;
213 
214 	/** Simple module version */
215 	Version(const std::string &desc, int flags = VF_NONE);
216 
217 	/** Complex version information, including linking compatibility data */
218 	Version(const std::string &desc, int flags, const std::string& linkdata);
219 };
220 
221 class CoreExport DataProvider : public ServiceProvider
222 {
223  public:
DataProvider(Module * Creator,const std::string & Name)224 	DataProvider(Module* Creator, const std::string& Name)
225 		: ServiceProvider(Creator, Name, SERVICE_DATA) {}
226 };
227 
228 /** Priority types which can be used by Module::Prioritize()
229  */
230 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
231 
232 /** Implementation-specific flags which may be set in Module::Implements()
233  */
234 enum Implementation
235 {
236 	I_On005Numeric,
237 	I_OnAcceptConnection,
238 	I_OnAddLine,
239 	I_OnBackgroundTimer,
240 	I_OnBuildNeighborList,
241 	I_OnChangeHost,
242 	I_OnChangeIdent,
243 	I_OnChangeRealHost,
244 	I_OnChangeRealName,
245 	I_OnChannelDelete,
246 	I_OnChannelPreDelete,
247 	I_OnCheckBan,
248 	I_OnCheckChannelBan,
249 	I_OnCheckInvite,
250 	I_OnCheckKey,
251 	I_OnCheckLimit,
252 	I_OnCheckReady,
253 	I_OnCommandBlocked,
254 	I_OnConnectionFail,
255 	I_OnDecodeMetaData,
256 	I_OnDelLine,
257 	I_OnExpireLine,
258 	I_OnExtBanCheck,
259 	I_OnGarbageCollect,
260 	I_OnKill,
261 	I_OnLoadModule,
262 	I_OnMode,
263 	I_OnModuleRehash,
264 	I_OnNumeric,
265 	I_OnOper,
266 	I_OnPassCompare,
267 	I_OnPostChangeRealHost,
268 	I_OnPostCommand,
269 	I_OnPostConnect,
270 	I_OnPostDeoper,
271 	I_OnPostJoin,
272 	I_OnPostOper,
273 	I_OnPostTopicChange,
274 	I_OnPreChangeHost,
275 	I_OnPreChangeRealName,
276 	I_OnPreCommand,
277 	I_OnPreMode,
278 	I_OnPreRehash,
279 	I_OnPreTopicChange,
280 	I_OnRawMode,
281 	I_OnSendSnotice,
282 	I_OnServiceAdd,
283 	I_OnServiceDel,
284 	I_OnSetConnectClass,
285 	I_OnSetUserIP,
286 	I_OnShutdown,
287 	I_OnUnloadModule,
288 	I_OnUserConnect,
289 	I_OnUserDisconnect,
290 	I_OnUserInit,
291 	I_OnUserInvite,
292 	I_OnUserJoin,
293 	I_OnUserKick,
294 	I_OnUserMessage,
295 	I_OnUserMessageBlocked,
296 	I_OnUserPart,
297 	I_OnUserPostInit,
298 	I_OnUserPostMessage,
299 	I_OnUserPostNick,
300 	I_OnUserPreInvite,
301 	I_OnUserPreJoin,
302 	I_OnUserPreKick,
303 	I_OnUserPreMessage,
304 	I_OnUserPreNick,
305 	I_OnUserPreQuit,
306 	I_OnUserQuit,
307 	I_OnUserRegister,
308 	I_OnUserWrite,
309 	I_END
310 };
311 
312 /** Base class for all InspIRCd modules
313  *  This class is the base class for InspIRCd modules. All modules must inherit from this class,
314  *  its methods will be called when irc server events occur. class inherited from module must be
315  *  instantiated by the ModuleFactory class (see relevant section) for the module to be initialised.
316  */
317 class CoreExport Module : public classbase, public usecountbase
318 {
319 	/** Detach an event from this module
320 	 * @param i Event type to detach
321 	 */
322 	void DetachEvent(Implementation i);
323 
324  public:
325 	/** A list of modules. */
326 	typedef std::vector<Module*> List;
327 
328 	/** File that this module was loaded from
329 	 */
330 	std::string ModuleSourceFile;
331 
332 	/** Reference to the dlopen() value
333 	 */
334 	DLLManager* ModuleDLLManager;
335 
336 	/** If true, this module will be unloaded soon, further unload attempts will fail
337 	 * Value is used by the ModuleManager internally, you should not modify it
338 	 */
339 	bool dying;
340 
341 	/** Default constructor.
342 	 * Creates a module class. Don't do any type of hook registration or checks
343 	 * for other modules here; do that in init().
344 	 */
345 	Module();
346 
347 	/** Module setup
348 	 * \exception ModuleException Throwing this class, or any class derived from ModuleException, causes loading of the module to abort.
349 	 */
init()350 	virtual void init() { }
351 
352 	/** Clean up prior to destruction
353 	 * If you override, you must call this AFTER your module's cleanup
354 	 */
355 	CullResult cull() CXX11_OVERRIDE;
356 
357 	/** Default destructor.
358 	 * destroys a module class
359 	 */
360 	virtual ~Module();
361 
362 	/** Called when the hooks provided by a module need to be prioritised. */
Prioritize()363 	virtual void Prioritize() { }
364 
365 	/** This method is called when you should reload module specific configuration:
366 	 * on boot, on a /REHASH and on module load.
367 	 * @param status The current status, can be inspected for more information;
368 	 * also used for reporting configuration errors and warnings.
369 	 */
370 	virtual void ReadConfig(ConfigStatus& status);
371 
372 	/** Returns the version number of a Module.
373 	 * The method should return a Version object with its version information assigned via
374 	 * Version::Version
375 	 */
376 	virtual Version GetVersion() = 0;
377 
378 	/** Called when a user connects.
379 	 * The details of the connecting user are available to you in the parameter User *user
380 	 * @param user The user who is connecting
381 	 */
382 	virtual void OnUserConnect(LocalUser* user);
383 
384 	/** Called when before a user quits.
385 	 * The details of the exiting user are available to you in the parameter User *user
386 	 * This event is only called when the user is fully registered when they quit. To catch
387 	 * raw disconnections, use the OnUserDisconnect method.
388 	 * @param user The user who is quitting
389 	 * @param message The user's quit message (as seen by non-opers)
390 	 * @param oper_message The user's quit message (as seen by opers)
391 	 */
392 	virtual ModResult OnUserPreQuit(LocalUser* user, std::string& message, std::string& oper_message);
393 
394 	/** Called when a user quits.
395 	 * The details of the exiting user are available to you in the parameter User *user
396 	 * This event is only called when the user is fully registered when they quit. To catch
397 	 * raw disconnections, use the OnUserDisconnect method.
398 	 * @param user The user who is quitting
399 	 * @param message The user's quit message (as seen by non-opers)
400 	 * @param oper_message The user's quit message (as seen by opers)
401 	 */
402 	virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
403 
404 	/** Called whenever a user's socket is closed.
405 	 * The details of the exiting user are available to you in the parameter User *user
406 	 * This event is called for all users, registered or not, as a cleanup method for modules
407 	 * which might assign resources to user, such as dns lookups, objects and sockets.
408 	 * @param user The user who is disconnecting
409 	 */
410 	virtual void OnUserDisconnect(LocalUser* user);
411 
412 	/** Called whenever a channel is about to be deleted
413 	 * @param chan The channel being deleted
414 	 * @return An integer specifying whether or not the channel may be deleted. 0 for yes, 1 for no.
415 	 */
416 	virtual ModResult OnChannelPreDelete(Channel *chan);
417 
418 	/** Called whenever a channel is deleted, either by QUIT, KICK or PART.
419 	 * @param chan The channel being deleted
420 	 */
421 	virtual void OnChannelDelete(Channel* chan);
422 
423 	/** Called when a user joins a channel.
424 	 * The details of the joining user are available to you in the parameter User *user,
425 	 * and the details of the channel they have joined is available in the variable Channel *channel
426 	 * @param memb The channel membership being created
427 	 * @param sync This is set to true if the JOIN is the result of a network sync and the remote user is being introduced
428 	 * to a channel due to the network sync.
429 	 * @param created This is true if the join created the channel
430 	 * @param except_list A list of users not to send to.
431 	 */
432 	virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
433 
434 	/** Called after a user joins a channel
435 	 * Identical to OnUserJoin, but called immediately afterwards, when any linking module has
436 	 * seen the join.
437 	 * @param memb The channel membership created
438 	 */
439 	virtual void OnPostJoin(Membership* memb);
440 
441 	/** Called when a user parts a channel.
442 	 * The details of the leaving user are available to you in the parameter User *user,
443 	 * and the details of the channel they have left is available in the variable Channel *channel
444 	 * @param memb The channel membership being destroyed
445 	 * @param partmessage The part message, or an empty string (may be modified)
446 	 * @param except_list A list of users to not send to.
447 	 */
448 	virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
449 
450 	/** Called on rehash.
451 	 * This method is called prior to a /REHASH or when a SIGHUP is received from the operating
452 	 * system. This is called in all cases -- including when this server will not execute the
453 	 * rehash because it is directed at a remote server.
454 	 *
455 	 * @param user The user performing the rehash, if any. If this is server initiated, the value of
456 	 * this variable will be NULL.
457 	 * @param parameter The (optional) parameter given to REHASH from the user. Empty when server
458 	 * initiated.
459 	 */
460 	virtual void OnPreRehash(User* user, const std::string &parameter);
461 
462 	/** Called on rehash.
463 	 * This method is called when a user initiates a module-specific rehash. This can be used to do
464 	 * expensive operations (such as reloading TLS (SSL) certificates) that are not executed on a normal
465 	 * rehash for efficiency. A rehash of this type does not reload the core configuration.
466 	 *
467 	 * @param user The user performing the rehash.
468 	 * @param parameter The parameter given to REHASH
469 	 */
470 	virtual void OnModuleRehash(User* user, const std::string &parameter);
471 
472 	/** Called whenever a snotice is about to be sent to a snomask.
473 	 * snomask and type may both be modified; the message may not.
474 	 * @param snomask The snomask the message is going to (e.g. 'A')
475 	 * @param type The textual description the snomask will go to (e.g. 'OPER')
476 	 * @param message The text message to be sent via snotice
477 	 * @return 1 to block the snotice from being sent entirely, 0 else.
478 	 */
479 	virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
480 
481 	/** Called whenever a user is about to join a channel, before any processing is done.
482 	 * Returning a value of 1 from this function stops the process immediately, causing no
483 	 * output to be sent to the user by the core. If you do this you must produce your own numerics,
484 	 * notices etc. This is useful for modules which may want to mimic +b, +k, +l etc. Returning -1 from
485 	 * this function forces the join to be allowed, bypassing restrictions such as banlists, invite, keys etc.
486 	 *
487 	 * IMPORTANT NOTE!
488 	 *
489 	 * If the user joins a NEW channel which does not exist yet, OnUserPreJoin will be called BEFORE the channel
490 	 * record is created. This will cause Channel* chan to be NULL. There is very little you can do in form of
491 	 * processing on the actual channel record at this point, however the channel NAME will still be passed in
492 	 * char* cname, so that you could for example implement a channel blacklist or whitelist, etc.
493 	 * @param user The user joining the channel
494 	 * @param chan If the  channel is a new channel, this will be NULL, otherwise it will be a pointer to the channel being joined
495 	 * @param cname The channel name being joined. For new channels this is valid where chan is not.
496 	 * @param privs A string containing the users privileges when joining the channel. For new channels this will contain "o".
497 	 * You may alter this string to alter the user's modes on the channel.
498 	 * @param keygiven The key given to join the channel, or an empty string if none was provided
499 	 * @return 1 To prevent the join, 0 to allow it.
500 	 */
501 	virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven);
502 
503 	/** Called whenever a user is about to be kicked.
504 	 * Returning a value of 1 from this function stops the process immediately, causing no
505 	 * output to be sent to the user by the core. If you do this you must produce your own numerics,
506 	 * notices etc.
507 	 * @param source The user issuing the kick
508 	 * @param memb The channel membership of the user who is being kicked.
509 	 * @param reason The kick reason
510 	 * @return 1 to prevent the kick, 0 to continue normally, -1 to explicitly allow the kick regardless of normal operation
511 	 */
512 	virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
513 
514 	/** Called whenever a user is kicked.
515 	 * If this method is called, the kick is already underway and cannot be prevented, so
516 	 * to prevent a kick, please use Module::OnUserPreKick instead of this method.
517 	 * @param source The user issuing the kick
518 	 * @param memb The channel membership of the user who was kicked.
519 	 * @param reason The kick reason
520 	 * @param except_list A list of users to not send to.
521 	 */
522 	virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
523 
524 	/** Called whenever a user opers locally.
525 	 * The User will contain the oper mode 'o' as this function is called after any modifications
526 	 * are made to the user's structure by the core.
527 	 * @param user The user who is opering up
528 	 * @param opertype The opers type name
529 	 */
530 	virtual void OnOper(User* user, const std::string &opertype);
531 
532 	/** Called after a user opers locally.
533 	 * This is identical to Module::OnOper(), except it is called after OnOper so that other modules
534 	 * can be guaranteed to already have processed the oper-up, for example m_spanningtree has sent
535 	 * out the OPERTYPE, etc.
536 	 * @param user The user who is opering up
537 	 * @param opername The name of the oper that the user is opering up to. Only valid locally. Empty string otherwise.
538 	 * @param opertype The opers type name
539 	 */
540 	virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
541 
542 	/** Called after a user deopers locally.
543 	 * @param user The user who has deopered.
544 	 */
545 	virtual void OnPostDeoper(User* user);
546 
547 	/** Called whenever a user is about to invite another user into a channel, before any processing is done.
548 	 * Returning 1 from this function stops the process immediately, causing no
549 	 * output to be sent to the user by the core. If you do this you must produce your own numerics,
550 	 * notices etc. This is useful for modules which may want to filter invites to channels.
551 	 * @param source The user who is issuing the INVITE
552 	 * @param dest The user being invited
553 	 * @param channel The channel the user is being invited to
554 	 * @param timeout The time the invite will expire (0 == never)
555 	 * @return 1 to deny the invite, 0 to check whether or not the user has permission to invite, -1 to explicitly allow the invite
556 	 */
557 	virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
558 
559 	/** Called after a user has been successfully invited to a channel.
560 	 * You cannot prevent the invite from occurring using this function, to do that,
561 	 * use OnUserPreInvite instead.
562 	 * @param source The user who is issuing the INVITE
563 	 * @param dest The user being invited
564 	 * @param channel The channel the user is being invited to
565 	 * @param timeout The time the invite will expire (0 == never)
566 	 * @param notifyrank Rank required to get an invite announcement (if enabled)
567 	 * @param notifyexcepts List of users to not send the default NOTICE invite announcement to
568 	 */
569 	virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
570 
571 	/** Called before a user sends a message to a channel, a user, or a server glob mask.
572 	 * @param user The user sending the message.
573 	 * @param target The target of the message. This can either be a channel, a user, or a server
574 	 *               glob mask.
575 	 * @param details Details about the message such as the message text and type. See the
576 	 *                MessageDetails class for more information.
577 	 * @return MOD_RES_ALLOW to explicitly allow the message, MOD_RES_DENY to explicitly deny the
578 	 *         message, or MOD_RES_PASSTHRU to let another module handle the event.
579 	 */
580 	virtual ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details);
581 
582 	/** Called when sending a message to all "neighbors" of a given user -
583 	 * that is, all users that share a common channel. This is used in
584 	 * commands such as NICK, QUIT, etc.
585 	 * @param source The source of the message
586 	 * @param include_c Channels to scan for users to include
587 	 * @param exceptions Map of user->bool that overrides the inclusion decision
588 	 *
589 	 * Set exceptions[user] = true to include, exceptions[user] = false to exclude
590 	 */
591 	virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
592 
593 	/** Called before local nickname changes. This can be used to implement Q-lines etc.
594 	 * If your method returns nonzero, the nickchange is silently forbidden, and it is down to your
595 	 * module to generate some meaningful output.
596 	 * @param user The username changing their nick
597 	 * @param newnick Their new nickname
598 	 * @return 1 to deny the change, 0 to allow
599 	 */
600 	virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
601 
602 	/** Called immediately after a user sends a message to a channel, a user, or a server glob mask.
603 	 * @param user The user sending the message.
604 	 * @param target The target of the message. This can either be a channel, a user, or a server
605 	 *               glob mask.
606 	 * @param details Details about the message such as the message text and type. See the
607 	 *                MessageDetails class for more information.
608 	 */
609 	virtual void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details);
610 
611 	/** Called immediately before a user sends a message to a channel, a user, or a server glob mask.
612 	 * @param user The user sending the message.
613 	 * @param target The target of the message. This can either be a channel, a user, or a server
614 	 *               glob mask.
615 	 * @param details Details about the message such as the message text and type. See the
616 	 *                MessageDetails class for more information.
617 	 */
618 	virtual void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details);
619 
620 	/** Called when a message sent by a user to a channel, a user, or a server glob mask is blocked.
621 	 * @param user The user sending the message.
622 	 * @param target The target of the message. This can either be a channel, a user, or a server
623 	 *               glob mask.
624 	 * @param details Details about the message such as the message text and type. See the
625 	 *                MessageDetails class for more information.
626 	 */
627 	virtual void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details);
628 
629 	/** Called after every MODE command sent from a user
630 	 * Either the usertarget or the chantarget variable contains the target of the modes,
631 	 * the actual target will have a non-NULL pointer.
632 	 * All changed modes are available in the changelist object.
633 	 * @param user The user sending the MODEs
634 	 * @param usertarget The target user of the modes, NULL if the target is a channel
635 	 * @param chantarget The target channel of the modes, NULL if the target is a user
636 	 * @param changelist The changed modes.
637 	 * @param processflags Flags passed to ModeParser::Process(), see ModeParser::ModeProcessFlags
638 	 * for the possible flags.
639 	 */
640 	virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags);
641 
642 	/** Allows module data, sent via ProtoSendMetaData, to be decoded again by a receiving module.
643 	 * Please see src/modules/m_swhois.cpp for a working example of how to use this method call.
644 	 * @param target The Channel* or User* that data should be added to
645 	 * @param extname The extension name which is being sent
646 	 * @param extdata The extension data, encoded at the other end by an identical module
647 	 */
648 	virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
649 
650 	/** Called whenever a user's hostname is changed.
651 	 * This event triggers after the host has been set.
652 	 * @param user The user whose host is being changed
653 	 * @param newhost The new hostname being set
654 	 */
655 	virtual void OnChangeHost(User* user, const std::string &newhost);
656 
657 	/** Called whenever a user's real hostname is changed.
658 	 * This event triggers before the host has been set.
659 	 * @param user The user whose host is being changed
660 	 * @param newhost The new hostname being set
661 	 */
662 	virtual void OnChangeRealHost(User* user, const std::string& newhost);
663 
664 	/** Called whenever a user's real hostname is changed.
665 	 * This event triggers after the host has been set.
666 	 * @param user The user whos host was changed.
667 	 */
668 	virtual void OnPostChangeRealHost(User* user);
669 
670 	/** Called whenever a user's real name is changed.
671 	 * This event triggers after the name has been set.
672 	 * @param user The user who's real name is being changed
673 	 * @param real The new real name being set on the user
674 	 */
675 	virtual void OnChangeRealName(User* user, const std::string& real);
676 
677 	/** Called whenever a user's IDENT is changed.
678 	 * This event triggers after the name has been set.
679 	 * @param user The user who's IDENT is being changed
680 	 * @param ident The new IDENT being set on the user
681 	 */
682 	virtual void OnChangeIdent(User* user, const std::string &ident);
683 
684 	/** Called whenever an xline is added by a local user.
685 	 * This method is triggered after the line is added.
686 	 * @param source The sender of the line or NULL for local server
687 	 * @param line The xline being added
688 	 */
689 	virtual void OnAddLine(User* source, XLine* line);
690 
691 	/** Called whenever an xline is deleted MANUALLY. See OnExpireLine for expiry.
692 	 * This method is triggered after the line is deleted.
693 	 * @param source The user removing the line or NULL for local server
694 	 * @param line the line being deleted
695 	 */
696 	virtual void OnDelLine(User* source, XLine* line);
697 
698 	/** Called whenever an xline expires.
699 	 * This method is triggered after the line is deleted.
700 	 * @param line The line being deleted.
701 	 */
702 	virtual void OnExpireLine(XLine *line);
703 
704 	/** Called before the module is unloaded to clean up extensibles.
705 	 * This method is called once for every channel, membership, and user.
706 	 * so that you can clear up any data relating to the specified extensible.
707 	 * @param type The type of extensible being cleaned up. If this is EXT_CHANNEL
708 	 *             then item is a Channel*, EXT_MEMBERSHIP then item is a Membership*,
709 	 *             and EXT_USER then item is a User*.
710 	 * @param item A pointer to the extensible which is being cleaned up.
711 	 */
712 	virtual void OnCleanup(ExtensionItem::ExtensibleType type, Extensible* item);
713 
714 	/** Called after any nickchange, local or remote. This can be used to track users after nickchanges
715 	 * have been applied. Please note that although you can see remote nickchanges through this function, you should
716 	 * NOT make any changes to the User if the user is a remote user as this may cause a desync.
717 	 * check user->server before taking any action (including returning nonzero from the method).
718 	 * Because this method is called after the nickchange is taken place, no return values are possible
719 	 * to indicate forbidding of the nick change. Use OnUserPreNick for this.
720 	 * @param user The user changing their nick
721 	 * @param oldnick The old nickname of the user before the nickchange
722 	 */
723 	virtual void OnUserPostNick(User* user, const std::string &oldnick);
724 
725 	/** Called before a mode change via the MODE command, to allow a single access check for
726 	 * a full mode change (use OnRawMode to check individual modes)
727 	 *
728 	 * Returning MOD_RES_ALLOW will skip prefix level checks, but can be overridden by
729 	 * OnRawMode for each individual mode
730 	 *
731 	 * @param source the user making the mode change
732 	 * @param dest the user destination of the umode change (NULL if a channel mode)
733 	 * @param channel the channel destination of the mode change
734 	 * @param modes Modes being changed, can be edited
735 	 */
736 	virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
737 
738 	/** Called when a 005 numeric is about to be output.
739 	 * The module should modify the 005 numeric if needed to indicate its features.
740 	* @param tokens The 005 map to be modified if necessary.
741 	*/
742 	virtual void On005Numeric(std::map<std::string, std::string>& tokens);
743 
744 	/** Called when a client is disconnected by KILL.
745 	 * If a client is killed by a server, e.g. a nickname collision or protocol error,
746 	 * source is NULL.
747 	 * Return 1 from this function to prevent the kill, and 0 from this function to allow
748 	 * it as normal. If you prevent the kill no output will be sent to the client, it is
749 	 * down to your module to generate this information.
750 	 * NOTE: It is NOT advisable to stop kills which originate from servers or remote users.
751 	 * If you do so youre risking race conditions, desyncs and worse!
752 	 * @param source The user sending the KILL
753 	 * @param dest The user being killed
754 	 * @param reason The kill reason
755 	 * @return 1 to prevent the kill, 0 to allow
756 	 */
757 	virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
758 
759 	/** Called whenever a module is loaded.
760 	 * mod will contain a pointer to the module, and string will contain its name,
761 	 * for example m_widgets.so. This function is primary for dependency checking,
762 	 * your module may decide to enable some extra features if it sees that you have
763 	 * for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly
764 	 * recommended that modules do *NOT* bail if they cannot satisfy dependencies,
765 	 * but instead operate under reduced functionality, unless the dependency is
766 	 * absolutely necessary (e.g. a module that extends the features of another
767 	 * module).
768 	 * @param mod A pointer to the new module
769 	 */
770 	virtual void OnLoadModule(Module* mod);
771 
772 	/** Called whenever a module is unloaded.
773 	 * mod will contain a pointer to the module, and string will contain its name,
774 	 * for example m_widgets.so. This function is primary for dependency checking,
775 	 * your module may decide to enable some extra features if it sees that you have
776 	 * for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly
777 	 * recommended that modules do *NOT* bail if they cannot satisfy dependencies,
778 	 * but instead operate under reduced functionality, unless the dependency is
779 	 * absolutely necessary (e.g. a module that extends the features of another
780 	 * module).
781 	 * @param mod Pointer to the module being unloaded (still valid)
782 	 */
783 	virtual void OnUnloadModule(Module* mod);
784 
785 	/** Called once every five seconds for background processing.
786 	 * This timer can be used to control timed features. Its period is not accurate
787 	 * enough to be used as a clock, but it is guaranteed to be called at least once in
788 	 * any five second period, directly from the main loop of the server.
789 	 * @param curtime The current timer derived from time(2)
790 	 */
791 	virtual void OnBackgroundTimer(time_t curtime);
792 
793 	/** Called whenever any command is about to be executed.
794 	 * This event occurs for all registered commands, whether they are registered in the core,
795 	 * or another module, and for invalid commands. Invalid commands may only be sent to this
796 	 * function when the value of validated is false. By returning 1 from this method you may prevent the
797 	 * command being executed. If you do this, no output is created by the core, and it is
798 	 * down to your module to produce any output necessary.
799 	 * Note that unless you return 1, you should not destroy any structures (e.g. by using
800 	 * InspIRCd::QuitUser) otherwise when the command's handler function executes after your
801 	 * method returns, it will be passed an invalid pointer to the user object and crash!)
802 	 * @param command The command being executed
803 	 * @param parameters An array of array of characters containing the parameters for the command
804 	 * @param user the user issuing the command
805 	 * @param validated True if the command has passed all checks, e.g. it is recognised, has enough parameters, the user has permission to execute it, etc.
806 	 * You should only change the parameter list and command string if validated == false (e.g. before the command lookup occurs).
807 	 * @return 1 to block the command, 0 to allow
808 	 */
809 	virtual ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated);
810 
811 	/** Called after any command has been executed.
812 	 * This event occurs for all registered commands, whether they are registered in the core,
813 	 * or another module, but it will not occur for invalid commands (e.g. ones which do not
814 	 * exist within the command table). The result code returned by the command handler is
815 	 * provided.
816 	 * @param command The command being executed
817 	 * @param parameters An array of array of characters containing the parameters for the command
818 	 * @param user the user issuing the command
819 	 * @param result The return code given by the command handler, one of CMD_SUCCESS or CMD_FAILURE
820 	 * @param loop Whether the command is being called from LoopCall or directly.
821 	 */
822 	virtual void OnPostCommand(Command* command, const CommandBase::Params& parameters, LocalUser* user, CmdResult result, bool loop);
823 
824 	/** Called when a command was blocked before it could be executed.
825 	 * @param command The command being executed.
826 	 * @param parameters The parameters for the command.
827 	 * @param user The user issuing the command.
828 	 */
829 	virtual void OnCommandBlocked(const std::string& command, const CommandBase::Params& parameters, LocalUser* user);
830 
831 	/** Called after a user object is initialised and added to the user list.
832 	 * When this is called the user has not had their I/O hooks checked or had their initial
833 	 * connect class assigned and may not yet have a serializer. You probably want to use
834 	 * the OnUserPostInit or OnUserSetIP hooks instead of this one.
835 	 * @param user The connecting user.
836 	 */
837 	virtual void OnUserInit(LocalUser* user);
838 
839 	/** Called after a user object has had their I/O hooks checked, their initial connection
840 	 * class assigned, and had a serializer set.
841 	 * @param user The connecting user.
842 	 */
843 	virtual void OnUserPostInit(LocalUser* user);
844 
845 	/** Called to check if a user who is connecting can now be allowed to register
846 	 * If any modules return false for this function, the user is held in the waiting
847 	 * state until all modules return true. For example a module which implements ident
848 	 * lookups will continue to return false for a user until their ident lookup is completed.
849 	 * Note that the registration timeout for a user overrides these checks, if the registration
850 	 * timeout is reached, the user is disconnected even if modules report that the user is
851 	 * not ready to connect.
852 	 * @param user The user to check
853 	 * @return true to indicate readiness, false if otherwise
854 	 */
855 	virtual ModResult OnCheckReady(LocalUser* user);
856 
857 	/** Called whenever a user is about to register their connection (e.g. before the user
858 	 * is sent the MOTD etc). Modules can use this method if they are performing a function
859 	 * which must be done before the actual connection is completed (e.g. ident lookups,
860 	 * dnsbl lookups, etc).
861 	 * Note that you should NOT delete the user record here by causing a disconnection!
862 	 * Use OnUserConnect for that instead.
863 	 * @param user The user registering
864 	 * @return 1 to indicate user quit, 0 to continue
865 	 */
866 	virtual ModResult OnUserRegister(LocalUser* user);
867 
868 	/** Called whenever a user joins a channel, to determine if invite checks should go ahead or not.
869 	 * This method will always be called for each join, whether or not the channel is actually +i, and
870 	 * determines the outcome of an if statement around the whole section of invite checking code.
871 	 * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
872 	 * @param user The user joining the channel
873 	 * @param chan The channel being joined
874 	 * @return 1 to explicitly allow the join, 0 to proceed as normal
875 	 */
876 	virtual ModResult OnCheckInvite(User* user, Channel* chan);
877 
878 	/** Called whenever a mode character is processed.
879 	 * Return 1 from this function to block the mode character from being processed entirely.
880 	 * @param user The user who is sending the mode
881 	 * @param chan The channel the mode is being sent to (or NULL if a usermode)
882 	 * @param mh The mode handler for the mode being changed
883 	 * @param param The parameter for the mode or an empty string
884 	 * @param adding true of the mode is being added, false if it is being removed
885 	 * @return ACR_DENY to deny the mode, ACR_DEFAULT to do standard mode checking, and ACR_ALLOW
886 	 * to skip all permission checking. Please note that for remote mode changes, your return value
887 	 * will be ignored!
888 	 */
889 	virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
890 
891 	/** Called whenever a user joins a channel, to determine if key checks should go ahead or not.
892 	 * This method will always be called for each join, whether or not the channel is actually +k, and
893 	 * determines the outcome of an if statement around the whole section of key checking code.
894 	 * if the user specified no key, the keygiven string will be a valid but empty value.
895 	 * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
896 	 * @param user The user joining the channel
897 	 * @param chan The channel being joined
898 	 * @param keygiven The key given on joining the channel.
899 	 * @return 1 to explicitly allow the join, 0 to proceed as normal
900 	 */
901 	virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
902 
903 	/** Called whenever a user joins a channel, to determine if channel limit checks should go ahead or not.
904 	 * This method will always be called for each join, whether or not the channel is actually +l, and
905 	 * determines the outcome of an if statement around the whole section of channel limit checking code.
906 	 * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
907 	 * @param user The user joining the channel
908 	 * @param chan The channel being joined
909 	 * @return 1 to explicitly allow the join, 0 to proceed as normal
910 	 */
911 	virtual ModResult OnCheckLimit(User* user, Channel* chan);
912 
913 	/**
914 	 * Checks for a user's ban from the channel
915 	 * @param user The user to check
916 	 * @param chan The channel to check in
917 	 * @return MOD_RES_DENY to mark as banned, MOD_RES_ALLOW to skip the
918 	 * ban check, or MOD_RES_PASSTHRU to check bans normally
919 	 */
920 	virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
921 
922 	/**
923 	 * Checks for a user's match of a single ban
924 	 * @param user The user to check for match
925 	 * @param chan The channel on which the match is being checked
926 	 * @param mask The mask being checked
927 	 * @return MOD_RES_DENY to mark as banned, MOD_RES_ALLOW to skip the
928 	 * ban check, or MOD_RES_PASSTHRU to check bans normally
929 	 */
930 	virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
931 
932 	/** Checks for a match on a given extban type
933 	 * @return MOD_RES_DENY to mark as banned, MOD_RES_ALLOW to skip the
934 	 * ban check, or MOD_RES_PASSTHRU to check bans normally
935 	 */
936 	virtual ModResult OnExtBanCheck(User* user, Channel* chan, char type);
937 
938 	/** Called whenever a change of a local users displayed host is attempted.
939 	 * Return 1 to deny the host change, or 0 to allow it.
940 	 * @param user The user whose host will be changed
941 	 * @param newhost The new hostname
942 	 * @return 1 to deny the host change, 0 to allow
943 	 */
944 	virtual ModResult OnPreChangeHost(LocalUser* user, const std::string &newhost);
945 
946 	/** Called whenever a change of a local users real name is attempted.
947 	 * return MOD_RES_DENY to deny the name change, or MOD_RES_ALLOW to allow it.
948 	 * @param user The user whose real name will be changed
949 	 * @param newhost The new real name.
950 	 * @return MOD_RES_DENY to deny the real name change, MOD_RES_ALLOW to allow
951 	 */
952 	virtual ModResult OnPreChangeRealName(LocalUser* user, const std::string &newhost);
953 
954 	/** Called before a topic is changed.
955 	 * Return 1 to deny the topic change, 0 to check details on the change, -1 to let it through with no checks
956 	 * As with other 'pre' events, you should only ever block a local event.
957 	 * @param user The user changing the topic
958 	 * @param chan The channels who's topic is being changed
959 	 * @param topic The actual topic text
960 	 * @return 1 to block the topic change, 0 to allow
961 	 */
962 	virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
963 
964 	/** Called whenever a topic has been changed.
965 	 * To block topic changes you must use OnPreTopicChange instead.
966 	 * @param user The user changing the topic
967 	 * @param chan The channels who's topic is being changed
968 	 * @param topic The actual topic text
969 	 */
970 	virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
971 
972 	/** Called whenever a password check is to be made. Replaces the old OldOperCompare API.
973 	 * The password field (from the config file) is in 'password' and is to be compared against
974 	 * 'input'. This method allows for encryption of passwords (oper, connect:allow, die/restart, etc).
975 	 * You should return a nonzero value to override the normal comparison, or zero to pass it on.
976 	 * @param ex The object that's causing the authentication (User* for \<oper> \<connect:allow> etc, Server* for \<link>).
977 	 * @param password The password from the configuration file (the password="" value).
978 	 * @param input The password entered by the user or whoever.
979 	 * @param hashtype The hash value from the config
980 	 * @return 0 to do nothing (pass on to next module/default), 1 == password is OK, -1 == password is not OK
981 	 */
982 	virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
983 
984 	/** Called after a user has fully connected and all modules have executed OnUserConnect
985 	 * This event is informational only. You should not change any user information in this
986 	 * event. To do so, use the OnUserConnect method to change the state of local users.
987 	 * This is called for both local and remote users.
988 	 * @param user The user who is connecting
989 	 */
990 	virtual void OnPostConnect(User* user);
991 
992 	/** Called when a port accepts a connection
993 	 * Return MOD_RES_ACCEPT if you have used the file descriptor.
994 	 * @param fd The file descriptor returned from accept()
995 	 * @param sock The socket connection for the new user
996 	 * @param client The client IP address and port
997 	 * @param server The server IP address and port
998 	 */
999 	virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
1000 
1001 	/** Called at intervals for modules to garbage-collect any hashes etc.
1002 	 * Certain data types such as hash_map 'leak' buckets, which must be
1003 	 * tidied up and freed by copying into a new item every so often. This
1004 	 * method is called when it is time to do that.
1005 	 */
1006 	virtual void OnGarbageCollect();
1007 
1008 	/** Called when a user's connect class is being matched
1009 	 * @return MOD_RES_ALLOW to force the class to match, MOD_RES_DENY to forbid it, or
1010 	 * MOD_RES_PASSTHRU to allow normal matching (by host/port).
1011 	 */
1012 	virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
1013 
1014 	virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
1015 
1016 	/** Called whenever a local user's IP is set for the first time, or when a local user's IP changes due to
1017 	 * a module like m_cgiirc changing it.
1018 	 * @param user The user whose IP is being set
1019 	 */
1020 	virtual void OnSetUserIP(LocalUser* user);
1021 
1022 	/** Called whenever a ServiceProvider is registered.
1023 	 * @param service ServiceProvider being registered.
1024 	 */
1025 	virtual void OnServiceAdd(ServiceProvider& service);
1026 
1027 	/** Called whenever a ServiceProvider is unregistered.
1028 	 * @param service ServiceProvider being unregistered.
1029 	 */
1030 	virtual void OnServiceDel(ServiceProvider& service);
1031 
1032 	/** Called whenever a message is about to be written to a user.
1033 	 * @param user The user who is having a message sent to them.
1034 	 * @param msg The message which is being written to the user.
1035 	 * @return MOD_RES_ALLOW to explicitly allow the message to be sent, MOD_RES_DENY to explicitly
1036 	 * deny the message from being sent, or MOD_RES_PASSTHRU to let another module handle the event.
1037 	 */
1038 	virtual ModResult OnUserWrite(LocalUser* user, ClientProtocol::Message& msg);
1039 
1040 	/** Called when a user connection has been unexpectedly disconnected.
1041 	 * @param user The user who has been unexpectedly disconnected.
1042 	 * @param error The type of error which caused this connection failure.
1043 	 * @return MOD_RES_ALLOW to explicitly retain the user as a zombie, MOD_RES_DENY to explicitly
1044 	 * disconnect the user, or MOD_RES_PASSTHRU to let another module handle the event.
1045 	 */
1046 	virtual ModResult OnConnectionFail(LocalUser* user, BufferedSocketError error);
1047 
1048 	/** Called before a server shuts down.
1049 	 * @param reason The reason the server is shutting down.
1050 	 */
1051 	virtual void OnShutdown(const std::string& reason);
1052 };
1053 
1054 /** ModuleManager takes care of all things module-related
1055  * in the core.
1056  */
1057 class CoreExport ModuleManager : public fakederef<ModuleManager>
1058 {
1059  public:
1060 	typedef std::multimap<std::string, ServiceProvider*, irc::insensitive_swo> DataProviderMap;
1061 	typedef std::vector<ServiceProvider*> ServiceList;
1062 
1063  private:
1064 	/** Holds a string describing the last module error to occur
1065 	 */
1066 	std::string LastModuleError;
1067 
1068 	/** List of loaded modules and shared object/dll handles
1069 	 * keyed by module name
1070 	 */
1071 	std::map<std::string, Module*> Modules;
1072 
1073 	enum {
1074 		PRIO_STATE_FIRST,
1075 		PRIO_STATE_AGAIN,
1076 		PRIO_STATE_LAST
1077 	} prioritizationState;
1078 
1079 	/** Loads all core modules (core_*)
1080 	 */
1081 	void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
1082 
1083 	/** Calls the Prioritize() method in all loaded modules
1084 	 * @return True if all went well, false if a dependency loop was detected
1085 	 */
1086 	bool PrioritizeHooks();
1087 
1088 	/** Unregister all user modes or all channel modes owned by a module
1089 	 * @param mod Module whose modes to unregister
1090 	 * @param modetype MODETYPE_USER to unregister user modes, MODETYPE_CHANNEL to unregister channel modes
1091 	 */
1092 	void UnregisterModes(Module* mod, ModeType modetype);
1093 
1094  public:
1095 	typedef std::map<std::string, Module*> ModuleMap;
1096 
1097 	/** Event handler hooks.
1098 	 * This needs to be public to be used by FOREACH_MOD and friends.
1099 	 */
1100 	Module::List EventHandlers[I_END];
1101 
1102 	/** List of data services keyed by name */
1103 	DataProviderMap DataProviders;
1104 
1105 	/** A list of ServiceProviders waiting to be registered.
1106 	 * Non-NULL when constructing a Module, NULL otherwise.
1107 	 * When non-NULL ServiceProviders add themselves to this list on creation and the core
1108 	 * automatically registers them (that is, call AddService()) after the Module is constructed,
1109 	 * and before Module::init() is called.
1110 	 * If a service is created after the construction of the Module (for example in init()) it
1111 	 * has to be registered manually.
1112 	 */
1113 	ServiceList* NewServices;
1114 
1115 	/** Expands the name of a module by prepending "m_" and appending ".so".
1116 	 * No-op if the name already has the ".so" extension.
1117 	 * @param modname Module name to expand
1118 	 * @return Module name starting with "m_" and ending with ".so"
1119 	 */
1120 	static std::string ExpandModName(const std::string& modname);
1121 
1122 	/** Simple, bog-standard, boring constructor.
1123 	 */
1124 	ModuleManager();
1125 
1126 	/** Destructor
1127 	 */
1128 	~ModuleManager();
1129 
1130 	/** Change the priority of one event in a module.
1131 	 * Each module event has a list of modules which are attached to that event type.
1132 	 * If you wish to be called before or after other specific modules, you may use this
1133 	 * method (usually within void Module::Prioritize()) to set your events priority.
1134 	 * You may use this call in other methods too, however, this is not supported behaviour
1135 	 * for a module.
1136 	 * @param mod The module to change the priority of
1137 	 * @param i The event to change the priority of
1138 	 * @param s The state you wish to use for this event. Use one of
1139 	 * PRIO_FIRST to set the event to be first called, PRIO_LAST to
1140 	 * set it to be the last called, or PRIO_BEFORE and PRIORITY_AFTER
1141 	 * to set it to be before or after one or more other modules.
1142 	 * @param which If PRIO_BEFORE or PRIORITY_AFTER is set in parameter 's',
1143 	 * then this contains a the module that your module must be placed before
1144 	 * or after.
1145 	 */
1146 	bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1147 
1148 	/** Change the priority of all events in a module.
1149 	 * @param mod The module to set the priority of
1150 	 * @param s The priority of all events in the module.
1151 	 * Note that with this method, it is not possible to effectively use
1152 	 * PRIO_BEFORE or PRIORITY_AFTER, you should use the more fine tuned
1153 	 * SetPriority method for this, where you may specify other modules to
1154 	 * be prioritized against.
1155 	 */
1156 	void SetPriority(Module* mod, Priority s);
1157 
1158 	/** Attach an event to a module.
1159 	 * You may later detach the event with ModuleManager::Detach().
1160 	 * If your module is unloaded, all events are automatically detached.
1161 	 * @param i Event type to attach
1162 	 * @param mod Module to attach event to
1163 	 * @return True if the event was attached
1164 	 */
1165 	bool Attach(Implementation i, Module* mod);
1166 
1167 	/** Detach an event from a module.
1168 	 * This is not required when your module unloads, as the core will
1169 	 * automatically detach your module from all events it is attached to.
1170 	 * @param i Event type to detach
1171 	 * @param mod Module to detach event from
1172 	 * @return True if the event was detached
1173 	 */
1174 	bool Detach(Implementation i, Module* mod);
1175 
1176 	/** Attach an array of events to a module
1177 	 * @param i Event types (array) to attach
1178 	 * @param mod Module to attach events to
1179 	 * @param sz The size of the implementation array
1180 	 */
1181 	void Attach(Implementation* i, Module* mod, size_t sz);
1182 
1183 	/** Detach all events from a module (used on unload)
1184 	 * @param mod Module to detach from
1185 	 */
1186 	void DetachAll(Module* mod);
1187 
1188 	/** Attach all events to a module (used on module load)
1189 	 * @param mod Module to attach to all events
1190 	 */
1191 	void AttachAll(Module* mod);
1192 
1193 	/** Returns text describing the last module error
1194 	 * @return The last error message to occur
1195 	 */
1196 	std::string& LastError();
1197 
1198 	/** Load a given module file
1199 	 * @param filename The file to load
1200 	 * @param defer Defer module init (loading many modules)
1201 	 * @return True if the module was found and loaded
1202 	 */
1203 	bool Load(const std::string& filename, bool defer = false);
1204 
1205 	/** Unload a given module file. Note that the module will not be
1206 	 * completely gone until the cull list has finished processing.
1207 	 *
1208 	 * @return true on success; if false, LastError will give a reason
1209 	 */
1210 	bool Unload(Module* module);
1211 
1212 	/** Called by the InspIRCd constructor to load all modules from the config file.
1213 	 */
1214 	void LoadAll();
1215 	void UnloadAll();
1216 	void DoSafeUnload(Module*);
1217 
1218 	/** Check if a module can be unloaded and if yes, prepare it for unload
1219 	 * @param mod Module to be unloaded
1220 	 * @return True if the module is unloadable, false otherwise.
1221 	 * If true the module must be unloaded in the current main loop iteration.
1222 	 */
1223 	bool CanUnload(Module* mod);
1224 
1225 	/** Find a module by name, and return a Module* to it.
1226 	 * This is preferred over iterating the module lists yourself.
1227 	 * @param name The module name to look up
1228 	 * @return A pointer to the module, or NULL if the module cannot be found
1229 	 */
1230 	Module* Find(const std::string &name);
1231 
1232 	/** Register a service provided by a module */
1233 	void AddService(ServiceProvider&);
1234 
1235 	/** Unregister a service provided by a module */
1236 	void DelService(ServiceProvider&);
1237 
1238 	/** Register all services in a given ServiceList
1239 	 * @param list The list containing the services to register
1240 	 */
1241 	void AddServices(const ServiceList& list);
1242 
AddServices(ServiceProvider ** list,int count)1243 	inline void AddServices(ServiceProvider** list, int count)
1244 	{
1245 		for(int i=0; i < count; i++)
1246 			AddService(*list[i]);
1247 	}
1248 
1249 	/** Find a service by name.
1250 	 * If multiple modules provide a given service, the first one loaded will be chosen.
1251 	 */
1252 	ServiceProvider* FindService(ServiceType Type, const std::string& name);
1253 
FindDataService(const std::string & name)1254 	template<typename T> inline T* FindDataService(const std::string& name)
1255 	{
1256 		return static_cast<T*>(FindService(SERVICE_DATA, name));
1257 	}
1258 
1259 	/** Get a map of all loaded modules keyed by their name
1260 	 * @return A ModuleMap containing all loaded modules
1261 	 */
GetModules()1262 	const ModuleMap& GetModules() const { return Modules; }
1263 
1264 	/** Make a service referenceable by dynamic_references
1265 	 * @param name Name that will be used by dynamic_references to find the object
1266 	 * @param service Service to make referenceable by dynamic_references
1267 	 */
1268 	void AddReferent(const std::string& name, ServiceProvider* service);
1269 
1270 	/** Make a service no longer referenceable by dynamic_references
1271 	 * @param service Service to make no longer referenceable by dynamic_references
1272 	 */
1273 	void DelReferent(ServiceProvider* service);
1274 };
1275