* +------------------------------------+
*
* InspIRCd: (C) 2002-2009 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
MSG_NOTICE = 1
};
-/** If you change the module API, change this value.
- * If you have enabled ipv6, the sizes of structs is
- * different, and modules will be incompatible with
- * ipv4 servers, so this value will be ten times as
- * high on ipv6 servers.
- */
-#define NATIVE_API_VERSION 12000
-#ifdef IPV6
-#define API_VERSION (NATIVE_API_VERSION * 10)
-#else
-#define API_VERSION (NATIVE_API_VERSION * 1)
-#endif
+/** If you change the module API, change this value. */
+#define API_VERSION 13000
class ServerConfig;
} \
} while (0);
+#define FOREACH_RESULT_MAP(y,x,f) \
+do { \
+ EventHandlerIter safei; \
+ for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \
+ { \
+ safei = _i; \
+ ++safei; \
+ try \
+ { \
+ int MOD_RESULT = (*_i)->x ; \
+ f; \
+ } \
+ catch (CoreException& modexcept) \
+ { \
+ ServerInstance->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
+ } \
+ _i = safei; \
+ } \
+} while(0);
+
/** Represents a non-local user.
* (in fact, any FD less than -1 does)
*/
#define FD_MAGIC_NUMBER -42
+/** Represents a fake user (i.e. a server)
+ */
+#define FD_FAKEUSER_NUMBER -7
/* Useful macros */
/** Is a local user */
-#define IS_LOCAL(x) ((x->GetFd() > -1))
+#define IS_LOCAL(x) (x->GetFd() > -1)
/** Is a remote user */
#define IS_REMOTE(x) (x->GetFd() < 0)
+/** Is a fake user */
+#define IS_FAKE(x) (x->GetFd() == FD_FAKEUSER_NUMBER)
/** Is a module created user */
#define IS_MODULE_CREATED(x) (x->GetFd() == FD_MAGIC_NUMBER)
/** Is an oper */
/** This member holds a pointer to arbitary data set by the emitter of the message
*/
char* data;
- /** This should be a null-terminated string identifying the type of request,
- * all modules should define this and use it to determine the nature of the
- * request before they attempt to cast the Request in any way.
- */
- const char* id;
+ /** This should be a null-terminated string identifying the type of request,
+ * all modules should define this and use it to determine the nature of the
+ * request before they attempt to cast the Request in any way.
+ */
+ const char* id;
/** This is a pointer to the sender of the message, which can be used to
* directly trigger events, or to create a reply.
*/
Module* dest;
public:
/** Create a new Request
- * This is for the 'old' way of casting whatever the data is
- * to char* and hoping you get the right thing at the other end.
- * This is slowly being depreciated in favor of the 'new' way.
+ * This is for the 'old' way of casting whatever the data is
+ * to char* and hoping you get the right thing at the other end.
+ * This is slowly being depreciated in favor of the 'new' way.
*/
Request(char* anydata, Module* src, Module* dst);
- /** Create a new Request
- * This is for the 'new' way of defining a subclass
- * of Request and defining it in a common header,
+ /** Create a new Request
+ * This is for the 'new' way of defining a subclass
+ * of Request and defining it in a common header,
* passing an object of your Request subclass through
- * as a Request* and using the ID string to determine
- * what to cast it back to and the other end. This is
- * much safer as there are no casts not confirmed by
- * the ID string, and all casts are child->parent and
- * can be checked at runtime with dynamic_cast<>()
- */
- Request(Module* src, Module* dst, const char* idstr);
+ * as a Request* and using the ID string to determine
+ * what to cast it back to and the other end. This is
+ * much safer as there are no casts not confirmed by
+ * the ID string, and all casts are child->parent and
+ * can be checked at runtime with dynamic_cast<>()
+ */
+ Request(Module* src, Module* dst, const char* idstr);
/** Fetch the Request data
*/
char* GetData();
- /** Fetch the ID string
+ /** Fetch the ID string
*/
const char* GetId();
/** Fetch the request source
I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserPreNick, I_OnUserMessage, I_OnUserNotice, I_OnMode,
I_OnGetServerDescription, I_OnSyncUser, I_OnSyncChannel, I_OnSyncChannelMetaData, I_OnSyncUserMetaData,
I_OnDecodeMetaData, I_ProtoSendMode, I_ProtoSendMetaData, I_OnWallops, I_OnChangeHost, I_OnChangeName, I_OnAddLine,
- I_OnDelLine, I_OnExpireLine, I_OnCleanup, I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill, I_OnLoadModule, I_OnUnloadModule,
- I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite, I_OnRawMode,
+ I_OnDelLine, I_OnExpireLine, I_OnCleanup, I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill,
+ I_OnLoadModule, I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite, I_OnRawMode,
I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckExtBan, I_OnCheckStringExtBan, I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos,
I_OnLocalTopicChange, I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan, I_OnDelBan,
I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead, I_OnChangeLocalUserGECOS, I_OnUserRegister,
I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnUserList,
I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed,
I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookUserIO, I_OnHostCycle,
+ I_OnPreRehash, I_OnModuleRehash,
I_END
};
/** Called on rehash.
* This method is called prior to a /REHASH or when a SIGHUP is received from the operating
- * system. You should use it to reload any files so that your module keeps in step with the
- * rest of the application. If a parameter is given, the core has done nothing. The module
- * receiving the event can decide if this parameter has any relevence to it.
- * @param user The user performing the rehash, if any -- if this is server initiated, the
- * value of this variable will be NULL.
- * @param parameter The (optional) parameter given to REHASH from the user.
+ * system. This is called in all cases -- including when this server will not execute the
+ * rehash because it is directed at a remote server.
+ *
+ * @param user The user performing the rehash, if any. If this is server initiated, the value of
+ * this variable will be NULL.
+ * @param parameter The (optional) parameter given to REHASH from the user. Empty when server
+ * initiated.
*/
- virtual void OnRehash(User* user, const std::string ¶meter);
+ virtual void OnPreRehash(User* user, const std::string ¶meter);
+
+ /** Called on rehash.
+ * This method is called when a user initiates a module-specific rehash. This can be used to do
+ * expensive operations (such as reloading SSL certificates) that are not executed on a normal
+ * rehash for efficiency. A rehash of this type does not reload the core configuration.
+ *
+ * @param user The user performing the rehash.
+ * @param parameter The parameter given to REHASH
+ */
+ virtual void OnModuleRehash(User* user, const std::string ¶meter);
+
+ /** Called on rehash.
+ * This method is called after a rehash has completed. You should use it to reload any module
+ * configuration from the main configuration file.
+ * @param user The user that performed the rehash, if it was initiated by a user and that user
+ * is still connected.
+ */
+ virtual void OnRehash(User* user);
/** Called whenever a snotice is about to be sent to a snomask.
* snomask and type may both be modified; the message may not.
* @param dest The target of the modes (User* or Channel*)
* @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
* @param text The actual modes and their parameters if any
+ * @param translate The translation types of the mode parameters
*/
- virtual void OnMode(User* user, void* dest, int target_type, const std::string &text);
+ virtual void OnMode(User* user, void* dest, int target_type, const std::vector<std::string> &text, const std::vector<TranslateType> &translate);
/** Allows modules to alter or create server descriptions
* Whenever a module requires a server description, for example for display in
* @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL
* @param target The Channel* or User* that modes should be sent for
* @param modeline The modes and parameters to be sent
+ * @param translate The translation types of the mode parameters
*/
- virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline);
+ virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::vector<std::string> &modeline, const std::vector<TranslateType> &translate);
/** Implemented by modules which provide the ability to link servers.
* These modules will implement this method, which allows metadata (extra data added to
* @param u The user to check
* @param c The channel the user is on
* @param type The type of extended ban to check for.
+ * @returns 1 = exempt, 0 = no match, -1 = banned
*/
virtual int OnCheckExtBan(User *u, Channel *c, char type);
/** Called whenever checking whether or not a string is extbanned. NOTE: one OnCheckExtBan will also trigger a number of
* OnCheckStringExtBan events for seperate host/IP comnbinations.
+ * @returns 1 = exempt, 0 = no match, -1 = banned
*/
virtual int OnCheckStringExtBan(const std::string &s, Channel *c, char type);
*/
virtual int OnDelBan(User* source, Channel* channel,const std::string &banmask);
- virtual void OnHookUserIO(User* user, const std::string &targetip);
+ virtual void OnHookUserIO(User* user);
/** Called immediately after any connection is accepted. This is intended for raw socket
* processing (e.g. modules which wrap the tcp connection within another library) and provides
* There are no return values from this call as all modules get an opportunity if required to
* process the connection.
* @param fd The file descriptor returned from accept()
- * @param ip The IP address of the connecting user
+ * @param client The client IP address and port
+ * @param server The server IP address and port
* @param localport The local port number the user connected to
*/
- virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport);
+ virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
/** Called immediately before any write() operation on a user's socket in the core. Because
* this event is a low level event no user information is associated with it. It is intended
{
protected:
InspIRCd* ServerInstance;
- /** The contents of the configuration file
- * This protected member should never be accessed by a module (and cannot be accessed unless the
- * core is changed). It will contain a pointer to the configuration file data with unneeded data
- * (such as comments) stripped from it.
- */
- ConfigDataHash* data;
- /** Used to store errors
- */
- std::ostringstream* errorlog;
- /** If we're using our own config data hash or not
- */
- bool privatehash;
- /** True if an error occured reading the config file
- */
- bool readerror;
/** Error code
*/
long error;
* as specified when running ./configure.
*/
ConfigReader(InspIRCd* Instance);
- /** Overloaded constructor.
- * This constructor initialises the ConfigReader class to read a user-specified config file
- */
- ConfigReader(InspIRCd* Instance, const std::string &filename);
/** Default destructor.
* This method destroys the ConfigReader class.
*/
* multiple instance tag.
*/
int Enumerate(const std::string &tag);
- /** Returns true if a config file is valid.
- * This method is partially implemented and will only return false if the config
- * file does not exist or could not be opened.
- */
- bool Verify();
- /** Dumps the list of errors in a config file to an output location. If bail is true,
- * then the program will abort. If bail is false and user points to a valid user
- * record, the error report will be spooled to the given user by means of NOTICE.
- * if bool is false AND user is false, the error report will be spooled to all opers
- * by means of a NOTICE to all opers.
- */
- void DumpErrors(bool bail,User* user);
/** Returns the number of items within a tag.
* For example if the tag was <test tag="blah" data="foo"> then this
*/
typedef IntModuleList::iterator EventHandlerIter;
-/** Module priority states
- */
-enum PriorityState
-{
- PRIO_DONTCARE,
- PRIO_FIRST,
- PRIO_LAST,
- PRIO_AFTER,
- PRIO_BEFORE
-};
-
/** ModuleManager takes care of all things module-related
* in the core.
*/
*/
std::string LastModuleError;
- /** The feature names published by various modules
+ /** The feature names published by various modules
*/
featurelist Features;
*/
std::map<std::string, std::pair<ircd_module*, Module*> > Modules;
+ enum {
+ PRIO_STATE_FIRST,
+ PRIO_STATE_AGAIN,
+ PRIO_STATE_LAST
+ } prioritizationState;
public:
/** Event handler hooks.
* @param i The event to change the priority of
* @param s The state you wish to use for this event. Use one of
* PRIO_FIRST to set the event to be first called, PRIO_LAST to
- * set it to be the last called, or PRIO_BEFORE and PRIO_AFTER
+ * set it to be the last called, or PRIO_BEFORE and PRIORITY_AFTER
* to set it to be before or after one or more other modules.
- * @param modules If PRIO_BEFORE or PRIO_AFTER is set in parameter 's',
+ * @param modules If PRIO_BEFORE or PRIORITY_AFTER is set in parameter 's',
* then this contains a list of one or more modules your module must be
* placed before or after. Your module will be placed before the highest
* priority module in this list for PRIO_BEFORE, or after the lowest
- * priority module in this list for PRIO_AFTER.
- * @param sz The number of modules being passed for PRIO_BEFORE and PRIO_AFTER.
+ * priority module in this list for PRIORITY_AFTER.
+ * @param sz The number of modules being passed for PRIO_BEFORE and PRIORITY_AFTER.
* Defaults to 1, as most of the time you will only want to prioritize your module
* to be before or after one other module.
*/
- bool SetPriority(Module* mod, Implementation i, PriorityState s, Module** modules = NULL, size_t sz = 1);
+ bool SetPriority(Module* mod, Implementation i, Priority s, Module** modules = NULL, size_t sz = 1);
/** Change the priority of all events in a module.
* @param mod The module to set the priority of
* @param s The priority of all events in the module.
* Note that with this method, it is not possible to effectively use
- * PRIO_BEFORE or PRIO_AFTER, you should use the more fine tuned
+ * PRIO_BEFORE or PRIORITY_AFTER, you should use the more fine tuned
* SetPriority method for this, where you may specify other modules to
* be prioritized against.
*/
- bool SetPriority(Module* mod, PriorityState s);
+ bool SetPriority(Module* mod, Priority s);
/** Attach an event to a module.
* You may later detatch the event with ModuleManager::Detach().