// *********************************************************************************************
+#define FD_MAGIC_NUMBER -42
+
extern void createcommand(char* cmd, handlerfunc f, char flags, int minparams, char* source);
extern void server_mode(char **parameters, int pcnt, userrec *user);
Admin(std::string name, std::string email, std::string nick);
};
+
+// Forward-delacare module for ModuleMessage etc
+class Module;
+
+// Thanks to Rob (from anope) for the idea of this message passing API
+// (its been done before, but this seemed a very neat and tidy way...
+
+/** The ModuleMessage class is the base class of Request and Event
+ * This class is used to represent a basic data structure which is passed
+ * between modules for safe inter-module communications.
+ */
+class ModuleMessage : public classbase
+{
+ public:
+ /** This class is pure virtual and must be inherited.
+ */
+ virtual char* Send() = 0;
+};
+
+/** The Request class is a unicast message directed at a given module.
+ * When this class is properly instantiated it may be sent to a module
+ * using the Send() method, which will call the given module's OnRequest
+ * method with this class as its parameter.
+ */
+class Request : public ModuleMessage
+{
+ protected:
+ /** This member holds a pointer to arbitary data set by the emitter of the message
+ */
+ char* data;
+ /** This is a pointer to the sender of the message, which can be used to
+ * directly trigger events, or to create a reply.
+ */
+ Module* source;
+ /** The single destination of the Request
+ */
+ Module* dest;
+ public:
+ /** Create a new Request
+ */
+ Request(char* anydata, Module* src, Module* dst);
+ /** Fetch the Request data
+ */
+ char* GetData();
+ /** Fetch the request source
+ */
+ Module* GetSource();
+ /** Fetch the request destination (should be 'this' in the receiving module)
+ */
+ Module* GetDest();
+ /** Send the Request.
+ * Upon returning the result will be arbitary data returned by the module you
+ * sent the request to. It is up to your module to know what this data is and
+ * how to deal with it.
+ */
+ char* Send();
+};
+
+
+/** The Event class is a unicast message directed at all modules.
+ * When the class is properly instantiated it may be sent to all modules
+ * using the Send() method, which will trigger the OnEvent method in
+ * all modules passing the object as its parameter.
+ */
+class Event : public ModuleMessage
+{
+ protected:
+ /** This member holds a pointer to arbitary data set by the emitter of the message
+ */
+ char* data;
+ /** This is a pointer to the sender of the message, which can be used to
+ * directly trigger events, or to create a reply.
+ */
+ Module* source;
+ /** The event identifier.
+ * This is arbitary text which should be used to distinguish
+ * one type of event from another.
+ */
+ std::string id;
+ public:
+ /** Create a new Event
+ */
+ Event(char* anydata, Module* src, std::string eventid);
+ /** Get the Event data
+ */
+ char* GetData();
+ /** Get the event Source
+ */
+ Module* GetSource();
+ /** Get the event ID.
+ * Use this to determine the event type for safe casting of the data
+ */
+ std::string GetEventID();
+ /** Send the Event.
+ * The return result of an Event::Send() will always be NULL as
+ * no replies are expected.
+ */
+ char* Send();
+};
+
+
/** Base class for all InspIRCd modules
* This class is the base class for InspIRCd modules. All modules must inherit from this class,
* its methods will be called when irc server events occur. class inherited from module must be
/** Called when a user quits.
* The details of the exiting user are available to you in the parameter userrec *user
+ * This event is only called when the user is fully registered when they quit. To catch
+ * raw disconnections, use the OnUserDisconnect method.
*/
virtual void OnUserQuit(userrec* user);
+ /** Called whenever a user's socket is closed.
+ * The details of the exiting user are available to you in the parameter userrec *user
+ * This event is called for all users, registered or not, as a cleanup method for modules
+ * which might assign resources to user, such as dns lookups, objects and sockets.
+ */
+ virtual void OnUserDisconnect(userrec* user);
+
/** Called when a user joins a channel.
* The details of the joining user are available to you in the parameter userrec *user,
* and the details of the channel they have joined is available in the variable chanrec *channel
*/
virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname);
-
+ /** Called whenever a user is about to be kicked.
+ * Returning a value of 1 from this function stops the process immediately, causing no
+ * output to be sent to the user by the core. If you do this you must produce your own numerics,
+ * notices etc.
+ */
+ virtual int OnUserPreKick(userrec* source, userrec* user, chanrec* chan, std::string reason);
+
+ /** Called whenever a user is kicked.
+ * If this method is called, the kick is already underway and cannot be prevented, so
+ * to prevent a kick, please use Module::OnUserPreKick instead of this method.
+ */
+ virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, std::string reason);
+
/** Called whenever a user opers locally.
* The userrec will contain the oper mode 'o' as this function is called after any modifications
* are made to the user's structure by the core.
* module).
*/
virtual void OnLoadModule(Module* mod,std::string name);
+
+ /** Called once every five seconds for background processing.
+ * This timer can be used to control timed features. Its period is not accurate
+ * enough to be used as a clock, but it is gauranteed to be called at least once in
+ * any five second period, directly from the main loop of the server.
+ */
+ virtual void OnBackgroundTimer(time_t curtime);
+
+ /** Called whenever a list is needed for a listmode.
+ * For example, when a /MODE #channel +b (without any other parameters) is called,
+ * if a module was handling +b this function would be called. The function can then
+ * output any lists it wishes to. Please note that all modules will see all mode
+ * characters to provide the ability to extend each other, so please only output
+ * a list if the mode character given matches the one(s) you want to handle.
+ */
+ virtual void OnSendList(userrec* user, chanrec* channel, char mode);
+
+ /** Called whenever any command is about to be executed.
+ * This event occurs for all registered commands, wether they are registered in the core,
+ * or another module, but it will not occur for invalid commands (e.g. ones which do not
+ * exist within the command table). By returning 1 from this method you may prevent the
+ * command being executed. If you do this, no output is created by the core, and it is
+ * down to your module to produce any output neccessary.
+ * Note that unless you return 1, you should not destroy any structures (e.g. by using
+ * Server::QuitUser) otherwise when the command's handler function executes after your
+ * method returns, it will be passed an invalid pointer to the user object and crash!)
+ */
+ virtual int OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user);
+
+ /** Called to check if a user who is connecting can now be allowed to register
+ * If any modules return false for this function, the user is held in the waiting
+ * state until all modules return true. For example a module which implements ident
+ * lookups will continue to return false for a user until their ident lookup is completed.
+ * Note that the registration timeout for a user overrides these checks, if the registration
+ * timeout is reached, the user is disconnected even if modules report that the user is
+ * not ready to connect.
+ */
+ virtual bool OnCheckReady(userrec* user);
+
+ /** Called whenever a user is about to register their connection (e.g. before the user
+ * is sent the MOTD etc). Modules can use this method if they are performing a function
+ * which must be done before the actual connection is completed (e.g. ident lookups,
+ * dnsbl lookups, etc).
+ * Note that you should NOT delete the user record here by causing a disconnection!
+ * Use OnUserConnect for that instead.
+ */
+ 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!
+ */
+ virtual int OnRawMode(userrec* user, chanrec* chan, char mode, std::string param, bool adding, int pcnt);
+
+ /** 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
+ * determines the outcome of an if statement around the whole section of invite checking code.
+ * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
+ */
+ virtual int OnCheckInvite(userrec* user, chanrec* chan);
+
+ /** Called whenever a user joins a channel, to determine if key checks should go ahead or not.
+ * This method will always be called for each join, wether or not the channel is actually +k, and
+ * determines the outcome of an if statement around the whole section of key checking code.
+ * if the user specified no key, the keygiven string will be a valid but empty value.
+ * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
+ */
+ virtual int OnCheckKey(userrec* user, chanrec* chan, std::string keygiven);
+
+ /** Called whenever a user joins a channel, to determine if channel limit checks should go ahead or not.
+ * This method will always be called for each join, wether or not the channel is actually +l, and
+ * determines the outcome of an if statement around the whole section of channel limit checking code.
+ * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
+ */
+ virtual int OnCheckLimit(userrec* user, chanrec* chan);
+
+ /** Called whenever a user joins a channel, to determine if banlist checks should go ahead or not.
+ * This method will always be called for each join, wether or not the user actually matches a channel ban, and
+ * determines the outcome of an if statement around the whole section of ban checking code.
+ * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
+ */
+ virtual int OnCheckBan(userrec* user, chanrec* chan);
+
+ /** Called on all /STATS commands
+ * This method is triggered for all /STATS use, including stats symbols handled by the core.
+ */
+ virtual void OnStats(char symbol);
+
+ /** Called whenever a change of a local users displayed host is attempted.
+ * Return 1 to deny the host change, or 0 to allow it.
+ */
+ virtual int OnChangeLocalUserHost(userrec* user, std::string newhost);
+
+ /** Called whenever a change of a local users GECOS (fullname field) is attempted.
+ * return 1 to deny the name change, or 0 to allow it.
+ */
+ virtual int OnChangeLocalUserGECOS(userrec* user, std::string newhost);
+
+ /** Called whenever a topic is changed by a local user.
+ * Return 1 to deny the topic change, or 0 to allow it.
+ */
+ virtual int OnLocalTopicChange(userrec* user, chanrec* chan, std::string topic);
+
+ /** Called whenever an unknown token is received in a server to server link.
+ * The token value is the unknown token -- please check that no other modules are using the token
+ * that you use. Returning 1 supresses the 'unknown token type' error which is usually sent to
+ * all opers with +s. The params list is a list of parameters, and if any parameters start with a
+ * colon (:) it is treated as the whole of the last parameter, identical to how RFC messages are
+ * handled. source is the sender of the message, and reply is what should be replied to for a unicast
+ * message. Note that there are not many messages in the mesh protocol which require unicast
+ * messaging. tcp_host is the server name as a string, ipaddr is its ip address in dotted decimal
+ * notation and port is the port number it is using.
+ */
+ virtual int OnMeshToken(char token,string_list params,serverrec* source,serverrec* reply, std::string tcp_host,std::string ipaddr,int port);
+
+ /** Called whenever an Event class is sent to all module by another module.
+ * Please see the documentation of Event::Send() for further information. The Event sent can
+ * always be assumed to be non-NULL, you should *always* check the value of Event::GetEventID()
+ * before doing anything to the event data, and you should *not* change the event data in any way!
+ */
+ virtual void OnEvent(Event* event);
+
+ /** Called whenever a Request class is sent to your module by another module.
+ * Please see the documentation of Request::Send() for further information. The Request sent
+ * can always be assumed to be non-NULL, you should not change the request object or its data.
+ * Your method may return arbitary data in the char* result which the requesting module
+ * may be able to use for pre-determined purposes (e.g. the results of an SQL query, etc).
+ */
+ virtual char* OnRequest(Request* request);
};
* so the above example would become '+aa one three' after processing.
*/
virtual bool AddExtendedListMode(char modechar);
-
+
/** Adds a command to the command table.
* This allows modules to add extra commands into the command table. You must place a function within your
* module which is is of type handlerfunc:
*/
virtual chanuserlist GetUsers(chanrec* chan);
+ /** Remove a user's connection to the irc server, but leave their client in existence in the
+ * user hash. When you call this function, the user's file descriptor will be replaced with the
+ * value of FD_MAGIC_NUMBER and their old file descriptor will be closed. This idle client will
+ * remain until it is restored with a valid file descriptor, or is removed from IRC by an operator
+ * After this call, the pointer to user will be invalid.
+ */
+ virtual bool UserToPseudo(userrec* user,std::string message);
+
+ /** This user takes one user, and switches their file descriptor with another user, so that one user
+ * "becomes" the other. The user in 'alive' is booted off the server with the given message. The user
+ * referred to by 'zombie' should have previously been locked with Server::ZombifyUser, otherwise
+ * stale sockets and file descriptor leaks can occur. After this call, the pointer to alive will be
+ * invalid, and the pointer to zombie will be equivalent in effect to the old pointer to alive.
+ */
+ virtual bool PseudoToUser(userrec* alive,userrec* zombie,std::string message);
+
+ /** Adds a G-line
+ * The G-line is propogated to all of the servers in the mesh and enforced as soon as it is added.
+ * The duration must be in seconds, however you can use the Server::CalcDuration method to convert
+ * durations into the 1w2d3h3m6s format used by /GLINE etc. The source is an arbitary string used
+ * to indicate who or what sent the data, usually this is the nickname of a person, or a server
+ * name.
+ */
+ virtual void AddGLine(long duration, std::string source, std::string reason, std::string hostmask);
+
+ /** Adds a Q-line
+ * The Q-line is propogated to all of the servers in the mesh and enforced as soon as it is added.
+ * The duration must be in seconds, however you can use the Server::CalcDuration method to convert
+ * durations into the 1w2d3h3m6s format used by /GLINE etc. The source is an arbitary string used
+ * to indicate who or what sent the data, usually this is the nickname of a person, or a server
+ * name.
+ */
+ virtual void AddQLine(long duration, std::string source, std::string reason, std::string nickname);
+
+ /** Adds a Z-line
+ * The Z-line is propogated to all of the servers in the mesh and enforced as soon as it is added.
+ * The duration must be in seconds, however you can use the Server::CalcDuration method to convert
+ * durations into the 1w2d3h3m6s format used by /GLINE etc. The source is an arbitary string used
+ * to indicate who or what sent the data, usually this is the nickname of a person, or a server
+ * name.
+ */
+ virtual void AddZLine(long duration, std::string source, std::string reason, std::string ipaddr);
+
+ /** Adds a K-line
+ * The K-line is enforced as soon as it is added.
+ * The duration must be in seconds, however you can use the Server::CalcDuration method to convert
+ * durations into the 1w2d3h3m6s format used by /GLINE etc. The source is an arbitary string used
+ * to indicate who or what sent the data, usually this is the nickname of a person, or a server
+ * name.
+ */
+ virtual void AddKLine(long duration, std::string source, std::string reason, std::string hostmask);
+
+ /** Adds a E-line
+ * The E-line is enforced as soon as it is added.
+ * The duration must be in seconds, however you can use the Server::CalcDuration method to convert
+ * durations into the 1w2d3h3m6s format used by /GLINE etc. The source is an arbitary string used
+ * to indicate who or what sent the data, usually this is the nickname of a person, or a server
+ * name.
+ */
+ virtual void AddELine(long duration, std::string source, std::string reason, std::string hostmask);
+
+ /** Deletes a G-Line from all servers on the mesh
+ */
+ virtual bool DelGLine(std::string hostmask);
+
+ /** Deletes a Q-Line from all servers on the mesh
+ */
+ virtual bool DelQLine(std::string nickname);
+
+ /** Deletes a Z-Line from all servers on the mesh
+ */
+ virtual bool DelZLine(std::string ipaddr);
+
+ /** Deletes a local K-Line
+ */
+ virtual bool DelKLine(std::string hostmask);
+
+ /** Deletes a local E-Line
+ */
+ virtual bool DelELine(std::string hostmask);
+
+ /** Calculates a duration
+ * This method will take a string containing a formatted duration (e.g. "1w2d") and return its value
+ * as a total number of seconds. This is the same function used internally by /GLINE etc to set
+ * the ban times.
+ */
+ virtual long CalcDuration(std::string duration);
+
+ /** Returns true if a nick!ident@host string is correctly formatted, false if otherwise.
+ */
+ virtual bool IsValidMask(std::string mask);
+
+ /** Sends a line of text to all connected servers.
+ * If a server is not directly reachable, the core deals with routing the message, and will also
+ * deal with failures transparently.
+ */
+ virtual void MeshSendAll(std::string text);
+
+ /** This method sends a line of text to all servers who have users which share common channels with the user you provide.
+ * For example, if user A is on server A, and they are on channels #one and #two, and user B is on server B, and also on
+ * channel #one, but user C is on server C and on neither #one or #two, this function will cause the text to only be
+ * sent to server B. However, if server B is only reachable via C, it will route it to C (you do not have to worry about
+ * this routing, it is done transparently, but its good to know how things work!)
+ */
+ virtual void MeshSendCommon(userrec* user, std::string text);
+
+ /** This function is equivalent to Server::MeshSendToAll except it will only route to servers which are directly routable.
+ */
+ virtual void MeshSendAllAlive(std::string text);
+
+ /** This function sends a line of text directly to a server.
+ * If the server is not directly routable at this time, the server attempts to route text through the mesh.
+ */
+ virtual void MeshSendUnicast(std::string destination, std::string text);
+
+ /** This function sends to all servers EXCEPT the one you specify.
+ * You should usually use this function to send messages, specifying the SENDER of your message as 'target'.
+ * This will prevent message loops.
+ */
+ virtual void MeshSendAllExcept(std::string target, std::string text);
+
+ /** This function is used to check if any users on channel c are on server servername.
+ * This is used internally by PRIVMSG etc. You should not need to use it.
+ */
+ virtual bool MeshCheckChan(chanrec *c,std::string servername);
+
+ /** This function is used to check if user u has any channels in common with users on servername.
+ * This is used internally by Server::MeshSendCommon. You should very rarely need to use it.
+ */
+ virtual bool MeshCheckCommon(userrec* u,std::string servername);
+
+ /** This function finds a module by name.
+ * You must provide the filename of the module. If the module cannot be found (is not loaded)
+ * the function will return NULL.
+ */
+ virtual Module* FindModule(std::string name);
};
+
#define CONF_NOT_A_NUMBER 0x000010
#define CONF_NOT_UNSIGNED 0x000080
#define CONF_VALUE_NOT_FOUND 0x000100
#define CONF_FILE_NOT_FOUND 0x000200
+
/** Allows reading of values from configuration files
* This class allows a module to read from either the main configuration file (inspircd.conf) or from
* a module-specified configuration file. It may either be instantiated with one parameter or none.