]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/modules.h
Documentation change to indicate errno is valid on return from the constructor -...
[user/henk/code/inspircd.git] / include / modules.h
index df9497fd2db64b1b49a52f99bda2477de2ce2aa3..8bc52b683db6b51acecf12570b1f20a96e1837bd 100644 (file)
@@ -2,19 +2,15 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- *                    E-mail:
- *             <brain@chatspike.net>
- *               <Craig@chatspike.net>
- *     
- * Written by Craig Edwards, Craig McLure, and others.
+ *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
  * This program is free but copyrighted software; see
- *         the file COPYING for details.
+ *            the file COPYING for details.
  *
  * ---------------------------------------------------
  */
 
-
 #ifndef __MODULES_H
 #define __MODULES_H
 
@@ -56,6 +52,11 @@ enum TargetTypeFlags {
        TYPE_OTHER
 };
 
+enum MessageType {
+       MSG_PRIVMSG = 0,
+       MSG_NOTICE = 1
+};
+
 #include "globals.h"
 #include "dynamic.h"
 #include "base.h"
@@ -68,9 +69,18 @@ enum TargetTypeFlags {
 #include "mode.h"
 #include "dns.h"
 
-/** If you change the module API, change this value
+/** 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 API_VERSION 11001
+#define NATIVE_API_VERSION 11011
+#ifdef IPV6
+#define API_VERSION (NATIVE_API_VERSION * 10)
+#else
+#define API_VERSION (NATIVE_API_VERSION * 1)
+#endif
 
 class ServerConfig;
 
@@ -87,6 +97,14 @@ typedef file_cache string_list;
  */
 typedef std::map<std::string,Module*> featurelist;
 
+/** Holds a list of modules which implement an interface
+ */
+typedef std::deque<Module*> modulelist;
+
+/** Holds a list of all modules which implement interfaces, by interface name
+ */
+typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
+
 /**
  * This #define allows us to call a method in all
  * loaded modules in a readable simple way, e.g.:
@@ -99,9 +117,9 @@ typedef std::map<std::string,Module*> featurelist;
                { \
                        ServerInstance->modules[_i]->x ; \
                } \
-               catch (ModuleException& modexcept) \
+               catch (CoreException& modexcept) \
                { \
-                       ServerInstance->Log(DEBUG,"Module exception caught: %s",modexcept.GetReason()); \
+                       ServerInstance->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \
                } \
        } \
   }
@@ -113,9 +131,9 @@ typedef std::map<std::string,Module*> featurelist;
                { \
                        z->modules[_i]->x ; \
                } \
-               catch (ModuleException& modexcept) \
+               catch (CoreException& modexcept) \
                { \
-                       z->Log(DEBUG,"Module exception caught: %s",modexcept.GetReason()); \
+                       z->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \
                } \
        } \
 }
@@ -136,9 +154,9 @@ typedef std::map<std::string,Module*> featurelist;
                                                break; \
                                        } \
                                } \
-                               catch (ModuleException& modexcept) \
+                               catch (CoreException& modexcept) \
                                { \
-                                       ServerInstance->Log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \
+                                       ServerInstance->Log(DEFAULT,"Exception cought: %s",modexcept.GetReason()); \
                                } \
                        } \
                } \
@@ -157,9 +175,9 @@ typedef std::map<std::string,Module*> featurelist;
                                                break; \
                                        } \
                                } \
-                               catch (ModuleException& modexcept) \
+                               catch (CoreException& modexcept) \
                                { \
-                                       z->Log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \
+                                       z->Log(DEBUG,"Exception cought: %s",modexcept.GetReason()); \
                                } \
                        } \
                } \
@@ -304,23 +322,29 @@ class Event : public ModuleMessage
  * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user
  * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time.
  */
-class ModuleException : public classbase
+class CoreException : public std::exception
 {
- private:
+ protected:
        /** Holds the error message to be displayed
         */
-       std::string err;
+       const std::string err;
+       const std::string source;
  public:
-       /** Default constructor, just uses the error mesage 'Module threw an exception'.
+       /** Default constructor, just uses the error mesage 'Core threw an exception'.
         */
-       ModuleException() : err("Module threw an exception") {}
+       CoreException() : err("Core threw an exception"), source("The core") {}
        /** This constructor can be used to specify an error message before throwing.
         */
-       ModuleException(std::string message) : err(message) {}
+       CoreException(const std::string &message) : err(message), source("The core") {}
+       /** This constructor can be used to specify an error message before throwing,
+        * and to specify the source of the exception.
+        */
+       CoreException(const std::string &message, const std::string &src) : err(message), source(src) {}
        /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
         * Actually no, it does nothing. Never mind.
+        * @throws Nothing!
         */
-       virtual ~ModuleException() {};
+       virtual ~CoreException() throw() {};
        /** Returns the reason for the exception.
         * The module should probably put something informative here as the user will see this upon failure.
         */
@@ -328,6 +352,28 @@ class ModuleException : public classbase
        {
                return err.c_str();
        }
+
+       virtual const char* GetSource()
+       {
+               return source.c_str();
+       }
+};
+
+class ModuleException : public CoreException
+{
+ public:
+       /** Default constructor, just uses the error mesage 'Module threw an exception'.
+        */
+       ModuleException() : CoreException("Module threw an exception", "A Module") {}
+
+       /** This constructor can be used to specify an error message before throwing.
+        */
+       ModuleException(const std::string &message) : CoreException(message, "A Module") {}
+       /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
+        * Actually no, it does nothing. Never mind.
+        * @throws Nothing!
+        */
+       virtual ~ModuleException() throw() {};
 };
 
 /** Priority types which can be returned from Module::Prioritize()
@@ -343,11 +389,12 @@ enum Implementation {     I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUse
                        I_OnDecodeMetaData, I_ProtoSendMode, I_ProtoSendMetaData, I_OnWallops, I_OnChangeHost, I_OnChangeName, I_OnAddGLine,
                        I_OnAddZLine, I_OnAddQLine, I_OnAddKLine, I_OnAddELine, I_OnDelGLine, I_OnDelZLine, I_OnDelKLine, I_OnDelELine, I_OnDelQLine,
                        I_OnCleanup, I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill, I_OnLoadModule, I_OnUnloadModule,
-                       I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnUserRrgister, I_OnRawMode, I_OnCheckInvite,
+                       I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnUserRrgister, I_OnCheckInvite,
                        I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnLocalTopicChange,
                        I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnOperCompre, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan, I_OnDelBan,
                        I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead, I_OnChangeLocalUserGECOS, I_OnUserRegister,
-                       I_OnOperCompare, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList, I_OnPostCommand, I_OnPostJoin };
+                       I_OnOperCompare, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList,
+                       I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect };
 
 /** Base class for all InspIRCd modules
  *  This class is the base class for InspIRCd modules. All modules must inherit from this class,
@@ -471,9 +518,11 @@ class Module : public Extensible
         * 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.
         */
-       virtual void OnRehash(const std::string &parameter);
+       virtual void OnRehash(userrec* user, const std::string &parameter);
 
        /** Called when a raw command is transmitted or received.
         * This method is the lowest level of handler available to a module. It will be called with raw
@@ -600,9 +649,11 @@ class Module : public Extensible
         * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
         * @param text Changeable text being sent by the user
         * @param status The status being used, e.g. PRIVMSG @#chan has status== '@', 0 to send to everyone.
+        * @param exempt_list A list of users not to send to. For channel messages, this will usually contain just the sender.
+        * It will be ignored for private messages.
         * @return 1 to deny the NOTICE, 0 to allow it
         */
-       virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text,char status);
+       virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text,char status, CUList &exempt_list);
 
        /** Called whenever a user is about to NOTICE A user or a channel, before any processing is done.
         * Returning any nonzero value from this function stops the process immediately, causing no
@@ -619,9 +670,21 @@ class Module : public Extensible
         * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
         * @param text Changeable text being sent by the user
         * @param status The status being used, e.g. PRIVMSG @#chan has status== '@', 0 to send to everyone.
+        * @param exempt_list A list of users not to send to. For channel notices, this will usually contain just the sender.
+        * It will be ignored for private notices.
         * @return 1 to deny the NOTICE, 0 to allow it
         */
