X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fmodules.h;h=e67f287c889d973542a671781135cd371089489f;hb=f25c4b7a2263f5f3ce9bb41ba56b43c0d3a6d124;hp=cc9f10d2c41090aa3aee6db07b7c3b2df6305531;hpb=ddc77036f61620d15faad818b228a147dbd88852;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/modules.h b/include/modules.h index cc9f10d2c..e67f287c8 100644 --- a/include/modules.h +++ b/include/modules.h @@ -76,18 +76,33 @@ enum MessageType { 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. +/** Used to represent an allow/deny module result. + * Not constructed as an enum because it reverses the value logic of some functions; + * the compiler will inline accesses to have the same efficiency as integer operations. */ -#define NATIVE_API_VERSION 12000 -#ifdef IPV6 -#define API_VERSION (NATIVE_API_VERSION * 10) -#else -#define API_VERSION (NATIVE_API_VERSION * 1) -#endif +struct ModResult { + int res; + explicit ModResult(int r) : res(r) {} + bool operator==(const ModResult& r) const + { + return res == r.res; + } + bool operator!=(const ModResult& r) const + { + return res != r.res; + } + bool operator!() const + { + return !res; + } +}; + +#define MOD_RES_ALLOW (ModResult(1)) +#define MOD_RES_PASSTHRU (ModResult(0)) +#define MOD_RES_DENY (ModResult(-1)) + +/** If you change the module API, change this value. */ +#define API_VERSION 13000 class ServerConfig; @@ -223,25 +238,42 @@ do { \ } \ } while (0); -#define FOREACH_RESULT_MAP(y,x,f) \ +/** + * Custom module result handling loop. This is a paired macro, and should only + * be used with while_each_hook. + * + * See src/channels.cpp for an example of use. + */ +#define DO_EACH_HOOK(z,n,v,args) \ do { \ - EventHandlerIter safei; \ - for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \ + EventHandlerIter iter_ ## n = z->Modules->EventHandlers[I_ ## n].begin(); \ + while (iter_ ## n != z->Modules->EventHandlers[I_ ## n].end()) \ { \ - safei = _i; \ - ++safei; \ + Module* mod_ ## n = *iter_ ## n; \ + iter_ ## n ++; \ try \ { \ - int MOD_RESULT = (*_i)->x ; \ - f; \ + v = (mod_ ## n)->n args; + +#define WHILE_EACH_HOOK(z,n) \ } \ - catch (CoreException& modexcept) \ + catch (CoreException& except_ ## n) \ { \ - ServerInstance->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \ + z->Logs->Log("MODULE",DEFAULT,"Exception caught: %s", (except_ ## n).GetReason()); \ + (void) mod_ ## n; /* catch mismatched pairs */ \ } \ - _i = safei; \ } \ -} while(0); +} while(0) + +#define FIRST_MOD_RESULT(z,n,v,args) do { \ + v = MOD_RES_PASSTHRU; \ + DO_EACH_HOOK(z,n,v,args) \ + { \ + if (v != MOD_RES_PASSTHRU) \ + break; \ + } \ + WHILE_EACH_HOOK(z,n); \ +} while (0) /** Represents a non-local user. * (in fact, any FD less than -1 does) @@ -312,11 +344,11 @@ class CoreExport Request : public ModuleMessage /** 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. */ @@ -326,26 +358,26 @@ class CoreExport Request : public ModuleMessage 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 @@ -413,19 +445,23 @@ enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFOR enum Implementation { I_BEGIN, - I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash, I_OnSendSnotice, - I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo, I_OnWhois, I_OnUserPreInvite, - 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_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_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash, + I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo, I_OnWhois, + I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserPreNick, + I_OnUserMessage, I_OnUserNotice, I_OnMode, I_OnGetServerDescription, I_OnSyncUser, + I_OnSyncChannel, I_OnDecodeMetaData, 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_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_OnSyncNetwork, 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 }; @@ -510,8 +546,9 @@ class CoreExport Module : public Extensible * of the channel (useful for modules such as auditorium) * @param sync This is set to true if the JOIN is the result of a network sync and the remote user is being introduced * to a channel due to the network sync. + * @param created This is true if the join created the channel */ - virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent); + virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created); /** Called after a user joins a channel * Identical to OnUserJoin, but called immediately afterwards, when any linking module has @@ -534,14 +571,33 @@ class CoreExport Module : public Extensible /** 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 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 OnRehash(User* user, const std::string ¶meter); + 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. @@ -766,7 +822,7 @@ class CoreExport Module : public Extensible * @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::deque &text, const std::deque &translate); + virtual void OnMode(User* user, void* dest, int target_type, const std::vector &text, const std::vector &translate); /** Allows modules to alter or create server descriptions * Whenever a module requires a server description, for example for display in @@ -797,9 +853,7 @@ class CoreExport Module : public Extensible * the linking protocol. This currently is m_spanningtree.so. A pointer to this module * is given in Module* proto, so that you may call its methods such as ProtoSendMode * (see below). This function will be called for every user visible on your side - * of the burst, allowing you to for example set modes, etc. Do not use this call to - * synchronize data which you have stored using class Extensible -- There is a specialist - * function OnSyncUserMetaData and OnSyncChannelMetaData for this! + * of the burst, allowing you to for example set modes, etc. * * For a good example of how to use this function, please see src/modules/m_chanprotect.cpp * @@ -809,36 +863,6 @@ class CoreExport Module : public Extensible */ virtual void OnSyncChannel(Channel* chan, Module* proto, void* opaque); - /* Allows modules to syncronize metadata related to channels over the network during a netburst. - * Whenever the linking module wants to send out data, but doesnt know what the data - * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then - * this method is called.You should use the ProtoSendMetaData function after you've - * correctly decided how the data should be represented, to send the metadata on its way if it belongs - * to your module. For a good example of how to use this method, see src/modules/m_swhois.cpp. - * @param chan The channel whos metadata is being syncronized - * @param proto A pointer to the module handling network protocol - * @param opaque An opaque pointer set by the protocol module, should not be modified! - * @param extname The extensions name which is being searched for - * @param displayable If this value is true, the data is going to be displayed to a user, - * and not sent across the network. Use this to determine wether or not to show sensitive data. - */ - virtual void OnSyncChannelMetaData(Channel* chan, Module* proto,void* opaque, const std::string &extname, bool displayable = false); - - /* Allows modules to syncronize metadata related to users over the network during a netburst. - * Whenever the linking module wants to send out data, but doesnt know what the data - * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then - * this method is called. You should use the ProtoSendMetaData function after you've - * correctly decided how the data should be represented, to send the metadata on its way if - * if it belongs to your module. - * @param user The user whos metadata is being syncronized - * @param proto A pointer to the module handling network protocol - * @param opaque An opaque pointer set by the protocol module, should not be modified! - * @param extname The extensions name which is being searched for - * @param displayable If this value is true, the data is going to be displayed to a user, - * and not sent across the network. Use this to determine wether or not to show sensitive data. - */ - virtual void OnSyncUserMetaData(User* user, Module* proto,void* opaque, const std::string &extname, bool displayable = false); - /* Allows modules to syncronize metadata not related to users or channels, over the network during a netburst. * Whenever the linking module wants to send out data, but doesnt know what the data * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then @@ -850,7 +874,7 @@ class CoreExport Module : public Extensible * @param displayable If this value is true, the data is going to be displayed to a user, * and not sent across the network. Use this to determine wether or not to show sensitive data. */ - virtual void OnSyncOtherMetaData(Module* proto, void* opaque, bool displayable = false); + virtual void OnSyncNetwork(Module* proto, void* opaque); /** Allows module data, sent via ProtoSendMetaData, to be decoded again by a receiving module. * Please see src/modules/m_swhois.cpp for a working example of how to use this method call. @@ -859,7 +883,7 @@ class CoreExport Module : public Extensible * @param extname The extension name which is being sent * @param extdata The extension data, encoded at the other end by an identical module through OnSyncChannelMetaData or OnSyncUserMetaData */ - virtual void OnDecodeMetaData(int target_type, void* target, const std::string &extname, const std::string &extdata); + virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata); /** Implemented by modules which provide the ability to link servers. * These modules will implement this method, which allows transparent sending of servermodes @@ -875,7 +899,7 @@ class CoreExport Module : public Extensible * @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::deque &modeline, const std::deque &translate); + virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::vector &modeline, const std::vector &translate); /** Implemented by modules which provide the ability to link servers. * These modules will implement this method, which allows metadata (extra data added to @@ -891,7 +915,14 @@ class CoreExport Module : public Extensible * @param extname The extension name to send metadata for * @param extdata Encoded data for this extension name, which will be encoded at the oppsite end by an identical module using OnDecodeMetaData */ - virtual void ProtoSendMetaData(void* opaque, TargetTypeFlags target_type, void* target, const std::string &extname, const std::string &extdata); + virtual void ProtoSendMetaData(void* opaque, Extensible* target, const std::string &extname, const std::string &extdata); + + /** + * Implemented by all modules that implement ProtoSendMetaData. + * Translates the item into a string format suitable for sending to other servers. + * Currently, this just translates nicks to their UID and channels to their name + */ + virtual std::string ProtoTranslate(Extensible* item); /** Called after every WALLOPS command. * @param user The user sending the WALLOPS @@ -1281,7 +1312,7 @@ class CoreExport Module : public Extensible */ 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 @@ -1289,10 +1320,11 @@ class CoreExport Module : public Extensible * 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 @@ -1427,21 +1459,6 @@ class CoreExport ConfigReader : public classbase { 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; @@ -1452,10 +1469,6 @@ class CoreExport ConfigReader : public classbase * 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. */ @@ -1519,18 +1532,6 @@ class CoreExport ConfigReader : public classbase * 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 @@ -1641,7 +1642,7 @@ class CoreExport ModuleManager : public classbase */ std::string LastModuleError; - /** The feature names published by various modules + /** The feature names published by various modules */ featurelist Features; @@ -1662,6 +1663,11 @@ class CoreExport ModuleManager : public classbase */ std::map > Modules; + enum { + PRIO_STATE_FIRST, + PRIO_STATE_AGAIN, + PRIO_STATE_LAST + } prioritizationState; public: /** Event handler hooks. @@ -1687,14 +1693,14 @@ class CoreExport ModuleManager : public classbase * @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. */ @@ -1704,7 +1710,7 @@ class CoreExport ModuleManager : public classbase * @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. */