-       virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text,char status);
+       virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text,char status, CUList &exempt_list);
+
+       /** Called whenever the server wants to build the exemption list for a channel, but is not directly doing a PRIVMSG or NOTICE.
+        * For example, the spanningtree protocol will call this event when passing a privmsg on (but not processing it directly).
+        * @param message_type The message type, either MSG_PRIVMSG or MSG_NOTICE
+        * @param chan The channel to build the exempt list of
+        * @param sender The original sender of the PRIVMSG or NOTICE
+        * @param status The status char to be used for the channel list
+        * @param exempt_list The exempt list to be populated
+        */
+       virtual void OnBuildExemptList(MessageType message_type, chanrec* chan, userrec* sender, char status, CUList &exempt_list);
        
        /** Called before any nickchange, local or remote. This can be used to implement Q-lines etc.
         * Please note that although you can see remote nickchanges through this function, you should
@@ -644,7 +707,7 @@ class Module : public Extensible
         * @param text the text being sent by the user
         * @param status The status being used, e.g. PRIVMSG @#chan has status== '@', 0 to send to everyone.
         */
-       virtual void OnUserMessage(userrec* user, void* dest, int target_type, const std::string &text, char status);
+       virtual void OnUserMessage(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list);
 
        /** Called after any NOTICE sent from a user.
         * The dest variable contains a userrec* if target_type is TYPE_USER and a chanrec*
@@ -655,7 +718,7 @@ class Module : public Extensible
         * @param text the text being sent by the user
         * @param status The status being used, e.g. NOTICE @#chan has status== '@', 0 to send to everyone.
         */
-       virtual void OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status);
+       virtual void OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list);
 
        /** Called after every MODE command sent from a user
         * The dest variable contains a userrec* if target_type is TYPE_USER and a chanrec*
@@ -1051,22 +1114,9 @@ class Module : public Extensible
         * Note that you should NOT delete the user record here by causing a disconnection!
         * Use OnUserConnect for that instead.
         * @param user The user registering
+        * @return 1 to indicate user quit, 0 to continue
         */
-       virtual void OnUserRegister(userrec* user);
-
-       /** Called whenever a mode character is processed.
-        * Return 1 from this function to block the mode character from being processed entirely,
-        * so that you may perform your own code instead. Note that this method allows you to override
-        * modes defined by other modes, but this is NOT RECOMMENDED!
-        * @param user The user who is sending the mode
-        * @param chan The channel the mode is being sent to
-        * @param mode The mode character being set
-        * @param param The parameter for the mode or an empty string
-        * @param adding true of the mode is being added, false if it is being removed
-        * @param pcnt The parameter count for the mode (0 or 1)
-        * @return 1 to deny the mode, 0 to allow
-        */
-       virtual int OnRawMode(userrec* user, chanrec* chan, char mode, const std::string &param, bool adding, int pcnt);
+       virtual int OnUserRegister(userrec* user);
 
        /** Called whenever a user joins a channel, to determine if invite checks should go ahead or not.
         * This method will always be called for each join, wether or not the channel is actually +i, and
@@ -1177,9 +1227,10 @@ class Module : public Extensible
         * to do nothing.
         * @param password The oper's password
         * @param input The password entered
-        * @return 1 to match the passwords, 0 to do nothing
+        * @param tagnumber The tag number (from the configuration file) of this oper's tag
+        * @return 1 to match the passwords, 0 to do nothing. -1 to not match, and not continue.
         */
-       virtual int OnOperCompare(const std::string &password, const std::string &input);
+       virtual int OnOperCompare(const std::string &password, const std::string &input, int tagnumber);
 
        /** Called whenever a user is given usermode +o, anywhere on the network.
         * You cannot override this and prevent it from happening as it is already happened and
@@ -1244,6 +1295,8 @@ class Module : public Extensible
         */
        virtual void OnRawSocketClose(int fd);
 
+       virtual void OnRawSocketConnect(int fd);
+
        /** Called immediately before any read() operation on a client socket in the core.
         * This occurs AFTER the select() or poll() so there is always data waiting to be read
         * when this event occurs.
@@ -1277,6 +1330,26 @@ class Module : public Extensible
         * return 0.
         */
        virtual int OnUserList(userrec* user, chanrec* Ptr);
+
+       /** Called whenever a line of WHOIS output is sent to a user.
+        * You may change the numeric and the text of the output by changing
+        * the values numeric and text, but you cannot change the user the
+        * numeric is sent to. You may however change the user's userrec values.
+        * @param user The user the numeric is being sent to
+        * @param dest The user being WHOISed
+        * @param numeric The numeric of the line being sent
+        * @param text The text of the numeric, including any parameters
+        * @return nonzero to drop the line completely so that the user does not
+        * receive it, or zero to allow the line to be sent.
+        */
+       virtual int OnWhoisLine(userrec* user, userrec* dest, int &numeric, std::string &text);
+
+       /** Called at intervals for modules to garbage-collect any hashes etc.
+        * Certain data types such as hash_map 'leak' buckets, which must be
+        * tidied up and freed by copying into a new item every so often. This
+        * method is called when it is time to do that.
+        */
+       virtual void OnGarbageCollect();
 };
 
 
@@ -1323,17 +1396,33 @@ class ConfigReader : public classbase
         * This method destroys the ConfigReader class.
         */
        ~ConfigReader();
+
        /** Retrieves a value from the config file.
         * This method retrieves a value from the config file. Where multiple copies of the tag
         * exist in the config file, index indicates which of the values to retrieve.
         */
-       std::string ReadValue(const std::string &tag, const std::string &name, int index);
+       std::string ReadValue(const std::string &tag, const std::string &name, int index, bool allow_linefeeds = false);
+       /** Retrieves a value from the config file.
+        * This method retrieves a value from the config file. Where multiple copies of the tag
+        * exist in the config file, index indicates which of the values to retrieve. If the
+        * tag is not found the default value is returned instead.
+        */
+       std::string ReadValue(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool allow_linefeeds = false);
+
        /** Retrieves a boolean value from the config file.
         * This method retrieves a boolean value from the config file. Where multiple copies of the tag
         * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes"
         * and "true" in the config file count as true to ReadFlag, and any other value counts as false.
         */
        bool ReadFlag(const std::string &tag, const std::string &name, int index);
+       /** Retrieves a boolean value from the config file.
+        * This method retrieves a boolean value from the config file. Where multiple copies of the tag
+        * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes"
+        * and "true" in the config file count as true to ReadFlag, and any other value counts as false.
+        * If the tag is not found, the default value is used instead.
+        */
+       bool ReadFlag(const std::string &tag, const std::string &name, const std::string &default_value, int index);
+
        /** Retrieves an integer value from the config file.
         * This method retrieves an integer value from the config file. Where multiple copies of the tag
         * exist in the config file, index indicates which of the values to retrieve. Any invalid integer
@@ -1343,6 +1432,16 @@ class ConfigReader : public classbase
         * will return CONF_NOT_UNSIGNED
         */
        long ReadInteger(const std::string &tag, const std::string &name, int index, bool needs_unsigned);
+       /** Retrieves an integer value from the config file.
+        * This method retrieves an integer value from the config file. Where multiple copies of the tag
+        * exist in the config file, index indicates which of the values to retrieve. Any invalid integer
+        * values in the tag will cause the objects error value to be set, and any call to GetError() will
+        * return CONF_INVALID_NUMBER to be returned. needs_unsigned is set if the number must be unsigned.
+        * If a signed number is placed into a tag which is specified unsigned, 0 will be returned and GetError()
+        * will return CONF_NOT_UNSIGNED. If the tag is not found, the default value is used instead.
+        */
+       long ReadInteger(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool needs_unsigned);
+
        /** Returns the last error to occur.
         * Valid errors can be found by looking in modules.h. Any nonzero value indicates an error condition.
         * A call to GetError() resets the error flag back to 0.